diff --git a/src/gpu/d3d12/SDL_gpu_d3d12.c b/src/gpu/d3d12/SDL_gpu_d3d12.c index 8243d02e1a..a489f204b8 100644 --- a/src/gpu/d3d12/SDL_gpu_d3d12.c +++ b/src/gpu/d3d12/SDL_gpu_d3d12.c @@ -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); +// These are actually color formats. +// For some genius reason, D3D12 splits format capabilites for depth-stencil views. static DXGI_FORMAT SDLToD3D12_TextureFormat[] = { DXGI_FORMAT_UNKNOWN, // INVALID 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_BC3_UNORM_SRGB, // BC3_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_D24_UNORM_S8_UINT, // D24_UNORM 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_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[] = { 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.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; 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]; @@ -2846,6 +2957,7 @@ static D3D12Texture *D3D12_INTERNAL_CreateTexture( D3D12_RESOURCE_FLAGS resourceFlags = (D3D12_RESOURCE_FLAGS)0; D3D12_RESOURCE_STATES initialState = (D3D12_RESOURCE_STATES)0; D3D12_CLEAR_VALUE clearValue; + DXGI_FORMAT format; bool useClearValue = false; bool needsUAV = (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; bool isMultisample = createinfo->sample_count > SDL_GPU_SAMPLECOUNT_1; + format = SDLToD3D12_TextureFormat[createinfo->format]; + if (createinfo->usage & SDL_GPU_TEXTUREUSAGE_COLOR_TARGET) { resourceFlags |= D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET; useClearValue = true; @@ -2875,6 +2989,7 @@ static D3D12Texture *D3D12_INTERNAL_CreateTexture( useClearValue = true; 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); + format = SDLToD3D12_DepthFormat[createinfo->format]; } if (needsUAV) { @@ -2896,7 +3011,7 @@ static D3D12Texture *D3D12_INTERNAL_CreateTexture( desc.Height = createinfo->height; desc.DepthOrArraySize = (UINT16)createinfo->layer_count_or_depth; 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.Quality = isMultisample ? D3D12_STANDARD_MULTISAMPLE_PATTERN : 0; 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.DepthOrArraySize = (UINT16)createinfo->layer_count_or_depth; desc.MipLevels = (UINT16)createinfo->num_levels; - desc.Format = SDLToD3D12_TextureFormat[createinfo->format]; + desc.Format = format; desc.SampleDesc.Count = 1; desc.SampleDesc.Quality = 0; desc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN; @@ -3065,7 +3180,7 @@ static D3D12Texture *D3D12_INTERNAL_CreateTexture( D3D12_DESCRIPTOR_HEAP_TYPE_DSV, &texture->subresources[subresourceIndex].dsvHandle); - dsvDesc.Format = SDLToD3D12_TextureFormat[createinfo->format]; + dsvDesc.Format = SDLToD3D12_DepthFormat[createinfo->format]; dsvDesc.Flags = (D3D12_DSV_FLAGS)0; if (isMultisample) { @@ -7646,6 +7761,22 @@ static bool D3D12_SupportsTextureFormat( if ((usage & SDL_GPU_TEXTUREUSAGE_COLOR_TARGET) && !(formatSupport.Support1 & D3D12_FORMAT_SUPPORT1_RENDER_TARGET)) { 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)) { return false; }