@@ -44,6 +44,9 @@ const _indirectOffsets = [ 0 ];
4444const _bundles = [ ] ;
4545const _singleBundleArray = [ null ] ;
4646
47+ const _viewDescriptor = { label : '' , baseMipLevel : 0 , mipLevelCount : 1 , baseArrayLayer : 0 , arrayLayerCount : 1 , dimension : null , depthOrArrayLayers : undefined } ;
48+ const _depthViewOptions = { dimension : undefined , arrayLayerCount : undefined , baseArrayLayer : undefined } ;
49+
4750function _resetCurrentSets ( sets ) {
4851
4952 for ( const key in sets . attributes ) delete sets . attributes [ key ] ;
@@ -531,22 +534,21 @@ class WebGPUBackend extends Backend {
531534
532535 const textureData = this . get ( textures [ i ] ) ;
533536
534- const viewDescriptor = {
535- label : `colorAttachment_${ i } ` ,
536- baseMipLevel : renderContext . activeMipmapLevel ,
537- mipLevelCount : 1 ,
538- baseArrayLayer : renderContext . activeCubeFace ,
539- arrayLayerCount : 1 ,
540- dimension : GPUTextureViewDimension . TwoD
541- } ;
537+ _viewDescriptor . label = 'colorAttachment_' + i ;
538+ _viewDescriptor . baseMipLevel = renderContext . activeMipmapLevel ;
539+ _viewDescriptor . mipLevelCount = 1 ;
540+ _viewDescriptor . baseArrayLayer = renderContext . activeCubeFace ;
541+ _viewDescriptor . arrayLayerCount = 1 ;
542+ _viewDescriptor . dimension = GPUTextureViewDimension . TwoD ;
543+ _viewDescriptor . depthOrArrayLayers = undefined ;
542544
543545 if ( renderTarget . isRenderTarget3D ) {
544546
545547 sliceIndex = renderContext . activeCubeFace ;
546548
547- viewDescriptor . baseArrayLayer = 0 ;
548- viewDescriptor . dimension = GPUTextureViewDimension . ThreeD ;
549- viewDescriptor . depthOrArrayLayers = textures [ i ] . image . depth ;
549+ _viewDescriptor . baseArrayLayer = 0 ;
550+ _viewDescriptor . dimension = GPUTextureViewDimension . ThreeD ;
551+ _viewDescriptor . depthOrArrayLayers = textures [ i ] . image . depth ;
550552
551553 } else if ( renderTarget . isRenderTarget && textures [ i ] . image . depth > 1 ) {
552554
@@ -555,13 +557,12 @@ class WebGPUBackend extends Backend {
555557 const cameras = renderContext . camera . cameras ;
556558 for ( let layer = 0 ; layer < cameras . length ; layer ++ ) {
557559
558- const layerViewDescriptor = {
559- ...viewDescriptor ,
560- baseArrayLayer : layer ,
561- arrayLayerCount : 1 ,
562- dimension : GPUTextureViewDimension . TwoD
563- } ;
564- const textureView = textureData . texture . createView ( layerViewDescriptor ) ;
560+ _viewDescriptor . baseArrayLayer = layer ;
561+ _viewDescriptor . arrayLayerCount = 1 ;
562+ _viewDescriptor . dimension = GPUTextureViewDimension . TwoD ;
563+ _viewDescriptor . depthOrArrayLayers = undefined ;
564+
565+ const textureView = textureData . texture . createView ( _viewDescriptor ) ;
565566 textureViews . push ( {
566567 view : textureView ,
567568 resolveTarget : undefined ,
@@ -572,16 +573,16 @@ class WebGPUBackend extends Backend {
572573
573574 } else {
574575
575- viewDescriptor . dimension = GPUTextureViewDimension . TwoDArray ;
576- viewDescriptor . depthOrArrayLayers = textures [ i ] . image . depth ;
576+ _viewDescriptor . dimension = GPUTextureViewDimension . TwoDArray ;
577+ _viewDescriptor . depthOrArrayLayers = textures [ i ] . image . depth ;
577578
578579 }
579580
580581 }
581582
582583 if ( isRenderCameraDepthArray !== true ) {
583584
584- const textureView = textureData . texture . createView ( viewDescriptor ) ;
585+ const textureView = textureData . texture . createView ( _viewDescriptor ) ;
585586
586587 let view , resolveTarget ;
587588
@@ -612,16 +613,22 @@ class WebGPUBackend extends Backend {
612613 if ( renderContext . depth ) {
613614
614615 const depthTextureData = this . get ( renderContext . depthTexture ) ;
615- const options = { } ;
616+
617+ // Reset then apply only when needed so createView() sees undefined for
618+ // unset fields rather than leftovers from a prior call.
619+ _depthViewOptions . dimension = undefined ;
620+ _depthViewOptions . arrayLayerCount = undefined ;
621+ _depthViewOptions . baseArrayLayer = undefined ;
622+
616623 if ( renderContext . depthTexture . isArrayTexture || renderContext . depthTexture . isCubeTexture ) {
617624
618- options . dimension = GPUTextureViewDimension . TwoD ;
619- options . arrayLayerCount = 1 ;
620- options . baseArrayLayer = renderContext . activeCubeFace ;
625+ _depthViewOptions . dimension = GPUTextureViewDimension . TwoD ;
626+ _depthViewOptions . arrayLayerCount = 1 ;
627+ _depthViewOptions . baseArrayLayer = renderContext . activeCubeFace ;
621628
622629 }
623630
624- descriptorBase . depthStencilView = depthTextureData . texture . createView ( options ) ;
631+ descriptorBase . depthStencilView = depthTextureData . texture . createView ( _depthViewOptions ) ;
625632
626633 }
627634
@@ -724,7 +731,14 @@ class WebGPUBackend extends Backend {
724731
725732 //
726733
727- occlusionQuerySet = device . createQuerySet ( { type : 'occlusion' , count : occlusionQueryCount , label : `occlusionQuerySet_${ renderContext . id } ` } ) ;
734+ if ( renderContextData . occlusionQuerySetDescriptor === undefined ) {
735+
736+ renderContextData . occlusionQuerySetDescriptor = { type : 'occlusion' , count : 0 , label : 'occlusionQuerySet_' + renderContext . id } ;
737+
738+ }
739+
740+ renderContextData . occlusionQuerySetDescriptor . count = occlusionQueryCount ;
741+ occlusionQuerySet = device . createQuerySet ( renderContextData . occlusionQuerySetDescriptor ) ;
728742
729743 renderContextData . occlusionQuerySet = occlusionQuerySet ;
730744 renderContextData . occlusionQueryIndex = 0 ;
@@ -974,7 +988,15 @@ class WebGPUBackend extends Backend {
974988 _createDepthLayerDescriptors ( renderContext , renderContextData , descriptor , cameras ) {
975989
976990 const depthStencilAttachment = descriptor . depthStencilAttachment ;
977- renderContextData . layerDescriptors = [ ] ;
991+ const baseColorAttachment = descriptor . colorAttachments [ 0 ] ;
992+
993+ if ( renderContextData . layerDescriptors === undefined ) {
994+
995+ renderContextData . layerDescriptors = [ ] ;
996+
997+ }
998+
999+ const layerDescriptors = renderContextData . layerDescriptors ;
9781000
9791001 const depthTextureData = this . get ( renderContext . depthTexture ) ;
9801002 if ( ! depthTextureData . viewCache ) {
@@ -985,53 +1007,94 @@ class WebGPUBackend extends Backend {
9851007
9861008 for ( let i = 0 ; i < cameras . length ; i ++ ) {
9871009
988- const layerDescriptor = {
989- ...descriptor ,
990- colorAttachments : [ {
991- ...descriptor . colorAttachments [ 0 ] ,
992- view : descriptor . colorAttachments [ i ] . view
993- } ]
994- } ;
1010+ let layerDescriptor = layerDescriptors [ i ] ;
9951011
996- if ( descriptor . depthStencilAttachment ) {
1012+ if ( layerDescriptor === undefined ) {
9971013
998- const layerIndex = i ;
1014+ layerDescriptor = { colorAttachments : [ { } ] } ;
1015+ layerDescriptors [ i ] = layerDescriptor ;
9991016
1000- if ( ! depthTextureData . viewCache [ layerIndex ] ) {
1017+ }
10011018
1002- depthTextureData . viewCache [ layerIndex ] = depthTextureData . texture . createView ( {
1003- dimension : GPUTextureViewDimension . TwoD ,
1004- baseArrayLayer : i ,
1005- arrayLayerCount : 1
1006- } ) ;
1019+ // Propagate base descriptor fields that aren't color/depth-stencil.
1020+ layerDescriptor . occlusionQuerySet = descriptor . occlusionQuerySet ;
1021+ layerDescriptor . timestampWrites = descriptor . timestampWrites ;
1022+
1023+ // Single color attachment per layer, with this layer's view.
1024+ const colorAttachment = layerDescriptor . colorAttachments [ 0 ] ;
1025+ colorAttachment . view = descriptor . colorAttachments [ i ] . view ;
1026+ colorAttachment . depthSlice = baseColorAttachment . depthSlice ;
1027+ colorAttachment . resolveTarget = baseColorAttachment . resolveTarget ;
1028+ colorAttachment . loadOp = baseColorAttachment . loadOp ;
1029+ colorAttachment . storeOp = baseColorAttachment . storeOp ;
1030+ colorAttachment . clearValue = baseColorAttachment . clearValue ;
1031+
1032+ if ( depthStencilAttachment ) {
1033+
1034+ if ( ! depthTextureData . viewCache [ i ] ) {
1035+
1036+ _depthViewOptions . dimension = GPUTextureViewDimension . TwoD ;
1037+ _depthViewOptions . baseArrayLayer = i ;
1038+ _depthViewOptions . arrayLayerCount = 1 ;
1039+
1040+ depthTextureData . viewCache [ i ] = depthTextureData . texture . createView ( _depthViewOptions ) ;
10071041
10081042 }
10091043
1010- layerDescriptor . depthStencilAttachment = {
1011- view : depthTextureData . viewCache [ layerIndex ] ,
1012- depthLoadOp : depthStencilAttachment . depthLoadOp || GPULoadOp . Clear ,
1013- depthStoreOp : depthStencilAttachment . depthStoreOp || GPUStoreOp . Store ,
1014- depthClearValue : depthStencilAttachment . depthClearValue || 1.0
1015- } ;
1044+ let dsa = layerDescriptor . depthStencilAttachment ;
1045+
1046+ if ( dsa === undefined ) {
1047+
1048+ dsa = { } ;
1049+ layerDescriptor . depthStencilAttachment = dsa ;
1050+
1051+ }
1052+
1053+ dsa . view = depthTextureData . viewCache [ i ] ;
1054+ dsa . depthLoadOp = depthStencilAttachment . depthLoadOp || GPULoadOp . Clear ;
1055+ dsa . depthStoreOp = depthStencilAttachment . depthStoreOp || GPUStoreOp . Store ;
1056+ dsa . depthClearValue = depthStencilAttachment . depthClearValue || 1.0 ;
10161057
10171058 if ( renderContext . stencil ) {
10181059
1019- layerDescriptor . depthStencilAttachment . stencilLoadOp = depthStencilAttachment . stencilLoadOp ;
1020- layerDescriptor . depthStencilAttachment . stencilStoreOp = depthStencilAttachment . stencilStoreOp ;
1021- layerDescriptor . depthStencilAttachment . stencilClearValue = depthStencilAttachment . stencilClearValue ;
1060+ dsa . stencilLoadOp = depthStencilAttachment . stencilLoadOp ;
1061+ dsa . stencilStoreOp = depthStencilAttachment . stencilStoreOp ;
1062+ dsa . stencilClearValue = depthStencilAttachment . stencilClearValue ;
1063+
1064+ } else {
1065+
1066+ dsa . stencilLoadOp = undefined ;
1067+ dsa . stencilStoreOp = undefined ;
1068+ dsa . stencilClearValue = undefined ;
10221069
10231070 }
10241071
10251072 } else {
10261073
1027- layerDescriptor . depthStencilAttachment = { ...depthStencilAttachment } ;
1074+ // Preserve prior behavior of spreading `depthStencilAttachment` when falsy (results in an empty object).
1075+ let dsa = layerDescriptor . depthStencilAttachment ;
10281076
1029- }
1077+ if ( dsa === undefined ) {
10301078
1031- renderContextData . layerDescriptors . push ( layerDescriptor ) ;
1079+ dsa = { } ;
1080+ layerDescriptor . depthStencilAttachment = dsa ;
1081+
1082+ } else {
1083+
1084+ for ( const key in dsa ) delete dsa [ key ] ;
1085+
1086+ }
1087+
1088+ }
10321089
10331090 }
10341091
1092+ // Drop stale entries if cameras.length shrank.
1093+ if ( layerDescriptors . length > cameras . length ) layerDescriptors . length = cameras . length ;
1094+
1095+ // Also drop stale cached depth views beyond current camera count.
1096+ if ( depthTextureData . viewCache . length > cameras . length ) depthTextureData . viewCache . length = cameras . length ;
1097+
10351098 }
10361099
10371100 /**
@@ -1360,7 +1423,7 @@ class WebGPUBackend extends Backend {
13601423 const device = this . device ;
13611424 const renderer = this . renderer ;
13621425
1363- let colorAttachments = [ ] ;
1426+ let colorAttachments ;
13641427 let depthStencilAttachment ;
13651428
13661429 let supportsDepth ;
@@ -1503,24 +1566,29 @@ class WebGPUBackend extends Backend {
15031566 beginCompute ( computeGroup ) {
15041567
15051568 const groupGPU = this . get ( computeGroup ) ;
1506- const isComputeGroup = Array . isArray ( computeGroup ) === true ;
1507- const computeGroupId = isComputeGroup ? computeGroup . map ( computeNode => computeNode . id ) . join ( '_' ) : computeGroup . id ;
15081569 const traceComputeSteps = groupGPU . traceComputeSteps === true ;
15091570
15101571 if ( groupGPU . encoderOptions === undefined ) {
15111572
1512- groupGPU . encoderOptions = { label : 'computeGroup_' + computeGroupId } ;
1573+ const isComputeGroup = Array . isArray ( computeGroup ) === true ;
1574+ const computeGroupId = isComputeGroup ? computeGroup . map ( computeNode => computeNode . id ) . join ( '_' ) : computeGroup . id ;
1575+ const label = 'computeGroup_' + computeGroupId ;
1576+
1577+ groupGPU . encoderOptions = { label } ;
1578+ groupGPU . passDescriptor = { label } ;
1579+ groupGPU . isComputeGroup = isComputeGroup ;
15131580
15141581 }
15151582
15161583 groupGPU . cmdEncoderGPU = this . device . createCommandEncoder ( groupGPU . encoderOptions ) ;
15171584 groupGPU . passEncoderGPU = null ;
15181585
1519- if ( isComputeGroup === false || traceComputeSteps === false ) {
1586+ if ( groupGPU . isComputeGroup === false || traceComputeSteps === false ) {
15201587
1521- const descriptor = {
1522- label : 'computeGroup_' + computeGroupId
1523- } ;
1588+ const descriptor = groupGPU . passDescriptor ;
1589+
1590+ // Clear properties that may have been set by initTimestampQuery on a previous call.
1591+ descriptor . timestampWrites = undefined ;
15241592
15251593 this . initTimestampQuery ( TimestampQuery . COMPUTE , this . getTimestampUID ( computeGroup ) , descriptor ) ;
15261594
0 commit comments