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 <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/D3D12GraphicsDevice.h>
#include <Graphics/D3D12/D3D12Synchronization.h> #include <Graphics/D3D12/D3D12Synchronization.h>
#include <Graphics/D3D12/D3D12Utils.h> #include <Graphics/D3D12/D3D12Utils.h>
#include <Core/Logging/LogManager.h>
#include <Core/Logging/LogTypes.h>
#include <string> #include <string>
namespace Juliet::D3D12 namespace Juliet::D3D12
{ {
namespace 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) bool HasD3D12CommandListForQueueType(NonNullPtr<D3D12CommandList> commandList, QueueType queueType)
{ {
switch (queueType) switch (queueType)
@@ -118,7 +130,18 @@ namespace Juliet::D3D12
bool AllocateCommandList(NonNullPtr<D3D12Driver> driver, QueueType queueType) 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) if (!commandList)
{ {
Log(LogLevel::Error, LogCategory::Graphics, "Cannot allocate D3D12CommandList: Out of memory"); Log(LogLevel::Error, LogCategory::Graphics, "Cannot allocate D3D12CommandList: Out of memory");
@@ -126,21 +149,6 @@ namespace Juliet::D3D12
return false; 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->AvailableCommandLists[driver->AvailableCommandListCount] = commandList;
driver->AvailableCommandListCount += 1; driver->AvailableCommandListCount += 1;
@@ -148,21 +156,30 @@ namespace Juliet::D3D12
commandList->Driver = driver; commandList->Driver = driver;
// Window Handling // Window Handling
commandList->PresentDataCapacity = 1; commandList->PresentDataCapacity = kMaxPresentDataPerCommandList;
commandList->PresentDataCount = 0; commandList->PresentDataCount = 0;
commandList->PresentDatas = commandList->PresentDatas = ArenaPushArray<D3D12PresentData>(
static_cast<D3D12PresentData*>(Calloc(commandList->PresentDataCapacity, sizeof(D3D12PresentData))); driver->DriverArena,
kMaxPresentDataPerCommandList JULIET_DEBUG_PARAM("Command list [{}] D3D12PresentData ptr array count "
"{}",
id, kMaxPresentDataPerCommandList));
// Resource tracking // Resource tracking
commandList->UsedTextureCapacity = 4; commandList->UsedTextureCapacity = kMaxTexturePerCommandList;
commandList->UsedTextureCount = 0; commandList->UsedTextureCount = 0;
commandList->UsedTextures = commandList->UsedTextures = ArenaPushArray<D3D12Texture*>(
static_cast<D3D12Texture**>(Calloc(commandList->UsedTextureCapacity, sizeof(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->UsedGraphicsPipelineCount = 0;
commandList->UsedGraphicsPipelines = static_cast<D3D12GraphicsPipeline**>( commandList->UsedGraphicsPipelines = ArenaPushArray<D3D12GraphicsPipeline*>(
Calloc(commandList->UsedGraphicsPipelineCapacity, sizeof(D3D12GraphicsPipeline*))); driver->DriverArena,
kMaxTexturePerCommandList JULIET_DEBUG_PARAM("Command list [{}] D3D12GraphicsPipeline ptr array count "
"{}",
id, kMaxTexturePerCommandList));
// TODO : Simplify this // TODO : Simplify this
if (!HasD3D12CommandListForQueueType(commandList, queueType)) if (!HasD3D12CommandListForQueueType(commandList, queueType))
@@ -264,13 +281,8 @@ namespace Juliet::D3D12
// Mark the command list as submitted // Mark the command list as submitted
const uint32 newValue = static_cast<uint32>(d3d12Driver->SubmittedCommandListCount) + 1U; const uint32 newValue = static_cast<uint32>(d3d12Driver->SubmittedCommandListCount) + 1U;
Assert(newValue <= 0xFF && "Command List count exceeded uint8 capacity!"); Assert(newValue <= 0xFF && "Command List count exceeded uint8 capacity!");
if (newValue >= d3d12Driver->SubmittedCommandListCapacity) Assert(newValue <= d3d12Driver->SubmittedCommandListCapacity);
{
d3d12Driver->SubmittedCommandListCapacity = static_cast<uint8>(newValue);
d3d12Driver->SubmittedCommandLists = static_cast<D3D12CommandList**>(
Realloc(d3d12Driver->SubmittedCommandLists, sizeof(D3D12CommandList*) * d3d12Driver->SubmittedCommandListCapacity));
}
d3d12Driver->SubmittedCommandLists[d3d12Driver->SubmittedCommandListCount] = d3d12CommandList; d3d12Driver->SubmittedCommandLists[d3d12Driver->SubmittedCommandListCount] = d3d12CommandList;
d3d12Driver->SubmittedCommandListCount += 1; d3d12Driver->SubmittedCommandListCount += 1;
@@ -447,11 +459,6 @@ namespace Juliet::D3D12
} }
commandList->GraphicsCommandList.Allocator->Release(); 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) bool CleanCommandList(NonNullPtr<D3D12Driver> driver, NonNullPtr<D3D12CommandList> commandList, bool cancel)
@@ -502,12 +509,7 @@ namespace Juliet::D3D12
} }
// Return the command list to the pool // Return the command list to the pool
if (driver->AvailableCommandListCount == driver->AvailableCommandListCapacity) Assert(driver->AvailableCommandListCount + 1 <= driver->AvailableCommandListCapacity);
{
driver->AvailableCommandListCapacity += 1;
driver->AvailableCommandLists = static_cast<D3D12CommandList**>(
Realloc(driver->AvailableCommandLists, driver->AvailableCommandListCapacity * sizeof(D3D12CommandList*)));
}
driver->AvailableCommandLists[driver->AvailableCommandListCount] = commandList; driver->AvailableCommandLists[driver->AvailableCommandListCount] = commandList;
driver->AvailableCommandListCount += 1; driver->AvailableCommandListCount += 1;
@@ -539,11 +541,7 @@ namespace Juliet::D3D12
} \ } \
} \ } \
\ \
if (commandList->count == commandList->capacity) \ Assert(commandList->count + 1 <= commandList->capacity); \
{ \
commandList->capacity += 1; \
commandList->array = (type*)Realloc(commandList->array, commandList->capacity * sizeof(type)); \
} \
commandList->array[commandList->count] = resource; \ commandList->array[commandList->count] = resource; \
commandList->count += 1; \ commandList->count += 1; \
++(resource)->ReferenceCount; ++(resource)->ReferenceCount;
+1 -1
View File
@@ -41,7 +41,7 @@ namespace Juliet::D3D12
{ {
CommandListHeader Common; CommandListHeader Common;
uint64 ID; index_t ID;
D3D12Driver* Driver; D3D12Driver* Driver;
@@ -492,11 +492,8 @@ namespace Juliet::D3D12
// Clean allocations // Clean allocations
SafeFree(driver->AvailableCommandLists);
SafeFree(driver->SubmittedCommandLists);
SafeFree(driver->GraphicsPipelinesToDispose); SafeFree(driver->GraphicsPipelinesToDispose);
// Free(driver->WindowData); // TODO Should free the vector of WindowData, but we have only one for now // Free(driver->WindowData); // TODO Should free the vector of WindowData, but we have only one for now
SafeFree(driver->AvailableFences);
if (driver->IndirectDrawCommandSignature) if (driver->IndirectDrawCommandSignature)
{ {
@@ -949,19 +946,24 @@ namespace Juliet::D3D12
} }
// Create Pools // Create Pools
driver->SubmittedCommandListCapacity = 4; constexpr static size_t kMaxCommandListNumber = 16;
driver->SubmittedCommandListCount = 0; driver->SubmittedCommandListCapacity = kMaxCommandListNumber;
driver->SubmittedCommandLists = driver->SubmittedCommandListCount = 0;
static_cast<D3D12CommandList**>(Calloc(driver->SubmittedCommandListCapacity, sizeof(D3D12CommandList*))); driver->SubmittedCommandLists = ArenaPushArray<D3D12CommandList*>(
driver->DriverArena,
kMaxCommandListNumber JULIET_DEBUG_PARAM("Command list Ptr Array Count: {}", kMaxCommandListNumber));
if (!driver->SubmittedCommandLists) if (!driver->SubmittedCommandLists)
{ {
DestroyDriver_Internal(driver); DestroyDriver_Internal(driver);
return nullptr; return nullptr;
} }
driver->AvailableFenceCapacity = 4; constexpr static size_t kMaxFencesNumber = 16;
driver->AvailableFenceCount = 0; driver->AvailableFenceCapacity = kMaxFencesNumber;
driver->AvailableFences = static_cast<D3D12Fence**>(Calloc(driver->AvailableFenceCapacity, sizeof(D3D12Fence*))); driver->AvailableFenceCount = 0;
driver->AvailableFences =
ArenaPushArray<D3D12Fence*>(driver->DriverArena,
kMaxFencesNumber JULIET_DEBUG_PARAM("Fence Ptr Array Count: {}", kMaxFencesNumber));
if (!driver->AvailableFences) if (!driver->AvailableFences)
{ {
DestroyDriver_Internal(driver); 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 // When the swap chain texture is acquired it's time to present
if (d3d12CommandList->PresentDataCount == d3d12CommandList->PresentDataCapacity) Assert(d3d12CommandList->PresentDataCount + 1 <= d3d12CommandList->PresentDataCapacity);
{
d3d12CommandList->PresentDataCapacity += 1;
d3d12CommandList->PresentDatas = static_cast<D3D12PresentData*>(
Realloc(d3d12CommandList->PresentDatas, d3d12CommandList->PresentDataCapacity * sizeof(D3D12PresentData)));
}
d3d12CommandList->PresentDatas[d3d12CommandList->PresentDataCount].WindowData = windowData; d3d12CommandList->PresentDatas[d3d12CommandList->PresentDataCount].WindowData = windowData;
d3d12CommandList->PresentDatas[d3d12CommandList->PresentDataCount].SwapChainImageIndex = swapchainIndex; d3d12CommandList->PresentDatas[d3d12CommandList->PresentDataCount].SwapChainImageIndex = swapchainIndex;
d3d12CommandList->PresentDataCount += 1; d3d12CommandList->PresentDataCount += 1;
@@ -1,6 +1,5 @@
#include <Core/Logging/LogManager.h> #include <Core/Logging/LogManager.h>
#include <Core/Logging/LogTypes.h> #include <Core/Logging/LogTypes.h>
#include <Core/Memory/Allocator.h>
#include <Graphics/D3D12/D3D12CommandList.h> #include <Graphics/D3D12/D3D12CommandList.h>
#include <Graphics/D3D12/D3D12GraphicsDevice.h> #include <Graphics/D3D12/D3D12GraphicsDevice.h>
#include <Graphics/D3D12/D3D12Synchronization.h> #include <Graphics/D3D12/D3D12Synchronization.h>
@@ -12,14 +11,8 @@ namespace Juliet::D3D12
{ {
void ReleaseFenceToPool(NonNullPtr<D3D12Driver> driver, NonNullPtr<D3D12Fence> fence) void ReleaseFenceToPool(NonNullPtr<D3D12Driver> driver, NonNullPtr<D3D12Fence> fence)
{ {
if (driver->AvailableFenceCount + 1 >= driver->AvailableFenceCapacity) Assert(driver->AvailableFenceCount + 1 <= driver->AvailableFenceCapacity);
{
driver->AvailableFenceCapacity = driver->AvailableFenceCapacity * 2;
driver->AvailableFences = static_cast<D3D12Fence**>(
Realloc(driver->AvailableFences, sizeof(D3D12Fence*) * driver->AvailableFenceCapacity));
LogDebug(LogCategory::Graphics, "ReleaseFenceToPool With Realloc");
}
driver->AvailableFences[driver->AvailableFenceCount] = fence; driver->AvailableFences[driver->AvailableFenceCount] = fence;
driver->AvailableFenceCount += 1; driver->AvailableFenceCount += 1;
@@ -223,7 +216,7 @@ namespace Juliet::D3D12
return nullptr; return nullptr;
} }
fence = static_cast<D3D12Fence*>(Calloc(1, sizeof(D3D12Fence))); fence = ArenaPushStruct<D3D12Fence>(driver->DriverArena JULIET_DEBUG_PARAM("D3D12Fence"));
if (!fence) if (!fence)
{ {
handle->Release(); handle->Release();
@@ -269,7 +262,6 @@ namespace Juliet::D3D12
{ {
CloseHandle(fence->Event); CloseHandle(fence->Event);
} }
Free(fence.Get());
} }
} // namespace Internal } // namespace Internal
} // namespace Juliet::D3D12 } // namespace Juliet::D3D12