mirror of
https://github.com/gfx-rs/wgpu.git
synced 2024-11-25 16:24:24 +00:00
[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:
parent
7e72f30179
commit
54e4c8654d
@ -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
|
||||
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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)]
|
||||
|
34
wgpu-hal/src/dx12/types.rs
Normal file
34
wgpu-hal/src/dx12/types.rs
Normal 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,
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user