From a345369269c720692f3becdfddca59a50cdfd7ed Mon Sep 17 00:00:00 2001 From: Swung0x48 Date: Wed, 6 May 2026 13:15:08 +0800 Subject: [PATCH] [Fix] (MG_Backend/DirectVulkan): fix null dereference crash in VkClearManager --- CMakeLists.txt | 2 +- .../DirectVulkan/Renderer/VkClearManager.cpp | 62 +++++++++++++------ 2 files changed, 43 insertions(+), 21 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 79f6f78b..42ed97d6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,7 +4,7 @@ project("MobileGL") option(MOBILEGL_BUILD_TEST "Build MobileGL tests" ON ) option(MOBILEGL_BUILD_BENCHMARK "Build MobileGL benchmarks" ON ) -option(MOBILEGL_FORCE_RELEASE_OPT "Enable Release optimization flags in Debug build" ON ) +option(MOBILEGL_FORCE_RELEASE_OPT "Enable Release optimization flags in Debug build" OFF) option(MOBILEGL_ENABLE_TRACY "Enable tracy for profiling" OFF) if (ANDROID) diff --git a/MobileGL/MG_Backend/DirectVulkan/Renderer/VkClearManager.cpp b/MobileGL/MG_Backend/DirectVulkan/Renderer/VkClearManager.cpp index 3baaa5ca..16187c3b 100644 --- a/MobileGL/MG_Backend/DirectVulkan/Renderer/VkClearManager.cpp +++ b/MobileGL/MG_Backend/DirectVulkan/Renderer/VkClearManager.cpp @@ -12,6 +12,20 @@ #include "MG_Util/Converters/MGToStr/TextureEnumConverter.h" namespace MobileGL::MG_Backend::DirectVulkan { + static SharedPtr GetClearableAttachmentTexture( + const MG_State::GLState::FramebufferObject& drawFbo, FramebufferAttachmentType attachmentType) { + if (attachmentType == FramebufferAttachmentType::None) { + return nullptr; + } + + const auto& attachment = drawFbo.GetAttachment(attachmentType); + if (!attachment.IsTexture() || attachment.IsRenderbuffer()) { + return nullptr; + } + + return attachment.GetTexture(); + } + Bool VkClearManager::Initialize() { return true; } @@ -26,39 +40,47 @@ namespace MobileGL::MG_Backend::DirectVulkan { auto& drawbufs = drawFbo.GetDrawBuffers(); // This should automatically work on default & offscreen FBO for (auto drawbuf: drawbufs) { - if (drawbuf == FramebufferAttachmentType::None || - drawFbo.GetAttachment(drawbuf).IsRenderbuffer()) + auto texture = GetClearableAttachmentTexture(drawFbo, drawbuf); + if (!texture) { continue; + } QueueClear({ .mask = GL_COLOR_BUFFER_BIT, .color = clearPayload.color - }, drawFbo.GetAttachment(drawbuf).GetTexture()); + }, texture); + MGLOG_D("%s: %s (texture %d) - color = (%.2f, %.2f, %.2f, %.2f)", __func__, MG_Util::ConvertFramebufferAttachmentTypeToString(drawbuf).c_str(), - drawFbo.GetAttachment(drawbuf).GetTexture()->GetExternalIndex(), + texture->GetExternalIndex(), clearPayload.color[0], clearPayload.color[1], clearPayload.color[2], clearPayload.color[3]); } } - if (mask & GL_DEPTH_BUFFER_BIT && - !drawFbo.GetAttachment(FramebufferAttachmentType::Depth).IsRenderbuffer()) { - QueueClear({ - .mask = GL_DEPTH_BUFFER_BIT, - .depth = clearPayload.depth, - }, drawFbo.GetAttachment(FramebufferAttachmentType::Depth).GetTexture()); - MGLOG_D("%s: Depth (texture %d) - depth = (%.2f)", __func__, - drawFbo.GetAttachment(FramebufferAttachmentType::Depth).GetTexture()->GetExternalIndex(), clearPayload.depth); + if (mask & GL_DEPTH_BUFFER_BIT) { + auto texture = GetClearableAttachmentTexture(drawFbo, FramebufferAttachmentType::Depth); + if (texture) { + QueueClear({ + .mask = GL_DEPTH_BUFFER_BIT, + .depth = clearPayload.depth, + }, texture); + + MGLOG_D("%s: Depth (texture %d) - depth = (%.2f)", __func__, + texture->GetExternalIndex(), clearPayload.depth); + } } - if (mask & GL_STENCIL_BUFFER_BIT && - !drawFbo.GetAttachment(FramebufferAttachmentType::Stencil).IsRenderbuffer()) { - QueueClear({ - .mask = GL_STENCIL_BUFFER_BIT, - .stencil = clearPayload.stencil, - }, drawFbo.GetAttachment(FramebufferAttachmentType::Stencil).GetTexture()); - MGLOG_D("%s: Stencil (texture %d) - stencil = (%u)", __func__, - drawFbo.GetAttachment(FramebufferAttachmentType::Stencil).GetTexture()->GetExternalIndex(), clearPayload.stencil); + if (mask & GL_STENCIL_BUFFER_BIT) { + auto texture = GetClearableAttachmentTexture(drawFbo, FramebufferAttachmentType::Stencil); + if (texture) { + QueueClear({ + .mask = GL_STENCIL_BUFFER_BIT, + .stencil = clearPayload.stencil, + }, texture); + + MGLOG_D("%s: Stencil (texture %d) - stencil = (%u)", __func__, + texture->GetExternalIndex(), clearPayload.stencil); + } } }