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

Revert "WebGPUBindingUtils: Improve Bind Group Layout cache system." (#32437)

Michael Herzog 4 месяцев назад
Родитель
Сommit
625d234eb7

+ 0 - 8
src/renderers/common/Backend.js

@@ -725,14 +725,6 @@ class Backend {
 
 	}
 
-	/**
-	 * Delete GPU data associated with a bind group.
-	 *
-	 * @abstract
-	 * @param {BindGroup} bindGroup - The bind group.
-	 */
-	deleteBindGroupData( /*bindGroup*/ ) { }
-
 	/**
 	 * Deletes an object from the internal data structure.
 	 *

+ 0 - 2
src/renderers/common/Bindings.js

@@ -164,7 +164,6 @@ class Bindings extends DataMap {
 
 		for ( const bindGroup of bindings ) {
 
-			this.backend.deleteBindGroupData( bindGroup );
 			this.delete( bindGroup );
 
 		}
@@ -182,7 +181,6 @@ class Bindings extends DataMap {
 
 		for ( const bindGroup of bindings ) {
 
-			this.backend.deleteBindGroupData( bindGroup );
 			this.delete( bindGroup );
 
 		}

+ 1 - 15
src/renderers/webgpu/WebGPUBackend.js

@@ -1665,9 +1665,7 @@ class WebGPUBackend extends Backend {
 
 					data[ 0 ] = i;
 
-					const { layoutGPU } = bindingsData.layout;
-
-					const bindGroupIndex = this.bindingUtils.createBindGroupIndex( data, layoutGPU );
+					const bindGroupIndex = this.bindingUtils.createBindGroupIndex( data, bindingsData.layout );
 
 					indexesGPU.push( bindGroupIndex );
 
@@ -2134,17 +2132,6 @@ class WebGPUBackend extends Backend {
 
 	}
 
-	/**
-	 * Delete data associated with the current bind group.
-	 *
-	 * @param {BindGroup} bindGroup - The bind group.
-	 */
-	deleteBindGroupData( bindGroup ) {
-
-		this.bindingUtils.deleteBindGroupData( bindGroup );
-
-	}
-
 	/**
 	 * Updates the given bind group definition.
 	 *
@@ -2500,7 +2487,6 @@ class WebGPUBackend extends Backend {
 	dispose() {
 
 		this.textureUtils.dispose();
-		this.bindingUtils.dispose();
 
 	}
 

+ 184 - 291
src/renderers/webgpu/utils/WebGPUBindingUtils.js

@@ -7,37 +7,6 @@ import { FloatType, IntType, UnsignedIntType } from '../../../constants.js';
 import { NodeAccess } from '../../../nodes/core/constants.js';
 import { isTypedArray, error } from '../../../utils.js';
 
-/**
-* Class representing a WebGPU bind group layout.
-*
-*/
-class BindGroupLayout {
-
-	/**
-	 * Constructs a new BindGroupLayout.
-	 *
-	 * @param {GPUBindGroupLayout} layoutGPU - A GPU Bind Group Layout.
-	 */
-	constructor( layoutGPU ) {
-
-		/**
-		 * The current GPUBindGroupLayout
-		 *
-		 * @type {GPUBindGroupLayout}
-		 */
-		this.layoutGPU = layoutGPU;
-
-		/**
-		 * The number of bind groups that use the current GPUBindGroupLayout
-		 *
-		 * @type {number}
-		 */
-		this.usedTimes = 0;
-
-	}
-
-}
-
 /**
  * A WebGPU backend utility module for managing bindings.
  *
@@ -65,11 +34,11 @@ class WebGPUBindingUtils {
 		this.backend = backend;
 
 		/**
-		 * A cache that maps combinations of layout entries to existing bind group layouts.
+		 * A cache for managing bind group layouts.
 		 *
-		 * @type {Map<string, BindGroupLayout>}
+		 * @type {WeakMap<Array<Binding>,GPUBindGroupLayout>}
 		 */
-		this.bindGroupLayoutCache = new Map();
+		this.bindGroupLayoutCache = new WeakMap();
 
 	}
 
