UNPKG

playcanvas

Version:

PlayCanvas WebGL game engine

133 lines (130 loc) 5.26 kB
import { Debug, DebugHelper } from '../../../core/debug.js'; import { WebgpuDebug } from './webgpu-debug.js'; /** * @import { BindGroup } from '../bind-group.js' * @import { WebgpuGraphicsDevice } from './webgpu-graphics-device.js' * @import { WebgpuTexture } from './webgpu-texture.js' */ /** * A WebGPU implementation of the BindGroup, which is a wrapper over GPUBindGroup. * * @ignore */ class WebgpuBindGroup { update(bindGroup) { this.destroy(); var device = bindGroup.device; /** @type {GPUBindGroupDescriptor} */ var desc = this.createDescriptor(device, bindGroup); WebgpuDebug.validate(device); this.bindGroup = device.wgpu.createBindGroup(desc); WebgpuDebug.end(device, 'BindGroup creation', { debugFormat: this.debugFormat, desc: desc, format: bindGroup.format, bindGroup: bindGroup }); } destroy() { this.bindGroup = null; } /** * Creates a bind group descriptor in WebGPU format * * @param {WebgpuGraphicsDevice} device - Graphics device. * @param {BindGroup} bindGroup - Bind group to create the * descriptor for. * @returns {object} - Returns the generated descriptor of type GPUBindGroupDescriptor, which * can be used to create a GPUBindGroup */ createDescriptor(device, bindGroup) { // Note: This needs to match WebgpuBindGroupFormat.createDescriptor var entries = []; var format = bindGroup.format; Debug.call(()=>{ this.debugFormat = ''; }); // uniform buffers var uniformBufferFormats = bindGroup.format.uniformBufferFormats; bindGroup.uniformBuffers.forEach((ub, i)=>{ var slot = uniformBufferFormats[i].slot; var buffer = ub.persistent ? ub.impl.buffer : ub.allocation.gpuBuffer.buffer; Debug.assert(buffer, 'NULL uniform buffer cannot be used by the bind group'); Debug.call(()=>{ this.debugFormat += "" + slot + ": UB\n"; }); entries.push({ binding: slot, resource: { buffer: buffer, offset: 0, size: ub.format.byteSize } }); }); // textures var textureFormats = bindGroup.format.textureFormats; bindGroup.textures.forEach((tex, textureIndex)=>{ /** @type {WebgpuTexture} */ var wgpuTexture = tex.impl; var textureFormat = format.textureFormats[textureIndex]; var slot = textureFormats[textureIndex].slot; // texture var view = wgpuTexture.getView(device); Debug.assert(view, 'NULL texture view cannot be used by the bind group'); Debug.call(()=>{ this.debugFormat += slot + ": " + bindGroup.format.textureFormats[textureIndex].name + "\n"; }); entries.push({ binding: slot, resource: view }); // sampler if (textureFormat.hasSampler) { var sampler = wgpuTexture.getSampler(device, textureFormat.sampleType); Debug.assert(sampler, 'NULL sampler cannot be used by the bind group'); Debug.call(()=>{ this.debugFormat += slot + 1 + ": " + sampler.label + "\n"; }); entries.push({ binding: slot + 1, resource: sampler }); } }); // storage textures var storageTextureFormats = bindGroup.format.storageTextureFormats; bindGroup.storageTextures.forEach((tex, textureIndex)=>{ /** @type {WebgpuTexture} */ var wgpuTexture = tex.impl; var slot = storageTextureFormats[textureIndex].slot; // texture var view = wgpuTexture.getView(device); Debug.assert(view, 'NULL texture view cannot be used by the bind group'); Debug.call(()=>{ this.debugFormat += slot + ": " + bindGroup.format.storageTextureFormats[textureIndex].name + "\n"; }); entries.push({ binding: slot, resource: view }); }); // storage buffers var storageBufferFormats = bindGroup.format.storageBufferFormats; bindGroup.storageBuffers.forEach((buffer, bufferIndex)=>{ /** @type {GPUBuffer} */ var wgpuBuffer = buffer.impl.buffer; var slot = storageBufferFormats[bufferIndex].slot; Debug.assert(wgpuBuffer, 'NULL storage buffer cannot be used by the bind group'); Debug.call(()=>{ this.debugFormat += "" + slot + ": SB\n"; }); entries.push({ binding: slot, resource: { buffer: wgpuBuffer } }); }); var desc = { layout: bindGroup.format.impl.bindGroupLayout, entries: entries }; DebugHelper.setLabel(desc, bindGroup.name); return desc; } } export { WebgpuBindGroup };