(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;
});