{"version":3,"file":"PipelineSystem.mjs","sources":["../../../../../src/rendering/renderers/gpu/pipeline/PipelineSystem.ts"],"sourcesContent":["import { ExtensionType } from '../../../../extensions/Extensions';\nimport { warn } from '../../../../utils/logging/warn';\nimport { ensureAttributes } from '../../gl/shader/program/ensureAttributes';\nimport { STENCIL_MODES } from '../../shared/state/const';\nimport { createIdFromString } from '../../shared/utils/createIdFromString';\nimport { GpuStencilModesToPixi } from '../state/GpuStencilModesToPixi';\n\nimport type { Topology } from '../../shared/geometry/const';\nimport type { Geometry } from '../../shared/geometry/Geometry';\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 { GpuProgram } from '../shader/GpuProgram';\nimport type { StencilState } from '../state/GpuStencilModesToPixi';\nimport type { WebGPURenderer } from '../WebGPURenderer';\n\nconst topologyStringToId = {\n    'point-list': 0,\n    'line-list': 1,\n    'line-strip': 2,\n    'triangle-list': 3,\n    'triangle-strip': 4,\n};\n\n// geometryLayouts = 256; // 8 bits // 256 states // value 0-255;\n// shaderKeys = 256; // 8 bits // 256 states // value 0-255;\n// state = 64; // 6 bits // 64 states // value 0-63;\n// blendMode = 32; // 5 bits // 32 states // value 0-31;\n// topology = 8; // 3 bits // 8 states // value 0-7;\nfunction getGraphicsStateKey(\n    geometryLayout: number,\n    shaderKey: number,\n    state: number,\n    blendMode: number,\n    topology: number,\n): number\n{\n    return (geometryLayout << 24) // Allocate the 8 bits for geometryLayouts at the top\n         | (shaderKey << 16) // Next 8 bits for shaderKeys\n         | (state << 10) // 6 bits for state\n         | (blendMode << 5) // 5 bits for blendMode\n         | topology; // And 3 bits for topology at the least significant position\n}\n\n// colorMask = 16;// 4 bits // 16 states // value 0-15;\n// stencilState = 8; // 3 bits // 8 states // value 0-7;\n// renderTarget = 1; // 2 bit // 3 states // value 0-3; // none, stencil, depth, depth-stencil\n// multiSampleCount = 1; // 1 bit // 2 states // value 0-1;\nfunction getGlobalStateKey(\n    stencilStateId: number,\n    multiSampleCount: number,\n    colorMask: number,\n    renderTarget: number,\n): number\n{\n    return (colorMask << 6) // Allocate the 4 bits for colorMask at the top\n         | (stencilStateId << 3) // Next 3 bits for stencilStateId\n         | (renderTarget << 1) // 2 bits for renderTarget\n         | multiSampleCount; // And 1 bit for multiSampleCount at the least significant position\n}\n\ntype PipeHash = Record<number, GPURenderPipeline>;\n\n/**\n * A system that creates and manages the GPU pipelines.\n *\n * Caching Mechanism: At its core, the system employs a two-tiered caching strategy to minimize\n * the redundant creation of GPU pipelines (or \"pipes\"). This strategy is based on generating unique\n * keys that represent the state of the graphics settings and the specific requirements of the\n * item being rendered. By caching these pipelines, subsequent draw calls with identical configurations\n * can reuse existing pipelines instead of generating new ones.\n *\n * State Management: The system differentiates between \"global\" state properties (like color masks\n * and stencil masks, which do not change frequently) and properties that may vary between draw calls\n * (such as geometry, shaders, and blend modes). Unique keys are generated for both these categories\n * using getStateKey for global state and getGraphicsStateKey for draw-specific settings. These keys are\n * then then used to caching the pipe. The next time we need a pipe we can check\n * the cache by first looking at the state cache and then the pipe cache.\n * @memberof rendering\n */\nexport class PipelineSystem implements System\n{\n    /** @ignore */\n    public static extension = {\n        type: [ExtensionType.WebGPUSystem],\n        name: 'pipeline',\n    } as const;\n    private readonly _renderer: WebGPURenderer;\n\n    protected CONTEXT_UID: number;\n\n    private _moduleCache: Record<string, GPUShaderModule> = Object.create(null);\n    private _bufferLayoutsCache: Record<number, GPUVertexBufferLayout[]> = Object.create(null);\n\n    private _pipeCache: PipeHash = Object.create(null);\n    private readonly _pipeStateCaches: Record<number, PipeHash> = Object.create(null);\n\n    private _gpu: GPU;\n    private _stencilState: StencilState;\n\n    private _stencilMode: STENCIL_MODES;\n    private _colorMask = 0b1111;\n    private _multisampleCount = 1;\n    private _depthStencilAttachment: 0 | 1;\n\n    constructor(renderer: WebGPURenderer)\n    {\n        this._renderer = renderer;\n    }\n\n    protected contextChange(gpu: GPU): void\n    {\n        this._gpu = gpu;\n        this.setStencilMode(STENCIL_MODES.DISABLED);\n\n        this._updatePipeHash();\n    }\n\n    public setMultisampleCount(multisampleCount: number): void\n    {\n        if (this._multisampleCount === multisampleCount) return;\n\n        this._multisampleCount = multisampleCount;\n\n        this._updatePipeHash();\n    }\n\n    public setRenderTarget(renderTarget: GpuRenderTarget)\n    {\n        this._multisampleCount = renderTarget.msaaSamples;\n        this._depthStencilAttachment = renderTarget.descriptor.depthStencilAttachment ? 1 : 0;\n\n        this._updatePipeHash();\n    }\n\n    public setColorMask(colorMask: number): void\n    {\n        if (this._colorMask === colorMask) return;\n\n        this._colorMask = colorMask;\n\n        this._updatePipeHash();\n    }\n\n    public setStencilMode(stencilMode: STENCIL_MODES): void\n    {\n        if (this._stencilMode === stencilMode) return;\n\n        this._stencilMode = stencilMode;\n        this._stencilState = GpuStencilModesToPixi[stencilMode];\n\n        this._updatePipeHash();\n    }\n\n    public setPipeline(geometry: Geometry, program: GpuProgram, state: State, passEncoder: GPURenderPassEncoder): void\n    {\n        const pipeline = this.getPipeline(geometry, program, state);\n\n        passEncoder.setPipeline(pipeline);\n    }\n\n    public getPipeline(\n        geometry: Geometry,\n        program: GpuProgram,\n        state: State,\n        topology?: Topology,\n    ): GPURenderPipeline\n    {\n        if (!geometry._layoutKey)\n        {\n            ensureAttributes(geometry, program.attributeData);\n\n            // prepare the geometry for the pipeline\n            this._generateBufferKey(geometry);\n        }\n\n        topology = topology || geometry.topology;\n\n        // now we have set the Ids - the key is different...\n        // eslint-disable-next-line max-len\n        const key = getGraphicsStateKey(\n            geometry._layoutKey,\n            program._layoutKey,\n            state.data,\n            state._blendModeId,\n            topologyStringToId[topology],\n        );\n\n        if (this._pipeCache[key]) return this._pipeCache[key];\n\n        this._pipeCache[key] = this._createPipeline(geometry, program, state, topology);\n\n        return this._pipeCache[key];\n    }\n\n    private _createPipeline(geometry: Geometry, program: GpuProgram, state: State, topology: Topology): GPURenderPipeline\n    {\n        const device = this._gpu.device;\n\n        const buffers = this._createVertexBufferLayouts(geometry, program);\n\n        const blendModes = this._renderer.state.getColorTargets(state);\n\n        blendModes[0].writeMask = this._stencilMode === STENCIL_MODES.RENDERING_MASK_ADD ? 0 : this._colorMask;\n\n        const layout = this._renderer.shader.getProgramData(program).pipeline;\n\n        const descriptor: GPURenderPipelineDescriptor = {\n            // TODO later check if its helpful to create..\n            // layout,\n            vertex: {\n                module: this._getModule(program.vertex.source),\n                entryPoint: program.vertex.entryPoint,\n                // geometry..\n                buffers,\n            },\n            fragment: {\n                module: this._getModule(program.fragment.source),\n                entryPoint: program.fragment.entryPoint,\n                targets: blendModes,\n            },\n            primitive: {\n                topology,\n                cullMode: state.cullMode,\n            },\n            layout,\n            multisample: {\n                count: this._multisampleCount,\n            },\n            // depthStencil,\n            label: `PIXI Pipeline`,\n        };\n\n        // only apply if the texture has stencil or depth\n        if (this._depthStencilAttachment)\n        {\n            // mask states..\n            descriptor.depthStencil = {\n                ...this._stencilState,\n                format: 'depth24plus-stencil8',\n                depthWriteEnabled: state.depthTest,\n                depthCompare: state.depthTest ? 'less' : 'always',\n            };\n        }\n\n        const pipeline = device.createRenderPipeline(descriptor);\n\n        return pipeline;\n    }\n\n    private _getModule(code: string): GPUShaderModule\n    {\n        return this._moduleCache[code] || this._createModule(code);\n    }\n\n    private _createModule(code: string): GPUShaderModule\n    {\n        const device = this._gpu.device;\n\n        this._moduleCache[code] = device.createShaderModule({\n            code,\n        });\n\n        return this._moduleCache[code];\n    }\n\n    private _generateBufferKey(geometry: Geometry): number\n    {\n        const keyGen = [];\n        let index = 0;\n        // generate a key..\n\n        const attributeKeys = Object.keys(geometry.attributes).sort();\n\n        for (let i = 0; i < attributeKeys.length; i++)\n        {\n            const attribute = geometry.attributes[attributeKeys[i]];\n\n            keyGen[index++] = attribute.offset;\n            keyGen[index++] = attribute.format;\n            keyGen[index++] = attribute.stride;\n            keyGen[index++] = attribute.instance;\n        }\n\n        const stringKey = keyGen.join('|');\n\n        geometry._layoutKey = createIdFromString(stringKey, 'geometry');\n\n        return geometry._layoutKey;\n    }\n\n    private _generateAttributeLocationsKey(program: GpuProgram): number\n    {\n        const keyGen = [];\n        let index = 0;\n        // generate a key..\n\n        const attributeKeys = Object.keys(program.attributeData).sort();\n\n        for (let i = 0; i < attributeKeys.length; i++)\n        {\n            const attribute = program.attributeData[attributeKeys[i]];\n\n            keyGen[index++] = attribute.location;\n        }\n\n        const stringKey = keyGen.join('|');\n\n        program._attributeLocationsKey = createIdFromString(stringKey, 'programAttributes');\n\n        return program._attributeLocationsKey;\n    }\n\n    private _createVertexBufferLayouts(geometry: Geometry, program: GpuProgram): GPUVertexBufferLayout[]\n    {\n        if (!program._attributeLocationsKey) this._generateAttributeLocationsKey(program);\n\n        const key = (geometry._layoutKey << 16) | program._attributeLocationsKey;\n\n        if (this._bufferLayoutsCache[key])\n        {\n            return this._bufferLayoutsCache[key];\n        }\n\n        const vertexBuffersLayout: GPUVertexBufferLayout[] = [];\n\n        geometry.buffers.forEach((buffer) =>\n        {\n            const bufferEntry: GPUVertexBufferLayout = {\n                arrayStride: 0,\n                stepMode: 'vertex',\n                attributes: [],\n            };\n\n            const bufferEntryAttributes = bufferEntry.attributes as GPUVertexAttribute[];\n\n            for (const i in program.attributeData)\n            {\n                const attribute = geometry.attributes[i];\n\n                if ((attribute.divisor ?? 1) !== 1)\n                {\n                    // TODO: Maybe emulate divisor with storage_buffers/float_textures?\n                    // For now just issue a warning\n                    warn(`Attribute ${i} has an invalid divisor value of '${attribute.divisor}'. `\n                        + 'WebGPU only supports a divisor value of 1');\n                }\n\n                if (attribute.buffer === buffer)\n                {\n                    bufferEntry.arrayStride = attribute.stride;\n                    bufferEntry.stepMode = attribute.instance ? 'instance' : 'vertex';\n\n                    bufferEntryAttributes.push({\n                        shaderLocation: program.attributeData[i].location,\n                        offset: attribute.offset,\n                        format: attribute.format,\n                    });\n                }\n            }\n\n            if (bufferEntryAttributes.length)\n            {\n                vertexBuffersLayout.push(bufferEntry);\n            }\n        });\n\n        this._bufferLayoutsCache[key] = vertexBuffersLayout;\n\n        return vertexBuffersLayout;\n    }\n\n    private _updatePipeHash(): void\n    {\n        const key = getGlobalStateKey(\n            this._stencilMode,\n            this._multisampleCount,\n            this._colorMask,\n            this._depthStencilAttachment\n        );\n\n        if (!this._pipeStateCaches[key])\n        {\n            this._pipeStateCaches[key] = Object.create(null);\n        }\n\n        this._pipeCache = this._pipeStateCaches[key];\n    }\n\n    public destroy(): void\n    {\n        (this._renderer as null) = null;\n        this._bufferLayoutsCache = null;\n    }\n}\n"],"names":[],"mappings":"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"}