diff --git a/core/libs/prx/libSceAgcDriver/Graphics/src/DccMetadata.cpp b/core/libs/prx/libSceAgcDriver/Graphics/src/DccMetadata.cpp index 54f6ac7b8..03e76d5c0 100644 --- a/core/libs/prx/libSceAgcDriver/Graphics/src/DccMetadata.cpp +++ b/core/libs/prx/libSceAgcDriver/Graphics/src/DccMetadata.cpp @@ -356,6 +356,7 @@ bool LayoutFor(VkFormat format, Layout& layout) { case VK_FORMAT_R16G16_UINT: layout = {2, {16, 16}, Kind::Uint}; return true; case VK_FORMAT_R16G16_SINT: layout = {2, {16, 16}, Kind::Sint}; return true; case VK_FORMAT_R16G16_SFLOAT: layout = {2, {16, 16}, Kind::Float}; return true; + case VK_FORMAT_B10G11R11_UFLOAT_PACK32: layout = {3, {11, 11, 10}, Kind::Float}; return true; case VK_FORMAT_A2B10G10R10_UNORM_PACK32: case VK_FORMAT_A2R10G10B10_UNORM_PACK32: layout = {4, {10, 10, 10, 2}, Kind::Unorm}; return true; case VK_FORMAT_A2B10G10R10_UINT_PACK32: layout = {4, {10, 10, 10, 2}, Kind::Uint}; return true; case VK_FORMAT_R8G8B8A8_UNORM: case VK_FORMAT_R8G8B8A8_SRGB: case VK_FORMAT_B8G8R8A8_UNORM: case VK_FORMAT_B8G8R8A8_SRGB: layout = {4, {8, 8, 8, 8}, Kind::Unorm}; return true; @@ -382,7 +383,14 @@ std::uint64_t One(Kind kind, std::uint32_t bits) { switch (kind) { case Kind::Unorm: case Kind::Uint: return bits >= 64 ? ~0ull : (1ull << bits) - 1u; case Kind::Snorm: case Kind::Sint: return (1ull << (bits - 1u)) - 1u; - case Kind::Float: return bits == 16 ? 0x3c00u : 0x3f800000u; + case Kind::Float: + switch (bits) { + case 10: return 0x1e0u; + case 11: return 0x3c0u; + case 16: return 0x3c00u; + case 32: return 0x3f800000u; + default: throw std::runtime_error("AGC graphics: DCC clear of a " + std::to_string(bits) + "-bit float channel is not implemented"); + } } return 0; } diff --git a/core/libs/prx/libSceAgcDriver/tests/TextureFormat.cpp b/core/libs/prx/libSceAgcDriver/tests/TextureFormat.cpp index 794d63228..33d1a9f45 100644 --- a/core/libs/prx/libSceAgcDriver/tests/TextureFormat.cpp +++ b/core/libs/prx/libSceAgcDriver/tests/TextureFormat.cpp @@ -125,6 +125,23 @@ void singleDccKeysTests() { Require(read(56) == DccKeys::Uncompressed, "comp-to-single keys mixed with uncompressed ones must read as stored"); } +void packedFloatDccClearTests() { + for (const bool alphaOnMsb : {false, true}) { + for (const auto keys : {DccKeys::Clear0000, DccKeys::Clear0001, DccKeys::Clear1110, DccKeys::Clear1111}) { + std::array texels{}; + texels.fill(0xdeadbeefu); + Require(FillDccClear(VK_FORMAT_B10G11R11_UFLOAT_PACK32, keys, alphaOnMsb, std::as_writable_bytes(std::span(texels))), "packed float fast clear was not encoded"); + const std::uint32_t expected = keys == DccKeys::Clear1110 || keys == DccKeys::Clear1111 ? 0x781e03c0u : 0u; + for (const auto texel : texels) Require(texel == expected, "packed float DCC clear did not encode RGB zero or one"); + } + } + alignas(64) std::array keys{0xc0, 0xc0, 0xc0, 0xc0}; + GuestTextureResource resource{}; + resource.format = 36; + resource.dccAddress = reinterpret_cast(keys.data()); + Require(TextureClearKeys(resource, 1024) == DccKeys::Clear1111, "packed float texture discarded its white fast-clear keys"); +} + } void RunTextureFormatTests() { @@ -175,4 +192,5 @@ void RunTextureFormatTests() { for (const std::uint32_t format : {1u, 14u, 56u, 71u, 169u, 171u, 173u, 181u}) Require(!IsSrgbTextureFormat(format), "guest format " + std::to_string(format) + " must not be an sRGB texture format"); convertedDccClearTests(); singleDccKeysTests(); + packedFloatDccClearTests(); }