Adapting arena push to support format as debug tag
Changed some d3d12 to work better with arenas
This commit is contained in:
@@ -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`.
|
|
||||||
@@ -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
|
||||||
|
|||||||
@@ -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>>,
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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*/)
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user