Adapting arena push to support format as debug tag

Changed some d3d12 to work better with arenas
This commit is contained in:
2026-07-29 14:44:16 -04:00
parent 4dc14a04b3
commit 7b21ca6b1d
18 changed files with 141 additions and 103 deletions
+5 -11
View File
@@ -1,21 +1,15 @@
--- ---
description: Build the Juliet project using FastBuild description: Build the Juliet projects
--- ---
// turbo-all // turbo-all
This workflow builds the Juliet project.
This workflow builds the Juliet project and writes output to `misc\agent_output.log`.
1. To build the default (clang-Debug): 1. To build the default (clang-Debug):
// turbo // turbo
`misc\agent_build.bat clang 2>&1 | tee misc\agent_output.log` `misc\build.bat clang`
2. To build a specific configuration (e.g., clang-Debug, msvc-Debug): 2. To build a specific configuration (e.g., clang-Debug, msvc-Debug):
// turbo // turbo
`misc\agent_build.bat clang-Debug 2>&1 | tee misc\agent_output.log` `misc\build.bat clang-Debug`
3. To see all available targets: 3. To see all available targets:
// turbo // turbo
`misc\agent_build.bat -showtargets 2>&1 | tee misc\agent_output.log` `misc\build.bat -showtargets`
4. Check build results by reading `misc\agent_output.log`.
+20 -15
View File
@@ -1,10 +1,22 @@
#pragma once #pragma once
#include <string.h>
#include <Core/Common/NonNullPtr.h> #include <Core/Common/NonNullPtr.h>
#include <Core/Math/MathUtils.h> #include <Core/Math/MathUtils.h>
#include <Core/Memory/Utils.h> #include <Core/Memory/Utils.h>
#ifdef global
#undef global
#define RESTORE_GLOBAL
#endif
#include <format>
#include <string>
#ifdef RESTORE_GLOBAL
#define global static
#undef RESTORE_GLOBAL
#endif
namespace Juliet namespace Juliet
{ {
struct Arena; struct Arena;
@@ -42,20 +54,6 @@ namespace Juliet
size_t Capacity; size_t Capacity;
}; };
struct StringListNode
{
StringListNode* Next;
String Content;
};
struct StringList
{
StringListNode* First;
StringListNode* Last;
size_t NodeCount;
size_t Size;
};
constexpr uint32 kInvalidUTF8 = 0xFFFD; constexpr uint32 kInvalidUTF8 = 0xFFFD;
inline size_t StringLength(String str) inline size_t StringLength(String str)
@@ -156,6 +154,13 @@ namespace Juliet
extern JULIET_API bool ConvertString(String from, String to, String src, StringBuffer& dst, bool nullTerminate); extern JULIET_API bool ConvertString(String from, String to, String src, StringBuffer& dst, bool nullTerminate);
JULIET_API String StringCopy(NonNullPtr<Arena> arena, String str); JULIET_API String StringCopy(NonNullPtr<Arena> arena, String str);
template <typename... Args>
String Format(NonNullPtr<Arena> arena, const char* formatStr, Args&&... args)
{
std::string result = std::vformat(formatStr, std::make_format_args(args...));
return StringCopy(arena, WrapString(result.c_str()));
}
} // namespace Juliet } // namespace Juliet
#ifdef UNIT_TEST #ifdef UNIT_TEST
+9 -12
View File
@@ -18,16 +18,12 @@ namespace Juliet
Count = 0; Count = 0;
Capacity = 0; Capacity = 0;
Arena = arena; Arena = arena;
ArenaPosAtCreation = ArenaPos(Arena);
Reserve(ReserveSize); Reserve(ReserveSize);
} }
void Destroy() void Destroy()
{ {
Assert(ArenaPos(Arena) == ArenaPosAtCreation + sizeof(Type) * Capacity);
ArenaPopTo(Arena, ArenaPosAtCreation);
DataFirst = DataLast = Data = nullptr; DataFirst = DataLast = Data = nullptr;
Count = 0; Count = 0;
Capacity = 0; Capacity = 0;
@@ -37,6 +33,8 @@ namespace Juliet
void Reserve(size_t newCapacity) void Reserve(size_t newCapacity)
{ {
Assert(Arena); Assert(Arena);
Assert(newCapacity <= ReserveSize && "VectorArena capacity should be <= ReserveSize.");
if (Data == nullptr) if (Data == nullptr)
{ {
Data = ArenaPushArray<Type>(Arena, newCapacity JULIET_DEBUG_PARAM(Name)); Data = ArenaPushArray<Type>(Arena, newCapacity JULIET_DEBUG_PARAM(Name));
@@ -44,7 +42,7 @@ namespace Juliet
} }
else else
{ {
Assert(newCapacity <= Capacity && "VectorArena capacity exceeded! Reallocation is disabled."); Unimplemented();
} }
} }
@@ -201,13 +199,12 @@ namespace Juliet
[[nodiscard]] size_t Size() const { return Count; } [[nodiscard]] size_t Size() const { return Count; }
Arena* Arena = nullptr; Arena* Arena = nullptr;
Type* DataFirst = nullptr; Type* DataFirst = nullptr;
Type* DataLast = nullptr; Type* DataLast = nullptr;
Type* Data = nullptr; Type* Data = nullptr;
size_t Count = 0; size_t Count = 0;
size_t Capacity = 0; size_t Capacity = 0;
index_t ArenaPosAtCreation = 0;
JULIET_DEBUG_ONLY(const char* Name = "VectorArena";) JULIET_DEBUG_ONLY(const char* Name = "VectorArena";)
}; };
static_assert(std::is_standard_layout_v<VectorArena<int>>, static_assert(std::is_standard_layout_v<VectorArena<int>>,
+29 -10
View File
@@ -6,6 +6,10 @@
#include <Core/Common/String.h> #include <Core/Common/String.h>
#include <Juliet.h> #include <Juliet.h>
#if JULIET_DEBUG
#include <Core/Memory/MemoryArenaDebug.h>
#endif
namespace Juliet namespace Juliet
{ {
constexpr global uint64 g_Arena_Default_Reserve_Size = Megabytes(64); constexpr global uint64 g_Arena_Default_Reserve_Size = Megabytes(64);
@@ -14,6 +18,7 @@ namespace Juliet
#if JULIET_DEBUG #if JULIET_DEBUG
struct ArenaDebugInfo; struct ArenaDebugInfo;
JULIET_API String FormatDebugTagV(const char* formatStr, std::format_args args);
#endif #endif
struct Arena struct Arena
@@ -58,30 +63,44 @@ namespace Juliet
JULIET_DEBUG_ONLY(bool CanReserveMore : 1 = true;) JULIET_DEBUG_ONLY(bool CanReserveMore : 1 = true;)
}; };
[[nodiscard]] JULIET_API Arena* ArenaAllocate(const ArenaParams& params JULIET_DEBUG_ONLY(, const char* name), [[nodiscard]] JULIET_API Arena* ArenaAllocate(const ArenaParams& params JULIET_DEBUG_PARAM(const char* name),
const std::source_location& loc = std::source_location::current()); const std::source_location& loc = std::source_location::current());
JULIET_API void ArenaRelease(NonNullPtr<Arena> arena); JULIET_API void ArenaRelease(NonNullPtr<Arena> arena);
// Raw Push, can be used but templated helpers exists below // Raw Push, can be used but templated helpers exists below
[[nodiscard]] JULIET_API void* ArenaPush(NonNullPtr<Arena> arena, size_t size, size_t align, [[nodiscard]] JULIET_API void* ArenaPush(NonNullPtr<Arena> arena, size_t size, size_t align,
bool shouldBeZeroed JULIET_DEBUG_ONLY(, const char* tag)); bool shouldBeZeroed JULIET_DEBUG_PARAM(const char* tag));
JULIET_API void ArenaPopTo(NonNullPtr<Arena> arena, size_t position); JULIET_API void ArenaPopTo(NonNullPtr<Arena> arena, size_t position);
JULIET_API void ArenaPop(NonNullPtr<Arena> arena, size_t amount); JULIET_API void ArenaPop(NonNullPtr<Arena> arena, size_t amount);
JULIET_API void ArenaClear(NonNullPtr<Arena> arena); JULIET_API void ArenaClear(NonNullPtr<Arena> arena);
[[nodiscard]] JULIET_API size_t ArenaPos(NonNullPtr<Arena> arena); [[nodiscard]] JULIET_API size_t ArenaPos(NonNullPtr<Arena> arena);
template <typename Type> template <typename Type JULIET_DEBUG_ONLY(, typename... DebugArgs)>
[[nodiscard]] Type* ArenaPushStruct(NonNullPtr<Arena> arena JULIET_DEBUG_PARAM(const char* tag = nullptr)) [[nodiscard]] Type* ArenaPushStruct(NonNullPtr<Arena> arena JULIET_DEBUG_PARAM(DebugArgs&&... debugArgs))
{ {
return static_cast<Type*>( return static_cast<Type*>(ArenaPush(arena, sizeof(Type) * 1, AlignOf(Type), true JULIET_DEBUG_PARAM(
ArenaPush(arena, sizeof(Type) * 1, AlignOf(Type), true JULIET_DEBUG_PARAM(tag ? tag : GetTypeName<Type>()))); [&]() -> const char* {
if constexpr (sizeof...(DebugArgs) > 0)
{
return Format(GetDebugInfoArena(), std::forward<DebugArgs>(debugArgs)...).Data;
}
return GetTypeName<Type>();
}()
)));
} }
template <typename Type> template <typename Type JULIET_DEBUG_ONLY(, typename... DebugArgs)>
[[nodiscard]] Type* ArenaPushArray(NonNullPtr<Arena> arena, size_t count JULIET_DEBUG_PARAM(const char* tag = nullptr)) [[nodiscard]] Type* ArenaPushArray(NonNullPtr<Arena> arena, size_t count JULIET_DEBUG_PARAM(DebugArgs&&... debugArgs))
{ {
return static_cast<Type*>(ArenaPush(arena, sizeof(Type) * count, Max(8ull, AlignOf(Type)), return static_cast<Type*>(ArenaPush(arena, sizeof(Type) * count, Max(8ull, AlignOf(Type)), true JULIET_DEBUG_PARAM(
true JULIET_DEBUG_PARAM(tag ? tag : GetTypeName<Type>()))); [&]() -> const char* {
if constexpr (sizeof...(DebugArgs) > 0)
{
return Format(GetDebugInfoArena(), std::forward<DebugArgs>(debugArgs)...).Data;
}
return GetTypeName<Type>();
}()
)));
} }
TempArena ArenaTempBegin(NonNullPtr<Arena> arena); TempArena ArenaTempBegin(NonNullPtr<Arena> arena);
+16 -13
View File
@@ -1,9 +1,9 @@
#pragma once #pragma once
#include <Juliet.h>
#include <Core/Common/CoreTypes.h> #include <Core/Common/CoreTypes.h>
#include <Core/Common/String.h>
#include <Core/Common/NonNullPtr.h> #include <Core/Common/NonNullPtr.h>
#include <Core/Common/String.h>
#include <Juliet.h>
#if JULIET_DEBUG #if JULIET_DEBUG
@@ -30,20 +30,23 @@ namespace Juliet
ArenaAllocation* Next; ArenaAllocation* Next;
}; };
// Arena (Struct) // Arena (Struct)
void DebugRegisterArena(NonNullPtr<Arena> arena); void DebugRegisterArena(NonNullPtr<Arena> arena);
void DebugUnregisterArena(NonNullPtr<Arena> arena); void DebugUnregisterArena(NonNullPtr<Arena> arena);
void DebugArenaSetDebugName(NonNullPtr<Arena> arena, const char* name); void DebugArenaSetDebugName(NonNullPtr<Arena> arena, const char* name);
bool IsDebugInfoArena(const Arena* arena); // To prevent recursion bool IsDebugInfoArena(const Arena* arena); // To prevent recursion
void DebugArenaFreeBlock(Arena* block); // To clear all debug infos in a block void DebugArenaFreeBlock(Arena* block); // To clear all debug infos in a block
void DebugArenaRemoveAllocation(Arena* block, size_t oldOffset); void DebugArenaRemoveAllocation(Arena* block, size_t oldOffset);
void DebugArenaPopTo(Arena* block, size_t newPosition); void DebugArenaPopTo(Arena* block, size_t newPosition);
void DebugArenaAddDebugInfo(Arena* block, size_t size, size_t offset, const char* tag); void DebugArenaAddDebugInfo(Arena* block, size_t size, size_t offset, const char* tag);
// MemoryArena (Pool-based) // MemoryArena (Pool-based)
void DebugFreeArenaAllocations(MemoryBlock* blk); void DebugFreeArenaAllocations(MemoryBlock* blk);
void DebugArenaAddAllocation(MemoryBlock* blk, size_t size, size_t offset, String tag); void DebugArenaAddAllocation(MemoryBlock* blk, size_t size, size_t offset, String tag);
void DebugArenaRemoveLastAllocation(MemoryBlock* blk); void DebugArenaRemoveLastAllocation(MemoryBlock* blk);
JULIET_API Arena* GetDebugInfoArena();
} // namespace Juliet } // namespace Juliet
-11
View File
@@ -37,12 +37,6 @@ namespace Juliet
stackTop = stackTop->Next; stackTop = stackTop->Next;
} }
template <typename SingleLinkedListType>
struct SingleLinkedListNode
{
SingleLinkedListType* Next;
};
// Double linked list // Double linked list
template <typename QueueType, typename QueueTypeNode> template <typename QueueType, typename QueueTypeNode>
void Enqueue(QueueType& queue, QueueTypeNode* node) void Enqueue(QueueType& queue, QueueTypeNode* node)
@@ -76,11 +70,6 @@ namespace Juliet
size_t Size; \ size_t Size; \
}; };
#define SLLQueuePush(f, l, n) SLLQueuePush_NZ(0, f, l, n, next)
#define SLLQueuePush_NZ(nil, f, l, n, next) \
(CheckNil(nil, f) ? ((f) = (l) = (n), SetNil(nil, (n)->next)) : ((l)->next = (n), (l) = (n), SetNil(nil, (n)->next)))
// TODO: homemade versions // TODO: homemade versions
#define MemSet memset #define MemSet memset
#define MemCopy memcpy #define MemCopy memcpy
+1 -1
View File
@@ -493,7 +493,7 @@ namespace Juliet
{ {
String result; String result;
result.Size = str.Size; result.Size = str.Size;
result.Data = static_cast<char*>(ArenaPush(arena, str.Size + 1, alignof(char), true JULIET_DEBUG_ONLY(, "String"))); result.Data = static_cast<char*>(ArenaPush(arena, str.Size + 1, alignof(char), true JULIET_DEBUG_PARAM("String")));
MemCopy(result.Data, str.Data, str.Size); MemCopy(result.Data, str.Data, str.Size);
result.Data[result.Size] = 0; result.Data[result.Size] = 0;
return result; return result;
+2 -2
View File
@@ -26,7 +26,7 @@ namespace Juliet
basePathLength + StringLength(dllName) + 1; // Need +1 because snprintf needs 0 terminated strings basePathLength + StringLength(dllName) + 1; // Need +1 because snprintf needs 0 terminated strings
code.DLLFullPath.Data = code.DLLFullPath.Data =
static_cast<char*>(ArenaPush(code.Arena, dllFullPathLength, alignof(char), true JULIET_DEBUG_ONLY(, "DLL Path"))); static_cast<char*>(ArenaPush(code.Arena, dllFullPathLength, alignof(char), true JULIET_DEBUG_PARAM("DLL Path")));
int writtenSize = snprintf(CStr(code.DLLFullPath), dllFullPathLength, "%s%s", CStr(basePath), CStr(dllName)); int writtenSize = snprintf(CStr(code.DLLFullPath), dllFullPathLength, "%s%s", CStr(basePath), CStr(dllName));
if (writtenSize < static_cast<int>(dllFullPathLength) - 1) if (writtenSize < static_cast<int>(dllFullPathLength) - 1)
{ {
@@ -40,7 +40,7 @@ namespace Juliet
const size_t lockPathLength = const size_t lockPathLength =
basePathLength + StringLength(lockFilename) + 1; // Need +1 because snprintf needs 0 terminated strings basePathLength + StringLength(lockFilename) + 1; // Need +1 because snprintf needs 0 terminated strings
code.LockFullPath.Data = code.LockFullPath.Data =
static_cast<char*>(ArenaPush(code.Arena, lockPathLength, alignof(char), true JULIET_DEBUG_ONLY(, "Lock File Path"))); static_cast<char*>(ArenaPush(code.Arena, lockPathLength, alignof(char), true JULIET_DEBUG_PARAM("Lock File Path")));
writtenSize = snprintf(CStr(code.LockFullPath), lockPathLength, "%s%s", CStr(basePath), CStr(lockFilename)); writtenSize = snprintf(CStr(code.LockFullPath), lockPathLength, "%s%s", CStr(basePath), CStr(lockFilename));
if (writtenSize < static_cast<int>(lockPathLength) - 1) if (writtenSize < static_cast<int>(lockPathLength) - 1)
{ {
+1 -1
View File
@@ -28,7 +28,7 @@ namespace Juliet::ImGuiService
void* ImGuiAllocWrapper(size_t size, void* /*user_data*/) void* ImGuiAllocWrapper(size_t size, void* /*user_data*/)
{ {
return ArenaPush(g_ImGuiArena, size, 8, false JULIET_DEBUG_ONLY(, "ImGuiAlloc")); return ArenaPush(g_ImGuiArena, size, 8, false JULIET_DEBUG_PARAM("ImGuiAlloc"));
} }
void ImGuiFreeWrapper(void* /*ptr*/, void* /*user_data*/) void ImGuiFreeWrapper(void* /*ptr*/, void* /*user_data*/)
+3 -2
View File
@@ -153,6 +153,9 @@ namespace Juliet
{ {
result = reinterpret_cast<Byte*>(current) + positionPrePush; result = reinterpret_cast<Byte*>(current) + positionPrePush;
current->Position = positionPostPush; current->Position = positionPostPush;
JULIET_DEBUG_ONLY(if (!IsDebugInfoArena(arena)) { DebugArenaAddDebugInfo(current, size, positionPrePush, tag); })
if (sizeToZero != 0) if (sizeToZero != 0)
{ {
MemoryZero(result, sizeToZero); MemoryZero(result, sizeToZero);
@@ -165,8 +168,6 @@ namespace Juliet
Assert(false, "Fatal Allocation Failure - Unexpected allocation failure"); Assert(false, "Fatal Allocation Failure - Unexpected allocation failure");
} }
JULIET_DEBUG_ONLY(if (!IsDebugInfoArena(arena)) { DebugArenaAddDebugInfo(current, size, positionPrePush, tag); })
return result; return result;
} }
+18 -1
View File
@@ -31,6 +31,15 @@ namespace Juliet
return ArenaPushStruct<ArenaDebugInfo>(g_DebugInfoArena JULIET_DEBUG_PARAM("ArenaDebugInfo")); return ArenaPushStruct<ArenaDebugInfo>(g_DebugInfoArena JULIET_DEBUG_PARAM("ArenaDebugInfo"));
} }
Arena* GetDebugInfoArena()
{
if (!g_DebugInfoArena)
{
g_DebugInfoArena = ArenaAllocate(
{ .ReserveSize = Megabytes(16), .CommitSize = Kilobytes(64) } JULIET_DEBUG_ONLY(, "Debug Info Arena"));
}
return g_DebugInfoArena;
}
static void FreeDebugInfo(ArenaDebugInfo* info) static void FreeDebugInfo(ArenaDebugInfo* info)
{ {
if (info) if (info)
@@ -138,7 +147,15 @@ namespace Juliet
ArenaDebugInfo* info = AllocDebugInfo(); ArenaDebugInfo* info = AllocDebugInfo();
if (info) if (info)
{ {
info->Tag = tag ? tag : "Untagged"; if (tag)
{
String copiedTag = StringCopy(g_DebugInfoArena, WrapString(tag));
info->Tag = copiedTag.Data;
}
else
{
info->Tag = "Untagged";
}
info->Size = size; info->Size = size;
info->Offset = offset; info->Offset = offset;
info->Next = block->FirstDebugInfo; info->Next = block->FirstDebugInfo;
+7 -9
View File
@@ -6,6 +6,9 @@
#include <Graphics/D3D12/D3D12Includes.h> #include <Graphics/D3D12/D3D12Includes.h>
// TODO: Convert the whole file to memory arenas // TODO: Convert the whole file to memory arenas
// Use the driver arena
// Use a linked list to support "free" descriptors
// Extend -> Push a new descriptor thats it...
namespace Juliet::D3D12::Internal namespace Juliet::D3D12::Internal
{ {
namespace namespace
@@ -25,8 +28,8 @@ namespace Juliet::D3D12::Internal
bool ExtendStagingDescriptorPool(NonNullPtr<D3D12Driver> driver, D3D12StagingDescriptorPool& pool) bool ExtendStagingDescriptorPool(NonNullPtr<D3D12Driver> driver, D3D12StagingDescriptorPool& pool)
{ {
D3D12DescriptorHeap* heap = Internal::CreateDescriptorHeap(driver, pool.Arena, pool.Heaps[0]->HeapType, D3D12DescriptorHeap* heap =
kStagingHeapDescriptorExpectedCount, true); Internal::CreateDescriptorHeap(driver, pool.Heaps[0]->HeapType, kStagingHeapDescriptorExpectedCount, true);
if (!heap) if (!heap)
{ {
return false; return false;
@@ -49,17 +52,13 @@ namespace Juliet::D3D12::Internal
D3D12StagingDescriptorPool* CreateStagingDescriptorPool(NonNullPtr<D3D12Driver> driver, D3D12_DESCRIPTOR_HEAP_TYPE type) D3D12StagingDescriptorPool* CreateStagingDescriptorPool(NonNullPtr<D3D12Driver> driver, D3D12_DESCRIPTOR_HEAP_TYPE type)
{ {
Arena* arena = ArenaAllocate({} JULIET_DEBUG_ONLY(, "Staging Descriptors")); D3D12DescriptorHeap* heap = CreateDescriptorHeap(driver, type, kStagingHeapDescriptorExpectedCount, true);
D3D12DescriptorHeap* heap = CreateDescriptorHeap(driver, arena, type, kStagingHeapDescriptorExpectedCount, true);
if (!heap) if (!heap)
{ {
ArenaRelease(arena);
return nullptr; return nullptr;
} }
auto pool = static_cast<D3D12StagingDescriptorPool*>(Calloc(1, sizeof(D3D12StagingDescriptorPool))); auto pool = static_cast<D3D12StagingDescriptorPool*>(Calloc(1, sizeof(D3D12StagingDescriptorPool)));
pool->Arena = arena;
// First create the heaps // First create the heaps
pool->HeapCount = 1; pool->HeapCount = 1;
@@ -118,7 +117,6 @@ namespace Juliet::D3D12::Internal
Free(pool->Heaps); Free(pool->Heaps);
Free(pool->FreeDescriptors); Free(pool->FreeDescriptors);
ArenaRelease(pool->Arena);
Free(pool.Get()); Free(pool.Get());
} }
} // namespace Juliet::D3D12::Internal } // namespace Juliet::D3D12::Internal
-1
View File
@@ -22,7 +22,6 @@ namespace Juliet::D3D12
struct D3D12StagingDescriptorPool struct D3D12StagingDescriptorPool
{ {
Arena* Arena;
Internal::D3D12DescriptorHeap** Heaps; Internal::D3D12DescriptorHeap** Heaps;
uint32 HeapCount; uint32 HeapCount;
@@ -1,6 +1,7 @@
#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 <Core/Memory/Allocator.h>
#include <Graphics/D3D12/AgilitySDK/D3D12TokenizedProgramFormat.hpp>
#include <Graphics/D3D12/D3D12DescriptorHeap.h> #include <Graphics/D3D12/D3D12DescriptorHeap.h>
#include <Graphics/D3D12/D3D12GraphicsDevice.h> #include <Graphics/D3D12/D3D12GraphicsDevice.h>
#include <Graphics/D3D12/D3D12Utils.h> #include <Graphics/D3D12/D3D12Utils.h>
@@ -12,13 +13,12 @@ namespace Juliet::D3D12::Internal
{ {
// Heap pool is just single linked list of free elements // Heap pool is just single linked list of free elements
constexpr size_t kInitialCapacity = 4; constexpr size_t kInitialCapacity = 4;
heapPool.Arena = ArenaAllocate({} JULIET_DEBUG_ONLY(, "Descriptor Heap Pool"));
heapPool.FirstFreeDescriptorHeap = nullptr; heapPool.FirstFreeDescriptorHeap = nullptr;
// Pre allocate 4 // Pre allocate 4
for (uint32 i = 0; i < kInitialCapacity; ++i) for (uint32 i = 0; i < kInitialCapacity; ++i)
{ {
D3D12DescriptorHeap* descriptorHeap = CreateDescriptorHeap(driver, heapPool.Arena, type, count, false); D3D12DescriptorHeap* descriptorHeap = CreateDescriptorHeap(driver, type, count, false);
descriptorHeap->Next = heapPool.FirstFreeDescriptorHeap; descriptorHeap->Next = heapPool.FirstFreeDescriptorHeap;
heapPool.FirstFreeDescriptorHeap = descriptorHeap; heapPool.FirstFreeDescriptorHeap = descriptorHeap;
} }
@@ -33,18 +33,17 @@ namespace Juliet::D3D12::Internal
DestroyDescriptorHeap(current); DestroyDescriptorHeap(current);
current = next; current = next;
} }
ArenaRelease(heapPool.Arena);
} }
D3D12DescriptorHeap* CreateDescriptorHeap(NonNullPtr<D3D12Driver> driver, NonNullPtr<Arena> arena, D3D12DescriptorHeap* CreateDescriptorHeap(NonNullPtr<D3D12Driver> driver, D3D12_DESCRIPTOR_HEAP_TYPE type, uint32 count, bool isStaging)
D3D12_DESCRIPTOR_HEAP_TYPE type, uint32 count, bool isStaging)
{ {
D3D12DescriptorHeap* heap = ArenaPushStruct<D3D12DescriptorHeap>(arena.Get()); D3D12DescriptorHeap* heap = ArenaPushStruct<D3D12DescriptorHeap>(
driver->DriverArena JULIET_DEBUG_PARAM("Descriptor Heap Type {}", CStr(GetDescriptorTypeNane(type))));
Assert(heap); Assert(heap);
heap->CurrentDescriptorIndex = 0; heap->CurrentDescriptorIndex = 0;
heap->FreeIndices.Create(arena JULIET_DEBUG_PARAM("DescriptorHeap Free Indices")); heap->FreeIndices.Create(driver->DriverArena JULIET_DEBUG_PARAM("DescriptorHeap Free Indices"));
heap->FreeIndices.Resize(16); heap->FreeIndices.Resize(16);
heap->CurrentFreeIndex = 0; heap->CurrentFreeIndex = 0;
@@ -148,7 +147,7 @@ namespace Juliet::D3D12::Internal
} }
else else
{ {
result = CreateDescriptorHeap(d3d12Driver, pool.Arena, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, result = CreateDescriptorHeap(d3d12Driver, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER,
GPUDriver::kSampler_HeapDescriptorCount, false); GPUDriver::kSampler_HeapDescriptorCount, false);
} }
@@ -40,7 +40,6 @@ namespace Juliet::D3D12::Internal
struct D3D12DescriptorHeapPool struct D3D12DescriptorHeapPool
{ {
Arena* Arena;
D3D12DescriptorHeap* FirstFreeDescriptorHeap; D3D12DescriptorHeap* FirstFreeDescriptorHeap;
}; };
@@ -51,8 +50,8 @@ namespace Juliet::D3D12::Internal
D3D12_DESCRIPTOR_HEAP_TYPE type, uint32 count); D3D12_DESCRIPTOR_HEAP_TYPE type, uint32 count);
extern void DestroyDescriptorHeapPool(D3D12DescriptorHeapPool& pool); extern void DestroyDescriptorHeapPool(D3D12DescriptorHeapPool& pool);
extern D3D12DescriptorHeap* CreateDescriptorHeap(NonNullPtr<D3D12Driver> driver, NonNullPtr<Arena> arena, extern D3D12DescriptorHeap* CreateDescriptorHeap(NonNullPtr<D3D12Driver> driver, D3D12_DESCRIPTOR_HEAP_TYPE type,
D3D12_DESCRIPTOR_HEAP_TYPE type, uint32 count, bool isStaging); uint32 count, bool isStaging);
extern void DestroyDescriptorHeap(NonNullPtr<D3D12DescriptorHeap> heap); extern void DestroyDescriptorHeap(NonNullPtr<D3D12DescriptorHeap> heap);
extern D3D12DescriptorHeap* AcquireSamplerHeapFromPool(NonNullPtr<D3D12Driver> d3d12Driver); extern D3D12DescriptorHeap* AcquireSamplerHeapFromPool(NonNullPtr<D3D12Driver> d3d12Driver);
@@ -1058,9 +1058,8 @@ namespace Juliet::D3D12
driver->GraphicsDevice = device; driver->GraphicsDevice = device;
// Create Global Bindless Heap that stays alive for the driver whole lifetime // Create Global Bindless Heap that stays alive for the driver whole lifetime
driver->BindlessDescriptorHeap = driver->BindlessDescriptorHeap = Internal::CreateDescriptorHeap(driver, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV,
Internal::CreateDescriptorHeap(driver, driver->DriverArena, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, GPUDriver::kCBV_SRV_UAV_HeapDescriptorCount, false);
GPUDriver::kCBV_SRV_UAV_HeapDescriptorCount, false);
return device; return device;
} }
+15
View File
@@ -53,4 +53,19 @@ namespace Juliet::D3D12
Log(LogLevel::Error, LogCategory::Graphics, "%s! Error: %s" HRESULT_FMT, errorMessage, wszMsgBuff, result); Log(LogLevel::Error, LogCategory::Graphics, "%s! Error: %s" HRESULT_FMT, errorMessage, wszMsgBuff, result);
} }
#if JULIET_DEBUG
String GetDescriptorTypeNane(D3D12_DESCRIPTOR_HEAP_TYPE type)
{
switch (type)
{
case D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV: return WrapString("D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV");
case D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER: return WrapString("D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER");
case D3D12_DESCRIPTOR_HEAP_TYPE_RTV: return WrapString("D3D12_DESCRIPTOR_HEAP_TYPE_RTV");
case D3D12_DESCRIPTOR_HEAP_TYPE_DSV: return WrapString("D3D12_DESCRIPTOR_HEAP_TYPE_DSV");
case D3D12_DESCRIPTOR_HEAP_TYPE_NUM_TYPES: return WrapString("Invalid");
}
return WrapString("Invalid");
}
#endif
} // namespace Juliet::D3D12 } // namespace Juliet::D3D12
+4
View File
@@ -15,4 +15,8 @@ namespace Juliet::D3D12
struct D3D12Driver; struct D3D12Driver;
extern void LogError(NonNullPtr<ID3D12Device5> D3D12Device, const char* errorMessage, HRESULT result); extern void LogError(NonNullPtr<ID3D12Device5> D3D12Device, const char* errorMessage, HRESULT result);
#if JULIET_DEBUG
String GetDescriptorTypeNane(D3D12_DESCRIPTOR_HEAP_TYPE type);
#endif
} // namespace Juliet::D3D12 } // namespace Juliet::D3D12