From aa99796d8afd6089b4ebc94ca9f7693ac699a31b Mon Sep 17 00:00:00 2001 From: nmzik Date: Sat, 18 Jul 2026 03:43:25 +0200 Subject: [PATCH] Fix Standard64KB 16-bit texture swizzle --- src/graphics/guest_gpu/tile.cpp | 21 ++++++++++----------- tests/ShaderRecompilerComputeTests.cpp | 20 ++++++++++++++++++++ 2 files changed, 30 insertions(+), 11 deletions(-) diff --git a/src/graphics/guest_gpu/tile.cpp b/src/graphics/guest_gpu/tile.cpp index 8084300b3..a88e71079 100644 --- a/src/graphics/guest_gpu/tile.cpp +++ b/src/graphics/guest_gpu/tile.cpp @@ -1089,12 +1089,11 @@ struct Standard64KB16Tables { constexpr Standard64KB16Tables() { for (uint32_t i = 0; i < 256; i++) { uint32_t x_part = 0; - x_part ^= (i << 1u) & 0x0006u; - x_part ^= (i << 4u) & 0x0040u; - x_part ^= (i << 5u) & 0x0100u; - x_part ^= (i << 6u) & 0x0400u; - x_part ^= (i << 7u) & 0x1000u; - x_part ^= (i << 8u) & 0x4000u; + x_part ^= (i << 1u) & 0x000eu; + x_part ^= (i << 4u) & 0x0080u; + x_part ^= (i << 5u) & 0x0200u; + x_part ^= (i << 6u) & 0x0800u; + x_part ^= (i << 7u) & 0x2000u; x_part ^= (i << 8u) & 0x8000u; x_words[i] = x_part >> 1u; @@ -1102,11 +1101,11 @@ struct Standard64KB16Tables { for (uint32_t i = 0; i < 128; i++) { uint32_t y_part = 0; - y_part ^= (i << 3u) & 0x0038u; - y_part ^= (i << 4u) & 0x0080u; - y_part ^= (i << 5u) & 0x0200u; - y_part ^= (i << 6u) & 0x0800u; - y_part ^= (i << 7u) & 0x2000u; + y_part ^= (i << 4u) & 0x0070u; + y_part ^= (i << 5u) & 0x0100u; + y_part ^= (i << 6u) & 0x0400u; + y_part ^= (i << 7u) & 0x1000u; + y_part ^= (i << 8u) & 0x4000u; y_words[i] = y_part >> 1u; } diff --git a/tests/ShaderRecompilerComputeTests.cpp b/tests/ShaderRecompilerComputeTests.cpp index 17dfc8199..eaf81f190 100644 --- a/tests/ShaderRecompilerComputeTests.cpp +++ b/tests/ShaderRecompilerComputeTests.cpp @@ -10276,6 +10276,26 @@ void CheckStandard64RenderTargetTileRoundTrip() { standard[16] == 512 && standard[32] == 4 && standard[16383] == 16383, "Standard64KB reciprocal mapping disagreed with the PS5 SDK"); + + constexpr uint32_t block_width_16 = 256; + constexpr uint32_t block_height_16 = 128; + std::vector tiled_16(block_size / sizeof(uint16_t)); + for (uint32_t i = 0; i < tiled_16.size(); i++) { + tiled_16[i] = static_cast(i); + } + std::vector linear_16(tiled_16.size(), 0xffffu); + TileConvertTiledToLinearStandard64KB16( + linear_16.data(), tiled_16.data(), block_width_16, block_height_16, + block_width_16, block_size); + const auto sample_16 = [&](uint32_t x, uint32_t y) { + return linear_16[static_cast(y) * block_width_16 + x]; + }; + Require("Standard64RenderTarget", "16-bit SDK byte mapping", + sample_16(0, 0) == 0 && sample_16(1, 0) == 1 && + sample_16(2, 0) == 2 && sample_16(4, 0) == 4 && + sample_16(8, 0) == 64 && sample_16(0, 1) == 8 && + sample_16(0, 2) == 16 && sample_16(0, 4) == 32, + "Standard64KB 16-bit mapping interleaved X/Y address bits incorrectly"); TileConvertLinearToTiledRenderTarget( render_target.data(), known.data(), block_width, block_height, block_width, sizeof(uint32_t), block_size);