From c6a4223420ae9fa4f39a17a059afe0ad418715cb Mon Sep 17 00:00:00 2001 From: xXPBSXx <20614131+xXPBSXx@users.noreply.github.com> Date: Tue, 13 Oct 2026 13:14:28 +0200 Subject: [PATCH] fix(agc): sample 10_10_10_2 SNorm and SInt textures Guest texture formats 51 (SNorm) and 55 (SInt) of the 10-bit packed group were missing from the texture lookup and the descriptor format table, so a descriptor using them threw 'unsupported guest texture format' while the UNorm (50) and UInt (54) siblings worked. Map them to A2B10G10R10_SNORM_PACK32 / A2B10G10R10_SINT_PACK32, classify them for sampling (float / signed integer), and list SINT among the integer formats. Co-Authored-By: Claude Sonnet 5.5 --- core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp | 2 +- .../prx/libSceAgcDriver/Graphics/src/TextureFormat.cpp | 2 ++ core/libs/prx/libSceAgcDriver/tests/TextureFormat.cpp | 9 +++++++++ .../recompiler/RdnaDecoder/src/RdnaDescriptorFormat.cpp | 4 +++- 4 files changed, 15 insertions(+), 2 deletions(-) diff --git a/core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp b/core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp index d4e73c741..d83ff3a75 100644 --- a/core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp +++ b/core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp @@ -817,7 +817,7 @@ bool IntegerFormat(VkFormat format) { switch (format) { case VK_FORMAT_R8_UINT: case VK_FORMAT_R8_SINT: case VK_FORMAT_R8G8_UINT: case VK_FORMAT_R8G8_SINT: case VK_FORMAT_R8G8B8A8_UINT: case VK_FORMAT_R8G8B8A8_SINT: case VK_FORMAT_B8G8R8A8_UINT: case VK_FORMAT_B8G8R8A8_SINT: - case VK_FORMAT_A8B8G8R8_UINT_PACK32: case VK_FORMAT_A8B8G8R8_SINT_PACK32: case VK_FORMAT_A2R10G10B10_UINT_PACK32: case VK_FORMAT_A2B10G10R10_UINT_PACK32: + case VK_FORMAT_A8B8G8R8_UINT_PACK32: case VK_FORMAT_A8B8G8R8_SINT_PACK32: case VK_FORMAT_A2R10G10B10_UINT_PACK32: case VK_FORMAT_A2B10G10R10_UINT_PACK32: case VK_FORMAT_A2B10G10R10_SINT_PACK32: case VK_FORMAT_R16_UINT: case VK_FORMAT_R16_SINT: case VK_FORMAT_R16G16_UINT: case VK_FORMAT_R16G16_SINT: case VK_FORMAT_R16G16B16A16_UINT: case VK_FORMAT_R16G16B16A16_SINT: case VK_FORMAT_R32_UINT: case VK_FORMAT_R32_SINT: case VK_FORMAT_R32G32_UINT: case VK_FORMAT_R32G32_SINT: case VK_FORMAT_R32G32B32_UINT: case VK_FORMAT_R32G32B32_SINT: diff --git a/core/libs/prx/libSceAgcDriver/Graphics/src/TextureFormat.cpp b/core/libs/prx/libSceAgcDriver/Graphics/src/TextureFormat.cpp index fdee455cf..ca7f4da8b 100644 --- a/core/libs/prx/libSceAgcDriver/Graphics/src/TextureFormat.cpp +++ b/core/libs/prx/libSceAgcDriver/Graphics/src/TextureFormat.cpp @@ -42,7 +42,9 @@ constexpr FormatEntry kFormatLookup[] = { {29, VK_FORMAT_R16G16_SFLOAT, 4, false}, {36, VK_FORMAT_B10G11R11_UFLOAT_PACK32, 4, false}, {50, VK_FORMAT_A2B10G10R10_UNORM_PACK32, 4, false}, + {51, VK_FORMAT_A2B10G10R10_SNORM_PACK32, 4, false}, {54, VK_FORMAT_A2B10G10R10_UINT_PACK32, 4, false}, + {55, VK_FORMAT_A2B10G10R10_SINT_PACK32, 4, false}, {56, VK_FORMAT_R8G8B8A8_UNORM, 4, false}, {57, VK_FORMAT_R8G8B8A8_SNORM, 4, false}, {60, VK_FORMAT_R8G8B8A8_UINT, 4, false}, diff --git a/core/libs/prx/libSceAgcDriver/tests/TextureFormat.cpp b/core/libs/prx/libSceAgcDriver/tests/TextureFormat.cpp index 33d1a9f45..6c97ab5cd 100644 --- a/core/libs/prx/libSceAgcDriver/tests/TextureFormat.cpp +++ b/core/libs/prx/libSceAgcDriver/tests/TextureFormat.cpp @@ -153,6 +153,15 @@ void RunTextureFormatTests() { Require(!IsBlockCompressed(1), "format 1 must not be block compressed"); Require(BlockWidth(1) == 1u && BlockHeight(1) == 1u, "format 1 must have a one-texel block"); + Require(ResolveTextureFormat(50) == VK_FORMAT_A2B10G10R10_UNORM_PACK32, "format 50 must resolve to A2B10G10R10_UNORM"); + Require(ResolveTextureFormat(51) == VK_FORMAT_A2B10G10R10_SNORM_PACK32, "format 51 must resolve to A2B10G10R10_SNORM"); + Require(ResolveTextureFormat(54) == VK_FORMAT_A2B10G10R10_UINT_PACK32, "format 54 must resolve to A2B10G10R10_UINT"); + Require(ResolveTextureFormat(55) == VK_FORMAT_A2B10G10R10_SINT_PACK32, "format 55 must resolve to A2B10G10R10_SINT"); + for (const std::uint32_t format : {50u, 51u, 54u, 55u}) Require(BytesPerElement(format) == 4u && !IsBlockCompressed(format), "packed 10-bit format " + std::to_string(format) + " must be four bytes and not block compressed"); + Require(ShaderRecompiler::SampledTextureNumericClass(ShaderRecompiler::IrBufferFormat::Format10_10_10_2SNorm) == ShaderRecompiler::IrTextureNumericClass::Float, "format 51 must sample as float"); + Require(ShaderRecompiler::SampledTextureNumericClass(ShaderRecompiler::IrBufferFormat::Format10_10_10_2SInt) == ShaderRecompiler::IrTextureNumericClass::Sint, "format 55 must sample as signed integer"); + Require(ShaderRecompiler::SampledTextureNumericClass(ShaderRecompiler::IrBufferFormat::Format10_10_10_2UInt) == ShaderRecompiler::IrTextureNumericClass::Uint, "format 54 must sample as unsigned integer"); + Require(ResolveTextureFormat(56) == VK_FORMAT_R8G8B8A8_UNORM, "format 56 must resolve to R8G8B8A8_UNORM"); Require(BytesPerElement(56) == 4u, "format 56 must be four bytes wide"); diff --git a/core/shader/recompiler/RdnaDecoder/src/RdnaDescriptorFormat.cpp b/core/shader/recompiler/RdnaDecoder/src/RdnaDescriptorFormat.cpp index 04f2b9e07..c3d1a6870 100644 --- a/core/shader/recompiler/RdnaDecoder/src/RdnaDescriptorFormat.cpp +++ b/core/shader/recompiler/RdnaDecoder/src/RdnaDescriptorFormat.cpp @@ -13,7 +13,7 @@ struct FormatInfo { bool sint32; }; -constexpr std::array kFormatInfoTable {{ +constexpr std::array kFormatInfoTable {{ {IrBufferFormat::Format8UNorm, true, false, false}, {IrBufferFormat::Format8SNorm, true, false, false}, {IrBufferFormat::Format8UInt, true, true, false}, @@ -40,7 +40,9 @@ constexpr std::array kFormatInfoTable {{ {IrBufferFormat::Format11_11_10Float, true, false, false}, {IrBufferFormat::Format10_11_11Float, true, true, false}, {IrBufferFormat::Format10_10_10_2UNorm, true, false, false}, + {IrBufferFormat::Format10_10_10_2SNorm, true, false, false}, {IrBufferFormat::Format10_10_10_2UInt, true, true, false}, + {IrBufferFormat::Format10_10_10_2SInt, true, false, true}, {IrBufferFormat::Format8_8_8_8UNorm, true, false, false}, {IrBufferFormat::Format8_8_8_8SNorm, true, false, false}, {IrBufferFormat::Format8_8_8_8UInt, true, true, false},