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

WebGPURenderer: Improve Sampler disposal. (#33850)

Michael Herzog 2 недель назад
Родитель
Сommit
ad321f20e1

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

@@ -289,6 +289,14 @@ class Backend {
 	 */
 	updateSampler( /*binding*/ ) { }
 
+	/**
+	 * Frees the GPU sampler for the given sampler binding.
+	 *
+	 * @abstract
+	 * @param {Sampler} binding - The sampler binding to free.
+	 */
+	destroySampler( /*binding*/ ) { }
+
 	/**
 	 * Creates a default texture for the given texture that can be used
 	 * as a placeholder until the actual texture is ready for usage.

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

@@ -267,6 +267,12 @@ class Bindings extends DataMap {
 
 					} else if ( binding.isSampler ) {
 
+						if ( binding.isSampledTexture !== true ) {
+
+							this.backend.destroySampler( binding );
+
+						}
+
 						binding.release();
 
 					}

+ 6 - 0
src/renderers/common/Textures.js

@@ -624,6 +624,12 @@ class Textures extends DataMap {
 
 						if ( binding.isSampler && binding.texture === texture ) {
 
+							if ( binding.isSampledTexture !== true ) {
+
+								this.backend.destroySampler( binding );
+
+							}
+
 							binding.reset();
 							binding.release();
 

+ 11 - 0
src/renderers/webgpu/WebGPUBackend.js

@@ -2156,6 +2156,17 @@ class WebGPUBackend extends Backend {
 
 	}
 
+	/**
+	 * Frees the GPU sampler for the given sampler binding.
+	 *
+	 * @param {Sampler} binding - The sampler binding to free.
+	 */
+	destroySampler( binding ) {
+
+		this.textureUtils.destroySampler( binding );
+
+	}
+
 	/**
 	 * Creates a default texture for the given texture that can be used
 	 * as a placeholder until the actual texture is ready for usage.

+ 40 - 13
src/renderers/webgpu/utils/WebGPUTextureUtils.js

@@ -210,20 +210,9 @@ class WebGPUTextureUtils {
 
 		if ( bindingData.sampler !== samplerData.sampler ) {
 
-			// check if previous sampler is unused so it can be deleted
+			// release the previous sampler (if any) so it can be deleted when unused
 
-			if ( bindingData.sampler !== undefined ) {
-
-				const oldSamplerData = this._samplerCache.get( bindingData.samplerKey );
-				oldSamplerData.usedTimes --;
-
-				if ( oldSamplerData.usedTimes === 0 ) {
-
-					this._samplerCache.delete( bindingData.samplerKey );
-
-				}
-
-			}
+			this._releaseSampler( bindingData );
 
 			// update to new sampler data
 
@@ -238,6 +227,44 @@ class WebGPUTextureUtils {
 
 	}
 
+	/**
+	 * Frees the GPU sampler referenced by the given sampler binding.
+	 *
+	 * @param {Sampler} binding - The sampler binding to free.
+	 */
+	destroySampler( binding ) {
+
+		this._releaseSampler( this.backend.get( binding ) );
+
+	}
+
+	/**
+	 * Releases the pooled sampler referenced by the given binding data and
+	 * removes it from the cache when no binding references it anymore.
+	 *
+	 * @private
+	 * @param {Object} bindingData - The binding data holding the sampler reference.
+	 */
+	_releaseSampler( bindingData ) {
+
+		if ( bindingData.sampler !== undefined ) {
+
+			const samplerData = this._samplerCache.get( bindingData.samplerKey );
+			samplerData.usedTimes --;
+
+			if ( samplerData.usedTimes === 0 ) {
+
+				this._samplerCache.delete( bindingData.samplerKey );
+
+			}
+
+			bindingData.sampler = undefined;
+			bindingData.samplerKey = undefined;
+
+		}
+
+	}
+
 	/**
 	 * Creates a default texture for the given texture that can be used
 	 * as a placeholder until the actual texture is ready for usage.

粤ICP备19079148号