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 • 16.6 kB
Source Map (JSON)
{"version":3,"file":"GpuEncoderSystem.mjs","sources":["../../../../src/rendering/renderers/gpu/GpuEncoderSystem.ts"],"sourcesContent":["import { ExtensionType } from '../../../extensions/Extensions';\n\nimport type { Rectangle } from '../../../maths/shapes/Rectangle';\nimport type { Buffer } from '../shared/buffer/Buffer';\nimport type { Topology } from '../shared/geometry/const';\nimport type { Geometry } from '../shared/geometry/Geometry';\nimport type { Shader } from '../shared/shader/Shader';\nimport type { UniformGroup } from '../shared/shader/UniformGroup';\nimport type { State } from '../shared/state/State';\nimport type { System } from '../shared/system/System';\nimport type { GPU } from './GpuDeviceSystem';\nimport type { GpuRenderTarget } from './renderTarget/GpuRenderTarget';\nimport type { GpuRenderTargetAdaptor } from './renderTarget/GpuRenderTargetAdaptor';\nimport type { BindGroup } from './shader/BindGroup';\nimport type { GpuProgram } from './shader/GpuProgram';\nimport type { WebGPURenderer } from './WebGPURenderer';\n\n/**\n * The system that handles encoding commands for the GPU.\n * @category rendering\n * @advanced\n */\nexport class GpuEncoderSystem implements System\n{\n /** @ignore */\n public static extension = {\n type: [ExtensionType.WebGPUSystem],\n name: 'encoder',\n priority: 1\n } as const;\n\n public commandEncoder: GPUCommandEncoder;\n public renderPassEncoder: GPURenderPassEncoder;\n public commandFinished: Promise<void>;\n\n private _resolveCommandFinished: (value: void) => void;\n\n private _gpu: GPU;\n private _boundBindGroup: Record<number, BindGroup> = Object.create(null);\n private _boundVertexBuffer: Record<number, Buffer> = Object.create(null);\n private _boundIndexBuffer: Buffer;\n private _boundPipeline: GPURenderPipeline;\n\n private readonly _renderer: WebGPURenderer;\n\n constructor(renderer: WebGPURenderer)\n {\n this._renderer = renderer;\n }\n\n public renderStart(): void\n {\n this.commandFinished = new Promise((resolve) =>\n {\n this._resolveCommandFinished = resolve;\n });\n\n // generate a render pass description..\n // create an encoder..\n this.commandEncoder = this._renderer.gpu.device.createCommandEncoder();\n }\n\n public beginRenderPass(gpuRenderTarget: GpuRenderTarget)\n {\n this.endRenderPass();\n\n this._clearCache();\n\n this.renderPassEncoder = this.commandEncoder.beginRenderPass(gpuRenderTarget.descriptor);\n }\n\n public endRenderPass()\n {\n if (this.renderPassEncoder)\n {\n this.renderPassEncoder.end();\n }\n\n this.renderPassEncoder = null;\n }\n\n public setViewport(viewport: Rectangle): void\n {\n this.renderPassEncoder.setViewport(viewport.x, viewport.y, viewport.width, viewport.height, 0, 1);\n }\n\n public setPipelineFromGeometryProgramAndState(\n geometry: Geometry,\n program: GpuProgram,\n state: any,\n topology?: Topology,\n ): void\n {\n const pipeline = this._renderer.pipeline.getPipeline(geometry, program, state, topology);\n\n this.setPipeline(pipeline);\n }\n\n public setPipeline(pipeline: GPURenderPipeline)\n {\n if (this._boundPipeline === pipeline) return;\n this._boundPipeline = pipeline;\n\n this.renderPassEncoder.setPipeline(pipeline);\n }\n\n private _setVertexBuffer(index: number, buffer: Buffer)\n {\n if (this._boundVertexBuffer[index] === buffer) return;\n\n this._boundVertexBuffer[index] = buffer;\n\n this.renderPassEncoder.setVertexBuffer(index, this._renderer.buffer.updateBuffer(buffer));\n }\n\n private _setIndexBuffer(buffer: Buffer)\n {\n if (this._boundIndexBuffer === buffer) return;\n\n this._boundIndexBuffer = buffer;\n\n const indexFormat = buffer.data.BYTES_PER_ELEMENT === 2 ? 'uint16' : 'uint32';\n\n this.renderPassEncoder.setIndexBuffer(this._renderer.buffer.updateBuffer(buffer), indexFormat);\n }\n\n public resetBindGroup(index: number)\n {\n this._boundBindGroup[index] = null;\n }\n\n public setBindGroup(index: number, bindGroup: BindGroup, program: GpuProgram)\n {\n if (this._boundBindGroup[index] === bindGroup) return;\n this._boundBindGroup[index] = bindGroup;\n\n bindGroup._touch(this._renderer.gc.now, this._renderer.tick);\n\n // TODO getting the bind group works as it looks at th e assets and generates a key\n // should this just be hidden behind a dirty flag?\n const gpuBindGroup = this._renderer.bindGroup.getBindGroup(bindGroup, program, index);\n\n // mark each item as having been used..\n this.renderPassEncoder.setBindGroup(index, gpuBindGroup);\n }\n\n public setGeometry(geometry: Geometry, program: GpuProgram)\n {\n // when binding a buffers for geometry, there is no need to bind a buffer more than once if it is interleaved.\n // which is often the case for Pixi. This is a performance optimisation.\n // Instead of looping through the attributes, we instead call getBufferNamesToBind\n // which returns a list of buffer names that need to be bound.\n // we can then loop through this list and bind the buffers.\n // essentially only binding a single time for any buffers that are interleaved.\n const buffersToBind = this._renderer.pipeline.getBufferNamesToBind(geometry, program);\n\n for (const i in buffersToBind)\n {\n this._setVertexBuffer(parseInt(i, 10), geometry.attributes[buffersToBind[i]].buffer);\n }\n\n if (geometry.indexBuffer)\n {\n this._setIndexBuffer(geometry.indexBuffer);\n }\n }\n\n private _setShaderBindGroups(shader: Shader, skipSync?: boolean)\n {\n for (const i in shader.groups)\n {\n const bindGroup = shader.groups[i] as BindGroup;\n\n // update any uniforms?\n if (!skipSync)\n {\n this._syncBindGroup(bindGroup);\n }\n\n this.setBindGroup(i as unknown as number, bindGroup, shader.gpuProgram);\n }\n }\n\n private _syncBindGroup(bindGroup: BindGroup)\n {\n for (const j in bindGroup.resources)\n {\n const resource = bindGroup.resources[j];\n\n if ((resource as UniformGroup).isUniformGroup)\n {\n this._renderer.ubo.updateUniformGroup(resource as UniformGroup);\n }\n }\n }\n\n public draw(options: {\n geometry: Geometry;\n shader: Shader;\n state?: State;\n topology?: Topology;\n size?: number;\n start?: number;\n instanceCount?: number;\n skipSync?: boolean;\n })\n {\n const { geometry, shader, state, topology, size, start, instanceCount, skipSync } = options;\n\n this.setPipelineFromGeometryProgramAndState(geometry, shader.gpuProgram, state, topology);\n this.setGeometry(geometry, shader.gpuProgram);\n this._setShaderBindGroups(shader, skipSync);\n\n if (geometry.indexBuffer)\n {\n this.renderPassEncoder.drawIndexed(\n size || geometry.indexBuffer.data.length,\n instanceCount ?? geometry.instanceCount,\n start || 0\n );\n }\n else\n {\n this.renderPassEncoder.draw(size || geometry.getSize(), instanceCount ?? geometry.instanceCount, start || 0);\n }\n }\n\n public finishRenderPass()\n {\n if (this.renderPassEncoder)\n {\n this.renderPassEncoder.end();\n this.renderPassEncoder = null;\n }\n }\n\n public postrender()\n {\n this.finishRenderPass();\n\n this._gpu.device.queue.submit([this.commandEncoder.finish()]);\n\n this._resolveCommandFinished();\n\n this.commandEncoder = null;\n }\n\n // restores a render pass if finishRenderPass was called\n // not optimised as really used for debugging!\n // used when we want to stop drawing and log a texture..\n public restoreRenderPass()\n {\n const descriptor = (this._renderer.renderTarget.adaptor as GpuRenderTargetAdaptor).getDescriptor(\n this._renderer.renderTarget.renderTarget,\n false,\n [0, 0, 0, 1],\n this._renderer.renderTarget.mipLevel,\n this._renderer.renderTarget.layer,\n );\n\n this.renderPassEncoder = this.commandEncoder.beginRenderPass(descriptor);\n\n const boundPipeline = this._boundPipeline;\n const boundVertexBuffer = { ...this._boundVertexBuffer };\n const boundIndexBuffer = this._boundIndexBuffer;\n const boundBindGroup = { ...this._boundBindGroup };\n\n this._clearCache();\n\n const viewport = this._renderer.renderTarget.viewport;\n\n this.renderPassEncoder.setViewport(viewport.x, viewport.y, viewport.width, viewport.height, 0, 1);\n\n // reinstate the cache...\n\n this.setPipeline(boundPipeline);\n\n for (const i in boundVertexBuffer)\n {\n this._setVertexBuffer(i as unknown as number, boundVertexBuffer[i]);\n }\n\n for (const i in boundBindGroup)\n {\n this.setBindGroup(i as unknown as number, boundBindGroup[i], null);\n }\n\n this._setIndexBuffer(boundIndexBuffer);\n }\n\n private _clearCache()\n {\n for (let i = 0; i < 16; i++)\n {\n this._boundBindGroup[i] = null;\n this._boundVertexBuffer[i] = null;\n }\n\n this._boundIndexBuffer = null;\n this._boundPipeline = null;\n }\n\n public destroy()\n {\n (this._renderer as null) = null;\n this._gpu = null;\n this._boundBindGroup = null;\n this._boundVertexBuffer = null;\n this._boundIndexBuffer = null;\n this._boundPipeline = null;\n }\n\n protected contextChange(gpu: GPU): void\n {\n this._gpu = gpu;\n }\n}\n"],"names":[],"mappings":"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"}