typegpu
Version:
A thin layer between JS and WebGPU/WGSL that improves development experience and allows for faster iteration.
57 lines (56 loc) • 2.06 kB
JavaScript
import { $internal } from "../../shared/symbols.js";
import { logger } from "../../tgpuLogger.js";
import { INTERNAL_beginComputePass, } from "./computePass.js";
import { INTERNAL_beginRenderPass, } from "./renderPass.js";
export function INTERNAL_createCommandEncoder(root, descriptor) {
return new TgpuCommandEncoderImpl(root, root.device.createCommandEncoder(descriptor), false);
}
export function INTERNAL_adoptCommandEncoder(root, rawEncoder) {
return new TgpuCommandEncoderImpl(root, rawEncoder, true);
}
// --------------
// Implementation
// --------------
class TgpuCommandEncoderImpl {
[$internal];
resourceType = 'command-encoder';
constructor(root, rawEncoder, adopted) {
this[$internal] = {
rawEncoder,
root,
adopted,
beforeFinish: new Map(),
afterSubmit: new Map(),
};
}
beginRenderPass(descriptor) {
return INTERNAL_beginRenderPass(this, descriptor);
}
beginComputePass(descriptor) {
return INTERNAL_beginComputePass(this, descriptor);
}
#recordPendingCommands() {
const { rawEncoder, beforeFinish } = this[$internal];
for (const record of beforeFinish.values()) {
record(rawEncoder);
}
beforeFinish.clear();
}
submit() {
const { rawEncoder, root, afterSubmit } = this[$internal];
this.#recordPendingCommands();
root.device.queue.submit([rawEncoder.finish()]);
for (const hook of afterSubmit.values()) {
hook();
}
afterSubmit.clear();
}
finish(descriptor) {
const { rawEncoder, root, afterSubmit } = this[$internal];
this.#recordPendingCommands();
if (afterSubmit.size > 0) {
logger.warnOnce('suspicious', root, 'finishWithPendingWork', 'Shader console.log output and performance callbacks do not fire for command buffers produced by encoder.finish(). Use encoder.submit() instead.');
}
return rawEncoder.finish(descriptor);
}
}