Browse Source

WebGPURenderer: Rework to use a single renderBundle per Group().static object (#29239)

Co-authored-by: aardgoose <angus.sawyer@email.com>
aardgoose 1 year ago
parent
commit
1c92c7b694

+ 15 - 30
src/renderers/common/Renderer.js

@@ -411,13 +411,12 @@ class Renderer {
 		const { object, camera, renderList } = bundle;
 
 		const renderContext = this._currentRenderContext;
-		const renderContextData = this.backend.get( renderContext );
 
 		//
 
 		const renderBundle = this._bundles.get( object, camera );
-
 		const renderBundleData = this.backend.get( renderBundle );
+
 		if ( renderBundleData.renderContexts === undefined ) renderBundleData.renderContexts = new Set();
 
 		//
@@ -428,17 +427,11 @@ class Renderer {
 
 		if ( renderBundleNeedsUpdate ) {
 
-			if ( renderContextData.renderObjects === undefined || object.needsUpdate === true ) {
+			this.backend.beginBundle( renderContext );
 
-				const nodeFrame = this._nodes.nodeFrame;
+			if ( renderBundleData.renderObjects === undefined || object.needsUpdate === true ) {
 
-				renderContextData.renderObjects = [];
-				renderContextData.renderBundles = [];
-				renderContextData.scene = sceneRef;
-				renderContextData.camera = camera;
-				renderContextData.renderId = nodeFrame.renderId;
-
-				renderContextData.registerBundlesPhase = true;
+				renderBundleData.renderObjects = [];
 
 			}
 
@@ -452,16 +445,17 @@ class Renderer {
 
 			//
 
+			this.backend.finishBundle( renderContext, renderBundle );
+
 			object.needsUpdate = false;
 
 		} else {
 
-			const renderContext = this._currentRenderContext;
-			const renderContextData = this.backend.get( renderContext );
+			const renderObjects = renderBundleData.renderObjects;
 
-			for ( let i = 0, l = renderContextData.renderObjects.length; i < l; i ++ ) {
+			for ( let i = 0, l = renderObjects.length; i < l; i ++ ) {
 
-				const renderObject = renderContextData.renderObjects[ i ];
+				const renderObject = renderObjects[ i ];
 
 				this._nodes.updateBefore( renderObject );
 
@@ -473,14 +467,14 @@ class Renderer {
 				this._nodes.updateForRender( renderObject );
 				this._bindings.updateForRender( renderObject );
 
-				this.backend.draw( renderObject, this.info );
-
 				this._nodes.updateAfter( renderObject );
 
 			}
 
 		}
 
+		this.backend.addBundle( renderContext, renderBundle );
+
 	}
 
 	render( scene, camera ) {
@@ -1371,7 +1365,7 @@ class Renderer {
 
 		}
 
-		if ( object.static === true ) {
+		if ( object.static === true && this.backend.beginBundle !== undefined ) {
 
 			const baseRenderList = renderList;
 
@@ -1601,25 +1595,16 @@ class Renderer {
 
 		//
 
-		if ( this._currentRenderBundle !== null && this._currentRenderBundle.needsUpdate === true ) {
+		if ( this._currentRenderBundle !== null ) {
 
-			const renderObjectData = this.backend.get( renderObject );
+			const renderBundleData = this.backend.get( this._currentRenderBundle );
 
-			renderObjectData.bundleEncoder = undefined;
-			renderObjectData.lastPipelineGPU = undefined;
+			renderBundleData.renderObjects.push( renderObject );
 
 		}
 
 		this.backend.draw( renderObject, this.info );
 
-		if ( this._currentRenderBundle !== null ) {
-
-			const renderContextData = this.backend.get( this._currentRenderContext );
-
-			renderContextData.renderObjects.push( renderObject );
-
-		}
-
 		this._nodes.updateAfter( renderObject );
 
 	}

+ 38 - 28
src/renderers/webgpu/WebGPUBackend.js

@@ -425,7 +425,8 @@ class WebGPUBackend extends Backend {
 		renderContextData.descriptor = descriptor;
 		renderContextData.encoder = encoder;
 		renderContextData.currentPass = currentPass;
-		renderContextData.currentSets = { attributes: {} };
+		renderContextData.currentSets = { attributes: {}, pipeline: null, index: null };
+		renderContextData.renderBundles = [];
 
 		//
 
@@ -450,9 +451,8 @@ class WebGPUBackend extends Backend {
 		const renderContextData = this.get( renderContext );
 		const occlusionQueryCount = renderContext.occlusionQueryCount;
 
-		if ( renderContextData.renderBundles !== undefined && renderContextData.renderBundles.length > 0 ) {
+		if ( renderContextData.renderBundles.length > 0 ) {
 
-			renderContextData.registerBundlesPhase = false;
 			renderContextData.currentPass.executeBundles( renderContextData.renderBundles );
 
 		}
@@ -834,19 +834,7 @@ class WebGPUBackend extends Backend {
 		const renderContextData = this.get( context );
 		const pipelineGPU = this.get( pipeline ).pipeline;
 		const currentSets = renderContextData.currentSets;
-
-		const renderObjectData = this.get( renderObject );
-
-		const { bundleEncoder, renderBundle, lastPipelineGPU } = renderObjectData;
-
-		if ( renderContextData.registerBundlesPhase === true && bundleEncoder !== undefined && lastPipelineGPU === pipelineGPU ) {
-
-			renderContextData.renderBundles.push( renderBundle );
-			return;
-
-		}
-
-		const passEncoderGPU = this.renderer._currentRenderBundle ? this.createBundleEncoder( context, renderObject ) : renderContextData.currentPass;
+		const passEncoderGPU = renderContextData.currentPass;
 
 		// pipeline
 
@@ -984,15 +972,6 @@ class WebGPUBackend extends Backend {
 
 		}
 
-		if ( this.renderer._currentRenderBundle ) {
-
-			const renderBundle = passEncoderGPU.finish();
-			renderObjectData.lastPipelineGPU = pipelineGPU;
-			renderObjectData.renderBundle = renderBundle;
-			renderObjectData.bundleEncoder = passEncoderGPU;
-
-		}
-
 	}
 
 	// cache key
@@ -1078,6 +1057,7 @@ class WebGPUBackend extends Backend {
 
 	}
 
+
 	// textures
 
 	createSampler( texture ) {
@@ -1266,9 +1246,39 @@ class WebGPUBackend extends Backend {
 
 	}
 
-	createBundleEncoder( renderContext, renderObject ) {
+	beginBundle( renderContext ) {
+
+		const renderContextData = this.get( renderContext );
+
+		renderContextData._currentPass = renderContextData.currentPass;
+		renderContextData._currentSets = renderContextData.currentSets;
+
+		renderContextData.currentSets = { attributes: {}, pipeline: null, index: null };
+		renderContextData.currentPass = this.pipelineUtils.createBundleEncoder( renderContext );
+
+	}
+
+	finishBundle( renderContext, bundle ) {
+
+		const renderContextData = this.get( renderContext );
+
+		const bundleEncoder = renderContextData.currentPass;
+		const bundleGPU = bundleEncoder.finish();
+
+		this.get( bundle ).bundleGPU = bundleGPU;
+
+		// restore render pass state
+
+		renderContextData.currentSets = renderContextData._currentSets;
+		renderContextData.currentPass = renderContextData._currentPass;
+
+	}
+
+	addBundle( renderContext, bundle ) {
+
+		const renderContextData = this.get( renderContext );
 
-		return this.pipelineUtils.createBundleEncoder( renderContext, renderObject );
+		renderContextData.renderBundles.push( this.get( bundle ).bundleGPU );
 
 	}
 
@@ -1472,7 +1482,7 @@ class WebGPUBackend extends Backend {
 		if ( renderContext.stencil ) descriptor.depthStencilAttachment.stencilLoadOp = GPULoadOp.Load;
 
 		renderContextData.currentPass = encoder.beginRenderPass( descriptor );
-		renderContextData.currentSets = { attributes: {} };
+		renderContextData.currentSets = { attributes: {}, pipeline: null, index: null };
 
 	}
 

+ 3 - 12
src/renderers/webgpu/utils/WebGPUPipelineUtils.js

@@ -168,17 +168,14 @@ class WebGPUPipelineUtils {
 
 	}
 
-	createBundleEncoder( renderContext, renderObject ) {
+	createBundleEncoder( renderContext ) {
 
 		const backend = this.backend;
 		const { utils, device } = backend;
 
-		const renderContextData = backend.get( renderContext );
-		const renderObjectData = backend.get( renderObject );
-
 		const depthStencilFormat = utils.getCurrentDepthStencilFormat( renderContext );
 		const colorFormat = utils.getCurrentColorFormat( renderContext );
-		const sampleCount = this._getSampleCount( renderObject.context );
+		const sampleCount = this._getSampleCount( renderContext );
 
 		const descriptor = {
 			label: 'renderBundleEncoder',
@@ -187,13 +184,7 @@ class WebGPUPipelineUtils {
 			sampleCount
 		};
 
-		const bundleEncoder = device.createRenderBundleEncoder( descriptor );
-
-		renderObjectData.bundleEncoder = bundleEncoder;
-		renderContextData.currentSets = { attributes: {} };
-		renderContextData._renderBundleViewport = renderContext.width + '_' + renderContext.height;
-
-		return bundleEncoder;
+		return device.createRenderBundleEncoder( descriptor );
 
 	}
 

粤ICP备19079148号