From 5862843a4051f4fdefee07801c9a06d0ec84969d Mon Sep 17 00:00:00 2001 From: Patedam Date: Sun, 2 Aug 2026 18:28:51 -0400 Subject: [PATCH] Convert bunch of alloc into arena push. Made most of the array of pointer fixed size. Could use linked list if needed. --- .../src/Graphics/D3D12/D3D12CommandList.cpp | 100 +++++++++--------- Juliet/src/Graphics/D3D12/D3D12CommandList.h | 2 +- .../Graphics/D3D12/D3D12GraphicsDevice.cpp | 22 ++-- Juliet/src/Graphics/D3D12/D3D12SwapChain.cpp | 7 +- .../Graphics/D3D12/D3D12Synchronization.cpp | 12 +-- 5 files changed, 65 insertions(+), 78 deletions(-) diff --git a/Juliet/src/Graphics/D3D12/D3D12CommandList.cpp b/Juliet/src/Graphics/D3D12/D3D12CommandList.cpp index 3ff29d2..0ccfcaf 100644 --- a/Juliet/src/Graphics/D3D12/D3D12CommandList.cpp +++ b/Juliet/src/Graphics/D3D12/D3D12CommandList.cpp @@ -1,18 +1,30 @@ -#include -#include #include + +#include +#include +#include #include #include #include -#include -#include #include namespace Juliet::D3D12 { namespace { + constexpr size_t kMaxTexturePerCommandList = 1024; + constexpr size_t kMaxGraphicsPipelinePerCommandList = 1024; + constexpr size_t kMaxPresentDataPerCommandList = 1; + constexpr size_t kMaxCommandListCount = 4; + + index_t CommandListID = 0; + + index_t GetNewCommandListID() + { + return CommandListID++; + } + bool HasD3D12CommandListForQueueType(NonNullPtr commandList, QueueType queueType) { switch (queueType) @@ -118,7 +130,18 @@ namespace Juliet::D3D12 bool AllocateCommandList(NonNullPtr driver, QueueType queueType) { - auto* commandList = static_cast(Calloc(1, sizeof(D3D12CommandList))); + if (driver->AvailableCommandLists == nullptr) + { + driver->AvailableCommandLists = + ArenaPushArray(driver->DriverArena, + kMaxCommandListCount JULIET_DEBUG_PARAM("Command list count {}", + kMaxCommandListCount)); + driver->AvailableCommandListCapacity = kMaxCommandListCount; + } + const index_t id = GetNewCommandListID(); + + auto* commandList = + ArenaPushStruct(driver->DriverArena JULIET_DEBUG_PARAM("D3D12CommandList [{}]", id)); if (!commandList) { Log(LogLevel::Error, LogCategory::Graphics, "Cannot allocate D3D12CommandList: Out of memory"); @@ -126,21 +149,6 @@ namespace Juliet::D3D12 return false; } - auto resizedArray = static_cast( - Realloc(driver->AvailableCommandLists, sizeof(D3D12CommandList*) * (driver->AvailableCommandListCapacity + 1))); - - if (!resizedArray) - { - Log(LogLevel::Error, LogCategory::Graphics, - "Error not implemented, out of memory, handle that by deallocating stuff and returning false"); - Internal::DestroyCommandList(commandList); - return false; - } - - uint32 id = driver->AvailableCommandListCapacity; - driver->AvailableCommandListCapacity += 1; - driver->AvailableCommandLists = resizedArray; - driver->AvailableCommandLists[driver->AvailableCommandListCount] = commandList; driver->AvailableCommandListCount += 1; @@ -148,21 +156,30 @@ namespace Juliet::D3D12 commandList->Driver = driver; // Window Handling - commandList->PresentDataCapacity = 1; + commandList->PresentDataCapacity = kMaxPresentDataPerCommandList; commandList->PresentDataCount = 0; - commandList->PresentDatas = - static_cast(Calloc(commandList->PresentDataCapacity, sizeof(D3D12PresentData))); + commandList->PresentDatas = ArenaPushArray( + driver->DriverArena, + kMaxPresentDataPerCommandList JULIET_DEBUG_PARAM("Command list [{}] D3D12PresentData ptr array count " + "{}", + id, kMaxPresentDataPerCommandList)); // Resource tracking - commandList->UsedTextureCapacity = 4; + commandList->UsedTextureCapacity = kMaxTexturePerCommandList; commandList->UsedTextureCount = 0; - commandList->UsedTextures = - static_cast(Calloc(commandList->UsedTextureCapacity, sizeof(D3D12Texture*))); + commandList->UsedTextures = ArenaPushArray( + driver->DriverArena, + kMaxTexturePerCommandList JULIET_DEBUG_PARAM("Command list [{}] D3D12Texture ptr array count " + "{}", + id, kMaxTexturePerCommandList)); - commandList->UsedGraphicsPipelineCapacity = 4; + commandList->UsedGraphicsPipelineCapacity = kMaxGraphicsPipelinePerCommandList; commandList->UsedGraphicsPipelineCount = 0; - commandList->UsedGraphicsPipelines = static_cast( - Calloc(commandList->UsedGraphicsPipelineCapacity, sizeof(D3D12GraphicsPipeline*))); + commandList->UsedGraphicsPipelines = ArenaPushArray( + driver->DriverArena, + kMaxTexturePerCommandList JULIET_DEBUG_PARAM("Command list [{}] D3D12GraphicsPipeline ptr array count " + "{}", + id, kMaxTexturePerCommandList)); // TODO : Simplify this if (!HasD3D12CommandListForQueueType(commandList, queueType)) @@ -264,13 +281,8 @@ namespace Juliet::D3D12 // Mark the command list as submitted const uint32 newValue = static_cast(d3d12Driver->SubmittedCommandListCount) + 1U; Assert(newValue <= 0xFF && "Command List count exceeded uint8 capacity!"); - if (newValue >= d3d12Driver->SubmittedCommandListCapacity) - { - d3d12Driver->SubmittedCommandListCapacity = static_cast(newValue); + Assert(newValue <= d3d12Driver->SubmittedCommandListCapacity); - d3d12Driver->SubmittedCommandLists = static_cast( - Realloc(d3d12Driver->SubmittedCommandLists, sizeof(D3D12CommandList*) * d3d12Driver->SubmittedCommandListCapacity)); - } d3d12Driver->SubmittedCommandLists[d3d12Driver->SubmittedCommandListCount] = d3d12CommandList; d3d12Driver->SubmittedCommandListCount += 1; @@ -447,11 +459,6 @@ namespace Juliet::D3D12 } commandList->GraphicsCommandList.Allocator->Release(); - - SafeFree(commandList->PresentDatas); - SafeFree(commandList->UsedTextures); - SafeFree(commandList->UsedGraphicsPipelines); - Free(commandList.Get()); } bool CleanCommandList(NonNullPtr driver, NonNullPtr commandList, bool cancel) @@ -502,12 +509,7 @@ namespace Juliet::D3D12 } // Return the command list to the pool - if (driver->AvailableCommandListCount == driver->AvailableCommandListCapacity) - { - driver->AvailableCommandListCapacity += 1; - driver->AvailableCommandLists = static_cast( - Realloc(driver->AvailableCommandLists, driver->AvailableCommandListCapacity * sizeof(D3D12CommandList*))); - } + Assert(driver->AvailableCommandListCount + 1 <= driver->AvailableCommandListCapacity); driver->AvailableCommandLists[driver->AvailableCommandListCount] = commandList; driver->AvailableCommandListCount += 1; @@ -539,11 +541,7 @@ namespace Juliet::D3D12 } \ } \ \ - if (commandList->count == commandList->capacity) \ - { \ - commandList->capacity += 1; \ - commandList->array = (type*)Realloc(commandList->array, commandList->capacity * sizeof(type)); \ - } \ + Assert(commandList->count + 1 <= commandList->capacity); \ commandList->array[commandList->count] = resource; \ commandList->count += 1; \ ++(resource)->ReferenceCount; diff --git a/Juliet/src/Graphics/D3D12/D3D12CommandList.h b/Juliet/src/Graphics/D3D12/D3D12CommandList.h index 2800bdf..dfb2048 100644 --- a/Juliet/src/Graphics/D3D12/D3D12CommandList.h +++ b/Juliet/src/Graphics/D3D12/D3D12CommandList.h @@ -41,7 +41,7 @@ namespace Juliet::D3D12 { CommandListHeader Common; - uint64 ID; + index_t ID; D3D12Driver* Driver; diff --git a/Juliet/src/Graphics/D3D12/D3D12GraphicsDevice.cpp b/Juliet/src/Graphics/D3D12/D3D12GraphicsDevice.cpp index 8e0da7f..5e4d117 100644 --- a/Juliet/src/Graphics/D3D12/D3D12GraphicsDevice.cpp +++ b/Juliet/src/Graphics/D3D12/D3D12GraphicsDevice.cpp @@ -492,11 +492,8 @@ namespace Juliet::D3D12 // Clean allocations - SafeFree(driver->AvailableCommandLists); - SafeFree(driver->SubmittedCommandLists); SafeFree(driver->GraphicsPipelinesToDispose); // Free(driver->WindowData); // TODO Should free the vector of WindowData, but we have only one for now - SafeFree(driver->AvailableFences); if (driver->IndirectDrawCommandSignature) { @@ -949,19 +946,24 @@ namespace Juliet::D3D12 } // Create Pools - driver->SubmittedCommandListCapacity = 4; - driver->SubmittedCommandListCount = 0; - driver->SubmittedCommandLists = - static_cast(Calloc(driver->SubmittedCommandListCapacity, sizeof(D3D12CommandList*))); + constexpr static size_t kMaxCommandListNumber = 16; + driver->SubmittedCommandListCapacity = kMaxCommandListNumber; + driver->SubmittedCommandListCount = 0; + driver->SubmittedCommandLists = ArenaPushArray( + driver->DriverArena, + kMaxCommandListNumber JULIET_DEBUG_PARAM("Command list Ptr Array Count: {}", kMaxCommandListNumber)); if (!driver->SubmittedCommandLists) { DestroyDriver_Internal(driver); return nullptr; } - driver->AvailableFenceCapacity = 4; - driver->AvailableFenceCount = 0; - driver->AvailableFences = static_cast(Calloc(driver->AvailableFenceCapacity, sizeof(D3D12Fence*))); + constexpr static size_t kMaxFencesNumber = 16; + driver->AvailableFenceCapacity = kMaxFencesNumber; + driver->AvailableFenceCount = 0; + driver->AvailableFences = + ArenaPushArray(driver->DriverArena, + kMaxFencesNumber JULIET_DEBUG_PARAM("Fence Ptr Array Count: {}", kMaxFencesNumber)); if (!driver->AvailableFences) { DestroyDriver_Internal(driver); diff --git a/Juliet/src/Graphics/D3D12/D3D12SwapChain.cpp b/Juliet/src/Graphics/D3D12/D3D12SwapChain.cpp index 4f91875..a0ae59b 100644 --- a/Juliet/src/Graphics/D3D12/D3D12SwapChain.cpp +++ b/Juliet/src/Graphics/D3D12/D3D12SwapChain.cpp @@ -172,12 +172,7 @@ namespace Juliet::D3D12 } // When the swap chain texture is acquired it's time to present - if (d3d12CommandList->PresentDataCount == d3d12CommandList->PresentDataCapacity) - { - d3d12CommandList->PresentDataCapacity += 1; - d3d12CommandList->PresentDatas = static_cast( - Realloc(d3d12CommandList->PresentDatas, d3d12CommandList->PresentDataCapacity * sizeof(D3D12PresentData))); - } + Assert(d3d12CommandList->PresentDataCount + 1 <= d3d12CommandList->PresentDataCapacity); d3d12CommandList->PresentDatas[d3d12CommandList->PresentDataCount].WindowData = windowData; d3d12CommandList->PresentDatas[d3d12CommandList->PresentDataCount].SwapChainImageIndex = swapchainIndex; d3d12CommandList->PresentDataCount += 1; diff --git a/Juliet/src/Graphics/D3D12/D3D12Synchronization.cpp b/Juliet/src/Graphics/D3D12/D3D12Synchronization.cpp index db4f9e2..eb96c07 100644 --- a/Juliet/src/Graphics/D3D12/D3D12Synchronization.cpp +++ b/Juliet/src/Graphics/D3D12/D3D12Synchronization.cpp @@ -1,6 +1,5 @@ #include #include -#include #include #include #include @@ -12,14 +11,8 @@ namespace Juliet::D3D12 { void ReleaseFenceToPool(NonNullPtr driver, NonNullPtr fence) { - if (driver->AvailableFenceCount + 1 >= driver->AvailableFenceCapacity) - { - driver->AvailableFenceCapacity = driver->AvailableFenceCapacity * 2; - driver->AvailableFences = static_cast( - Realloc(driver->AvailableFences, sizeof(D3D12Fence*) * driver->AvailableFenceCapacity)); + Assert(driver->AvailableFenceCount + 1 <= driver->AvailableFenceCapacity); - LogDebug(LogCategory::Graphics, "ReleaseFenceToPool With Realloc"); - } driver->AvailableFences[driver->AvailableFenceCount] = fence; driver->AvailableFenceCount += 1; @@ -223,7 +216,7 @@ namespace Juliet::D3D12 return nullptr; } - fence = static_cast(Calloc(1, sizeof(D3D12Fence))); + fence = ArenaPushStruct(driver->DriverArena JULIET_DEBUG_PARAM("D3D12Fence")); if (!fence) { handle->Release(); @@ -269,7 +262,6 @@ namespace Juliet::D3D12 { CloseHandle(fence->Event); } - Free(fence.Get()); } } // namespace Internal } // namespace Juliet::D3D12