Browse Source

WebGPURenderer: cache renderPassDesciptors and associated views. (#27518)

* cache descriptors

* check sample count for msaa targets

* add missing ;

* set renderContext depth/stencil state correctly

---------

Co-authored-by: aardgoose <[email protected]>
aardgoose 1 năm trước cách đây
mục cha
commit
aea1821209

+ 4 - 3
examples/jsm/renderers/common/Renderer.js

@@ -266,9 +266,6 @@ class Renderer {
 		renderContext.scissorValue.width >>= activeMipmapLevel;
 		renderContext.scissorValue.height >>= activeMipmapLevel;
 
-		renderContext.depth = this.depth;
-		renderContext.stencil = this.stencil;
-
 		//
 
 		sceneRef.onBeforeRender( this, scene, camera, renderTarget );
@@ -304,6 +301,8 @@ class Renderer {
 			renderContext.width = renderTargetData.width;
 			renderContext.height = renderTargetData.height;
 			renderContext.renderTarget = renderTarget;
+			renderContext.depth = renderTarget.depthBuffer;
+			renderContext.stencil = renderTarget.stencilBuffer;
 
 		} else {
 
@@ -311,6 +310,8 @@ class Renderer {
 			renderContext.depthTexture = null;
 			renderContext.width = this.domElement.width;
 			renderContext.height = this.domElement.height;
+			renderContext.depth = this.depth;
+			renderContext.stencil = this.stencil;
 
 		}
 

+ 3 - 3
examples/jsm/renderers/common/Textures.js

@@ -1,6 +1,6 @@
 import DataMap from './DataMap.js';
 
-import { Vector3, DepthTexture, DepthStencilFormat, UnsignedInt248Type, LinearFilter, NearestFilter, EquirectangularReflectionMapping, EquirectangularRefractionMapping, CubeReflectionMapping, CubeRefractionMapping } from 'three';
+import { Vector3, DepthTexture, DepthStencilFormat, DepthFormat, UnsignedIntType, UnsignedInt248Type, LinearFilter, NearestFilter, EquirectangularReflectionMapping, EquirectangularRefractionMapping, CubeReflectionMapping, CubeRefractionMapping } from 'three';
 
 const _size = new Vector3();
 
@@ -47,8 +47,8 @@ class Textures extends DataMap {
 		if ( depthTexture === undefined ) {
 
 			depthTexture = new DepthTexture();
-			depthTexture.format = DepthStencilFormat;
-			depthTexture.type = UnsignedInt248Type;
+			depthTexture.format = renderTarget.stencilBuffer ? DepthStencilFormat : DepthFormat;
+			depthTexture.type = renderTarget.stencilBuffer ? UnsignedInt248Type : UnsignedIntType;
 			depthTexture.image.width = mipWidth;
 			depthTexture.image.height = mipHeight;
 

+ 126 - 47
examples/jsm/renderers/webgpu/WebGPUBackend.js

@@ -47,6 +47,7 @@ class WebGPUBackend extends Backend {
 		this.device = null;
 		this.context = null;
 		this.colorBuffer = null;
+		this.defaultRenderPassdescriptor = null;
 
 		this.utils = new WebGPUUtils( this );
 		this.attributeUtils = new WebGPUAttributeUtils( this );
@@ -137,60 +138,86 @@ class WebGPUBackend extends Backend {
 
 	}
 
-	beginRender( renderContext ) {
+	_getDefaultRenderPassDescriptor( renderContext ) {
 
-		const renderContextData = this.get( renderContext );
+		let descriptor = this.defaultRenderPassdescriptor;
 
-		const device = this.device;
-		const occlusionQueryCount = renderContext.occlusionQueryCount;
+		const antialias = this.parameters.antialias;
 
-		let occlusionQuerySet;
+		if ( descriptor === null ) {
 
-		if ( occlusionQueryCount > 0 ) {
+			descriptor = {
+				colorAttachments: [ {
+					view: null
+				} ],
+				depthStencilAttachment: {
+					view: this.textureUtils.getDepthBuffer( renderContext.depth, renderContext.stencil ).createView()
+				}
+			};
 
-			if ( renderContextData.currentOcclusionQuerySet ) renderContextData.currentOcclusionQuerySet.destroy();
-			if ( renderContextData.currentOcclusionQueryBuffer ) renderContextData.currentOcclusionQueryBuffer.destroy();
+			const colorAttachment = descriptor.colorAttachments[ 0 ];
 
-			// Get a reference to the array of objects with queries. The renderContextData property
-			// can be changed by another render pass before the buffer.mapAsyc() completes.
-			renderContextData.currentOcclusionQuerySet = renderContextData.occlusionQuerySet;
-			renderContextData.currentOcclusionQueryBuffer = renderContextData.occlusionQueryBuffer;
-			renderContextData.currentOcclusionQueryObjects = renderContextData.occlusionQueryObjects;
+			if ( antialias === true ) {
 
-			//
+				colorAttachment.view = this.colorBuffer.createView();
 
-			occlusionQuerySet = device.createQuerySet( { type: 'occlusion', count: occlusionQueryCount } );
+			} else {
 
-			renderContextData.occlusionQuerySet = occlusionQuerySet;
-			renderContextData.occlusionQueryIndex = 0;
-			renderContextData.occlusionQueryObjects = new Array( occlusionQueryCount );
+				colorAttachment.resolveTarget = undefined;
 
-			renderContextData.lastOcclusionObject = null;
+			}
 
-		}
+			this.defaultRenderPassdescriptor = descriptor;
 
-		const descriptor = {
-			colorAttachments: [ {
-				view: null
-			} ],
-			depthStencilAttachment: {
-				view: null
-			},
-			occlusionQuerySet
-		};
+		}
 
 		const colorAttachment = descriptor.colorAttachments[ 0 ];
-		const depthStencilAttachment = descriptor.depthStencilAttachment;
 
-		const antialias = this.parameters.antialias;
+		if ( antialias === true ) {
 
-		if ( renderContext.textures !== null ) {
+			colorAttachment.resolveTarget = this.context.getCurrentTexture().createView();
 
-			const textures = renderContext.textures;
+		} else {
 
-			descriptor.colorAttachments = [];
+			colorAttachment.view = this.context.getCurrentTexture().createView();
 
-			const colorAttachments = descriptor.colorAttachments;
+		}
+
+		return descriptor;
+
+	}
+
+	_getRenderPassDescriptor( renderContext ) {
+
+		const renderTarget = renderContext.renderTarget;
+		const renderTargetData = this.get( renderTarget );
+
+		let descriptors = renderTargetData.descriptors;
+
+		if ( descriptors === undefined ) {
+
+			descriptors = [];
+
+			renderTargetData.descriptors = descriptors;
+
+		}
+
+		if ( renderTargetData.width !== renderTarget.width ||
+			renderTargetData.height !== renderTarget.height ||
+			renderTargetData.activeMipmapLevel !== renderTarget.activeMipmapLevel ||
+			renderTargetData.samples !== renderTarget.samples
+		) {
+
+			descriptors.length = 0;
+
+		}
+
+		let descriptor = descriptors[ renderContext.activeCubeFace ];
+
+		if ( descriptor === undefined ) {
+
+			const textures = renderContext.textures;
+			const colorAttachments = [];
 
 			for ( let i = 0; i < textures.length; i ++ ) {
 
@@ -228,7 +255,9 @@ class WebGPUBackend extends Backend {
 
 			const depthTextureData = this.get( renderContext.depthTexture );
 
-			depthStencilAttachment.view = depthTextureData.texture.createView();
+			const depthStencilAttachment = {
+				view: depthTextureData.texture.createView(),
+			};
 
 			if ( renderContext.stencil && renderContext.depthTexture.format === DepthFormat ) {
 
@@ -236,24 +265,72 @@ class WebGPUBackend extends Backend {
 
 			}
 
-		} else {
+			descriptor = {
+				colorAttachments,
+				depthStencilAttachment
+			};
 
-			if ( antialias === true ) {
+			descriptors[ renderContext.activeCubeFace ] = descriptor;
 
-				colorAttachment.view = this.colorBuffer.createView();
-				colorAttachment.resolveTarget = this.context.getCurrentTexture().createView();
+			renderTargetData.width = renderTarget.width;
+			renderTargetData.height = renderTarget.height;
+			renderTargetData.samples = renderTarget.samples;
+			renderTargetData.activeMipmapLevel = renderTarget.activeMipmapLevel;
 
-			} else {
+		}
 
-				colorAttachment.view = this.context.getCurrentTexture().createView();
-				colorAttachment.resolveTarget = undefined;
+		return descriptor;
 
-			}
+	}
+
+	beginRender( renderContext ) {
+
+		const renderContextData = this.get( renderContext );
+
+		const device = this.device;
+		const occlusionQueryCount = renderContext.occlusionQueryCount;
+
+		let occlusionQuerySet;
+
+		if ( occlusionQueryCount > 0 ) {
+
+			if ( renderContextData.currentOcclusionQuerySet ) renderContextData.currentOcclusionQuerySet.destroy();
+			if ( renderContextData.currentOcclusionQueryBuffer ) renderContextData.currentOcclusionQueryBuffer.destroy();
+
+			// Get a reference to the array of objects with queries. The renderContextData property
+			// can be changed by another render pass before the buffer.mapAsyc() completes.
+			renderContextData.currentOcclusionQuerySet = renderContextData.occlusionQuerySet;
+			renderContextData.currentOcclusionQueryBuffer = renderContextData.occlusionQueryBuffer;
+			renderContextData.currentOcclusionQueryObjects = renderContextData.occlusionQueryObjects;
+
+			//
+
+			occlusionQuerySet = device.createQuerySet( { type: 'occlusion', count: occlusionQueryCount } );
 
-			depthStencilAttachment.view = this.textureUtils.getDepthBuffer( renderContext.depth, renderContext.stencil ).createView();
+			renderContextData.occlusionQuerySet = occlusionQuerySet;
+			renderContextData.occlusionQueryIndex = 0;
+			renderContextData.occlusionQueryObjects = new Array( occlusionQueryCount );
+
+			renderContextData.lastOcclusionObject = null;
 
 		}
 
+		let descriptor;
+
+		if ( renderContext.textures !== null ) {
+
+			descriptor = this._getRenderPassDescriptor( renderContext );
+
+		} else {
+
+			descriptor = this._getDefaultRenderPassDescriptor( renderContext );
+
+		}
+
+		descriptor.occlusionQuerySet = occlusionQuerySet;
+
+		const depthStencilAttachment = descriptor.depthStencilAttachment;
+
 		if ( renderContext.textures !== null ) {
 
 			const colorAttachments = descriptor.colorAttachments;
@@ -277,9 +354,10 @@ class WebGPUBackend extends Backend {
 
 			}
 
-
 		} else {
 
+			const colorAttachment = descriptor.colorAttachments[ 0 ];
+
 			if ( renderContext.clearColor ) {
 
 				colorAttachment.clearValue = renderContext.clearColorValue;
@@ -1051,7 +1129,8 @@ class WebGPUBackend extends Backend {
 	updateSize() {
 
 		this.colorBuffer = this.textureUtils.getColorBuffer();
-	
+		this.defaultRenderPassdescriptor = null;
+
 	}
 
 	// utils public