Skip to content

Commit

Permalink
[dx12] use typeless formats for textures that might be viewed as srgb…
Browse files Browse the repository at this point in the history
… or non-srgb

query `CastingFullyTypedFormatSupported` and skip typeless formats if available
  • Loading branch information
teoxoy committed Mar 3, 2023
1 parent e998d7b commit 4507a2b
Show file tree
Hide file tree
Showing 6 changed files with 95 additions and 25 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
48 changes: 39 additions & 9 deletions wgpu-hal/src/auxil/dxgi/conv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
}

Expand Down
15 changes: 13 additions & 2 deletions wgpu-hal/src/dx12/adapter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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
Expand Down
20 changes: 6 additions & 14 deletions wgpu-hal/src/dx12/device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
2 changes: 2 additions & 0 deletions wgpu-hal/src/dx12/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 _};
Expand Down Expand Up @@ -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)]
Expand Down
34 changes: 34 additions & 0 deletions wgpu-hal/src/dx12/types.rs
Original file line number Diff line number Diff line change
@@ -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,
}
}

0 comments on commit 4507a2b

Please sign in to comment.