mirror of
https://github.com/gfx-rs/wgpu.git
synced 2026-04-22 03:02:01 -04:00
[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:
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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(),
|
||||
|
||||
@@ -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>,
|
||||
|
||||
Reference in New Issue
Block a user