Convert bunch of alloc into arena push.

Made most of the array of pointer fixed size. Could use linked list if needed.
This commit is contained in:
2026-08-02 18:28:51 -04:00
parent 0bb2d8d9dc
commit 5862843a40
5 changed files with 65 additions and 78 deletions
+49 -51
View File
@@ -1,18 +1,30 @@
#include <Core/Memory/Allocator.h>
#include <Graphics/D3D12/D3D12Buffer.h>
#include <Graphics/D3D12/D3D12CommandList.h>
#include <Core/Logging/LogManager.h>
#include <Core/Logging/LogTypes.h>
#include <Graphics/D3D12/D3D12Buffer.h>
#include <Graphics/D3D12/D3D12GraphicsDevice.h>
#include <Graphics/D3D12/D3D12Synchronization.h>
#include <Graphics/D3D12/D3D12Utils.h>
#include <Core/Logging/LogManager.h>
#include <Core/Logging/LogTypes.h>
#include <string>
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<D3D12CommandList> commandList, QueueType queueType)
{
switch (queueType)
@@ -118,7 +130,18 @@ namespace Juliet::D3D12
bool AllocateCommandList(NonNullPtr<D3D12Driver> driver, QueueType queueType)
{
auto* commandList = static_cast<D3D12CommandList*>(Calloc(1, sizeof(D3D12CommandList)));
if (driver->AvailableCommandLists == nullptr)
{
driver->AvailableCommandLists =
ArenaPushArray<D3D12CommandList*>(driver->DriverArena,
kMaxCommandListCount JULIET_DEBUG_PARAM("Command list count {}",
kMaxCommandListCount));
driver->AvailableCommandListCapacity = kMaxCommandListCount;
}
const index_t id = GetNewCommandListID();
auto* commandList =
ArenaPushStruct<D3D12CommandList>(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<D3D12CommandList**>(
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<D3D12PresentData*>(Calloc(commandList->PresentDataCapacity, sizeof(D3D12PresentData)));
commandList->PresentDatas = ArenaPushArray<D3D12PresentData>(
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<D3D12Texture**>(Calloc(commandList->UsedTextureCapacity, sizeof(D3D12Texture*)));
commandList->UsedTextures = ArenaPushArray<D3D12Texture*>(
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<D3D12GraphicsPipeline**>(
Calloc(commandList->UsedGraphicsPipelineCapacity, sizeof(D3D12GraphicsPipeline*)));
commandList->UsedGraphicsPipelines = ArenaPushArray<D3D12GraphicsPipeline*>(
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<uint32>(d3d12Driver->SubmittedCommandListCount) + 1U;
Assert(newValue <= 0xFF && "Command List count exceeded uint8 capacity!");
if (newValue >= d3d12Driver->SubmittedCommandListCapacity)
{
d3d12Driver->SubmittedCommandListCapacity = static_cast<uint8>(newValue);
Assert(newValue <= d3d12Driver->SubmittedCommandListCapacity);
d3d12Driver->SubmittedCommandLists = static_cast<D3D12CommandList**>(
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<D3D12Driver> driver, NonNullPtr<D3D12CommandList> 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<D3D12CommandList**>(
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;
+1 -1
View File
@@ -41,7 +41,7 @@ namespace Juliet::D3D12
{
CommandListHeader Common;
uint64 ID;
index_t ID;
D3D12Driver* Driver;
@@ -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<D3D12CommandList**>(Calloc(driver->SubmittedCommandListCapacity, sizeof(D3D12CommandList*)));
constexpr static size_t kMaxCommandListNumber = 16;
driver->SubmittedCommandListCapacity = kMaxCommandListNumber;
driver->SubmittedCommandListCount = 0;
driver->SubmittedCommandLists = ArenaPushArray<D3D12CommandList*>(
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<D3D12Fence**>(Calloc(driver->AvailableFenceCapacity, sizeof(D3D12Fence*)));
constexpr static size_t kMaxFencesNumber = 16;
driver->AvailableFenceCapacity = kMaxFencesNumber;
driver->AvailableFenceCount = 0;
driver->AvailableFences =
ArenaPushArray<D3D12Fence*>(driver->DriverArena,
kMaxFencesNumber JULIET_DEBUG_PARAM("Fence Ptr Array Count: {}", kMaxFencesNumber));
if (!driver->AvailableFences)
{
DestroyDriver_Internal(driver);
+1 -6
View File
@@ -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<D3D12PresentData*>(
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;
@@ -1,6 +1,5 @@
#include <Core/Logging/LogManager.h>
#include <Core/Logging/LogTypes.h>
#include <Core/Memory/Allocator.h>
#include <Graphics/D3D12/D3D12CommandList.h>
#include <Graphics/D3D12/D3D12GraphicsDevice.h>
#include <Graphics/D3D12/D3D12Synchronization.h>
@@ -12,14 +11,8 @@ namespace Juliet::D3D12
{
void ReleaseFenceToPool(NonNullPtr<D3D12Driver> driver, NonNullPtr<D3D12Fence> fence)
{
if (driver->AvailableFenceCount + 1 >= driver->AvailableFenceCapacity)
{
driver->AvailableFenceCapacity = driver->AvailableFenceCapacity * 2;
driver->AvailableFences = static_cast<D3D12Fence**>(
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<D3D12Fence*>(Calloc(1, sizeof(D3D12Fence)));
fence = ArenaPushStruct<D3D12Fence>(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