gpu: add packed unsigned-scaled vertex formats

Co-authored-by: Çağatay Güçlü <33038942+defektu@users.noreply.github.com>
This commit is contained in:
nmzik
2026-10-05 01:15:06 +04:00
parent b27b89f513
commit 8e46a3ccfa
2 changed files with 29 additions and 14 deletions
+1
View File
@@ -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},
+28 -14
View File
@@ -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<float, 4> 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<uint32_t>(format) << 12u);
vertex.resources_dst[i].registers_num =
@@ -15485,9 +15499,8 @@ public:
std::vector<u32> 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<float, 4> 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<float>(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 {