Skip to content

Commit 09430e8

Browse files
aardgooseaardgooseMugen87
authored
WebGPURenderer: Use renderBundles for repeated mipmap creation. (#29197)
* mip bundle * Update WebGPUTexturePassUtils.js Clean up. * label pipelines * simplify --------- Co-authored-by: aardgoose <[email protected]> Co-authored-by: Michael Herzog <[email protected]>
1 parent f22b8b0 commit 09430e8

File tree

1 file changed

+62
-5
lines changed

1 file changed

+62
-5
lines changed

src/renderers/webgpu/utils/WebGPUTexturePassUtils.js

Lines changed: 62 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
1+
import DataMap from '../../common/DataMap.js';
12
import { GPUTextureViewDimension, GPUIndexFormat, GPUFilterMode, GPUPrimitiveTopology, GPULoadOp, GPUStoreOp } from './WebGPUConstants.js';
23

3-
class WebGPUTexturePassUtils {
4+
class WebGPUTexturePassUtils extends DataMap {
45

56
constructor( device ) {
67

8+
super();
9+
710
this.device = device;
811

912
const mipmapVertexSource = `
@@ -99,6 +102,7 @@ fn main( @location( 0 ) vTex : vec2<f32> ) -> @location( 0 ) vec4<f32> {
99102
if ( pipeline === undefined ) {
100103

101104
pipeline = this.device.createRenderPipeline( {
105+
label: `mipmap-${ format }`,
102106
vertex: {
103107
module: this.mipmapVertexShaderModule,
104108
entryPoint: 'main'
@@ -130,6 +134,7 @@ fn main( @location( 0 ) vTex : vec2<f32> ) -> @location( 0 ) vec4<f32> {
130134
if ( pipeline === undefined ) {
131135

132136
pipeline = this.device.createRenderPipeline( {
137+
label: `flipY-${ format }`,
133138
vertex: {
134139
module: this.mipmapVertexShaderModule,
135140
entryPoint: 'main'
@@ -226,9 +231,33 @@ fn main( @location( 0 ) vTex : vec2<f32> ) -> @location( 0 ) vec4<f32> {
226231

227232
generateMipmaps( textureGPU, textureGPUDescriptor, baseArrayLayer = 0 ) {
228233

229-
const pipeline = this.getTransferPipeline( textureGPUDescriptor.format );
234+
const textureData = this.get( textureGPU );
235+
236+
if ( textureData.useCount === undefined ) {
237+
238+
textureData.useCount = 0;
239+
textureData.layers = [];
240+
241+
}
242+
243+
const passes = textureData.layers[ baseArrayLayer ] || this._mipmapCreateBundles( textureGPU, textureGPUDescriptor, baseArrayLayer );
230244

231245
const commandEncoder = this.device.createCommandEncoder( {} );
246+
247+
this._mipmapRunBundles( commandEncoder, passes );
248+
249+
this.device.queue.submit( [ commandEncoder.finish() ] );
250+
251+
if ( textureData.useCount !== 0 ) textureData.layers[ baseArrayLayer ] = passes;
252+
253+
textureData.useCount ++;
254+
255+
}
256+
257+
_mipmapCreateBundles( textureGPU, textureGPUDescriptor, baseArrayLayer ) {
258+
259+
const pipeline = this.getTransferPipeline( textureGPUDescriptor.format );
260+
232261
const bindGroupLayout = pipeline.getBindGroupLayout( 0 ); // @TODO: Consider making this static.
233262

234263
let srcView = textureGPU.createView( {
@@ -238,6 +267,8 @@ fn main( @location( 0 ) vTex : vec2<f32> ) -> @location( 0 ) vec4<f32> {
238267
baseArrayLayer
239268
} );
240269

270+
const passes = [];
271+
241272
for ( let i = 1; i < textureGPUDescriptor.mipLevelCount; i ++ ) {
242273

243274
const bindGroup = this.device.createBindGroup( {
@@ -258,25 +289,51 @@ fn main( @location( 0 ) vTex : vec2<f32> ) -> @location( 0 ) vec4<f32> {
258289
baseArrayLayer
259290
} );
260291

261-
const passEncoder = commandEncoder.beginRenderPass( {
292+
const passDescriptor = {
262293
colorAttachments: [ {
263294
view: dstView,
264295
loadOp: GPULoadOp.Clear,
265296
storeOp: GPUStoreOp.Store,
266297
clearValue: [ 0, 0, 0, 0 ]
267298
} ]
299+
};
300+
301+
const passEncoder = this.device.createRenderBundleEncoder( {
302+
colorFormats: [ textureGPUDescriptor.format ]
268303
} );
269304

270305
passEncoder.setPipeline( pipeline );
271306
passEncoder.setBindGroup( 0, bindGroup );
272307
passEncoder.draw( 4, 1, 0, 0 );
273-
passEncoder.end();
308+
309+
passes.push( {
310+
renderBundles: [ passEncoder.finish() ],
311+
passDescriptor
312+
} );
274313

275314
srcView = dstView;
276315

277316
}
278317

279-
this.device.queue.submit( [ commandEncoder.finish() ] );
318+
return passes;
319+
320+
}
321+
322+
_mipmapRunBundles( commandEncoder, passes ) {
323+
324+
const levels = passes.length;
325+
326+
for ( let i = 0; i < levels; i ++ ) {
327+
328+
const pass = passes[ i ];
329+
330+
const passEncoder = commandEncoder.beginRenderPass( pass.passDescriptor );
331+
332+
passEncoder.executeBundles( pass.renderBundles );
333+
334+
passEncoder.end();
335+
336+
}
280337

281338
}
282339

0 commit comments

Comments
 (0)