From e5b002c8ccac8d02fcfaf5766623806103e7acff Mon Sep 17 00:00:00 2001 From: Anish Bhobe Date: Wed, 2 Apr 2025 21:56:49 +0200 Subject: [PATCH] Rename freelist and clean up code. --- aster/include/aster/systems/CMakeLists.txt | 2 +- aster/include/aster/systems/commit_manager.h | 21 ++- aster/include/aster/systems/manager.h | 36 +++-- .../include/aster/systems/resource_manager.h | 10 +- .../{image_view_manager.h => view_manager.h} | 2 +- aster/include/aster/util/CMakeLists.txt | 2 +- aster/include/aster/util/freelist.h | 96 +++++++++++++ aster/include/aster/util/intrusive_slist.h | 127 ------------------ aster/src/aster/systems/CMakeLists.txt | 2 +- aster/src/aster/systems/commit_manager.cpp | 8 +- aster/src/aster/systems/image_manager.cpp | 2 +- ...mage_view_manager.cpp => view_manager.cpp} | 4 +- samples/02_box/box.cpp | 3 +- samples/03_model_render/asset_loader.h | 2 +- samples/03_model_render/model_render.cpp | 2 + 15 files changed, 153 insertions(+), 166 deletions(-) rename aster/include/aster/systems/{image_view_manager.h => view_manager.h} (99%) create mode 100644 aster/include/aster/util/freelist.h delete mode 100644 aster/include/aster/util/intrusive_slist.h rename aster/src/aster/systems/{image_view_manager.cpp => view_manager.cpp} (95%) diff --git a/aster/include/aster/systems/CMakeLists.txt b/aster/include/aster/systems/CMakeLists.txt index 0055274..35ce1c5 100644 --- a/aster/include/aster/systems/CMakeLists.txt +++ b/aster/include/aster/systems/CMakeLists.txt @@ -7,7 +7,7 @@ INTERFACE "manager.h" "buffer_manager.h" "image_manager.h" - "image_view_manager.h" + "view_manager.h" "sampler_manager.h" "resource.h" "resource_manager.h" diff --git a/aster/include/aster/systems/commit_manager.h b/aster/include/aster/systems/commit_manager.h index ce8aa68..f5e46a2 100644 --- a/aster/include/aster/systems/commit_manager.h +++ b/aster/include/aster/systems/commit_manager.h @@ -7,17 +7,15 @@ #include "aster/aster.h" #include "buffer_manager.h" -#include "image_manager.h" +#include "view_manager.h" #include "sampler_manager.h" -#include "aster/util/intrusive_slist.h" +#include "aster/util/freelist.h" #include "EASTL/deque.h" #include "EASTL/intrusive_hash_map.h" -#include "EASTL/bonus/fixed_ring_buffer.h" #include "resource.h" -#include "aster/core/image_view.h" namespace systems { @@ -33,7 +31,7 @@ class CommitManager using Handle = typename Manager::Handle; using Resource = ResId; - struct Entry : public eastl::intrusive_hash_node_key + struct Entry : eastl::intrusive_hash_node_key { std::atomic m_CommitCount; @@ -51,7 +49,7 @@ class CommitManager assert(rc < MaxValue); } - bool + u32 IsReferenced() const { return m_CommitCount; @@ -87,9 +85,9 @@ class CommitManager static_assert(sizeof(Entry) == 24); eastl::vector m_Data; - IntrusiveStack m_FreeList; + FreeList m_FreeList; eastl::intrusive_hash_map m_InUse; - std::array, 4> m_ToDelete; + std::array, 4> m_ToDelete; u8 m_ToDeleteIndex = 0; explicit HandleMapper(const u32 maxCount) @@ -189,13 +187,14 @@ class CommitManager } void - ClearEntries(IntrusiveStack& entries) + ClearEntries(FreeList& entries) { - while (auto item = entries.TryPop()) + while (!entries.Empty()) { - Entry &entry = item.value(); + Entry &entry = entries.Pop(); entry.mKey.reset(); entry.m_CommitCount = 0; + } } }; diff --git a/aster/include/aster/systems/manager.h b/aster/include/aster/systems/manager.h index 640d1f4..09e707c 100644 --- a/aster/include/aster/systems/manager.h +++ b/aster/include/aster/systems/manager.h @@ -7,6 +7,7 @@ #include "aster/aster.h" #include "aster/core/type_traits.h" +#include "aster/util/freelist.h" #include #include @@ -32,10 +33,9 @@ class Manager : m_Data{maxCount} , m_Device{device} { - u32 i = 0; for (auto &element : m_Data) { - *Recast(&element) = ++i; + m_FreeList.Push(element); } } @@ -49,7 +49,6 @@ class Manager } } - m_FreeHead = 0; m_Device = nullptr; } @@ -60,11 +59,22 @@ class Manager { for (i64 i = m_Data.size() - 1; i >= 0; --i) { - if (auto *pIter = &m_Data[i]; !pIter->IsValid()) + if (auto *pIter = &m_Data[i]; !pIter->IsReferenced()) { pIter->Destroy(m_Device); - *Recast(pIter) = m_FreeHead; - m_FreeHead = i; + m_FreeList.Push(*pIter); + } + } + } + + void Sweep() requires concepts::SelfDestructible + { + for (i64 i = m_Data.size() - 1; i >= 0; --i) + { + if (auto *pIter = &m_Data[i]; !pIter->IsValid()) + { + pIter->Destroy(); + m_FreeList.Push(*pIter); } } } @@ -73,7 +83,7 @@ class Manager private: eastl::vector m_Data; // Data also keeps the freelist during 'not use'. - u32 m_FreeHead = 0; + FreeList m_FreeList; protected: const Device *m_Device; @@ -85,17 +95,15 @@ class Manager [[nodiscard]] Handle Alloc() { - ERROR_IF(m_FreeHead >= m_Data.size(), "Max buffers allocated.") THEN_ABORT(-1); + ERROR_IF(m_FreeList.Empty(), "Max buffers allocated.") THEN_ABORT(-1); - const auto index = m_FreeHead; - Type *pAlloc = &m_Data[index]; - m_FreeHead = *Recast(pAlloc); - memset(pAlloc, 0, sizeof *pAlloc); + Type &pAlloc = m_FreeList.Pop(); + memset(&pAlloc, 0, sizeof pAlloc); if constexpr (concepts::SelfDestructible) { - pAlloc->m_Device = m_Device; + pAlloc.m_Device = m_Device; } - return {pAlloc}; + return {&pAlloc}; } }; } // namespace systems diff --git a/aster/include/aster/systems/resource_manager.h b/aster/include/aster/systems/resource_manager.h index ae0e780..c5cbdee 100644 --- a/aster/include/aster/systems/resource_manager.h +++ b/aster/include/aster/systems/resource_manager.h @@ -9,7 +9,7 @@ #include "buffer_manager.h" #include "image_manager.h" -#include "image_view_manager.h" +#include "view_manager.h" #include "sampler_manager.h" namespace systems @@ -129,6 +129,14 @@ class ResourceManager return m_CombinedImageViews; } + void Update() + { + m_Views.Sweep(); + m_Images.Sweep(); + m_Buffers.Sweep(); + m_Samplers.Sweep(); + } + ~ResourceManager() = default; PIN_MEMORY(ResourceManager); diff --git a/aster/include/aster/systems/image_view_manager.h b/aster/include/aster/systems/view_manager.h similarity index 99% rename from aster/include/aster/systems/image_view_manager.h rename to aster/include/aster/systems/view_manager.h index ea6d4fa..d2f2b02 100644 --- a/aster/include/aster/systems/image_view_manager.h +++ b/aster/include/aster/systems/view_manager.h @@ -1,5 +1,5 @@ // ============================================= -// Aster: image_manager.h +// Aster: view_manager.h // Copyright (c) 2020-2024 Anish Bhobe // ============================================= diff --git a/aster/include/aster/util/CMakeLists.txt b/aster/include/aster/util/CMakeLists.txt index 34d26b6..fc5c8c0 100644 --- a/aster/include/aster/util/CMakeLists.txt +++ b/aster/include/aster/util/CMakeLists.txt @@ -5,4 +5,4 @@ cmake_minimum_required(VERSION 3.13) target_sources(aster_core INTERFACE "logger.h" - "intrusive_slist.h") + "freelist.h") diff --git a/aster/include/aster/util/freelist.h b/aster/include/aster/util/freelist.h new file mode 100644 index 0000000..354d84f --- /dev/null +++ b/aster/include/aster/util/freelist.h @@ -0,0 +1,96 @@ +// ============================================= +// Aster: freelist.h +// Copyright (c) 2020-2024 Anish Bhobe +// ============================================= + +#pragma once + +#include + +struct FreeListNode +{ + FreeListNode *m_Next; +}; + +template +concept FreeListCapable = sizeof(T) >= sizeof(FreeListNode); + +template +struct FreeList +{ + using Value = T; + using Reference = T &; + using ConstReference = const T &; + using Pointer = T *; + + FreeListNode* m_Top; + + FreeList() + : m_Top{nullptr} + { + } + + FreeList(FreeList &&other) noexcept + : m_Top{Take(other.m_Top)} + { + } + + FreeList & + operator=(FreeList &&other) noexcept + { + if (this == &other) + return *this; + m_Top = Take(other.m_Top); + return *this; + } + + DISALLOW_COPY_AND_ASSIGN(FreeList); + + ~FreeList() + { + m_Top = nullptr; + } + + [[nodiscard]] bool + Empty() const + { + return !m_Top; + } + + [[nodiscard]] Reference + Pop() + { + assert(m_Top); + Reference ref = *Recast(m_Top); + m_Top = m_Top->m_Next; + return ref; + } + + void + Push(Reference ref) + { + auto next = Recast(&ref); + next->m_Next = m_Top; + m_Top = next; + } + + [[nodiscard]] ConstReference + Peek() const + { + assert(m_Top); + return *m_Top; + } + + [[nodiscard]] Reference + Peek() + { + assert(m_Top); + return *m_Top; + } + + void + Clear() + { + m_Top = nullptr; + } +}; diff --git a/aster/include/aster/util/intrusive_slist.h b/aster/include/aster/util/intrusive_slist.h deleted file mode 100644 index e0ff4fe..0000000 --- a/aster/include/aster/util/intrusive_slist.h +++ /dev/null @@ -1,127 +0,0 @@ -// ============================================= -// Aster: intrusive_slist.h -// Copyright (c) 2020-2024 Anish Bhobe -// ============================================= - -#pragma once - -#include - -template -concept HasNext = requires(T &a) { - { a.Next() } -> std::same_as; - { a.SetNext(a) }; -}; - -struct IntrusiveStackNode -{ - IntrusiveStackNode *m_Next; - - IntrusiveStackNode * - Next() const - { - return m_Next; - } - - void - SetNext(IntrusiveStackNode &a) - { - m_Next = &a; - } -}; - -template -struct IntrusiveStack -{ - using Value = T; - using Reference = T &; - using OptionalRef = std::optional>; - using ConstReference = const T &; - using Pointer = T *; - - Pointer m_Top; - - IntrusiveStack() - : m_Top{nullptr} - { - } - - IntrusiveStack(IntrusiveStack &&other) noexcept - : m_Top{Take(other.m_Top)} - { - } - - IntrusiveStack & - operator=(IntrusiveStack &&other) noexcept - { - if (this == &other) - return *this; - m_Top = Take(other.m_Top); - return *this; - } - - DISALLOW_COPY_AND_ASSIGN(IntrusiveStack); - - ~IntrusiveStack() - { - m_Top = nullptr; - } - - [[nodiscard]] bool - Empty() const - { - return !m_Top; - } - - [[nodiscard]] Reference - Pop() - { - assert(m_Top); - Reference ref = *m_Top; - m_Top = m_Top->Next(); - return ref; - } - - [[nodiscard]] OptionalRef - TryPop() - { - if (m_Top) - return Pop(); - return std::nullopt; - } - - void - Push(Reference ref) - { - ref.SetNext(*m_Top); - m_Top = &ref; - } - - [[nodiscard]] ConstReference - Peek() const - { - assert(m_Top); - return *m_Top; - } - - [[nodiscard]] Reference - Peek() - { - assert(m_Top); - return *m_Top; - } - - [[nodiscard]] OptionalRef - TryPeek() - { - if (m_Top) - return Peek(); - return std::nullopt; - } - - void - Clear() - { - m_Top = nullptr; - } -}; diff --git a/aster/src/aster/systems/CMakeLists.txt b/aster/src/aster/systems/CMakeLists.txt index 8de503c..dcd476c 100644 --- a/aster/src/aster/systems/CMakeLists.txt +++ b/aster/src/aster/systems/CMakeLists.txt @@ -7,6 +7,6 @@ PRIVATE "manager.cpp" "buffer_manager.cpp" "image_manager.cpp" -"image_view_manager.cpp" +"view_manager.cpp" "sampler_manager.cpp" "commit_manager.cpp") diff --git a/aster/src/aster/systems/commit_manager.cpp b/aster/src/aster/systems/commit_manager.cpp index 00881d0..264368d 100644 --- a/aster/src/aster/systems/commit_manager.cpp +++ b/aster/src/aster/systems/commit_manager.cpp @@ -55,10 +55,10 @@ CommitManager::CommitManager(const Device *device, u32 const maxBuffers, const u .type = vk::DescriptorType::eCombinedImageSampler, .descriptorCount = maxImages, }, - // vk::DescriptorPoolSize{ - // .type = vk::DescriptorType::eStorageImage, - // .descriptorCount = storageTexturesCount, - // }, + vk::DescriptorPoolSize{ + .type = vk::DescriptorType::eStorageImage, + .descriptorCount = maxStorageImages, + }, }; const vk::DescriptorPoolCreateInfo poolCreateInfo = { diff --git a/aster/src/aster/systems/image_manager.cpp b/aster/src/aster/systems/image_manager.cpp index 4b90566..9e64aa8 100644 --- a/aster/src/aster/systems/image_manager.cpp +++ b/aster/src/aster/systems/image_manager.cpp @@ -1,5 +1,5 @@ // ============================================= -// Aster: buffer_manager.cpp +// Aster: image_manager.cpp // Copyright (c) 2020-2025 Anish Bhobe // ============================================= diff --git a/aster/src/aster/systems/image_view_manager.cpp b/aster/src/aster/systems/view_manager.cpp similarity index 95% rename from aster/src/aster/systems/image_view_manager.cpp rename to aster/src/aster/systems/view_manager.cpp index 8a7a4e8..a4557d5 100644 --- a/aster/src/aster/systems/image_view_manager.cpp +++ b/aster/src/aster/systems/view_manager.cpp @@ -1,9 +1,9 @@ // ============================================= -// Aster: image_view_manager.cpp +// Aster: view_manager.cpp // Copyright (c) 2020-2025 Anish Bhobe // ============================================= -#include "systems/image_view_manager.h" +#include "systems/view_manager.h" #include "core/device.h" diff --git a/samples/02_box/box.cpp b/samples/02_box/box.cpp index 4e88987..a00ed39 100644 --- a/samples/02_box/box.cpp +++ b/samples/02_box/box.cpp @@ -23,7 +23,7 @@ #include "aster/systems/commit_manager.h" #include "frame.h" #include "stb_image.h" -#include "aster/systems/image_view_manager.h" +#include "aster/systems/view_manager.h" #include "aster/systems/resource_manager.h" #include @@ -427,6 +427,7 @@ main(int, char **) { Time::Update(); commitManager.Update(); + resourceManager.Update(); camera.m_Model *= rotate(mat4{1.0f}, Cast(45.0_deg * Time::m_Delta), vec3(0.0f, 1.0f, 0.0f)); ubo->Write(0, sizeof camera, &camera); diff --git a/samples/03_model_render/asset_loader.h b/samples/03_model_render/asset_loader.h index c5adf60..3d27010 100644 --- a/samples/03_model_render/asset_loader.h +++ b/samples/03_model_render/asset_loader.h @@ -12,7 +12,7 @@ #include "nodes.h" #include "tiny_gltf.h" #include "aster/systems/image_manager.h" -#include "aster/systems/image_view_manager.h" +#include "aster/systems/view_manager.h" #include "aster/systems/resource.h" namespace systems diff --git a/samples/03_model_render/model_render.cpp b/samples/03_model_render/model_render.cpp index a4cea1b..be33502 100644 --- a/samples/03_model_render/model_render.cpp +++ b/samples/03_model_render/model_render.cpp @@ -432,6 +432,8 @@ main(int, char **) while (window.Poll()) { Time::Update(); + commitManager.Update(); + resourceManager.Update(); gui::StartBuild();