UNPKG

playcanvas

Version:

PlayCanvas WebGL game engine

84 lines (81 loc) 3.3 kB
import { TRACEID_RENDER_QUEUE } from '../../../core/constants.js'; import { Debug, DebugHelper } from '../../../core/debug.js'; /** * @import { WebgpuGraphicsDevice } from './webgpu-graphics-device.js' */ /** * A WebGPU implementation of the Buffer. * * @ignore */ class WebgpuBuffer { destroy(device) { if (this.buffer) { this.buffer.destroy(); this.buffer = null; } } get initialized() { return !!this.buffer; } loseContext() {} allocate(device, size) { Debug.assert(!this.buffer, 'Buffer already allocated'); this.buffer = device.wgpu.createBuffer({ size, usage: this.usageFlags }); } /** * @param {WebgpuGraphicsDevice} device - Graphics device. * @param {*} storage - */ unlock(device, storage) { var wgpu = device.wgpu; // offset of getMappedRange must me a multiple of 8 // size of getMappedRange must be a multiple of 4 if (!this.buffer) { // size needs to be a multiple of 4 // note: based on specs, descriptor.size must be a multiple of 4 if descriptor.mappedAtCreation is true var size = storage.byteLength + 3 & -4; this.usageFlags |= GPUBufferUsage.COPY_DST; this.allocate(device, size); DebugHelper.setLabel(this.buffer, this.usageFlags & GPUBufferUsage.VERTEX ? 'VertexBuffer' : this.usageFlags & GPUBufferUsage.INDEX ? 'IndexBuffer' : this.usageFlags & GPUBufferUsage.UNIFORM ? 'UniformBuffer' : this.usageFlags & GPUBufferUsage.STORAGE ? 'StorageBuffer' : ''); // mappedAtCreation path - this could be used when the data is provided // this.buffer = device.wgpu.createBuffer({ // size: size, // usage: target, // mappedAtCreation: true // }); // const dest = new Uint8Array(this.buffer.getMappedRange()); // const src = new Uint8Array(storage.buffer ? storage.buffer : storage); // dest.set(src); // this.buffer.unmap(); } var _storage_byteOffset; // src size needs to be a multiple of 4 as well var srcOffset = (_storage_byteOffset = storage.byteOffset) != null ? _storage_byteOffset : 0; var _storage_buffer; var srcData = new Uint8Array((_storage_buffer = storage.buffer) != null ? _storage_buffer : storage, srcOffset, storage.byteLength); var data = new Uint8Array(this.buffer.size); data.set(srcData); // copy data to the gpu buffer Debug.trace(TRACEID_RENDER_QUEUE, "writeBuffer: " + this.buffer.label); wgpu.queue.writeBuffer(this.buffer, 0, data, 0, data.length); } read(device, offset, size, data) { return device.readStorageBuffer(this, offset, size, data); } write(device, bufferOffset, data, dataOffset, size) { device.writeStorageBuffer(this, bufferOffset, data, dataOffset, size); } clear(device, offset, size) { device.clearStorageBuffer(this, offset, size); } constructor(usageFlags = 0){ /** * @type {GPUBuffer|null} * @private */ this.buffer = null; this.usageFlags = 0; this.usageFlags = usageFlags; } } export { WebgpuBuffer };