Bläddra i källkod

WebGPURenderer: Prevent duplicated init requests (#25964)

Currently WebGPURenderer init() requests can be duplicated
for example by contiguous .render() calls without await.

With this commit init() request (promise) is cached and
the duplicated requests can be avoided.
Takahiro 2 år sedan
förälder
incheckning
ea321889db
1 ändrade filer med 61 tillägg och 45 borttagningar
  1. 61 45
      examples/jsm/renderers/webgpu/WebGPURenderer.js

+ 61 - 45
examples/jsm/renderers/webgpu/WebGPURenderer.js

@@ -150,6 +150,7 @@ class WebGPURenderer {
 		this._renderTarget = null;
 		this._renderTarget = null;
 
 
 		this._initialized = false;
 		this._initialized = false;
+		this._initPromise = null;
 
 
 		// some parameters require default values other than "undefined"
 		// some parameters require default values other than "undefined"
 
 
@@ -183,75 +184,90 @@ class WebGPURenderer {
 
 
 		}
 		}
 
 
-		const parameters = this._parameters;
+		if ( this._initPromise !== null ) {
 
 
-		const adapterOptions = {
-			powerPreference: parameters.powerPreference
-		};
+			return this._initPromise;
 
 
-		const adapter = await navigator.gpu.requestAdapter( adapterOptions );
+		}
 
 
-		if ( adapter === null ) {
+		this._initPromise = new Promise( async ( resolve, reject ) => {
 
 
-			throw new Error( 'WebGPURenderer: Unable to create WebGPU adapter.' );
+			const parameters = this._parameters;
 
 
-		}
+			const adapterOptions = {
+				powerPreference: parameters.powerPreference
+			};
 
 
-		// feature support
+			const adapter = await navigator.gpu.requestAdapter( adapterOptions );
 
 
-		const features = Object.values( GPUFeatureName );
+			if ( adapter === null ) {
 
 
-		const supportedFeatures = [];
+				reject( new Error( 'WebGPURenderer: Unable to create WebGPU adapter.' ) );
+				return;
 
 
-		for ( const name of features ) {
+			}
 
 
-			if ( adapter.features.has( name ) ) {
+			// feature support
 
 
-				supportedFeatures.push( name );
+			const features = Object.values( GPUFeatureName );
+
+			const supportedFeatures = [];
+
+			for ( const name of features ) {
+
+				if ( adapter.features.has( name ) ) {
+
+					supportedFeatures.push( name );
+
+				}
 
 
 			}
 			}
 
 
-		}
+			const deviceDescriptor = {
+				requiredFeatures: supportedFeatures,
+				requiredLimits: parameters.requiredLimits
+			};
 
 
-		const deviceDescriptor = {
-			requiredFeatures: supportedFeatures,
-			requiredLimits: parameters.requiredLimits
-		};
+			const device = await adapter.requestDevice( deviceDescriptor );
 
 
-		const device = await adapter.requestDevice( deviceDescriptor );
+			const context = ( parameters.context !== undefined ) ? parameters.context : this.domElement.getContext( 'webgpu' );
 
 
-		const context = ( parameters.context !== undefined ) ? parameters.context : this.domElement.getContext( 'webgpu' );
+			this._adapter = adapter;
+			this._device = device;
+			this._context = context;
 
 
-		this._adapter = adapter;
-		this._device = device;
-		this._context = context;
+			this._configureContext();
 
 
-		this._configureContext();
+			this._info = new WebGPUInfo();
+			this._properties = new WebGPUProperties();
+			this._attributes = new WebGPUAttributes( device );
+			this._geometries = new WebGPUGeometries( this._attributes, this._properties, this._info );
+			this._textures = new WebGPUTextures( device, this._properties, this._info );
+			this._utils = new WebGPUUtils( this );
+			this._nodes = new WebGPUNodes( this, this._properties );
+			this._objects = new WebGPURenderObjects( this, this._nodes, this._geometries, this._info );
+			this._computePipelines = new WebGPUComputePipelines( device, this._nodes );
+			this._renderPipelines = new WebGPURenderPipelines( device, this._nodes, this._utils );
+			this._bindings = this._renderPipelines.bindings = new WebGPUBindings( device, this._info, this._properties, this._textures, this._renderPipelines, this._computePipelines, this._attributes, this._nodes );
+			this._renderLists = new WebGPURenderLists();
+			this._renderStates = new WebGPURenderStates();
+			this._background = new WebGPUBackground( this, this._properties );
 
 
-		this._info = new WebGPUInfo();
-		this._properties = new WebGPUProperties();
-		this._attributes = new WebGPUAttributes( device );
-		this._geometries = new WebGPUGeometries( this._attributes, this._properties, this._info );
-		this._textures = new WebGPUTextures( device, this._properties, this._info );
-		this._utils = new WebGPUUtils( this );
-		this._nodes = new WebGPUNodes( this, this._properties );
-		this._objects = new WebGPURenderObjects( this, this._nodes, this._geometries, this._info );
-		this._computePipelines = new WebGPUComputePipelines( device, this._nodes );
-		this._renderPipelines = new WebGPURenderPipelines( device, this._nodes, this._utils );
-		this._bindings = this._renderPipelines.bindings = new WebGPUBindings( device, this._info, this._properties, this._textures, this._renderPipelines, this._computePipelines, this._attributes, this._nodes );
-		this._renderLists = new WebGPURenderLists();
-		this._renderStates = new WebGPURenderStates();
-		this._background = new WebGPUBackground( this, this._properties );
+			//
 
 
-		//
+			this._setupColorBuffer();
+			this._setupDepthBuffer();
 
 
-		this._setupColorBuffer();
-		this._setupDepthBuffer();
+			this._animation.setNodes( this._nodes );
+			this._animation.start();
+
+			this._initialized = true;
+
+			resolve();
 
 
-		this._animation.setNodes( this._nodes );
-		this._animation.start();
+		} );
 
 
-		this._initialized = true;
+		return this._initPromise;
 
 
 	}
 	}