Rename freelist and clean up code.
This commit is contained in:
parent
ec6aeb6f3b
commit
e5b002c8cc
|
|
@ -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"
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
// =============================================
|
// =============================================
|
||||||
// Aster: image_manager.h
|
// Aster: view_manager.h
|
||||||
// Copyright (c) 2020-2024 Anish Bhobe
|
// Copyright (c) 2020-2024 Anish Bhobe
|
||||||
// =============================================
|
// =============================================
|
||||||
|
|
||||||
|
|
@ -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")
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
@ -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;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
@ -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")
|
||||||
|
|
|
||||||
|
|
@ -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 = {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
// =============================================
|
// =============================================
|
||||||
// Aster: buffer_manager.cpp
|
// Aster: image_manager.cpp
|
||||||
// Copyright (c) 2020-2025 Anish Bhobe
|
// Copyright (c) 2020-2025 Anish Bhobe
|
||||||
// =============================================
|
// =============================================
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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"
|
||||||
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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();
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue