vulkan_memory_allocator: Release allocations with no commits

master
ReinUsesLisp 2021-01-19 02:39:29 +07:00 committed by Fernando Sahmkow
parent 973bf306ed
commit 5b1efe522e
2 changed files with 22 additions and 5 deletions

@ -69,10 +69,10 @@ constexpr VkExportMemoryAllocateInfo EXPORT_ALLOCATE_INFO{
class MemoryAllocation { class MemoryAllocation {
public: public:
explicit MemoryAllocation(vk::DeviceMemory memory_, VkMemoryPropertyFlags properties, explicit MemoryAllocation(MemoryAllocator* const allocator_, vk::DeviceMemory memory_,
u64 allocation_size_, u32 type) VkMemoryPropertyFlags properties, u64 allocation_size_, u32 type)
: memory{std::move(memory_)}, allocation_size{allocation_size_}, property_flags{properties}, : allocator{allocator_}, memory{std::move(memory_)}, allocation_size{allocation_size_},
shifted_memory_type{1U << type} {} property_flags{properties}, shifted_memory_type{1U << type} {}
#if defined(_WIN32) || defined(__unix__) #if defined(_WIN32) || defined(__unix__)
~MemoryAllocation() { ~MemoryAllocation() {
@ -106,6 +106,10 @@ public:
const auto it = std::ranges::find(commits, begin, &Range::begin); const auto it = std::ranges::find(commits, begin, &Range::begin);
ASSERT_MSG(it != commits.end(), "Invalid commit"); ASSERT_MSG(it != commits.end(), "Invalid commit");
commits.erase(it); commits.erase(it);
if (commits.empty()) {
// Do not call any code involving 'this' after this call, the object will be destroyed
allocator->ReleaseMemory(this);
}
} }
[[nodiscard]] std::span<u8> Map() { [[nodiscard]] std::span<u8> Map() {
@ -171,6 +175,7 @@ private:
return candidate; return candidate;
} }
MemoryAllocator* const allocator; ///< Parent memory allocation.
const vk::DeviceMemory memory; ///< Vulkan memory allocation handler. const vk::DeviceMemory memory; ///< Vulkan memory allocation handler.
const u64 allocation_size; ///< Size of this allocation. const u64 allocation_size; ///< Size of this allocation.
const VkMemoryPropertyFlags property_flags; ///< Vulkan memory property flags. const VkMemoryPropertyFlags property_flags; ///< Vulkan memory property flags.
@ -275,10 +280,17 @@ bool MemoryAllocator::TryAllocMemory(VkMemoryPropertyFlags flags, u32 type_mask,
return false; return false;
} }
} }
allocations.push_back(std::make_unique<MemoryAllocation>(std::move(memory), flags, size, type)); allocations.push_back(
std::make_unique<MemoryAllocation>(this, std::move(memory), flags, size, type));
return true; return true;
} }
void MemoryAllocator::ReleaseMemory(MemoryAllocation* alloc) {
const auto it = std::ranges::find(allocations, alloc, &std::unique_ptr<MemoryAllocation>::get);
ASSERT(it != allocations.end());
allocations.erase(it);
}
std::optional<MemoryCommit> MemoryAllocator::TryCommit(const VkMemoryRequirements& requirements, std::optional<MemoryCommit> MemoryAllocator::TryCommit(const VkMemoryRequirements& requirements,
VkMemoryPropertyFlags flags) { VkMemoryPropertyFlags flags) {
for (auto& allocation : allocations) { for (auto& allocation : allocations) {

@ -69,6 +69,8 @@ private:
/// Memory allocator container. /// Memory allocator container.
/// Allocates and releases memory allocations on demand. /// Allocates and releases memory allocations on demand.
class MemoryAllocator { class MemoryAllocator {
friend MemoryAllocation;
public: public:
/** /**
* Construct memory allocator * Construct memory allocator
@ -104,6 +106,9 @@ private:
/// Tries to allocate a chunk of memory. /// Tries to allocate a chunk of memory.
bool TryAllocMemory(VkMemoryPropertyFlags flags, u32 type_mask, u64 size); bool TryAllocMemory(VkMemoryPropertyFlags flags, u32 type_mask, u64 size);
/// Releases a chunk of memory.
void ReleaseMemory(MemoryAllocation* alloc);
/// Tries to allocate a memory commit. /// Tries to allocate a memory commit.
std::optional<MemoryCommit> TryCommit(const VkMemoryRequirements& requirements, std::optional<MemoryCommit> TryCommit(const VkMemoryRequirements& requirements,
VkMemoryPropertyFlags flags); VkMemoryPropertyFlags flags);