Bladeren bron

Refactoring of WebGPUPipelineContext to avoid dup with WebGPUShaderProcessingContext

Popov72 4 jaren geleden
bovenliggende
commit
148b628808
2 gewijzigde bestanden met toevoegingen van 28 en 66 verwijderingen
  1. 7 26
      src/Engines/WebGPU/webgpuPipelineContext.ts
  2. 21 40
      src/Engines/webgpuEngine.ts

+ 7 - 26
src/Engines/WebGPU/webgpuPipelineContext.ts

@@ -3,7 +3,7 @@ import { Nullable } from '../../types';
 import { WebGPUEngine } from '../webgpuEngine';
 import { InternalTexture } from '../../Materials/Textures/internalTexture';
 import { Effect } from '../../Materials/effect';
-import { WebGPUTextureSamplerBindingDescription, WebGPUShaderProcessingContext } from './webgpuShaderProcessingContext';
+import { WebGPUShaderProcessingContext } from './webgpuShaderProcessingContext';
 import { UniformBuffer } from "../../Materials/uniformBuffer";
 import { IMatrixLike, IVector2Like, IVector3Like, IVector4Like, IColor3Like, IColor4Like } from '../../Maths/math.like';
 
@@ -54,14 +54,8 @@ export interface IWebGPURenderPipelineStageDescriptor {
 export class WebGPUPipelineContext implements IPipelineContext {
     public engine: WebGPUEngine;
 
-    public availableAttributes: { [key: string]: number };
-    public availableUBOs: { [key: string]: { setIndex: number, bindingIndex: number} };
-    public availableSamplers: { [key: string]: WebGPUTextureSamplerBindingDescription };
+    public shaderProcessingContext: WebGPUShaderProcessingContext;
 
-    public orderedAttributes: string[];
-    public orderedUBOsAndSamplers: { name: string, isSampler: boolean, isComparisonSampler?: boolean, isTexture: boolean, textureNeedsDepthComparison?: boolean, textureDimension?: GPUTextureViewDimension }[][];
-
-    public leftOverUniforms: { name: string, type: string, length: number }[];
     public leftOverUniformsByName: { [name: string]: string };
 
     public sources: {
@@ -76,12 +70,7 @@ export class WebGPUPipelineContext implements IPipelineContext {
     public samplers: { [name: string]: Nullable<IWebGPUPipelineContextSamplerCache> } = { };
     public textures: { [name: string]: Nullable<IWebGPUPipelineContextTextureCache> } = { };
 
-    public vertexInputs: IWebGPUPipelineContextVertexInputsCache;
-
     public bindGroupLayouts: GPUBindGroupLayout[];
-    public bindGroups: GPUBindGroup[];
-
-    public renderPipeline: GPURenderPipeline;
 
     /**
      * Stores the uniform buffer
@@ -108,16 +97,8 @@ export class WebGPUPipelineContext implements IPipelineContext {
 
     constructor(shaderProcessingContext: WebGPUShaderProcessingContext, engine: WebGPUEngine) {
         this._name = "unnamed";
-        if (shaderProcessingContext) {
-            this.availableAttributes = shaderProcessingContext.availableAttributes;
-            this.availableUBOs = shaderProcessingContext.availableUBOs;
-            this.availableSamplers = shaderProcessingContext.availableSamplers;
-            this.orderedAttributes = shaderProcessingContext.orderedAttributes;
-            this.orderedUBOsAndSamplers = shaderProcessingContext.orderedUBOsAndSamplers;
-
-            this.leftOverUniforms = shaderProcessingContext.leftOverUniforms;
-            this.leftOverUniformsByName = {};
-        }
+        this.shaderProcessingContext = shaderProcessingContext;
+        this.leftOverUniformsByName = {};
     }
 
     public _handlesSpectorRebuildCallback(onCompiled: (program: any) => void): void {
@@ -139,7 +120,7 @@ export class WebGPUPipelineContext implements IPipelineContext {
         // this._fragmentSourceCodeOverride = "";
         // this._vertexSourceCodeOverride = "";
 
-        const foundSamplers = this.availableSamplers;
+        const foundSamplers = this.shaderProcessingContext.availableSamplers;
         let index: number;
         for (index = 0; index < samplerList.length; index++) {
             const name = samplerList[index];
@@ -167,13 +148,13 @@ export class WebGPUPipelineContext implements IPipelineContext {
      * Build the uniform buffer used in the material.
      */
     public buildUniformLayout(): void {
-        if (!this.leftOverUniforms.length) {
+        if (!this.shaderProcessingContext.leftOverUniforms.length) {
             return;
         }
 
         this.uniformBuffer = new UniformBuffer(this.engine, undefined, undefined, "leftOver-" + this._name);
 
-        for (let leftOverUniform of this.leftOverUniforms) {
+        for (let leftOverUniform of this.shaderProcessingContext.leftOverUniforms) {
             const size = _uniformSizes[leftOverUniform.type];
             this.uniformBuffer.addUniform(leftOverUniform.name, size, leftOverUniform.length);
             // TODO WEBGPU. Replace with info from uniform buffer class

+ 21 - 40
src/Engines/webgpuEngine.ts

@@ -963,7 +963,7 @@ export class WebGPUEngine extends Engine {
         // Should be done at processing time, not need to double the work in here.
         for (let i = 0; i < attributesNames.length; i++) {
             const attributeName = attributesNames[i];
-            const attributeLocation = gpuPipelineContext.availableAttributes[attributeName];
+            const attributeLocation = gpuPipelineContext.shaderProcessingContext.availableAttributes[attributeName];
             if (attributeLocation === undefined) {
                 continue;
             }
@@ -1654,13 +1654,14 @@ export class WebGPUEngine extends Engine {
 
             if (webgpuPipelineContext.textures[name]) {
                 if (webgpuPipelineContext.textures[name]!.texture !== internalTexture) {
-                    webgpuPipelineContext.bindGroups = null as any; // the bind groups need to be rebuilt (at least the bind group owning this texture, but it's easier to just have them all rebuilt)
+                    // TODO WEBGPU when the bindGroups has a caching mechanism set up, clear this cache
+                    //webgpuPipelineContext.bindGroups = null as any; // the bind groups need to be rebuilt (at least the bind group owning this texture, but it's easier to just have them all rebuilt)
                 }
                 webgpuPipelineContext.textures[name]!.texture = internalTexture!;
             }
             else {
                 // TODO WEBGPU. 121 mapping samplers <-> availableSamplers
-                const availableSampler = webgpuPipelineContext.availableSamplers[baseName];
+                const availableSampler = webgpuPipelineContext.shaderProcessingContext.availableSamplers[baseName];
                 if (availableSampler) {
                     webgpuPipelineContext.samplers[baseName] = {
                         samplerBinding: availableSampler.sampler.bindingIndex,
@@ -1695,7 +1696,8 @@ export class WebGPUEngine extends Engine {
             const webgpuPipelineContext = this._currentEffect._pipelineContext as WebGPUPipelineContext;
             if (!texture) {
                 if (webgpuPipelineContext.textures[name] && webgpuPipelineContext.textures[name]!.texture) {
-                    webgpuPipelineContext.bindGroups = null as any; // the bind groups need to be rebuilt (at least the bind group owning this texture, but it's easier to just have them all rebuilt)
+                    // TODO WEBGPU when the bindGroups has a caching mechanism set up, clear this cache
+                    //webgpuPipelineContext.bindGroups = null as any; // the bind groups need to be rebuilt (at least the bind group owning this texture, but it's easier to just have them all rebuilt)
                 }
                 webgpuPipelineContext.textures[name] = null;
                 return false;
@@ -3197,8 +3199,8 @@ export class WebGPUEngine extends Engine {
         const bindGroupLayouts: GPUBindGroupLayout[] = [];
         const webgpuPipelineContext = this._currentEffect!._pipelineContext as WebGPUPipelineContext;
 
-        for (let i = 0; i < webgpuPipelineContext.orderedUBOsAndSamplers.length; i++) {
-            const setDefinition = webgpuPipelineContext.orderedUBOsAndSamplers[i];
+        for (let i = 0; i < webgpuPipelineContext.shaderProcessingContext.orderedUBOsAndSamplers.length; i++) {
+            const setDefinition = webgpuPipelineContext.shaderProcessingContext.orderedUBOsAndSamplers[i];
             if (setDefinition === undefined) {
                 const entries: GPUBindGroupLayoutEntry[] = [];
                 const uniformsBindGroupLayout = this._device.createBindGroupLayout({
@@ -3210,7 +3212,7 @@ export class WebGPUEngine extends Engine {
 
             const entries: GPUBindGroupLayoutEntry[] = [];
             for (let j = 0; j < setDefinition.length; j++) {
-                const bindingDefinition = webgpuPipelineContext.orderedUBOsAndSamplers[i][j];
+                const bindingDefinition = webgpuPipelineContext.shaderProcessingContext.orderedUBOsAndSamplers[i][j];
                 if (bindingDefinition === undefined) {
                     continue;
                 }
@@ -3256,12 +3258,6 @@ export class WebGPUEngine extends Engine {
     }
 
     private _getRenderPipeline(topology: GPUPrimitiveTopology): GPURenderPipeline {
-        // This is wrong to cache this way but workarounds the need of cache in the simple demo context.
-        const webgpuPipelineContext = this._currentEffect!._pipelineContext as WebGPUPipelineContext;
-        /*if (webgpuPipelineContext.renderPipeline) {
-            return webgpuPipelineContext.renderPipeline;
-        }*/
-
         this._counters.numPipelineDescriptorCreation++;
 
         // Unsupported at the moment but needs to be extracted from the MSAA param.
@@ -3272,7 +3268,7 @@ export class WebGPUEngine extends Engine {
         const inputStateDescriptor = this._getVertexInputDescriptor(topology);
         const pipelineLayout = this._getPipelineLayout();
 
-        webgpuPipelineContext.renderPipeline = this._device.createRenderPipeline({
+        return this._device.createRenderPipeline({
             sampleCount: this._currentRenderTarget ? this._currentRenderTarget.samples : this._mainPassSampleCount,
             primitiveTopology: topology,
             rasterizationState: rasterizationStateDescriptor,
@@ -3283,19 +3279,12 @@ export class WebGPUEngine extends Engine {
             vertexState: inputStateDescriptor,
             layout: pipelineLayout,
         });
-        return webgpuPipelineContext.renderPipeline;
     }
 
     private _getVertexInputsToRender(): IWebGPUPipelineContextVertexInputsCache {
         const effect = this._currentEffect!;
-        const webgpuPipelineContext = this._currentEffect!._pipelineContext as WebGPUPipelineContext;
 
-        let vertexInputs = webgpuPipelineContext.vertexInputs;
-        /*!!if (vertexInputs) {
-            return vertexInputs;
-        }*/
-
-        vertexInputs = {
+        let vertexInputs: IWebGPUPipelineContextVertexInputsCache = {
             indexBuffer: null,
             indexOffset: 0,
 
@@ -3303,7 +3292,6 @@ export class WebGPUEngine extends Engine {
             vertexBuffers: [],
             vertexOffsets: [],
         };
-        webgpuPipelineContext.vertexInputs = vertexInputs;
 
         if (this._currentIndexBuffer) {
             // TODO WEBGPU. Check if cache would be worth it.
@@ -3336,15 +3324,9 @@ export class WebGPUEngine extends Engine {
         return vertexInputs;
     }
 
-    private _getBindGroupsToRender(): GPUBindGroup[] {
+    private _getBindGroupsToRender(renderPipeline: GPURenderPipeline): GPUBindGroup[] {
         const webgpuPipelineContext = this._currentEffect!._pipelineContext as WebGPUPipelineContext;
-        let bindGroups = webgpuPipelineContext.bindGroups;
-        /*if (bindGroups) {
-            if (webgpuPipelineContext.uniformBuffer) {
-                webgpuPipelineContext.uniformBuffer.update();
-            }
-            return bindGroups;
-        }*/
+        let bindGroups: GPUBindGroup[] = [];
 
         this._counters.numBindGroupsCreation++;
 
@@ -3353,20 +3335,18 @@ export class WebGPUEngine extends Engine {
             webgpuPipelineContext.uniformBuffer.update();
         }
 
-        bindGroups = [];
-        webgpuPipelineContext.bindGroups = bindGroups;
-
         const bindGroupLayouts = webgpuPipelineContext.bindGroupLayouts;
 
-        for (let i = 0; i < webgpuPipelineContext.orderedUBOsAndSamplers.length; i++) {
-            const setDefinition = webgpuPipelineContext.orderedUBOsAndSamplers[i];
+        for (let i = 0; i < webgpuPipelineContext.shaderProcessingContext.orderedUBOsAndSamplers.length; i++) {
+            const setDefinition = webgpuPipelineContext.shaderProcessingContext.orderedUBOsAndSamplers[i];
             if (setDefinition === undefined) {
                 let groupLayout: GPUBindGroupLayout;
                 if (bindGroupLayouts && bindGroupLayouts[i]) {
                     groupLayout = bindGroupLayouts[i];
                 }
                 else {
-                    groupLayout = webgpuPipelineContext.renderPipeline.getBindGroupLayout(i);
+                    // TODO WEBGPU can it happens? we should be able to avoid a dependency on renderPipeline here
+                    groupLayout = renderPipeline.getBindGroupLayout(i);
                 }
                 bindGroups[i] = this._device.createBindGroup({
                     layout: groupLayout,
@@ -3377,7 +3357,7 @@ export class WebGPUEngine extends Engine {
 
             const entries: GPUBindGroupEntry[] = [];
             for (let j = 0; j < setDefinition.length; j++) {
-                const bindingDefinition = webgpuPipelineContext.orderedUBOsAndSamplers[i][j];
+                const bindingDefinition = webgpuPipelineContext.shaderProcessingContext.orderedUBOsAndSamplers[i][j];
                 if (bindingDefinition === undefined) {
                     continue;
                 }
@@ -3459,7 +3439,8 @@ export class WebGPUEngine extends Engine {
                     groupLayout = bindGroupLayouts[i];
                 }
                 else {
-                    groupLayout = webgpuPipelineContext.renderPipeline.getBindGroupLayout(i);
+                    // TODO WEBGPU can it happens? we should be able to avoid a dependency on renderPipeline here
+                    groupLayout = renderPipeline.getBindGroupLayout(i);
                 }
                 bindGroups[i] = this._device.createBindGroup({
                     layout: groupLayout,
@@ -3507,7 +3488,7 @@ export class WebGPUEngine extends Engine {
         const vertexInputs = this._getVertexInputsToRender();
         this._bindVertexInputs(vertexInputs);
 
-        const bindGroups = this._getBindGroupsToRender();
+        const bindGroups = this._getBindGroupsToRender(pipeline);
         this._setRenderBindGroups(bindGroups);
 
         if (this._stencilState.stencilTest) {