1
+ import DataMap from '../../common/DataMap.js' ;
1
2
import { GPUTextureViewDimension , GPUIndexFormat , GPUFilterMode , GPUPrimitiveTopology , GPULoadOp , GPUStoreOp } from './WebGPUConstants.js' ;
2
3
3
- class WebGPUTexturePassUtils {
4
+ class WebGPUTexturePassUtils extends DataMap {
4
5
5
6
constructor ( device ) {
6
7
8
+ super ( ) ;
9
+
7
10
this . device = device ;
8
11
9
12
const mipmapVertexSource = `
@@ -99,6 +102,7 @@ fn main( @location( 0 ) vTex : vec2<f32> ) -> @location( 0 ) vec4<f32> {
99
102
if ( pipeline === undefined ) {
100
103
101
104
pipeline = this . device . createRenderPipeline ( {
105
+ label : `mipmap-${ format } ` ,
102
106
vertex : {
103
107
module : this . mipmapVertexShaderModule ,
104
108
entryPoint : 'main'
@@ -130,6 +134,7 @@ fn main( @location( 0 ) vTex : vec2<f32> ) -> @location( 0 ) vec4<f32> {
130
134
if ( pipeline === undefined ) {
131
135
132
136
pipeline = this . device . createRenderPipeline ( {
137
+ label : `flipY-${ format } ` ,
133
138
vertex : {
134
139
module : this . mipmapVertexShaderModule ,
135
140
entryPoint : 'main'
@@ -226,9 +231,33 @@ fn main( @location( 0 ) vTex : vec2<f32> ) -> @location( 0 ) vec4<f32> {
226
231
227
232
generateMipmaps ( textureGPU , textureGPUDescriptor , baseArrayLayer = 0 ) {
228
233
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 ) ;
230
244
231
245
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
+
232
261
const bindGroupLayout = pipeline . getBindGroupLayout ( 0 ) ; // @TODO : Consider making this static.
233
262
234
263
let srcView = textureGPU . createView ( {
@@ -238,6 +267,8 @@ fn main( @location( 0 ) vTex : vec2<f32> ) -> @location( 0 ) vec4<f32> {
238
267
baseArrayLayer
239
268
} ) ;
240
269
270
+ const passes = [ ] ;
271
+
241
272
for ( let i = 1 ; i < textureGPUDescriptor . mipLevelCount ; i ++ ) {
242
273
243
274
const bindGroup = this . device . createBindGroup ( {
@@ -258,25 +289,51 @@ fn main( @location( 0 ) vTex : vec2<f32> ) -> @location( 0 ) vec4<f32> {
258
289
baseArrayLayer
259
290
} ) ;
260
291
261
- const passEncoder = commandEncoder . beginRenderPass ( {
292
+ const passDescriptor = {
262
293
colorAttachments : [ {
263
294
view : dstView ,
264
295
loadOp : GPULoadOp . Clear ,
265
296
storeOp : GPUStoreOp . Store ,
266
297
clearValue : [ 0 , 0 , 0 , 0 ]
267
298
} ]
299
+ } ;
300
+
301
+ const passEncoder = this . device . createRenderBundleEncoder ( {
302
+ colorFormats : [ textureGPUDescriptor . format ]
268
303
} ) ;
269
304
270
305
passEncoder . setPipeline ( pipeline ) ;
271
306
passEncoder . setBindGroup ( 0 , bindGroup ) ;
272
307
passEncoder . draw ( 4 , 1 , 0 , 0 ) ;
273
- passEncoder . end ( ) ;
308
+
309
+ passes . push ( {
310
+ renderBundles : [ passEncoder . finish ( ) ] ,
311
+ passDescriptor
312
+ } ) ;
274
313
275
314
srcView = dstView ;
276
315
277
316
}
278
317
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
+ }
280
337
281
338
}
282
339
0 commit comments