diff --git a/src/renderers/webgpu/WebGPUBackend.js b/src/renderers/webgpu/WebGPUBackend.js index 0fde9a319689e8..17cb0d8711b459 100644 --- a/src/renderers/webgpu/WebGPUBackend.js +++ b/src/renderers/webgpu/WebGPUBackend.js @@ -1166,7 +1166,7 @@ class WebGPUBackend extends Backend { } - async initTimestampQuery( renderContext, descriptor ) { + initTimestampQuery( renderContext, descriptor ) { if ( ! this.trackTimestamp ) return; @@ -1175,27 +1175,8 @@ class WebGPUBackend extends Backend { if ( ! renderContextData.timeStampQuerySet ) { - // Push an error scope to catch any errors during query set creation - this.device.pushErrorScope( 'out-of-memory' ); - - const timeStampQuerySet = await this.device.createQuerySet( { type: 'timestamp', count: 2, label: `timestamp_renderContext_${renderContext.id}` } ); - - // Pop the error scope and check for errors - const error = await this.device.popErrorScope(); - - if ( error ) { - - if ( ! renderContextData.attemptingTimeStampQuerySetFailed ) { - - console.error( `[GPUOutOfMemoryError][renderContext_${renderContext.id}]:\nFailed to create timestamp query set. This may be because timestamp queries are already running in other tabs.` ); - renderContextData.attemptingTimeStampQuerySetFailed = true; - - } - - renderContextData.timeStampQuerySet = null; // Mark as unavailable - return; - - } + const type = renderContext.isComputeNode ? 'compute' : 'render'; + const timeStampQuerySet = this.device.createQuerySet( { type: 'timestamp', count: 2, label: `timestamp_${type}_${renderContext.id}` } ); const timestampWrites = { querySet: timeStampQuerySet, @@ -1219,7 +1200,6 @@ class WebGPUBackend extends Backend { const renderContextData = this.get( renderContext ); - if ( ! renderContextData.timeStampQuerySet ) return; const size = 2 * BigInt64Array.BYTES_PER_ELEMENT; @@ -1235,18 +1215,21 @@ class WebGPUBackend extends Backend { label: 'timestamp result buffer', size: size, usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ, - } ), - isMappingPending: false, + } ) }; } - const { resolveBuffer, resultBuffer, isMappingPending } = renderContextData.currentTimestampQueryBuffers; + const { resolveBuffer, resultBuffer } = renderContextData.currentTimestampQueryBuffers; - if ( isMappingPending === true ) return; encoder.resolveQuerySet( renderContextData.timeStampQuerySet, 0, 2, resolveBuffer, 0 ); - encoder.copyBufferToBuffer( resolveBuffer, 0, resultBuffer, 0, size ); + + if ( resultBuffer.mapState === 'unmapped' ) { + + encoder.copyBufferToBuffer( resolveBuffer, 0, resultBuffer, 0, size ); + + } } @@ -1256,29 +1239,28 @@ class WebGPUBackend extends Backend { const renderContextData = this.get( renderContext ); - if ( ! renderContextData.timeStampQuerySet ) return; - if ( renderContextData.currentTimestampQueryBuffers === undefined ) return; - const { resultBuffer, isMappingPending } = renderContextData.currentTimestampQueryBuffers; + const { resultBuffer } = renderContextData.currentTimestampQueryBuffers; - if ( isMappingPending === true ) return; + await this.device.queue.onSubmittedWorkDone(); - renderContextData.currentTimestampQueryBuffers.isMappingPending = true; + if ( resultBuffer.mapState === 'unmapped' ) { - resultBuffer.mapAsync( GPUMapMode.READ ).then( () => { + resultBuffer.mapAsync( GPUMapMode.READ ).then( () => { - const times = new BigUint64Array( resultBuffer.getMappedRange() ); - const duration = Number( times[ 1 ] - times[ 0 ] ) / 1000000; + const times = new BigUint64Array( resultBuffer.getMappedRange() ); + const duration = Number( times[ 1 ] - times[ 0 ] ) / 1000000; - this.renderer.info.updateTimestamp( type, duration ); + this.renderer.info.updateTimestamp( type, duration ); - resultBuffer.unmap(); + resultBuffer.unmap(); - renderContextData.currentTimestampQueryBuffers.isMappingPending = false; - } ); + } ); + + } }