Cleaned up memory arena debugger + tag.

WIP
This commit is contained in:
2026-01-21 20:36:38 -05:00
parent a41a5e6b20
commit c10d371836
21 changed files with 169 additions and 215 deletions

View File

@@ -18,8 +18,6 @@
constexpr Juliet::Class entityKind##entity(#entity, sizeof(#entity) / sizeof(char)); \
const Juliet::Class* entity::Kind = &entityKind##entity;
namespace Game
{
using DerivedType = void*;
@@ -50,8 +48,8 @@ namespace Game
EntityType* MakeEntity(EntityManager& manager, float x, float y)
{
auto* arena = Juliet::GetGameArena();
EntityType* result = Juliet::ArenaPushType<EntityType>(arena);
Entity* base = result->Base = Juliet::ArenaPushType<Entity>(arena);
EntityType* result = Juliet::ArenaPushType<EntityType>(arena, ConstString("EntityType"));
Entity* base = result->Base = Juliet::ArenaPushType<Entity>(arena, ConstString("Entity"));
base->X = x;
base->Y = y;
base->Derived = result;

View File

@@ -40,7 +40,7 @@ extern "C" JULIET_API void GameInit(GameInitParams* /*params*/)
int Score;
};
auto* gameState = ArenaPushType<GameState>(GetGameArena());
auto* gameState = ArenaPushType<GameState>(GetGameArena(), ConstString("GameState"));
gameState->TotalTime = 0.0f;
gameState->Score = 0;

View File

@@ -22,6 +22,6 @@ namespace Juliet
JULIET_API ImGuiContext* GetContext();
// Run internal unit tests
JULIET_API void RunTests(NonNullPtr<GraphicsDevice> device, NonNullPtr<Window> window);
}
}
JULIET_API void RunTests();
} // namespace ImGuiService
} // namespace Juliet

View File

@@ -8,5 +8,5 @@
namespace Juliet::UnitTest
{
void TestImGui(NonNullPtr<GraphicsDevice> device, NonNullPtr<Window> window);
void TestImGui();
}

View File

@@ -1,9 +1,10 @@
#pragma once
#include <Juliet.h>
#include <Core/Common/CoreTypes.h>
#include <Core/Common/CoreUtils.h>
#include <Core/Common/String.h>
#include <Core/Memory/Utils.h>
#include <Juliet.h>
namespace Juliet
{
@@ -12,12 +13,13 @@ namespace Juliet
uint8* Data;
size_t Size;
size_t Offset;
#if JULIET_DEBUG
struct AllocationInfo
{
size_t Offset;
size_t Size;
const char* Tag;
String Tag;
};
// Use a simple array for now to avoid std::vector dependency in the header or complex management
// Ideally this should be a linked list or similar
@@ -25,14 +27,11 @@ namespace Juliet
AllocationInfo Allocations[kMaxAllocations];
size_t AllocationCount = 0;
#endif
};
JULIET_API void MemoryArenaCreate(MemoryArena* arena, void* backingMemory, size_t size);
JULIET_API void* ArenaPush(MemoryArena* arena, size_t size, size_t alignment = 16, const char* tag = nullptr);
JULIET_API void* ArenaRealloc(MemoryArena* arena, void* oldPtr, size_t oldSize, size_t newSize, size_t alignment = 16, const char* tag = nullptr);
JULIET_API void* ArenaPush(MemoryArena* arena, size_t size, size_t alignment, String tag);
JULIET_API void* ArenaRealloc(MemoryArena* arena, void* oldPtr, size_t oldSize, size_t newSize, size_t alignment, String tag);
JULIET_API void ArenaReset(MemoryArena* arena);
JULIET_API size_t ArenaGetMarker(MemoryArena* arena);
JULIET_API void ArenaResetToMarker(MemoryArena* arena, size_t marker);
@@ -55,7 +54,7 @@ namespace Juliet
void MemoryArenasShutdown();
template <typename T>
inline T* ArenaPushType(MemoryArena* arena, const char* tag = nullptr)
inline T* ArenaPushType(MemoryArena* arena, String tag)
{
T* result = static_cast<T*>(ArenaPush(arena, sizeof(T), alignof(T), tag));
@@ -67,7 +66,7 @@ namespace Juliet
}
template <typename T>
inline T* ArenaPushArray(MemoryArena* arena, size_t count, const char* tag = nullptr)
inline T* ArenaPushArray(MemoryArena* arena, size_t count, String tag)
{
T* result = static_cast<T*>(ArenaPush(arena, sizeof(T) * count, alignof(T), tag));
@@ -79,8 +78,9 @@ namespace Juliet
}
template <typename T>
inline T* ArenaRealloc(MemoryArena* arena, T* oldPtr, size_t oldCount, size_t newCount)
inline T* ArenaRealloc(MemoryArena* arena, T* oldPtr, size_t oldCount, size_t newCount, String tag)
{
return static_cast<T*>(Juliet::ArenaRealloc(arena, static_cast<void*>(oldPtr), sizeof(T) * oldCount, sizeof(T) * newCount, alignof(T)));
return static_cast<T*>(Juliet::ArenaRealloc(arena, static_cast<void*>(oldPtr), sizeof(T) * oldCount,
sizeof(T) * newCount, alignof(T), tag));
}
} // namespace Juliet

