From e2e52965df2e1f4d6ca179e8ec945e791da94656 Mon Sep 17 00:00:00 2001 From: Swung0x48 Date: Wed, 25 Feb 2026 16:12:33 +0800 Subject: [PATCH] [Feat] (MG_Backend/DirectVulkan): VkClearManager --- CMakeLists.txt | 3 +- .../DirectVulkan/Renderer/VkClearManager.cpp | 85 +++++++++++++++++++ .../DirectVulkan/Renderer/VkClearManager.h | 49 +++++++++++ .../FramebufferState/FramebufferObject.h | 1 + MobileGL/MG_Util/Types.h | 2 + 5 files changed, 139 insertions(+), 1 deletion(-) create mode 100644 MobileGL/MG_Backend/DirectVulkan/Renderer/VkClearManager.cpp create mode 100644 MobileGL/MG_Backend/DirectVulkan/Renderer/VkClearManager.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 140dfef1..cbb1302c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -225,10 +225,11 @@ set(SOURCE_FILES MobileGL/MG_Backend/DirectVulkan/Renderer/VertexInputStateBuilder.cpp MobileGL/MG_Backend/DirectVulkan/Renderer/VertexInputStateFactory.cpp MobileGL/MG_Backend/DirectVulkan/Renderer/VkBufferObject.cpp - MobileGL/MG_Backend/DirectVulkan/Renderer/VkRenderTargetManager.cpp + MobileGL/MG_Backend/DirectVulkan/Renderer/VkRenderTargetManager.cpp MobileGL/MG_Backend/DirectVulkan/Renderer/VkRenderPassManager.cpp MobileGL/MG_Backend/DirectVulkan/Renderer/VkTextureManager.cpp MobileGL/MG_Backend/DirectVulkan/Renderer/VkSamplerManager.cpp + MobileGL/MG_Backend/DirectVulkan/Renderer/VkClearManager.cpp MobileGL/MG_State/GLState/Core.cpp MobileGL/MG_State/GLState/ErrorState/Error.cpp diff --git a/MobileGL/MG_Backend/DirectVulkan/Renderer/VkClearManager.cpp b/MobileGL/MG_Backend/DirectVulkan/Renderer/VkClearManager.cpp new file mode 100644 index 00000000..08b9fdb7 --- /dev/null +++ b/MobileGL/MG_Backend/DirectVulkan/Renderer/VkClearManager.cpp @@ -0,0 +1,85 @@ +// MobileGL - MobileGL/MG_Backend/DirectVulkan/Renderer/VkClearManager.cpp +// Copyright (c) 2025-2026 MobileGL-Dev +// Licensed under the GNU Lesser General Public License v3.0: +// https://www.gnu.org/licenses/gpl-3.0.txt +// https://www.gnu.org/licenses/lgpl-3.0.txt +// SPDX-License-Identifier: LGPL-3.0-only +// End of Source File Header + +#include "VkClearManager.h" + +namespace MobileGL::MG_Backend::DirectVulkan { + Bool VkClearManager::Initialize() { + return true; + } + + void VkClearManager::Shutdown() { + + } + + void VkClearManager::QueueClear(GLbitfield mask, const ClearFramebufferPayload& clearPayload, + MG_State::GLState::FramebufferObject& drawFbo) { + if (mask & GL_COLOR_BUFFER_BIT) { + auto& drawbufs = drawFbo.GetDrawBuffers(); + // This should automatically work on default & offscreen FBO + for (auto drawbuf: drawbufs) { + if (drawbuf == FramebufferAttachmentType::None || + drawFbo.GetAttachment(drawbuf).IsRenderbuffer()) + continue; + + QueueClear({ + .color = clearPayload.color, + .attachmentType = drawbuf + }, drawFbo.GetAttachment(drawbuf).GetTexture()); + } + } + + if (mask & GL_DEPTH_BUFFER_BIT && + !drawFbo.GetAttachment(FramebufferAttachmentType::Depth).IsRenderbuffer()) { + QueueClear({ + .depth = clearPayload.depth, + .attachmentType = FramebufferAttachmentType::Depth, + }, drawFbo.GetAttachment(FramebufferAttachmentType::Depth).GetTexture()); + } + + if (mask & GL_STENCIL_BUFFER_BIT && + !drawFbo.GetAttachment(FramebufferAttachmentType::Stencil).IsRenderbuffer()) { + QueueClear({ + .stencil = clearPayload.stencil, + .attachmentType = FramebufferAttachmentType::Stencil, + }, drawFbo.GetAttachment(FramebufferAttachmentType::Depth).GetTexture()); + } + } + + void VkClearManager::QueueClear(const ClearAttachmentPayload& clearPayload, + const SharedPtr& texture) { + WeakPtr weakTexturePtr = texture; + if (weakTexturePtr.expired()) + return; + auto* pTexture = weakTexturePtr.lock().get(); + m_aliveObjects[pTexture] = weakTexturePtr; + m_pendingClears[pTexture] = clearPayload; + } + + Bool VkClearManager::DequeueClear(MG_State::GLState::ITextureObject* texture, ClearAttachmentPayload& outPayload) { + if (m_aliveObjects.find(texture) == m_aliveObjects.end()) + return false; + + outPayload = m_pendingClears[texture]; + m_aliveObjects.erase(texture); + m_pendingClears.erase(texture); + return true; + } + + SizeT VkClearManager::CollectGarbage() { + SizeT count = 0; + for (const auto& [raw, weak]: m_aliveObjects) { + if (weak.expired()) { + count++; + m_pendingClears.erase(raw); + m_aliveObjects.erase(raw); + } + } + return count; + } +} // namespace MobileGL::MG_Backend::DirectVulkan diff --git a/MobileGL/MG_Backend/DirectVulkan/Renderer/VkClearManager.h b/MobileGL/MG_Backend/DirectVulkan/Renderer/VkClearManager.h new file mode 100644 index 00000000..ad511026 --- /dev/null +++ b/MobileGL/MG_Backend/DirectVulkan/Renderer/VkClearManager.h @@ -0,0 +1,49 @@ +// MobileGL - MobileGL/MG_Backend/DirectVulkan/Renderer/VkClearManager.h +// Copyright (c) 2025-2026 MobileGL-Dev +// Licensed under the GNU Lesser General Public License v3.0: +// https://www.gnu.org/licenses/gpl-3.0.txt +// https://www.gnu.org/licenses/lgpl-3.0.txt +// SPDX-License-Identifier: LGPL-3.0-only +// End of Source File Header + +#pragma once + +#include "../VkIncludes.h" +#include "../VulkanRendererConfig.h" +#include "MG_State/GLState/FramebufferState/FramebufferObject.h" +#include "MG_Util/Math/VectorTypes.h" + +#include + +namespace MobileGL::MG_Backend::DirectVulkan { + struct ClearFramebufferPayload { + FloatVec4 color; + Float depth{}; + Uint32 stencil{}; + }; + + struct ClearAttachmentPayload { + union { + FloatVec4 color; + Float depth{}; + Uint32 stencil; + }; + FramebufferAttachmentType attachmentType = FramebufferAttachmentType::Color0; + }; + + class VkClearManager { + public: + Bool Initialize(); + void Shutdown(); + + void QueueClear(GLbitfield mask, const ClearFramebufferPayload& clearPayload, MG_State::GLState::FramebufferObject& drawFbo); + void QueueClear( + const ClearAttachmentPayload& clearPayload, + const SharedPtr& texture); + Bool DequeueClear(MG_State::GLState::ITextureObject* texture, ClearAttachmentPayload& outPayload); + SizeT CollectGarbage(); + private: + UnorderedMap m_pendingClears; + UnorderedMap> m_aliveObjects; + }; +} // namespace MobileGL::MG_Backend::DirectVulkan diff --git a/MobileGL/MG_State/GLState/FramebufferState/FramebufferObject.h b/MobileGL/MG_State/GLState/FramebufferState/FramebufferObject.h index c0061971..cd029c89 100644 --- a/MobileGL/MG_State/GLState/FramebufferState/FramebufferObject.h +++ b/MobileGL/MG_State/GLState/FramebufferState/FramebufferObject.h @@ -62,6 +62,7 @@ namespace MobileGL { Color29, Color30, Color31, + ColorMax = Color31, FramebufferAttachmentTypeCount, Unknown = -1 diff --git a/MobileGL/MG_Util/Types.h b/MobileGL/MG_Util/Types.h index 9ba2fc86..08681eab 100644 --- a/MobileGL/MG_Util/Types.h +++ b/MobileGL/MG_Util/Types.h @@ -42,6 +42,8 @@ namespace MobileGL { using SharedPtr = std::shared_ptr; template using UniquePtr = std::unique_ptr; + template + using WeakPtr = std::weak_ptr; template inline SharedPtr MakeShared(Args&&... args) { return std::make_shared(std::forward(args)...);