Răsfoiți Sursa

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 ani în urmă
părinte
comite
ea321889db
1 a modificat fișierele cu 61 adăugiri și 45 ștergeri
  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._initialized = false;
+		this._initPromise = null;
 
 		// 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;
 
 	}