UNPKG

pixi.js

Version:

<p align="center"> <a href="https://pixijs.com" target="_blank" rel="noopener noreferrer"> <img height="150" src="https://files.pixijs.download/branding/pixijs-logo-transparent-dark.svg?v=1" alt="PixiJS logo"> </a> </p> <br/> <p align="center">

1 lines 12 kB
{"version":3,"file":"GpuMipmapGenerator.mjs","sources":["../../../../../../src/rendering/renderers/gpu/texture/utils/GpuMipmapGenerator.ts"],"sourcesContent":["/**\n * A class which generates mipmaps for a GPUTexture.\n * Thanks to toji for the original implementation\n * https://github.com/toji/web-texture-tool/blob/main/src/webgpu-mipmap-generator.js\n * @category rendering\n * @ignore\n */\nexport class GpuMipmapGenerator\n{\n public device: GPUDevice;\n public sampler: GPUSampler;\n public pipelines: Record<string, GPURenderPipeline>;\n\n public mipmapShaderModule: any;\n\n constructor(device: GPUDevice)\n {\n this.device = device;\n this.sampler = device.createSampler({ minFilter: 'linear' });\n // We'll need a new pipeline for every texture format used.\n this.pipelines = {};\n }\n\n private _getMipmapPipeline(format: GPUTextureFormat)\n {\n let pipeline = this.pipelines[format];\n\n if (!pipeline)\n {\n // Shader modules is shared between all pipelines, so only create once.\n if (!this.mipmapShaderModule)\n {\n this.mipmapShaderModule = this.device.createShaderModule({\n code: /* wgsl */ `\n var<private> pos : array<vec2<f32>, 3> = array<vec2<f32>, 3>(\n vec2<f32>(-1.0, -1.0), vec2<f32>(-1.0, 3.0), vec2<f32>(3.0, -1.0));\n\n struct VertexOutput {\n @builtin(position) position : vec4<f32>,\n @location(0) texCoord : vec2<f32>,\n };\n\n @vertex\n fn vertexMain(@builtin(vertex_index) vertexIndex : u32) -> VertexOutput {\n var output : VertexOutput;\n output.texCoord = pos[vertexIndex] * vec2<f32>(0.5, -0.5) + vec2<f32>(0.5);\n output.position = vec4<f32>(pos[vertexIndex], 0.0, 1.0);\n return output;\n }\n\n @group(0) @binding(0) var imgSampler : sampler;\n @group(0) @binding(1) var img : texture_2d<f32>;\n\n @fragment\n fn fragmentMain(@location(0) texCoord : vec2<f32>) -> @location(0) vec4<f32> {\n return textureSample(img, imgSampler, texCoord);\n }\n `,\n });\n }\n\n pipeline = this.device.createRenderPipeline({\n layout: 'auto',\n vertex: {\n module: this.mipmapShaderModule,\n entryPoint: 'vertexMain',\n },\n fragment: {\n module: this.mipmapShaderModule,\n entryPoint: 'fragmentMain',\n targets: [{ format }],\n }\n });\n\n this.pipelines[format] = pipeline;\n }\n\n return pipeline;\n }\n\n /**\n * Generates mipmaps for the given GPUTexture from the data in level 0.\n * @param {module:External.GPUTexture} texture - Texture to generate mipmaps for.\n * @returns {module:External.GPUTexture} - The originally passed texture\n */\n public generateMipmap(texture: GPUTexture)\n {\n const pipeline = this._getMipmapPipeline(texture.format);\n\n if (texture.dimension === '3d' || texture.dimension === '1d')\n {\n throw new Error('Generating mipmaps for non-2d textures is currently unsupported!');\n }\n\n let mipTexture = texture;\n const arrayLayerCount = texture.depthOrArrayLayers || 1; // Only valid for 2D textures.\n\n // If the texture was created with RENDER_ATTACHMENT usage we can render directly between mip levels.\n const renderToSource = texture.usage & GPUTextureUsage.RENDER_ATTACHMENT;\n\n if (!renderToSource)\n {\n // Otherwise we have to use a separate texture to render into. It can be one mip level smaller than the source\n // texture, since we already have the top level.\n const mipTextureDescriptor = {\n size: {\n width: Math.ceil(texture.width / 2),\n height: Math.ceil(texture.height / 2),\n depthOrArrayLayers: arrayLayerCount,\n },\n format: texture.format,\n usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_SRC | GPUTextureUsage.RENDER_ATTACHMENT,\n mipLevelCount: texture.mipLevelCount - 1,\n };\n\n mipTexture = this.device.createTexture(mipTextureDescriptor);\n }\n\n const commandEncoder = this.device.createCommandEncoder({});\n // TODO: Consider making this static.\n const bindGroupLayout = pipeline.getBindGroupLayout(0);\n\n for (let arrayLayer = 0; arrayLayer < arrayLayerCount; ++arrayLayer)\n {\n let srcView = texture.createView({\n baseMipLevel: 0,\n mipLevelCount: 1,\n dimension: '2d',\n baseArrayLayer: arrayLayer,\n arrayLayerCount: 1,\n });\n\n let dstMipLevel = renderToSource ? 1 : 0;\n\n for (let i = 1; i < texture.mipLevelCount; ++i)\n {\n const dstView = mipTexture.createView({\n baseMipLevel: dstMipLevel++,\n mipLevelCount: 1,\n dimension: '2d',\n baseArrayLayer: arrayLayer,\n arrayLayerCount: 1,\n });\n\n const passEncoder = commandEncoder.beginRenderPass({\n colorAttachments: [{\n view: dstView,\n storeOp: 'store',\n loadOp: 'clear',\n clearValue: { r: 0, g: 0, b: 0, a: 0 },\n }],\n });\n\n const bindGroup = this.device.createBindGroup({\n layout: bindGroupLayout,\n entries: [{\n binding: 0,\n resource: this.sampler,\n }, {\n binding: 1,\n resource: srcView,\n }],\n });\n\n passEncoder.setPipeline(pipeline);\n passEncoder.setBindGroup(0, bindGroup);\n passEncoder.draw(3, 1, 0, 0);\n\n passEncoder.end();\n\n srcView = dstView;\n }\n }\n\n // If we didn't render to the source texture, finish by copying the mip results from the temporary mipmap texture\n // to the source.\n if (!renderToSource)\n {\n const mipLevelSize = {\n width: Math.ceil(texture.width / 2),\n height: Math.ceil(texture.height / 2),\n depthOrArrayLayers: arrayLayerCount,\n };\n\n for (let i = 1; i < texture.mipLevelCount; ++i)\n {\n commandEncoder.copyTextureToTexture({\n texture: mipTexture,\n mipLevel: i - 1,\n }, {\n texture,\n mipLevel: i,\n }, mipLevelSize);\n\n mipLevelSize.width = Math.ceil(mipLevelSize.width / 2);\n mipLevelSize.height = Math.ceil(mipLevelSize.height / 2);\n }\n }\n\n this.device.queue.submit([commandEncoder.finish()]);\n\n if (!renderToSource)\n {\n mipTexture.destroy();\n }\n\n return texture;\n }\n}\n"],"names":[],"mappings":"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"}