in src/webgpu/api/operation/memory_sync/operation_context_helper.ts [183:277]
ensureContext(context: OperationContext) {
// Find the common ancestor. So we can transition from currentContext -> context.
const ancestorContext =
kOperationContexts[
Math.min(
kOperationContexts.indexOf(context),
kOperationContexts.indexOf(this.currentContext)
)
];
// Pop the context until we're at the common ancestor.
while (this.currentContext !== ancestorContext) {
// About to pop the render pass encoder. Execute any outstanding render bundles.
if (this.currentContext === 'render-pass-encoder') {
this.flushRenderBundles();
}
const result = this.popContext();
if (result) {
if (result instanceof GPURenderBundle) {
this.renderBundles.push(result);
} else {
this.commandBuffers.push(result);
}
}
}
if (this.currentContext === context) {
return;
}
switch (context) {
case 'queue':
unreachable();
break;
case 'command-encoder':
assert(this.currentContext === 'queue');
this.commandEncoder = this.device.createCommandEncoder();
break;
case 'compute-pass-encoder':
switch (this.currentContext) {
case 'queue':
this.commandEncoder = this.device.createCommandEncoder();
// fallthrough
case 'command-encoder':
assert(this.commandEncoder !== undefined);
this.computePassEncoder = this.commandEncoder.beginComputePass();
break;
case 'compute-pass-encoder':
case 'render-bundle-encoder':
case 'render-pass-encoder':
unreachable();
}
break;
case 'render-pass-encoder':
switch (this.currentContext) {
case 'queue':
this.commandEncoder = this.device.createCommandEncoder();
// fallthrough
case 'command-encoder':
assert(this.commandEncoder !== undefined);
this.renderPassEncoder = this.commandEncoder.beginRenderPass({
colorAttachments: [this.makeDummyAttachment()],
});
break;
case 'render-pass-encoder':
case 'render-bundle-encoder':
case 'compute-pass-encoder':
unreachable();
}
break;
case 'render-bundle-encoder':
switch (this.currentContext) {
case 'queue':
this.commandEncoder = this.device.createCommandEncoder();
// fallthrough
case 'command-encoder':
assert(this.commandEncoder !== undefined);
this.renderPassEncoder = this.commandEncoder.beginRenderPass({
colorAttachments: [this.makeDummyAttachment()],
});
// fallthrough
case 'render-pass-encoder':
this.renderBundleEncoder = this.device.createRenderBundleEncoder({
colorFormats: [this.kTextureFormat],
});
break;
case 'render-bundle-encoder':
case 'compute-pass-encoder':
unreachable();
}
break;
}
this.currentContext = context;
}