From 0876ed820515ec360ba07668b9bc7938224d87c3 Mon Sep 17 00:00:00 2001 From: Patedam Date: Sun, 8 Feb 2026 15:01:09 -0500 Subject: [PATCH 1/7] Port all window management to the new memory arena --- Juliet/include/Core/Common/CoreUtils.h | 9 +- Juliet/include/Core/Container/Vector.h | 113 ++++++++++-------- .../include/Core/Networking/NetworkPacket.h | 6 + Juliet/src/Core/HAL/Display/Display.cpp | 73 ++++++----- Juliet/src/Core/HAL/Display/DisplayDevice.h | 4 +- .../HAL/Display/Win32/Win32DisplayDevice.cpp | 9 +- .../HAL/Display/Win32/Win32DisplayEvent.cpp | 17 +-- .../Core/HAL/Display/Win32/Win32Window.cpp | 13 +- Juliet/src/Core/HAL/Display/Window.h | 5 +- .../src/UnitTest/Container/VectorUnitTest.cpp | 34 +++++- 10 files changed, 164 insertions(+), 119 deletions(-) diff --git a/Juliet/include/Core/Common/CoreUtils.h b/Juliet/include/Core/Common/CoreUtils.h index 4da2dba..4aa84e2 100644 --- a/Juliet/include/Core/Common/CoreUtils.h +++ b/Juliet/include/Core/Common/CoreUtils.h @@ -162,11 +162,12 @@ namespace Juliet return (x + alignment - 1) & ~(alignment - 1); } - inline void Swap(auto* Restrict a, auto* Restrict b) + template + inline void Swap(T* Restrict a, T* Restrict b) { - auto temp = *a; - *a = *b; - *b = temp; + T temp = std::move(*a); + *a = std::move(*b); + *b = std::move(temp); } // Move to another file dedicated to those diff --git a/Juliet/include/Core/Container/Vector.h b/Juliet/include/Core/Container/Vector.h index d065ad6..82b89fb 100644 --- a/Juliet/include/Core/Container/Vector.h +++ b/Juliet/include/Core/Container/Vector.h @@ -3,75 +3,80 @@ #include #include #include -#include namespace Juliet { template struct VectorArena { - public: - VectorArena() - : First(nullptr) - , Last(nullptr) - , Count(0) - , Stride(sizeof(Type)) + void Create() { - Arena = ArenaAllocate(); + Assert(!Arena); + + DataFirst = DataLast = nullptr; + Count = 0; + Stride = sizeof(Type); + Arena = ArenaAllocate(); + } + void Destroy() + { + ArenaRelease(Arena); + DataFirst = DataLast = nullptr; + Count = 0; + Stride = 0; + Arena = nullptr; } - ~VectorArena() { ArenaRelease(Arena); } + void PushBack(const Type& value) + { + Assert(Arena); - VectorArena(const VectorArena&) - : Arena(nullptr) - , First(nullptr) - , Last(nullptr) - , Count(0) - , Stride(sizeof(Type)) - { - Assert(false, "Copying VectorArena is not allowed"); + Type* entry = ArenaPushStruct(Arena); + *entry = value; + + if (Count == 0) + { + DataFirst = entry; + } + DataLast = entry; + ++Count; } - VectorArena(VectorArena&&) noexcept - : Arena(nullptr) - , First(nullptr) - , Last(nullptr) - , Count(0) - , Stride(sizeof(Type)) - { - Assert(false, "Moving VectorArena is not allowed"); - } - void operator=(const VectorArena&) { Assert(false, "Copying VectorArena is not allowed"); } - void operator=(VectorArena&&) noexcept { Assert(false, "Moving VectorArena is not allowed"); } void PushBack(Type&& value) { + Assert(Arena); + Type* entry = ArenaPushStruct(Arena); *entry = std::move(value); if (Count == 0) { - First = entry; + DataFirst = entry; } - Last = entry; - + DataLast = entry; ++Count; } void RemoveAtFast(index_t index) { + Assert(Arena); Assert(index < Count); Assert(Count > 0); - Type* elementAdr = First + index; + Type* elementAdr = DataFirst + index; - // Swap Last and element - Swap(Last, elementAdr); - --Last; + // Swap DataLast and element + if (DataLast != elementAdr) + { + Swap(DataLast, elementAdr); + } + + --DataLast; --Count; if (Count == 0) { - First = Last = nullptr; + DataFirst = DataLast = nullptr; } ArenaPop(Arena, Stride); @@ -79,34 +84,36 @@ namespace Juliet void Clear() { + Assert(Arena); + ArenaClear(Arena); - First = Last = nullptr; - Count = 0; + DataFirst = DataLast = nullptr; + Count = 0; } // C++ Accessors for loop supports and Index based access - Type& operator[](size_t index) { return First[index]; } - const Type& operator[](size_t index) const { return First[index]; } + Type& operator[](size_t index) { return DataFirst[index]; } + const Type& operator[](size_t index) const { return DataFirst[index]; } - Type* begin() { return First; } - Type* end() { return First + Count; } + Type* begin() { return DataFirst; } + Type* end() { return DataFirst + Count; } - const Type* begin() const { return First; } - const Type* end() const { return First + Count; } + const Type* begin() const { return DataFirst; } + const Type* end() const { return DataFirst + Count; } + + Type* First() { return DataFirst; } + Type* Last() { return DataLast; } size_t Size() const { return Count; } - private: Arena* Arena; - Type* First; - Type* Last; + Type* DataFirst; + Type* DataLast; size_t Count; size_t Stride; }; - - // TODO : Create my own Vector class based on https://github.com/niklas-ourmachinery/bitsquid-foundation/blob/master/collection_types.h - template - class Vector : public std::vector - { - }; + static_assert(std::is_standard_layout_v>, + "VectorArena must have a standard layout to remain POD-like."); + static_assert(std::is_trivially_copyable_v>, + "VectorArena must be trivially copyable (no custom destructors/assignment)."); } // namespace Juliet diff --git a/Juliet/include/Core/Networking/NetworkPacket.h b/Juliet/include/Core/Networking/NetworkPacket.h index e3d91f9..8d9f292 100644 --- a/Juliet/include/Core/Networking/NetworkPacket.h +++ b/Juliet/include/Core/Networking/NetworkPacket.h @@ -5,6 +5,12 @@ namespace Juliet { + // TODO Use VectorArena + template + class Vector : public std::vector + { + }; + class NetworkPacket { public: diff --git a/Juliet/src/Core/HAL/Display/Display.cpp b/Juliet/src/Core/HAL/Display/Display.cpp index 3e661db..1d8745e 100644 --- a/Juliet/src/Core/HAL/Display/Display.cpp +++ b/Juliet/src/Core/HAL/Display/Display.cpp @@ -10,7 +10,9 @@ namespace Juliet namespace { DisplayDevice* g_CurrentDisplayDevice = nullptr; - } + + void DestroyPlatformWindow(index_t windowIndex); + } // namespace namespace Internal::Display { @@ -60,9 +62,9 @@ namespace Juliet } // Destroy all Windows that are still alive - if (g_CurrentDisplayDevice->MainWindow) + for (index_t idx = g_CurrentDisplayDevice->Windows.Size(); idx-- > 0;) { - DestroyPlatformWindow(g_CurrentDisplayDevice->MainWindow); + DestroyPlatformWindow(idx); } g_CurrentDisplayDevice->Shutdown(g_CurrentDisplayDevice); @@ -78,44 +80,59 @@ namespace Juliet { Assert(g_CurrentDisplayDevice->CreatePlatformWindow); - auto* arena = g_CurrentDisplayDevice->Arena; - Assert(arena); + Window window = {}; + window.Arena = ArenaAllocate(); + window.Width = width; + window.Height = height; - auto* window = ArenaPushStruct(arena); - Assert(window); + window.Title = StringCopy(window.Arena, WrapString(title)); - window->Width = width; - window->Height = height; + g_CurrentDisplayDevice->Windows.PushBack(window); - window->Title = StringCopy(arena, WrapString(title)); - - g_CurrentDisplayDevice->MainWindow = window; - if (!g_CurrentDisplayDevice->CreatePlatformWindow(g_CurrentDisplayDevice, window)) + auto* pWindow = g_CurrentDisplayDevice->Windows.Last(); + if (!g_CurrentDisplayDevice->CreatePlatformWindow(g_CurrentDisplayDevice, pWindow)) { - // Note: We don't "free" from arena easily, but since this is catastrophic - // and persistent, we just leak the small amount of arena space or handle it if we had a marker. + ArenaRelease(window.Arena); return nullptr; } // TODO : make SHOW optional on creation with a flag - g_CurrentDisplayDevice->ShowWindow(g_CurrentDisplayDevice, window); + g_CurrentDisplayDevice->ShowWindow(g_CurrentDisplayDevice, pWindow); - return window; + return pWindow; } + namespace + { + void DestroyPlatformWindow(index_t windowIndex) + { + VectorArena& windows = g_CurrentDisplayDevice->Windows; + Window* window = &windows[windowIndex]; + + HideWindow(window); + + g_CurrentDisplayDevice->DestroyPlatformWindow(g_CurrentDisplayDevice, window); + + ArenaClear(window->Arena); + ArenaRelease(window->Arena); + + windows.RemoveAtFast(windowIndex); + } + } // namespace + void DestroyPlatformWindow(NonNullPtr window) { - Assert(g_CurrentDisplayDevice->MainWindow == window.Get()); - - HideWindow(window); - - // TODO: Pop from arena. - window->Title.Data = nullptr; - window->Title.Size = 0; - - g_CurrentDisplayDevice->DestroyPlatformWindow(g_CurrentDisplayDevice, window); - - g_CurrentDisplayDevice->MainWindow = nullptr; + // Find and destroy + VectorArena& windows = g_CurrentDisplayDevice->Windows; + for (index_t idx = windows.Size() - 1; idx != 0; --idx) + { + Window& windowRef = windows[idx]; + if (windowRef.ID == window->ID) + { + DestroyPlatformWindow(idx); + break; + } + } } void ShowWindow(NonNullPtr window) diff --git a/Juliet/src/Core/HAL/Display/DisplayDevice.h b/Juliet/src/Core/HAL/Display/DisplayDevice.h index 29323bd..7d9cd63 100644 --- a/Juliet/src/Core/HAL/Display/DisplayDevice.h +++ b/Juliet/src/Core/HAL/Display/DisplayDevice.h @@ -29,9 +29,7 @@ namespace Juliet // Events void (*PumpEvents)(NonNullPtr self); - // TODO : Use vector - VectorArena Windows; - Window* MainWindow = nullptr; + VectorArena Windows; }; struct DisplayDeviceFactory diff --git a/Juliet/src/Core/HAL/Display/Win32/Win32DisplayDevice.cpp b/Juliet/src/Core/HAL/Display/Win32/Win32DisplayDevice.cpp index 295287f..f700464 100644 --- a/Juliet/src/Core/HAL/Display/Win32/Win32DisplayDevice.cpp +++ b/Juliet/src/Core/HAL/Display/Win32/Win32DisplayDevice.cpp @@ -1,9 +1,7 @@ #include #include #include -#include #include -#include namespace Juliet::Win32 { @@ -14,7 +12,10 @@ namespace Juliet::Win32 return true; } void Shutdown(NonNullPtr /*self*/) {} - void Free(NonNullPtr /*self*/) {} + void Free(NonNullPtr device) + { + device->Windows.Destroy(); + } DisplayDevice* CreateDevice(Arena* arena) { @@ -36,6 +37,8 @@ namespace Juliet::Win32 device->PumpEvents = PumpEvents; + device->Windows.Create(); + return device; } } // namespace diff --git a/Juliet/src/Core/HAL/Display/Win32/Win32DisplayEvent.cpp b/Juliet/src/Core/HAL/Display/Win32/Win32DisplayEvent.cpp index 5b3be09..34fe64d 100644 --- a/Juliet/src/Core/HAL/Display/Win32/Win32DisplayEvent.cpp +++ b/Juliet/src/Core/HAL/Display/Win32/Win32DisplayEvent.cpp @@ -14,10 +14,9 @@ // For GET_X_LPARAM, GET_Y_LPARAM. #include -#include // Need For IMGUI_IMPL_API +#include // Need For IMGUI_IMPL_API extern IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); - namespace Juliet::Win32 { namespace @@ -29,17 +28,12 @@ namespace Juliet::Win32 { if (auto* displayDevice = GetDisplayDevice()) { - auto* window = displayDevice->MainWindow; - // TODO : use a vector - // for (Window* window : displayDevice->MainWindow) + for (auto& window : displayDevice->Windows) { - if (window) + auto state = static_cast(window.State); + if (state && state->Handle == handle) { - auto state = static_cast(window->State); - if (state && state->Handle == handle) - { - return state; - } + return state; } } } @@ -158,7 +152,6 @@ namespace Juliet::Win32 LRESULT returnCode = -1; - // Wait until the window state is created before doing anything auto* windowState = GetWindowStateFromHandle(handle); if (!windowState) diff --git a/Juliet/src/Core/HAL/Display/Win32/Win32Window.cpp b/Juliet/src/Core/HAL/Display/Win32/Win32Window.cpp index 2669002..aa3f7db 100644 --- a/Juliet/src/Core/HAL/Display/Win32/Win32Window.cpp +++ b/Juliet/src/Core/HAL/Display/Win32/Win32Window.cpp @@ -14,7 +14,7 @@ namespace Juliet::Win32 bool SetupWindowState(NonNullPtr /*self*/, NonNullPtr window, HWND handle) { - auto state = ArenaPushType(GetEngineArena(), ConstString("Window32State")); + auto* state = ArenaPushStruct(window->Arena); window->State = state; state->Handle = handle; @@ -23,18 +23,15 @@ namespace Juliet::Win32 state->IsMouseTracked = false; - // TODO Use SetProp to associate data to the window handle. Could be used to fetch it from the WinProc - return true; } void CleanUpWindowState(NonNullPtr /*self*/, NonNullPtr window) { - if (auto* state = static_cast(window->State)) - { - ReleaseDC(state->Handle, state->HDC); - DestroyWindow(state->Handle); - } + auto* state = static_cast(window->State); + Assert(state); + ReleaseDC(state->Handle, state->HDC); + DestroyWindow(state->Handle); window->State = nullptr; } } // namespace diff --git a/Juliet/src/Core/HAL/Display/Window.h b/Juliet/src/Core/HAL/Display/Window.h index bd844d6..32faa1e 100644 --- a/Juliet/src/Core/HAL/Display/Window.h +++ b/Juliet/src/Core/HAL/Display/Window.h @@ -15,9 +15,10 @@ namespace Juliet { WindowID ID; WindowState* State; + Arena* Arena; - int32 Width; - int32 Height; + int32 Width; + int32 Height; String Title; }; } // namespace Juliet diff --git a/Juliet/src/UnitTest/Container/VectorUnitTest.cpp b/Juliet/src/UnitTest/Container/VectorUnitTest.cpp index 3bc44aa..4cabdaf 100644 --- a/Juliet/src/UnitTest/Container/VectorUnitTest.cpp +++ b/Juliet/src/UnitTest/Container/VectorUnitTest.cpp @@ -31,7 +31,8 @@ namespace Juliet { // Test 1: Integer VectorArena { - VectorArena vec; + VectorArena vec = {}; + vec.Create(); VerifyVectorState(vec, 0); vec.PushBack(10); @@ -58,11 +59,14 @@ namespace Juliet sum += val; } Assert(sum == 60); + vec.Destroy(); } // Test 2: RemoveAtFast { - VectorArena vec; + VectorArena vec = {}; + vec.Create(); + vec.PushBack(10); vec.PushBack(20); vec.PushBack(30); @@ -84,11 +88,15 @@ namespace Juliet // Remove remaining element vec.RemoveAtFast(0); VerifyVectorState(vec, 0); + + vec.Destroy(); } // Test 3: Clear and Reuse { - VectorArena vec; + VectorArena vec = {}; + vec.Create(); + vec.PushBack(100); vec.PushBack(200); VerifyVectorState(vec, 2); @@ -100,6 +108,8 @@ namespace Juliet VerifyVectorState(vec, 1); Assert(vec[0] == 300); Assert(*(vec.end() - 1) == 300); + + vec.Destroy(); } // Test 4: Struct VectorArena @@ -116,7 +126,9 @@ namespace Juliet } }; - VectorArena vec; + VectorArena vec = {}; + vec.Create(); + VerifyVectorState(vec, 0); vec.PushBack({ 1, 1.0f }); @@ -129,11 +141,15 @@ namespace Juliet VerifyVectorState(vec, 2); Assert(vec[0] == (TestItem{ 1, 1.0f })); Assert(vec[1] == (TestItem{ 3, 3.0f })); + + vec.Destroy(); } // Test 5: Add 2, Remove 2 -> Expect nullptr { - VectorArena vec; + VectorArena vec = {}; + vec.Create(); + vec.PushBack(1); vec.PushBack(2); VerifyVectorState(vec, 2); @@ -141,11 +157,15 @@ namespace Juliet vec.RemoveAtFast(0); vec.RemoveAtFast(0); VerifyVectorState(vec, 0); + + vec.Destroy(); } // Test 6: Volume Test (100 items) { - VectorArena vec; + VectorArena vec = {}; + vec.Create(); + VerifyVectorState(vec, 0); // Push 100 items @@ -170,6 +190,8 @@ namespace Juliet vec.Clear(); VerifyVectorState(vec, 0); + + vec.Destroy(); } } } // namespace Juliet -- 2.49.1 From 679edf48ed3f7e06cb5535549d281564ad699712 Mon Sep 17 00:00:00 2001 From: Patedam Date: Sun, 8 Feb 2026 22:21:31 -0500 Subject: [PATCH 2/7] Converted everything that was using the old "EngineArena" to our new Arena type --- Juliet/Juliet.vcxproj | 1 - Juliet/Juliet.vcxproj.filters | 3 - Juliet/include/Core/Container/Vector.h | 10 +- Juliet/include/Core/HotReload/HotReload.h | 5 +- Juliet/include/Core/Memory/MemoryArena.h | 6 + Juliet/include/Juliet.h | 2 + Juliet/src/Core/HAL/Display/Display.cpp | 1 - .../HAL/Display/Win32/Win32DisplayDevice.cpp | 1 - .../Core/HAL/Display/Win32/Win32Window.cpp | 3 +- Juliet/src/Core/HotReload/HotReload.cpp | 11 +- Juliet/src/Core/ImGui/ImGuiService.cpp | 29 +---- Juliet/src/Core/Memory/EngineArena.h | 10 -- Juliet/src/Core/Memory/MemoryArena.cpp | 15 +-- Juliet/src/Engine/Debug/MemoryDebugger.cpp | 2 - .../src/Graphics/D3D12/D3D12CommandList.cpp | 7 +- Juliet/src/Graphics/D3D12/D3D12Common.cpp | 16 ++- Juliet/src/Graphics/D3D12/D3D12Common.h | 9 +- .../Graphics/D3D12/D3D12DescriptorHeap.cpp | 115 ++++++++++-------- .../src/Graphics/D3D12/D3D12DescriptorHeap.h | 31 +++-- .../Graphics/D3D12/D3D12GraphicsDevice.cpp | 55 ++------- Juliet/src/Graphics/GraphicsDevice.h | 13 +- 21 files changed, 156 insertions(+), 189 deletions(-) delete mode 100644 Juliet/src/Core/Memory/EngineArena.h diff --git a/Juliet/Juliet.vcxproj b/Juliet/Juliet.vcxproj index de66553..2e691f3 100644 --- a/Juliet/Juliet.vcxproj +++ b/Juliet/Juliet.vcxproj @@ -156,7 +156,6 @@ - diff --git a/Juliet/Juliet.vcxproj.filters b/Juliet/Juliet.vcxproj.filters index 9f1d957..2394074 100644 --- a/Juliet/Juliet.vcxproj.filters +++ b/Juliet/Juliet.vcxproj.filters @@ -315,9 +315,6 @@ src\Core\Memory - - src\Core\Memory - src\Core\Memory diff --git a/Juliet/include/Core/Container/Vector.h b/Juliet/include/Core/Container/Vector.h index 82b89fb..a8bee89 100644 --- a/Juliet/include/Core/Container/Vector.h +++ b/Juliet/include/Core/Container/Vector.h @@ -16,7 +16,7 @@ namespace Juliet DataFirst = DataLast = nullptr; Count = 0; Stride = sizeof(Type); - Arena = ArenaAllocate(); + Arena = ArenaAllocate(JULIET_DEBUG_ONLY({ .CanReserveMore = false })); } void Destroy() { @@ -27,6 +27,14 @@ namespace Juliet Arena = nullptr; } + void Resize(size_t newCount) + { + Type* entry = ArenaPushArray(Arena, newCount); + Count = newCount; + DataFirst = entry; + DataLast = entry + newCount; + } + void PushBack(const Type& value) { Assert(Arena); diff --git a/Juliet/include/Core/HotReload/HotReload.h b/Juliet/include/Core/HotReload/HotReload.h index da236a8..25dff9a 100644 --- a/Juliet/include/Core/HotReload/HotReload.h +++ b/Juliet/include/Core/HotReload/HotReload.h @@ -9,6 +9,8 @@ namespace Juliet struct HotReloadCode { + Arena* Arena; + String DLLFullPath; String LockFullPath; String TransientDLLName; @@ -26,8 +28,7 @@ namespace Juliet bool IsValid : 1; }; - extern JULIET_API void InitHotReloadCode(HotReloadCode& code, String dllName, - String transientDllName, String lockFilename); + extern JULIET_API void InitHotReloadCode(HotReloadCode& code, String dllName, String transientDllName, String lockFilename); extern JULIET_API void ShutdownHotReloadCode(HotReloadCode& code); extern JULIET_API void LoadCode(HotReloadCode& code); diff --git a/Juliet/include/Core/Memory/MemoryArena.h b/Juliet/include/Core/Memory/MemoryArena.h index 7f29ed1..2c6d190 100644 --- a/Juliet/include/Core/Memory/MemoryArena.h +++ b/Juliet/include/Core/Memory/MemoryArena.h @@ -30,6 +30,8 @@ namespace Juliet uint64 Reserved; Arena* FreeLast; + + JULIET_DEBUG_ONLY(bool CanReserveMore : 1;) }; static_assert(sizeof(Arena) <= k_ArenaHeaderSize); @@ -37,6 +39,10 @@ namespace Juliet { uint64 ReserveSize = g_Arena_Default_Reserve_Size; uint64 CommitSize = g_Arena_Default_Commit_Size; + + // 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;) }; [[nodiscard]] Arena* ArenaAllocate(const ArenaParams& params = {}, diff --git a/Juliet/include/Juliet.h b/Juliet/include/Juliet.h index 9026b29..b202916 100644 --- a/Juliet/include/Juliet.h +++ b/Juliet/include/Juliet.h @@ -21,8 +21,10 @@ #ifdef DEBUG #define JULIET_DEBUG 1 +#define JULIET_DEBUG_ONLY(expr) expr #else #define JULIET_DEBUG 0 +#define JULIET_DEBUG_ONLY(expr) #endif // Manual override to disable ImGui diff --git a/Juliet/src/Core/HAL/Display/Display.cpp b/Juliet/src/Core/HAL/Display/Display.cpp index 1d8745e..db66949 100644 --- a/Juliet/src/Core/HAL/Display/Display.cpp +++ b/Juliet/src/Core/HAL/Display/Display.cpp @@ -2,7 +2,6 @@ #include #include #include -#include #include namespace Juliet diff --git a/Juliet/src/Core/HAL/Display/Win32/Win32DisplayDevice.cpp b/Juliet/src/Core/HAL/Display/Win32/Win32DisplayDevice.cpp index f700464..241ea09 100644 --- a/Juliet/src/Core/HAL/Display/Win32/Win32DisplayDevice.cpp +++ b/Juliet/src/Core/HAL/Display/Win32/Win32DisplayDevice.cpp @@ -1,7 +1,6 @@ #include #include #include -#include namespace Juliet::Win32 { diff --git a/Juliet/src/Core/HAL/Display/Win32/Win32Window.cpp b/Juliet/src/Core/HAL/Display/Win32/Win32Window.cpp index aa3f7db..1ba3b9a 100644 --- a/Juliet/src/Core/HAL/Display/Win32/Win32Window.cpp +++ b/Juliet/src/Core/HAL/Display/Win32/Win32Window.cpp @@ -2,8 +2,7 @@ #include #include #include -#include -#include +#include namespace Juliet::Win32 { diff --git a/Juliet/src/Core/HotReload/HotReload.cpp b/Juliet/src/Core/HotReload/HotReload.cpp index da31704..9d41a68 100644 --- a/Juliet/src/Core/HotReload/HotReload.cpp +++ b/Juliet/src/Core/HotReload/HotReload.cpp @@ -2,8 +2,6 @@ #include #include #include -#include -#include #include #include @@ -13,6 +11,8 @@ namespace Juliet { void InitHotReloadCode(HotReloadCode& code, String dllName, String transientDllName, String lockFilename) { + code.Arena = ArenaAllocate(); + // Get the app base path and build the dll path from there. String basePath = GetBasePath(); size_t basePathLength = StringLength(basePath); @@ -24,7 +24,8 @@ namespace Juliet // 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(GetEngineArena(), dllFullPathLength, ConstString("DLLFullPath")); + + code.DLLFullPath.Data = ArenaPushArray(code.Arena, dllFullPathLength); int writtenSize = snprintf(CStr(code.DLLFullPath), dllFullPathLength, "%s%s", CStr(basePath), CStr(dllName)); if (writtenSize < static_cast(dllFullPathLength) - 1) { @@ -37,7 +38,7 @@ namespace Juliet // Lock filename path const size_t lockPathLength = basePathLength + StringLength(lockFilename) + 1; // Need +1 because snprintf needs 0 terminated strings - code.LockFullPath.Data = ArenaPushArray(GetEngineArena(), lockPathLength, ConstString("LockFullPath")); + code.LockFullPath.Data = ArenaPushArray(code.Arena, lockPathLength); writtenSize = snprintf(CStr(code.LockFullPath), lockPathLength, "%s%s", CStr(basePath), CStr(lockFilename)); if (writtenSize < static_cast(lockPathLength) - 1) { @@ -59,6 +60,8 @@ namespace Juliet // Arena memory persists until engine shutdown code.LockFullPath.Size = 0; // Arena memory persists until engine shutdown + + ArenaRelease(code.Arena); } void ReloadCode(HotReloadCode& code) diff --git a/Juliet/src/Core/ImGui/ImGuiService.cpp b/Juliet/src/Core/ImGui/ImGuiService.cpp index a4a07e5..667632b 100644 --- a/Juliet/src/Core/ImGui/ImGuiService.cpp +++ b/Juliet/src/Core/ImGui/ImGuiService.cpp @@ -9,7 +9,6 @@ #include #include -#include #include // Forward declare implementation functions from backends @@ -24,34 +23,16 @@ namespace Juliet::ImGuiService // Dedicated Paged Arena for ImGui // Sharing the same underlying Engine Pool for blocks, but separate Arena chain. - MemoryArena g_ImGuiArena; + Arena* g_ImGuiArena = {}; void* ImGuiAllocWrapper(size_t size, void* /*user_data*/) { - // Store size in header to allow Pop - // Align total size to 16 to avoid padding issues with ArenaPop LIFO check - size_t actualSize = size + 16; - actualSize = (actualSize + 15) & ~static_cast(15); - - // We do save the size when we push so we can pop exactly the size. - if (void* ptr = ArenaPush(&g_ImGuiArena, actualSize, 16, ConstString("ImGui"))) - { - // Write size at start - *static_cast(ptr) = actualSize; - return static_cast(ptr) + 16; - } - return nullptr; + return ArenaPush(g_ImGuiArena, size, 8, false); } - void ImGuiFreeWrapper(void* ptr, void* /*user_data*/) + void ImGuiFreeWrapper(void* /*ptr*/, void* /*user_data*/) { - Assert(ptr); - - uint8* originalPtr = static_cast(ptr) - 16; - size_t actualSize = *reinterpret_cast(originalPtr); - - // Attempt LIFO Pop - ArenaPop(&g_ImGuiArena, originalPtr, actualSize); + // TODO : Free list of imgui elements. } } // namespace @@ -60,7 +41,7 @@ namespace Juliet::ImGuiService Assert(!g_Initialized); // Initialize ImGui Arena using Engine Pool - MemoryArenaCreate(&g_ImGuiArena, GetEngineArena()->BackingPool); + g_ImGuiArena = ArenaAllocate(); // Setup Allocator ImGui::SetAllocatorFunctions(ImGuiAllocWrapper, ImGuiFreeWrapper, nullptr); diff --git a/Juliet/src/Core/Memory/EngineArena.h b/Juliet/src/Core/Memory/EngineArena.h deleted file mode 100644 index e64a49d..0000000 --- a/Juliet/src/Core/Memory/EngineArena.h +++ /dev/null @@ -1,10 +0,0 @@ -#pragma once - -#include - -namespace Juliet -{ - // Persistent engine-only arena. - // Not exported to the Game DLL. - MemoryArena* GetEngineArena(); -} // namespace Juliet diff --git a/Juliet/src/Core/Memory/MemoryArena.cpp b/Juliet/src/Core/Memory/MemoryArena.cpp index 469e3d4..f7ac744 100644 --- a/Juliet/src/Core/Memory/MemoryArena.cpp +++ b/Juliet/src/Core/Memory/MemoryArena.cpp @@ -44,6 +44,8 @@ namespace Juliet arena->BasePosition = 0; arena->Position = k_ArenaHeaderSize; + arena->CanReserveMore = params.CanReserveMore; + return arena; } @@ -65,6 +67,8 @@ namespace Juliet // If allowed and needed, add a new block and chain it to the arena. if (current->Reserved < positionPostPush /* flags : chaining allowed */) { + Assert(arena->CanReserveMore); + Arena* newBlock = nullptr; { Arena* prev_block; @@ -552,11 +556,9 @@ namespace Juliet namespace { MemoryPool g_ScratchMemory; - MemoryPool g_EngineMemory; MemoryPool g_GameMemory; MemoryArena g_ScratchArena; - MemoryArena g_EngineArena; MemoryArena g_GameArena; // Backing Buffers @@ -565,7 +567,6 @@ namespace Juliet void* g_GameBuffer = nullptr; constexpr size_t kScratchSize = Megabytes(64); - constexpr size_t kEngineSize = Megabytes(256); constexpr size_t kGameSize = Megabytes(512); void InitPool(MemoryPool* pool, void* buffer, size_t size) @@ -589,10 +590,7 @@ namespace Juliet { return &g_ScratchArena; } - MemoryArena* GetEngineArena() - { - return &g_EngineArena; - } + MemoryArena* GetGameArena() { return &g_GameArena; @@ -606,15 +604,12 @@ namespace Juliet void MemoryArenasInit() { g_ScratchBuffer = Malloc(kScratchSize); - g_EngineBuffer = Malloc(kEngineSize); g_GameBuffer = Malloc(kGameSize); InitPool(&g_ScratchMemory, g_ScratchBuffer, kScratchSize); - InitPool(&g_EngineMemory, g_EngineBuffer, kEngineSize); InitPool(&g_GameMemory, g_GameBuffer, kGameSize); MemoryArenaCreate(&g_ScratchArena, &g_ScratchMemory); - MemoryArenaCreate(&g_EngineArena, &g_EngineMemory); MemoryArenaCreate(&g_GameArena, &g_GameMemory); #if JULIET_DEBUG diff --git a/Juliet/src/Engine/Debug/MemoryDebugger.cpp b/Juliet/src/Engine/Debug/MemoryDebugger.cpp index c47498b..a519065 100644 --- a/Juliet/src/Engine/Debug/MemoryDebugger.cpp +++ b/Juliet/src/Engine/Debug/MemoryDebugger.cpp @@ -1,5 +1,4 @@ #include -#include #include #include @@ -420,7 +419,6 @@ namespace Juliet::Debug if (ImGui::Begin("Memory Debugger")) { DrawMemoryArena(ConstString("Game Arena"), *GetGameArena(), s_ConfirmedHovered, frameHovered); - DrawMemoryArena(ConstString("Engine Arena"), *GetEngineArena(), s_ConfirmedHovered, frameHovered); } ImGui::End(); diff --git a/Juliet/src/Graphics/D3D12/D3D12CommandList.cpp b/Juliet/src/Graphics/D3D12/D3D12CommandList.cpp index d5e61fb..fc5ab4c 100644 --- a/Juliet/src/Graphics/D3D12/D3D12CommandList.cpp +++ b/Juliet/src/Graphics/D3D12/D3D12CommandList.cpp @@ -454,8 +454,11 @@ namespace Juliet::D3D12 return false; } - ReturnSamplerHeapToPool(driver, commandList->Sampler_Heap); - commandList->Sampler_Heap = nullptr; + if (commandList->Sampler_Heap) [[likely]] + { + ReturnSamplerHeapToPool(driver, commandList->Sampler_Heap); + commandList->Sampler_Heap = nullptr; + } commandList->CRB_SRV_UAV_Heap = nullptr; // Clean up resource tracking diff --git a/Juliet/src/Graphics/D3D12/D3D12Common.cpp b/Juliet/src/Graphics/D3D12/D3D12Common.cpp index b5ccea6..afe5656 100644 --- a/Juliet/src/Graphics/D3D12/D3D12Common.cpp +++ b/Juliet/src/Graphics/D3D12/D3D12Common.cpp @@ -4,8 +4,8 @@ #include #include #include -#include +// TODO: Convert the whole file to memory arenas namespace Juliet::D3D12::Internal { namespace @@ -25,8 +25,8 @@ namespace Juliet::D3D12::Internal bool ExtendStagingDescriptorPool(NonNullPtr driver, D3D12StagingDescriptorPool& pool) { - D3D12DescriptorHeap* heap = - Internal::CreateDescriptorHeap(driver, pool.Heaps[0]->HeapType, kStagingHeapDescriptorExpectedCount, true); + D3D12DescriptorHeap* heap = Internal::CreateDescriptorHeap(driver, pool.Arena, pool.Heaps[0]->HeapType, + kStagingHeapDescriptorExpectedCount, true); if (!heap) { return false; @@ -49,13 +49,17 @@ namespace Juliet::D3D12::Internal D3D12StagingDescriptorPool* CreateStagingDescriptorPool(NonNullPtr driver, D3D12_DESCRIPTOR_HEAP_TYPE type) { - D3D12DescriptorHeap* heap = CreateDescriptorHeap(driver, type, kStagingHeapDescriptorExpectedCount, true); + Arena* arena = ArenaAllocate(); + + D3D12DescriptorHeap* heap = CreateDescriptorHeap(driver, arena, type, kStagingHeapDescriptorExpectedCount, true); if (!heap) { + ArenaRelease(arena); return nullptr; } - auto pool = static_cast(Calloc(1, sizeof(D3D12StagingDescriptorPool))); + auto pool = static_cast(Calloc(1, sizeof(D3D12StagingDescriptorPool))); + pool->Arena = arena; // First create the heaps pool->HeapCount = 1; @@ -113,6 +117,8 @@ namespace Juliet::D3D12::Internal Free(pool->Heaps); Free(pool->FreeDescriptors); + + ArenaRelease(pool->Arena); Free(pool.Get()); } } // namespace Juliet::D3D12::Internal diff --git a/Juliet/src/Graphics/D3D12/D3D12Common.h b/Juliet/src/Graphics/D3D12/D3D12Common.h index ff0f676..afccec4 100644 --- a/Juliet/src/Graphics/D3D12/D3D12Common.h +++ b/Juliet/src/Graphics/D3D12/D3D12Common.h @@ -22,8 +22,9 @@ namespace Juliet::D3D12 struct D3D12StagingDescriptorPool { + Arena* Arena; Internal::D3D12DescriptorHeap** Heaps; - uint32 HeapCount; + uint32 HeapCount; // Descriptor handles are owned by resources, so these can be thought of as descriptions of a free index within a heap. uint32 FreeDescriptorCapacity; @@ -35,9 +36,9 @@ namespace Juliet::D3D12 struct D3D12StagingDescriptor { D3D12StagingDescriptorPool* Pool; - Internal::D3D12DescriptorHeap* Heap; - D3D12_CPU_DESCRIPTOR_HANDLE CpuHandle; - uint32 CpuHandleIndex; + Internal::D3D12DescriptorHeap* Heap; + D3D12_CPU_DESCRIPTOR_HANDLE CpuHandle; + uint32 CpuHandleIndex; }; namespace Internal diff --git a/Juliet/src/Graphics/D3D12/D3D12DescriptorHeap.cpp b/Juliet/src/Graphics/D3D12/D3D12DescriptorHeap.cpp index 05921ab..2cd7c4a 100644 --- a/Juliet/src/Graphics/D3D12/D3D12DescriptorHeap.cpp +++ b/Juliet/src/Graphics/D3D12/D3D12DescriptorHeap.cpp @@ -1,26 +1,52 @@ #include #include #include -#include #include #include #include namespace Juliet::D3D12::Internal { - D3D12DescriptorHeap* CreateDescriptorHeap(NonNullPtr driver, D3D12_DESCRIPTOR_HEAP_TYPE type, uint32 count, bool isStaging) + void CreateDescriptorHeapPool(NonNullPtr driver, D3D12DescriptorHeapPool& heapPool, + D3D12_DESCRIPTOR_HEAP_TYPE type, uint32 count) { - auto heap = ArenaPushType(GetEngineArena(), ConstString("D3D12DescriptorHeap")); - if (!heap) + // Heap pool is just single linked list of free elements + constexpr size_t kInitialCapacity = 4; + heapPool.Arena = ArenaAllocate(); + heapPool.FirstFreeDescriptorHeap = nullptr; + + // Pre allocate 4 + for (uint32 i = 0; i < kInitialCapacity; ++i) { - return nullptr; + D3D12DescriptorHeap* descriptorHeap = CreateDescriptorHeap(driver, heapPool.Arena, type, count, false); + descriptorHeap->Next = heapPool.FirstFreeDescriptorHeap; + heapPool.FirstFreeDescriptorHeap = descriptorHeap; } + } + + void DestroyDescriptorHeapPool(D3D12DescriptorHeapPool& heapPool) + { + D3D12DescriptorHeap* current = heapPool.FirstFreeDescriptorHeap; + while (current != nullptr) + { + D3D12DescriptorHeap* next = current->Next; + DestroyDescriptorHeap(current); + current = next; + } + ArenaRelease(heapPool.Arena); + } + + D3D12DescriptorHeap* CreateDescriptorHeap(NonNullPtr driver, NonNullPtr arena, + D3D12_DESCRIPTOR_HEAP_TYPE type, uint32 count, bool isStaging) + { + D3D12DescriptorHeap* heap = ArenaPushStruct(arena.Get()); + Assert(heap); heap->CurrentDescriptorIndex = 0; - heap->FreeIndicesCapacity = 16; - heap->FreeIndicesCount = 0; - heap->FreeIndices = ArenaPushArray(GetEngineArena(), heap->FreeIndicesCapacity, - ConstString("D3D12DescriptorHeap/FreeIndices")); + + heap->FreeIndices.Create(); + heap->FreeIndices.Resize(16); + heap->CurrentFreeIndex = 0; D3D12_DESCRIPTOR_HEAP_DESC heapDesc; heapDesc.NumDescriptors = count; @@ -54,23 +80,21 @@ namespace Juliet::D3D12::Internal void DestroyDescriptorHeap(NonNullPtr heap) { + heap->FreeIndices.Destroy(); if (heap->Handle) { heap->Handle->Release(); } - // TODO: should not free because its on an arena, but need to use arena properly - // SafeFree(heap->FreeIndices); - // Free(heap.Get()); } bool AssignDescriptor(D3D12DescriptorHeap* heap, D3D12Descriptor& outDescriptor) { uint32 index = UINT32_MAX; - if (heap->FreeIndicesCount > 0) + if (heap->CurrentFreeIndex > 0) { - heap->FreeIndicesCount -= 1; - index = heap->FreeIndices[heap->FreeIndicesCount]; + heap->CurrentFreeIndex -= 1; + index = heap->FreeIndices[heap->CurrentFreeIndex]; } else if (heap->CurrentDescriptorIndex < heap->MaxDescriptors) { @@ -102,55 +126,42 @@ namespace Juliet::D3D12::Internal D3D12DescriptorHeap* heap = descriptor.Heap; - if (heap->FreeIndicesCount >= heap->FreeIndicesCapacity) + if (heap->CurrentFreeIndex >= heap->FreeIndices.Count) { - size_t oldCapacity = heap->FreeIndicesCapacity; - heap->FreeIndicesCapacity *= 2; - heap->FreeIndices = ArenaRealloc(GetEngineArena(), heap->FreeIndices, oldCapacity, - heap->FreeIndicesCapacity, ConstString("FreeIndices")); - } - - heap->FreeIndices[heap->FreeIndicesCount] = descriptor.Index; - heap->FreeIndicesCount++; - } - - D3D12DescriptorHeap* AcquireSamplerHeapFromPool(NonNullPtr d3d12Driver, DescriptorHeapCreator creator) - { - D3D12DescriptorHeap* result; - D3D12DescriptorHeapPool* pool = &d3d12Driver->SamplerHeapPool; - - if (pool->Count > 0) - { - result = pool->Heaps[pool->Count - 1]; - pool->Count -= 1; + heap->FreeIndices.PushBack(descriptor.Index); } else { - result = creator(d3d12Driver, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, GPUDriver::kSampler_HeapDescriptorCount, false); + heap->FreeIndices[heap->CurrentFreeIndex] = descriptor.Index; + heap->CurrentFreeIndex++; + } + } + + D3D12DescriptorHeap* AcquireSamplerHeapFromPool(NonNullPtr d3d12Driver) + { + D3D12DescriptorHeapPool& pool = d3d12Driver->SamplerHeapPool; + + D3D12DescriptorHeap* result = pool.FirstFreeDescriptorHeap; + if (result) + { + pool.FirstFreeDescriptorHeap = pool.FirstFreeDescriptorHeap->Next; + } + else + { + result = CreateDescriptorHeap(d3d12Driver, pool.Arena, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, + GPUDriver::kSampler_HeapDescriptorCount, false); } return result; } - void ReturnSamplerHeapToPool(NonNullPtr d3d12Driver, D3D12DescriptorHeap* heap) + void ReturnSamplerHeapToPool(NonNullPtr d3d12Driver, NonNullPtr heap) { - if (heap == nullptr) - { - return; - } - - D3D12DescriptorHeapPool* pool = &d3d12Driver->SamplerHeapPool; + D3D12DescriptorHeapPool& pool = d3d12Driver->SamplerHeapPool; heap->CurrentDescriptorIndex = 0; - if (pool->Count >= pool->Capacity) - { - size_t oldCapacity = pool->Capacity; - pool->Capacity *= 2; - pool->Heaps = ArenaRealloc(GetEngineArena(), pool->Heaps, oldCapacity, pool->Capacity, ConstString("Heaps")); - } - - pool->Heaps[pool->Count] = heap; - pool->Count += 1; + heap->Next = pool.FirstFreeDescriptorHeap; + pool.FirstFreeDescriptorHeap = heap; } } // namespace Juliet::D3D12::Internal diff --git a/Juliet/src/Graphics/D3D12/D3D12DescriptorHeap.h b/Juliet/src/Graphics/D3D12/D3D12DescriptorHeap.h index c101473..4804c0b 100644 --- a/Juliet/src/Graphics/D3D12/D3D12DescriptorHeap.h +++ b/Juliet/src/Graphics/D3D12/D3D12DescriptorHeap.h @@ -1,6 +1,7 @@ #pragma once #include +#include #include // Forward declare @@ -14,6 +15,7 @@ namespace Juliet::D3D12::Internal // https://learn.microsoft.com/en-us/windows/win32/direct3d12/descriptor-heaps struct D3D12DescriptorHeap { + D3D12DescriptorHeap* Next; ID3D12DescriptorHeap* Handle; D3D12_DESCRIPTOR_HEAP_TYPE HeapType; D3D12_CPU_DESCRIPTOR_HANDLE DescriptorHeapCPUStart; @@ -22,11 +24,10 @@ namespace Juliet::D3D12::Internal uint32 DescriptorSize; uint32 CurrentDescriptorIndex; // only used by GPU heaps - uint32* FreeIndices; - uint32 FreeIndicesCapacity; - uint32 FreeIndicesCount; + VectorArena FreeIndices; + index_t CurrentFreeIndex; - bool Staging : 1; + bool Staging : 1; }; struct D3D12Descriptor @@ -39,20 +40,24 @@ namespace Juliet::D3D12::Internal struct D3D12DescriptorHeapPool { - D3D12DescriptorHeap** Heaps; - size_t Capacity; - size_t Count; + Arena* Arena; + D3D12DescriptorHeap* FirstFreeDescriptorHeap; }; - using DescriptorHeapCreator = D3D12DescriptorHeap* (*)(NonNullPtr, D3D12_DESCRIPTOR_HEAP_TYPE, uint32, bool); + using DescriptorHeapCreator = D3D12DescriptorHeap* (*)(NonNullPtr, D3D12DescriptorHeapPool& heapPool, + D3D12_DESCRIPTOR_HEAP_TYPE, uint32, bool); - extern D3D12DescriptorHeap* CreateDescriptorHeap(NonNullPtr driver, - D3D12_DESCRIPTOR_HEAP_TYPE type, uint32 count, bool isStaging); + extern void CreateDescriptorHeapPool(NonNullPtr driver, D3D12DescriptorHeapPool& heapPool, + D3D12_DESCRIPTOR_HEAP_TYPE type, uint32 count); + extern void DestroyDescriptorHeapPool(D3D12DescriptorHeapPool& pool); + + extern D3D12DescriptorHeap* CreateDescriptorHeap(NonNullPtr driver, NonNullPtr arena, + D3D12_DESCRIPTOR_HEAP_TYPE type, uint32 count, bool isStaging); extern void DestroyDescriptorHeap(NonNullPtr heap); - extern D3D12DescriptorHeap* AcquireSamplerHeapFromPool(NonNullPtr d3d12Driver, DescriptorHeapCreator creator = CreateDescriptorHeap); - extern void ReturnSamplerHeapToPool(NonNullPtr d3d12Driver, D3D12DescriptorHeap* heap); + extern D3D12DescriptorHeap* AcquireSamplerHeapFromPool(NonNullPtr d3d12Driver); + extern void ReturnSamplerHeapToPool(NonNullPtr d3d12Driver, NonNullPtr heap); extern bool AssignDescriptor(D3D12DescriptorHeap* heap, D3D12Descriptor& outDescriptor); extern void ReleaseDescriptor(const D3D12Descriptor& descriptor); -} // namespace Juliet::D3D12 +} // namespace Juliet::D3D12::Internal diff --git a/Juliet/src/Graphics/D3D12/D3D12GraphicsDevice.cpp b/Juliet/src/Graphics/D3D12/D3D12GraphicsDevice.cpp index 483499b..bbe2971 100644 --- a/Juliet/src/Graphics/D3D12/D3D12GraphicsDevice.cpp +++ b/Juliet/src/Graphics/D3D12/D3D12GraphicsDevice.cpp @@ -3,7 +3,6 @@ #include #include #include -#include #include #include #include @@ -471,22 +470,7 @@ namespace Juliet::D3D12 } } - auto DestroyDescriptorHeapPool = [](Internal::D3D12DescriptorHeapPool& heapPool) - { - if (heapPool.Heaps) - { - for (uint32 i = 0; i < heapPool.Count; ++i) - { - if (heapPool.Heaps[i]) - { - Internal::DestroyDescriptorHeap(heapPool.Heaps[i]); - heapPool.Heaps[i] = nullptr; - } - } - // SafeFree(heapPool.Heaps); // Allocated with Arena, do not free. - } - }; - DestroyDescriptorHeapPool(driver->SamplerHeapPool); + Internal::DestroyDescriptorHeapPool(driver->SamplerHeapPool); // Release command buffers for (uint32 i = 0; i < driver->AvailableCommandListCount; i += 1) @@ -571,6 +555,7 @@ namespace Juliet::D3D12 driver->D3D12SerializeVersionedRootSignatureFct = nullptr; + ArenaRelease(driver->DriverArena); Free(driver.Get()); } @@ -745,6 +730,9 @@ namespace Juliet::D3D12 { auto driver = static_cast(Calloc(1, sizeof(D3D12Driver))); + // TODO : Convert everything to arena + driver->DriverArena = ArenaAllocate(); + #if JULIET_DEBUG #ifdef IDXGIINFOQUEUE_SUPPORTED if (enableDebug) @@ -1023,32 +1011,8 @@ namespace Juliet::D3D12 } } - // Other Descriptor pools - auto CreateDescriptorPool = [&](Internal::D3D12DescriptorHeapPool& heapPool, - D3D12_DESCRIPTOR_HEAP_TYPE type, uint32 count) -> bool - { - heapPool.Capacity = 4; - heapPool.Count = 4; - heapPool.Heaps = ArenaPushArray(GetEngineArena(), heapPool.Capacity, - ConstString("DescriptorHeap")); - - for (uint32 i = 0; i < heapPool.Capacity; ++i) - { - heapPool.Heaps[i] = Internal::CreateDescriptorHeap(driver, type, count, false); - - if (heapPool.Heaps[i] == nullptr) - { - return false; - } - } - return true; - }; - - if (!CreateDescriptorPool(driver->SamplerHeapPool, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, GPUDriver::kSampler_HeapDescriptorCount)) - { - DestroyDriver_Internal(driver); - return nullptr; - } + CreateDescriptorHeapPool(driver, driver->SamplerHeapPool, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, + GPUDriver::kSampler_HeapDescriptorCount); // Deferred dispose vectors driver->GraphicsPipelinesToDisposeCapacity = 4; @@ -1125,8 +1089,9 @@ namespace Juliet::D3D12 driver->GraphicsDevice = device; // Create Global Bindless Heap that stays alive for the driver whole lifetime - driver->BindlessDescriptorHeap = Internal::CreateDescriptorHeap(driver, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, - GPUDriver::kCBV_SRV_UAV_HeapDescriptorCount, false); + driver->BindlessDescriptorHeap = + Internal::CreateDescriptorHeap(driver, driver->DriverArena, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, + GPUDriver::kCBV_SRV_UAV_HeapDescriptorCount, false); return device; } diff --git a/Juliet/src/Graphics/GraphicsDevice.h b/Juliet/src/Graphics/GraphicsDevice.h index 6086224..7ce668e 100644 --- a/Juliet/src/Graphics/GraphicsDevice.h +++ b/Juliet/src/Graphics/GraphicsDevice.h @@ -30,6 +30,8 @@ namespace Juliet struct GPUDriver { + Arena* DriverArena = {}; + static constexpr uint8 kMaxFramesInFlight = 3; static constexpr uint8 kMaxColorTargetInfo = 4; static constexpr uint8 kMaxUniformBuffersPerStage = 4; @@ -74,9 +76,6 @@ namespace Juliet void (*DrawIndexedPrimitives)(NonNullPtr commandList, uint32 numIndices, uint32 numInstances, uint32 firstIndex, uint32 vertexOffset, uint32 firstInstance); - - - void (*SetPushConstants)(NonNullPtr commandList, ShaderStage stage, uint32 rootParameterIndex, uint32 numConstants, const void* constants); @@ -108,10 +107,10 @@ namespace Juliet void* (*MapGraphicsTransferBuffer)(NonNullPtr driver, NonNullPtr buffer); void (*UnmapGraphicsTransferBuffer)(NonNullPtr driver, NonNullPtr buffer); - void (*CopyBuffer)(NonNullPtr commandList, NonNullPtr dst, - NonNullPtr src, size_t size, size_t dstOffset, size_t srcOffset); - void (*CopyBufferToTexture)(NonNullPtr commandList, NonNullPtr dst, - NonNullPtr src); // Assume full copy for now + void (*CopyBuffer)(NonNullPtr commandList, NonNullPtr dst, + NonNullPtr src, size_t size, size_t dstOffset, size_t srcOffset); + void (*CopyBufferToTexture)(NonNullPtr commandList, NonNullPtr dst, + NonNullPtr src); // Assume full copy for now void (*TransitionBufferToReadable)(NonNullPtr commandList, NonNullPtr buffer); uint32 (*GetDescriptorIndex)(NonNullPtr device, NonNullPtr buffer); -- 2.49.1 From f73b8284bb8c98e273be691e1ffb2fc7db9a940c Mon Sep 17 00:00:00 2001 From: Patedam Date: Tue, 10 Feb 2026 23:01:42 -0500 Subject: [PATCH 3/7] Adding base to reallocate + unit test --- Juliet/include/Core/Common/CoreTypes.h | 2 + Juliet/include/Core/Memory/MemoryArena.h | 15 ++- Juliet/src/Core/Memory/MemoryArena.cpp | 100 +++++++++++++++++++- Juliet/src/Core/Memory/MemoryArenaTests.cpp | 44 +++------ 4 files changed, 125 insertions(+), 36 deletions(-) diff --git a/Juliet/include/Core/Common/CoreTypes.h b/Juliet/include/Core/Common/CoreTypes.h index b93bb99..8db89c3 100644 --- a/Juliet/include/Core/Common/CoreTypes.h +++ b/Juliet/include/Core/Common/CoreTypes.h @@ -25,6 +25,8 @@ struct ByteBuffer size_t Size; }; +using ptrdiff_t = decltype(static_cast(nullptr) - static_cast(nullptr)); + using FunctionPtr = auto (*)(void) -> void; // Limits diff --git a/Juliet/include/Core/Memory/MemoryArena.h b/Juliet/include/Core/Memory/MemoryArena.h index 2c6d190..43ac87e 100644 --- a/Juliet/include/Core/Memory/MemoryArena.h +++ b/Juliet/include/Core/Memory/MemoryArena.h @@ -13,7 +13,8 @@ namespace Juliet constexpr global uint64 g_Arena_Default_Commit_Size = Kilobytes(64); constexpr global uint64 k_ArenaHeaderSize = 128; - // Refactor + struct ArenaFreeNode; + struct Arena { Arena* Previous; @@ -29,8 +30,13 @@ namespace Juliet uint64 Committed; uint64 Reserved; - Arena* FreeLast; + Arena* FreeBlockLast; + ArenaFreeNode* FreeNodes; + + bool AllowRealloc : 1; + + JULIET_DEBUG_ONLY(uint16 LostNodeCount); JULIET_DEBUG_ONLY(bool CanReserveMore : 1;) }; static_assert(sizeof(Arena) <= k_ArenaHeaderSize); @@ -40,6 +46,9 @@ namespace Juliet uint64 ReserveSize = g_Arena_Default_Reserve_Size; uint64 CommitSize = g_Arena_Default_Commit_Size; + // True: All push will be 32 bytes minimum + 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;) @@ -51,6 +60,8 @@ namespace Juliet // Raw Push, can be used but templated helpers exists below [[nodiscard]] void* ArenaPush(NonNullPtr arena, size_t size, size_t align, bool shouldBeZeroed); + [[nodiscard]] void* ArenaReallocate(NonNullPtr arena, void* oldPtr, size_t oldSize, size_t newSize, + size_t align, bool shouldBeZeroed); void ArenaPopTo(NonNullPtr arena, size_t position); void ArenaPop(NonNullPtr arena, size_t amount); void ArenaClear(NonNullPtr arena); diff --git a/Juliet/src/Core/Memory/MemoryArena.cpp b/Juliet/src/Core/Memory/MemoryArena.cpp index f7ac744..6b8eabe 100644 --- a/Juliet/src/Core/Memory/MemoryArena.cpp +++ b/Juliet/src/Core/Memory/MemoryArena.cpp @@ -17,6 +17,20 @@ namespace Juliet constexpr uint64 k_PageSize = Kilobytes(4); } // namespace + struct ArenaFreeNode + { + ArenaFreeNode* Next; + ArenaFreeNode* Previous; + index_t Position; + size_t Size; + }; + + namespace + { + static_assert(sizeof(ArenaFreeNode) == 32, "ArenaFreeNode should be 32 bytes and not more"); + constexpr size_t k_ArenaFreeNodeSize = sizeof(ArenaFreeNode); + } // namespace + // https://github.com/EpicGamesExt/raddebugger/blob/master/src/base/base_arena.c Arena* ArenaAllocate(const ArenaParams& params, const std::source_location& loc) @@ -44,6 +58,9 @@ namespace Juliet arena->BasePosition = 0; arena->Position = k_ArenaHeaderSize; + arena->FreeNodes = nullptr; + arena->AllowRealloc = params.AllowRealloc; + arena->CanReserveMore = params.CanReserveMore; return arena; @@ -64,6 +81,47 @@ namespace Juliet size_t positionPrePush = AlignPow2(current->Position, align); size_t positionPostPush = positionPrePush + size; + if (arena->AllowRealloc) + { + size = Max(size, k_ArenaFreeNodeSize); + + for (ArenaFreeNode* freeNode = current->FreeNodes; freeNode != nullptr; freeNode = freeNode->Next) + { + if (size <= freeNode->Size) + { + index_t position = freeNode->Position; + size_t remainingSize = freeNode->Size - size; + if (remainingSize < k_ArenaFreeNodeSize) + { + ArenaFreeNode* previous = freeNode->Previous; + ArenaFreeNode* next = freeNode->Next; + if (previous) + { + previous->Next = next; + } + if (next) + { + next->Previous = previous; + } + + JULIET_DEBUG_ONLY(remainingSize > 0 ? ++current->LostNodeCount : current->LostNodeCount); + } + else + { + freeNode->Position += size; + } + + auto* result = reinterpret_cast(current) + position; + if (shouldBeZeroed) + { + MemoryZero(result, size); + } + + return result; + } + } + } + // If allowed and needed, add a new block and chain it to the arena. if (current->Reserved < positionPostPush /* flags : chaining allowed */) { @@ -72,7 +130,7 @@ namespace Juliet Arena* newBlock = nullptr; { Arena* prev_block; - for (newBlock = arena->FreeLast, prev_block = nullptr; newBlock != nullptr; + for (newBlock = arena->FreeBlockLast, prev_block = nullptr; newBlock != nullptr; prev_block = newBlock, newBlock = newBlock->Previous) { if (newBlock->Reserved >= AlignPow2(newBlock->Position, align) + size) @@ -83,7 +141,7 @@ namespace Juliet } else { - arena->FreeLast = newBlock->Previous; + arena->FreeBlockLast = newBlock->Previous; } break; } @@ -153,6 +211,42 @@ namespace Juliet return result; } + void* ArenaReallocate(NonNullPtr arena, void* oldPtr, size_t oldSize, size_t newSize, size_t align, bool shouldBeZeroed) + { + // Find the correct block + Arena* block = nullptr; + for (block = arena->Current; block != nullptr; block = block->Previous) + { + if ((block < oldPtr) && (oldPtr <= (block + block->Reserved))) + { + break; + } + } + Assert(block != nullptr); + + MemoryZero(oldPtr, oldSize); + ArenaFreeNode* freeNode = static_cast(oldPtr); + ptrdiff_t posPtr = static_cast(oldPtr) - reinterpret_cast(block); + index_t position = static_cast(posPtr) - block->BasePosition; + freeNode->Position = position; + freeNode->Size = oldSize; + + if (block->FreeNodes != nullptr) + { + block->FreeNodes = freeNode; + } + else + { + freeNode->Previous = block->FreeNodes; + if (block->FreeNodes != nullptr) + { + block->FreeNodes->Next = freeNode; + } + block->FreeNodes = freeNode; + } + return ArenaPush(arena, newSize, align, shouldBeZeroed); + } + void ArenaPopTo(NonNullPtr arena, size_t position) { size_t clampedPosition = ClampBottom(k_ArenaHeaderSize, position); @@ -162,7 +256,7 @@ namespace Juliet { previous = current->Previous; current->Position = k_ArenaHeaderSize; - SingleLinkedListPushPrevious(arena->FreeLast, current); + SingleLinkedListPushPrevious(arena->FreeBlockLast, current); } // No freelist : diff --git a/Juliet/src/Core/Memory/MemoryArenaTests.cpp b/Juliet/src/Core/Memory/MemoryArenaTests.cpp index cc630e8..015961f 100644 --- a/Juliet/src/Core/Memory/MemoryArenaTests.cpp +++ b/Juliet/src/Core/Memory/MemoryArenaTests.cpp @@ -139,40 +139,22 @@ namespace Juliet::UnitTest pool.FreeList = blk; } - MemoryArena arena; - MemoryArenaCreate(&arena, &pool); + { + // Test reallocate + Arena* arena = ArenaAllocate({ .AllowRealloc = true }); + char* charArray = ArenaPushArray(arena, 128); + char* secondCharArray = ArenaPushArray(arena, 128); + char* thirdCharArray = ArenaPushArray(arena, 128); - // 5. Arena Pop - // Align sizes to 16 to avoid padding issues during Pop - void* pop1 = ArenaPush(&arena, 5008, 16, ConstString("Pop1")); + secondCharArray = static_cast(ArenaReallocate(arena, secondCharArray, 128, 256, alignof(char), true)); - void* pop2 = ArenaPush(&arena, 208, 16, ConstString("Pop2")); - // Pop Middle (Should Fail) - bool res1 = ArenaPop(&arena, pop1, 5008); - Assert(res1 == false); + char* fourthCharArray = ArenaPushArray(arena, 128); - // Pop Top (Should Success) - bool res2 = ArenaPop(&arena, pop2, 208); // 200->208 - Assert(res2 == true); - - // Verify Used space is back to pop1 end - Assert(arena.CurrentBlock->Used == ArenaGetMarker(&arena).Offset); // This usage of GetMarker is valid if marker was implicit? - // Actually we didn't take a marker. - // We can verify by allocating pop3. It should overwrite pop2 location. - void* pop3 = ArenaPush(&arena, 16, 16, ConstString("Pop3")); - Assert(pop3 == pop2); - - // Cleanup popped items from stack logic for reset... - // Pop pop3 - ArenaPop(&arena, pop3, 16); - // Pop pop1 - ArenaPop(&arena, pop1, 5008); - Assert(arena.CurrentBlock->Used == 0); // Should be effectively 0 - - printf("[Success] Arena Pop\n"); - - // Cleanup - SafeFree(testBacking); + Assert(charArray); + Assert(secondCharArray); + Assert(thirdCharArray); + Assert(fourthCharArray); + } printf("All Paged MemoryArena tests passed.\n"); } -- 2.49.1 From 536f6c5c608813a28ebdf7a0479d460e86cd2b61 Mon Sep 17 00:00:00 2001 From: Patedam Date: Thu, 12 Feb 2026 21:51:15 -0500 Subject: [PATCH 4/7] Using reallocate for Vector. WIP, unit test not passing --- Juliet/include/Core/Container/Vector.h | 48 ++++++++++++++++++--- Juliet/include/Juliet.h | 2 +- Juliet/src/Core/Memory/MemoryArena.cpp | 10 ++++- Juliet/src/Core/Memory/MemoryArenaTests.cpp | 24 +---------- 4 files changed, 53 insertions(+), 31 deletions(-) diff --git a/Juliet/include/Core/Container/Vector.h b/Juliet/include/Core/Container/Vector.h index a8bee89..679fd9d 100644 --- a/Juliet/include/Core/Container/Vector.h +++ b/Juliet/include/Core/Container/Vector.h @@ -6,7 +6,7 @@ namespace Juliet { - template + template struct VectorArena { void Create() @@ -16,8 +16,27 @@ namespace Juliet DataFirst = DataLast = nullptr; Count = 0; Stride = sizeof(Type); - Arena = ArenaAllocate(JULIET_DEBUG_ONLY({ .CanReserveMore = false })); + ArenaParams params{ .AllowRealloc = AllowRealloc JULIET_DEBUG_ONLY(, .CanReserveMore = false) }; + Arena = ArenaAllocate(params); + InternalArena = true; + + Reserve(ReserveSize); } + + void Create(NonNullPtr arena) + { + Assert(!Arena); + static_assert(AllowRealloc == false); + + DataFirst = DataLast = nullptr; + Count = 0; + Stride = sizeof(Type); + Arena = arena.Get(); + InternalArena = false; + + Reserve(ReserveSize); + } + void Destroy() { ArenaRelease(Arena); @@ -27,6 +46,22 @@ namespace Juliet Arena = nullptr; } + void Reserve(size_t newCapacity) + { + if (newCapacity > Capacity) + { + if (Data == nullptr) + { + Data = ArenaPushArray(Arena, newCapacity); + } + else if (AllowRealloc && InternalArena) + { + Data = static_cast(ArenaReallocate(Arena, Data, Capacity, newCapacity, AlignOf(Type), true)); + } + Capacity = newCapacity; + } + } + void Resize(size_t newCount) { Type* entry = ArenaPushArray(Arena, newCount); @@ -39,7 +74,7 @@ namespace Juliet { Assert(Arena); - Type* entry = ArenaPushStruct(Arena); + Type* entry = Data + (Count * Stride); *entry = value; if (Count == 0) @@ -54,7 +89,7 @@ namespace Juliet { Assert(Arena); - Type* entry = ArenaPushStruct(Arena); + Type* entry = Data + (Count * Stride); *entry = std::move(value); if (Count == 0) @@ -86,8 +121,6 @@ namespace Juliet { DataFirst = DataLast = nullptr; } - - ArenaPop(Arena, Stride); } void Clear() @@ -117,8 +150,11 @@ namespace Juliet Arena* Arena; Type* DataFirst; Type* DataLast; + Type* Data; size_t Count; + size_t Capacity; size_t Stride; + bool InternalArena : 1; }; static_assert(std::is_standard_layout_v>, "VectorArena must have a standard layout to remain POD-like."); diff --git a/Juliet/include/Juliet.h b/Juliet/include/Juliet.h index b202916..e200816 100644 --- a/Juliet/include/Juliet.h +++ b/Juliet/include/Juliet.h @@ -21,7 +21,7 @@ #ifdef DEBUG #define JULIET_DEBUG 1 -#define JULIET_DEBUG_ONLY(expr) expr +#define JULIET_DEBUG_ONLY(...) __VA_ARGS__ #else #define JULIET_DEBUG 0 #define JULIET_DEBUG_ONLY(expr) diff --git a/Juliet/src/Core/Memory/MemoryArena.cpp b/Juliet/src/Core/Memory/MemoryArena.cpp index 6b8eabe..50487aa 100644 --- a/Juliet/src/Core/Memory/MemoryArena.cpp +++ b/Juliet/src/Core/Memory/MemoryArena.cpp @@ -213,7 +213,9 @@ namespace Juliet void* ArenaReallocate(NonNullPtr arena, void* oldPtr, size_t oldSize, size_t newSize, size_t align, bool shouldBeZeroed) { - // Find the correct block + void* result = ArenaPush(arena, newSize, align, shouldBeZeroed); + + // Find the correct block to release Arena* block = nullptr; for (block = arena->Current; block != nullptr; block = block->Previous) { @@ -224,6 +226,10 @@ namespace Juliet } Assert(block != nullptr); + // Copy old to new + MemCopy(result, oldPtr, oldSize); + + // Zero the old memory MemoryZero(oldPtr, oldSize); ArenaFreeNode* freeNode = static_cast(oldPtr); ptrdiff_t posPtr = static_cast(oldPtr) - reinterpret_cast(block); @@ -244,7 +250,7 @@ namespace Juliet } block->FreeNodes = freeNode; } - return ArenaPush(arena, newSize, align, shouldBeZeroed); + return result; } void ArenaPopTo(NonNullPtr arena, size_t position) diff --git a/Juliet/src/Core/Memory/MemoryArenaTests.cpp b/Juliet/src/Core/Memory/MemoryArenaTests.cpp index 015961f..b25563c 100644 --- a/Juliet/src/Core/Memory/MemoryArenaTests.cpp +++ b/Juliet/src/Core/Memory/MemoryArenaTests.cpp @@ -117,28 +117,6 @@ namespace Juliet::UnitTest ArenaRelease(testArena); - // Setup Pool and Arena for Pop Tests - size_t testPoolSize = Megabytes(1); - void* testBacking = Calloc(1, testPoolSize); - MemoryPool pool; - pool.BaseAddress = testBacking; - pool.TotalSize = testPoolSize; - pool.FreeList = nullptr; - - // Initialize FreeList (Simulate pool) - size_t blockSize = Kilobytes(128); - size_t numBlocks = testPoolSize / blockSize; - uint8* ptr = static_cast(testBacking); - for (size_t i = 0; i < numBlocks; ++i) - { - MemoryBlock* blk = reinterpret_cast(ptr + i * blockSize); - blk->Magic = MemoryBlock::kMagic; - blk->TotalSize = blockSize; - blk->Used = 0; - blk->Next = pool.FreeList; - pool.FreeList = blk; - } - { // Test reallocate Arena* arena = ArenaAllocate({ .AllowRealloc = true }); @@ -154,6 +132,8 @@ namespace Juliet::UnitTest Assert(secondCharArray); Assert(thirdCharArray); Assert(fourthCharArray); + + ArenaRelease(arena); } printf("All Paged MemoryArena tests passed.\n"); -- 2.49.1 From 6a6f34516c32d3f4e07b7340da43a9daef1d3fea Mon Sep 17 00:00:00 2001 From: Patedam Date: Fri, 13 Feb 2026 21:56:27 -0500 Subject: [PATCH 5/7] Fixed push back --- Juliet/include/Core/Container/Vector.h | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/Juliet/include/Core/Container/Vector.h b/Juliet/include/Core/Container/Vector.h index 679fd9d..081d65f 100644 --- a/Juliet/include/Core/Container/Vector.h +++ b/Juliet/include/Core/Container/Vector.h @@ -15,7 +15,6 @@ namespace Juliet DataFirst = DataLast = nullptr; Count = 0; - Stride = sizeof(Type); ArenaParams params{ .AllowRealloc = AllowRealloc JULIET_DEBUG_ONLY(, .CanReserveMore = false) }; Arena = ArenaAllocate(params); InternalArena = true; @@ -30,7 +29,6 @@ namespace Juliet DataFirst = DataLast = nullptr; Count = 0; - Stride = sizeof(Type); Arena = arena.Get(); InternalArena = false; @@ -42,7 +40,7 @@ namespace Juliet ArenaRelease(Arena); DataFirst = DataLast = nullptr; Count = 0; - Stride = 0; + Capacity = 0; Arena = nullptr; } @@ -74,7 +72,7 @@ namespace Juliet { Assert(Arena); - Type* entry = Data + (Count * Stride); + Type* entry = Data + Count; *entry = value; if (Count == 0) @@ -89,7 +87,7 @@ namespace Juliet { Assert(Arena); - Type* entry = Data + (Count * Stride); + Type* entry = Data + Count; *entry = std::move(value); if (Count == 0) @@ -153,7 +151,6 @@ namespace Juliet Type* Data; size_t Count; size_t Capacity; - size_t Stride; bool InternalArena : 1; }; static_assert(std::is_standard_layout_v>, -- 2.49.1 From c6552d2def5fd56b636cd6724520f345868c1fff Mon Sep 17 00:00:00 2001 From: Patedam Date: Fri, 13 Feb 2026 22:02:11 -0500 Subject: [PATCH 6/7] Allow reallocating when we use external arena. Internal arena do not need reallocate as it is consecutive memory --- Juliet/include/Core/Container/Vector.h | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/Juliet/include/Core/Container/Vector.h b/Juliet/include/Core/Container/Vector.h index 081d65f..ba529be 100644 --- a/Juliet/include/Core/Container/Vector.h +++ b/Juliet/include/Core/Container/Vector.h @@ -12,6 +12,7 @@ namespace Juliet void Create() { Assert(!Arena); + static_assert(AllowRealloc == false); DataFirst = DataLast = nullptr; Count = 0; @@ -25,7 +26,6 @@ namespace Juliet void Create(NonNullPtr arena) { Assert(!Arena); - static_assert(AllowRealloc == false); DataFirst = DataLast = nullptr; Count = 0; @@ -72,6 +72,12 @@ namespace Juliet { Assert(Arena); + if (Count + 1 == Capacity) + { + Assert(AllowRealloc); + Reserve(Capacity * 2); + } + Type* entry = Data + Count; *entry = value; @@ -87,6 +93,12 @@ namespace Juliet { Assert(Arena); + if (Count + 1 == Capacity) + { + Assert(AllowRealloc); + Reserve(Capacity * 2); + } + Type* entry = Data + Count; *entry = std::move(value); -- 2.49.1 From 5337d4cb669174839b613dbf3e01b2c3ff771e7e Mon Sep 17 00:00:00 2001 From: Patedam Date: Fri, 13 Feb 2026 23:00:14 -0500 Subject: [PATCH 7/7] Made gemini improve and fix unit tests Found and fixed some bugs at the same time --- External/ImGui.vcxproj | 4 +- Game/Game.vcxproj | 12 +- Juliet/Juliet.vcxproj | 8 +- Juliet/include/Core/Container/Vector.h | 48 ++++-- Juliet/include/Core/Main.h | 2 - Juliet/src/Core/Memory/MemoryArena.cpp | 30 ++-- Juliet/src/Core/Memory/MemoryArenaTests.cpp | 35 ++++ .../src/UnitTest/Container/VectorUnitTest.cpp | 151 ++++++++++++++---- JulietApp/JulietApp.bff | 2 +- JulietApp/JulietApp.vcxproj | 16 +- .../JulietShaderCompiler.vcxproj | 2 +- fbuild.bff | 2 +- 12 files changed, 231 insertions(+), 81 deletions(-) diff --git a/External/ImGui.vcxproj b/External/ImGui.vcxproj index 6e82868..be4b9fe 100644 --- a/External/ImGui.vcxproj +++ b/External/ImGui.vcxproj @@ -196,7 +196,7 @@ cd $(SolutionDir) & misc\fbuild -ide -dist -monitor -cache $(ProjectName)-$(Configuration) cd $(SolutionDir) & misc\fbuild -ide -dist -monitor -cache -clean $(ProjectName)-$(Configuration) - _CRT_SECURE_NO_WARNINGS;_UNICODE;UNICODE;WIN32_LEAN_AND_MEAN;WIN32;_WIN32;__WINDOWS__;_HAS_EXCEPTIONS=0;WIN64;DEBUG;PROFILING_ENABLED;JULIET_ENABLE_IMGUI;IMGUI_API=__declspec(dllexport); + _CRT_SECURE_NO_WARNINGS;_UNICODE;UNICODE;WIN32_LEAN_AND_MEAN;WIN32;_WIN32;__WINDOWS__;_HAS_EXCEPTIONS=0;WIN64;DEBUG;PROFILING_ENABLED;JULIET_ENABLE_IMGUI;JULIET_DEBUG;IMGUI_API=__declspec(dllexport); ..\;imgui;imgui\backends;C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.44.35207\include\;C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\ucrt;C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\um;C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\shared; /std:c++20 /wd5267 /wd4061 /wd4505 /wd4514 /wd4577 /wd4625 /wd4710 /wd4711 /wd4746 /wd4820 /wd5045 /wd5220 /wd5245 /wd4365 /wd5219 $(SolutionDir)\bin\$(Configuration)\ @@ -226,7 +226,7 @@ cd $(SolutionDir) & misc\fbuild -ide -dist -monitor -cache $(ProjectName)-$(Configuration) cd $(SolutionDir) & misc\fbuild -ide -dist -monitor -cache -clean $(ProjectName)-$(Configuration) - _CRT_SECURE_NO_WARNINGS;_UNICODE;UNICODE;WIN32_LEAN_AND_MEAN;WIN32;_WIN32;__WINDOWS__;_HAS_EXCEPTIONS=0;WIN64;DEBUG;PROFILING_ENABLED;JULIET_ENABLE_IMGUI;IMGUI_API=__declspec(dllexport); + _CRT_SECURE_NO_WARNINGS;_UNICODE;UNICODE;WIN32_LEAN_AND_MEAN;WIN32;_WIN32;__WINDOWS__;_HAS_EXCEPTIONS=0;WIN64;DEBUG;PROFILING_ENABLED;JULIET_ENABLE_IMGUI;JULIET_DEBUG;IMGUI_API=__declspec(dllexport); ..\;imgui;imgui\backends;C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.44.35207\include\;C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\ucrt;C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\um;C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\shared; /std:c++20 /wd5267 /wd4061 /wd4505 /wd4514 /wd4577 /wd4625 /wd4710 /wd4711 /wd4746 /wd4820 /wd5045 /wd5220 /wd5245 /wd4365 /wd5219 $(SolutionDir)\bin\$(Configuration)\ diff --git a/Game/Game.vcxproj b/Game/Game.vcxproj index 39a02b8..8268a04 100644 --- a/Game/Game.vcxproj +++ b/Game/Game.vcxproj @@ -257,7 +257,7 @@ cd $(SolutionDir) & misc\fbuild -ide -dist -monitor -cache $(ProjectName)-$(Configuration) cd $(SolutionDir) & misc\fbuild -ide -dist -monitor -cache -clean $(ProjectName)-$(Configuration) - _CRT_SECURE_NO_WARNINGS;_UNICODE;UNICODE;WIN32_LEAN_AND_MEAN;WIN32;_WIN32;__WINDOWS__;_HAS_EXCEPTIONS=0;WIN64;DEBUG;PROFILING_ENABLED;JULIET_ENABLE_IMGUI;IMGUI_API=__declspec(dllexport); + _CRT_SECURE_NO_WARNINGS;_UNICODE;UNICODE;WIN32_LEAN_AND_MEAN;WIN32;_WIN32;__WINDOWS__;_HAS_EXCEPTIONS=0;WIN64;DEBUG;PROFILING_ENABLED;JULIET_ENABLE_IMGUI;JULIET_DEBUG;IMGUI_API=__declspec(dllexport); ..\;..\External\imgui;..\External\imgui\backends;C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.44.35207\include\;C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\ucrt;C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\um;C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\shared; /std:c++20 /wd5267 /wd4061 /wd4505 /wd4514 /wd4577 /wd4625 /wd4710 /wd4711 /wd4746 /wd4820 /wd5045 /wd5220 /wd5245 /wd4365 /wd5219 $(SolutionDir)\bin\$(Configuration)\ @@ -287,7 +287,7 @@ cd $(SolutionDir) & misc\fbuild -ide -dist -monitor -cache $(ProjectName)-$(Configuration) cd $(SolutionDir) & misc\fbuild -ide -dist -monitor -cache -clean $(ProjectName)-$(Configuration) - _CRT_SECURE_NO_WARNINGS;_UNICODE;UNICODE;WIN32_LEAN_AND_MEAN;WIN32;_WIN32;__WINDOWS__;_HAS_EXCEPTIONS=0;WIN64;DEBUG;PROFILING_ENABLED;JULIET_ENABLE_IMGUI;IMGUI_API=__declspec(dllexport); + _CRT_SECURE_NO_WARNINGS;_UNICODE;UNICODE;WIN32_LEAN_AND_MEAN;WIN32;_WIN32;__WINDOWS__;_HAS_EXCEPTIONS=0;WIN64;DEBUG;PROFILING_ENABLED;JULIET_ENABLE_IMGUI;JULIET_DEBUG;IMGUI_API=__declspec(dllexport); ..\;..\External\imgui;..\External\imgui\backends;C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.44.35207\include\;C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\ucrt;C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\um;C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\shared; /std:c++20 /wd5267 /wd4061 /wd4505 /wd4514 /wd4577 /wd4625 /wd4710 /wd4711 /wd4746 /wd4820 /wd5045 /wd5220 /wd5245 /wd4365 /wd5219 $(SolutionDir)\bin\$(Configuration)\ @@ -317,7 +317,7 @@ cd $(SolutionDir) & misc\fbuild -ide -dist -monitor -cache $(ProjectName)-$(Configuration) cd $(SolutionDir) & misc\fbuild -ide -dist -monitor -cache -clean $(ProjectName)-$(Configuration) - _CRT_SECURE_NO_WARNINGS;_UNICODE;UNICODE;WIN32_LEAN_AND_MEAN;WIN32;_WIN32;__WINDOWS__;_HAS_EXCEPTIONS=0;WIN64;DEBUG;PROFILING_ENABLED;JULIET_ENABLE_IMGUI;JULIET_EXPORT;JULIET_WIN32; + _CRT_SECURE_NO_WARNINGS;_UNICODE;UNICODE;WIN32_LEAN_AND_MEAN;WIN32;_WIN32;__WINDOWS__;_HAS_EXCEPTIONS=0;WIN64;DEBUG;PROFILING_ENABLED;JULIET_ENABLE_IMGUI;JULIET_DEBUG;JULIET_EXPORT;JULIET_WIN32; ..\;..\Juliet\include;..\Juliet\src;..\External\imgui;..\External\imgui\backends;C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.44.35207\include\;C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\ucrt;C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\um;C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\shared; /std:c++20 /wd5267 /wd4061 /wd4505 /wd4514 /wd4577 /wd4625 /wd4710 /wd4711 /wd4746 /wd4820 /wd5045 /wd5220 /wd5245 $(SolutionDir)\bin\$(Configuration)\ @@ -347,7 +347,7 @@ cd $(SolutionDir) & misc\fbuild -ide -dist -monitor -cache $(ProjectName)-$(Configuration) cd $(SolutionDir) & misc\fbuild -ide -dist -monitor -cache -clean $(ProjectName)-$(Configuration) - _CRT_SECURE_NO_WARNINGS;_UNICODE;UNICODE;WIN32_LEAN_AND_MEAN;WIN32;_WIN32;__WINDOWS__;_HAS_EXCEPTIONS=0;WIN64;DEBUG;PROFILING_ENABLED;JULIET_ENABLE_IMGUI;JULIET_EXPORT;JULIET_WIN32; + _CRT_SECURE_NO_WARNINGS;_UNICODE;UNICODE;WIN32_LEAN_AND_MEAN;WIN32;_WIN32;__WINDOWS__;_HAS_EXCEPTIONS=0;WIN64;DEBUG;PROFILING_ENABLED;JULIET_ENABLE_IMGUI;JULIET_DEBUG;JULIET_EXPORT;JULIET_WIN32; ..\;..\Juliet\include;..\Juliet\src;..\External\imgui;..\External\imgui\backends;C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.44.35207\include\;C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\ucrt;C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\um;C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\shared; /std:c++20 /wd5267 /wd4061 /wd4505 /wd4514 /wd4577 /wd4625 /wd4710 /wd4711 /wd4746 /wd4820 /wd5045 /wd5220 /wd5245 $(SolutionDir)\bin\$(Configuration)\ @@ -377,7 +377,7 @@ cd $(SolutionDir) & misc\fbuild -ide -dist -monitor -cache $(ProjectName)-$(Configuration) cd $(SolutionDir) & misc\fbuild -ide -dist -monitor -cache -clean $(ProjectName)-$(Configuration) - _CRT_SECURE_NO_WARNINGS;_UNICODE;UNICODE;WIN32_LEAN_AND_MEAN;WIN32;_WIN32;__WINDOWS__;_HAS_EXCEPTIONS=0;WIN64;DEBUG;PROFILING_ENABLED;JULIET_ENABLE_IMGUI;JULIET_EXPORT;JULIET_WIN32; + _CRT_SECURE_NO_WARNINGS;_UNICODE;UNICODE;WIN32_LEAN_AND_MEAN;WIN32;_WIN32;__WINDOWS__;_HAS_EXCEPTIONS=0;WIN64;DEBUG;PROFILING_ENABLED;JULIET_ENABLE_IMGUI;JULIET_DEBUG;JULIET_EXPORT;JULIET_WIN32; ..\;..\Juliet\include;..\Game;C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.44.35207\include\;C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\ucrt;C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\um;C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\shared; /std:c++20 /wd5267 /wd4061 /wd4505 /wd4514 /wd4577 /wd4625 /wd4710 /wd4711 /wd4746 /wd4820 /wd5045 /wd5220 /wd5245 $(SolutionDir)\bin\$(Configuration)\ @@ -407,7 +407,7 @@ cd $(SolutionDir) & misc\fbuild -ide -dist -monitor -cache $(ProjectName)-$(Configuration) cd $(SolutionDir) & misc\fbuild -ide -dist -monitor -cache -clean $(ProjectName)-$(Configuration) - _CRT_SECURE_NO_WARNINGS;_UNICODE;UNICODE;WIN32_LEAN_AND_MEAN;WIN32;_WIN32;__WINDOWS__;_HAS_EXCEPTIONS=0;WIN64;DEBUG;PROFILING_ENABLED;JULIET_ENABLE_IMGUI;JULIET_EXPORT;JULIET_WIN32; + _CRT_SECURE_NO_WARNINGS;_UNICODE;UNICODE;WIN32_LEAN_AND_MEAN;WIN32;_WIN32;__WINDOWS__;_HAS_EXCEPTIONS=0;WIN64;DEBUG;PROFILING_ENABLED;JULIET_ENABLE_IMGUI;JULIET_DEBUG;JULIET_EXPORT;JULIET_WIN32; ..\;..\Juliet\include;..\Game;C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.44.35207\include\;C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\ucrt;C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\um;C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\shared; /std:c++20 /wd5267 /wd4061 /wd4505 /wd4514 /wd4577 /wd4625 /wd4710 /wd4711 /wd4746 /wd4820 /wd5045 /wd5220 /wd5245 $(SolutionDir)\bin\$(Configuration)\ diff --git a/Juliet/Juliet.vcxproj b/Juliet/Juliet.vcxproj index 2e691f3..a8e099e 100644 --- a/Juliet/Juliet.vcxproj +++ b/Juliet/Juliet.vcxproj @@ -343,7 +343,7 @@ cd $(SolutionDir) & misc\fbuild -ide -dist -monitor -cache $(ProjectName)-$(Configuration) cd $(SolutionDir) & misc\fbuild -ide -dist -monitor -cache -clean $(ProjectName)-$(Configuration) - _CRT_SECURE_NO_WARNINGS;_UNICODE;UNICODE;WIN32_LEAN_AND_MEAN;WIN32;_WIN32;__WINDOWS__;_HAS_EXCEPTIONS=0;WIN64;DEBUG;PROFILING_ENABLED;JULIET_ENABLE_IMGUI;IMGUI_API=__declspec(dllexport); + _CRT_SECURE_NO_WARNINGS;_UNICODE;UNICODE;WIN32_LEAN_AND_MEAN;WIN32;_WIN32;__WINDOWS__;_HAS_EXCEPTIONS=0;WIN64;DEBUG;PROFILING_ENABLED;JULIET_ENABLE_IMGUI;JULIET_DEBUG;IMGUI_API=__declspec(dllexport); ..\;..\External\imgui;..\External\imgui\backends;C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.44.35207\include\;C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\ucrt;C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\um;C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\shared; /std:c++20 /wd5267 /wd4061 /wd4505 /wd4514 /wd4577 /wd4625 /wd4710 /wd4711 /wd4746 /wd4820 /wd5045 /wd5220 /wd5245 /wd4365 /wd5219 $(SolutionDir)\bin\$(Configuration)\ @@ -373,7 +373,7 @@ cd $(SolutionDir) & misc\fbuild -ide -dist -monitor -cache $(ProjectName)-$(Configuration) cd $(SolutionDir) & misc\fbuild -ide -dist -monitor -cache -clean $(ProjectName)-$(Configuration) - _CRT_SECURE_NO_WARNINGS;_UNICODE;UNICODE;WIN32_LEAN_AND_MEAN;WIN32;_WIN32;__WINDOWS__;_HAS_EXCEPTIONS=0;WIN64;DEBUG;PROFILING_ENABLED;JULIET_ENABLE_IMGUI;IMGUI_API=__declspec(dllexport); + _CRT_SECURE_NO_WARNINGS;_UNICODE;UNICODE;WIN32_LEAN_AND_MEAN;WIN32;_WIN32;__WINDOWS__;_HAS_EXCEPTIONS=0;WIN64;DEBUG;PROFILING_ENABLED;JULIET_ENABLE_IMGUI;JULIET_DEBUG;IMGUI_API=__declspec(dllexport); ..\;..\External\imgui;..\External\imgui\backends;C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.44.35207\include\;C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\ucrt;C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\um;C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\shared; /std:c++20 /wd5267 /wd4061 /wd4505 /wd4514 /wd4577 /wd4625 /wd4710 /wd4711 /wd4746 /wd4820 /wd5045 /wd5220 /wd5245 /wd4365 /wd5219 $(SolutionDir)\bin\$(Configuration)\ @@ -403,7 +403,7 @@ cd $(SolutionDir) & misc\fbuild -ide -dist -monitor -cache $(ProjectName)-$(Configuration) cd $(SolutionDir) & misc\fbuild -ide -dist -monitor -cache -clean $(ProjectName)-$(Configuration) - _CRT_SECURE_NO_WARNINGS;_UNICODE;UNICODE;WIN32_LEAN_AND_MEAN;WIN32;_WIN32;__WINDOWS__;_HAS_EXCEPTIONS=0;WIN64;DEBUG;PROFILING_ENABLED;JULIET_ENABLE_IMGUI;JULIET_EXPORT;JULIET_WIN32; + _CRT_SECURE_NO_WARNINGS;_UNICODE;UNICODE;WIN32_LEAN_AND_MEAN;WIN32;_WIN32;__WINDOWS__;_HAS_EXCEPTIONS=0;WIN64;DEBUG;PROFILING_ENABLED;JULIET_ENABLE_IMGUI;JULIET_DEBUG;JULIET_EXPORT;JULIET_WIN32; ..\;include;src;..\External\imgui;..\External\imgui\backends;C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.44.35207\include\;C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\ucrt;C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\um;C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\shared; /std:c++20 /wd5267 /wd4061 /wd4505 /wd4514 /wd4577 /wd4625 /wd4710 /wd4711 /wd4746 /wd4820 /wd5045 /wd5220 /wd5245 $(SolutionDir)\bin\$(Configuration)\ @@ -433,7 +433,7 @@ cd $(SolutionDir) & misc\fbuild -ide -dist -monitor -cache $(ProjectName)-$(Configuration) cd $(SolutionDir) & misc\fbuild -ide -dist -monitor -cache -clean $(ProjectName)-$(Configuration) - _CRT_SECURE_NO_WARNINGS;_UNICODE;UNICODE;WIN32_LEAN_AND_MEAN;WIN32;_WIN32;__WINDOWS__;_HAS_EXCEPTIONS=0;WIN64;DEBUG;PROFILING_ENABLED;JULIET_ENABLE_IMGUI;JULIET_EXPORT;JULIET_WIN32; + _CRT_SECURE_NO_WARNINGS;_UNICODE;UNICODE;WIN32_LEAN_AND_MEAN;WIN32;_WIN32;__WINDOWS__;_HAS_EXCEPTIONS=0;WIN64;DEBUG;PROFILING_ENABLED;JULIET_ENABLE_IMGUI;JULIET_DEBUG;JULIET_EXPORT;JULIET_WIN32; ..\;include;src;..\External\imgui;..\External\imgui\backends;C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.44.35207\include\;C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\ucrt;C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\um;C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\shared; /std:c++20 /wd5267 /wd4061 /wd4505 /wd4514 /wd4577 /wd4625 /wd4710 /wd4711 /wd4746 /wd4820 /wd5045 /wd5220 /wd5245 $(SolutionDir)\bin\$(Configuration)\ diff --git a/Juliet/include/Core/Container/Vector.h b/Juliet/include/Core/Container/Vector.h index ba529be..f35e46c 100644 --- a/Juliet/include/Core/Container/Vector.h +++ b/Juliet/include/Core/Container/Vector.h @@ -37,7 +37,10 @@ namespace Juliet void Destroy() { - ArenaRelease(Arena); + if (InternalArena) + { + ArenaRelease(Arena); + } DataFirst = DataLast = nullptr; Count = 0; Capacity = 0; @@ -52,9 +55,11 @@ namespace Juliet { Data = ArenaPushArray(Arena, newCapacity); } - else if (AllowRealloc && InternalArena) + else if (AllowRealloc && !InternalArena) { - Data = static_cast(ArenaReallocate(Arena, Data, Capacity, newCapacity, AlignOf(Type), true)); + DataFirst = Data = static_cast(ArenaReallocate(Arena, Data, Capacity * sizeof(Type), + newCapacity * sizeof(Type), AlignOf(Type), true)); + DataLast = Data + Count - 1; } Capacity = newCapacity; } @@ -62,20 +67,36 @@ namespace Juliet void Resize(size_t newCount) { - Type* entry = ArenaPushArray(Arena, newCount); - Count = newCount; - DataFirst = entry; - DataLast = entry + newCount; + if (newCount == Count) + { + return; + } + + if (newCount > Capacity) + { + Reserve(newCount); + } + + Count = newCount; + + if (Count > 0) + { + DataFirst = Data; + DataLast = Data + Count - 1; + } + else + { + DataFirst = DataLast = nullptr; + } } void PushBack(const Type& value) { Assert(Arena); - if (Count + 1 == Capacity) + if (Count + 1 > Capacity) { - Assert(AllowRealloc); - Reserve(Capacity * 2); + Reserve(Capacity == 0 ? ReserveSize : Capacity * 2); } Type* entry = Data + Count; @@ -93,10 +114,9 @@ namespace Juliet { Assert(Arena); - if (Count + 1 == Capacity) + if (Count + 1 > Capacity) { - Assert(AllowRealloc); - Reserve(Capacity * 2); + Reserve(Capacity == 0 ? ReserveSize : Capacity * 2); } Type* entry = Data + Count; @@ -139,7 +159,9 @@ namespace Juliet ArenaClear(Arena); DataFirst = DataLast = nullptr; + Data = nullptr; Count = 0; + Capacity = 0; } // C++ Accessors for loop supports and Index based access diff --git a/Juliet/include/Core/Main.h b/Juliet/include/Core/Main.h index 31e0b03..4ae14fd 100644 --- a/Juliet/include/Core/Main.h +++ b/Juliet/include/Core/Main.h @@ -9,7 +9,6 @@ extern int JulietMain(int, wchar_t**); #define WINAPI __stdcall #endif -#if COMPILER_MSVC #if UNICODE int wmain(int argc, wchar_t** argv) { @@ -21,7 +20,6 @@ int main(int argc, char** argv) return Juliet::Bootstrap(JulietMain, argc, argv); } #endif -#endif extern "C" { diff --git a/Juliet/src/Core/Memory/MemoryArena.cpp b/Juliet/src/Core/Memory/MemoryArena.cpp index 50487aa..e2d534d 100644 --- a/Juliet/src/Core/Memory/MemoryArena.cpp +++ b/Juliet/src/Core/Memory/MemoryArena.cpp @@ -219,7 +219,8 @@ namespace Juliet Arena* block = nullptr; for (block = arena->Current; block != nullptr; block = block->Previous) { - if ((block < oldPtr) && (oldPtr <= (block + block->Reserved))) + if ((reinterpret_cast(block) < static_cast(oldPtr)) && + (static_cast(oldPtr) <= (reinterpret_cast(block) + block->Reserved))) { break; } @@ -227,26 +228,25 @@ namespace Juliet Assert(block != nullptr); // Copy old to new - MemCopy(result, oldPtr, oldSize); + MemCopy(result, oldPtr, std::min(oldSize, newSize)); // Zero the old memory MemoryZero(oldPtr, oldSize); - ArenaFreeNode* freeNode = static_cast(oldPtr); - ptrdiff_t posPtr = static_cast(oldPtr) - reinterpret_cast(block); - index_t position = static_cast(posPtr) - block->BasePosition; - freeNode->Position = position; - freeNode->Size = oldSize; - if (block->FreeNodes != nullptr) + if (oldSize >= sizeof(ArenaFreeNode)) { - block->FreeNodes = freeNode; - } - else - { - freeNode->Previous = block->FreeNodes; - if (block->FreeNodes != nullptr) + ArenaFreeNode* freeNode = static_cast(oldPtr); + ptrdiff_t posPtr = static_cast(oldPtr) - reinterpret_cast(block); + index_t position = static_cast(posPtr); + freeNode->Position = position; + freeNode->Size = oldSize; + + // Insert at head of the free list + freeNode->Next = block->FreeNodes; + freeNode->Previous = nullptr; + if (block->FreeNodes) { - block->FreeNodes->Next = freeNode; + block->FreeNodes->Previous = freeNode; } block->FreeNodes = freeNode; } diff --git a/Juliet/src/Core/Memory/MemoryArenaTests.cpp b/Juliet/src/Core/Memory/MemoryArenaTests.cpp index b25563c..1f1083f 100644 --- a/Juliet/src/Core/Memory/MemoryArenaTests.cpp +++ b/Juliet/src/Core/Memory/MemoryArenaTests.cpp @@ -136,6 +136,41 @@ namespace Juliet::UnitTest ArenaRelease(arena); } + { + // Test Reallocate Shrink (Buffer Overflow Bug Check) + Arena* arena = ArenaAllocate({ .AllowRealloc = true }); + + size_t largeSize = 100; + char* large = ArenaPushArray(arena, largeSize); + MemSet(large, 'A', largeSize); + + size_t smallSize = 50; + char* smallData = static_cast(ArenaReallocate(arena, large, largeSize, smallSize, alignof(char), true)); + + for (size_t i = 0; i < smallSize; ++i) + { + Assert(smallData[i] == 'A'); + } + + // Allocate next block (should be immediately after 'small') + // Don't zero it, if overflow happened it will contain 'A's + char* next = static_cast(ArenaPush(arena, 50, alignof(char), false)); + + bool corrupted = false; + for(size_t i = 0; i < 50; ++i) + { + if (next[i] == 'A') + { + corrupted = true; + break; + } + } + + Assert(!corrupted); + + ArenaRelease(arena); + } + printf("All Paged MemoryArena tests passed.\n"); } } // namespace Juliet::UnitTest diff --git a/Juliet/src/UnitTest/Container/VectorUnitTest.cpp b/Juliet/src/UnitTest/Container/VectorUnitTest.cpp index 4cabdaf..d7c80c9 100644 --- a/Juliet/src/UnitTest/Container/VectorUnitTest.cpp +++ b/Juliet/src/UnitTest/Container/VectorUnitTest.cpp @@ -9,8 +9,8 @@ namespace Juliet { namespace { - template - inline void VerifyVectorState(const VectorArena& vec, size_t expectedCount) + template + inline void VerifyVectorState(const VectorArena& vec, size_t expectedCount) { Assert(vec.Size() == expectedCount); @@ -29,7 +29,7 @@ namespace Juliet void VectorUnitTest() { - // Test 1: Integer VectorArena + // Test 1: Integer VectorArena (Basic Operations) { VectorArena vec = {}; vec.Create(); @@ -92,7 +92,7 @@ namespace Juliet vec.Destroy(); } - // Test 3: Clear and Reuse + // Test 3: Clear and Reuse (Pointer State Check) { VectorArena vec = {}; vec.Create(); @@ -102,7 +102,7 @@ namespace Juliet VerifyVectorState(vec, 2); vec.Clear(); - VerifyVectorState(vec, 0); + VerifyVectorState(vec, 0); // Should verify begin/end are nullptr vec.PushBack(300); VerifyVectorState(vec, 1); @@ -145,52 +145,147 @@ namespace Juliet vec.Destroy(); } - // Test 5: Add 2, Remove 2 -> Expect nullptr + // Test 5: Reallocation Support (AllowRealloc = true) { - VectorArena vec = {}; - vec.Create(); + // Initial capacity 4, allow realloc + ArenaParams params{ .AllowRealloc = true }; + Arena* externalArena = ArenaAllocate(params); + + VectorArena vec = {}; + vec.Create(externalArena); + + Assert(vec.Capacity == 4); vec.PushBack(1); vec.PushBack(2); - VerifyVectorState(vec, 2); + vec.PushBack(3); + vec.PushBack(4); + Assert(vec.Capacity == 4); - vec.RemoveAtFast(0); - vec.RemoveAtFast(0); - VerifyVectorState(vec, 0); + // Trigger realloc + vec.PushBack(5); + Assert(vec.Capacity >= 5); // Should have grown (likely doubled to 8) + VerifyVectorState(vec, 5); + + Assert(vec[0] == 1); + Assert(vec[1] == 2); + Assert(vec[2] == 3); + Assert(vec[3] == 4); + Assert(vec[4] == 5); vec.Destroy(); } - // Test 6: Volume Test (100 items) + // Test 6: Move Semantics { + struct MoveOnly + { + int Value; + bool MovedFrom = false; + + MoveOnly(int v) : Value(v) {} + MoveOnly(const MoveOnly&) = delete; // No copy + [[maybe_unused]] MoveOnly(MoveOnly&& other) noexcept : Value(other.Value), MovedFrom(false) + { + other.MovedFrom = true; + other.Value = -1; + } + MoveOnly& operator=(const MoveOnly&) = delete; + [[maybe_unused]] MoveOnly& operator=(MoveOnly&& other) noexcept + { + Value = other.Value; + MovedFrom = false; + other.MovedFrom = true; + other.Value = -1; + return *this; + } + }; + + VectorArena vec = {}; + ArenaParams params{ .AllowRealloc = true }; + Arena* externalArena = ArenaAllocate(params); + NonNullPtr validArena(externalArena); + vec.Create(validArena); + + MoveOnly item1(10); + vec.PushBack(std::move(item1)); + + Assert(item1.MovedFrom); // Verify original was moved from + Assert(vec.Size() == 1); + Assert(vec[0].Value == 10); + Assert(!vec[0].MovedFrom); + + vec.Destroy(); + } + + // Test 7: Resize Behavior + { + ArenaParams params{ .AllowRealloc = true }; + Arena* externalArena = ArenaAllocate(params); + NonNullPtr validArena(externalArena); + + VectorArena vec = {}; + vec.Create(validArena); + + vec.PushBack(1); + vec.PushBack(2); + Assert(vec.Size() == 2); + + // Resize smaller + vec.Resize(1); + Assert(vec.Size() == 1); + Assert(vec[0] == 1); + + // Resize larger + vec.Resize(4); + Assert(vec.Size() == 4); + Assert(vec[0] == 1); + // Verify new elements are NOT necessarily zero-initialized (garbage or previous memory). + // We only check size and preserved data. + // Assert(vec[1] == 0); + // Assert(vec[2] == 0); + // Assert(vec[3] == 0); + + vec.Destroy(); + } + + // Test 8: External Arena Usage + { + ArenaParams params{ .AllowRealloc = true }; + Arena* externalArena = ArenaAllocate(params); + NonNullPtr validArena(externalArena); + VectorArena vec = {}; - vec.Create(); + vec.Create(validArena); // Pass external arena - VerifyVectorState(vec, 0); + vec.PushBack(42); + Assert(vec.Size() == 1); + Assert(vec[0] == 42); - // Push 100 items + vec.Destroy(); + } + + // Test 9: Volume Test (100 items with Realloc) + { + ArenaParams params{ .AllowRealloc = true }; + Arena* externalArena = ArenaAllocate(params); + NonNullPtr validArena(externalArena); + + VectorArena vec = {}; + vec.Create(validArena); + + // Push 100 items -> Should realloc multiple times for (int i = 0; i < 100; ++i) { - vec.PushBack(static_cast(i)); + vec.PushBack(i); } VerifyVectorState(vec, 100); - // Verify content for (int i = 0; i < 100; ++i) { Assert(vec[static_cast(i)] == i); } - // Remove 50 items from front (causing swaps) - for (int i = 0; i < 50; ++i) - { - vec.RemoveAtFast(0); - } - VerifyVectorState(vec, 50); - - vec.Clear(); - VerifyVectorState(vec, 0); - vec.Destroy(); } } diff --git a/JulietApp/JulietApp.bff b/JulietApp/JulietApp.bff index 4c22f30..e3675ba 100644 --- a/JulietApp/JulietApp.bff +++ b/JulietApp/JulietApp.bff @@ -84,7 +84,7 @@ .SubSystem = ' /SUBSYSTEM:WINDOWS' If ( .BuildConfigName == 'Debug' ) { - ^SubSystem = ' /SUBSYSTEM:WINDOWS' // We use console in debug + ^SubSystem = ' /SUBSYSTEM:CONSOLE' // We use console in debug } .LinkerOptions + .SubSystem diff --git a/JulietApp/JulietApp.vcxproj b/JulietApp/JulietApp.vcxproj index f39cb79..4358ef9 100644 --- a/JulietApp/JulietApp.vcxproj +++ b/JulietApp/JulietApp.vcxproj @@ -333,7 +333,7 @@ cd $(SolutionDir) & misc\fbuild -ide -dist -monitor -cache $(ProjectName)-$(Configuration) cd $(SolutionDir) & misc\fbuild -ide -dist -monitor -cache -clean $(ProjectName)-$(Configuration) - _CRT_SECURE_NO_WARNINGS;_UNICODE;UNICODE;WIN32_LEAN_AND_MEAN;WIN32;_WIN32;__WINDOWS__;_HAS_EXCEPTIONS=0;WIN64;DEBUG;PROFILING_ENABLED;JULIET_ENABLE_IMGUI;IMGUI_API=__declspec(dllexport); + _CRT_SECURE_NO_WARNINGS;_UNICODE;UNICODE;WIN32_LEAN_AND_MEAN;WIN32;_WIN32;__WINDOWS__;_HAS_EXCEPTIONS=0;WIN64;DEBUG;PROFILING_ENABLED;JULIET_ENABLE_IMGUI;JULIET_DEBUG;IMGUI_API=__declspec(dllexport); ..\;..\External\imgui;..\External\imgui\backends;C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.44.35207\include\;C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\ucrt;C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\um;C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\shared; /std:c++20 /wd5267 /wd4061 /wd4505 /wd4514 /wd4577 /wd4625 /wd4710 /wd4711 /wd4746 /wd4820 /wd5045 /wd5220 /wd5245 /wd4365 /wd5219 $(SolutionDir)\bin\$(Configuration)\ @@ -363,7 +363,7 @@ cd $(SolutionDir) & misc\fbuild -ide -dist -monitor -cache $(ProjectName)-$(Configuration) cd $(SolutionDir) & misc\fbuild -ide -dist -monitor -cache -clean $(ProjectName)-$(Configuration) - _CRT_SECURE_NO_WARNINGS;_UNICODE;UNICODE;WIN32_LEAN_AND_MEAN;WIN32;_WIN32;__WINDOWS__;_HAS_EXCEPTIONS=0;WIN64;DEBUG;PROFILING_ENABLED;JULIET_ENABLE_IMGUI;IMGUI_API=__declspec(dllexport); + _CRT_SECURE_NO_WARNINGS;_UNICODE;UNICODE;WIN32_LEAN_AND_MEAN;WIN32;_WIN32;__WINDOWS__;_HAS_EXCEPTIONS=0;WIN64;DEBUG;PROFILING_ENABLED;JULIET_ENABLE_IMGUI;JULIET_DEBUG;IMGUI_API=__declspec(dllexport); ..\;..\External\imgui;..\External\imgui\backends;C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.44.35207\include\;C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\ucrt;C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\um;C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\shared; /std:c++20 /wd5267 /wd4061 /wd4505 /wd4514 /wd4577 /wd4625 /wd4710 /wd4711 /wd4746 /wd4820 /wd5045 /wd5220 /wd5245 /wd4365 /wd5219 $(SolutionDir)\bin\$(Configuration)\ @@ -393,7 +393,7 @@ cd $(SolutionDir) & misc\fbuild -ide -dist -monitor -cache $(ProjectName)-$(Configuration) cd $(SolutionDir) & misc\fbuild -ide -dist -monitor -cache -clean $(ProjectName)-$(Configuration) - _CRT_SECURE_NO_WARNINGS;_UNICODE;UNICODE;WIN32_LEAN_AND_MEAN;WIN32;_WIN32;__WINDOWS__;_HAS_EXCEPTIONS=0;WIN64;DEBUG;PROFILING_ENABLED;JULIET_ENABLE_IMGUI;JULIET_EXPORT;JULIET_WIN32; + _CRT_SECURE_NO_WARNINGS;_UNICODE;UNICODE;WIN32_LEAN_AND_MEAN;WIN32;_WIN32;__WINDOWS__;_HAS_EXCEPTIONS=0;WIN64;DEBUG;PROFILING_ENABLED;JULIET_ENABLE_IMGUI;JULIET_DEBUG;JULIET_EXPORT;JULIET_WIN32; ..\;..\Juliet\include;..\Juliet\src;..\External\imgui;..\External\imgui\backends;C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.44.35207\include\;C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\ucrt;C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\um;C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\shared; /std:c++20 /wd5267 /wd4061 /wd4505 /wd4514 /wd4577 /wd4625 /wd4710 /wd4711 /wd4746 /wd4820 /wd5045 /wd5220 /wd5245 $(SolutionDir)\bin\$(Configuration)\ @@ -423,7 +423,7 @@ cd $(SolutionDir) & misc\fbuild -ide -dist -monitor -cache $(ProjectName)-$(Configuration) cd $(SolutionDir) & misc\fbuild -ide -dist -monitor -cache -clean $(ProjectName)-$(Configuration) - _CRT_SECURE_NO_WARNINGS;_UNICODE;UNICODE;WIN32_LEAN_AND_MEAN;WIN32;_WIN32;__WINDOWS__;_HAS_EXCEPTIONS=0;WIN64;DEBUG;PROFILING_ENABLED;JULIET_ENABLE_IMGUI;JULIET_EXPORT;JULIET_WIN32; + _CRT_SECURE_NO_WARNINGS;_UNICODE;UNICODE;WIN32_LEAN_AND_MEAN;WIN32;_WIN32;__WINDOWS__;_HAS_EXCEPTIONS=0;WIN64;DEBUG;PROFILING_ENABLED;JULIET_ENABLE_IMGUI;JULIET_DEBUG;JULIET_EXPORT;JULIET_WIN32; ..\;..\Juliet\include;..\Juliet\src;..\External\imgui;..\External\imgui\backends;C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.44.35207\include\;C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\ucrt;C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\um;C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\shared; /std:c++20 /wd5267 /wd4061 /wd4505 /wd4514 /wd4577 /wd4625 /wd4710 /wd4711 /wd4746 /wd4820 /wd5045 /wd5220 /wd5245 $(SolutionDir)\bin\$(Configuration)\ @@ -453,7 +453,7 @@ cd $(SolutionDir) & misc\fbuild -ide -dist -monitor -cache $(ProjectName)-$(Configuration) cd $(SolutionDir) & misc\fbuild -ide -dist -monitor -cache -clean $(ProjectName)-$(Configuration) - _CRT_SECURE_NO_WARNINGS;_UNICODE;UNICODE;WIN32_LEAN_AND_MEAN;WIN32;_WIN32;__WINDOWS__;_HAS_EXCEPTIONS=0;WIN64;DEBUG;PROFILING_ENABLED;JULIET_ENABLE_IMGUI;JULIET_EXPORT;JULIET_WIN32; + _CRT_SECURE_NO_WARNINGS;_UNICODE;UNICODE;WIN32_LEAN_AND_MEAN;WIN32;_WIN32;__WINDOWS__;_HAS_EXCEPTIONS=0;WIN64;DEBUG;PROFILING_ENABLED;JULIET_ENABLE_IMGUI;JULIET_DEBUG;JULIET_EXPORT;JULIET_WIN32; ..\;..\Juliet\include;..\Game;C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.44.35207\include\;C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\ucrt;C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\um;C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\shared; /std:c++20 /wd5267 /wd4061 /wd4505 /wd4514 /wd4577 /wd4625 /wd4710 /wd4711 /wd4746 /wd4820 /wd5045 /wd5220 /wd5245 $(SolutionDir)\bin\$(Configuration)\ @@ -483,7 +483,7 @@ cd $(SolutionDir) & misc\fbuild -ide -dist -monitor -cache $(ProjectName)-$(Configuration) cd $(SolutionDir) & misc\fbuild -ide -dist -monitor -cache -clean $(ProjectName)-$(Configuration) - _CRT_SECURE_NO_WARNINGS;_UNICODE;UNICODE;WIN32_LEAN_AND_MEAN;WIN32;_WIN32;__WINDOWS__;_HAS_EXCEPTIONS=0;WIN64;DEBUG;PROFILING_ENABLED;JULIET_ENABLE_IMGUI;JULIET_EXPORT;JULIET_WIN32; + _CRT_SECURE_NO_WARNINGS;_UNICODE;UNICODE;WIN32_LEAN_AND_MEAN;WIN32;_WIN32;__WINDOWS__;_HAS_EXCEPTIONS=0;WIN64;DEBUG;PROFILING_ENABLED;JULIET_ENABLE_IMGUI;JULIET_DEBUG;JULIET_EXPORT;JULIET_WIN32; ..\;..\Juliet\include;..\Game;C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.44.35207\include\;C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\ucrt;C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\um;C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\shared; /std:c++20 /wd5267 /wd4061 /wd4505 /wd4514 /wd4577 /wd4625 /wd4710 /wd4711 /wd4746 /wd4820 /wd5045 /wd5220 /wd5245 $(SolutionDir)\bin\$(Configuration)\ @@ -513,7 +513,7 @@ cd $(SolutionDir) & misc\fbuild -ide -dist -monitor -cache $(ProjectName)-$(Configuration) cd $(SolutionDir) & misc\fbuild -ide -dist -monitor -cache -clean $(ProjectName)-$(Configuration) - _CRT_SECURE_NO_WARNINGS;_UNICODE;UNICODE;WIN32_LEAN_AND_MEAN;WIN32;_WIN32;__WINDOWS__;_HAS_EXCEPTIONS=0;WIN64;DEBUG;PROFILING_ENABLED;JULIET_ENABLE_IMGUI;JULIET_WIN32; + _CRT_SECURE_NO_WARNINGS;_UNICODE;UNICODE;WIN32_LEAN_AND_MEAN;WIN32;_WIN32;__WINDOWS__;_HAS_EXCEPTIONS=0;WIN64;DEBUG;PROFILING_ENABLED;JULIET_ENABLE_IMGUI;JULIET_DEBUG;JULIET_WIN32; ..\;..\Juliet\include;..\Juliet\src;..\External\imgui;C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.44.35207\include\;C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\ucrt;C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\um;C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\shared; /std:c++20 /wd5267 /wd4061 /wd4505 /wd4514 /wd4577 /wd4625 /wd4710 /wd4711 /wd4746 /wd4820 /wd5045 /wd5220 /wd5245 $(SolutionDir)\bin\$(Configuration)\ @@ -543,7 +543,7 @@ cd $(SolutionDir) & misc\fbuild -ide -dist -monitor -cache $(ProjectName)-$(Configuration) cd $(SolutionDir) & misc\fbuild -ide -dist -monitor -cache -clean $(ProjectName)-$(Configuration) - _CRT_SECURE_NO_WARNINGS;_UNICODE;UNICODE;WIN32_LEAN_AND_MEAN;WIN32;_WIN32;__WINDOWS__;_HAS_EXCEPTIONS=0;WIN64;DEBUG;PROFILING_ENABLED;JULIET_ENABLE_IMGUI;JULIET_WIN32; + _CRT_SECURE_NO_WARNINGS;_UNICODE;UNICODE;WIN32_LEAN_AND_MEAN;WIN32;_WIN32;__WINDOWS__;_HAS_EXCEPTIONS=0;WIN64;DEBUG;PROFILING_ENABLED;JULIET_ENABLE_IMGUI;JULIET_DEBUG;JULIET_WIN32; ..\;..\Juliet\include;..\Juliet\src;..\External\imgui;C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.44.35207\include\;C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\ucrt;C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\um;C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\shared; /std:c++20 $(SolutionDir)\bin\$(Configuration)\ diff --git a/JulietShaderCompiler/JulietShaderCompiler.vcxproj b/JulietShaderCompiler/JulietShaderCompiler.vcxproj index c041e40..d84bed1 100644 --- a/JulietShaderCompiler/JulietShaderCompiler.vcxproj +++ b/JulietShaderCompiler/JulietShaderCompiler.vcxproj @@ -51,7 +51,7 @@ cd $(SolutionDir) & misc\fbuild -ide -dist -monitor -cache $(ProjectName)-$(Configuration) cd $(SolutionDir) & misc\fbuild -ide -dist -monitor -cache -clean $(ProjectName)-$(Configuration) - _CRT_SECURE_NO_WARNINGS;_UNICODE;UNICODE;WIN32_LEAN_AND_MEAN;WIN32;_WIN32;__WINDOWS__;_HAS_EXCEPTIONS=0;WIN64;DEBUG;PROFILING_ENABLED;JULIET_ENABLE_IMGUI;JULIET_EXPORT;JULIET_WIN32; + _CRT_SECURE_NO_WARNINGS;_UNICODE;UNICODE;WIN32_LEAN_AND_MEAN;WIN32;_WIN32;__WINDOWS__;_HAS_EXCEPTIONS=0;WIN64;DEBUG;PROFILING_ENABLED;JULIET_ENABLE_IMGUI;JULIET_DEBUG;JULIET_EXPORT;JULIET_WIN32; ..\;..\Juliet\include;..\Juliet\src;..\External\imgui;..\External\imgui\backends;C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.44.35207\include\;C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\ucrt;C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\um;C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\shared; /std:c++20 $(SolutionDir)\bin\$(Configuration)\ diff --git a/fbuild.bff b/fbuild.bff index eefac59..507dd41 100644 --- a/fbuild.bff +++ b/fbuild.bff @@ -31,7 +31,7 @@ Settings //------------------------------------------------------------------------------ .Debug_Config = [ - .CompilerOptions = ' -DDEBUG -DPROFILING_ENABLED -DJULIET_ENABLE_IMGUI' + .CompilerOptions = ' -DDEBUG -DPROFILING_ENABLED -DJULIET_ENABLE_IMGUI -DJULIET_DEBUG' .CompilerOptionsC = .CompilerOptions .BuildConfigName = 'Debug' ] -- 2.49.1