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 24.2 kB
{"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;\n// colorTargetCount = 4; // 2 bits // 4 states // value 0-3; // supports 1-4 color targets\nfunction getGlobalStateKey(\n stencilStateId: number,\n multiSampleCount: number,\n colorMask: number,\n renderTarget: number,\n colorTargetCount: number,\n): number\n{\n return (colorMask << 8) // Allocate the 4 bits for colorMask at the top\n | (stencilStateId << 5) // Next 3 bits for stencilStateId\n | (renderTarget << 3) // 2 bits for renderTarget\n | (colorTargetCount << 1) // 2 bits for colorTargetCount\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 * @category rendering\n * @advanced\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 private readonly _bindingNamesCache: Record<string, Record<string, string>> = 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 _colorTargetCount = 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 this._colorTargetCount = renderTarget.colorTargetCount;\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 ||= geometry.topology;\n\n // now we have set the Ids - the key is different...\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, this._colorTargetCount);\n\n // Apply write mask to all color targets\n const writeMask = this._stencilMode === STENCIL_MODES.RENDERING_MASK_ADD ? 0 : this._colorMask;\n\n for (let i = 0; i < blendModes.length; i++)\n {\n blendModes[i].writeMask = writeMask;\n }\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 /**\n * Returns a hash of buffer names mapped to bind locations.\n * This is used to bind the correct buffer to the correct location in the shader.\n * @param geometry - The geometry where to get the buffer names\n * @param program - The program where to get the buffer names\n * @returns An object of buffer names mapped to the bind location.\n */\n public getBufferNamesToBind(geometry: Geometry, program: GpuProgram): Record<string, string>\n {\n const key = (geometry._layoutKey << 16) | program._attributeLocationsKey;\n\n if (this._bindingNamesCache[key]) return this._bindingNamesCache[key];\n\n const data = this._createVertexBufferLayouts(geometry, program);\n\n // now map the data to the buffers..\n const bufferNamesToBind: Record<string, string> = Object.create(null);\n\n const attributeData = program.attributeData;\n\n for (let i = 0; i < data.length; i++)\n {\n const attributes = Object.values(data[i].attributes);\n\n const shaderLocation = attributes[0].shaderLocation;\n\n for (const j in attributeData)\n {\n if (attributeData[j].location === shaderLocation)\n {\n bufferNamesToBind[i] = j;\n break;\n }\n }\n }\n\n this._bindingNamesCache[key] = bufferNamesToBind;\n\n return bufferNamesToBind;\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 this._colorTargetCount,\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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"}