@@ -84,33 +53,185 @@ class WebGPUBindingUtils {
 		const backend = this.backend;
 		const device = backend.device;
 
-		const bindingsData = backend.get( bindGroup );
+		const entries = [];
 
-		// When current bind group has already been assigned a layout
-		if ( bindingsData.bindGroupLayout !== undefined ) {
+		let index = 0;
 
-			return bindingsData.bindGroupLayout.layoutGPU;
+		for ( const binding of bindGroup.bindings ) {
 
-		}
+			const bindingGPU = {
+				binding: index ++,
+				visibility: binding.visibility
+			};
 
-		const entries = this._createBindingsLayoutEntries( bindGroup );
+			if ( binding.isUniformBuffer || binding.isStorageBuffer ) {
 
-		const bindGroupLayoutKey = JSON.stringify( entries );
+				const buffer = {}; // GPUBufferBindingLayout
 
-		let bindGroupLayout = this.bindGroupLayoutCache.get( bindGroupLayoutKey );
+				if ( binding.isStorageBuffer ) {
 
-		if ( bindGroupLayout === undefined ) {
+					if ( binding.visibility & GPUShaderStage.COMPUTE ) {
 
-			bindGroupLayout = new BindGroupLayout( device.createBindGroupLayout( { entries } ) );
-			this.bindGroupLayoutCache.set( bindGroupLayoutKey, bindGroupLayout );
+						// compute
 
-		}
+						if ( binding.access === NodeAccess.READ_WRITE || binding.access === NodeAccess.WRITE_ONLY ) {
+
+							buffer.type = GPUBufferBindingType.Storage;
+
+						} else {
+
+							buffer.type = GPUBufferBindingType.ReadOnlyStorage;
+
+						}
+
+					} else {
+
+						buffer.type = GPUBufferBindingType.ReadOnlyStorage;
+
+					}
+
+				}
+
+				bindingGPU.buffer = buffer;
+
+			} else if ( binding.isSampledTexture && binding.store ) {
+
+				const storageTexture = {}; // GPUStorageTextureBindingLayout
+				storageTexture.format = this.backend.get( binding.texture ).texture.format;
+
+				const access = binding.access;
+
+				if ( access === NodeAccess.READ_WRITE ) {
+
+					storageTexture.access = GPUStorageTextureAccess.ReadWrite;
+
+				} else if ( access === NodeAccess.WRITE_ONLY ) {
+
+					storageTexture.access = GPUStorageTextureAccess.WriteOnly;
+
+				} else {
+
+					storageTexture.access = GPUStorageTextureAccess.ReadOnly;
+
+				}
+
+				if ( binding.texture.isArrayTexture ) {
+
+					storageTexture.viewDimension = GPUTextureViewDimension.TwoDArray;
+
+				} else if ( binding.texture.is3DTexture ) {
+
+					storageTexture.viewDimension = GPUTextureViewDimension.ThreeD;
+
+				}
+
+				bindingGPU.storageTexture = storageTexture;
+
+			} else if ( binding.isSampledTexture ) {
+
+				const texture = {}; // GPUTextureBindingLayout
+
+				const { primarySamples } = backend.utils.getTextureSampleData( binding.texture );
+
+				if ( primarySamples > 1 ) {
+
+					texture.multisampled = true;
+
+					if ( ! binding.texture.isDepthTexture ) {
+
+						texture.sampleType = GPUTextureSampleType.UnfilterableFloat;
+
+					}
+
+				}
+
+				if ( binding.texture.isDepthTexture ) {
+
+					if ( backend.compatibilityMode && binding.texture.compareFunction === null ) {
+
+						texture.sampleType = GPUTextureSampleType.UnfilterableFloat;
+
+					} else {
+
+						texture.sampleType = GPUTextureSampleType.Depth;
+
+					}
+
+				} else if ( binding.texture.isDataTexture || binding.texture.isDataArrayTexture || binding.texture.isData3DTexture ) {
+
+					const type = binding.texture.type;
+
+					if ( type === IntType ) {
+
+						texture.sampleType = GPUTextureSampleType.SInt;
+
+					} else if ( type === UnsignedIntType ) {
+
+						texture.sampleType = GPUTextureSampleType.UInt;
+
+					} else if ( type === FloatType ) {
+
+						if ( this.backend.hasFeature( 'float32-filterable' ) ) {
 
-		bindingsData.layout = bindGroupLayout;
-		bindingsData.layout.usedTimes ++;
-		bindingsData.layoutKey = bindGroupLayoutKey;
+							texture.sampleType = GPUTextureSampleType.Float;
 
-		return bindGroupLayout.layoutGPU;
+						} else {
+
+							texture.sampleType = GPUTextureSampleType.UnfilterableFloat;
+
+						}
+
+					}
+
+				}
+
+				if ( binding.isSampledCubeTexture ) {
+
+					texture.viewDimension = GPUTextureViewDimension.Cube;
+
+				} else if ( binding.texture.isArrayTexture || binding.texture.isDataArrayTexture || binding.texture.isCompressedArrayTexture ) {
+
+					texture.viewDimension = GPUTextureViewDimension.TwoDArray;
+
+				} else if ( binding.isSampledTexture3D ) {
+
+					texture.viewDimension = GPUTextureViewDimension.ThreeD;
+
+				}
+
+				bindingGPU.texture = texture;
+
+			} else if ( binding.isSampler ) {
+
+				const sampler = {}; // GPUSamplerBindingLayout
+
+				if ( binding.texture.isDepthTexture ) {
+
+					if ( binding.texture.compareFunction !== null ) {
+
+						sampler.type = GPUSamplerBindingType.Comparison;
+
+					} else if ( backend.compatibilityMode ) {
+
+						sampler.type = GPUSamplerBindingType.NonFiltering;
+
+					}
+
+				}
+
+				bindingGPU.sampler = sampler;
+
+			} else {
+
+				error( `WebGPUBindingUtils: Unsupported binding "${ binding }".` );
+
+			}
+
+			entries.push( bindingGPU );
+
+		}
+
+		return device.createBindGroupLayout( { entries } );
 
 	}
 
