فهرست منبع

optional _getPipelineLayout usage, update api

Otto-Ville Lamminpää 5 سال پیش
والد
کامیت
9b209583bd
4فایلهای تغییر یافته به همراه84 افزوده شده و 79 حذف شده
  1. 1 1
      src/Engines/WebGPU/webgpuPipelineContext.ts
  2. 79 13
      src/Engines/webgpuEngine.ts
  3. 3 2
      src/LibDeclarations/webgpu.d.ts
  4. 1 63
      src/Materials/effect.ts

+ 1 - 1
src/Engines/WebGPU/webgpuPipelineContext.ts

@@ -63,7 +63,7 @@ export class WebGPUPipelineContext implements IPipelineContext {
 
     public vertexInputs: IWebGPUPipelineContextVertexInputsCache;
 
-    public bindGroupLayouts: (GPUBindGroupLayout | undefined)[];
+    public bindGroupLayouts: GPUBindGroupLayout[];
     public bindGroups: GPUBindGroup[];
 
     public renderPipeline: GPURenderPipeline;

+ 79 - 13
src/Engines/webgpuEngine.ts

@@ -298,9 +298,6 @@ export class WebGPUEngine extends Engine {
         return Promise.reject("gslang is not available.");
     }
 
-    public getDevice(): GPUDevice {
-        return this._device;
-    }
     private _initializeLimits(): void {
         // Init caps
         // TODO WEBGPU Real Capability check once limits will be working.
@@ -1987,6 +1984,65 @@ export class WebGPUEngine extends Engine {
         return inputStateDescriptor;
     }
 
+    private _getPipelineLayout(): GPUPipelineLayout {
+        const bindGroupLayouts: GPUBindGroupLayout[] = [];
+        const webgpuPipelineContext = this._currentEffect!._pipelineContext as WebGPUPipelineContext;
+
+        for (let i = 0; i < webgpuPipelineContext.orderedUBOsAndSamplers.length; i++) {
+            const setDefinition = webgpuPipelineContext.orderedUBOsAndSamplers[i];
+            if (setDefinition === undefined) {
+                const bindings: GPUBindGroupLayoutBinding[] = [];
+                const uniformsBindGroupLayout = this._device.createBindGroupLayout({
+                    bindings,
+                });
+                bindGroupLayouts[i] = uniformsBindGroupLayout;
+                continue;
+            }
+
+            const bindings: GPUBindGroupLayoutBinding[] = [];
+            for (let j = 0; j < setDefinition.length; j++) {
+                const bindingDefinition = webgpuPipelineContext.orderedUBOsAndSamplers[i][j];
+                if (bindingDefinition === undefined) {
+                    continue;
+                }
+
+                // TODO WEBGPU. Optimize shared samplers visibility for vertex/framgent.
+                if (bindingDefinition.isSampler) {
+                    bindings.push({
+                        binding: j,
+                        visibility: WebGPUConstants.GPUShaderStageBit_VERTEX | WebGPUConstants.GPUShaderStageBit_FRAGMENT,
+                        type: WebGPUConstants.GPUBindingType_sampledTexture,
+                        textureDimension: bindingDefinition.textureDimension,
+                        // TODO WEBGPU. Handle texture component type properly.
+                        // textureComponentType?: GPUTextureComponentType,
+                    }, {
+                        // TODO WEBGPU. No Magic + 1 (coming from current 1 texture 1 sampler startegy).
+                        binding: j + 1,
+                        visibility: WebGPUConstants.GPUShaderStageBit_VERTEX | WebGPUConstants.GPUShaderStageBit_FRAGMENT,
+                        type: WebGPUConstants.GPUBindingType_sampler
+                    });
+                }
+                else {
+                    bindings.push({
+                        binding: j,
+                        visibility: WebGPUConstants.GPUShaderStageBit_VERTEX | WebGPUConstants.GPUShaderStageBit_FRAGMENT,
+                        type: WebGPUConstants.GPUBindingType_uniformBuffer,
+                    });
+                }
+            }
+
+            if (bindings.length > 0) {
+                const uniformsBindGroupLayout = this._device.createBindGroupLayout({
+                    bindings,
+                });
+                bindGroupLayouts[i] = uniformsBindGroupLayout;
+            }
+        }
+
+        webgpuPipelineContext.bindGroupLayouts = bindGroupLayouts;
+        return this._device.createPipelineLayout({ bindGroupLayouts });
+    }
+
     private _getRenderPipeline(fillMode: number): GPURenderPipeline {
         // This is wrong to cache this way but workarounds the need of cache in the simple demo context.
         const gpuPipeline = this._currentEffect!._pipelineContext as WebGPUPipelineContext;
@@ -2001,7 +2057,7 @@ export class WebGPUEngine extends Engine {
         const colorStateDescriptors = this._getColorStateDescriptors();
         const stages = this._getStages();
         const inputStateDescriptor = this._getVertexInputDescriptor();
-        const pipelineLayout = this._currentEffect!.getPipelineLayout();
+        const pipelineLayout = this._getPipelineLayout();
 
         gpuPipeline.renderPipeline = this._device.createRenderPipeline({
             sampleCount: this._mainPassSampleCount,
@@ -2090,13 +2146,17 @@ export class WebGPUEngine extends Engine {
         for (let i = 0; i < webgpuPipelineContext.orderedUBOsAndSamplers.length; i++) {
             const setDefinition = webgpuPipelineContext.orderedUBOsAndSamplers[i];
             if (setDefinition === undefined) {
-                const groupLayout = bindGroupLayouts[i];
-                if (groupLayout) {
-                    bindGroups[i] = this._device.createBindGroup({
-                        layout: groupLayout,
-                        bindings: [],
-                    });
+                let groupLayout: GPUBindGroupLayout;
+                if (bindGroupLayouts && bindGroupLayouts[i]) {
+                    groupLayout = bindGroupLayouts[i];
+                }
+                else {
+                    groupLayout = webgpuPipelineContext.renderPipeline.getBindGroupLayout(i);
                 }
+                bindGroups[i] = this._device.createBindGroup({
+                    layout: groupLayout,
+                    entries: [],
+                });
                 continue;
             }
 
@@ -2148,11 +2208,17 @@ export class WebGPUEngine extends Engine {
                 }
             }
 
-            const groupLayout = bindGroupLayouts[i];
-            if (groupLayout) {
+            if (bindings.length > 0) {
+                let groupLayout: GPUBindGroupLayout;
+                if (bindGroupLayouts && bindGroupLayouts[i]) {
+                    groupLayout = bindGroupLayouts[i];
+                }
+                else {
+                    groupLayout = webgpuPipelineContext.renderPipeline.getBindGroupLayout(i);
+                }
                 bindGroups[i] = this._device.createBindGroup({
                     layout: groupLayout,
-                    bindings,
+                    entries: bindings,
                 });
             }
         }

+ 3 - 2
src/LibDeclarations/webgpu.d.ts

@@ -223,7 +223,7 @@ interface GPUBindGroupBinding {
 
 interface GPUBindGroupDescriptor extends GPUObjectDescriptorBase {
   layout: GPUBindGroupLayout;
-  bindings: GPUBindGroupBinding[];
+  entries: GPUBindGroupBinding[];
 }
 
 interface GPUBindGroupLayoutBinding {
@@ -802,8 +802,9 @@ interface GPURenderBundleEncoderDescriptor
   sampleCount?: number;
 }
 
-class GPURenderPipeline implements GPUObjectBase {
+declare class GPURenderPipeline implements GPUObjectBase {
   label: string | undefined;
+  getBindGroupLayout: (number) => GPUBindGroupLayout;
 }
 
 class GPUSampler implements GPUObjectBase {

+ 1 - 63
src/Materials/effect.ts

@@ -11,9 +11,6 @@ import { ProcessingOptions, ShaderProcessingContext } from '../Engines/Processor
 import { IMatrixLike, IVector2Like, IVector3Like, IVector4Like, IColor3Like, IColor4Like } from '../Maths/math.like';
 import { ThinEngine } from '../Engines/thinEngine';
 import { IEffectFallbacks } from './iEffectFallbacks';
-import { WebGPUPipelineContext } from '../Engines/WebGPU/webgpuPipelineContext';
-import type { WebGPUEngine } from '../Engines/webgpuEngine';
-import { WebGPUConstants } from '../Engines/WebGPU/webgpuConstants';
 
 declare type Engine = import("../Engines/engine").Engine;
 declare type InternalTexture = import("../Materials/Textures/internalTexture").InternalTexture;
@@ -300,7 +297,7 @@ export class Effect implements IDisposable {
                 });
             }
 
-        }
+        };
         this._loadShader(vertexSource, "Vertex", "", (vertexCode) => {
             ShaderProcessor.Process(vertexCode, processorOptions, (migratedVertexCode) => {
                 shaderCodes[0] = migratedVertexCode;
@@ -683,65 +680,6 @@ export class Effect implements IDisposable {
         }
     }
 
-    public getPipelineLayout(): GPUPipelineLayout {
-        const bindGroupLayouts: GPUBindGroupLayout[] = [];
-        const webgpuPipelineContext = this._pipelineContext as WebGPUPipelineContext;
-
-        for (let i = 0; i < webgpuPipelineContext.orderedUBOsAndSamplers.length; i++) {
-            const setDefinition = webgpuPipelineContext.orderedUBOsAndSamplers[i];
-            if (setDefinition === undefined) {
-                const bindings: GPUBindGroupLayoutBinding[] = [];
-                const uniformsBindGroupLayout = (this._engine as WebGPUEngine).getDevice().createBindGroupLayout({
-                    bindings,
-                });
-                bindGroupLayouts[i] = uniformsBindGroupLayout;
-                continue;
-            }
-
-            const bindings: GPUBindGroupLayoutBinding[] = [];
-            for (let j = 0; j < setDefinition.length; j++) {
-                const bindingDefinition = webgpuPipelineContext.orderedUBOsAndSamplers[i][j];
-                if (bindingDefinition === undefined) {
-                    continue;
-                }
-
-                // TODO WEBGPU. Optimize shared samplers visibility for vertex/framgent.
-                if (bindingDefinition.isSampler) {
-                    bindings.push({
-                        binding: j,
-                        visibility: WebGPUConstants.GPUShaderStageBit_VERTEX | WebGPUConstants.GPUShaderStageBit_FRAGMENT,
-                        type: WebGPUConstants.GPUBindingType_sampledTexture,
-                        textureDimension: bindingDefinition.textureDimension,
-                        // TODO WEBGPU. Handle texture component type properly.
-                        // textureComponentType?: GPUTextureComponentType,
-                    }, {
-                        // TODO WEBGPU. No Magic + 1 (coming from current 1 texture 1 sampler startegy).
-                        binding: j + 1,
-                        visibility: WebGPUConstants.GPUShaderStageBit_VERTEX | WebGPUConstants.GPUShaderStageBit_FRAGMENT,
-                        type: WebGPUConstants.GPUBindingType_sampler
-                    });
-                }
-                else {
-                    bindings.push({
-                        binding: j,
-                        visibility: WebGPUConstants.GPUShaderStageBit_VERTEX | WebGPUConstants.GPUShaderStageBit_FRAGMENT,
-                        type: WebGPUConstants.GPUBindingType_uniformBuffer,
-                    });
-                }
-            }
-
-            if (bindings.length > 0) {
-                const uniformsBindGroupLayout = (this._engine as WebGPUEngine).getDevice().createBindGroupLayout({
-                    bindings,
-                });
-                bindGroupLayouts[i] = uniformsBindGroupLayout;
-            }
-        }
-
-        webgpuPipelineContext.bindGroupLayouts = bindGroupLayouts;
-        return (this._engine as WebGPUEngine).getDevice().createPipelineLayout({ bindGroupLayouts });
-    }
-
     /**
      * Checks if the effect is supported. (Must be called after compilation)
      */