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)
{
Manager.Arena = arena.Get();
Manager.Entities.Create(arena);
Manager.Entities.Create(arena JULIET_DEBUG_PARAM("Entities"));
}
void ShutdownEntityManager()

View File

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

View File

@@ -60,7 +60,6 @@ namespace Juliet
bool AllowRealloc = false;
// 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;)
};
@@ -72,12 +71,12 @@ namespace Juliet
// Raw Push, can be used but templated helpers exists below
[[nodiscard]] JULIET_API void* ArenaPush(NonNullPtr<Arena> arena, size_t size, size_t align,
bool shouldBeZeroed JULIET_DEBUG_ONLY(, const char* tag));
[[nodiscard]] void* ArenaReallocate(NonNullPtr<Arena> arena, void* oldPtr, size_t oldSize, size_t newSize,
size_t align, bool shouldBeZeroed JULIET_DEBUG_ONLY(, const char* tag));
void ArenaPopTo(NonNullPtr<Arena> arena, size_t position);
void ArenaPop(NonNullPtr<Arena> arena, size_t amount);
void ArenaClear(NonNullPtr<Arena> arena);
[[nodiscard]] size_t ArenaPos(NonNullPtr<Arena> arena);
[[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));
JULIET_API void ArenaPopTo(NonNullPtr<Arena> arena, size_t position);
JULIET_API void ArenaPop(NonNullPtr<Arena> arena, size_t amount);
JULIET_API void ArenaClear(NonNullPtr<Arena> arena);
[[nodiscard]] JULIET_API size_t ArenaPos(NonNullPtr<Arena> arena);
template <typename Type>
[[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())));
}
// #define push_array_no_zero_aligned(a, T, c, align) (T *)arena_push((a), sizeof(T)*(c), (align), (0))
// #define push_array_aligned(a, T, c, align) (T *)arena_push((a), sizeof(T)*(c), (align), (1))
// #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)))
template <typename Type>
[[nodiscard]] Type* ArenaPushArray(NonNullPtr<Arena> arena, size_t count JULIET_DEBUG_ONLY(, const char* tag))
{
return static_cast<Type*>(ArenaPush(arena, sizeof(Type) * count, Max(8ull, AlignOf(Type)), true JULIET_DEBUG_ONLY(, tag)));
}
template <typename Type>
[[nodiscard]] Type* ArenaPushArray(NonNullPtr<Arena> arena, size_t count)

View File

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

View File

@@ -44,7 +44,7 @@ namespace Juliet::D3D12::Internal
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->CurrentFreeIndex = 0;

View File

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

View File

@@ -26,11 +26,11 @@ class JulietApplication : public Juliet::IApplication
Juliet::GraphicsDevice* GetGraphicsDevice() override { return GraphicsDevice; }
// Render Lifecycle
void OnPreRender(Juliet::CommandList* cmd) override;
void OnRender(Juliet::RenderPass* pass, Juliet::CommandList* cmd) override;
Juliet::ColorTargetInfo GetColorTargetInfo(Juliet::Texture* swapchainTexture) override;
Juliet::DepthStencilTargetInfo* GetDepthTargetInfo() override;
Juliet::Camera GetDebugCamera() override;
void OnPreRender(Juliet::CommandList* cmd) override;
void OnRender(Juliet::RenderPass* pass, Juliet::CommandList* cmd) override;
Juliet::ColorTargetInfo GetColorTargetInfo(Juliet::Texture* swapchainTexture) override;
Juliet::DepthStencilTargetInfo* GetDepthTargetInfo() override;
Juliet::Camera GetDebugCamera() override;
public:
void SetAutoCloseFrameCount(int count) { AutoCloseFrameCount = count; }
@@ -45,7 +45,10 @@ class JulietApplication : public Juliet::IApplication
Juliet::GraphicsTransferBuffer* TransferBuffer = {};
Juliet::Texture* DepthBuffer = {};
bool Running = false;
Juliet::Arena* GameArena = nullptr;
Juliet::Arena* GameScratchArena = nullptr;
bool Running = false;
int AutoCloseFrameCount = -1;
};