From 025af7d95328d299e7c0ef7c54fcfe8c070cf20b Mon Sep 17 00:00:00 2001 From: teoxoy <28601907+teoxoy@users.noreply.github.com> Date: Fri, 3 Mar 2023 16:57:49 +0100 Subject: [PATCH] [dx12] use typeless formats for textures that might be viewed as srgb or non-srgb --- CHANGELOG.md | 1 + wgpu-hal/src/auxil/dxgi/conv.rs | 48 ++++++++++++++++++++++++++------- wgpu-hal/src/dx12/adapter.rs | 17 ++++++++++-- wgpu-hal/src/dx12/device.rs | 20 +++++--------- wgpu-hal/src/dx12/mod.rs | 1 + 5 files changed, 62 insertions(+), 25 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index da5ac74ff38..fd7d7d46719 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -99,6 +99,7 @@ By @teoxoy in [#3436](https://github.com/gfx-rs/wgpu/pull/3436) #### DX12 - Fix DXC validation issues when using a custom `dxil_path`. By @Elabajaba in [#3434](https://github.com/gfx-rs/wgpu/pull/3434) +- Use typeless formats for textures that might be viewed as srgb or non-srgb. By @teoxoy in [#3555](https://github.com/gfx-rs/wgpu/pull/3555) #### GLES diff --git a/wgpu-hal/src/auxil/dxgi/conv.rs b/wgpu-hal/src/auxil/dxgi/conv.rs index 696e953d146..9cec1432391 100644 --- a/wgpu-hal/src/auxil/dxgi/conv.rs +++ b/wgpu-hal/src/auxil/dxgi/conv.rs @@ -163,17 +163,47 @@ pub fn map_texture_format_for_copy( }) } -pub fn map_texture_format_depth_stencil_typeless( +pub fn map_texture_format_for_resource( format: wgt::TextureFormat, + usage: crate::TextureUses, + has_view_formats: bool, + casting_fully_typed_format_supported: bool, ) -> dxgiformat::DXGI_FORMAT { - match format { - wgt::TextureFormat::Depth16Unorm => dxgiformat::DXGI_FORMAT_R16_TYPELESS, - wgt::TextureFormat::Depth32Float => dxgiformat::DXGI_FORMAT_R32_TYPELESS, - wgt::TextureFormat::Depth32FloatStencil8 => dxgiformat::DXGI_FORMAT_R32G8X24_TYPELESS, - wgt::TextureFormat::Stencil8 - | wgt::TextureFormat::Depth24Plus - | wgt::TextureFormat::Depth24PlusStencil8 => dxgiformat::DXGI_FORMAT_R24G8_TYPELESS, - _ => unreachable!(), + use wgt::TextureFormat as Tf; + use winapi::shared::dxgiformat::*; + + if casting_fully_typed_format_supported { + map_texture_format(format) + + // We might view this resource as srgb or non-srgb + } else if has_view_formats { + match format { + Tf::Rgba8Unorm | Tf::Rgba8UnormSrgb => DXGI_FORMAT_R8G8B8A8_TYPELESS, + Tf::Bgra8Unorm | Tf::Bgra8UnormSrgb => DXGI_FORMAT_B8G8R8A8_TYPELESS, + Tf::Bc1RgbaUnorm | Tf::Bc1RgbaUnormSrgb => DXGI_FORMAT_BC1_TYPELESS, + Tf::Bc2RgbaUnorm | Tf::Bc2RgbaUnormSrgb => DXGI_FORMAT_BC2_TYPELESS, + Tf::Bc3RgbaUnorm | Tf::Bc3RgbaUnormSrgb => DXGI_FORMAT_BC3_TYPELESS, + Tf::Bc7RgbaUnorm | Tf::Bc7RgbaUnormSrgb => DXGI_FORMAT_BC7_TYPELESS, + format => map_texture_format(format), + } + + // We might view this resource as SRV/UAV but also as DSV + } else if format.is_depth_stencil_format() + && usage.intersects( + crate::TextureUses::RESOURCE + | crate::TextureUses::STORAGE_READ + | crate::TextureUses::STORAGE_READ_WRITE, + ) + { + match format { + Tf::Depth16Unorm => DXGI_FORMAT_R16_TYPELESS, + Tf::Depth32Float => DXGI_FORMAT_R32_TYPELESS, + Tf::Depth32FloatStencil8 => DXGI_FORMAT_R32G8X24_TYPELESS, + Tf::Stencil8 | Tf::Depth24Plus | Tf::Depth24PlusStencil8 => DXGI_FORMAT_R24G8_TYPELESS, + _ => unreachable!(), + } + } else { + map_texture_format(format) } } diff --git a/wgpu-hal/src/dx12/adapter.rs b/wgpu-hal/src/dx12/adapter.rs index eed8a4e465f..a9d49a908a5 100644 --- a/wgpu-hal/src/dx12/adapter.rs +++ b/wgpu-hal/src/dx12/adapter.rs @@ -151,8 +151,20 @@ impl super::Adapter { hr == 0 && features2.DepthBoundsTestSupported != 0 }; - //Note: `D3D12_FEATURE_D3D12_OPTIONS3::CastingFullyTypedFormatSupported` can be checked - // to know if we can skip "typeless" formats entirely. + // winapi doesn't have options 3 :( + + // let casting_fully_typed_format_supported = { + // let mut features3: d3d12_ty::D3D12_FEATURE_DATA_D3D12_OPTIONS3 = + // unsafe { mem::zeroed() }; + // let hr = unsafe { + // device.CheckFeatureSupport( + // d3d12_ty::D3D12_FEATURE_D3D12_OPTIONS3, + // &mut features3 as *mut _ as *mut _, + // mem::size_of::() as _, + // ) + // }; + // hr == 0 && features3.CastingFullyTypedFormatSupported != 0 + // }; let private_caps = super::PrivateCapabilities { instance_flags, @@ -166,6 +178,7 @@ impl super::Adapter { super::MemoryArchitecture::NonUnified }, heap_create_not_zeroed: false, //TODO: winapi support for Options7 + casting_fully_typed_format_supported: false, }; // Theoretically vram limited, but in practice 2^20 is the limit diff --git a/wgpu-hal/src/dx12/device.rs b/wgpu-hal/src/dx12/device.rs index 62a7710ce80..24fea556631 100644 --- a/wgpu-hal/src/dx12/device.rs +++ b/wgpu-hal/src/dx12/device.rs @@ -406,20 +406,12 @@ impl crate::Device for super::Device { Height: desc.size.height, DepthOrArraySize: desc.size.depth_or_array_layers as u16, MipLevels: desc.mip_level_count as u16, - Format: if crate::FormatAspects::from(desc.format).contains(crate::FormatAspects::COLOR) - || !desc.usage.intersects( - crate::TextureUses::RESOURCE - | crate::TextureUses::STORAGE_READ - | crate::TextureUses::STORAGE_READ_WRITE, - ) { - auxil::dxgi::conv::map_texture_format(desc.format) - } else { - // This branch is needed if it's a depth texture, and it's ever needed to be viewed as SRV or UAV, - // because then we'd create a non-depth format view of it. - // Note: we can skip this branch if - // `D3D12_FEATURE_D3D12_OPTIONS3::CastingFullyTypedFormatSupported` - auxil::dxgi::conv::map_texture_format_depth_stencil_typeless(desc.format) - }, + Format: auxil::dxgi::conv::map_texture_format_for_resource( + desc.format, + desc.usage, + !desc.view_formats.is_empty(), + self.private_caps.casting_fully_typed_format_supported, + ), SampleDesc: dxgitype::DXGI_SAMPLE_DESC { Count: desc.sample_count, Quality: 0, diff --git a/wgpu-hal/src/dx12/mod.rs b/wgpu-hal/src/dx12/mod.rs index 56070190029..d68117500ce 100644 --- a/wgpu-hal/src/dx12/mod.rs +++ b/wgpu-hal/src/dx12/mod.rs @@ -174,6 +174,7 @@ struct PrivateCapabilities { memory_architecture: MemoryArchitecture, #[allow(unused)] // TODO: Exists until windows-rs is standard, then it can probably be removed? heap_create_not_zeroed: bool, + casting_fully_typed_format_supported: bool, } #[derive(Default)]