@@ -506,8 +506,56 @@ impl crate::CommandEncoder for super::CommandEncoder {
506506 T : Iterator < Item = crate :: TextureBarrier < ' a , super :: Texture > > ,
507507 {
508508 self . temp . barriers . clear ( ) ;
509+ self . temp . texture_barriers . clear ( ) ;
510+
511+ let mut barriers_ds_split = core:: mem:: take ( & mut self . temp . texture_barriers )
512+ . into_iter ( )
513+ . map ( |_| -> crate :: TextureBarrier < ' a , super :: Texture > { unreachable ! ( ) } )
514+ . collect :: < Vec < _ > > ( ) ;
509515
510516 for barrier in barriers {
517+ // For depth stencil textures, we generate one `TextureBarrier` with `TextureAspect::All`,
518+ // but in DX12 depth and stencil are subresources and need to be transitioned separately
519+ // to separate their read-only states.
520+ if barrier. usage . from . intersects (
521+ wgt:: TextureUses :: DEPTH_READ
522+ | wgt:: TextureUses :: DEPTH_WRITE
523+ | wgt:: TextureUses :: STENCIL_READ
524+ | wgt:: TextureUses :: STENCIL_WRITE ,
525+ ) || barrier. usage . to . intersects (
526+ wgt:: TextureUses :: DEPTH_READ
527+ | wgt:: TextureUses :: DEPTH_WRITE
528+ | wgt:: TextureUses :: STENCIL_READ
529+ | wgt:: TextureUses :: STENCIL_WRITE ,
530+ ) {
531+ let mut barrier_depth = barrier;
532+ let mut barrier_stencil = barrier;
533+
534+ barrier_depth. range . aspect = wgt:: TextureAspect :: DepthOnly ;
535+ barrier_depth
536+ . usage
537+ . from
538+ . remove ( wgt:: TextureUses :: STENCIL_READ | wgt:: TextureUses :: STENCIL_WRITE ) ;
539+ barrier_depth
540+ . usage
541+ . to
542+ . remove ( wgt:: TextureUses :: STENCIL_READ | wgt:: TextureUses :: STENCIL_WRITE ) ;
543+
544+ barrier_stencil. range . aspect = wgt:: TextureAspect :: StencilOnly ;
545+ barrier_stencil
546+ . usage
547+ . from
548+ . remove ( wgt:: TextureUses :: DEPTH_READ | wgt:: TextureUses :: DEPTH_WRITE ) ;
549+ barrier_stencil
550+ . usage
551+ . to
552+ . remove ( wgt:: TextureUses :: DEPTH_READ | wgt:: TextureUses :: DEPTH_WRITE ) ;
553+ } else {
554+ barriers_ds_split. push ( barrier) ;
555+ }
556+ }
557+
558+ for barrier in barriers_ds_split {
511559 let s0 = conv:: map_texture_usage_to_state ( barrier. usage . from ) ;
512560 let s1 = conv:: map_texture_usage_to_state ( barrier. usage . to ) ;
513561 if s0 != s1 {
@@ -598,6 +646,11 @@ impl crate::CommandEncoder for super::CommandEncoder {
598646 . ResourceBarrier ( & self . temp . barriers )
599647 } ;
600648 }
649+
650+ self . temp . texture_barriers = barriers_ds_split
651+ . into_iter ( )
652+ . map ( |_| -> crate :: TextureBarrier < ' static , super :: Texture > { unreachable ! ( ) } )
653+ . collect ( ) ;
601654 }
602655
603656 unsafe fn clear_buffer ( & mut self , buffer : & super :: Buffer , range : crate :: MemoryRange ) {
0 commit comments