GPU D3D12: Fix depth texture sampling

This commit is contained in:
cosmonaut
2024-10-29 12:05:35 -07:00
parent ff14a1781f
commit 014b473bcc

View File

@@ -248,6 +248,8 @@ static D3D12_BLEND_OP SDLToD3D12_BlendOp[] = {
}; };
SDL_COMPILE_TIME_ASSERT(SDLToD3D12_BlendOp, SDL_arraysize(SDLToD3D12_BlendOp) == SDL_GPU_BLENDOP_MAX_ENUM_VALUE); SDL_COMPILE_TIME_ASSERT(SDLToD3D12_BlendOp, SDL_arraysize(SDLToD3D12_BlendOp) == SDL_GPU_BLENDOP_MAX_ENUM_VALUE);
// These are actually color formats.
// For some genius reason, D3D12 splits format capabilites for depth-stencil views.
static DXGI_FORMAT SDLToD3D12_TextureFormat[] = { static DXGI_FORMAT SDLToD3D12_TextureFormat[] = {
DXGI_FORMAT_UNKNOWN, // INVALID DXGI_FORMAT_UNKNOWN, // INVALID
DXGI_FORMAT_A8_UNORM, // A8_UNORM DXGI_FORMAT_A8_UNORM, // A8_UNORM
@@ -307,6 +309,115 @@ static DXGI_FORMAT SDLToD3D12_TextureFormat[] = {
DXGI_FORMAT_BC2_UNORM_SRGB, // BC2_UNORM_SRGB DXGI_FORMAT_BC2_UNORM_SRGB, // BC2_UNORM_SRGB
DXGI_FORMAT_BC3_UNORM_SRGB, // BC3_UNORM_SRGB DXGI_FORMAT_BC3_UNORM_SRGB, // BC3_UNORM_SRGB
DXGI_FORMAT_BC7_UNORM_SRGB, // BC7_UNORM_SRGB DXGI_FORMAT_BC7_UNORM_SRGB, // BC7_UNORM_SRGB
DXGI_FORMAT_R16_UNORM, // D16_UNORM
DXGI_FORMAT_R24_UNORM_X8_TYPELESS, // D24_UNORM
DXGI_FORMAT_R32_FLOAT, // D32_FLOAT
DXGI_FORMAT_R24_UNORM_X8_TYPELESS, // D24_UNORM_S8_UINT
DXGI_FORMAT_R32_FLOAT_X8X24_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_TextureFormat, SDL_arraysize(SDLToD3D12_TextureFormat) == SDL_GPU_TEXTUREFORMAT_MAX_ENUM_VALUE);
static DXGI_FORMAT SDLToD3D12_DepthFormat[] = {
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_D16_UNORM, // D16_UNORM DXGI_FORMAT_D16_UNORM, // D16_UNORM
DXGI_FORMAT_D24_UNORM_S8_UINT, // D24_UNORM DXGI_FORMAT_D24_UNORM_S8_UINT, // D24_UNORM
DXGI_FORMAT_D32_FLOAT, // D32_FLOAT DXGI_FORMAT_D32_FLOAT, // D32_FLOAT
@@ -355,7 +466,7 @@ static DXGI_FORMAT SDLToD3D12_TextureFormat[] = {
DXGI_FORMAT_UNKNOWN, // ASTC_12x10_FLOAT DXGI_FORMAT_UNKNOWN, // ASTC_12x10_FLOAT
DXGI_FORMAT_UNKNOWN, // ASTC_12x12_FLOAT DXGI_FORMAT_UNKNOWN, // ASTC_12x12_FLOAT
}; };
SDL_COMPILE_TIME_ASSERT(SDLToD3D12_TextureFormat, SDL_arraysize(SDLToD3D12_TextureFormat) == SDL_GPU_TEXTUREFORMAT_MAX_ENUM_VALUE); SDL_COMPILE_TIME_ASSERT(SDLToD3D12_DepthFormat, SDL_arraysize(SDLToD3D12_DepthFormat) == SDL_GPU_TEXTUREFORMAT_MAX_ENUM_VALUE);
static D3D12_COMPARISON_FUNC SDLToD3D12_CompareOp[] = { static D3D12_COMPARISON_FUNC SDLToD3D12_CompareOp[] = {
D3D12_COMPARISON_FUNC_NEVER, // INVALID D3D12_COMPARISON_FUNC_NEVER, // INVALID
@@ -2691,7 +2802,7 @@ static SDL_GPUGraphicsPipeline *D3D12_CreateGraphicsPipeline(
psoDesc.SampleDesc.Count = SDLToD3D12_SampleCount[createinfo->multisample_state.sample_count]; psoDesc.SampleDesc.Count = SDLToD3D12_SampleCount[createinfo->multisample_state.sample_count];
psoDesc.SampleDesc.Quality = (createinfo->multisample_state.sample_count > SDL_GPU_SAMPLECOUNT_1) ? D3D12_STANDARD_MULTISAMPLE_PATTERN : 0; psoDesc.SampleDesc.Quality = (createinfo->multisample_state.sample_count > SDL_GPU_SAMPLECOUNT_1) ? D3D12_STANDARD_MULTISAMPLE_PATTERN : 0;
psoDesc.DSVFormat = SDLToD3D12_TextureFormat[createinfo->target_info.depth_stencil_format]; psoDesc.DSVFormat = SDLToD3D12_DepthFormat[createinfo->target_info.depth_stencil_format];
psoDesc.NumRenderTargets = createinfo->target_info.num_color_targets; psoDesc.NumRenderTargets = createinfo->target_info.num_color_targets;
for (uint32_t i = 0; i < createinfo->target_info.num_color_targets; i += 1) { for (uint32_t i = 0; i < createinfo->target_info.num_color_targets; i += 1) {
psoDesc.RTVFormats[i] = SDLToD3D12_TextureFormat[createinfo->target_info.color_target_descriptions[i].format]; psoDesc.RTVFormats[i] = SDLToD3D12_TextureFormat[createinfo->target_info.color_target_descriptions[i].format];
@@ -2846,6 +2957,7 @@ static D3D12Texture *D3D12_INTERNAL_CreateTexture(
D3D12_RESOURCE_FLAGS resourceFlags = (D3D12_RESOURCE_FLAGS)0; D3D12_RESOURCE_FLAGS resourceFlags = (D3D12_RESOURCE_FLAGS)0;
D3D12_RESOURCE_STATES initialState = (D3D12_RESOURCE_STATES)0; D3D12_RESOURCE_STATES initialState = (D3D12_RESOURCE_STATES)0;
D3D12_CLEAR_VALUE clearValue; D3D12_CLEAR_VALUE clearValue;
DXGI_FORMAT format;
bool useClearValue = false; bool useClearValue = false;
bool needsUAV = bool needsUAV =
(createinfo->usage & SDL_GPU_TEXTUREUSAGE_COMPUTE_STORAGE_WRITE) || (createinfo->usage & SDL_GPU_TEXTUREUSAGE_COMPUTE_STORAGE_WRITE) ||
@@ -2861,6 +2973,8 @@ static D3D12Texture *D3D12_INTERNAL_CreateTexture(
Uint32 depth = createinfo->type == SDL_GPU_TEXTURETYPE_3D ? createinfo->layer_count_or_depth : 1; Uint32 depth = createinfo->type == SDL_GPU_TEXTURETYPE_3D ? createinfo->layer_count_or_depth : 1;
bool isMultisample = createinfo->sample_count > SDL_GPU_SAMPLECOUNT_1; bool isMultisample = createinfo->sample_count > SDL_GPU_SAMPLECOUNT_1;
format = SDLToD3D12_TextureFormat[createinfo->format];
if (createinfo->usage & SDL_GPU_TEXTUREUSAGE_COLOR_TARGET) { if (createinfo->usage & SDL_GPU_TEXTUREUSAGE_COLOR_TARGET) {
resourceFlags |= D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET; resourceFlags |= D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET;
useClearValue = true; useClearValue = true;
@@ -2875,6 +2989,7 @@ static D3D12Texture *D3D12_INTERNAL_CreateTexture(
useClearValue = true; useClearValue = true;
clearValue.DepthStencil.Depth = SDL_GetFloatProperty(createinfo->props, SDL_PROP_GPU_CREATETEXTURE_D3D12_CLEAR_DEPTH_FLOAT, 0); clearValue.DepthStencil.Depth = SDL_GetFloatProperty(createinfo->props, SDL_PROP_GPU_CREATETEXTURE_D3D12_CLEAR_DEPTH_FLOAT, 0);
clearValue.DepthStencil.Stencil = (UINT8)SDL_GetNumberProperty(createinfo->props, SDL_PROP_GPU_CREATETEXTURE_D3D12_CLEAR_STENCIL_UINT8, 0); clearValue.DepthStencil.Stencil = (UINT8)SDL_GetNumberProperty(createinfo->props, SDL_PROP_GPU_CREATETEXTURE_D3D12_CLEAR_STENCIL_UINT8, 0);
format = SDLToD3D12_DepthFormat[createinfo->format];
} }
if (needsUAV) { if (needsUAV) {
@@ -2896,7 +3011,7 @@ static D3D12Texture *D3D12_INTERNAL_CreateTexture(
desc.Height = createinfo->height; desc.Height = createinfo->height;
desc.DepthOrArraySize = (UINT16)createinfo->layer_count_or_depth; desc.DepthOrArraySize = (UINT16)createinfo->layer_count_or_depth;
desc.MipLevels = (UINT16)createinfo->num_levels; desc.MipLevels = (UINT16)createinfo->num_levels;
desc.Format = SDLToD3D12_TextureFormat[createinfo->format]; desc.Format = format;
desc.SampleDesc.Count = SDLToD3D12_SampleCount[createinfo->sample_count]; desc.SampleDesc.Count = SDLToD3D12_SampleCount[createinfo->sample_count];
desc.SampleDesc.Quality = isMultisample ? D3D12_STANDARD_MULTISAMPLE_PATTERN : 0; desc.SampleDesc.Quality = isMultisample ? D3D12_STANDARD_MULTISAMPLE_PATTERN : 0;
desc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN; // Apparently this is the most efficient choice desc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN; // Apparently this is the most efficient choice
@@ -2908,7 +3023,7 @@ static D3D12Texture *D3D12_INTERNAL_CreateTexture(
desc.Height = createinfo->height; desc.Height = createinfo->height;
desc.DepthOrArraySize = (UINT16)createinfo->layer_count_or_depth; desc.DepthOrArraySize = (UINT16)createinfo->layer_count_or_depth;
desc.MipLevels = (UINT16)createinfo->num_levels; desc.MipLevels = (UINT16)createinfo->num_levels;
desc.Format = SDLToD3D12_TextureFormat[createinfo->format]; desc.Format = format;
desc.SampleDesc.Count = 1; desc.SampleDesc.Count = 1;
desc.SampleDesc.Quality = 0; desc.SampleDesc.Quality = 0;
desc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN; desc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;
@@ -3065,7 +3180,7 @@ static D3D12Texture *D3D12_INTERNAL_CreateTexture(
D3D12_DESCRIPTOR_HEAP_TYPE_DSV, D3D12_DESCRIPTOR_HEAP_TYPE_DSV,
&texture->subresources[subresourceIndex].dsvHandle); &texture->subresources[subresourceIndex].dsvHandle);
dsvDesc.Format = SDLToD3D12_TextureFormat[createinfo->format]; dsvDesc.Format = SDLToD3D12_DepthFormat[createinfo->format];
dsvDesc.Flags = (D3D12_DSV_FLAGS)0; dsvDesc.Flags = (D3D12_DSV_FLAGS)0;
if (isMultisample) { if (isMultisample) {
@@ -7646,6 +7761,22 @@ static bool D3D12_SupportsTextureFormat(
if ((usage & SDL_GPU_TEXTUREUSAGE_COLOR_TARGET) && !(formatSupport.Support1 & D3D12_FORMAT_SUPPORT1_RENDER_TARGET)) { if ((usage & SDL_GPU_TEXTUREUSAGE_COLOR_TARGET) && !(formatSupport.Support1 & D3D12_FORMAT_SUPPORT1_RENDER_TARGET)) {
return false; return false;
} }
// Special case check for depth, because D3D12 is great.
formatSupport.Format = SDLToD3D12_DepthFormat[format];
formatSupport.Support1 = D3D12_FORMAT_SUPPORT1_NONE;
formatSupport.Support2 = D3D12_FORMAT_SUPPORT2_NONE;
res = ID3D12Device_CheckFeatureSupport(
renderer->device,
D3D12_FEATURE_FORMAT_SUPPORT,
&formatSupport,
sizeof(formatSupport));
if (FAILED(res)) {
// Format is apparently unknown
return false;
}
if ((usage & SDL_GPU_TEXTUREUSAGE_DEPTH_STENCIL_TARGET) && !(formatSupport.Support1 & D3D12_FORMAT_SUPPORT1_DEPTH_STENCIL)) { if ((usage & SDL_GPU_TEXTUREUSAGE_DEPTH_STENCIL_TARGET) && !(formatSupport.Support1 & D3D12_FORMAT_SUPPORT1_DEPTH_STENCIL)) {
return false; return false;
} }