@kitware/vtk.js
Version:
Visualization Toolkit for the Web
239 lines (194 loc) • 8.01 kB
JavaScript
import { newInstance as newInstance$1, obj, get, setGet } from '../../macros.js';
import vtkWebGPUShaderCache from './ShaderCache.js';
var forwarded = ['setBindGroup', 'setIndexBuffer', 'setVertexBuffer', 'draw', 'drawIndexed']; // ----------------------------------------------------------------------------
// vtkWebGPURenderEncoder methods
// ----------------------------------------------------------------------------
function vtkWebGPURenderEncoder(publicAPI, model) {
// Set our className
model.classHierarchy.push('vtkWebGPURenderEncoder');
publicAPI.begin = function (encoder) {
model.drawCallbacks = [];
model.handle = encoder.beginRenderPass(model.description);
if (model.label) {
model.handle.pushDebugGroup(model.label);
}
};
publicAPI.end = function () {
// loop over registered pipelines and their callbacks
for (var i = 0; i < model.drawCallbacks.length; i++) {
var pStruct = model.drawCallbacks[i];
var pl = pStruct.pipeline;
publicAPI.setPipeline(pl);
for (var cb = 0; cb < pStruct.callbacks.length; cb++) {
pStruct.callbacks[cb](publicAPI);
}
}
if (model.label) {
model.handle.popDebugGroup();
}
model.handle.end();
model.boundPipeline = null;
};
publicAPI.setPipeline = function (pl) {
if (model.boundPipeline === pl) {
return;
}
model.handle.setPipeline(pl.getHandle());
var pd = pl.getPipelineDescription(); // check attachment state
if (model.colorTextureViews.length !== pd.fragment.targets.length) {
console.log("mismatched attachment counts on pipeline ".concat(pd.fragment.targets.length, " while encoder has ").concat(model.colorTextureViews.length));
console.trace();
} else {
for (var i = 0; i < model.colorTextureViews.length; i++) {
var _model$colorTextureVi;
var fmt = (_model$colorTextureVi = model.colorTextureViews[i].getTexture()) === null || _model$colorTextureVi === void 0 ? void 0 : _model$colorTextureVi.getFormat();
if (fmt && fmt !== pd.fragment.targets[i].format) {
console.log("mismatched attachments for attachment ".concat(i, " on pipeline ").concat(pd.fragment.targets[i].format, " while encoder has ").concat(fmt));
console.trace();
}
}
} // check depth buffer
if (!model.depthTextureView !== !('depthStencil' in pd)) {
console.log('mismatched depth attachments');
console.trace();
} else if (model.depthTextureView) {
var _model$depthTextureVi;
var dfmt = (_model$depthTextureVi = model.depthTextureView.getTexture()) === null || _model$depthTextureVi === void 0 ? void 0 : _model$depthTextureVi.getFormat();
if (dfmt && dfmt !== pd.depthStencil.format) {
console.log("mismatched depth attachments on pipeline ".concat(pd.depthStencil.format, " while encoder has ").concat(dfmt));
console.trace();
}
}
model.boundPipeline = pl;
};
publicAPI.replaceShaderCode = function (pipeline) {
model.replaceShaderCodeFunction(pipeline);
};
publicAPI.setColorTextureView = function (idx, view) {
if (model.colorTextureViews[idx] === view) {
return;
}
model.colorTextureViews[idx] = view;
};
publicAPI.activateBindGroup = function (bg) {
var device = model.boundPipeline.getDevice();
var midx = model.boundPipeline.getBindGroupLayoutCount(bg.getLabel());
model.handle.setBindGroup(midx, bg.getBindGroup(device)); // verify bind group layout matches
var bgl1 = device.getBindGroupLayoutDescription(bg.getBindGroupLayout(device));
var bgl2 = device.getBindGroupLayoutDescription(model.boundPipeline.getBindGroupLayout(midx));
if (bgl1 !== bgl2) {
console.log("renderEncoder ".concat(model.pipelineHash, " mismatched bind group layouts bind group has\n").concat(bgl1, "\n versus pipeline\n").concat(bgl2, "\n"));
console.trace();
}
};
publicAPI.attachTextureViews = function () {
// for each texture create a view if we do not already have one
for (var i = 0; i < model.colorTextureViews.length; i++) {
if (!model.description.colorAttachments[i]) {
model.description.colorAttachments[i] = {
view: model.colorTextureViews[i].getHandle()
};
} else {
model.description.colorAttachments[i].view = model.colorTextureViews[i].getHandle();
}
}
if (model.depthTextureView) {
model.description.depthStencilAttachment.view = model.depthTextureView.getHandle();
}
}; // register pipeline callbacks from a mapper
publicAPI.registerDrawCallback = function (pipeline, cb) {
// if there is a matching pipeline just add the cb
for (var i = 0; i < model.drawCallbacks.length; i++) {
if (model.drawCallbacks[i].pipeline === pipeline) {
model.drawCallbacks[i].callbacks.push(cb);
return;
}
}
model.drawCallbacks.push({
pipeline: pipeline,
callbacks: [cb]
});
}; // simple forwarders
var _loop = function _loop(i) {
publicAPI[forwarded[i]] = function () {
var _model$handle;
return (_model$handle = model.handle)[forwarded[i]].apply(_model$handle, arguments);
};
};
for (var i = 0; i < forwarded.length; i++) {
_loop(i);
}
} // ----------------------------------------------------------------------------
// Object factory
// ----------------------------------------------------------------------------
var DEFAULT_VALUES = {
description: null,
handle: null,
boundPipeline: null,
pipelineHash: null,
pipelineSettings: null,
replaceShaderCodeFunction: null,
depthTextureView: null,
label: null
}; // ----------------------------------------------------------------------------
function extend(publicAPI, model) {
var initialValues = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
Object.assign(model, DEFAULT_VALUES, initialValues); // Build VTK API
obj(publicAPI, model);
model.description = {
colorAttachments: [{
view: undefined,
loadOp: 'load',
storeOp: 'store'
}],
depthStencilAttachment: {
view: undefined,
depthLoadOp: 'clear',
depthClearValue: 0.0,
depthStoreOp: 'store'
}
}; // default shader code just writes out the computedColor
model.replaceShaderCodeFunction = function (pipeline) {
var fDesc = pipeline.getShaderDescription('fragment');
fDesc.addOutput('vec4<f32>', 'outColor');
var code = fDesc.getCode();
code = vtkWebGPUShaderCache.substitute(code, '//VTK::RenderEncoder::Impl', ['output.outColor = computedColor;']).result;
fDesc.setCode(code);
}; // default pipeline settings
model.pipelineSettings = {
primitive: {
cullMode: 'none'
},
depthStencil: {
depthWriteEnabled: true,
depthCompare: 'greater-equal',
format: 'depth32float'
},
fragment: {
targets: [{
format: 'rgba16float',
blend: {
color: {
srcFactor: 'src-alpha',
dstFactor: 'one-minus-src-alpha'
},
alpha: {
srcfactor: 'one',
dstFactor: 'one-minus-src-alpha'
}
}
}]
}
};
model.colorTextureViews = [];
get(publicAPI, model, ['boundPipeline', 'colorTextureViews']);
setGet(publicAPI, model, ['depthTextureView', 'description', 'handle', 'label', 'pipelineHash', 'pipelineSettings', 'replaceShaderCodeFunction']); // For more macro methods, see "Sources/macros.js"
// Object specific methods
vtkWebGPURenderEncoder(publicAPI, model);
} // ----------------------------------------------------------------------------
var newInstance = newInstance$1(extend, 'vtkWebGPURenderEncoder'); // ----------------------------------------------------------------------------
var vtkWebGPURenderEncoder$1 = {
newInstance: newInstance,
extend: extend
};
export { vtkWebGPURenderEncoder$1 as default, extend, newInstance };