From 6cd27f1b073818920a3b5ce36531fdf2d6ac7d21 Mon Sep 17 00:00:00 2001 From: Andreas Reich Date: Sun, 19 Dec 2021 20:52:12 +0100 Subject: [PATCH 1/2] [dx12] Fix partial texture barrier not affecting stencil aspect Fix clearing of D24Plus also clearing "hidden" stencil --- wgpu-hal/src/dx12/command.rs | 34 ++++++++++++++++++++++++++-------- wgpu-hal/src/dx12/device.rs | 5 ++++- wgpu-hal/src/dx12/mod.rs | 1 + 3 files changed, 31 insertions(+), 9 deletions(-) diff --git a/wgpu-hal/src/dx12/command.rs b/wgpu-hal/src/dx12/command.rs index 91a6bd9b67..61e6c88012 100644 --- a/wgpu-hal/src/dx12/command.rs +++ b/wgpu-hal/src/dx12/command.rs @@ -1,3 +1,5 @@ +use crate::FormatAspects; + use super::{conv, HResult as _}; use std::{mem, ops::Range, ptr}; use winapi::um::d3d12; @@ -319,15 +321,29 @@ impl crate::CommandEncoder for super::CommandEncoder { // Only one barrier if it affects the whole image. self.temp.barriers.push(raw); } else { - // Generate barrier for each layer/level combination. + let has_stencil = FormatAspects::from(barrier.texture.format) + .contains(FormatAspects::STENCIL); + let planes = if has_stencil { + match barrier.range.aspect { + wgt::TextureAspect::All => 0..2, + wgt::TextureAspect::StencilOnly => 1..2, + wgt::TextureAspect::DepthOnly => 0..1, + } + } else { + 0..1 + }; + for rel_mip_level in 0..mip_level_count { for rel_array_layer in 0..array_layer_count { - raw.u.Transition_mut().Subresource = barrier.texture.calc_subresource( - barrier.range.base_mip_level + rel_mip_level, - barrier.range.base_array_layer + rel_array_layer, - 0, - ); - self.temp.barriers.push(raw); + for plane in planes.clone() { + raw.u.Transition_mut().Subresource = + barrier.texture.calc_subresource( + barrier.range.base_mip_level + rel_mip_level, + barrier.range.base_array_layer + rel_array_layer, + plane, + ); + self.temp.barriers.push(raw); + } } } } @@ -610,7 +626,9 @@ impl crate::CommandEncoder for super::CommandEncoder { if !ds.depth_ops.contains(crate::AttachmentOps::LOAD) { flags |= native::ClearFlags::DEPTH; } - if !ds.stencil_ops.contains(crate::AttachmentOps::LOAD) { + if !ds.stencil_ops.contains(crate::AttachmentOps::LOAD) + && ds.target.view.has_stencil_aspect + { flags |= native::ClearFlags::STENCIL; } diff --git a/wgpu-hal/src/dx12/device.rs b/wgpu-hal/src/dx12/device.rs index 25423ed5f5..7c7d1fe310 100644 --- a/wgpu-hal/src/dx12/device.rs +++ b/wgpu-hal/src/dx12/device.rs @@ -1,3 +1,5 @@ +use crate::FormatAspects; + use super::{conv, descriptor, view, HResult as _}; use parking_lot::Mutex; use std::{ffi, mem, num::NonZeroU32, ptr, slice, sync::Arc}; @@ -495,6 +497,7 @@ impl crate::Device for super::Device { Ok(super::TextureView { raw_format: view_desc.format, + has_stencil_aspect: FormatAspects::from(desc.format).contains(FormatAspects::STENCIL), target_base: ( texture.resource, texture.calc_subresource(desc.range.base_mip_level, desc.range.base_array_layer, 0), @@ -558,7 +561,7 @@ impl crate::Device for super::Device { .usage .intersects(crate::TextureUses::DEPTH_STENCIL_WRITE) { - let raw_desc = view_desc.to_dsv(crate::FormatAspects::empty()); + let raw_desc = view_desc.to_dsv(FormatAspects::empty()); let handle = self.dsv_pool.lock().alloc_handle(); self.raw.CreateDepthStencilView( texture.resource.as_mut_ptr(), diff --git a/wgpu-hal/src/dx12/mod.rs b/wgpu-hal/src/dx12/mod.rs index 1867d02368..dccabe2262 100644 --- a/wgpu-hal/src/dx12/mod.rs +++ b/wgpu-hal/src/dx12/mod.rs @@ -422,6 +422,7 @@ impl Texture { #[derive(Debug)] pub struct TextureView { raw_format: native::Format, + has_stencil_aspect: bool, target_base: (native::Resource, u32), handle_srv: Option, handle_uav: Option, From e534d758ad73a5f8db8dc84236ce0e2322a62c2e Mon Sep 17 00:00:00 2001 From: Andreas Reich Date: Sun, 26 Dec 2021 14:18:10 +0100 Subject: [PATCH 2/2] [dx12] fix handling stencil only formats for clears & barriers --- wgpu-hal/src/dx12/command.rs | 16 +++++++++------- wgpu-hal/src/dx12/device.rs | 2 +- wgpu-hal/src/dx12/mod.rs | 2 +- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/wgpu-hal/src/dx12/command.rs b/wgpu-hal/src/dx12/command.rs index 61e6c88012..48f72377b0 100644 --- a/wgpu-hal/src/dx12/command.rs +++ b/wgpu-hal/src/dx12/command.rs @@ -1,5 +1,3 @@ -use crate::FormatAspects; - use super::{conv, HResult as _}; use std::{mem, ops::Range, ptr}; use winapi::um::d3d12; @@ -321,9 +319,10 @@ impl crate::CommandEncoder for super::CommandEncoder { // Only one barrier if it affects the whole image. self.temp.barriers.push(raw); } else { - let has_stencil = FormatAspects::from(barrier.texture.format) - .contains(FormatAspects::STENCIL); - let planes = if has_stencil { + // Selected texture aspect is relevant if the texture format has both depth _and_ stencil aspects. + let planes = if crate::FormatAspects::from(barrier.texture.format) + .contains(crate::FormatAspects::DEPTH | crate::FormatAspects::STENCIL) + { match barrier.range.aspect { wgt::TextureAspect::All => 0..2, wgt::TextureAspect::StencilOnly => 1..2, @@ -623,11 +622,14 @@ impl crate::CommandEncoder for super::CommandEncoder { } if let Some(ref ds) = desc.depth_stencil_attachment { let mut flags = native::ClearFlags::empty(); - if !ds.depth_ops.contains(crate::AttachmentOps::LOAD) { + let aspects = ds.target.view.format_aspects; + if !ds.depth_ops.contains(crate::AttachmentOps::LOAD) + && aspects.contains(crate::FormatAspects::DEPTH) + { flags |= native::ClearFlags::DEPTH; } if !ds.stencil_ops.contains(crate::AttachmentOps::LOAD) - && ds.target.view.has_stencil_aspect + && aspects.contains(crate::FormatAspects::STENCIL) { flags |= native::ClearFlags::STENCIL; } diff --git a/wgpu-hal/src/dx12/device.rs b/wgpu-hal/src/dx12/device.rs index 7c7d1fe310..660601d41a 100644 --- a/wgpu-hal/src/dx12/device.rs +++ b/wgpu-hal/src/dx12/device.rs @@ -497,7 +497,7 @@ impl crate::Device for super::Device { Ok(super::TextureView { raw_format: view_desc.format, - has_stencil_aspect: FormatAspects::from(desc.format).contains(FormatAspects::STENCIL), + format_aspects: FormatAspects::from(desc.format), target_base: ( texture.resource, texture.calc_subresource(desc.range.base_mip_level, desc.range.base_array_layer, 0), diff --git a/wgpu-hal/src/dx12/mod.rs b/wgpu-hal/src/dx12/mod.rs index dccabe2262..b4dd295059 100644 --- a/wgpu-hal/src/dx12/mod.rs +++ b/wgpu-hal/src/dx12/mod.rs @@ -422,7 +422,7 @@ impl Texture { #[derive(Debug)] pub struct TextureView { raw_format: native::Format, - has_stencil_aspect: bool, + format_aspects: crate::FormatAspects, // May explicitly ignore stencil aspect of raw_format! target_base: (native::Resource, u32), handle_srv: Option, handle_uav: Option,