UNPKG

playcanvas

Version:

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

76 lines (75 loc) 2.87 kB
var __defProp = Object.defineProperty; var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value); import { DebugHelper } from "../../../core/debug.js"; import { DebugGraphics } from "../debug-graphics.js"; import { DynamicBuffers } from "../dynamic-buffers.js"; import { WebgpuDynamicBuffer } from "./webgpu-dynamic-buffer.js"; class WebgpuDynamicBuffers extends DynamicBuffers { constructor() { super(...arguments); /** * Staging buffers which are getting copied over to gpu buffers in the command buffer waiting * to be submitted. When those command buffers are submitted, we can mapAsync these staging * buffers for reuse. * * @type {WebgpuDynamicBuffer[]} */ __publicField(this, "pendingStagingBuffers", []); } createBuffer(device, size, isStaging) { return new WebgpuDynamicBuffer(device, size, isStaging); } /** * Submit all used buffers to the device. */ submit() { super.submit(); const count = this.usedBuffers.length; if (count) { const device = this.device; const gpuBuffers = this.gpuBuffers; const commandEncoder = device.wgpu.createCommandEncoder(); DebugHelper.setLabel(commandEncoder, "DynamicBuffersSubmit"); DebugGraphics.pushGpuMarker(device, "DynamicBuffersSubmit"); for (let i = count - 1; i >= 0; i--) { const usedBuffer = this.usedBuffers[i]; const { stagingBuffer, gpuBuffer, offset, size } = usedBuffer; const src = stagingBuffer.buffer; src.unmap(); commandEncoder.copyBufferToBuffer(src, offset, gpuBuffer.buffer, offset, size); gpuBuffers.push(gpuBuffer); } DebugGraphics.popGpuMarker(device); const cb = commandEncoder.finish(); DebugHelper.setLabel(cb, "DynamicBuffers"); device.addCommandBuffer(cb, true); for (let i = 0; i < count; i++) { const stagingBuffer = this.usedBuffers[i].stagingBuffer; this.pendingStagingBuffers.push(stagingBuffer); } this.usedBuffers.length = 0; } } /** * Called when all scheduled command buffers are submitted to the device. */ onCommandBuffersSubmitted() { const count = this.pendingStagingBuffers.length; if (count) { for (let i = 0; i < count; i++) { const stagingBuffer = this.pendingStagingBuffers[i]; stagingBuffer.buffer.mapAsync(GPUMapMode.WRITE).then(() => { if (this.stagingBuffers) { stagingBuffer.onAvailable(); this.stagingBuffers.push(stagingBuffer); } }); } this.pendingStagingBuffers.length = 0; } } } export { WebgpuDynamicBuffers };