Merge pull request #4315 from JAB-dev/feat/agc-dcc-packed-float-clear

feat(agc): encode packed R11G11B10 float DCC fast clears
This commit is contained in:
Dean 2026-10-14 00:10:16 +13:00 committed by GitHub
commit 6f7cda184b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 27 additions and 1 deletions

View File

@ -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;
}

View File

@ -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<std::uint32_t, 4> 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<std::uint8_t, 4> keys{0xc0, 0xc0, 0xc0, 0xc0};
GuestTextureResource resource{};
resource.format = 36;
resource.dccAddress = reinterpret_cast<std::uint64_t>(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();
}