Skip to content

Commit

Permalink
WebGPURenderer: Use renderBundles for repeated mipmap creation. (#29197)
Browse files Browse the repository at this point in the history
* mip bundle

* Update WebGPUTexturePassUtils.js

Clean up.

* label pipelines

* simplify

---------

Co-authored-by: aardgoose <[email protected]>
Co-authored-by: Michael Herzog <[email protected]>
  • Loading branch information
3 people authored Aug 22, 2024
1 parent f22b8b0 commit 09430e8
Showing 1 changed file with 62 additions and 5 deletions.
67 changes: 62 additions & 5 deletions src/renderers/webgpu/utils/WebGPUTexturePassUtils.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import DataMap from '../../common/DataMap.js';
import { GPUTextureViewDimension, GPUIndexFormat, GPUFilterMode, GPUPrimitiveTopology, GPULoadOp, GPUStoreOp } from './WebGPUConstants.js';

class WebGPUTexturePassUtils {
class WebGPUTexturePassUtils extends DataMap {

constructor( device ) {

super();

this.device = device;

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

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

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

generateMipmaps( textureGPU, textureGPUDescriptor, baseArrayLayer = 0 ) {

const pipeline = this.getTransferPipeline( textureGPUDescriptor.format );
const textureData = this.get( textureGPU );

if ( textureData.useCount === undefined ) {

textureData.useCount = 0;
textureData.layers = [];

}

const passes = textureData.layers[ baseArrayLayer ] || this._mipmapCreateBundles( textureGPU, textureGPUDescriptor, baseArrayLayer );

const commandEncoder = this.device.createCommandEncoder( {} );

this._mipmapRunBundles( commandEncoder, passes );

this.device.queue.submit( [ commandEncoder.finish() ] );

if ( textureData.useCount !== 0 ) textureData.layers[ baseArrayLayer ] = passes;

textureData.useCount ++;

}

_mipmapCreateBundles( textureGPU, textureGPUDescriptor, baseArrayLayer ) {

const pipeline = this.getTransferPipeline( textureGPUDescriptor.format );

const bindGroupLayout = pipeline.getBindGroupLayout( 0 ); // @TODO: Consider making this static.

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

const passes = [];

for ( let i = 1; i < textureGPUDescriptor.mipLevelCount; i ++ ) {

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

const passEncoder = commandEncoder.beginRenderPass( {
const passDescriptor = {
colorAttachments: [ {
view: dstView,
loadOp: GPULoadOp.Clear,
storeOp: GPUStoreOp.Store,
clearValue: [ 0, 0, 0, 0 ]
} ]
};

const passEncoder = this.device.createRenderBundleEncoder( {
colorFormats: [ textureGPUDescriptor.format ]
} );

passEncoder.setPipeline( pipeline );
passEncoder.setBindGroup( 0, bindGroup );
passEncoder.draw( 4, 1, 0, 0 );
passEncoder.end();

passes.push( {
renderBundles: [ passEncoder.finish() ],
passDescriptor
} );

srcView = dstView;

}

this.device.queue.submit( [ commandEncoder.finish() ] );
return passes;

}

_mipmapRunBundles( commandEncoder, passes ) {

const levels = passes.length;

for ( let i = 0; i < levels; i ++ ) {

const pass = passes[ i ];

const passEncoder = commandEncoder.beginRenderPass( pass.passDescriptor );

passEncoder.executeBundles( pass.renderBundles );

passEncoder.end();

}

}

Expand Down

0 comments on commit 09430e8

Please sign in to comment.