From 853c5f1264fc91fd78fd0a26e0047d6a965e7103 Mon Sep 17 00:00:00 2001 From: Swung0x48 Date: Tue, 29 Sep 2026 19:55:53 -0400 Subject: [PATCH] [Fix] (Magma): a uniform block declared at an empty binding point reads a zeroed block instead of dereferencing a null buffer --- .../DirectVulkan/Renderer/UniformManager.cpp | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/MobileGL/MG_Backend/DirectVulkan/Renderer/UniformManager.cpp b/MobileGL/MG_Backend/DirectVulkan/Renderer/UniformManager.cpp index 8a417540..0282863f 100644 --- a/MobileGL/MG_Backend/DirectVulkan/Renderer/UniformManager.cpp +++ b/MobileGL/MG_Backend/DirectVulkan/Renderer/UniformManager.cpp @@ -2099,9 +2099,19 @@ namespace MobileGL::MG_Backend::DirectVulkan { auto& bindingPoint = MG_State::pGLContext->GetBufferBindingPoint(BufferTarget::Uniform, frontendBinding); const auto& bufferObject = bindingPoint.GetBoundObject(); - MOBILEGL_ASSERT(bufferObject != nullptr, - "ResolveUniformBufferPayload: no UBO bound at frontend binding %u for block '%s'", - frontendBinding, program.GetUniformBlockName(static_cast(blockIndex)).c_str()); + static thread_local Vector paddedUbo; + if (bufferObject == nullptr) { + // A block the program declares at a point with nothing bound - never bound, or its + // buffer was deleted while bound, which unbinds it (UnboundUniformBlockScenario). GL + // leaves what the shader READS undefined and raises no error; this used to dereference + // the null object. Answer it with a zeroed block of the reflected size instead. + const VkDeviceSize blockSize = + static_cast(program.GetUBOSizeAt(static_cast(blockIndex))); + paddedUbo.assign(static_cast(blockSize > 0 ? blockSize : 16), 0); + out.payload = paddedUbo.data(); + out.payloadSize = static_cast(paddedUbo.size()); + return true; + } bufferObject->SyncPersistentMappedRange(); MOBILEGL_ASSERT(bufferObject->MappedData() != nullptr && bufferObject->GetSize() != 0, @@ -2134,7 +2144,6 @@ namespace MobileGL::MG_Backend::DirectVulkan { outSize = blockSize; outData = bufferObject->MappedData() + static_cast(rangeStart); if (available < blockSize) { - static thread_local Vector paddedUbo; paddedUbo.assign(static_cast(blockSize), 0); Memcpy(paddedUbo.data(), outData, static_cast(available)); outData = paddedUbo.data();