Rename freelist and clean up code.

This commit is contained in:
Anish Bhobe 2025-04-02 21:56:49 +02:00
parent ec6aeb6f3b
commit e5b002c8cc
15 changed files with 153 additions and 166 deletions

View File

@ -7,7 +7,7 @@ INTERFACE
"manager.h" "manager.h"
"buffer_manager.h" "buffer_manager.h"
"image_manager.h" "image_manager.h"
"image_view_manager.h" "view_manager.h"
"sampler_manager.h" "sampler_manager.h"
"resource.h" "resource.h"
"resource_manager.h" "resource_manager.h"

View File

@ -7,17 +7,15 @@
#include "aster/aster.h" #include "aster/aster.h"
#include "buffer_manager.h" #include "buffer_manager.h"
#include "image_manager.h" #include "view_manager.h"
#include "sampler_manager.h" #include "sampler_manager.h"
#include "aster/util/intrusive_slist.h" #include "aster/util/freelist.h"
#include "EASTL/deque.h" #include "EASTL/deque.h"
#include "EASTL/intrusive_hash_map.h" #include "EASTL/intrusive_hash_map.h"
#include "EASTL/bonus/fixed_ring_buffer.h"
#include "resource.h" #include "resource.h"
#include "aster/core/image_view.h"
namespace systems namespace systems
{ {
@ -33,7 +31,7 @@ class CommitManager
using Handle = typename Manager::Handle; using Handle = typename Manager::Handle;
using Resource = ResId<Type>; using Resource = ResId<Type>;
struct Entry : public eastl::intrusive_hash_node_key<Handle> struct Entry : eastl::intrusive_hash_node_key<Handle>
{ {
std::atomic<u32> m_CommitCount; std::atomic<u32> m_CommitCount;
@ -51,7 +49,7 @@ class CommitManager
assert(rc < MaxValue<u32>); assert(rc < MaxValue<u32>);
} }
bool u32
IsReferenced() const IsReferenced() const
{ {
return m_CommitCount; return m_CommitCount;
@ -87,9 +85,9 @@ class CommitManager
static_assert(sizeof(Entry) == 24); static_assert(sizeof(Entry) == 24);
eastl::vector<Entry> m_Data; eastl::vector<Entry> m_Data;
IntrusiveStack<Entry> m_FreeList; FreeList<Entry> m_FreeList;
eastl::intrusive_hash_map<typename Entry::key_type, Entry, 31, typename Entry::Hash> m_InUse; eastl::intrusive_hash_map<typename Entry::key_type, Entry, 31, typename Entry::Hash> m_InUse;
std::array<IntrusiveStack<Entry>, 4> m_ToDelete; std::array<FreeList<Entry>, 4> m_ToDelete;
u8 m_ToDeleteIndex = 0; u8 m_ToDeleteIndex = 0;
explicit HandleMapper(const u32 maxCount) explicit HandleMapper(const u32 maxCount)
@ -189,13 +187,14 @@ class CommitManager
} }
void void
ClearEntries(IntrusiveStack<Entry>& entries) ClearEntries(FreeList<Entry>& entries)
{ {
while (auto item = entries.TryPop()) while (!entries.Empty())
{ {
Entry &entry = item.value(); Entry &entry = entries.Pop();
entry.mKey.reset(); entry.mKey.reset();
entry.m_CommitCount = 0; entry.m_CommitCount = 0;
} }
} }
}; };

View File

