UNPKG

playcanvas

Version:

Open-source WebGL/WebGPU 3D engine for the web

52 lines (51 loc) 1.59 kB
import { BUFFERUSAGE_COPY_DST, BUFFERUSAGE_INDIRECT } from "../constants.js"; import { StorageBuffer } from "../storage-buffer.js"; class WebgpuDrawCommands { device; gpuIndirect = null; gpuIndirectSigned = null; storage = null; constructor(device) { this.device = device; } allocate(maxCount) { if (this.gpuIndirect && this.gpuIndirect.length === 5 * maxCount) { return; } this.storage?.destroy(); this.gpuIndirect = new Uint32Array(5 * maxCount); this.gpuIndirectSigned = new Int32Array(this.gpuIndirect.buffer); this.storage = new StorageBuffer(this.device, this.gpuIndirect.byteLength, BUFFERUSAGE_INDIRECT | BUFFERUSAGE_COPY_DST); } add(i, indexOrVertexCount, instanceCount, firstIndexOrVertex, baseVertex = 0, firstInstance = 0) { const o = i * 5; this.gpuIndirect[o + 0] = indexOrVertexCount; this.gpuIndirect[o + 1] = instanceCount; this.gpuIndirect[o + 2] = firstIndexOrVertex; this.gpuIndirectSigned[o + 3] = baseVertex; this.gpuIndirect[o + 4] = firstInstance; } update(count) { if (this.storage && count > 0) { const used = count * 5; this.storage.write(0, this.gpuIndirect, 0, used); } let totalPrimitives = 0; if (this.gpuIndirect && count > 0) { for (let d = 0; d < count; d++) { const offset = d * 5; const indexOrVertexCount = this.gpuIndirect[offset + 0]; const instanceCount = this.gpuIndirect[offset + 1]; totalPrimitives += indexOrVertexCount * instanceCount; } } return totalPrimitives; } destroy() { this.storage?.destroy(); this.storage = null; } } export { WebgpuDrawCommands };