From 82f509c5350de1bd45061fc32d4f20801ca5e946 Mon Sep 17 00:00:00 2001 From: Swung0x48 Date: Sun, 20 Sep 2026 20:58:48 -0400 Subject: [PATCH] [MG_Backend] (Magma): reconcile a shader-written element buffer before the draw records The client-memory upload's index scan waits for the GPU (SyncGpuWrites), and that wait flushes the batch the frame's command buffer belongs to - so a handle taken before it is stale by the time the draw records into it. Reconciling in the entry point, before SetupDraw starts recording, keeps the wait out of the recording. --- .../MG_Backend/DirectVulkan/DirectVulkan.cpp | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/MobileGL/MG_Backend/DirectVulkan/DirectVulkan.cpp b/MobileGL/MG_Backend/DirectVulkan/DirectVulkan.cpp index 54b2805f..870cdc71 100644 --- a/MobileGL/MG_Backend/DirectVulkan/DirectVulkan.cpp +++ b/MobileGL/MG_Backend/DirectVulkan/DirectVulkan.cpp @@ -1045,6 +1045,30 @@ namespace MobileGL::MG_Backend::DirectVulkan { payload.params.indexCount = count; payload.params.instanceCount = 1; + // A CLIENT-MEMORY VERTEX ARRAY'S upload is bounded by a scan of this draw's index bytes, + // and those bytes may be shader-written: the scan reconciles the element buffer's shadow, + // which WAITS for the GPU. A wait in the middle of the draw's own recording flushes the + // batch that command buffer belongs to - the handle SetupDraw is holding goes stale, and + // the next vkCmd* records into a command buffer that is no longer the frame's. Reconciling + // HERE, before SetupDraw starts recording, keeps the wait out of the recording. + if (MG_Config::Transport == MG_Config::TransportMode::Monolith) { + const auto& currentVAO = MGB_CTX->GetBoundVertexArray(); + Bool clientArray = false; + if (currentVAO) { + for (const auto& attribute : currentVAO->GetAllAttributes()) { + if (attribute.Enabled && !attribute.Buffer) { + clientArray = true; + break; + } + } + } + if (clientArray) { + if (const auto& elementBuffer = currentVAO->GetIndexBufferBindingSlot().GetBoundObject()) { + elementBuffer->SyncGpuWrites(); + } + } + } + pVulkanRenderer->DrawElements(payload); }