@@ -124,12 +245,19 @@ class WebGPUBindingUtils {
 	 */
 	createBindings( bindGroup, bindings, cacheIndex, version = 0 ) {
 
-		const { backend } = this;
+		const { backend, bindGroupLayoutCache } = this;
 		const bindingsData = backend.get( bindGroup );
 
 		// setup (static) binding layout and (dynamic) binding group
 
-		const bindLayoutGPU = this.createBindingsLayout( bindGroup );
+		let bindLayoutGPU = bindGroupLayoutCache.get( bindGroup.bindingsReference );
+
+		if ( bindLayoutGPU === undefined ) {
+
+			bindLayoutGPU = this.createBindingsLayout( bindGroup );
+			bindGroupLayoutCache.set( bindGroup.bindingsReference, bindLayoutGPU );
+
+		}
 
 		let bindGroupGPU;
 
@@ -164,6 +292,7 @@ class WebGPUBindingUtils {
 		}
 
 		bindingsData.group = bindGroupGPU;
+		bindingsData.layout = bindLayoutGPU;
 
 	}
 
@@ -225,10 +354,10 @@ class WebGPUBindingUtils {
 	 * Creates a GPU bind group for the camera index.
 	 *
 	 * @param {Uint32Array} data - The index data.
-	 * @param {GPUBindGroupLayout} layoutGPU - The GPU bind group layout.
+	 * @param {GPUBindGroupLayout} layout - The GPU bind group layout.
 	 * @return {GPUBindGroup} The GPU bind group.
 	 */
-	createBindGroupIndex( data, layoutGPU ) {
+	createBindGroupIndex( data, layout ) {
 
 		const backend = this.backend;
 		const device = backend.device;
@@ -248,7 +377,7 @@ class WebGPUBindingUtils {
 
 		return device.createBindGroup( {
 			label: 'bindGroupCameraIndex_' + index,
-			layout: layoutGPU,
+			layout,
 			entries
 		} );
 
@@ -409,242 +538,6 @@ class WebGPUBindingUtils {
 
 	}
 
-	/**
-	 * Creates a bind group layout entry for the given binding.
-	 *
-	 * @param {Binding} binding - The binding.
-	 * @param {number} index - The index of the bind group layout entry in the bind group layout.
-	 * @return {GPUBindGroupLayoutEntry} The bind group layout entry.
-	 */
-	_createBindingLayoutEntry( binding, index ) {
-
-		const backend = this.backend;
-
-		const bindingGPU = {
-			binding: index,
-			visibility: binding.visibility
-		};
-
-		if ( binding.isUniformBuffer || binding.isStorageBuffer ) {
-
-			const buffer = {}; // GPUBufferBindingLayout
-
-			if ( binding.isStorageBuffer ) {
-
-				if ( binding.visibility & GPUShaderStage.COMPUTE ) {
-
-					// compute
-
-					if ( binding.access === NodeAccess.READ_WRITE || binding.access === NodeAccess.WRITE_ONLY ) {
-
-						buffer.type = GPUBufferBindingType.Storage;
-
-					} else {
-
-						buffer.type = GPUBufferBindingType.ReadOnlyStorage;
-
-					}
-
-				} else {
-
-					buffer.type = GPUBufferBindingType.ReadOnlyStorage;
-
-				}
-
-			}
-
-			bindingGPU.buffer = buffer;
-
-		} else if ( binding.isSampledTexture && binding.store ) {
-
-			const storageTexture = {}; // GPUStorageTextureBindingLayout
-			storageTexture.format = this.backend.get( binding.texture ).texture.format;
-
-			const access = binding.access;
-
-			if ( access === NodeAccess.READ_WRITE ) {
-
-				storageTexture.access = GPUStorageTextureAccess.ReadWrite;
-
-			} else if ( access === NodeAccess.WRITE_ONLY ) {
-
-				storageTexture.access = GPUStorageTextureAccess.WriteOnly;
-
-			} else {
-
-				storageTexture.access = GPUStorageTextureAccess.ReadOnly;
-
-			}
-
-			if ( binding.texture.isArrayTexture ) {
-
-				storageTexture.viewDimension = GPUTextureViewDimension.TwoDArray;
-
-			} else if ( binding.texture.is3DTexture ) {
-
-				storageTexture.viewDimension = GPUTextureViewDimension.ThreeD;
-
-			}
-
-			bindingGPU.storageTexture = storageTexture;
-
-		} else if ( binding.isSampledTexture ) {
-
-			const texture = {}; // GPUTextureBindingLayout
-
-			const { primarySamples } = backend.utils.getTextureSampleData( binding.texture );
-
-			if ( primarySamples > 1 ) {
-
-				texture.multisampled = true;
-
-				if ( ! binding.texture.isDepthTexture ) {
-
-					texture.sampleType = GPUTextureSampleType.UnfilterableFloat;
-
-				}
-
-			}
-
-			if ( binding.texture.isDepthTexture ) {
-
-				if ( backend.compatibilityMode && binding.texture.compareFunction === null ) {
-
-					texture.sampleType = GPUTextureSampleType.UnfilterableFloat;
-
-				} else {
-
-					texture.sampleType = GPUTextureSampleType.Depth;
-
-				}
-
-			} else if ( binding.texture.isDataTexture || binding.texture.isDataArrayTexture || binding.texture.isData3DTexture ) {
-
-				const type = binding.texture.type;
-
-				if ( type === IntType ) {
-
-					texture.sampleType = GPUTextureSampleType.SInt;
-
-				} else if ( type === UnsignedIntType ) {
-
-					texture.sampleType = GPUTextureSampleType.UInt;
-
-				} else if ( type === FloatType ) {
-
-					if ( this.backend.hasFeature( 'float32-filterable' ) ) {
-
-						texture.sampleType = GPUTextureSampleType.Float;
-
-					} else {
-
-						texture.sampleType = GPUTextureSampleType.UnfilterableFloat;
-
-					}
-
-				}
-
-			}
-
-			if ( binding.isSampledCubeTexture ) {
-
-				texture.viewDimension = GPUTextureViewDimension.Cube;
-
-			} else if ( binding.texture.isArrayTexture || binding.texture.isDataArrayTexture || binding.texture.isCompressedArrayTexture ) {
-
-				texture.viewDimension = GPUTextureViewDimension.TwoDArray;
-
-			} else if ( binding.isSampledTexture3D ) {
-
-				texture.viewDimension = GPUTextureViewDimension.ThreeD;
-
-			}
-
-			bindingGPU.texture = texture;
-
-		} else if ( binding.isSampler ) {
-
-			const sampler = {}; // GPUSamplerBindingLayout
-
-			if ( binding.texture.isDepthTexture ) {
-
-				if ( binding.texture.compareFunction !== null ) {
-
-					sampler.type = GPUSamplerBindingType.Comparison;
-
-				} else if ( backend.compatibilityMode ) {
-
-					sampler.type = GPUSamplerBindingType.NonFiltering;
-
-				}
-
-			}
-
-			bindingGPU.sampler = sampler;
-
-		} else {
-
-			error( `WebGPUBindingUtils: Unsupported binding "${ binding }".` );
-
-		}
-
-		return bindingGPU;
-
-	}
-
-	/**
-	 * Creates a GPU bind group layout entries for the given bind group.
-	 *
-	 * @param {BindGroup} bindGroup - The bind group.
-	 * @return {Array<GPUBindGroupLayoutEntry>} The GPU bind group layout entries.
-	 */
-	_createBindingsLayoutEntries( bindGroup ) {
-
-		const entries = [];
-		let index = 0;
-
-		for ( const binding of bindGroup.bindings ) {
-
-			entries.push( this._createBindingLayoutEntry( binding, index ) );
-			index ++;
-
-		}
-
-		return entries;
-
-	}
-
-	/**
-	 * Delete the data associated with a bind group.
-	 *
-	 * @param {BindGroup} bindGroup - The bind group.
-	 */
-	deleteBindGroupData( bindGroup ) {
-
-		const { backend } = this;
-
-		const bindingsData = backend.get( bindGroup );
-
-		// Decrement the layout reference's usedTimes attribute
-		bindingsData.layout.usedTimes --;
-
-		// Remove reference from map
-		if ( bindingsData.layout.usedTimes === 0 ) {
-
-			this.bindGroupLayoutCache.delete( bindingsData.layoutKey );
-
-		}
-
-		bindingsData.layout = null;
-
-	}
-
-	dispose() {
-
-		this.bindGroupLayoutCache.clear();
-
-	}
-
 }
 
 export default WebGPUBindingUtils;

+ 2 - 4
src/renderers/webgpu/utils/WebGPUPipelineUtils.js

@@ -106,9 +106,8 @@ class WebGPUPipelineUtils {
 		for ( const bindGroup of renderObject.getBindings() ) {
 
 			const bindingsData = backend.get( bindGroup );
-			const { layoutGPU } = bindingsData.layout;
 
-			bindGroupLayouts.push( layoutGPU );
+			bindGroupLayouts.push( bindingsData.layout );
 
 		}
 
@@ -342,9 +341,8 @@ class WebGPUPipelineUtils {
 		for ( const bindingsGroup of bindings ) {
 
 			const bindingsData = backend.get( bindingsGroup );
-			const { layoutGPU } = bindingsData.layout;
 
-			bindGroupLayouts.push( layoutGPU );
+			bindGroupLayouts.push( bindingsData.layout );
 
 		}
 

粤ICP备19079148号