@ -7,6 +7,7 @@
#include "aster/aster.h" #include "aster/aster.h"
#include "aster/core/type_traits.h" #include "aster/core/type_traits.h"
#include "aster/util/freelist.h"
#include <EASTL/intrusive_ptr.h> #include <EASTL/intrusive_ptr.h>
#include <EASTL/vector.h> #include <EASTL/vector.h>
@ -32,10 +33,9 @@ class Manager
: m_Data{maxCount} : m_Data{maxCount}
, m_Device{device} , m_Device{device}
{ {
u32 i = 0;
for (auto &element : m_Data) for (auto &element : m_Data)
{ {
*Recast<u32 *>(&element) = ++i; m_FreeList.Push(element);
} }
} }
@ -49,7 +49,6 @@ class Manager
} }
} }
m_FreeHead = 0;
m_Device = nullptr; m_Device = nullptr;
} }
@ -60,11 +59,22 @@ class Manager
{ {
for (i64 i = m_Data.size() - 1; i >= 0; --i) 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); pIter->Destroy(m_Device);
*Recast<u32 *>(pIter) = m_FreeHead; m_FreeList.Push(*pIter);
m_FreeHead = i; }
}
}
void Sweep() requires concepts::SelfDestructible<Type>
{
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: private:
eastl::vector<Type> m_Data; // Data also keeps the freelist during 'not use'. eastl::vector<Type> m_Data; // Data also keeps the freelist during 'not use'.
u32 m_FreeHead = 0; FreeList<Type> m_FreeList;
protected: protected:
const Device *m_Device; const Device *m_Device;
@ -85,17 +95,15 @@ class Manager
[[nodiscard]] Handle [[nodiscard]] Handle
Alloc() 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_FreeList.Pop();
Type *pAlloc = &m_Data[index]; memset(&pAlloc, 0, sizeof pAlloc);
m_FreeHead = *Recast<u32 *>(pAlloc);
memset(pAlloc, 0, sizeof *pAlloc);
if constexpr (concepts::SelfDestructible<Type>) if constexpr (concepts::SelfDestructible<Type>)
{ {
pAlloc->m_Device = m_Device; pAlloc.m_Device = m_Device;
} }
return {pAlloc}; return {&pAlloc};
} }
}; };
} // namespace systems } // namespace systems

View File

@ -9,7 +9,7 @@
#include "buffer_manager.h" #include "buffer_manager.h"
#include "image_manager.h" #include "image_manager.h"
#include "image_view_manager.h" #include "view_manager.h"
#include "sampler_manager.h" #include "sampler_manager.h"
namespace systems namespace systems
@ -129,6 +129,14 @@ class ResourceManager
return m_CombinedImageViews; return m_CombinedImageViews;
} }
void Update()
{
m_Views.Sweep();
m_Images.Sweep();
m_Buffers.Sweep();
m_Samplers.Sweep();
}
~ResourceManager() = default; ~ResourceManager() = default;
PIN_MEMORY(ResourceManager); PIN_MEMORY(ResourceManager);

View File

@ -1,5 +1,5 @@
// ============================================= // =============================================
// Aster: image_manager.h // Aster: view_manager.h
// Copyright (c) 2020-2024 Anish Bhobe // Copyright (c) 2020-2024 Anish Bhobe
// ============================================= // =============================================

View File

@ -5,4 +5,4 @@ cmake_minimum_required(VERSION 3.13)
target_sources(aster_core target_sources(aster_core
INTERFACE INTERFACE
"logger.h" "logger.h"
"intrusive_slist.h") "freelist.h")

View File

@ -0,0 +1,96 @@
// =============================================
// Aster: freelist.h
// Copyright (c) 2020-2024 Anish Bhobe
// =============================================
#pragma once
#include <optional>
struct FreeListNode
{
FreeListNode *m_Next;
};
template <typename T>
concept FreeListCapable = sizeof(T) >= sizeof(FreeListNode);
template <FreeListCapable T>
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<Pointer>(m_Top);
m_Top = m_Top->m_Next;
return ref;
}
void
Push(Reference ref)
{
auto next = Recast<FreeListNode *>(&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;
}
};

View File

