playcanvas
Version:
Open-source WebGL/WebGPU 3D engine for the web
76 lines (75 loc) • 2.87 kB
JavaScript
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
};