1
1
import type { AnyComputeBuiltin , OmitBuiltins } from '../../builtin' ;
2
- import type { AnyWgslData } from '../../data' ;
3
- import type { AnyData } from '../../data/dataTypes' ;
4
- import { invariant } from '../../errors' ;
2
+ import type { AnyData , Disarray } from '../../data/dataTypes' ;
3
+ import type { AnyWgslData , BaseData , WgslArray } from '../../data/wgslTypes' ;
4
+ import {
5
+ MissingBindGroupsError ,
6
+ MissingVertexBuffersError ,
7
+ invariant ,
8
+ } from '../../errors' ;
5
9
import type { JitTranspiler } from '../../jitTranspiler' ;
6
10
import { WeakMemo } from '../../memo' ;
7
11
import {
@@ -25,6 +29,7 @@ import {
25
29
import {
26
30
INTERNAL_createBuffer ,
27
31
type TgpuBuffer ,
32
+ type Vertex ,
28
33
isBuffer ,
29
34
} from '../buffer/buffer' ;
30
35
import type {
@@ -47,9 +52,11 @@ import {
47
52
} from '../pipeline/computePipeline' ;
48
53
import {
49
54
type AnyFragmentTargets ,
55
+ type INTERNAL_TgpuRenderPipeline ,
50
56
INTERNAL_createRenderPipeline ,
51
57
type RenderPipelineCoreOptions ,
52
58
type TgpuRenderPipeline ,
59
+ isRenderPipeline ,
53
60
} from '../pipeline/renderPipeline' ;
54
61
import {
55
62
type TgpuAccessor ,
@@ -79,6 +86,7 @@ import type {
79
86
CreateTextureOptions ,
80
87
CreateTextureResult ,
81
88
ExperimentalTgpuRoot ,
89
+ RenderPass ,
82
90
TgpuRoot ,
83
91
WithBinding ,
84
92
WithCompute ,
@@ -325,6 +333,7 @@ class TgpuRootImpl
325
333
}
326
334
327
335
unwrap ( resource : TgpuComputePipeline ) : GPUComputePipeline ;
336
+ unwrap ( resource : TgpuRenderPipeline ) : GPURenderPipeline ;
328
337
unwrap ( resource : TgpuBindGroupLayout ) : GPUBindGroupLayout ;
329
338
unwrap ( resource : TgpuBindGroup ) : GPUBindGroup ;
330
339
unwrap ( resource : TgpuBuffer < AnyData > ) : GPUBuffer ;
@@ -340,6 +349,7 @@ class TgpuRootImpl
340
349
unwrap (
341
350
resource :
342
351
| TgpuComputePipeline
352
+ | TgpuRenderPipeline
343
353
| TgpuBindGroupLayout
344
354
| TgpuBindGroup
345
355
| TgpuBuffer < AnyData >
@@ -351,6 +361,7 @@ class TgpuRootImpl
351
361
| TgpuVertexLayout ,
352
362
) :
353
363
| GPUComputePipeline
364
+ | GPURenderPipeline
354
365
| GPUBindGroupLayout
355
366
| GPUBindGroup
356
367
| GPUBuffer
@@ -361,6 +372,11 @@ class TgpuRootImpl
361
372
return ( resource as unknown as INTERNAL_TgpuComputePipeline ) . rawPipeline ;
362
373
}
363
374
375
+ if ( isRenderPipeline ( resource ) ) {
376
+ return ( resource as unknown as INTERNAL_TgpuRenderPipeline ) . core . unwrap ( )
377
+ . pipeline ;
378
+ }
379
+
364
380
if ( isBindGroupLayout ( resource ) ) {
365
381
return this . _unwrappedBindGroupLayouts . getOrMake ( resource ) ;
366
382
}
@@ -394,6 +410,160 @@ class TgpuRootImpl
394
410
throw new Error ( `Unknown resource type: ${ resource } ` ) ;
395
411
}
396
412
413
+ beginRenderPass (
414
+ descriptor : GPURenderPassDescriptor ,
415
+ callback : ( pass : RenderPass ) => void ,
416
+ ) : void {
417
+ const pass = this . commandEncoder . beginRenderPass ( descriptor ) ;
418
+
419
+ const bindGroups = new Map <
420
+ TgpuBindGroupLayout ,
421
+ TgpuBindGroup | GPUBindGroup
422
+ > ( ) ;
423
+ const vertexBuffers = new Map <
424
+ TgpuVertexLayout ,
425
+ {
426
+ buffer :
427
+ | ( TgpuBuffer < WgslArray < BaseData > | Disarray < BaseData > > & Vertex )
428
+ | GPUBuffer ;
429
+ offset ?: number | undefined ;
430
+ size ?: number | undefined ;
431
+ }
432
+ > ( ) ;
433
+
434
+ let currentPipeline :
435
+ | ( TgpuRenderPipeline & INTERNAL_TgpuRenderPipeline )
436
+ | undefined ;
437
+
438
+ const setupPassBeforeDraw = ( ) => {
439
+ if ( ! currentPipeline ) {
440
+ throw new Error ( 'Cannot draw without a call to pass.setPipeline' ) ;
441
+ }
442
+
443
+ const { core, priors } = currentPipeline ;
444
+ const memo = core . unwrap ( ) ;
445
+
446
+ pass . setPipeline ( memo . pipeline ) ;
447
+
448
+ const missingBindGroups = new Set ( memo . bindGroupLayouts ) ;
449
+ memo . bindGroupLayouts . forEach ( ( layout , idx ) => {
450
+ if ( memo . catchall && idx === memo . catchall [ 0 ] ) {
451
+ // Catch-all
452
+ pass . setBindGroup ( idx , this . unwrap ( memo . catchall [ 1 ] ) ) ;
453
+ missingBindGroups . delete ( layout ) ;
454
+ } else {
455
+ const bindGroup =
456
+ priors . bindGroupLayoutMap ?. get ( layout ) ?? bindGroups . get ( layout ) ;
457
+ if ( bindGroup !== undefined ) {
458
+ missingBindGroups . delete ( layout ) ;
459
+ if ( isBindGroup ( bindGroup ) ) {
460
+ pass . setBindGroup ( idx , this . unwrap ( bindGroup ) ) ;
461
+ } else {
462
+ pass . setBindGroup ( idx , bindGroup ) ;
463
+ }
464
+ }
465
+ }
466
+ } ) ;
467
+
468
+ const missingVertexLayouts = new Set < TgpuVertexLayout > ( ) ;
469
+ core . usedVertexLayouts . forEach ( ( vertexLayout , idx ) => {
470
+ const opts =
471
+ {
472
+ buffer : priors . vertexLayoutMap ?. get ( vertexLayout ) ,
473
+ offset : undefined ,
474
+ size : undefined ,
475
+ } ?? vertexBuffers . get ( vertexLayout ) ;
476
+
477
+ if ( ! opts || ! opts . buffer ) {
478
+ missingVertexLayouts . add ( vertexLayout ) ;
479
+ } else if ( isBuffer ( opts . buffer ) ) {
480
+ pass . setVertexBuffer (
481
+ idx ,
482
+ this . unwrap ( opts . buffer ) ,
483
+ opts . offset ,
484
+ opts . size ,
485
+ ) ;
486
+ } else {
487
+ pass . setVertexBuffer ( idx , opts . buffer , opts . offset , opts . size ) ;
488
+ }
489
+ } ) ;
490
+
491
+ if ( missingBindGroups . size > 0 ) {
492
+ throw new MissingBindGroupsError ( missingBindGroups ) ;
493
+ }
494
+
495
+ if ( missingVertexLayouts . size > 0 ) {
496
+ throw new MissingVertexBuffersError ( missingVertexLayouts ) ;
497
+ }
498
+ } ;
499
+
500
+ callback ( {
501
+ setViewport ( ...args ) {
502
+ pass . setViewport ( ...args ) ;
503
+ } ,
504
+ setScissorRect ( ...args ) {
505
+ pass . setScissorRect ( ...args ) ;
506
+ } ,
507
+ setBlendConstant ( ...args ) {
508
+ pass . setBlendConstant ( ...args ) ;
509
+ } ,
510
+ setStencilReference ( ...args ) {
511
+ pass . setStencilReference ( ...args ) ;
512
+ } ,
513
+ beginOcclusionQuery ( ...args ) {
514
+ pass . beginOcclusionQuery ( ...args ) ;
515
+ } ,
516
+ endOcclusionQuery ( ...args ) {
517
+ pass . endOcclusionQuery ( ...args ) ;
518
+ } ,
519
+ executeBundles ( ...args ) {
520
+ pass . executeBundles ( ...args ) ;
521
+ } ,
522
+ setPipeline ( pipeline ) {
523
+ currentPipeline = pipeline as TgpuRenderPipeline &
524
+ INTERNAL_TgpuRenderPipeline ;
525
+ } ,
526
+
527
+ setIndexBuffer : ( buffer , indexFormat , offset , size ) => {
528
+ if ( isBuffer ( buffer ) ) {
529
+ pass . setIndexBuffer ( this . unwrap ( buffer ) , indexFormat , offset , size ) ;
530
+ } else {
531
+ pass . setIndexBuffer ( buffer , indexFormat , offset , size ) ;
532
+ }
533
+ } ,
534
+
535
+ setVertexBuffer ( vertexLayout , buffer , offset , size ) {
536
+ vertexBuffers . set ( vertexLayout , { buffer, offset, size } ) ;
537
+ } ,
538
+
539
+ setBindGroup ( bindGroupLayout , bindGroup ) {
540
+ bindGroups . set ( bindGroupLayout , bindGroup ) ;
541
+ } ,
542
+
543
+ draw ( vertexCount , instanceCount , firstVertex , firstInstance ) {
544
+ setupPassBeforeDraw ( ) ;
545
+ pass . draw ( vertexCount , instanceCount , firstVertex , firstInstance ) ;
546
+ } ,
547
+
548
+ drawIndexed ( ...args ) {
549
+ setupPassBeforeDraw ( ) ;
550
+ pass . drawIndexed ( ...args ) ;
551
+ } ,
552
+
553
+ drawIndirect ( ...args ) {
554
+ setupPassBeforeDraw ( ) ;
555
+ pass . drawIndirect ( ...args ) ;
556
+ } ,
557
+
558
+ drawIndexedIndirect ( ...args ) {
559
+ setupPassBeforeDraw ( ) ;
560
+ pass . drawIndexedIndirect ( ...args ) ;
561
+ } ,
562
+ } ) ;
563
+
564
+ pass . end ( ) ;
565
+ }
566
+
397
567
flush ( ) {
398
568
if ( ! this . _commandEncoder ) {
399
569
return ;
0 commit comments