149 lines
8.1 KiB
JavaScript
149 lines
8.1 KiB
JavaScript
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
|