瀏覽代碼

Add useNewBindings to the pipeline context interface

Popov72 4 年之前
父節點
當前提交
fa1f05c0a7

+ 3 - 0
src/Engines/IPipelineContext.ts

@@ -27,6 +27,9 @@ export interface IPipelineContext {
     /** @hidden */
     _fillEffectInformation(effect: Effect, uniformBuffersNames: { [key: string]: number }, uniformsNames: string[], uniforms: { [key: string]: Nullable<WebGLUniformLocation> }, samplerList: string[], samplers: { [key: string]: number }, attributesNames: string[], attributes: number[]): void;
 
+    /** @hidden */
+    _useNewBindings(): void;
+
     /** Releases the resources associated with the pipeline. */
     dispose(): void;
 

+ 5 - 0
src/Engines/WebGL/webGLPipelineContext.ts

@@ -76,6 +76,11 @@ export class WebGLPipelineContext implements IPipelineContext {
         }
     }
 
+    /** @hidden */
+    public _useNewBindings(): void {
+        // nothing to do in WebGL
+    }
+
     /**
      * Release all associated resources.
      **/

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

@@ -150,6 +150,11 @@ export class WebGPUPipelineContext implements IPipelineContext {
         this.buildUniformLayout();
     }
 
+    /** @hidden */
+    public _useNewBindings(): void {
+        this.buildUniformLayout();
+    }
+
     /**
      * Build the uniform buffer used in the material.
      */
@@ -158,16 +163,33 @@ export class WebGPUPipelineContext implements IPipelineContext {
             return;
         }
 
-        this.uniformBuffer = new UniformBuffer(this.engine);
+        if (this.uniformBuffer) {
+            // If the uniform buffer is already existing it means one wants to do multiple rendering with the same pipeline context
+            // we need to have a new uniform buffer for the new rendering, else all the rendering will end up using the same uniform buffer.
+            // Calling _rebuild() is enough to recreate the underlying hardware buffer without removing any other data.
+            // That means the user does not need to re-set all the uniforms of the buffer, the new buffer is in the same state than the previous one.
+
+            // TODO WEBGPU don't recreate a new buffer each time (it is created in _rebuild()), keeps an array of buffers and reuse them. It means
+            // we need to be notified when a frame starts so that we can reset the pointer into this array
+            const buffer = this.uniformBuffer.getBuffer();
+            if (buffer) {
+                this.engine._releaseBuffer(buffer);
+            }
+            this.uniformBuffer._rebuild();
+        } else {
+            this.uniformBuffer = new UniformBuffer(this.engine);
+
+            for (let leftOverUniform of this.leftOverUniforms) {
+                const size = _uniformSizes[leftOverUniform.type];
+                this.uniformBuffer.addUniform(leftOverUniform.name, size, leftOverUniform.length);
+                // TODO WEBGPU. Replace with info from uniform buffer class
+                this.leftOverUniformsByName[leftOverUniform.name] = leftOverUniform.type;
+            }
 
-        for (let leftOverUniform of this.leftOverUniforms) {
-            const size = _uniformSizes[leftOverUniform.type];
-            this.uniformBuffer.addUniform(leftOverUniform.name, size, leftOverUniform.length);
-            // TODO WEBGPU. Replace with info from uniform buffer class
-            this.leftOverUniformsByName[leftOverUniform.name] = leftOverUniform.type;
+            this.uniformBuffer.create();
         }
 
-        this.uniformBuffer.create();
+        this.bindGroups = null as any;
     }
 
     /**

+ 4 - 0
src/Engines/nativeEngine.ts

@@ -167,6 +167,10 @@ class NativePipelineContext implements IPipelineContext {
         attributes.push(...engine.getAttributes(this, attributesNames));
     }
 
+    /** @hidden */
+    public _useNewBindings(): void {
+    }
+
     /**
      * Release all associated resources.
      **/

+ 7 - 0
src/Materials/effect.ts

@@ -1233,6 +1233,13 @@ export class Effect implements IDisposable {
     }
 
     /**
+     * Instructs the underlying rendering system that we want to use a new set of parameter bindings for the next rendering operation using this effect
+     */
+    public useNewBindings(): void {
+        this._pipelineContext!._useNewBindings();
+    }
+
+    /**
      * Release all associated resources.
      **/
     public dispose() {