mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-26 21:06:53 +01:00
graphics: decode register clears of RGBA16 UNORM, UINT and SINT and RG32 UINT and SINT targets
Co-authored-by: Senaxx <michelbeld@gmail.com> Co-authored-by: Jetsku <59046009+Jetsku@users.noreply.github.com>
This commit is contained in:
@@ -378,6 +378,9 @@ inline constexpr std::array<VideoOutFormatPolicy, 8> VIDEO_OUT_FORMAT_POLICIES {
|
|||||||
const auto encoded = static_cast<float>(value & 0xffu) / 255.0f;
|
const auto encoded = static_cast<float>(value & 0xffu) / 255.0f;
|
||||||
return encoded <= 0.04045f ? encoded / 12.92f : std::pow((encoded + 0.055f) / 1.055f, 2.4f);
|
return encoded <= 0.04045f ? encoded / 12.92f : std::pow((encoded + 0.055f) / 1.055f, 2.4f);
|
||||||
};
|
};
|
||||||
|
const auto unorm16 = [](uint64_t value) {
|
||||||
|
return static_cast<float>(value & 0xffffu) / 65535.0f;
|
||||||
|
};
|
||||||
const auto float16 = [](uint32_t value) {
|
const auto float16 = [](uint32_t value) {
|
||||||
const auto sign = (value & 0x8000u) << 16u;
|
const auto sign = (value & 0x8000u) << 16u;
|
||||||
const auto exponent = (value >> 10u) & 0x1fu;
|
const auto exponent = (value >> 10u) & 0x1fu;
|
||||||
@@ -403,19 +406,35 @@ inline constexpr std::array<VideoOutFormatPolicy, 8> VIDEO_OUT_FORMAT_POLICIES {
|
|||||||
next.float32[1] = float16(packed >> 16u);
|
next.float32[1] = float16(packed >> 16u);
|
||||||
[[fallthrough]];
|
[[fallthrough]];
|
||||||
case vk::Format::eR16Sfloat: next.float32[0] = float16(packed); break;
|
case vk::Format::eR16Sfloat: next.float32[0] = float16(packed); break;
|
||||||
case vk::Format::eR16G16Unorm:
|
case vk::Format::eR16G16B16A16Unorm:
|
||||||
next.float32[1] = static_cast<float>(packed >> 16u) / 65535.0f;
|
next.float32[2] = unorm16(clear_words >> 32u);
|
||||||
|
next.float32[3] = unorm16(clear_words >> 48u);
|
||||||
[[fallthrough]];
|
[[fallthrough]];
|
||||||
case vk::Format::eR16Unorm:
|
case vk::Format::eR16G16Unorm:
|
||||||
next.float32[0] = static_cast<float>(packed & 0xffffu) / 65535.0f;
|
next.float32[1] = unorm16(packed >> 16u);
|
||||||
|
[[fallthrough]];
|
||||||
|
case vk::Format::eR16Unorm: next.float32[0] = unorm16(packed); break;
|
||||||
|
case vk::Format::eR16G16B16A16Uint:
|
||||||
|
for (uint32_t i = 0; i < 4; i++) {
|
||||||
|
next.uint32[i] = static_cast<uint16_t>(clear_words >> (16u * i));
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
// Each clear register stores one raw 32-bit float channel.
|
case vk::Format::eR16G16B16A16Sint:
|
||||||
|
for (uint32_t i = 0; i < 4; i++) {
|
||||||
|
next.int32[i] = static_cast<int16_t>(clear_words >> (16u * i));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
// Each clear register stores one raw 32-bit channel.
|
||||||
case vk::Format::eR32G32Sfloat:
|
case vk::Format::eR32G32Sfloat:
|
||||||
next.float32[1] = std::bit_cast<float>(static_cast<uint32_t>(clear_words >> 32u));
|
next.float32[1] = std::bit_cast<float>(static_cast<uint32_t>(clear_words >> 32u));
|
||||||
[[fallthrough]];
|
[[fallthrough]];
|
||||||
case vk::Format::eR32Sfloat: next.float32[0] = std::bit_cast<float>(packed); break;
|
case vk::Format::eR32Sfloat: next.float32[0] = std::bit_cast<float>(packed); break;
|
||||||
case vk::Format::eR32Uint: next.uint32[0] = packed; break;
|
case vk::Format::eR32G32Uint:
|
||||||
case vk::Format::eR32Sint: next.int32[0] = static_cast<int32_t>(packed); break;
|
case vk::Format::eR32G32Sint:
|
||||||
|
next.uint32[1] = static_cast<uint32_t>(clear_words >> 32u);
|
||||||
|
[[fallthrough]];
|
||||||
|
case vk::Format::eR32Uint:
|
||||||
|
case vk::Format::eR32Sint: next.uint32[0] = packed; break;
|
||||||
// Narrow targets hold their channels in the low bits of the first word. UFC 6 (PPSA23566)
|
// Narrow targets hold their channels in the low bits of the first word. UFC 6 (PPSA23566)
|
||||||
// fast-clears an R8_UINT map through CMASK every frame and then writes only part of it;
|
// fast-clears an R8_UINT map through CMASK every frame and then writes only part of it;
|
||||||
// without these the clear was dropped and old contents piled up.
|
// without these the clear was dropped and old contents piled up.
|
||||||
|
|||||||
@@ -12506,6 +12506,8 @@ public:
|
|||||||
PackedCase{vk::Format::eR16G16Unorm, 0x0000ffffu, {1.0f, 0.0f}},
|
PackedCase{vk::Format::eR16G16Unorm, 0x0000ffffu, {1.0f, 0.0f}},
|
||||||
PackedCase{vk::Format::eR16G16Unorm, 0x80000001u,
|
PackedCase{vk::Format::eR16G16Unorm, 0x80000001u,
|
||||||
{1.0f / 65535.0f, 32768.0f / 65535.0f}},
|
{1.0f / 65535.0f, 32768.0f / 65535.0f}},
|
||||||
|
PackedCase{vk::Format::eR16G16B16A16Unorm, 0x000180000000ffffull,
|
||||||
|
{1.0f, 0.0f, 32768.0f / 65535.0f, 1.0f / 65535.0f}},
|
||||||
PackedCase{vk::Format::eR8Unorm, 0xffffff80u, {128.0f / 255.0f}},
|
PackedCase{vk::Format::eR8Unorm, 0xffffff80u, {128.0f / 255.0f}},
|
||||||
PackedCase{vk::Format::eR8G8Unorm, 0xffff40ffu, {1.0f, 64.0f / 255.0f}},
|
PackedCase{vk::Format::eR8G8Unorm, 0xffff40ffu, {1.0f, 64.0f / 255.0f}},
|
||||||
};
|
};
|
||||||
@@ -12541,11 +12543,19 @@ public:
|
|||||||
};
|
};
|
||||||
for (const auto &test : {UintCase{vk::Format::eR8Uint, 0xffffff05u, {5u}},
|
for (const auto &test : {UintCase{vk::Format::eR8Uint, 0xffffff05u, {5u}},
|
||||||
UintCase{vk::Format::eR8G8Uint, 0xffff0a05u, {5u, 10u}},
|
UintCase{vk::Format::eR8G8Uint, 0xffff0a05u, {5u, 10u}},
|
||||||
UintCase{vk::Format::eR16Uint, 0xffff1234u, {0x1234u}}}) {
|
UintCase{vk::Format::eR16Uint, 0xffff1234u, {0x1234u}},
|
||||||
Require(name, "packed unsigned color clear",
|
UintCase{vk::Format::eR16G16B16A16Uint, 0x4444333322221111ull,
|
||||||
|
{0x1111u, 0x2222u, 0x3333u, 0x4444u}},
|
||||||
|
UintCase{vk::Format::eR16G16B16A16Sint, 0x7fff0001ffff8000ull,
|
||||||
|
{0xffff8000u, 0xffffffffu, 1u, 0x7fffu}},
|
||||||
|
UintCase{vk::Format::eR32G32Uint, 0x89abcdef01234567ull,
|
||||||
|
{0x01234567u, 0x89abcdefu}},
|
||||||
|
UintCase{vk::Format::eR32G32Sint, 0x80000000ffffffffull,
|
||||||
|
{0xffffffffu, 0x80000000u}}}) {
|
||||||
|
Require(name, "packed integer color clear",
|
||||||
DecodePackedColorClear(test.format, test.word, clear) &&
|
DecodePackedColorClear(test.format, test.word, clear) &&
|
||||||
std::bit_cast<std::array<uint32_t, 4>>(clear.uint32) == test.channels,
|
std::bit_cast<std::array<uint32_t, 4>>(clear.uint32) == test.channels,
|
||||||
"narrow unsigned clear lost a channel or kept bits of the next one");
|
"integer clear lost a channel, its sign or bits of the next one");
|
||||||
}
|
}
|
||||||
Require(name, "R8 DWORD fill",
|
Require(name, "R8 DWORD fill",
|
||||||
!DecodeColorDwordFill(vk::Format::eR8Uint, 0x01020304u, clear) &&
|
!DecodeColorDwordFill(vk::Format::eR8Uint, 0x01020304u, clear) &&
|
||||||
@@ -12561,6 +12571,10 @@ public:
|
|||||||
DecodeColorDwordFill(vk::Format::eR32G32Sfloat, 0x3f800000u, clear) &&
|
DecodeColorDwordFill(vk::Format::eR32G32Sfloat, 0x3f800000u, clear) &&
|
||||||
clear.float32[0] == 1.0f && clear.float32[1] == 1.0f,
|
clear.float32[0] == 1.0f && clear.float32[1] == 1.0f,
|
||||||
"a repeated DWORD fill was decoded as a two-register clear");
|
"a repeated DWORD fill was decoded as a two-register clear");
|
||||||
|
Require(name, "RGBA16 DWORD fill",
|
||||||
|
DecodeColorDwordFill(vk::Format::eR16G16B16A16Uint, 0x22221111u, clear) &&
|
||||||
|
clear.uint32[2] == 0x1111u && clear.uint32[3] == 0x2222u,
|
||||||
|
"a DWORD fill did not repeat across the 64-bit pixel");
|
||||||
constexpr uintptr_t base = 0x0000000204100000ull;
|
constexpr uintptr_t base = 0x0000000204100000ull;
|
||||||
constexpr uint64_t allocation_size = 0x1000000;
|
constexpr uint64_t allocation_size = 0x1000000;
|
||||||
constexpr uint64_t allocation_alignment = 0x10000;
|
constexpr uint64_t allocation_alignment = 0x10000;
|
||||||
|
|||||||
Reference in New Issue
Block a user