(function (global, factory) { if (typeof define === "function" && define.amd) { define(["exports", "./constants.js"], factory); } else if (typeof exports !== "undefined") { factory(exports, require("./constants.js")); } else { var mod = { exports: {} }; factory(mod.exports, global.constants); global.WebGPUTextureUtils = mod.exports; } })(typeof globalThis !== "undefined" ? globalThis : typeof self !== "undefined" ? self : this, function (_exports, _constants) { "use strict"; Object.defineProperty(_exports, "__esModule", { value: true }); _exports.default = void 0; function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; } // ported from https://github.com/toji/web-texture-tool/blob/master/src/webgpu-mipmap-generator.js var WebGPUTextureUtils = /*#__PURE__*/function () { function WebGPUTextureUtils(device) { _classCallCheck(this, WebGPUTextureUtils); this.device = device; var mipmapVertexSource = "\n[[ block ]]\nstruct VarysStruct {\n\n\t[[ builtin( position ) ]] Position: vec4<f32>;\n\t[[ location( 0 ) ]] vTex : vec2<f32>;\n\n};\n\n[[ stage( vertex ) ]]\nfn main( [[ builtin( vertex_index ) ]] vertexIndex : u32 ) -> VarysStruct {\n\n\tvar Varys: VarysStruct;\n\n\tvar pos = array< vec2<f32>, 4 >(\n\t\tvec2<f32>( -1.0, 1.0 ),\n\t\tvec2<f32>( 1.0, 1.0 ),\n\t\tvec2<f32>( -1.0, -1.0 ),\n\t\tvec2<f32>( 1.0, -1.0 )\n\t);\n\n\tvar tex = array< vec2<f32>, 4 >(\n\t\tvec2<f32>( 0.0, 0.0 ),\n\t\tvec2<f32>( 1.0, 0.0 ),\n\t\tvec2<f32>( 0.0, 1.0 ),\n\t\tvec2<f32>( 1.0, 1.0 )\n\t);\n\n\tVarys.vTex = tex[ vertexIndex ];\n\tVarys.Position = vec4<f32>( pos[ vertexIndex ], 0.0, 1.0 );\n\n\treturn Varys;\n\n}\n"; var mipmapFragmentSource = "\n[[ group( 0 ), binding( 0 ) ]] \nvar imgSampler : sampler;\n\n[[ group( 0 ), binding( 1 ) ]] \nvar img : texture_2d<f32>;\n\n[[ stage( fragment ) ]]\nfn main( [[ location( 0 ) ]] vTex : vec2<f32> ) -> [[ location( 0 ) ]] vec4<f32> {\n\n\treturn textureSample( img, imgSampler, vTex );\n\n}\n"; this.sampler = device.createSampler({ minFilter: _constants.GPUFilterMode.Linear }); // We'll need a new pipeline for every texture format used. this.pipelines = {}; this.mipmapVertexShaderModule = device.createShaderModule({ code: mipmapVertexSource }); this.mipmapFragmentShaderModule = device.createShaderModule({ code: mipmapFragmentSource }); } _createClass(WebGPUTextureUtils, [{ key: "getMipmapPipeline", value: function getMipmapPipeline(format) { var pipeline = this.pipelines[format]; if (pipeline === undefined) { pipeline = this.device.createRenderPipeline({ vertex: { module: this.mipmapVertexShaderModule, entryPoint: 'main' }, fragment: { module: this.mipmapFragmentShaderModule, entryPoint: 'main', targets: [{ format: format }] }, primitive: { topology: _constants.GPUPrimitiveTopology.TriangleStrip, stripIndexFormat: _constants.GPUIndexFormat.Uint32 } }); this.pipelines[format] = pipeline; } return pipeline; } }, { key: "generateMipmaps", value: function generateMipmaps(textureGPU, textureGPUDescriptor) { var pipeline = this.getMipmapPipeline(textureGPUDescriptor.format); var commandEncoder = this.device.createCommandEncoder({}); var bindGroupLayout = pipeline.getBindGroupLayout(0); // @TODO: Consider making this static. var srcView = textureGPU.createView({ baseMipLevel: 0, mipLevelCount: 1 }); for (var i = 1; i < textureGPUDescriptor.mipLevelCount; i++) { var dstView = textureGPU.createView({ baseMipLevel: i, mipLevelCount: 1 }); var passEncoder = commandEncoder.beginRenderPass({ colorAttachments: [{ view: dstView, loadValue: [0, 0, 0, 0] }] }); var bindGroup = this.device.createBindGroup({ layout: bindGroupLayout, entries: [{ binding: 0, resource: this.sampler }, { binding: 1, resource: srcView }] }); passEncoder.setPipeline(pipeline); passEncoder.setBindGroup(0, bindGroup); passEncoder.draw(4, 1, 0, 0); passEncoder.endPass(); srcView = dstView; } this.device.queue.submit([commandEncoder.finish()]); } }]); return WebGPUTextureUtils; }(); var _default = WebGPUTextureUtils; _exports.default = _default; });