From 61b0532865643f8d36869e339b4493aa216354d2 Mon Sep 17 00:00:00 2001 From: Swung0x48 Date: Mon, 10 Aug 2026 21:58:06 -0400 Subject: [PATCH] [Fix] (MG_Backend/DirectVulkan): replay client-memory multi-draw through the single-draw path - the batched shared index view cannot express per-draw client pointers and dropped the whole batch --- .../MG_Backend/DirectVulkan/DirectVulkan.cpp | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/MobileGL/MG_Backend/DirectVulkan/DirectVulkan.cpp b/MobileGL/MG_Backend/DirectVulkan/DirectVulkan.cpp index 45c8a899..eb108838 100644 --- a/MobileGL/MG_Backend/DirectVulkan/DirectVulkan.cpp +++ b/MobileGL/MG_Backend/DirectVulkan/DirectVulkan.cpp @@ -966,6 +966,29 @@ namespace MobileGL::MG_Backend::DirectVulkan { if (drawcount <= 0) { return; } + + // With no element-array buffer bound, every indices[i] is a client pointer into a + // separate CPU allocation, not an offset into one shared buffer. The batched payload + // below cannot express that: it carries ONE index-buffer view for the whole batch and + // turns each pointer into a firstIndex relative to it. Replay the sub-draws through + // the single-draw entry point instead - it snapshots each client range into its own + // transient slice, which is exactly what the unrolled draws this must match do. + // (The batch used to be built this way; the shared-view rewrite that added + // MultiDrawIndexedCmd left the client-memory shape addressing a view whose byte + // offset is a hardcoded 0, so UploadAndBindIndexBuffer saw a null client pointer, + // declined the whole batch and painted nothing.) + const auto& vao = *MG_State::pGLContext->GetBoundVertexArray(); + if (vao.GetIndexBufferBindingSlot().GetBoundObject() == nullptr) { + for (GLsizei i = 0; i < drawcount; ++i) { + if (count[i] <= 0) { + continue; + } + DrawElementsBaseVertex(mode, count[i], type, indices[i], + basevertex != nullptr ? basevertex[i] : 0); + } + return; + } + MultiDrawIndexedCmd payload{}; payload.mode = mode; payload.indexBufferView.indexType = type;