Просмотр исходного кода

WebGPURenderer: Per "texture set" bindGroup caching. (#29845)

* prototype per texture set bindgroup

* lint

* add cache versioning

---------

Co-authored-by: aardgoose <angus.sawyer@email.com>
aardgoose 1 год назад
Родитель
Сommit
bb7f17afb4

+ 4 - 6
examples/jsm/tsl/display/GaussianBlurNode.js

@@ -4,8 +4,7 @@ import { TempNode, nodeObject, Fn, If, float, NodeUpdateType, uv, uniform, conve
 // WebGPU: The use of a single QuadMesh for both gaussian blur passes results in a single RenderObject with a SampledTexture binding that
 // alternates between source textures and triggers creation of new BindGroups and BindGroupLayouts every frame.
 
-const _quadMesh1 = /*@__PURE__*/ new QuadMesh();
-const _quadMesh2 = /*@__PURE__*/ new QuadMesh();
+const _quadMesh = /*@__PURE__*/ new QuadMesh();
 
 let _rendererState;
 
@@ -108,8 +107,7 @@ class GaussianBlurNode extends TempNode {
 
 		const currentTexture = textureNode.value;
 
-		_quadMesh1.material = this._material;
-		_quadMesh2.material = this._material;
+		_quadMesh.material = this._material;
 
 		this.setSize( map.image.width, map.image.height );
 
@@ -124,7 +122,7 @@ class GaussianBlurNode extends TempNode {
 
 		this._passDirection.value.set( 1, 0 );
 
-		_quadMesh1.render( renderer );
+		_quadMesh.render( renderer );
 
 		// vertical
 
@@ -133,7 +131,7 @@ class GaussianBlurNode extends TempNode {
 
 		this._passDirection.value.set( 0, 1 );
 
-		_quadMesh2.render( renderer );
+		_quadMesh.render( renderer );
 
 		// restore
 

+ 20 - 4
src/renderers/common/Bindings.js

@@ -32,7 +32,7 @@ class Bindings extends DataMap {
 
 				this._init( bindGroup );
 
-				this.backend.createBindings( bindGroup, bindings );
+				this.backend.createBindings( bindGroup, bindings, 0 );
 
 				groupData.bindGroup = bindGroup;
 
@@ -56,7 +56,7 @@ class Bindings extends DataMap {
 
 				this._init( bindGroup );
 
-				this.backend.createBindings( bindGroup, bindings );
+				this.backend.createBindings( bindGroup, bindings, 0 );
 
 				groupData.bindGroup = bindGroup;
 
@@ -116,6 +116,9 @@ class Bindings extends DataMap {
 		const { backend } = this;
 
 		let needsBindingsUpdate = false;
+		let cacheBindings = true;
+		let cacheIndex = 0;
+		let version = 0;
 
 		// iterate over all bindings and check if buffer updates or a new binding group is required
 
@@ -145,7 +148,9 @@ class Bindings extends DataMap {
 
 			} else if ( binding.isSampledTexture ) {
 
-				if ( binding.needsBindingsUpdate( this.textures.get( binding.texture ).generation ) ) needsBindingsUpdate = true;
+				const texturesTextureData = this.textures.get( binding.texture );
+
+				if ( binding.needsBindingsUpdate( texturesTextureData.generation ) ) needsBindingsUpdate = true;
 
 				const updated = binding.update();
 
@@ -159,6 +164,17 @@ class Bindings extends DataMap {
 
 				const textureData = backend.get( texture );
 
+				if ( textureData.externalTexture !== undefined || texturesTextureData.isDefaultTexture ) {
+
+					cacheBindings = false;
+
+				} else {
+
+					cacheIndex = cacheIndex * 10 + texture.id;
+					version += texture.version;
+
+				}
+
 				if ( backend.isWebGPUBackend === true && textureData.texture === undefined && textureData.externalTexture === undefined ) {
 
 					// TODO: Remove this once we found why updated === false isn't bound to a texture in the WebGPU backend
@@ -193,7 +209,7 @@ class Bindings extends DataMap {
 
 		if ( needsBindingsUpdate === true ) {
 
-			this.backend.updateBindings( bindGroup, bindings );
+			this.backend.updateBindings( bindGroup, bindings, cacheBindings ? cacheIndex : 0, version );
 
 		}
 

+ 4 - 4
src/renderers/webgpu/WebGPUBackend.js

@@ -1361,15 +1361,15 @@ class WebGPUBackend extends Backend {
 
 	// bindings
 
-	createBindings( bindGroup ) {
+	createBindings( bindGroup, bindings, cacheIndex, version ) {
 
-		this.bindingUtils.createBindings( bindGroup );
+		this.bindingUtils.createBindings( bindGroup, bindings, cacheIndex, version );
 
 	}
 
-	updateBindings( bindGroup ) {
+	updateBindings( bindGroup, bindings, cacheIndex, version ) {
 
-		this.bindingUtils.createBindings( bindGroup );
+		this.bindingUtils.createBindings( bindGroup, bindings, cacheIndex, version );
 
 	}
 

+ 33 - 3
src/renderers/webgpu/utils/WebGPUBindingUtils.js

@@ -140,7 +140,7 @@ class WebGPUBindingUtils {
 
 	}
 
-	createBindings( bindGroup ) {
+	createBindings( bindGroup, bindings, cacheIndex, version = 0 ) {
 
 		const { backend, bindGroupLayoutCache } = this;
 		const bindingsData = backend.get( bindGroup );
@@ -156,10 +156,40 @@ class WebGPUBindingUtils {
 
 		}
 
-		const bindGroupGPU = this.createBindGroup( bindGroup, bindLayoutGPU );
+		let bindGroupGPU;
+
+		if ( cacheIndex > 0 ) {
+
+			if ( bindingsData.groups === undefined ) {
+
+				bindingsData.groups = [];
+				bindingsData.versions = [];
+
+			}
+
+			if ( bindingsData.versions[ cacheIndex ] === version ) {
+
+				bindGroupGPU = bindingsData.groups[ cacheIndex ];
+
+			}
+
+		}
+
+		if ( bindGroupGPU === undefined ) {
+
+			bindGroupGPU = this.createBindGroup( bindGroup, bindLayoutGPU );
+
+			if ( cacheIndex > 0 ) {
+
+				bindingsData.groups[ cacheIndex ] = bindGroupGPU;
+				bindingsData.versions[ cacheIndex ] = version;
+
+			}
+
+		}
 
-		bindingsData.layout = bindLayoutGPU;
 		bindingsData.group = bindGroupGPU;
+		bindingsData.layout = bindLayoutGPU;
 
 	}
 

粤ICP备19079148号