Przeglądaj źródła

WebGPURenderer: WebGLBackend Cleanup RTT buffers when dispose texture (#27513)

* cleanup fbos

* removed unecessary cached sample as its already handled in Textures
Renaud Rohlinger 1 rok temu
rodzic
commit
2997d0c37d

+ 41 - 16
examples/jsm/renderers/webgl/WebGLBackend.js

@@ -112,7 +112,7 @@ class WebGLBackend extends Backend {
 
 	finishRender( renderContext ) {
 
-		const { gl } = this;
+		const { gl, state } = this;
 		const renderContextData = this.get( renderContext );
 		const previousContext = renderContextData.previousContext;
 
@@ -144,18 +144,26 @@ class WebGLBackend extends Backend {
 			const { samples } = renderContext.renderTarget;
 			const fb = renderTargetContextData.framebuffer;
 
+			const mask = gl.COLOR_BUFFER_BIT;
+
 			if ( samples > 0 ) {
 
-				// TODO For loop support MRT
 				const msaaFrameBuffer = renderTargetContextData.msaaFrameBuffer;
 
-				gl.bindFramebuffer( gl.READ_FRAMEBUFFER, msaaFrameBuffer );
-				gl.bindFramebuffer( gl.DRAW_FRAMEBUFFER, fb );
+				const textures = renderContext.textures;
+
+				state.bindFramebuffer( gl.READ_FRAMEBUFFER, msaaFrameBuffer );
+				state.bindFramebuffer( gl.DRAW_FRAMEBUFFER, fb );
+
+				for ( let i = 0; i < textures.length; i ++ ) {
 
+					// TODO Add support for MRT
 
-				gl.blitFramebuffer( 0, 0, renderContext.width, renderContext.height, 0, 0, renderContext.width, renderContext.height, gl.COLOR_BUFFER_BIT, gl.NEAREST );
+					gl.blitFramebuffer( 0, 0, renderContext.width, renderContext.height, 0, 0, renderContext.width, renderContext.height, mask, gl.NEAREST );
 
-				gl.invalidateFramebuffer( gl.READ_FRAMEBUFFER, renderTargetContextData.invalidationArray );
+					gl.invalidateFramebuffer( gl.READ_FRAMEBUFFER, renderTargetContextData.invalidationArray );
+
+				}
 
 			}
 
@@ -869,7 +877,7 @@ class WebGLBackend extends Backend {
 
 			const renderTarget = renderContext.renderTarget;
 			const renderTargetContextData = this.get( renderTarget );
-			const { samples, stencilBuffer } = renderTarget;
+			const { samples, depthBuffer, stencilBuffer } = renderTarget;
 			const cubeFace = this.renderer._activeCubeFace;
 			const isCube = renderTarget.isWebGLCubeRenderTarget === true;
 
@@ -950,20 +958,37 @@ class WebGLBackend extends Backend {
 
 					state.bindFramebuffer( gl.FRAMEBUFFER, msaaFb );
 
-					// TODO For loop support MRT
-					const msaaRenderbuffer = gl.createRenderbuffer();
-					gl.bindRenderbuffer( gl.RENDERBUFFER, msaaRenderbuffer );
+					const msaaRenderbuffers = [];
+
+					const textures = renderContext.textures;
+
+					for ( let i = 0; i < textures.length; i ++ ) {
 
-					const texture = renderContext.textures[ 0 ];
-					const textureData = this.get( texture );
 
-					gl.renderbufferStorageMultisample( gl.RENDERBUFFER, samples, textureData.glInternalFormat, renderContext.width, renderContext.height );
-					gl.framebufferRenderbuffer( gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, msaaRenderbuffer );
+						msaaRenderbuffers[ i ] = gl.createRenderbuffer();
 
-					invalidationArray.push( gl.COLOR_ATTACHMENT0 );
+						gl.bindRenderbuffer( gl.RENDERBUFFER, msaaRenderbuffers[ i ] );
+
+						invalidationArray.push( gl.COLOR_ATTACHMENT0 + i );
+
+						if ( depthBuffer ) {
+
+							const depthStyle = stencilBuffer ? gl.DEPTH_STENCIL_ATTACHMENT : gl.DEPTH_ATTACHMENT;
+							invalidationArray.push( depthStyle );
+
+						}
+
+						const texture = renderContext.textures[ i ];
+						const textureData = this.get( texture );
+
+						gl.renderbufferStorageMultisample( gl.RENDERBUFFER, samples, textureData.glInternalFormat, renderContext.width, renderContext.height );
+						gl.framebufferRenderbuffer( gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + i, gl.RENDERBUFFER, msaaRenderbuffers[ i ] );
+
+
+					}
 
-					renderTargetContextData.msaaRenderbuffer = msaaRenderbuffer;
 					renderTargetContextData.msaaFrameBuffer = msaaFb;
+					renderTargetContextData.msaaRenderbuffers = msaaRenderbuffers;
 
 					if ( depthRenderbuffer === undefined ) {
 

+ 52 - 28
examples/jsm/renderers/webgl/utils/WebGLTextureUtils.js

@@ -408,21 +408,68 @@ class WebGLTextureUtils {
 
 	}
 
-	destroyTexture( texture ) {
+	deallocateRenderBuffers( renderTarget ) {
+
 
 		const { gl, backend } = this;
-		const { textureGPU, renderTarget } = backend.get( texture );
 
 		// remove framebuffer reference
 		if ( renderTarget ) {
 
 			const renderContextData = backend.get( renderTarget );
-			renderContextData.framebuffer = undefined;
-			renderContextData.msaaFrameBuffer = undefined;
-			renderContextData.depthRenderbuffer = undefined;
+
+			renderContextData.renderBufferStorageSetup = undefined;
+
+			if ( renderContextData.framebuffer ) {
+
+				gl.deleteFramebuffer( renderContextData.framebuffer );
+				renderContextData.framebuffer = undefined;
+
+			}
+
+			if ( renderContextData.depthRenderbuffer ) {
+
+				gl.deleteRenderbuffer( renderContextData.depthRenderbuffer );
+				renderContextData.depthRenderbuffer = undefined;
+
+			}
+
+			if ( renderContextData.stencilRenderbuffer ) {
+
+				gl.deleteRenderbuffer( renderContextData.stencilRenderbuffer );
+				renderContextData.stencilRenderbuffer = undefined;
+
+			}
+
+			if ( renderContextData.msaaFrameBuffer ) {
+
+				gl.deleteFramebuffer( renderContextData.msaaFrameBuffer );
+				renderContextData.msaaFrameBuffer = undefined;
+
+			}
+
+			if ( renderContextData.msaaRenderbuffers ) {
+
+				for ( let i = 0; i < renderContextData.msaaRenderbuffers.length; i ++ ) {
+
+					gl.deleteRenderbuffer( renderContextData.msaaRenderbuffers[ i ] );
+
+				}
+
+				renderContextData.msaaRenderbuffers = undefined;
+
+			}
 
 		}
 
+	}
+
+	destroyTexture( texture ) {
+
+		const { gl, backend } = this;
+		const { textureGPU, renderTarget } = backend.get( texture );
+
+		this.deallocateRenderBuffers( renderTarget );
 		gl.deleteTexture( textureGPU );
 
 		backend.delete( texture );
@@ -521,31 +568,8 @@ class WebGLTextureUtils {
 
 			gl.framebufferRenderbuffer( gl.FRAMEBUFFER, gl.DEPTH_STENCIL_ATTACHMENT, gl.RENDERBUFFER, renderbuffer );
 
-		} else {
-
-			const textures = renderContext.textures;
-
-			for ( let i = 0; i < textures.length; i ++ ) {
-
-				const texture = textures[ i ];
-				const { glInternalFormat } = this.get( texture );
-
-				if ( samples > 0 ) {
-
-					gl.renderbufferStorageMultisample( gl.RENDERBUFFER, samples, glInternalFormat, width, height );
-
-				} else {
-
-					gl.renderbufferStorage( gl.RENDERBUFFER, glInternalFormat, width, height );
-
-				}
-
-			}
-
 		}
 
-		gl.bindRenderbuffer( gl.RENDERBUFFER, null );
-
 	}
 
 	async copyTextureToBuffer( texture, x, y, width, height ) {