[dx12] use typeless formats for textures that might be viewed as srgb or non-srgb (#3555)

query `CastingFullyTypedFormatSupported` and skip typeless formats if available
This commit is contained in:
Teodor Tanasoaia 2023-03-03 20:42:34 +01:00 committed by GitHub
parent 7e72f30179
commit 54e4c8654d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 95 additions and 25 deletions

View File

@ -114,6 +114,7 @@ By @teoxoy in [#3534](https://github.com/gfx-rs/wgpu/pull/3534)
#### 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

View File

@ -163,18 +163,48 @@ 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 {
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 {
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,
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)
}
}
pub fn map_index_format(format: wgt::IndexFormat) -> dxgiformat::DXGI_FORMAT {

View File

@ -151,8 +151,18 @@ 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.
let casting_fully_typed_format_supported = {
let mut features3: crate::dx12::types::D3D12_FEATURE_DATA_D3D12_OPTIONS3 =
unsafe { mem::zeroed() };
let hr = unsafe {
device.CheckFeatureSupport(
21, // D3D12_FEATURE_D3D12_OPTIONS3
&mut features3 as *mut _ as *mut _,
mem::size_of::<crate::dx12::types::D3D12_FEATURE_DATA_D3D12_OPTIONS3>() as _,
)
};
hr == 0 && features3.CastingFullyTypedFormatSupported != 0
};
let private_caps = super::PrivateCapabilities {
instance_flags,
@ -166,6 +176,7 @@ impl super::Adapter {
super::MemoryArchitecture::NonUnified
},
heap_create_not_zeroed: false, //TODO: winapi support for Options7
casting_fully_typed_format_supported,
};
// Theoretically vram limited, but in practice 2^20 is the limit

View File

@ -406,20 +406,12 @@ impl crate::Device<super::Api> 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,

View File

@ -41,6 +41,7 @@ mod device;
mod instance;
mod shader_compilation;
mod suballocation;
mod types;
mod view;
use crate::auxil::{self, dxgi::result::HResult as _};
@ -174,6 +175,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)]

View File

@ -0,0 +1,34 @@
#![allow(non_camel_case_types)]
#![allow(non_snake_case)]
winapi::ENUM! {
enum D3D12_VIEW_INSTANCING_TIER {
D3D12_VIEW_INSTANCING_TIER_NOT_SUPPORTED = 0,
D3D12_VIEW_INSTANCING_TIER_1 = 1,
D3D12_VIEW_INSTANCING_TIER_2 = 2,
D3D12_VIEW_INSTANCING_TIER_3 = 3,
}
}
winapi::ENUM! {
enum D3D12_COMMAND_LIST_SUPPORT_FLAGS {
D3D12_COMMAND_LIST_SUPPORT_FLAG_NONE = 0,
// D3D12_COMMAND_LIST_SUPPORT_FLAG_DIRECT,
// D3D12_COMMAND_LIST_SUPPORT_FLAG_BUNDLE,
// D3D12_COMMAND_LIST_SUPPORT_FLAG_COMPUTE,
// D3D12_COMMAND_LIST_SUPPORT_FLAG_COPY,
// D3D12_COMMAND_LIST_SUPPORT_FLAG_VIDEO_DECODE,
// D3D12_COMMAND_LIST_SUPPORT_FLAG_VIDEO_PROCESS,
// D3D12_COMMAND_LIST_SUPPORT_FLAG_VIDEO_ENCODE,
}
}
winapi::STRUCT! {
struct D3D12_FEATURE_DATA_D3D12_OPTIONS3 {
CopyQueueTimestampQueriesSupported: winapi::shared::minwindef::BOOL,
CastingFullyTypedFormatSupported: winapi::shared::minwindef::BOOL,
WriteBufferImmediateSupportFlags: D3D12_COMMAND_LIST_SUPPORT_FLAGS,
ViewInstancingTier: D3D12_VIEW_INSTANCING_TIER,
BarycentricsSupported: winapi::shared::minwindef::BOOL,
}
}