mirror of
https://github.com/boykopovar/AnyPS5.git
synced 2026-11-06 13:30:00 +00:00
test(agc): cover exact sRGB multisample DCC clears
This commit is contained in:
1 parent
b986c11a34
commit
d7afc36cf0
3 files changed
+93
No files matched your search
@@ -2377,6 +2377,9 @@ if(BUILD_TESTING)
|
||||
add_test(NAME agc_driver_two_sample_dithered_alpha_to_coverage COMMAND agc_driver_alpha_to_coverage_tests --dithered2)
|
||||
set(multisampledDccClearTests)
|
||||
foreach(samples IN ITEMS 2 4 8)
|
||||
set(testName "agc_driver_msaa_dcc_srgb_clear_${samples}")
|
||||
add_test(NAME ${testName} COMMAND agc_driver_alpha_to_coverage_tests --dcc-srgb-clear ${samples})
|
||||
list(APPEND multisampledDccClearTests ${testName})
|
||||
set(testName "agc_driver_msaa_dcc_clear_${samples}")
|
||||
add_test(NAME ${testName} COMMAND agc_driver_alpha_to_coverage_tests --dcc-fast-clear ${samples})
|
||||
list(APPEND multisampledDccClearTests ${testName})
|
||||
|
||||
@@ -4320,6 +4320,31 @@ void multisampleDccStateTests() {
|
||||
target.cmaskFastClear = true;
|
||||
expectFailure([&] { static_cast<void>(AgcDriver::Graphics::MultisampledDccClear(target, dcc, cmask)); }, "multisampled DCC CMASK compression or register clear");
|
||||
}
|
||||
for (const auto samples : {2u, 4u, 8u}) {
|
||||
for (const auto format : {VK_FORMAT_R8G8B8A8_SRGB, VK_FORMAT_B8G8R8A8_SRGB}) {
|
||||
for (const auto key : {0x00u, 0x40u, 0x80u, 0xc0u}) {
|
||||
for (const auto alphaOnMsb : {false, true}) {
|
||||
AgcDriver::Graphics::ColorTarget target{};
|
||||
target.extent = {64, 64};
|
||||
target.format = format;
|
||||
target.tileMode = AgcDriver::Graphics::ColorTileMode::RenderTarget;
|
||||
target.elementBytes = 4;
|
||||
target.samples = samples;
|
||||
target.dccAddress = 0x200000u;
|
||||
target.dccPipeAligned = true;
|
||||
target.dccAlphaOnMsb = alphaOnMsb;
|
||||
const std::vector<std::byte> dcc(AgcDriver::Graphics::MultisampledDccBytes(target), static_cast<std::byte>(key));
|
||||
const auto clear = AgcDriver::Graphics::MultisampledDccClear(target, dcc, {});
|
||||
const auto alpha = alphaOnMsb ? 3u : format == VK_FORMAT_B8G8R8A8_SRGB ? 2u : 0u;
|
||||
for (std::uint32_t channel = 0; channel < 4; ++channel) {
|
||||
const bool one = channel == alpha ? key == 0x40u || key == 0xc0u : key == 0x80u || key == 0xc0u;
|
||||
Require(clear.float32[channel] == static_cast<float>(one), "an sRGB multisampled DCC endpoint did not produce its exact linear clear value");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void multisampledDepthTests() {
|
||||
|
||||
@@ -522,6 +522,64 @@ constexpr std::array<DitherCase, 56> TwoSampleDitherCases{{
|
||||
{0x00007e00u, 4u, {0x00u, 0x00u, 0x00u, 0x00u}},
|
||||
}};
|
||||
|
||||
void DccSrgbClearTests(AgcDriver::VulkanDevice& device, std::uint32_t samples) {
|
||||
const ColorTargetLayout layout(Width, Height, ColorTileMode::RenderTarget, 4);
|
||||
const ColorTargetLayout allocation(Width, Height, ColorTileMode::RenderTarget, 8);
|
||||
std::vector<std::unique_ptr<Block>> blocks;
|
||||
struct ClearTargets {
|
||||
AgcDriver::VulkanDevice& device;
|
||||
~ClearTargets() {
|
||||
std::lock_guard lock(AgcDriver::GuestMemory::GpuMutex());
|
||||
device.SubmitRecorded(true);
|
||||
device.WaitIdle();
|
||||
AgcDriver::Graphics::ClearMultisampleTargets(device.Device());
|
||||
AgcDriver::Graphics::ClearCachedTextures(device.Device());
|
||||
}
|
||||
} clearTargets{device};
|
||||
const auto targetFor = [&](const Block& block, std::uint32_t count, VkFormat format) {
|
||||
auto target = DecodeTarget(block, count);
|
||||
target.format = format;
|
||||
target.elementBytes = 4;
|
||||
target.bytes = layout.Bytes();
|
||||
return target;
|
||||
};
|
||||
for (const auto format : {VK_FORMAT_R8G8B8A8_SRGB, VK_FORMAT_B8G8R8A8_SRGB}) {
|
||||
for (const auto key : {0x00u, 0x40u, 0x80u, 0xc0u}) {
|
||||
for (const auto alphaOnMsb : {false, true}) {
|
||||
blocks.push_back(std::make_unique<Block>(allocation.Bytes() * samples));
|
||||
auto& source = *blocks.back();
|
||||
std::memset(source.data, 0x5a, source.bytes);
|
||||
blocks.push_back(std::make_unique<Block>(BlockBytes));
|
||||
auto& metadata = *blocks.back();
|
||||
std::memset(metadata.data, key, metadata.bytes);
|
||||
auto target = targetFor(source, samples, format);
|
||||
target.dccAddress = metadata.Address();
|
||||
target.dccPipeAligned = true;
|
||||
target.dccAlphaOnMsb = alphaOnMsb;
|
||||
Draw(device, target, false, Float32Export, Program(Color{0.25f, 0.5f, 0.75f, 0.125f}, Float32Export, 0u), false, true);
|
||||
blocks.push_back(std::make_unique<Block>(allocation.Bytes()));
|
||||
auto& resolved = *blocks.back();
|
||||
std::memset(resolved.data, 0xa5, resolved.bytes);
|
||||
AgcDriver::Graphics::ColorMetadataPass pass{};
|
||||
pass.mode = AgcDriver::Graphics::ColorMetadataPass::Mode::Resolve;
|
||||
pass.source = target;
|
||||
pass.targets = {targetFor(resolved, 1u, format)};
|
||||
device.ColorMetadataPass(pass);
|
||||
const auto stored = ReadBack(device, resolved);
|
||||
const auto bytes = std::as_bytes(std::span(stored));
|
||||
std::array<std::byte, 4> expected{};
|
||||
const auto keys = key == 0x00u ? AgcDriver::Graphics::DccKeys::Clear0000 : key == 0x40u ? AgcDriver::Graphics::DccKeys::Clear0001 : key == 0x80u ? AgcDriver::Graphics::DccKeys::Clear1110 : AgcDriver::Graphics::DccKeys::Clear1111;
|
||||
Require(AgcDriver::Graphics::FillDccClear(format, keys, alphaOnMsb, expected), "the sRGB DCC expected texel was not encoded");
|
||||
for (std::uint32_t y = 0; y < Height; ++y) {
|
||||
for (std::uint32_t x = 0; x < Width; ++x) {
|
||||
for (std::uint32_t channel = 0; channel < 4; ++channel) Require(bytes[layout.Offset(x, y) + channel] == expected[channel], "an sRGB DCC import or resolve changed an undrawn sample endpoint");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DccFastClearTests(AgcDriver::VulkanDevice& device, std::uint32_t selectedSamples) {
|
||||
const ColorTargetLayout layout(Width, Height, ColorTileMode::RenderTarget, 8);
|
||||
const auto expectRange = [](std::string_view message, const char* plane, std::uint64_t address, std::size_t bytes, std::uint32_t samples) {
|
||||
@@ -1147,6 +1205,13 @@ int main(int argc, char** argv) {
|
||||
try {
|
||||
const auto device = OpenVulkanTestDevice();
|
||||
if (!device) return VulkanTestSkipped;
|
||||
if (argc == 3 && std::string_view(argv[1]) == "--dcc-srgb-clear") {
|
||||
const auto samples = std::string_view(argv[2]) == "2" ? 2u : std::string_view(argv[2]) == "4" ? 4u : std::string_view(argv[2]) == "8" ? 8u : 0u;
|
||||
Require(samples != 0, "unknown sRGB DCC test sample count");
|
||||
DccSrgbClearTests(*device, samples);
|
||||
std::cout << "Multisampled sRGB DCC clear tests passed\n";
|
||||
return 0;
|
||||
}
|
||||
if ((argc == 2 || argc == 3) && std::string_view(argv[1]) == "--dcc-fast-clear") {
|
||||
const auto samples = argc == 2 ? 0u : std::string_view(argv[2]) == "2" ? 2u : std::string_view(argv[2]) == "4" ? 4u : std::string_view(argv[2]) == "8" ? 8u : 0u;
|
||||
Require(argc == 2 || samples != 0, "unknown DCC test sample count");
|
||||
|
||||
Reference in new issue
Block a user