From 232c9ccfda30280c51c053ccf66e7f006629e1a0 Mon Sep 17 00:00:00 2001 From: Wumpf Date: Sun, 26 Dec 2021 18:07:08 +0100 Subject: [PATCH] [dx12] Fix partial texture barrier not affecting stencil aspect (#2308) * [dx12] Fix partial texture barrier not affecting stencil aspect Fix clearing of D24Plus also clearing "hidden" stencil * [dx12] fix handling stencil only formats for clears & barriers --- wgpu-hal/src/dx12/command.rs | 38 +++++++++++++++++++++++++++--------- wgpu-hal/src/dx12/device.rs | 5 ++++- wgpu-hal/src/dx12/mod.rs | 1 + 3 files changed, 34 insertions(+), 10 deletions(-) diff --git a/wgpu-hal/src/dx12/command.rs b/wgpu-hal/src/dx12/command.rs index 91a6bd9b67..48f72377b0 100644 --- a/wgpu-hal/src/dx12/command.rs +++ b/wgpu-hal/src/dx12/command.rs @@ -319,15 +319,30 @@ 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. + // 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, + 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); + } } } } @@ -607,10 +622,15 @@ 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) { + if !ds.stencil_ops.contains(crate::AttachmentOps::LOAD) + && 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 25423ed5f5..660601d41a 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, + format_aspects: FormatAspects::from(desc.format), 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..b4dd295059 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, + format_aspects: crate::FormatAspects, // May explicitly ignore stencil aspect of raw_format! target_base: (native::Resource, u32), handle_srv: Option, handle_uav: Option,