// MobileGL - MobileGL/MG_Backend/DirectVulkan/Renderer/BufferArena.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 "BufferSlice.h" #include "VkBufferObject.h" #include "../VkIncludes.h" #include #include namespace MobileGL::MG_Backend::DirectVulkan { struct BufferArenaDesc { VmaAllocator allocator = nullptr; Uint32 frameCount = 0; VkBufferUsageFlags usage = 0; VmaMemoryUsage memoryUsage = VMA_MEMORY_USAGE_AUTO; VmaAllocationCreateFlags allocationFlags = 0; VkDeviceSize minBufferSize = 0; Bool persistentlyMapped = false; }; class BufferArena { public: Bool Initialize(const BufferArenaDesc& desc); void Shutdown(); void BeginFrame(Uint32 frameIndex); void ResetFrame(Uint32 frameIndex); void CollectDeferredReleases(Uint32 frameIndex); Bool Allocate(Uint32 frameIndex, VkDeviceSize size, VkDeviceSize alignment, BufferSlice& outSlice); Bool Upload(Uint32 frameIndex, const void* data, VkDeviceSize size, VkDeviceSize alignment, BufferSlice& outSlice); VkDeviceSize GetWriteCursor(Uint32 frameIndex) const; Uint32 GetFrameCount() const; private: struct FrameResources { VkBufferObject buffer; VkDeviceSize writeCursor = 0; }; Bool EnsureCapacity(Uint32 frameIndex, VkDeviceSize requiredEndOffset); void AssertValidFrameIndex(Uint32 frameIndex) const; BufferArenaDesc m_desc{}; Vector m_frames; Vector> m_deferredReleases; }; } // namespace MobileGL::MG_Backend::DirectVulkan