From c81b62293a5e7d6e46535c22fad77808cbc33e7f Mon Sep 17 00:00:00 2001
From: Logan Benjamin <[EMAIL REDACTED]>
Date: Thu, 24 Apr 2025 11:30:16 +1200
Subject: [PATCH] GPU D3D12 - Update to use typeless formats for depth buffer
(#12701)
For a depth buffer in D3D12 that is also going to be used in a texture sampler, the creation (on an Intel HD 5500 igpu) fails. e.g. SDL_GPUTextureCreateInfo type = TEXTURE_2D, format = D32_FLOAT, usage = DEPTH_STENCIL_TARGET | SAMPLER
The error messages are:
D32_FLOAT
D3D12 ERROR: ID3D12Device::CreateShaderResourceView: The Format (0x29, R32_FLOAT) is invalid when creating a View; the
Resource was already created with a fully qualified Format, which is not castable (0x28, D32_FLOAT).
D24_UNORM
D3D12 ERROR: ID3D12Device::CreateShaderResourceView: For the resource format D24_UNORM_S8_UINT, when making a D3D view, the format name for the view can't be R24_UNORM_X8_TYPELESS.
I found this is because the texture format needs to be created as _TYPELESS, then the views (depth stencil view, shader resource view) should then be created as their respective types - e.g. texture = R32_TYPELESS, dsv = D32_FLOAT, srv = R32_FLOAT
Tested and working on:
NVidia RTX 3050 (D3D12 feature set 12_2)
Intel HD 5500 (D3D12 feature set 11_1)
---
src/gpu/d3d12/SDL_gpu_d3d12.c | 122 ++++++++++++++++++++++++++++++++--
1 file changed, 117 insertions(+), 5 deletions(-)
diff --git a/src/gpu/d3d12/SDL_gpu_d3d12.c b/src/gpu/d3d12/SDL_gpu_d3d12.c
index 01c5c37d6461c..c869d64e06487 100644
--- a/src/gpu/d3d12/SDL_gpu_d3d12.c
+++ b/src/gpu/d3d12/SDL_gpu_d3d12.c
@@ -463,6 +463,115 @@ static DXGI_FORMAT SDLToD3D12_DepthFormat[] = {
};
SDL_COMPILE_TIME_ASSERT(SDLToD3D12_DepthFormat, SDL_arraysize(SDLToD3D12_DepthFormat) == SDL_GPU_TEXTUREFORMAT_MAX_ENUM_VALUE);
+static DXGI_FORMAT SDLToD3D12_TypelessFormat[] = {
+ DXGI_FORMAT_UNKNOWN, // INVALID
+ DXGI_FORMAT_UNKNOWN, // A8_UNORM
+ DXGI_FORMAT_UNKNOWN, // R8_UNORM
+ DXGI_FORMAT_UNKNOWN, // R8G8_UNORM
+ DXGI_FORMAT_UNKNOWN, // R8G8B8A8_UNORM
+ DXGI_FORMAT_UNKNOWN, // R16_UNORM
+ DXGI_FORMAT_UNKNOWN, // R16G16_UNORM
+ DXGI_FORMAT_UNKNOWN, // R16G16B16A16_UNORM
+ DXGI_FORMAT_UNKNOWN, // R10G10B10A2_UNORM
+ DXGI_FORMAT_UNKNOWN, // B5G6R5_UNORM
+ DXGI_FORMAT_UNKNOWN, // B5G5R5A1_UNORM
+ DXGI_FORMAT_UNKNOWN, // B4G4R4A4_UNORM
+ DXGI_FORMAT_UNKNOWN, // B8G8R8A8_UNORM
+ DXGI_FORMAT_UNKNOWN, // BC1_UNORM
+ DXGI_FORMAT_UNKNOWN, // BC2_UNORM
+ DXGI_FORMAT_UNKNOWN, // BC3_UNORM
+ DXGI_FORMAT_UNKNOWN, // BC4_UNORM
+ DXGI_FORMAT_UNKNOWN, // BC5_UNORM
+ DXGI_FORMAT_UNKNOWN, // BC7_UNORM
+ DXGI_FORMAT_UNKNOWN, // BC6H_FLOAT
+ DXGI_FORMAT_UNKNOWN, // BC6H_UFLOAT
+ DXGI_FORMAT_UNKNOWN, // R8_SNORM
+ DXGI_FORMAT_UNKNOWN, // R8G8_SNORM
+ DXGI_FORMAT_UNKNOWN, // R8G8B8A8_SNORM
+ DXGI_FORMAT_UNKNOWN, // R16_SNORM
+ DXGI_FORMAT_UNKNOWN, // R16G16_SNORM
+ DXGI_FORMAT_UNKNOWN, // R16G16B16A16_SNORM
+ DXGI_FORMAT_UNKNOWN, // R16_FLOAT
+ DXGI_FORMAT_UNKNOWN, // R16G16_FLOAT
+ DXGI_FORMAT_UNKNOWN, // R16G16B16A16_FLOAT
+ DXGI_FORMAT_UNKNOWN, // R32_FLOAT
+ DXGI_FORMAT_UNKNOWN, // R32G32_FLOAT
+ DXGI_FORMAT_UNKNOWN, // R32G32B32A32_FLOAT
+ DXGI_FORMAT_UNKNOWN, // R11G11B10_UFLOAT
+ DXGI_FORMAT_UNKNOWN, // R8_UINT
+ DXGI_FORMAT_UNKNOWN, // R8G8_UINT
+ DXGI_FORMAT_UNKNOWN, // R8G8B8A8_UINT
+ DXGI_FORMAT_UNKNOWN, // R16_UINT
+ DXGI_FORMAT_UNKNOWN, // R16G16_UINT
+ DXGI_FORMAT_UNKNOWN, // R16G16B16A16_UINT
+ DXGI_FORMAT_UNKNOWN, // R32_UINT
+ DXGI_FORMAT_UNKNOWN, // R32G32_UINT
+ DXGI_FORMAT_UNKNOWN, // R32G32B32A32_UINT
+ DXGI_FORMAT_UNKNOWN, // R8_INT
+ DXGI_FORMAT_UNKNOWN, // R8G8_INT
+ DXGI_FORMAT_UNKNOWN, // R8G8B8A8_INT
+ DXGI_FORMAT_UNKNOWN, // R16_INT
+ DXGI_FORMAT_UNKNOWN, // R16G16_INT
+ DXGI_FORMAT_UNKNOWN, // R16G16B16A16_INT
+ DXGI_FORMAT_UNKNOWN, // R32_INT
+ DXGI_FORMAT_UNKNOWN, // R32G32_INT
+ DXGI_FORMAT_UNKNOWN, // R32G32B32A32_INT
+ DXGI_FORMAT_UNKNOWN, // R8G8B8A8_UNORM_SRGB
+ DXGI_FORMAT_UNKNOWN, // B8G8R8A8_UNORM_SRGB
+ DXGI_FORMAT_UNKNOWN, // BC1_UNORM_SRGB
+ DXGI_FORMAT_UNKNOWN, // BC2_UNORM_SRGB
+ DXGI_FORMAT_UNKNOWN, // BC3_UNORM_SRGB
+ DXGI_FORMAT_UNKNOWN, // BC7_UNORM_SRGB
+ DXGI_FORMAT_R16_TYPELESS, // D16_UNORM
+ DXGI_FORMAT_R24G8_TYPELESS, // D24_UNORM
+ DXGI_FORMAT_R32_TYPELESS, // D32_FLOAT
+ DXGI_FORMAT_R24G8_TYPELESS, // D24_UNORM_S8_UINT
+ DXGI_FORMAT_R32G8X24_TYPELESS, // D32_FLOAT_S8_UINT
+ DXGI_FORMAT_UNKNOWN, // ASTC_4x4_UNORM
+ DXGI_FORMAT_UNKNOWN, // ASTC_5x4_UNORM
+ DXGI_FORMAT_UNKNOWN, // ASTC_5x5_UNORM
+ DXGI_FORMAT_UNKNOWN, // ASTC_6x5_UNORM
+ DXGI_FORMAT_UNKNOWN, // ASTC_6x6_UNORM
+ DXGI_FORMAT_UNKNOWN, // ASTC_8x5_UNORM
+ DXGI_FORMAT_UNKNOWN, // ASTC_8x6_UNORM
+ DXGI_FORMAT_UNKNOWN, // ASTC_8x8_UNORM
+ DXGI_FORMAT_UNKNOWN, // ASTC_10x5_UNORM
+ DXGI_FORMAT_UNKNOWN, // ASTC_10x6_UNORM
+ DXGI_FORMAT_UNKNOWN, // ASTC_10x8_UNORM
+ DXGI_FORMAT_UNKNOWN, // ASTC_10x10_UNORM
+ DXGI_FORMAT_UNKNOWN, // ASTC_12x10_UNORM
+ DXGI_FORMAT_UNKNOWN, // ASTC_12x12_UNORM
+ DXGI_FORMAT_UNKNOWN, // ASTC_4x4_UNORM_SRGB
+ DXGI_FORMAT_UNKNOWN, // ASTC_5x4_UNORM_SRGB
+ DXGI_FORMAT_UNKNOWN, // ASTC_5x5_UNORM_SRGB
+ DXGI_FORMAT_UNKNOWN, // ASTC_6x5_UNORM_SRGB
+ DXGI_FORMAT_UNKNOWN, // ASTC_6x6_UNORM_SRGB
+ DXGI_FORMAT_UNKNOWN, // ASTC_8x5_UNORM_SRGB
+ DXGI_FORMAT_UNKNOWN, // ASTC_8x6_UNORM_SRGB
+ DXGI_FORMAT_UNKNOWN, // ASTC_8x8_UNORM_SRGB
+ DXGI_FORMAT_UNKNOWN, // ASTC_10x5_UNORM_SRGB
+ DXGI_FORMAT_UNKNOWN, // ASTC_10x6_UNORM_SRGB
+ DXGI_FORMAT_UNKNOWN, // ASTC_10x8_UNORM_SRGB
+ DXGI_FORMAT_UNKNOWN, // ASTC_10x10_UNORM_SRGB
+ DXGI_FORMAT_UNKNOWN, // ASTC_12x10_UNORM_SRGB
+ DXGI_FORMAT_UNKNOWN, // ASTC_12x12_UNORM_SRGB
+ DXGI_FORMAT_UNKNOWN, // ASTC_4x4_FLOAT
+ DXGI_FORMAT_UNKNOWN, // ASTC_5x4_FLOAT
+ DXGI_FORMAT_UNKNOWN, // ASTC_5x5_FLOAT
+ DXGI_FORMAT_UNKNOWN, // ASTC_6x5_FLOAT
+ DXGI_FORMAT_UNKNOWN, // ASTC_6x6_FLOAT
+ DXGI_FORMAT_UNKNOWN, // ASTC_8x5_FLOAT
+ DXGI_FORMAT_UNKNOWN, // ASTC_8x6_FLOAT
+ DXGI_FORMAT_UNKNOWN, // ASTC_8x8_FLOAT
+ DXGI_FORMAT_UNKNOWN, // ASTC_10x5_FLOAT
+ DXGI_FORMAT_UNKNOWN, // ASTC_10x6_FLOAT
+ DXGI_FORMAT_UNKNOWN, // ASTC_10x8_FLOAT
+ DXGI_FORMAT_UNKNOWN, // ASTC_10x10_FLOAT
+ DXGI_FORMAT_UNKNOWN, // ASTC_12x10_FLOAT
+ DXGI_FORMAT_UNKNOWN, // ASTC_12x12_FLOAT
+};
+SDL_COMPILE_TIME_ASSERT(SDLToD3D12_TypelessFormat, SDL_arraysize(SDLToD3D12_TypelessFormat) == SDL_GPU_TEXTUREFORMAT_MAX_ENUM_VALUE);
+
static D3D12_COMPARISON_FUNC SDLToD3D12_CompareOp[] = {
D3D12_COMPARISON_FUNC_NEVER, // INVALID
D3D12_COMPARISON_FUNC_NEVER, // NEVER
@@ -3184,6 +3293,10 @@ static D3D12Texture *D3D12_INTERNAL_CreateTexture(
D3D12_CLEAR_VALUE clearValue;
DXGI_FORMAT format;
bool useClearValue = false;
+ bool needsSRV =
+ (createinfo->usage & SDL_GPU_TEXTUREUSAGE_SAMPLER) ||
+ (createinfo->usage & SDL_GPU_TEXTUREUSAGE_GRAPHICS_STORAGE_READ) ||
+ (createinfo->usage & SDL_GPU_TEXTUREUSAGE_COMPUTE_STORAGE_READ);
bool needsUAV =
(createinfo->usage & SDL_GPU_TEXTUREUSAGE_COMPUTE_STORAGE_WRITE) ||
(createinfo->usage & SDL_GPU_TEXTUREUSAGE_COMPUTE_STORAGE_SIMULTANEOUS_READ_WRITE);
@@ -3203,6 +3316,7 @@ static D3D12Texture *D3D12_INTERNAL_CreateTexture(
if (createinfo->usage & SDL_GPU_TEXTUREUSAGE_COLOR_TARGET) {
resourceFlags |= D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET;
useClearValue = true;
+ clearValue.Format = format;
clearValue.Color[0] = SDL_GetFloatProperty(createinfo->props, SDL_PROP_GPU_TEXTURE_CREATE_D3D12_CLEAR_R_FLOAT, 0);
clearValue.Color[1] = SDL_GetFloatProperty(createinfo->props, SDL_PROP_GPU_TEXTURE_CREATE_D3D12_CLEAR_G_FLOAT, 0);
clearValue.Color[2] = SDL_GetFloatProperty(createinfo->props, SDL_PROP_GPU_TEXTURE_CREATE_D3D12_CLEAR_B_FLOAT, 0);
@@ -3212,9 +3326,10 @@ static D3D12Texture *D3D12_INTERNAL_CreateTexture(
if (createinfo->usage & SDL_GPU_TEXTUREUSAGE_DEPTH_STENCIL_TARGET) {
resourceFlags |= D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL;
useClearValue = true;
+ clearValue.Format = SDLToD3D12_DepthFormat[createinfo->format];
clearValue.DepthStencil.Depth = SDL_GetFloatProperty(createinfo->props, SDL_PROP_GPU_TEXTURE_CREATE_D3D12_CLEAR_DEPTH_FLOAT, 0);
clearValue.DepthStencil.Stencil = (UINT8)SDL_GetNumberProperty(createinfo->props, SDL_PROP_GPU_TEXTURE_CREATE_D3D12_CLEAR_STENCIL_NUMBER, 0);
- format = SDLToD3D12_DepthFormat[createinfo->format];
+ format = needsSRV ? SDLToD3D12_TypelessFormat[createinfo->format] : SDLToD3D12_DepthFormat[createinfo->format];
}
if (needsUAV) {
@@ -3256,7 +3371,6 @@ static D3D12Texture *D3D12_INTERNAL_CreateTexture(
}
initialState = isSwapchainTexture ? D3D12_RESOURCE_STATE_PRESENT : D3D12_INTERNAL_DefaultTextureResourceState(createinfo->usage);
- clearValue.Format = desc.Format;
res = ID3D12Device_CreateCommittedResource(
renderer->device,
@@ -3276,9 +3390,7 @@ static D3D12Texture *D3D12_INTERNAL_CreateTexture(
texture->resource = handle;
// Create the SRV if applicable
- if ((createinfo->usage & SDL_GPU_TEXTUREUSAGE_SAMPLER) ||
- (createinfo->usage & SDL_GPU_TEXTUREUSAGE_GRAPHICS_STORAGE_READ) ||
- (createinfo->usage & SDL_GPU_TEXTUREUSAGE_COMPUTE_STORAGE_READ)) {
+ if (needsSRV) {
D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc;
D3D12_INTERNAL_AssignStagingDescriptorHandle(