Fixing some VectorArena to use external arena and reduce the number of alloc.

Made the passing of name to arena more flexible
This commit is contained in:
2026-02-14 22:28:32 -05:00
parent 36ee786128
commit 38f8662d80
7 changed files with 41 additions and 27 deletions

View File

@@ -14,7 +14,7 @@ namespace Game
void InitEntityManager(Juliet::NonNullPtr<Juliet::Arena> arena) void InitEntityManager(Juliet::NonNullPtr<Juliet::Arena> arena)
{ {
Manager.Arena = arena.Get(); Manager.Arena = arena.Get();
Manager.Entities.Create(arena); Manager.Entities.Create(arena JULIET_DEBUG_PARAM("Entities"));
} }
void ShutdownEntityManager() void ShutdownEntityManager()

View File

@@ -9,24 +9,28 @@ namespace Juliet
template <typename Type, size_t ReserveSize = 16, bool AllowRealloc = false> template <typename Type, size_t ReserveSize = 16, bool AllowRealloc = false>
struct VectorArena struct VectorArena
{ {
void Create(JULIET_DEBUG_ONLY(const char* name = "VectorArena")) void Create(JULIET_DEBUG_PARAM_FIRST(const char* name = nullptr))
{ {
Assert(!Arena); Assert(!Arena);
static_assert(AllowRealloc == false); static_assert(AllowRealloc == false);
DataFirst = DataLast = nullptr; DataFirst = DataLast = nullptr;
Count = 0; Count = 0;
ArenaParams params{ .AllowRealloc = AllowRealloc JULIET_DEBUG_ONLY(, .CanReserveMore = false) };
Arena = ArenaAllocate(params JULIET_DEBUG_ONLY(, name)); JULIET_DEBUG_ONLY(Name = name ? name : Name);
ArenaParams params{ .AllowRealloc = AllowRealloc JULIET_DEBUG_PARAM(.CanReserveMore = false) };
Arena = ArenaAllocate(params JULIET_DEBUG_PARAM(Name));
InternalArena = true; InternalArena = true;
Reserve(ReserveSize); Reserve(ReserveSize);
} }
void Create(NonNullPtr<Arena> arena) void Create(NonNullPtr<Arena> arena JULIET_DEBUG_PARAM(const char* name = nullptr))
{ {
Assert(!Arena); Assert(!Arena);
JULIET_DEBUG_ONLY(Name = name ? name : Name);
DataFirst = DataLast = nullptr; DataFirst = DataLast = nullptr;
Count = 0; Count = 0;
Arena = arena.Get(); Arena = arena.Get();
@@ -53,7 +57,7 @@ namespace Juliet
{ {
if (Data == nullptr) if (Data == nullptr)
{ {
Data = ArenaPushArray<Type>(Arena, newCapacity); Data = ArenaPushArray<Type>(Arena, newCapacity JULIET_DEBUG_PARAM(Name));
} }
else if constexpr (AllowRealloc) else if constexpr (AllowRealloc)
{ {
@@ -61,7 +65,7 @@ namespace Juliet
{ {
DataFirst = Data = DataFirst = Data =
static_cast<Type*>(ArenaReallocate(Arena, Data, Capacity * sizeof(Type), newCapacity * sizeof(Type), static_cast<Type*>(ArenaReallocate(Arena, Data, Capacity * sizeof(Type), newCapacity * sizeof(Type),
AlignOf(Type), true JULIET_DEBUG_ONLY(, "VectorRealloc"))); AlignOf(Type), true JULIET_DEBUG_PARAM("VectorRealloc")));
DataLast = Data + Count - 1; DataLast = Data + Count - 1;
} }
} }
@@ -192,6 +196,7 @@ namespace Juliet
size_t Count; size_t Count;
size_t Capacity; size_t Capacity;
bool InternalArena : 1; bool InternalArena : 1;
JULIET_DEBUG_ONLY(const char* Name = "VectorArena");
}; };
static_assert(std::is_standard_layout_v<VectorArena<int>>, static_assert(std::is_standard_layout_v<VectorArena<int>>,
"VectorArena must have a standard layout to remain POD-like."); "VectorArena must have a standard layout to remain POD-like.");

View File

@@ -60,7 +60,6 @@ namespace Juliet
bool AllowRealloc = false; bool AllowRealloc = false;
// When false, will assert if a new block is reserved. // When false, will assert if a new block is reserved.
// Useful for Vectors as they are guaranteed to be linear and i wont need to implement memcopy to increase capacity
JULIET_DEBUG_ONLY(bool CanReserveMore : 1 = true;) JULIET_DEBUG_ONLY(bool CanReserveMore : 1 = true;)
}; };
@@ -72,12 +71,12 @@ namespace Juliet
// Raw Push, can be used but templated helpers exists below // Raw Push, can be used but templated helpers exists below
[[nodiscard]] JULIET_API void* ArenaPush(NonNullPtr<Arena> arena, size_t size, size_t align, [[nodiscard]] JULIET_API void* ArenaPush(NonNullPtr<Arena> arena, size_t size, size_t align,
bool shouldBeZeroed JULIET_DEBUG_ONLY(, const char* tag)); bool shouldBeZeroed JULIET_DEBUG_ONLY(, const char* tag));
[[nodiscard]] void* ArenaReallocate(NonNullPtr<Arena> arena, void* oldPtr, size_t oldSize, size_t newSize, [[nodiscard]] JULIET_API void* ArenaReallocate(NonNullPtr<Arena> arena, void* oldPtr, size_t oldSize, size_t newSize,
size_t align, bool shouldBeZeroed JULIET_DEBUG_ONLY(, const char* tag)); size_t align, bool shouldBeZeroed JULIET_DEBUG_ONLY(, const char* tag));
void ArenaPopTo(NonNullPtr<Arena> arena, size_t position); JULIET_API void ArenaPopTo(NonNullPtr<Arena> arena, size_t position);
void ArenaPop(NonNullPtr<Arena> arena, size_t amount); JULIET_API void ArenaPop(NonNullPtr<Arena> arena, size_t amount);
void ArenaClear(NonNullPtr<Arena> arena); JULIET_API void ArenaClear(NonNullPtr<Arena> arena);
[[nodiscard]] size_t ArenaPos(NonNullPtr<Arena> arena); [[nodiscard]] JULIET_API size_t ArenaPos(NonNullPtr<Arena> arena);
template <typename Type> template <typename Type>
[[nodiscard]] Type* ArenaPushStruct(NonNullPtr<Arena> arena) [[nodiscard]] Type* ArenaPushStruct(NonNullPtr<Arena> arena)
@@ -86,10 +85,11 @@ namespace Juliet
ArenaPush(arena, sizeof(Type) * 1, AlignOf(Type), true JULIET_DEBUG_ONLY(, typeid(Type).name()))); ArenaPush(arena, sizeof(Type) * 1, AlignOf(Type), true JULIET_DEBUG_ONLY(, typeid(Type).name())));
} }
// #define push_array_no_zero_aligned(a, T, c, align) (T *)arena_push((a), sizeof(T)*(c), (align), (0)) template <typename Type>
// #define push_array_aligned(a, T, c, align) (T *)arena_push((a), sizeof(T)*(c), (align), (1)) [[nodiscard]] Type* ArenaPushArray(NonNullPtr<Arena> arena, size_t count JULIET_DEBUG_ONLY(, const char* tag))
// #define push_array_no_zero(a, T, c) push_array_no_zero_aligned(a, T, c, Max(8, AlignOf(T))) {
// #define push_array(a, T, c) push_array_aligned(a, T, c, Max(8, AlignOf(T))) return static_cast<Type*>(ArenaPush(arena, sizeof(Type) * count, Max(8ull, AlignOf(Type)), true JULIET_DEBUG_ONLY(, tag)));
}
template <typename Type> template <typename Type>
[[nodiscard]] Type* ArenaPushArray(NonNullPtr<Arena> arena, size_t count) [[nodiscard]] Type* ArenaPushArray(NonNullPtr<Arena> arena, size_t count)

