shadow$provide.module$node_modules$pixi_DOT_js$lib$rendering$renderers$gpu$pipeline$PipelineSystem = function(global, require, module, exports) { global = require("module$node_modules$pixi_DOT_js$lib$extensions$Extensions"); var warn = require("module$node_modules$pixi_DOT_js$lib$utils$logging$warn"), ensureAttributes = require("module$node_modules$pixi_DOT_js$lib$rendering$renderers$gl$shader$program$ensureAttributes"), _const = require("module$node_modules$pixi_DOT_js$lib$rendering$renderers$shared$state$const"), createIdFromString = require("module$node_modules$pixi_DOT_js$lib$rendering$renderers$shared$utils$createIdFromString"), GpuStencilModesToPixi = require("module$node_modules$pixi_DOT_js$lib$rendering$renderers$gpu$state$GpuStencilModesToPixi"); "use strict"; const topologyStringToId = {"point-list":0, "line-list":1, "line-strip":2, "triangle-list":3, "triangle-strip":4}; class PipelineSystem { constructor(renderer) { this._moduleCache = Object.create(null); this._bufferLayoutsCache = Object.create(null); this._bindingNamesCache = Object.create(null); this._pipeCache = Object.create(null); this._pipeStateCaches = Object.create(null); this._colorMask = 15; this._colorTargetCount = this._multisampleCount = 1; this._renderer = renderer; } contextChange(gpu) { this._gpu = gpu; this.setStencilMode(_const.STENCIL_MODES.DISABLED); this._updatePipeHash(); } setMultisampleCount(multisampleCount) { this._multisampleCount !== multisampleCount && (this._multisampleCount = multisampleCount, this._updatePipeHash()); } setRenderTarget(renderTarget) { this._multisampleCount = renderTarget.msaaSamples; this._depthStencilAttachment = renderTarget.descriptor.depthStencilAttachment ? 1 : 0; this._colorTargetCount = renderTarget.colorTargetCount; this._updatePipeHash(); } setColorMask(colorMask) { this._colorMask !== colorMask && (this._colorMask = colorMask, this._updatePipeHash()); } setStencilMode(stencilMode) { this._stencilMode !== stencilMode && (this._stencilMode = stencilMode, this._stencilState = GpuStencilModesToPixi.GpuStencilModesToPixi[stencilMode], this._updatePipeHash()); } setPipeline(geometry, program, state, passEncoder) { geometry = this.getPipeline(geometry, program, state); passEncoder.setPipeline(geometry); } getPipeline(geometry, program, state, topology) { geometry._layoutKey || (ensureAttributes.ensureAttributes(geometry, program.attributeData), this._generateBufferKey(geometry)); topology || (topology = geometry.topology); const key = geometry._layoutKey << 24 | program._layoutKey << 16 | state.data << 10 | state._blendModeId << 5 | topologyStringToId[topology]; if (this._pipeCache[key]) { return this._pipeCache[key]; } this._pipeCache[key] = this._createPipeline(geometry, program, state, topology); return this._pipeCache[key]; } _createPipeline(geometry, program, state, topology) { const device = this._gpu.device; geometry = this._createVertexBufferLayouts(geometry, program); const blendModes = this._renderer.state.getColorTargets(state, this._colorTargetCount); var writeMask = this._stencilMode === _const.STENCIL_MODES.RENDERING_MASK_ADD ? 0 : this._colorMask; for (let i = 0; i < blendModes.length; i++) { blendModes[i].writeMask = writeMask; } writeMask = this._renderer.shader.getProgramData(program).pipeline; program = {vertex:{module:this._getModule(program.vertex.source), entryPoint:program.vertex.entryPoint, buffers:geometry}, fragment:{module:this._getModule(program.fragment.source), entryPoint:program.fragment.entryPoint, targets:blendModes}, primitive:{topology, cullMode:state.cullMode}, layout:writeMask, multisample:{count:this._multisampleCount}, label:"PIXI Pipeline"}; this._depthStencilAttachment && (program.depthStencil = {...this._stencilState, format:"depth24plus-stencil8", depthWriteEnabled:state.depthTest, depthCompare:state.depthTest ? "less" : "always"}); return device.createRenderPipeline(program); } _getModule(code) { return this._moduleCache[code] || this._createModule(code); } _createModule(code) { this._moduleCache[code] = this._gpu.device.createShaderModule({code}); return this._moduleCache[code]; } _generateBufferKey(geometry) { var keyGen = []; let index = 0; const attributeKeys = Object.keys(geometry.attributes).sort(); for (let i = 0; i < attributeKeys.length; i++) { const attribute = geometry.attributes[attributeKeys[i]]; keyGen[index++] = attribute.offset; keyGen[index++] = attribute.format; keyGen[index++] = attribute.stride; keyGen[index++] = attribute.instance; } keyGen = keyGen.join("|"); geometry._layoutKey = createIdFromString.createIdFromString(keyGen, "geometry"); return geometry._layoutKey; } _generateAttributeLocationsKey(program) { var keyGen = []; let index = 0; const attributeKeys = Object.keys(program.attributeData).sort(); for (let i = 0; i < attributeKeys.length; i++) { const attribute = program.attributeData[attributeKeys[i]]; keyGen[index++] = attribute.location; } keyGen = keyGen.join("|"); program._attributeLocationsKey = createIdFromString.createIdFromString(keyGen, "programAttributes"); return program._attributeLocationsKey; } getBufferNamesToBind(geometry, program) { const key = geometry._layoutKey << 16 | program._attributeLocationsKey; if (this._bindingNamesCache[key]) { return this._bindingNamesCache[key]; } geometry = this._createVertexBufferLayouts(geometry, program); const bufferNamesToBind = Object.create(null); program = program.attributeData; for (let i = 0; i < geometry.length; i++) { const shaderLocation = Object.values(geometry[i].attributes)[0].shaderLocation; for (const j in program) { if (program[j].location === shaderLocation) { bufferNamesToBind[i] = j; break; } } } return this._bindingNamesCache[key] = bufferNamesToBind; } _createVertexBufferLayouts(geometry, program) { program._attributeLocationsKey || this._generateAttributeLocationsKey(program); const key = geometry._layoutKey << 16 | program._attributeLocationsKey; if (this._bufferLayoutsCache[key]) { return this._bufferLayoutsCache[key]; } const vertexBuffersLayout = []; geometry.buffers.forEach(buffer => { const bufferEntry = {arrayStride:0, stepMode:"vertex", attributes:[]}, bufferEntryAttributes = bufferEntry.attributes; for (const i in program.attributeData) { const attribute = geometry.attributes[i]; 1 !== (attribute.divisor ?? 1) && warn.warn(`Attribute ${i} has an invalid divisor value of '${attribute.divisor}'. WebGPU only supports a divisor value of 1`); attribute.buffer === buffer && (bufferEntry.arrayStride = attribute.stride, bufferEntry.stepMode = attribute.instance ? "instance" : "vertex", bufferEntryAttributes.push({shaderLocation:program.attributeData[i].location, offset:attribute.offset, format:attribute.format})); } bufferEntryAttributes.length && vertexBuffersLayout.push(bufferEntry); }); return this._bufferLayoutsCache[key] = vertexBuffersLayout; } _updatePipeHash() { const key = this._colorMask << 8 | this._stencilMode << 5 | this._depthStencilAttachment << 3 | this._colorTargetCount << 1 | this._multisampleCount; this._pipeStateCaches[key] || (this._pipeStateCaches[key] = Object.create(null)); this._pipeCache = this._pipeStateCaches[key]; } destroy() { this._bufferLayoutsCache = this._renderer = null; } } PipelineSystem.extension = {type:[global.ExtensionType.WebGPUSystem], name:"pipeline"}; exports.PipelineSystem = PipelineSystem; }; //# sourceMappingURL=module$node_modules$pixi_DOT_js$lib$rendering$renderers$gpu$pipeline$PipelineSystem.js.map