diff options
| author | Sssnowyyy <78863999+Sssnowyyy@users.noreply.github.com> | 2026-11-02 11:38:11 -0500 |
|---|---|---|
| committer | Sssnowyyy <78863999+Sssnowyyy@users.noreply.github.com> | 2026-11-02 14:53:47 -0500 |
| commit | 13fc5fda26e6b5a9af67f5a654e831187bfa1962 (patch) | |
| tree | c1666bbbbd10107c4cd6a9041e765135821526f9 /src/tests/video_core | |
| parent | 256b1dc346e19bc60c2884d4af875fc53ef0a99a (diff) | |
vulkan: repack 69-byte vertices only when needed
SetVertexRepackLayout returned old_mask | new_mask, which stays non-zero
on every draw that uses a 69-byte binding. PrepareDraw then re-dirtied the
vertex buffers and vertex input each time, so the repack compute pass ran
and the render pass ended once per draw, which is costly on tiled GPUs.
Return old_mask ^ new_mask so only a layout change re-dirties the
bindings. The repacked copy only stays valid while the source data is
unchanged, so the buffer cache now flags the vertex buffers overlapping a
CPU write, inline or DMA write, or GPU write, and re-dirties the repacked
ones before binding. Command buffer submission already invalidates all
vertex buffer state, which keeps the staging copy within its tick.
Also pass the source buffer size to the repack pass and clamp the
word-rounded storage descriptor range to it; it could run up to three
bytes past the end of the buffer. A binding that does not fit is skipped
like one over the device limits.
Follow-up to e38b738b84.
Assisted-by: Claude Sonnet 5.5 (implementation and commit message)
Diffstat (limited to 'src/tests/video_core')
| -rw-r--r-- | src/tests/video_core/vertex_repack.cpp | 26 |
1 files changed, 18 insertions, 8 deletions
diff --git a/src/tests/video_core/vertex_repack.cpp b/src/tests/video_core/vertex_repack.cpp index 6409be3ca4..3705a97926 100644 --- a/src/tests/video_core/vertex_repack.cpp +++ b/src/tests/video_core/vertex_repack.cpp @@ -85,7 +85,8 @@ TEST_CASE("Static vertex repacking requires explicit experimental opt-in", "[ver TEST_CASE("Vertex repack planning keeps descriptor offsets aligned", "[vertex_repack]") { for (const u32 alignment : {4U, 16U, 64U, 256U, 4096U}) { for (const u32 offset : {0U, 1U, 3U, 255U, 4099U}) { - const auto plan = Vulkan::MakeVertexRepackParameters(offset, 70, alignment, 1U << 20, 65535); + const auto plan = Vulkan::MakeVertexRepackParameters(offset, 70, alignment, 1U << 20, + 65535, 1U << 20); REQUIRE(plan.has_value()); REQUIRE(plan->source_base % alignment == 0); REQUIRE(plan->source_base + plan->source_bias == offset); @@ -99,13 +100,22 @@ TEST_CASE("Vertex repack planning keeps descriptor offsets aligned", "[vertex_re } TEST_CASE("Vertex repack planning rejects overflow and device-limit violations", "[vertex_repack]") { - REQUIRE_FALSE(Vulkan::MakeVertexRepackParameters(0, 0, 256, 1U << 20, 65535)); - REQUIRE_FALSE(Vulkan::MakeVertexRepackParameters(0, 69, 0, 1U << 20, 65535)); - REQUIRE_FALSE(Vulkan::MakeVertexRepackParameters(0, 69, 256, 71, 65535)); - REQUIRE_FALSE(Vulkan::MakeVertexRepackParameters(255, 69, 256, 323, 65535)); - REQUIRE_FALSE(Vulkan::MakeVertexRepackParameters(0, 69, 256, 1U << 20, 0)); - REQUIRE_FALSE(Vulkan::MakeVertexRepackParameters(0, 0xffffffffU, 256, ~u64{0}, 0xffffffffU)); - const auto one = Vulkan::MakeVertexRepackParameters(0, 69, 256, 72, 1); + REQUIRE_FALSE(Vulkan::MakeVertexRepackParameters(0, 0, 256, 1U << 20, 65535, 1U << 20)); + REQUIRE_FALSE(Vulkan::MakeVertexRepackParameters(0, 69, 0, 1U << 20, 65535, 1U << 20)); + REQUIRE_FALSE(Vulkan::MakeVertexRepackParameters(0, 69, 256, 71, 65535, 1U << 20)); + REQUIRE_FALSE(Vulkan::MakeVertexRepackParameters(255, 69, 256, 323, 65535, 1U << 20)); + REQUIRE_FALSE(Vulkan::MakeVertexRepackParameters(0, 69, 256, 1U << 20, 0, 1U << 20)); + REQUIRE_FALSE( + Vulkan::MakeVertexRepackParameters(0, 0xffffffffU, 256, ~u64{0}, 0xffffffffU, ~u64{0})); + const auto one = Vulkan::MakeVertexRepackParameters(0, 69, 256, 72, 1, 72); REQUIRE(one.has_value()); REQUIRE(one->source_range == 72); } + +TEST_CASE("Vertex repack planning keeps the source range inside the buffer", "[vertex_repack]") { + const auto clamped = Vulkan::MakeVertexRepackParameters(0, 69, 256, 1U << 20, 65535, 69); + REQUIRE(clamped.has_value()); + REQUIRE(clamped->source_range == 69); + REQUIRE_FALSE(Vulkan::MakeVertexRepackParameters(0, 69, 256, 1U << 20, 65535, 68)); + REQUIRE_FALSE(Vulkan::MakeVertexRepackParameters(300, 69, 256, 1U << 20, 65535, 256)); +} |
