diff --git a/src/graphics/host_gpu/vulkanCommon.cpp b/src/graphics/host_gpu/vulkanCommon.cpp index e39dfb7eb..4b00153d5 100644 --- a/src/graphics/host_gpu/vulkanCommon.cpp +++ b/src/graphics/host_gpu/vulkanCommon.cpp @@ -48,6 +48,7 @@ constexpr FormatMapping kFormatMappings[] = { {Prospero::BufferFormat::k11_11_10Float, vk::Format::eB10G11R11UfloatPack32}, {Prospero::BufferFormat::k10_10_10_2UNorm, vk::Format::eA2B10G10R10UnormPack32}, {Prospero::BufferFormat::k10_10_10_2SNorm, vk::Format::eA2B10G10R10SnormPack32}, + {Prospero::BufferFormat::k10_10_10_2UScaled, vk::Format::eA2B10G10R10UscaledPack32}, {Prospero::BufferFormat::k10_10_10_2UInt, vk::Format::eA2B10G10R10UintPack32}, {Prospero::BufferFormat::k8_8_8_8UNorm, vk::Format::eR8G8B8A8Unorm}, {Prospero::BufferFormat::k8_8_8_8SNorm, vk::Format::eR8G8B8A8Snorm}, diff --git a/tests/ShaderRecompilerComputeTests.cpp b/tests/ShaderRecompilerComputeTests.cpp index 7a51c1fa6..34d4022b5 100644 --- a/tests/ShaderRecompilerComputeTests.cpp +++ b/tests/ShaderRecompilerComputeTests.cpp @@ -15326,10 +15326,26 @@ public: m_device.destroyShaderModule(module, nullptr); } - void CheckRasterization(bool depth_feedback, bool packed_vertex_color = false) { - const char *name = packed_vertex_color ? "PackedFloatVertexColor" - : depth_feedback ? "DepthAttachmentFeedback" - : "PolygonModeRasterization"; + void CheckRasterization( + bool depth_feedback, + Prospero::BufferFormat color_format = Prospero::BufferFormat::k32_32_32_32Float) { + const char *name = depth_feedback ? "DepthAttachmentFeedback" : "PolygonModeRasterization"; + uint32_t packed_color = 0; + std::array packed_expected{}; + switch (color_format) { + case Prospero::BufferFormat::k11_11_10Float: + name = "PackedFloatVertexColor"; + packed_color = 0x801e0380u; + packed_expected = {0.5f, 1.0f, 2.0f, 1.0f}; + break; + case Prospero::BufferFormat::k10_10_10_2UScaled: + name = "PackedUscaledVertexColor"; + packed_color = 513u | (257u << 10u) | (1023u << 20u) | (3u << 30u); + packed_expected = {513.0f, 257.0f, 1023.0f, 3.0f}; + break; + default: break; + } + const bool packed_vertex_color = color_format != Prospero::BufferFormat::k32_32_32_32Float; const uint32_t extent = depth_feedback ? 8 : 32; constexpr uintptr_t depth_address = 0x0000000204400000ull; constexpr uint64_t allocation_size = 0x40000; @@ -15452,9 +15468,7 @@ public: vertex.buffers[0].stride = 6 * sizeof(float); vertex.resources[1].UpdateAddress48(2 * sizeof(float)); for (uint32_t i = 0; i < 2; i++) { - const auto format = i == 0 ? Prospero::BufferFormat::k32_32Float - : packed_vertex_color ? Prospero::BufferFormat::k11_11_10Float - : Prospero::BufferFormat::k32_32_32_32Float; + const auto format = i == 0 ? Prospero::BufferFormat::k32_32Float : color_format; vertex.resources[i].fields[3] = DstSel(4, 5, 6, 7) | (static_cast(format) << 12u); vertex.resources_dst[i].registers_num = @@ -15485,9 +15499,8 @@ public: std::vector vertex_words(vertices.size()); std::memcpy(vertex_words.data(), vertices.data(), sizeof(vertices)); if (packed_vertex_color) { - // R11/G11/B10 unsigned floats: 0.5, 1.0, 2.0; Vulkan supplies the missing alpha as 1. for (uint32_t i = 0; i < 3; i++) { - vertex_words[i * 6 + 2] = 0x801e0380u; + vertex_words[i * 6 + 2] = packed_color; } } auto buffer = CreateHostBuffer(name, sizeof(vertices), vk::BufferUsageFlagBits::eVertexBuffer, @@ -15580,12 +15593,11 @@ public: draw(filled); const auto solid_pixels = read_color(); if (packed_vertex_color) { - const std::array expected{0.5f, 1.0f, 2.0f, 1.0f}; const auto center = 4 * ((extent / 2) * extent + extent / 2); - for (uint32_t component = 0; component < expected.size(); component++) { + for (uint32_t component = 0; component < packed_expected.size(); component++) { Require(name, "packed vertex fetch and coverage", std::abs(std::bit_cast(solid_pixels[center + component]) - - expected[component]) < 0.0001f && solid_pixels[component] == 0, + packed_expected[component]) < 0.0001f && solid_pixels[component] == 0, "packed vertex color changed channels, clamped HDR, or filled outside the triangle"); } } else if (depth_feedback) { @@ -40011,7 +40023,8 @@ int main(int argc, char **argv) { if (argc == 2 && std::strcmp(argv[1], "--polygon-mode-only") == 0) { VulkanHarness vulkan; vulkan.CheckRasterization(false); - vulkan.CheckRasterization(false, true); + vulkan.CheckRasterization(false, Prospero::BufferFormat::k11_11_10Float); + vulkan.CheckRasterization(false, Prospero::BufferFormat::k10_10_10_2UScaled); return 0; } if (argc == 2 && std::strcmp(argv[1], "--htile-clear-only") == 0) { @@ -40278,7 +40291,8 @@ int main(int argc, char **argv) { vulkan.CheckRenderExecutorStencilBindingDiscovery(); vulkan.CheckBgra16Readback(); vulkan.CheckRasterization(false); - vulkan.CheckRasterization(false, true); + vulkan.CheckRasterization(false, Prospero::BufferFormat::k11_11_10Float); + vulkan.CheckRasterization(false, Prospero::BufferFormat::k10_10_10_2UScaled); vulkan.CheckBufferCacheDirtyGarbageCollection(); #endif } else {