View File

@@ -1,13 +1,9 @@
#pragma once
#include <Juliet.h>
#include <Core/Memory/MemoryArena.h>
namespace Juliet
#include <Core/Memory/MemoryArena.h>
#include <Juliet.h>
namespace Juliet::Debug
{
class JULIET_API MemoryDebugger
{
public:
static void DrawMemoryArena(const char* name, const MemoryArena& arena);
static void DrawGlobalArenas();
};
}
JULIET_API void DebugDrawMemoryArena();
} // namespace Juliet::Debug

View File

@@ -2,8 +2,8 @@
#include <Core/HAL/Display/Display_Private.h>
#include <Core/HAL/Display/DisplayDevice.h>
#include <Core/Memory/Allocator.h>
#include <Core/Memory/MemoryArena.h>
#include <Core/Memory/EngineArena.h>
#include <Core/Memory/MemoryArena.h>
#include <format>
namespace Juliet
@@ -17,7 +17,7 @@ namespace Juliet
{
// TODO : IfDef new factories that are not compatible
constexpr DisplayDeviceFactory* Factories[] = { &Win32DisplayDeviceFactory, nullptr };
} // namespace
} // namespace Internal::Display
void InitializeDisplaySystem()
{
@@ -75,7 +75,7 @@ namespace Juliet
Assert(g_CurrentDisplayDevice->CreatePlatformWindow);
MemoryArena* arena = GetEngineArena();
auto window = ArenaPushType<Window>(arena);
auto window = ArenaPushType<Window>(arena, ConstString("Window"));
if (!window)
{
return nullptr;
@@ -84,7 +84,7 @@ namespace Juliet
window->Height = height;
auto titleLen = StringLength(title);
auto buffer = ArenaPushArray<char>(arena, titleLen);
auto buffer = ArenaPushArray<char>(arena, titleLen, ConstString("Window Title Array"));
MemCopy(buffer, title, titleLen);
window->Title.Data = buffer;

View File

@@ -18,7 +18,7 @@ namespace Juliet::Win32
DisplayDevice* CreateDevice()
{
auto device = ArenaPushType<DisplayDevice>(GetEngineArena());
auto device = ArenaPushType<DisplayDevice>(GetEngineArena(), ConstString("DisplayDevice"));
if (!device)
{

View File

@@ -14,7 +14,7 @@ namespace Juliet::Win32
bool SetupWindowState(NonNullPtr<DisplayDevice> /*self*/, NonNullPtr<Window> window, HWND handle)
{
auto state = ArenaPushType<Window32State>(GetEngineArena());
auto state = ArenaPushType<Window32State>(GetEngineArena(), ConstString("Window32State"));
window->State = state;
state->Handle = handle;

View File

@@ -22,8 +22,9 @@ namespace Juliet
// First allocate all the full path.
// TODO: Add path composition into filesystem + string format + string builder
const size_t dllFullPathLength = basePathLength + StringLength(dllName) + 1; // Need +1 because snprintf needs 0 terminated strings
code.DLLFullPath.Data = ArenaPushArray<char>(GetEngineArena(), dllFullPathLength);
const size_t dllFullPathLength =
basePathLength + StringLength(dllName) + 1; // Need +1 because snprintf needs 0 terminated strings
code.DLLFullPath.Data = ArenaPushArray<char>(GetEngineArena(), dllFullPathLength, ConstString("DLLFullPath"));
int writtenSize = snprintf(CStr(code.DLLFullPath), dllFullPathLength, "%s%s", CStr(basePath), CStr(dllName));
if (writtenSize < static_cast<int>(dllFullPathLength) - 1)
{
@@ -34,8 +35,9 @@ namespace Juliet
code.DLLFullPath.Size = static_cast<size_t>(writtenSize);
// Lock filename path
const size_t lockPathLength = basePathLength + StringLength(lockFilename) + 1; // Need +1 because snprintf needs 0 terminated strings
code.LockFullPath.Data = ArenaPushArray<char>(GetEngineArena(), lockPathLength);
const size_t lockPathLength =
basePathLength + StringLength(lockFilename) + 1; // Need +1 because snprintf needs 0 terminated strings
code.LockFullPath.Data = ArenaPushArray<char>(GetEngineArena(), lockPathLength, ConstString("LockFullPath"));
writtenSize = snprintf(CStr(code.LockFullPath), lockPathLength, "%s%s", CStr(basePath), CStr(lockFilename));
if (writtenSize < static_cast<int>(lockPathLength) - 1)
{

View File

@@ -56,7 +56,7 @@ namespace Juliet
basePathLength + StringLength(code.TransientDLLName) + /* _ */ 1 + kTempDLLBufferSizeForID + 1 /* \0 */;
// Allocate from Scratch Arena (transient)
auto tempDllPath = ArenaPushArray<char>(GetScratchArena(), tempDllMaxBufferSize);
auto tempDllPath = ArenaPushArray<char>(GetScratchArena(), tempDllMaxBufferSize, ConstString("tempDllPath"));
for (uint32 attempt = 0; attempt < kMaxAttempts; ++attempt)
{
@@ -79,7 +79,8 @@ namespace Juliet
return;
}
if (static_cast<size_t>(writtenSize) + 1 < basePathLength + static_cast<size_t>(idLength) + code.TransientDLLName.Size)
if (static_cast<size_t>(writtenSize) + 1 <
basePathLength + static_cast<size_t>(idLength) + code.TransientDLLName.Size)
{
// Scratch memory, no free needed
Log(LogLevel::Error, LogCategory::Core, "Cannot create temp full path");

View File

@@ -1,16 +1,15 @@
#include <cstdio>
#include <Core/HAL/Display/Win32/Win32Window.h>
#include <Core/HAL/Display/Window.h>
#include <Core/ImGui/ImGuiService.h>
#include <Core/ImGui/ImGuiTests.h>
#include <Core/Logging/LogManager.h>
#include <Core/Memory/EngineArena.h>
#include <Core/Memory/MemoryArena.h>
#include <Graphics/D3D12/D3D12Includes.h>
#include <backends/imgui_impl_win32.h>
#include <imgui.h>
#include <backends/imgui_impl_dx12.h>
#include <backends/imgui_impl_win32.h>
#include <cstdio>
// Forward declare implementation functions from backends
extern IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
@@ -24,7 +23,7 @@ namespace Juliet::ImGuiService
void* ImGuiAllocWrapper(size_t size, void* /*user_data*/)
{
return ArenaPush(GetGameArena(), size, 16, "ImGui");
return ArenaPush(GetEngineArena(), size, 16, ConstString("ImGui"));
}
void ImGuiFreeWrapper(void* /*ptr*/, void* /*user_data*/)
@@ -35,10 +34,7 @@ namespace Juliet::ImGuiService
void Initialize(NonNullPtr<Window> window)
{
if (g_Initialized)
{
return;
}
Assert(!g_Initialized);
// Setup Allocator
ImGui::SetAllocatorFunctions(ImGuiAllocWrapper, ImGuiFreeWrapper, nullptr);
@@ -46,7 +42,6 @@ namespace Juliet::ImGuiService
IMGUI_CHECKVERSION();
g_ImGuiContext = ImGui::CreateContext();
ImGuiIO& io = ImGui::GetIO();
(void)io;
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
// io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls
@@ -56,17 +51,12 @@ namespace Juliet::ImGuiService
auto* win32State = static_cast<Win32::Window32State*>(window->State);
ImGui_ImplWin32_Init(win32State->Handle);
// Renderer Init is done later or here?
// We need the ID3D12Device, which is in GraphicsDevice.
// We should probably split Init.
// For now, let's assume we do Renderer Init in GraphicsDevice.
g_Initialized = true;
}
void Shutdown()
{
if (!g_Initialized) return;
Assert(g_Initialized);
ImGui_ImplWin32_Shutdown();
ImGui::DestroyContext(g_ImGuiContext);
@@ -76,7 +66,7 @@ namespace Juliet::ImGuiService
void NewFrame()
{
if (!g_Initialized) return;
Assert(g_Initialized);
ImGui_ImplWin32_NewFrame();
ImGui::NewFrame();
@@ -84,7 +74,7 @@ namespace Juliet::ImGuiService
void Render()
{
if (!g_Initialized) return;
Assert(g_Initialized);
ImGui::Render();
}
@@ -99,24 +89,9 @@ namespace Juliet::ImGuiService
return g_ImGuiContext;
}
void RunTests(NonNullPtr<GraphicsDevice> device, NonNullPtr<Window> window)
void RunTests()
{
printf("ImGuiService: Running Unit Tests...\n");
Juliet::UnitTest::TestImGui(device, window);
// Also run internal Dear ImGui validation
if (g_ImGuiContext)
{
// Verify version and data layout (Basic internal check)
bool result = ImGui::DebugCheckVersionAndDataLayout(IMGUI_VERSION, sizeof(ImGuiIO), sizeof(ImGuiStyle), sizeof(ImVec2), sizeof(ImVec4), sizeof(ImDrawVert), sizeof(ImDrawIdx));
if (result)
{
printf("ImGuiService: DebugCheckVersionAndDataLayout Passed.\n");
}
else
{
printf("ImGuiService: DebugCheckVersionAndDataLayout FAILED!\n");
}
}
Juliet::UnitTest::TestImGui();
}
} // namespace Juliet::ImGuiService

View File

@@ -1,29 +1,15 @@
#include <Core/HAL/Display/Display.h>
#include <Core/ImGui/ImGuiService.h>
#include <Core/Memory/MemoryArena.h>
#include <cstdio>
#include <Graphics/Graphics.h>
#include <imgui.h>
#include <Juliet.h>
#include <cstdio>
namespace Juliet::UnitTest
{
// Mocking window creation is hard because it needs real OS calls.
// We will assume the test runner has created a window or we create a headless one?
// Win32Window requires RegisterClass etc.
// Let's rely on the fact that if we run this test in "App" mode it works,
// but in CI headless it might fail if we don't handle it.
// For now, let's skip the Platform Init part if we can't create a window,
// or try to create a dummy window.
void TestImGui(NonNullPtr<GraphicsDevice> device, NonNullPtr<Window> window)
void TestImGui()
{
(void)device;
// 1. Verify Allocator Hook
// Initialize (Idempotent safe)
ImGuiService::Initialize(window);
ImGuiContext* ctx = ImGuiService::GetContext();
if (ImGui::GetCurrentContext() != ctx)
@@ -35,31 +21,28 @@ namespace Juliet::UnitTest
(void)ctx;
printf("TestImGui: Context Verified.\n");
// 3. Verify IO
ImGuiIO& io = ImGui::GetIO();
Assert(io.BackendPlatformName != nullptr);
printf("TestImGui: IO Verified. Backend: %s\n", io.BackendPlatformName);
// 4. Verify Version
Assert(ImGui::GetVersion() != nullptr);
printf("TestImGui: Version Verified: %s\n", ImGui::GetVersion());
// 5. Verify Fonts
Assert(io.Fonts != nullptr);
printf("TestImGui: Fonts Verified.\n");
bool built = io.Fonts->IsBuilt();
Assert(built);
printf("TestImGui: Fonts Built Status: %d\n", built);
// Assert(io.Fonts->IsBuilt() == false); // Disabled as Renderer might have built it
unsigned char* pixels;
int width, height;
io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height);
Assert(pixels != nullptr);
Assert(width > 0 && height > 0);
Assert(io.Fonts->IsBuilt() == true);
(void)pixels; (void)width; (void)height;
(void)pixels;
(void)width;
(void)height;
printf("TestImGui: Font Atlas Verified.\n");
// 6. Verify Style
@@ -72,7 +55,8 @@ namespace Juliet::UnitTest
Assert(ImGuiService::IsInitialized());
// Simulate a frame
if (io.DisplaySize.x <= 0.0f || io.DisplaySize.y <= 0.0f) {
if (io.DisplaySize.x <= 0.0f || io.DisplaySize.y <= 0.0f)
{
io.DisplaySize = ImVec2(1920, 1080);
}
io.DeltaTime = 1.0f / 60.0f;
@@ -85,5 +69,4 @@ namespace Juliet::UnitTest
printf("ImGui tests passed (Exhaustive).\n");
}
} // namespace Juliet::UnitTest

View File

@@ -23,9 +23,8 @@ namespace Juliet
#endif
}
void* ArenaPush(MemoryArena* arena, size_t size, size_t alignment, const char* tag)
void* ArenaPush(MemoryArena* arena, size_t size, size_t alignment, [[maybe_unused]] String tag)
{
(void)tag; // TODO: Use tag for allocation tracking in Debug builds
Assert(arena);
// Alignment must be power of 2
@@ -47,7 +46,8 @@ namespace Juliet
#if JULIET_DEBUG
if (arena->AllocationCount < MemoryArena::kMaxAllocations)
{
arena->Allocations[arena->AllocationCount] = { offset - reinterpret_cast<size_t>(arena->Data), size, tag ? tag : "Unknown" };
arena->Allocations[arena->AllocationCount] = { offset - reinterpret_cast<size_t>(arena->Data), size,
IsValid(tag) ? tag : WrapString("Unknown") };
arena->AllocationCount++;
}
#endif
@@ -55,8 +55,7 @@ namespace Juliet
return result;
}
void* ArenaRealloc(MemoryArena* arena, void* oldPtr, size_t oldSize, size_t newSize, size_t alignment, const char* tag)
void* ArenaRealloc(MemoryArena* arena, void* oldPtr, size_t oldSize, size_t newSize, size_t alignment, String tag)
{
Assert(arena);
// Alignment must be power of 2
@@ -119,7 +118,7 @@ namespace Juliet
if (newPtr)
{
size_t copySize = oldSize < newSize ? oldSize : newSize;
std::memcpy(newPtr, oldPtr, copySize);
MemCopy(newPtr, oldPtr, copySize);
}
return newPtr;
}
@@ -161,7 +160,6 @@ namespace Juliet
}
// --- Global Arenas & Management ---
namespace
{
MemoryArena g_ScratchArena;

View File

@@ -1,6 +1,6 @@
#include <cstdio>
#include <Core/Common/CoreUtils.h>
#include <Core/Memory/MemoryArena.h>
#include <cstdio>
#if JULIET_DEBUG
@@ -16,12 +16,12 @@ namespace Juliet::UnitTest
Assert(arena.Offset == 0);
Assert(arena.Size == 1024);
void* p1 = ArenaPush(&arena, 100);
void* p1 = ArenaPush(&arena, 100, 16, ConstString("Test"));
Assert(p1 != nullptr);
Assert(arena.Offset >= 100);
size_t marker = ArenaGetMarker(&arena);
void* p2 = ArenaPush(&arena, 200);
void* p2 = ArenaPush(&arena, 200, 16, ConstString("Test"));
Assert(p2 != nullptr);
Assert(arena.Offset >= marker + 200);
@@ -32,9 +32,9 @@ namespace Juliet::UnitTest
Assert(arena.Offset == 0);
// 2. Alignment Test
void* p3 = ArenaPush(&arena, 1, 1);
void* p3 = ArenaPush(&arena, 1, 1, ConstString("Test"));
[[maybe_unused]] size_t addr = reinterpret_cast<size_t>(p3);
void* p4 = ArenaPush(&arena, 1, 16);
void* p4 = ArenaPush(&arena, 1, 16, ConstString("Test"));
size_t addr2 = reinterpret_cast<size_t>(p4);
Assert((addr2 % 16) == 0);
@@ -44,18 +44,18 @@ namespace Juliet::UnitTest
int a;
float b;
};
TestData* data = ArenaPushType<TestData>(&arena);
TestData* data = ArenaPushType<TestData>(&arena, ConstString("Test"));
Assert(data != nullptr);
data->a = 10;
data->b = 20.0f;
TestData* dataArray = ArenaPushArray<TestData>(&arena, 10);
TestData* dataArray = ArenaPushArray<TestData>(&arena, 10, ConstString("Test"));
Assert(dataArray != nullptr);
// 4. Scratch Arena
MemoryArena* scratch = GetScratchArena();
Assert(scratch != nullptr);
void* sp = ArenaPush(scratch, 100);
void* sp = ArenaPush(scratch, 100, 16, ConstString("Test"));
Assert(sp != nullptr);
ScratchArenaReset();
Assert(scratch->Offset == 0);

View File

@@ -1,12 +1,16 @@
#include <Core/Common/String.h>
#include <Core/Memory/EngineArena.h>
#include <cstdio>
#include <Engine/Debug/MemoryDebugger.h>
#include <imgui.h>
#include <cstdio>
namespace Juliet
namespace Juliet::Debug
{
void MemoryDebugger::DrawMemoryArena(const char* name, const MemoryArena& arena)
namespace
{
if (ImGui::CollapsingHeader(name, ImGuiTreeNodeFlags_DefaultOpen))
void DrawMemoryArena(String name, const MemoryArena& arena)
{
if (ImGui::CollapsingHeader(CStr(name), ImGuiTreeNodeFlags_DefaultOpen))
{
float progress = 0.0f;
if (arena.Size > 0)
@@ -19,6 +23,7 @@ namespace Juliet
ImGui::ProgressBar(progress, ImVec2(0.0f, 0.0f), overlay);
#if JULIET_DEBUG
ImGui::PushID(CStr(name));
if (ImGui::TreeNode("Allocations"))
{
size_t displayedSize = 0;
@@ -35,7 +40,7 @@ namespace Juliet
const auto& alloc = arena.Allocations[i];
ImGui::TableNextRow();
ImGui::TableSetColumnIndex(0);
ImGui::Text("%s", alloc.Tag);
ImGui::Text("%s", CStr(alloc.Tag));
ImGui::TableSetColumnIndex(1);
ImGui::Text("%zu", alloc.Size);
ImGui::TableSetColumnIndex(2);
@@ -50,19 +55,22 @@ namespace Juliet
ImGui::TreePop();
}
ImGui::PopID();
#else
ImGui::Text("Detailed allocation tracking disabled in Release build.");
#endif
}
}
} // namespace
void MemoryDebugger::DrawGlobalArenas()
void DebugDrawMemoryArena()
{
if (ImGui::Begin("Memory Debugger"))
{
DrawMemoryArena("Scratch Arena", *GetScratchArena());
DrawMemoryArena("Game Arena", *GetGameArena());
DrawMemoryArena(ConstString("Game Arena"), *GetGameArena());
DrawMemoryArena(ConstString("Engine Arena"), *GetEngineArena());
DrawMemoryArena(ConstString("Scratch Arena"), *GetScratchArena());
}
ImGui::End();
}
}
} // namespace Juliet::Debug

View File

@@ -1,8 +1,8 @@
#include <Core/Logging/LogManager.h>
#include <Engine/Engine.h>
#include <Core/Common/CoreUtils.h>
#include <Core/JulietInit.h>
#include <Core/Logging/LogManager.h>
#include <Core/Memory/MemoryArena.h>
#include <Engine/Engine.h>
#include <Graphics/DebugDisplay.h>
#include <Graphics/Graphics.h>
#include <Graphics/RenderPass.h>
@@ -32,9 +32,7 @@ namespace Juliet
}
#ifdef JULIET_ENABLE_IMGUI
Window* window = EngineInstance.Application->GetPlatformWindow();
if (window)
if (NonNullPtr window = EngineInstance.Application->GetPlatformWindow())
{
ImGuiService::Initialize(window);
ImGui::SetCurrentContext(ImGuiService::GetContext());
@@ -44,7 +42,7 @@ namespace Juliet
ImGuiRenderer_Initialize(device);
// Run Unit Tests automatically
ImGuiService::RunTests(device, window);
ImGuiService::RunTests();
}
}
#endif

View File

@@ -10,7 +10,7 @@ namespace Juliet::D3D12::Internal
{
ID3D12DescriptorHeap* handle;
auto heap = static_cast<D3D12DescriptorHeap*>(Calloc(1, sizeof(D3D12DescriptorHeap)));
auto heap = ArenaPushType<D3D12DescriptorHeap>(GetEngineArena(), ConstString("D3D12DescriptorHeap"));
if (!heap)
{
return nullptr;
@@ -19,7 +19,8 @@ namespace Juliet::D3D12::Internal
heap->CurrentDescriptorIndex = 0;
heap->FreeIndicesCapacity = 16;
heap->FreeIndicesCount = 0;
heap->FreeIndices = static_cast<uint32*>(Calloc(heap->FreeIndicesCapacity, sizeof(uint32)));
heap->FreeIndices = ArenaPushArray<uint32>(GetEngineArena(), heap->FreeIndicesCapacity,
ConstString("D3D12DescriptorHeap/FreeIndices"));
D3D12_DESCRIPTOR_HEAP_DESC heapDesc;
heapDesc.NumDescriptors = count;
@@ -27,8 +28,7 @@ namespace Juliet::D3D12::Internal
heapDesc.Flags = isStaging ? D3D12_DESCRIPTOR_HEAP_FLAG_NONE : D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE;
heapDesc.NodeMask = 0;
HRESULT result =
driver->D3D12Device->CreateDescriptorHeap(&heapDesc, IID_ID3D12DescriptorHeap, (void**)&handle);
HRESULT result = driver->D3D12Device->CreateDescriptorHeap(&heapDesc, IID_ID3D12DescriptorHeap, (void**)&handle);
if (FAILED(result))
{
LogError(driver->D3D12Device, "Failed to create descriptor heap!", result);
@@ -143,8 +143,8 @@ namespace Juliet::D3D12::Internal
size_t oldCapacity = pool->Capacity;
pool->Capacity = pool->Capacity == 0 ? 1 : pool->Capacity * 2;
// Using ArenaRealloc (Template):
pool->Heaps = ArenaRealloc<D3D12DescriptorHeap*>(GetEngineArena(), pool->Heaps, oldCapacity, pool->Capacity);
pool->Heaps = ArenaRealloc<D3D12DescriptorHeap*>(GetEngineArena(), pool->Heaps, oldCapacity, pool->Capacity,
ConstString("DescriptorHeapArray"));
// Initialize new slots to nullptr
for (size_t i = oldCapacity; i < pool->Capacity; ++i)

View File

@@ -1035,7 +1035,8 @@ namespace Juliet::D3D12
{
heapPool.Capacity = 4;
heapPool.Count = 4;
heapPool.Heaps = ArenaPushArray<Internal::D3D12DescriptorHeap*>(GetEngineArena(), heapPool.Capacity);
heapPool.Heaps = ArenaPushArray<Internal::D3D12DescriptorHeap*>(GetEngineArena(), heapPool.Capacity,
ConstString("DescriptorHeap"));
for (uint32 i = 0; i < heapPool.Capacity; ++i)
{

View File

@@ -5,10 +5,10 @@
#include <Core/Logging/LogManager.h>
#include <Core/Logging/LogTypes.h>
#include <Core/Memory/Allocator.h>
#include <Core/Memory/MemoryArena.h>
#include <Graphics/GraphicsPipeline.h>
#include <backends/imgui_impl_win32.h>
#include <imgui.h>
namespace Juliet

View File

@@ -267,10 +267,6 @@ void JulietApplication::Update()
}
}
if (evt.Type == EventType::Key_Down)
{
}
// Shader hot reload using keyboard.
if (!reloadShadersDebounce && ((GetKeyModState() & KeyMod::Alt) != KeyMod::None) && IsKeyDown(ScanCode::R))
{
@@ -355,6 +351,11 @@ void JulietApplication::Update()
Running = false;
}
}
if (ShowMemoryDebugger)
{
Debug::DebugDrawMemoryArena();
}
}
void JulietApplication::OnPreRender(CommandList* cmd)
@@ -383,8 +384,6 @@ void JulietApplication::OnPreRender(CommandList* cmd)
CopyBuffer(cmd, ConstantBuffer, TransferBuffer, 256);
TransitionBufferToReadable(cmd, ConstantBuffer);
}
}
void JulietApplication::OnRender(RenderPass* pass, CommandList* cmd)
@@ -403,11 +402,6 @@ void JulietApplication::OnRender(RenderPass* pass, CommandList* cmd)
SetPushConstants(cmd, ShaderStage::Vertex, 0, sizeof(pushData) / 4, &pushData);
DrawPrimitives(pass, 6, 1, 0, 0);
if (ShowMemoryDebugger)
{
MemoryDebugger::DrawGlobalArenas();
}
}
ColorTargetInfo JulietApplication::GetColorTargetInfo(Texture* swapchainTexture)