View File

@@ -22,9 +22,13 @@
#ifdef DEBUG #ifdef DEBUG
#define JULIET_DEBUG 1 #define JULIET_DEBUG 1
#define JULIET_DEBUG_ONLY(...) __VA_ARGS__ #define JULIET_DEBUG_ONLY(...) __VA_ARGS__
#define JULIET_DEBUG_PARAM_FIRST(...) __VA_ARGS__
#define JULIET_DEBUG_PARAM(...) , __VA_ARGS__
#else #else
#define JULIET_DEBUG 0 #define JULIET_DEBUG 0
#define JULIET_DEBUG_ONLY(...) #define JULIET_DEBUG_ONLY(...)
#define JULIET_DEBUG_PARAM_FIRST(...)
#define JULIET_DEBUG_PARAM(...)
#endif #endif
// Manual override to disable ImGui // Manual override to disable ImGui

View File

@@ -44,7 +44,7 @@ namespace Juliet::D3D12::Internal
heap->CurrentDescriptorIndex = 0; heap->CurrentDescriptorIndex = 0;
heap->FreeIndices.Create(JULIET_DEBUG_ONLY("DescriptorHeap FreeIndices")); heap->FreeIndices.Create(arena JULIET_DEBUG_PARAM("DescriptorHeap Free Indices"));
heap->FreeIndices.Resize(16); heap->FreeIndices.Resize(16);
heap->CurrentFreeIndex = 0; heap->CurrentFreeIndex = 0;

View File

@@ -198,8 +198,8 @@ void JulietApplication::Init()
if ((Running = GameCode.IsValid)) if ((Running = GameCode.IsValid))
{ {
GameInitParams params; GameInitParams params;
params.GameArena = ArenaAllocate({} JULIET_DEBUG_ONLY(, "Game Arena")); params.GameArena = GameArena = ArenaAllocate({} JULIET_DEBUG_ONLY(, "Game Arena"));
params.ScratchArena = ArenaAllocate({} JULIET_DEBUG_ONLY(, "Scratch Arena")); params.ScratchArena = GameScratchArena = ArenaAllocate({} JULIET_DEBUG_ONLY(, "Scratch Arena"));
Game.Init(&params); Game.Init(&params);
} }
} }
@@ -356,6 +356,8 @@ void JulietApplication::Update()
Debug::DebugDrawMemoryArena(); Debug::DebugDrawMemoryArena();
#endif #endif
} }
ArenaClear(GameScratchArena);
} }
void JulietApplication::OnPreRender(CommandList* cmd) void JulietApplication::OnPreRender(CommandList* cmd)

View File

@@ -45,6 +45,9 @@ class JulietApplication : public Juliet::IApplication
Juliet::GraphicsTransferBuffer* TransferBuffer = {}; Juliet::GraphicsTransferBuffer* TransferBuffer = {};
Juliet::Texture* DepthBuffer = {}; Juliet::Texture* DepthBuffer = {};
Juliet::Arena* GameArena = nullptr;
Juliet::Arena* GameScratchArena = nullptr;
bool Running = false; bool Running = false;
int AutoCloseFrameCount = -1; int AutoCloseFrameCount = -1;
}; };