@ -1,127 +0,0 @@
// =============================================
// Aster: intrusive_slist.h
// Copyright (c) 2020-2024 Anish Bhobe
// =============================================
#pragma once
#include <optional>
template <typename T>
concept HasNext = requires(T &a) {
{ a.Next() } -> std::same_as<T *>;
{ a.SetNext(a) };
};
struct IntrusiveStackNode
{
IntrusiveStackNode *m_Next;
IntrusiveStackNode *
Next() const
{
return m_Next;
}
void
SetNext(IntrusiveStackNode &a)
{
m_Next = &a;
}
};
template <HasNext T = IntrusiveStackNode>
struct IntrusiveStack
{
using Value = T;
using Reference = T &;
using OptionalRef = std::optional<std::reference_wrapper<T>>;
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;
}
};

View File

@ -7,6 +7,6 @@ PRIVATE
"manager.cpp" "manager.cpp"
"buffer_manager.cpp" "buffer_manager.cpp"
"image_manager.cpp" "image_manager.cpp"
"image_view_manager.cpp" "view_manager.cpp"
"sampler_manager.cpp" "sampler_manager.cpp"
"commit_manager.cpp") "commit_manager.cpp")

View File

@ -55,10 +55,10 @@ CommitManager::CommitManager(const Device *device, u32 const maxBuffers, const u
.type = vk::DescriptorType::eCombinedImageSampler, .type = vk::DescriptorType::eCombinedImageSampler,
.descriptorCount = maxImages, .descriptorCount = maxImages,
}, },
// vk::DescriptorPoolSize{ vk::DescriptorPoolSize{
// .type = vk::DescriptorType::eStorageImage, .type = vk::DescriptorType::eStorageImage,
// .descriptorCount = storageTexturesCount, .descriptorCount = maxStorageImages,
// }, },
}; };
const vk::DescriptorPoolCreateInfo poolCreateInfo = { const vk::DescriptorPoolCreateInfo poolCreateInfo = {

View File

@ -1,5 +1,5 @@
// ============================================= // =============================================
// Aster: buffer_manager.cpp // Aster: image_manager.cpp
// Copyright (c) 2020-2025 Anish Bhobe // Copyright (c) 2020-2025 Anish Bhobe
// ============================================= // =============================================

View File

@ -1,9 +1,9 @@
// ============================================= // =============================================
// Aster: image_view_manager.cpp // Aster: view_manager.cpp
// Copyright (c) 2020-2025 Anish Bhobe // Copyright (c) 2020-2025 Anish Bhobe
// ============================================= // =============================================
#include "systems/image_view_manager.h" #include "systems/view_manager.h"
#include "core/device.h" #include "core/device.h"

View File

@ -23,7 +23,7 @@
#include "aster/systems/commit_manager.h" #include "aster/systems/commit_manager.h"
#include "frame.h" #include "frame.h"
#include "stb_image.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 "aster/systems/resource_manager.h"
#include <EASTL/array.h> #include <EASTL/array.h>
@ -427,6 +427,7 @@ main(int, char **)
{ {
Time::Update(); Time::Update();
commitManager.Update(); commitManager.Update();
resourceManager.Update();
camera.m_Model *= rotate(mat4{1.0f}, Cast<f32>(45.0_deg * Time::m_Delta), vec3(0.0f, 1.0f, 0.0f)); camera.m_Model *= rotate(mat4{1.0f}, Cast<f32>(45.0_deg * Time::m_Delta), vec3(0.0f, 1.0f, 0.0f));
ubo->Write(0, sizeof camera, &camera); ubo->Write(0, sizeof camera, &camera);

View File

@ -12,7 +12,7 @@
#include "nodes.h" #include "nodes.h"
#include "tiny_gltf.h" #include "tiny_gltf.h"
#include "aster/systems/image_manager.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" #include "aster/systems/resource.h"
namespace systems namespace systems

View File

@ -432,6 +432,8 @@ main(int, char **)
while (window.Poll()) while (window.Poll())
{ {
Time::Update(); Time::Update();
commitManager.Update();
resourceManager.Update();
gui::StartBuild(); gui::StartBuild();