UNPKG

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
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); } }