/* * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ #pragma once #include "Base/Utils.hpp" #include namespace OpenVulkano::Vulkan { class MemoryAllocation { public: vk::DeviceMemory memory; size_t used; const size_t size; const uint32_t type; const vk::Device device; void* mapped; private: uint32_t mappedCount; static constexpr uint32_t CHILD_MAPPED_FLAG = 1u << 31; public: MemoryAllocation(size_t size, uint32_t type, vk::Device device): memory(nullptr), used(0), size(size), type(type), device(device), mapped(nullptr), mappedCount(0) { } ~MemoryAllocation() { if (device && memory) device.free(memory); } [[nodiscard]] size_t FreeSpace() const { return size - used; } [[nodiscard]] size_t FreeSpace(size_t alignment) const { return size - Utils::Align(used, alignment); } void HandleChildMappingValidation() const; void* Map() { HandleChildMappingValidation(); if (!mapped) { mapped = device.mapMemory(memory, 0, size, vk::MemoryMapFlags()); } mappedCount++; return mapped; } void UnMap() { if (mappedCount > 0) { mappedCount--; if (mappedCount == 0) { device.unmapMemory(memory); } } } [[nodiscard]] bool IsChildMapped() const { return mappedCount & CHILD_MAPPED_FLAG; } void* MapChild(size_t offset, vk::DeviceSize size) { HandleChildMappingValidation(); mappedCount |= CHILD_MAPPED_FLAG; mappedCount++; return device.mapMemory(memory, offset, size, vk::MemoryMapFlags()); } void UnMapChild() { mappedCount &= ~CHILD_MAPPED_FLAG; mappedCount--; if (mappedCount == 0) { device.unmapMemory(memory); } } }; }