[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
This commit is contained in:
Wumpf
2021-12-26 18:07:08 +01:00
committed by GitHub
parent b0654e17af
commit bdfddca628
3 changed files with 34 additions and 10 deletions

View File

@@ -319,15 +319,30 @@ impl crate::CommandEncoder<super::Api> 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<super::Api> 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;
}

View File

@@ -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<super::Api> 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<super::Api> 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(),

View File

@@ -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<descriptor::Handle>,
handle_uav: Option<descriptor::Handle>,