diff --git a/src/xenia/gpu/d3d12/d3d12_texture_cache.h b/src/xenia/gpu/d3d12/d3d12_texture_cache.h index bf5c9b05b..0cb1cfa27 100644 --- a/src/xenia/gpu/d3d12/d3d12_texture_cache.h +++ b/src/xenia/gpu/d3d12/d3d12_texture_cache.h @@ -318,18 +318,21 @@ class D3D12TextureCache final : public TextureCache { kLoadShaderIndexR10G11B11ToRGBA16SNorm, false, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RGBB}, // k_DXT1 + // Signed needs decompression to R8G8B8A8_SNORM (no BC1_SNORM in DXGI). {DXGI_FORMAT_BC1_UNORM, DXGI_FORMAT_BC1_UNORM, kLoadShaderIndex64bpb, - DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, true, + DXGI_FORMAT_R8G8B8A8_SNORM, kLoadShaderIndexDXT1ToRGBA8, true, DXGI_FORMAT_R8G8B8A8_UNORM, kLoadShaderIndexDXT1ToRGBA8, xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA}, // k_DXT2_3 + // Signed needs decompression to R8G8B8A8_SNORM (no BC2_SNORM in DXGI). {DXGI_FORMAT_BC2_UNORM, DXGI_FORMAT_BC2_UNORM, kLoadShaderIndex128bpb, - DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, true, + DXGI_FORMAT_R8G8B8A8_SNORM, kLoadShaderIndexDXT3ToRGBA8, true, DXGI_FORMAT_R8G8B8A8_UNORM, kLoadShaderIndexDXT3ToRGBA8, xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA}, // k_DXT4_5 + // Signed needs decompression to R8G8B8A8_SNORM (no BC3_SNORM in DXGI). {DXGI_FORMAT_BC3_UNORM, DXGI_FORMAT_BC3_UNORM, kLoadShaderIndex128bpb, - DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, true, + DXGI_FORMAT_R8G8B8A8_SNORM, kLoadShaderIndexDXT5ToRGBA8, true, DXGI_FORMAT_R8G8B8A8_UNORM, kLoadShaderIndexDXT5ToRGBA8, xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA}, // k_16_16_16_16_EDRAM @@ -463,8 +466,9 @@ class D3D12TextureCache final : public TextureCache { DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RGGG}, // k_DXN + // Signed needs decompression to R8G8_SNORM (no BC5_SNORM in DXGI). {DXGI_FORMAT_BC5_UNORM, DXGI_FORMAT_BC5_UNORM, kLoadShaderIndex128bpb, - DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, true, + DXGI_FORMAT_R8G8_SNORM, kLoadShaderIndexDXNToRG8, true, DXGI_FORMAT_R8G8_UNORM, kLoadShaderIndexDXNToRG8, xenos::XE_GPU_TEXTURE_SWIZZLE_RGGG}, // k_8_8_8_8_AS_16_16_16_16 @@ -473,18 +477,21 @@ class D3D12TextureCache final : public TextureCache { kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA}, // k_DXT1_AS_16_16_16_16 + // Signed needs decompression to R8G8B8A8_SNORM (no BC1_SNORM in DXGI). {DXGI_FORMAT_BC1_UNORM, DXGI_FORMAT_BC1_UNORM, kLoadShaderIndex64bpb, - DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, true, + DXGI_FORMAT_R8G8B8A8_SNORM, kLoadShaderIndexDXT1ToRGBA8, true, DXGI_FORMAT_R8G8B8A8_UNORM, kLoadShaderIndexDXT1ToRGBA8, xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA}, // k_DXT2_3_AS_16_16_16_16 + // Signed needs decompression to R8G8B8A8_SNORM (no BC2_SNORM in DXGI). {DXGI_FORMAT_BC2_UNORM, DXGI_FORMAT_BC2_UNORM, kLoadShaderIndex128bpb, - DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, true, + DXGI_FORMAT_R8G8B8A8_SNORM, kLoadShaderIndexDXT3ToRGBA8, true, DXGI_FORMAT_R8G8B8A8_UNORM, kLoadShaderIndexDXT3ToRGBA8, xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA}, // k_DXT4_5_AS_16_16_16_16 + // Signed needs decompression to R8G8B8A8_SNORM (no BC3_SNORM in DXGI). {DXGI_FORMAT_BC3_UNORM, DXGI_FORMAT_BC3_UNORM, kLoadShaderIndex128bpb, - DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, true, + DXGI_FORMAT_R8G8B8A8_SNORM, kLoadShaderIndexDXT5ToRGBA8, true, DXGI_FORMAT_R8G8B8A8_UNORM, kLoadShaderIndexDXT5ToRGBA8, xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA}, // k_2_10_10_10_AS_16_16_16_16 @@ -517,8 +524,9 @@ class D3D12TextureCache final : public TextureCache { DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, true, DXGI_FORMAT_R8_UNORM, kLoadShaderIndexDXT5AToR8, xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR}, // k_CTX1 - {DXGI_FORMAT_R8G8_UNORM, DXGI_FORMAT_R8G8_UNORM, kLoadShaderIndexCTX1, - DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN, + // Signed uses R8G8_SNORM with same decompression shader. + {DXGI_FORMAT_R8G8_TYPELESS, DXGI_FORMAT_R8G8_UNORM, kLoadShaderIndexCTX1, + DXGI_FORMAT_R8G8_SNORM, kLoadShaderIndexCTX1, false, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RGGG}, // k_DXT3A_AS_1_1_1_1 {DXGI_FORMAT_B4G4R4A4_UNORM, DXGI_FORMAT_B4G4R4A4_UNORM, @@ -717,6 +725,22 @@ class D3D12TextureCache final : public TextureCache { : host_format.dxgi_format_resource; } DXGI_FORMAT GetDXGIResourceFormat(TextureKey key) const { + const HostFormat& host_format = host_formats_[uint32_t(key.format)]; + // For signed block-compressed formats without native SNORM BC support + // (like DXT1/2/3/4/5, DXN), we must decompress to an uncompressed format + // that supports SNORM views. Use TYPELESS to allow creating SNORM SRVs. + if (key.signed_separate && host_format.is_block_compressed && + host_format.dxgi_format_signed != DXGI_FORMAT_UNKNOWN) { + // Return the appropriate TYPELESS format based on signed format. + switch (host_format.dxgi_format_signed) { + case DXGI_FORMAT_R8G8B8A8_SNORM: + return DXGI_FORMAT_R8G8B8A8_TYPELESS; + case DXGI_FORMAT_R8G8_SNORM: + return DXGI_FORMAT_R8G8_TYPELESS; + default: + return DXGI_FORMAT_R8G8B8A8_TYPELESS; + } + } return GetDXGIResourceFormat(key.format, key.GetWidth(), key.GetHeight()); } DXGI_FORMAT GetDXGIUnormFormat(xenos::TextureFormat format, uint32_t width, diff --git a/src/xenia/gpu/vulkan/vulkan_texture_cache.cc b/src/xenia/gpu/vulkan/vulkan_texture_cache.cc index 12290634b..9e90c8d0e 100644 --- a/src/xenia/gpu/vulkan/vulkan_texture_cache.cc +++ b/src/xenia/gpu/vulkan/vulkan_texture_cache.cc @@ -191,18 +191,24 @@ constexpr VulkanTextureCache::HostFormatPair xenos::XE_GPU_TEXTURE_SWIZZLE_RGBB}, // k_DXT1 // VK_FORMAT_BC1_RGBA_UNORM_BLOCK is optional. + // Signed needs decompression to R8G8B8A8_SNORM (no BC1_SNORM in + // Vulkan). {{kLoadShaderIndex64bpb, VK_FORMAT_BC1_RGBA_UNORM_BLOCK, true}, - {kLoadShaderIndexUnknown}, + {kLoadShaderIndexDXT1ToRGBA8, VK_FORMAT_R8G8B8A8_SNORM}, xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA}, // k_DXT2_3 // VK_FORMAT_BC2_UNORM_BLOCK is optional. + // Signed needs decompression to R8G8B8A8_SNORM (no BC2_SNORM in + // Vulkan). {{kLoadShaderIndex128bpb, VK_FORMAT_BC2_UNORM_BLOCK, true}, - {kLoadShaderIndexUnknown}, + {kLoadShaderIndexDXT3ToRGBA8, VK_FORMAT_R8G8B8A8_SNORM}, xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA}, // k_DXT4_5 // VK_FORMAT_BC3_UNORM_BLOCK is optional. + // Signed needs decompression to R8G8B8A8_SNORM (no BC3_SNORM in + // Vulkan). {{kLoadShaderIndex128bpb, VK_FORMAT_BC3_UNORM_BLOCK, true}, - {kLoadShaderIndexUnknown}, + {kLoadShaderIndexDXT5ToRGBA8, VK_FORMAT_R8G8B8A8_SNORM}, xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA}, // k_16_16_16_16_EDRAM // Not usable as a texture, also has -32...32 range. @@ -335,8 +341,9 @@ constexpr VulkanTextureCache::HostFormatPair xenos::XE_GPU_TEXTURE_SWIZZLE_RGGG}, // k_DXN // VK_FORMAT_BC5_UNORM_BLOCK is optional. + // Signed needs decompression to R8G8_SNORM (no BC5_SNORM in Vulkan). {{kLoadShaderIndex128bpb, VK_FORMAT_BC5_UNORM_BLOCK, true}, - {kLoadShaderIndexUnknown}, + {kLoadShaderIndexDXNToRG8, VK_FORMAT_R8G8_SNORM}, xenos::XE_GPU_TEXTURE_SWIZZLE_RGGG}, // k_8_8_8_8_AS_16_16_16_16 {{kLoadShaderIndex32bpb, VK_FORMAT_R8G8B8A8_UNORM}, @@ -345,18 +352,24 @@ constexpr VulkanTextureCache::HostFormatPair true}, // k_DXT1_AS_16_16_16_16 // VK_FORMAT_BC1_RGBA_UNORM_BLOCK is optional. + // Signed needs decompression to R8G8B8A8_SNORM (no BC1_SNORM in + // Vulkan). {{kLoadShaderIndex64bpb, VK_FORMAT_BC1_RGBA_UNORM_BLOCK, true}, - {kLoadShaderIndexUnknown}, + {kLoadShaderIndexDXT1ToRGBA8, VK_FORMAT_R8G8B8A8_SNORM}, xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA}, // k_DXT2_3_AS_16_16_16_16 // VK_FORMAT_BC2_UNORM_BLOCK is optional. + // Signed needs decompression to R8G8B8A8_SNORM (no BC2_SNORM in + // Vulkan). {{kLoadShaderIndex128bpb, VK_FORMAT_BC2_UNORM_BLOCK, true}, - {kLoadShaderIndexUnknown}, + {kLoadShaderIndexDXT3ToRGBA8, VK_FORMAT_R8G8B8A8_SNORM}, xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA}, // k_DXT4_5_AS_16_16_16_16 // VK_FORMAT_BC3_UNORM_BLOCK is optional. + // Signed needs decompression to R8G8B8A8_SNORM (no BC3_SNORM in + // Vulkan). {{kLoadShaderIndex128bpb, VK_FORMAT_BC3_UNORM_BLOCK, true}, - {kLoadShaderIndexUnknown}, + {kLoadShaderIndexDXT5ToRGBA8, VK_FORMAT_R8G8B8A8_SNORM}, xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA}, // k_2_10_10_10_AS_16_16_16_16 // VK_FORMAT_A2B10G10R10_SNORM_PACK32 is optional. @@ -390,8 +403,9 @@ constexpr VulkanTextureCache::HostFormatPair {kLoadShaderIndexUnknown}, xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR}, // k_CTX1 + // Signed uses R8G8_SNORM with same decompression shader. {{kLoadShaderIndexCTX1, VK_FORMAT_R8G8_UNORM}, - {kLoadShaderIndexUnknown}, + {kLoadShaderIndexCTX1, VK_FORMAT_R8G8_SNORM}, xenos::XE_GPU_TEXTURE_SWIZZLE_RGGG}, // k_DXT3A_AS_1_1_1_1 {{kLoadShaderIndexDXT3AAs1111ToARGB4, VK_FORMAT_B4G4R4A4_UNORM_PACK16},