UNPKG

playcanvas

Version:

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

70 lines (69 loc) 2.12 kB
class WebgpuQuerySet { querySet; stagingBuffers = []; activeStagingBuffer = null; bytesPerSlot; constructor(device, isTimestamp, capacity) { this.device = device; this.capacity = capacity; this.bytesPerSlot = isTimestamp ? 8 : 4; const wgpu = device.wgpu; this.querySet = wgpu.createQuerySet({ type: isTimestamp ? "timestamp" : "occlusion", count: capacity }); this.queryBuffer = wgpu.createBuffer({ size: this.bytesPerSlot * capacity, usage: GPUBufferUsage.QUERY_RESOLVE | GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_SRC | GPUBufferUsage.COPY_DST }); } destroy() { this.device.deferDestroy(this.querySet); this.querySet = null; this.device.deferDestroy(this.queryBuffer); this.queryBuffer = null; this.activeStagingBuffer = null; this.stagingBuffers.forEach((stagingBuffer) => { stagingBuffer.destroy(); }); this.stagingBuffers = null; } getStagingBuffer() { let stagingBuffer = this.stagingBuffers.pop(); if (!stagingBuffer) { stagingBuffer = this.device.wgpu.createBuffer({ size: this.queryBuffer.size, usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ }); } return stagingBuffer; } resolve(count) { const device = this.device; const commandEncoder = device.getCommandEncoder(); commandEncoder.resolveQuerySet(this.querySet, 0, count, this.queryBuffer, 0); const activeStagingBuffer = this.getStagingBuffer(); this.activeStagingBuffer = activeStagingBuffer; commandEncoder.copyBufferToBuffer(this.queryBuffer, 0, activeStagingBuffer, 0, this.bytesPerSlot * count); } request(count, renderVersion) { const stagingBuffer = this.activeStagingBuffer; this.activeStagingBuffer = null; return stagingBuffer.mapAsync(GPUMapMode.READ).then(() => { const srcTimings = new BigInt64Array(stagingBuffer.getMappedRange()); const timings = []; for (let i = 0; i < count; i++) { timings.push(Number(srcTimings[i * 2 + 1] - srcTimings[i * 2]) * 1e-6); } stagingBuffer.unmap(); this.stagingBuffers?.push(stagingBuffer); return { renderVersion, timings }; }); } } export { WebgpuQuerySet };