@@ -506,8 +506,60 @@ 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 = 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_stencil = crate :: TextureBarrier {
532+ texture : barrier. texture ,
533+ range : barrier. range ,
534+ usage : barrier. usage . clone ( ) ,
535+ } ;
536+ let mut barrier_depth = barrier;
537+
538+ barrier_depth. range . aspect = wgt:: TextureAspect :: DepthOnly ;
539+ barrier_depth
540+ . usage
541+ . from
542+ . remove ( wgt:: TextureUses :: STENCIL_READ | wgt:: TextureUses :: STENCIL_WRITE ) ;
543+ barrier_depth
544+ . usage
545+ . to
546+ . remove ( wgt:: TextureUses :: STENCIL_READ | wgt:: TextureUses :: STENCIL_WRITE ) ;
547+
548+ barrier_stencil. range . aspect = wgt:: TextureAspect :: StencilOnly ;
549+ barrier_stencil
550+ . usage
551+ . from
552+ . remove ( wgt:: TextureUses :: DEPTH_READ | wgt:: TextureUses :: DEPTH_WRITE ) ;
553+ barrier_stencil
554+ . usage
555+ . to
556+ . remove ( wgt:: TextureUses :: DEPTH_READ | wgt:: TextureUses :: DEPTH_WRITE ) ;
557+ } else {
558+ barriers_ds_split. push ( barrier) ;
559+ }
560+ }
561+
562+ for barrier in & barriers_ds_split {
511563 let s0 = conv:: map_texture_usage_to_state ( barrier. usage . from ) ;
512564 let s1 = conv:: map_texture_usage_to_state ( barrier. usage . to ) ;
513565 if s0 != s1 {
@@ -598,6 +650,12 @@ impl crate::CommandEncoder for super::CommandEncoder {
598650 . ResourceBarrier ( & self . temp . barriers )
599651 } ;
600652 }
653+
654+ barriers_ds_split. clear ( ) ;
655+ self . temp . texture_barriers = barriers_ds_split
656+ . into_iter ( )
657+ . map ( |_| -> crate :: TextureBarrier < ' static , super :: Texture > { unreachable ! ( ) } )
658+ . collect ( ) ;
601659 }
602660
603661 unsafe fn clear_buffer ( & mut self , buffer : & super :: Buffer , range : crate :: MemoryRange ) {
0 commit comments