diff --git a/Juliet/Juliet.vcxproj b/Juliet/Juliet.vcxproj
index 5e8ad2d..77e03f3 100644
--- a/Juliet/Juliet.vcxproj
+++ b/Juliet/Juliet.vcxproj
@@ -227,6 +227,10 @@
+
+
+
+
{ab9c7e88-6c94-4f93-bc2a-7f5284b7d434}
diff --git a/Juliet/include/Core/Container/Vector.h b/Juliet/include/Core/Container/Vector.h
index 6496b26..f26909a 100644
--- a/Juliet/include/Core/Container/Vector.h
+++ b/Juliet/include/Core/Container/Vector.h
@@ -98,6 +98,34 @@ namespace Juliet
}
}
+ void PushBack(const Type* buffer, size_t amount)
+ {
+ Assert(Arena);
+
+ if (Count + amount > Capacity)
+ {
+ if (Capacity == 0 && Count + amount < ReserveSize)
+ {
+ Reserve(ReserveSize);
+ }
+ else
+ {
+ size_t newCapacity = Max(Capacity * 2, AlignPow2(Capacity + amount, AlignOf(Type)));
+ Reserve(newCapacity);
+ }
+ }
+
+ Type* dst = Data + Count;
+ MemCopy(dst, buffer, amount * sizeof(Type));
+
+ if (Count == 0)
+ {
+ DataFirst = dst;
+ }
+ DataLast = dst + amount;
+ Count += amount;
+ }
+
void PushBack(const Type& value)
{
Assert(Arena);
@@ -172,6 +200,8 @@ namespace Juliet
Capacity = 0;
}
+ bool IsEmpty() const { return Count == 0; }
+
// C++ Accessors for loop supports and Index based access
Type& operator[](size_t index) { return DataFirst[index]; }
const Type& operator[](size_t index) const { return DataFirst[index]; }
diff --git a/Juliet/include/Graphics/Mesh.h b/Juliet/include/Graphics/Mesh.h
index cbdd4be..58ffa56 100644
--- a/Juliet/include/Graphics/Mesh.h
+++ b/Juliet/include/Graphics/Mesh.h
@@ -11,18 +11,10 @@ namespace Juliet
struct Mesh
{
- Vertex* Vertices;
- uint16* Indices;
-
size_t VertexCount;
size_t IndexCount;
index_t VertexOffset;
index_t IndexOffset;
- index_t IndexByteOffset;
};
-
- JULIET_API Mesh* CreateCubeMesh(NonNullPtr arena);
- JULIET_API Mesh* CreateQuadMesh(NonNullPtr arena);
- JULIET_API void DestroyMesh(NonNullPtr mesh);
} // namespace Juliet
diff --git a/Juliet/include/Graphics/MeshRenderer.h b/Juliet/include/Graphics/MeshRenderer.h
new file mode 100644
index 0000000..769001f
--- /dev/null
+++ b/Juliet/include/Graphics/MeshRenderer.h
@@ -0,0 +1,63 @@
+#pragma once
+
+#include
+#include
+#include
+#include
+
+namespace Juliet
+{
+ struct GraphicsTransferBuffer;
+ struct RenderPass;
+ struct CommandList;
+ struct GraphicsBuffer;
+ struct Window;
+ struct GraphicsPipeline;
+ struct GraphicsDevice;
+ struct Mesh;
+
+ using MeshID = index_t;
+
+ constexpr size_t kGeometryPage = Megabytes(64);
+ constexpr size_t kIndexPage = Megabytes(32);
+ constexpr size_t kDefaultMeshNumber = 500;
+ constexpr size_t kDefaultVertexCount = 2'000'000; // Fit less than one geometry page
+ constexpr size_t kDefaultIndexCount = 16'000'000; // Fit less than one index page
+
+ struct MeshRenderer
+ {
+ // Note we prevent realloc for now.
+ VectorArena Meshes;
+ VectorArena Vertices;
+ VectorArena Indices;
+
+ GraphicsBuffer* VertexBuffer;
+ GraphicsBuffer* IndexBuffer;
+ GraphicsTransferBuffer* StreamCopyBuffer;
+ GraphicsTransferBuffer* LoadCopyBuffer;
+
+ GraphicsDevice* Device;
+ GraphicsPipeline* Pipeline;
+ };
+
+ struct PushData
+ {
+ Matrix ViewProjection;
+ uint32 BufferIndex;
+ };
+
+ [[nodiscard]] JULIET_API bool InitializeMeshRenderer(NonNullPtr arena, NonNullPtr device,
+ NonNullPtr window);
+ JULIET_API void ShutdownMeshRenderer();
+ JULIET_API void LoadMeshesOnGPU(NonNullPtr cmdList);
+ JULIET_API void RenderMeshes(NonNullPtr pass, NonNullPtr cmdList, PushData& pushData);
+
+ // Utils
+ [[nodiscard]] JULIET_API MeshID AddCube();
+ [[nodiscard]] JULIET_API MeshID AddQuad();
+
+#if ALLOW_SHADER_HOT_RELOAD
+ JULIET_API void ReloadMeshRendererShaders();
+#endif
+
+} // namespace Juliet
diff --git a/Juliet/include/Graphics/VertexData.h b/Juliet/include/Graphics/VertexData.h
index 10f714b..2de9735 100644
--- a/Juliet/include/Graphics/VertexData.h
+++ b/Juliet/include/Graphics/VertexData.h
@@ -7,4 +7,6 @@ namespace Juliet
float Position[3];
float Color[4];
};
+
+ using Index = uint16;
} // namespace Juliet
diff --git a/Juliet/src/Engine/Engine.cpp b/Juliet/src/Engine/Engine.cpp
index bc6cb1f..b8fd099 100644
--- a/Juliet/src/Engine/Engine.cpp
+++ b/Juliet/src/Engine/Engine.cpp
@@ -42,15 +42,15 @@ namespace Juliet
#ifdef JULIET_ENABLE_IMGUI
if (NonNullPtr window = EngineInstance.Application->GetPlatformWindow())
{
- ImGuiService::Initialize(window);
- ImGui::SetCurrentContext(ImGuiService::GetContext());
+ // ImGuiService::Initialize(window);
+ // ImGui::SetCurrentContext(ImGuiService::GetContext());
if (device)
{
- ImGuiRenderer_Initialize(device);
+ // ImGuiRenderer_Initialize(device);
// Run Unit Tests automatically
- ImGuiService::RunTests();
+ // ImGuiService::RunTests();
}
}
#endif
@@ -64,9 +64,9 @@ namespace Juliet
#ifdef JULIET_ENABLE_IMGUI
if (device)
{
- ImGuiRenderer_Shutdown(device);
+ // ImGuiRenderer_Shutdown(device);
}
- ImGuiService::Shutdown();
+ // ImGuiService::Shutdown();
#endif
// DebugDisplay system
@@ -107,7 +107,7 @@ namespace Juliet
EngineInstance.Application->OnPreRender(cmdList);
// Prepare debug display data (before render pass)
- DebugDisplay_Prepare(cmdList);
+ // DebugDisplay_Prepare(cmdList);
// Get render targets from application
ColorTargetInfo colorInfo = EngineInstance.Application->GetColorTargetInfo(swapChainTexture);
@@ -119,12 +119,12 @@ namespace Juliet
EngineInstance.Application->OnRender(pass, cmdList);
// Debug display flush (inside render pass)
- Camera debugCamera = EngineInstance.Application->GetDebugCamera();
- DebugDisplay_Flush(cmdList, pass, debugCamera);
+ // Camera debugCamera = EngineInstance.Application->GetDebugCamera();
+ // DebugDisplay_Flush(cmdList, pass, debugCamera);
#ifdef JULIET_ENABLE_IMGUI
// ImGui rendering (always last before EndRenderPass)
- ImGuiRenderer_Render(cmdList, pass);
+ // ImGuiRenderer_Render(cmdList, pass);
#endif
EndRenderPass(pass);
@@ -178,7 +178,7 @@ namespace Juliet
while (EngineInstance.Application->IsRunning())
{
#ifdef JULIET_ENABLE_IMGUI
- ImGuiRenderer_NewFrame();
+ // ImGuiRenderer_NewFrame();
#endif
// Logic tick
diff --git a/Juliet/src/Graphics/D3D12/D3D12Buffer.cpp b/Juliet/src/Graphics/D3D12/D3D12Buffer.cpp
index 78962b0..71adce5 100644
--- a/Juliet/src/Graphics/D3D12/D3D12Buffer.cpp
+++ b/Juliet/src/Graphics/D3D12/D3D12Buffer.cpp
@@ -113,10 +113,10 @@ namespace Juliet::D3D12
{
heapProperties.Type = D3D12_HEAP_TYPE_UPLOAD;
heapFlags = D3D12_HEAP_FLAG_ALLOW_ONLY_BUFFERS;
+ initialState = D3D12_RESOURCE_STATE_GENERIC_READ;
}
heapProperties.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
heapProperties.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;
- initialState = D3D12_RESOURCE_STATE_GENERIC_READ;
break;
}
@@ -142,10 +142,10 @@ namespace Juliet::D3D12
{
heapProperties.Type = D3D12_HEAP_TYPE_UPLOAD;
heapFlags = D3D12_HEAP_FLAG_ALLOW_ONLY_BUFFERS;
+ initialState = D3D12_RESOURCE_STATE_GENERIC_READ;
}
heapProperties.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
heapProperties.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;
- initialState = D3D12_RESOURCE_STATE_GENERIC_READ;
break;
}
}
diff --git a/Juliet/src/Graphics/D3D12/D3D12CommandList.cpp b/Juliet/src/Graphics/D3D12/D3D12CommandList.cpp
index a0f7085..f511972 100644
--- a/Juliet/src/Graphics/D3D12/D3D12CommandList.cpp
+++ b/Juliet/src/Graphics/D3D12/D3D12CommandList.cpp
@@ -246,7 +246,8 @@ namespace Juliet::D3D12
d3d12Driver->GraphicsQueue->ExecuteCommandLists(1, ppCommandLists);
// Acquire a fence and set it to the in-flight fence
- d3d12CommandList->InFlightFence = Internal::AcquireFence(d3d12Driver);
+ d3d12CommandList->InFlightFence =
+ Internal::AcquireFence(d3d12Driver JULIET_DEBUG_PARAM(ConstString("SubmitCommandLists")));
if (!d3d12CommandList->InFlightFence)
{
return false;
@@ -487,7 +488,8 @@ namespace Juliet::D3D12
// Release Fence if needed
if (commandList->AutoReleaseFence)
{
- ReleaseFence(driver.Get(), reinterpret_cast(commandList->InFlightFence));
+ ReleaseFence(driver.Get(), reinterpret_cast(commandList->InFlightFence)
+ JULIET_DEBUG_PARAM(ConstString("CleanCommandList")));
commandList->InFlightFence = nullptr;
}
diff --git a/Juliet/src/Graphics/D3D12/D3D12GraphicsDevice.cpp b/Juliet/src/Graphics/D3D12/D3D12GraphicsDevice.cpp
index a2e0146..d9d17eb 100644
--- a/Juliet/src/Graphics/D3D12/D3D12GraphicsDevice.cpp
+++ b/Juliet/src/Graphics/D3D12/D3D12GraphicsDevice.cpp
@@ -604,7 +604,8 @@ namespace Juliet::D3D12
{
if (windowData->InFlightFences[idx] != nullptr)
{
- ReleaseFence(driver, windowData->InFlightFences[idx]);
+ ReleaseFence(driver,
+ windowData->InFlightFences[idx] JULIET_DEBUG_PARAM(ConstString("DeatchFromWindow")));
windowData->InFlightFences[idx] = nullptr;
}
}
diff --git a/Juliet/src/Graphics/D3D12/D3D12SwapChain.cpp b/Juliet/src/Graphics/D3D12/D3D12SwapChain.cpp
index d686711..4f91875 100644
--- a/Juliet/src/Graphics/D3D12/D3D12SwapChain.cpp
+++ b/Juliet/src/Graphics/D3D12/D3D12SwapChain.cpp
@@ -140,7 +140,8 @@ namespace Juliet::D3D12
{
// Wait until the fence for the frame is signaled.
// In VSYNC this means waiting that the least recent presented frame is done
- if (!Wait(driver, true, &windowData->InFlightFences[windowData->WindowFrameCounter], 1))
+ if (!Wait(driver, true, &windowData->InFlightFences[windowData->WindowFrameCounter],
+ 1 JULIET_DEBUG_PARAM(ConstString("AcquireSwapChainTexture"))))
{
return false;
}
@@ -155,7 +156,8 @@ namespace Juliet::D3D12
}
}
- ReleaseFence(driver, windowData->InFlightFences[windowData->WindowFrameCounter]);
+ ReleaseFence(driver, windowData->InFlightFences[windowData->WindowFrameCounter] JULIET_DEBUG_PARAM(
+ ConstString("AcquireSwapChainTexture")));
windowData->InFlightFences[windowData->WindowFrameCounter] = nullptr;
}
@@ -219,7 +221,8 @@ namespace Juliet::D3D12
if (windowData->InFlightFences[windowData->WindowFrameCounter] != nullptr)
{
- if (!Wait(d3d12Driver, true, &windowData->InFlightFences[windowData->WindowFrameCounter], 1))
+ if (!Wait(d3d12Driver, true, &windowData->InFlightFences[windowData->WindowFrameCounter],
+ 1 JULIET_DEBUG_PARAM(ConstString("WaitForSwapchain"))))
{
return false;
}
diff --git a/Juliet/src/Graphics/D3D12/D3D12Synchronization.cpp b/Juliet/src/Graphics/D3D12/D3D12Synchronization.cpp
index 2cc8262..6705bb0 100644
--- a/Juliet/src/Graphics/D3D12/D3D12Synchronization.cpp
+++ b/Juliet/src/Graphics/D3D12/D3D12Synchronization.cpp
@@ -17,16 +17,21 @@ namespace Juliet::D3D12
driver->AvailableFenceCapacity = driver->AvailableFenceCapacity * 2;
driver->AvailableFences = static_cast(
Realloc(driver->AvailableFences, sizeof(D3D12Fence*) * driver->AvailableFenceCapacity));
+
+ LogMessage(LogCategory::Core, "ReleaseFenceToPool With Realloc");
}
driver->AvailableFences[driver->AvailableFenceCount] = fence;
driver->AvailableFenceCount += 1;
+
+ LogMessage(LogCategory::Core, "ReleaseFenceToPool %x fence. Handle %x | Event %x | Refcount %d",
+ fence.Get(), fence->Handle, fence->Event, fence->ReferenceCount);
}
} // namespace
bool WaitUntilGPUIsIdle(NonNullPtr driver)
{
auto d3d12driver = static_cast(driver.Get());
- D3D12Fence* fence = Internal::AcquireFence(d3d12driver);
+ D3D12Fence* fence = Internal::AcquireFence(d3d12driver JULIET_DEBUG_PARAM(ConstString("WaitUntilGPUIsIdle")));
if (!fence)
{
return false;
@@ -56,7 +61,7 @@ namespace Juliet::D3D12
}
}
- ReleaseFence(driver, reinterpret_cast(fence));
+ ReleaseFence(driver, reinterpret_cast(fence) JULIET_DEBUG_PARAM(ConstString("WaitUntilGPUIsIdle")));
bool result = true;
@@ -71,16 +76,17 @@ namespace Juliet::D3D12
return result;
}
- bool Wait(NonNullPtr driver, bool waitForAll, Fence* const* fences, uint32 numFences)
+ bool Wait(NonNullPtr driver, bool waitForAll, Fence* const* fences, uint32 numFences JULIET_DEBUG_PARAM(String querier))
{
auto d3d12driver = static_cast(driver.Get());
// TODO: use scratch allocator for alloca (stack alloc)
- auto events = static_cast(alloca(sizeof(HANDLE) * numFences));
+ HANDLE* events = static_cast(alloca(sizeof(HANDLE) * numFences));
+ MemoryZero(events, sizeof(HANDLE) * numFences);
for (uint32 i = 0; i < numFences; ++i)
{
- auto fence = reinterpret_cast(fences[i]);
+ D3D12Fence* fence = reinterpret_cast(fences[i]);
HRESULT res = fence->Handle->SetEventOnCompletion(D3D12_FENCE_SIGNAL_VALUE, fence->Event);
if (FAILED(res))
@@ -91,6 +97,13 @@ namespace Juliet::D3D12
events[i] = fence->Event;
}
+ LogMessage(LogCategory::Core, "Waiting for %d fences. Querier %s", numFences, CStr(querier));
+ for (uint32 i = 0; i < numFences; ++i)
+ {
+ D3D12Fence* d3d12fence = reinterpret_cast(fences[i]);
+ LogMessage(LogCategory::Core, "Waiting for %x fence. Handle %x | Event %x | Refcount %d", d3d12fence,
+ d3d12fence->Handle, d3d12fence->Event, d3d12fence->ReferenceCount);
+ }
DWORD waitResult = WaitForMultipleObjects(numFences, events, waitForAll, INFINITE);
if (waitResult == WAIT_FAILED)
@@ -122,11 +135,13 @@ namespace Juliet::D3D12
return true;
}
- void ReleaseFence(NonNullPtr driver, NonNullPtr fence)
+ void ReleaseFence(NonNullPtr driver, NonNullPtr fence JULIET_DEBUG_PARAM(String querier))
{
auto d3d12driver = static_cast(driver.Get());
auto d3d12Fence = reinterpret_cast(fence.Get());
+ LogMessage(LogCategory::Core, "ReleaseFence Querier %s | %x fence. Handle %x | Event %x | Refcount %d",
+ CStr(querier), d3d12Fence, d3d12Fence->Handle, d3d12Fence->Event, d3d12Fence->ReferenceCount);
if (--d3d12Fence->ReferenceCount == 0)
{
ReleaseFenceToPool(d3d12driver, d3d12Fence);
@@ -170,7 +185,7 @@ namespace Juliet::D3D12
}
}
- D3D12Fence* AcquireFence(NonNullPtr driver)
+ D3D12Fence* AcquireFence(NonNullPtr driver JULIET_DEBUG_PARAM(String querier))
{
D3D12Fence* fence;
ID3D12Fence* handle;
@@ -180,7 +195,7 @@ namespace Juliet::D3D12
if (driver->AvailableFenceCount == 0)
{
HRESULT result = driver->D3D12Device->CreateFence(D3D12_FENCE_UNSIGNALED_VALUE, D3D12_FENCE_FLAG_NONE,
- IID_ID3D12Fence, reinterpret_cast(&handle));
+ IID_ID3D12Fence, reinterpret_cast(&handle));
if (FAILED(result))
{
LogError(driver->D3D12Device, "Failed to create fence!", result);
@@ -197,15 +212,22 @@ namespace Juliet::D3D12
fence->Handle = handle;
fence->Event = CreateEvent(nullptr, false, false, nullptr);
fence->ReferenceCount = 0;
+ LogMessage(LogCategory::Core, "Acquire Querier %s | Setting Signal to 0 NEW fence", CStr(querier));
}
else
{
fence = driver->AvailableFences[driver->AvailableFenceCount - 1];
driver->AvailableFenceCount -= 1;
fence->Handle->Signal(D3D12_FENCE_UNSIGNALED_VALUE);
+ LogMessage(LogCategory::Core, "Acquire Querier %s | Setting Signal to 0, RECYCLING", CStr(querier));
}
fence->ReferenceCount += 1;
+ Assert(fence->ReferenceCount == 1);
+
+ LogMessage(LogCategory::Core, "Acquire Querier %s | %x fence. Handle %x | Event %x | Refcount %d",
+ CStr(querier), fence, fence->Handle, fence->Event, fence->ReferenceCount);
+
return fence;
}
diff --git a/Juliet/src/Graphics/D3D12/D3D12Synchronization.h b/Juliet/src/Graphics/D3D12/D3D12Synchronization.h
index fd1c7e7..746966e 100644
--- a/Juliet/src/Graphics/D3D12/D3D12Synchronization.h
+++ b/Juliet/src/Graphics/D3D12/D3D12Synchronization.h
@@ -26,9 +26,10 @@ namespace Juliet::D3D12
};
extern bool WaitUntilGPUIsIdle(NonNullPtr driver);
- extern bool Wait(NonNullPtr driver, bool waitForAll, Fence* const* fences, uint32 numFences);
+ extern bool Wait(NonNullPtr driver, bool waitForAll, Fence* const* fences,
+ uint32 numFences JULIET_DEBUG_PARAM(String querier));
extern bool QueryFence(NonNullPtr driver, NonNullPtr fence);
- extern void ReleaseFence(NonNullPtr driver, NonNullPtr fence);
+ extern void ReleaseFence(NonNullPtr driver, NonNullPtr fence JULIET_DEBUG_PARAM(String querier));
namespace Internal
{
@@ -36,7 +37,7 @@ namespace Juliet::D3D12
D3D12_RESOURCE_STATES destinationState, ID3D12Resource* resource,
uint32 subresourceIndex, bool needsUavBarrier);
- extern D3D12Fence* AcquireFence(NonNullPtr driver);
+ extern D3D12Fence* AcquireFence(NonNullPtr driver JULIET_DEBUG_PARAM(String querier));
extern void DestroyFence(NonNullPtr fence);
} // namespace Internal
} // namespace Juliet::D3D12
diff --git a/Juliet/src/Graphics/D3D12/D3D12Texture.cpp b/Juliet/src/Graphics/D3D12/D3D12Texture.cpp
index ff0d00b..4a286c9 100644
--- a/Juliet/src/Graphics/D3D12/D3D12Texture.cpp
+++ b/Juliet/src/Graphics/D3D12/D3D12Texture.cpp
@@ -1,124 +1,124 @@
+#include
#include
#include
#include
+#include
#include
+#include
#include
#include
-#include
#include
-#include
-#include
namespace Juliet::D3D12
{
namespace
{
DXGI_FORMAT JulietToD3D12_TextureFormat[] = {
- DXGI_FORMAT_UNKNOWN, // INVALID
- DXGI_FORMAT_A8_UNORM, // A8_UNORM
- DXGI_FORMAT_R8_UNORM, // R8_UNORM
- DXGI_FORMAT_R8G8_UNORM, // R8G8_UNORM
- DXGI_FORMAT_R8G8B8A8_UNORM, // R8G8B8A8_UNORM
- DXGI_FORMAT_R16_UNORM, // R16_UNORM
- DXGI_FORMAT_R16G16_UNORM, // R16G16_UNORM
- DXGI_FORMAT_R16G16B16A16_UNORM, // R16G16B16A16_UNORM
- DXGI_FORMAT_R10G10B10A2_UNORM, // R10G10B10A2_UNORM
- DXGI_FORMAT_B5G6R5_UNORM, // B5G6R5_UNORM
- DXGI_FORMAT_B5G5R5A1_UNORM, // B5G5R5A1_UNORM
- DXGI_FORMAT_B4G4R4A4_UNORM, // B4G4R4A4_UNORM
- DXGI_FORMAT_B8G8R8A8_UNORM, // B8G8R8A8_UNORM
- DXGI_FORMAT_BC1_UNORM, // BC1_UNORM
- DXGI_FORMAT_BC2_UNORM, // BC2_UNORM
- DXGI_FORMAT_BC3_UNORM, // BC3_UNORM
- DXGI_FORMAT_BC4_UNORM, // BC4_UNORM
- DXGI_FORMAT_BC5_UNORM, // BC5_UNORM
- DXGI_FORMAT_BC7_UNORM, // BC7_UNORM
- DXGI_FORMAT_BC6H_SF16, // BC6H_FLOAT
- DXGI_FORMAT_BC6H_UF16, // BC6H_UFLOAT
- DXGI_FORMAT_R8_SNORM, // R8_SNORM
- DXGI_FORMAT_R8G8_SNORM, // R8G8_SNORM
- DXGI_FORMAT_R8G8B8A8_SNORM, // R8G8B8A8_SNORM
- DXGI_FORMAT_R16_SNORM, // R16_SNORM
- DXGI_FORMAT_R16G16_SNORM, // R16G16_SNORM
- DXGI_FORMAT_R16G16B16A16_SNORM, // R16G16B16A16_SNORM
- DXGI_FORMAT_R16_FLOAT, // R16_FLOAT
- DXGI_FORMAT_R16G16_FLOAT, // R16G16_FLOAT
- DXGI_FORMAT_R16G16B16A16_FLOAT, // R16G16B16A16_FLOAT
- DXGI_FORMAT_R32_FLOAT, // R32_FLOAT
- DXGI_FORMAT_R32G32_FLOAT, // R32G32_FLOAT
- DXGI_FORMAT_R32G32B32A32_FLOAT, // R32G32B32A32_FLOAT
- DXGI_FORMAT_R11G11B10_FLOAT, // R11G11B10_UFLOAT
- DXGI_FORMAT_R8_UINT, // R8_UINT
- DXGI_FORMAT_R8G8_UINT, // R8G8_UINT
- DXGI_FORMAT_R8G8B8A8_UINT, // R8G8B8A8_UINT
- DXGI_FORMAT_R16_UINT, // R16_UINT
- DXGI_FORMAT_R16G16_UINT, // R16G16_UINT
- DXGI_FORMAT_R16G16B16A16_UINT, // R16G16B16A16_UINT
- DXGI_FORMAT_R32_UINT, // R32_UINT
- DXGI_FORMAT_R32G32_UINT, // R32G32_UINT
- DXGI_FORMAT_R32G32B32A32_UINT, // R32G32B32A32_UINT
- DXGI_FORMAT_R8_SINT, // R8_INT
- DXGI_FORMAT_R8G8_SINT, // R8G8_INT
- DXGI_FORMAT_R8G8B8A8_SINT, // R8G8B8A8_INT
- DXGI_FORMAT_R16_SINT, // R16_INT
- DXGI_FORMAT_R16G16_SINT, // R16G16_INT
- DXGI_FORMAT_R16G16B16A16_SINT, // R16G16B16A16_INT
- DXGI_FORMAT_R32_SINT, // R32_INT
- DXGI_FORMAT_R32G32_SINT, // R32G32_INT
- DXGI_FORMAT_R32G32B32A32_SINT, // R32G32B32A32_INT
- DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, // R8G8B8A8_UNORM_SRGB
- DXGI_FORMAT_B8G8R8A8_UNORM_SRGB, // B8G8R8A8_UNORM_SRGB
- DXGI_FORMAT_BC1_UNORM_SRGB, // BC1_UNORM_SRGB
- DXGI_FORMAT_BC2_UNORM_SRGB, // BC2_UNORM_SRGB
- DXGI_FORMAT_BC3_UNORM_SRGB, // BC3_UNORM_SRGB
- DXGI_FORMAT_BC7_UNORM_SRGB, // BC7_UNORM_SRGB
- DXGI_FORMAT_R16_TYPELESS, // D16_UNORM
- DXGI_FORMAT_R24G8_TYPELESS, // D24_UNORM
- DXGI_FORMAT_R32_TYPELESS, // D32_FLOAT
- DXGI_FORMAT_R24G8_TYPELESS, // D24_UNORM_S8_UINT
- DXGI_FORMAT_R32G8X24_TYPELESS, // D32_FLOAT_S8_UINT
- DXGI_FORMAT_UNKNOWN, // ASTC_4x4_UNORM
- DXGI_FORMAT_UNKNOWN, // ASTC_5x4_UNORM
- DXGI_FORMAT_UNKNOWN, // ASTC_5x5_UNORM
- DXGI_FORMAT_UNKNOWN, // ASTC_6x5_UNORM
- DXGI_FORMAT_UNKNOWN, // ASTC_6x6_UNORM
- DXGI_FORMAT_UNKNOWN, // ASTC_8x5_UNORM
- DXGI_FORMAT_UNKNOWN, // ASTC_8x6_UNORM
- DXGI_FORMAT_UNKNOWN, // ASTC_8x8_UNORM
- DXGI_FORMAT_UNKNOWN, // ASTC_10x5_UNORM
- DXGI_FORMAT_UNKNOWN, // ASTC_10x6_UNORM
- DXGI_FORMAT_UNKNOWN, // ASTC_10x8_UNORM
- DXGI_FORMAT_UNKNOWN, // ASTC_10x10_UNORM
- DXGI_FORMAT_UNKNOWN, // ASTC_12x10_UNORM
- DXGI_FORMAT_UNKNOWN, // ASTC_12x12_UNORM
- DXGI_FORMAT_UNKNOWN, // ASTC_4x4_UNORM_SRGB
- DXGI_FORMAT_UNKNOWN, // ASTC_5x4_UNORM_SRGB
- DXGI_FORMAT_UNKNOWN, // ASTC_5x5_UNORM_SRGB
- DXGI_FORMAT_UNKNOWN, // ASTC_6x5_UNORM_SRGB
- DXGI_FORMAT_UNKNOWN, // ASTC_6x6_UNORM_SRGB
- DXGI_FORMAT_UNKNOWN, // ASTC_8x5_UNORM_SRGB
- DXGI_FORMAT_UNKNOWN, // ASTC_8x6_UNORM_SRGB
- DXGI_FORMAT_UNKNOWN, // ASTC_8x8_UNORM_SRGB
- DXGI_FORMAT_UNKNOWN, // ASTC_10x5_UNORM_SRGB
- DXGI_FORMAT_UNKNOWN, // ASTC_10x6_UNORM_SRGB
- DXGI_FORMAT_UNKNOWN, // ASTC_10x8_UNORM_SRGB
- DXGI_FORMAT_UNKNOWN, // ASTC_10x10_UNORM_SRGB
- DXGI_FORMAT_UNKNOWN, // ASTC_12x10_UNORM_SRGB
- DXGI_FORMAT_UNKNOWN, // ASTC_12x12_UNORM_SRGB
- DXGI_FORMAT_UNKNOWN, // ASTC_4x4_FLOAT
- DXGI_FORMAT_UNKNOWN, // ASTC_5x4_FLOAT
- DXGI_FORMAT_UNKNOWN, // ASTC_5x5_FLOAT
- DXGI_FORMAT_UNKNOWN, // ASTC_6x5_FLOAT
- DXGI_FORMAT_UNKNOWN, // ASTC_6x6_FLOAT
- DXGI_FORMAT_UNKNOWN, // ASTC_8x5_FLOAT
- DXGI_FORMAT_UNKNOWN, // ASTC_8x6_FLOAT
- DXGI_FORMAT_UNKNOWN, // ASTC_8x8_FLOAT
- DXGI_FORMAT_UNKNOWN, // ASTC_10x5_FLOAT
- DXGI_FORMAT_UNKNOWN, // ASTC_10x6_FLOAT
- DXGI_FORMAT_UNKNOWN, // ASTC_10x8_FLOAT
- DXGI_FORMAT_UNKNOWN, // ASTC_10x10_FLOAT
- DXGI_FORMAT_UNKNOWN, // ASTC_12x10_FLOAT
- DXGI_FORMAT_UNKNOWN, // ASTC_12x12_FLOAT
+ DXGI_FORMAT_UNKNOWN, // INVALID
+ DXGI_FORMAT_A8_UNORM, // A8_UNORM
+ DXGI_FORMAT_R8_UNORM, // R8_UNORM
+ DXGI_FORMAT_R8G8_UNORM, // R8G8_UNORM
+ DXGI_FORMAT_R8G8B8A8_UNORM, // R8G8B8A8_UNORM
+ DXGI_FORMAT_R16_UNORM, // R16_UNORM
+ DXGI_FORMAT_R16G16_UNORM, // R16G16_UNORM
+ DXGI_FORMAT_R16G16B16A16_UNORM, // R16G16B16A16_UNORM
+ DXGI_FORMAT_R10G10B10A2_UNORM, // R10G10B10A2_UNORM
+ DXGI_FORMAT_B5G6R5_UNORM, // B5G6R5_UNORM
+ DXGI_FORMAT_B5G5R5A1_UNORM, // B5G5R5A1_UNORM
+ DXGI_FORMAT_B4G4R4A4_UNORM, // B4G4R4A4_UNORM
+ DXGI_FORMAT_B8G8R8A8_UNORM, // B8G8R8A8_UNORM
+ DXGI_FORMAT_BC1_UNORM, // BC1_UNORM
+ DXGI_FORMAT_BC2_UNORM, // BC2_UNORM
+ DXGI_FORMAT_BC3_UNORM, // BC3_UNORM
+ DXGI_FORMAT_BC4_UNORM, // BC4_UNORM
+ DXGI_FORMAT_BC5_UNORM, // BC5_UNORM
+ DXGI_FORMAT_BC7_UNORM, // BC7_UNORM
+ DXGI_FORMAT_BC6H_SF16, // BC6H_FLOAT
+ DXGI_FORMAT_BC6H_UF16, // BC6H_UFLOAT
+ DXGI_FORMAT_R8_SNORM, // R8_SNORM
+ DXGI_FORMAT_R8G8_SNORM, // R8G8_SNORM
+ DXGI_FORMAT_R8G8B8A8_SNORM, // R8G8B8A8_SNORM
+ DXGI_FORMAT_R16_SNORM, // R16_SNORM
+ DXGI_FORMAT_R16G16_SNORM, // R16G16_SNORM
+ DXGI_FORMAT_R16G16B16A16_SNORM, // R16G16B16A16_SNORM
+ DXGI_FORMAT_R16_FLOAT, // R16_FLOAT
+ DXGI_FORMAT_R16G16_FLOAT, // R16G16_FLOAT
+ DXGI_FORMAT_R16G16B16A16_FLOAT, // R16G16B16A16_FLOAT
+ DXGI_FORMAT_R32_FLOAT, // R32_FLOAT
+ DXGI_FORMAT_R32G32_FLOAT, // R32G32_FLOAT
+ DXGI_FORMAT_R32G32B32A32_FLOAT, // R32G32B32A32_FLOAT
+ DXGI_FORMAT_R11G11B10_FLOAT, // R11G11B10_UFLOAT
+ DXGI_FORMAT_R8_UINT, // R8_UINT
+ DXGI_FORMAT_R8G8_UINT, // R8G8_UINT
+ DXGI_FORMAT_R8G8B8A8_UINT, // R8G8B8A8_UINT
+ DXGI_FORMAT_R16_UINT, // R16_UINT
+ DXGI_FORMAT_R16G16_UINT, // R16G16_UINT
+ DXGI_FORMAT_R16G16B16A16_UINT, // R16G16B16A16_UINT
+ DXGI_FORMAT_R32_UINT, // R32_UINT
+ DXGI_FORMAT_R32G32_UINT, // R32G32_UINT
+ DXGI_FORMAT_R32G32B32A32_UINT, // R32G32B32A32_UINT
+ DXGI_FORMAT_R8_SINT, // R8_INT
+ DXGI_FORMAT_R8G8_SINT, // R8G8_INT
+ DXGI_FORMAT_R8G8B8A8_SINT, // R8G8B8A8_INT
+ DXGI_FORMAT_R16_SINT, // R16_INT
+ DXGI_FORMAT_R16G16_SINT, // R16G16_INT
+ DXGI_FORMAT_R16G16B16A16_SINT, // R16G16B16A16_INT
+ DXGI_FORMAT_R32_SINT, // R32_INT
+ DXGI_FORMAT_R32G32_SINT, // R32G32_INT
+ DXGI_FORMAT_R32G32B32A32_SINT, // R32G32B32A32_INT
+ DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, // R8G8B8A8_UNORM_SRGB
+ DXGI_FORMAT_B8G8R8A8_UNORM_SRGB, // B8G8R8A8_UNORM_SRGB
+ DXGI_FORMAT_BC1_UNORM_SRGB, // BC1_UNORM_SRGB
+ DXGI_FORMAT_BC2_UNORM_SRGB, // BC2_UNORM_SRGB
+ DXGI_FORMAT_BC3_UNORM_SRGB, // BC3_UNORM_SRGB
+ DXGI_FORMAT_BC7_UNORM_SRGB, // BC7_UNORM_SRGB
+ DXGI_FORMAT_R16_TYPELESS, // D16_UNORM
+ DXGI_FORMAT_R24G8_TYPELESS, // D24_UNORM
+ DXGI_FORMAT_R32_TYPELESS, // D32_FLOAT
+ DXGI_FORMAT_R24G8_TYPELESS, // D24_UNORM_S8_UINT
+ DXGI_FORMAT_R32G8X24_TYPELESS, // D32_FLOAT_S8_UINT
+ DXGI_FORMAT_UNKNOWN, // ASTC_4x4_UNORM
+ DXGI_FORMAT_UNKNOWN, // ASTC_5x4_UNORM
+ DXGI_FORMAT_UNKNOWN, // ASTC_5x5_UNORM
+ DXGI_FORMAT_UNKNOWN, // ASTC_6x5_UNORM
+ DXGI_FORMAT_UNKNOWN, // ASTC_6x6_UNORM
+ DXGI_FORMAT_UNKNOWN, // ASTC_8x5_UNORM
+ DXGI_FORMAT_UNKNOWN, // ASTC_8x6_UNORM
+ DXGI_FORMAT_UNKNOWN, // ASTC_8x8_UNORM
+ DXGI_FORMAT_UNKNOWN, // ASTC_10x5_UNORM
+ DXGI_FORMAT_UNKNOWN, // ASTC_10x6_UNORM
+ DXGI_FORMAT_UNKNOWN, // ASTC_10x8_UNORM
+ DXGI_FORMAT_UNKNOWN, // ASTC_10x10_UNORM
+ DXGI_FORMAT_UNKNOWN, // ASTC_12x10_UNORM
+ DXGI_FORMAT_UNKNOWN, // ASTC_12x12_UNORM
+ DXGI_FORMAT_UNKNOWN, // ASTC_4x4_UNORM_SRGB
+ DXGI_FORMAT_UNKNOWN, // ASTC_5x4_UNORM_SRGB
+ DXGI_FORMAT_UNKNOWN, // ASTC_5x5_UNORM_SRGB
+ DXGI_FORMAT_UNKNOWN, // ASTC_6x5_UNORM_SRGB
+ DXGI_FORMAT_UNKNOWN, // ASTC_6x6_UNORM_SRGB
+ DXGI_FORMAT_UNKNOWN, // ASTC_8x5_UNORM_SRGB
+ DXGI_FORMAT_UNKNOWN, // ASTC_8x6_UNORM_SRGB
+ DXGI_FORMAT_UNKNOWN, // ASTC_8x8_UNORM_SRGB
+ DXGI_FORMAT_UNKNOWN, // ASTC_10x5_UNORM_SRGB
+ DXGI_FORMAT_UNKNOWN, // ASTC_10x6_UNORM_SRGB
+ DXGI_FORMAT_UNKNOWN, // ASTC_10x8_UNORM_SRGB
+ DXGI_FORMAT_UNKNOWN, // ASTC_10x10_UNORM_SRGB
+ DXGI_FORMAT_UNKNOWN, // ASTC_12x10_UNORM_SRGB
+ DXGI_FORMAT_UNKNOWN, // ASTC_12x12_UNORM_SRGB
+ DXGI_FORMAT_UNKNOWN, // ASTC_4x4_FLOAT
+ DXGI_FORMAT_UNKNOWN, // ASTC_5x4_FLOAT
+ DXGI_FORMAT_UNKNOWN, // ASTC_5x5_FLOAT
+ DXGI_FORMAT_UNKNOWN, // ASTC_6x5_FLOAT
+ DXGI_FORMAT_UNKNOWN, // ASTC_6x6_FLOAT
+ DXGI_FORMAT_UNKNOWN, // ASTC_8x5_FLOAT
+ DXGI_FORMAT_UNKNOWN, // ASTC_8x6_FLOAT
+ DXGI_FORMAT_UNKNOWN, // ASTC_8x8_FLOAT
+ DXGI_FORMAT_UNKNOWN, // ASTC_10x5_FLOAT
+ DXGI_FORMAT_UNKNOWN, // ASTC_10x6_FLOAT
+ DXGI_FORMAT_UNKNOWN, // ASTC_10x8_FLOAT
+ DXGI_FORMAT_UNKNOWN, // ASTC_10x10_FLOAT
+ DXGI_FORMAT_UNKNOWN, // ASTC_12x10_FLOAT
+ DXGI_FORMAT_UNKNOWN, // ASTC_12x12_FLOAT
};
static_assert(sizeof(JulietToD3D12_TextureFormat) / sizeof(JulietToD3D12_TextureFormat[0]) ==
ToUnderlying(TextureFormat::Count));
@@ -375,13 +375,9 @@ namespace Juliet::D3D12
case TextureType::Texture_2D:
case TextureType::Texture_2DArray:
case TextureType::Texture_Cube:
- case TextureType::Texture_CubeArray:
- desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
- break;
+ case TextureType::Texture_CubeArray: desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D; break;
case TextureType::Texture_3D:
- case TextureType::Texture_3DArray:
- desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE3D;
- break;
+ case TextureType::Texture_3DArray: desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE3D; break;
}
desc.Alignment = 0;
@@ -396,17 +392,27 @@ namespace Juliet::D3D12
desc.Flags = D3D12_RESOURCE_FLAG_NONE;
if ((createInfo.Flags & TextureUsageFlag::ColorTarget) != TextureUsageFlag::None)
+ {
desc.Flags |= D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET;
+ }
if ((createInfo.Flags & TextureUsageFlag::DepthStencilTarget) != TextureUsageFlag::None)
+ {
desc.Flags |= D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL;
+ }
if ((createInfo.Flags & TextureUsageFlag::ComputeStorageWrite) != TextureUsageFlag::None)
+ {
desc.Flags |= D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS;
+ }
D3D12_HEAP_PROPERTIES heapProps = {};
- heapProps.Type = D3D12_HEAP_TYPE_DEFAULT;
+ heapProps.Type = D3D12_HEAP_TYPE_DEFAULT;
+ heapProps.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
+ heapProps.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;
+ heapProps.CreationNodeMask = 0; // We don't do multi-adapter operation
+ heapProps.VisibleNodeMask = 0; // We don't do multi-adapter operation
- ID3D12Resource* resource = nullptr;
- D3D12_CLEAR_VALUE clearValue = {};
+ ID3D12Resource* resource = nullptr;
+ D3D12_CLEAR_VALUE clearValue = {};
D3D12_CLEAR_VALUE* pClearValue = nullptr;
if (desc.Flags & D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL)
@@ -426,9 +432,10 @@ namespace Juliet::D3D12
pClearValue = &clearValue;
}
+ D3D12_RESOURCE_STATES initialState = GetDefaultTextureResourceState(createInfo.Flags);
HRESULT hr = d3d12Driver->D3D12Device->CreateCommittedResource(&heapProps, D3D12_HEAP_FLAG_NONE, &desc,
- D3D12_RESOURCE_STATE_COMMON, pClearValue, IID_ID3D12Resource,
- reinterpret_cast(&resource));
+ initialState, pClearValue, IID_ID3D12Resource,
+ reinterpret_cast(&resource));
if (FAILED(hr))
{
@@ -451,10 +458,11 @@ namespace Juliet::D3D12
texture->Resource = resource;
texture->ReferenceCount = 1;
- uint32 numLayers = std::max(1, createInfo.LayerCount);
- uint32 numMips = std::max(1, createInfo.MipLevelCount);
+ uint32 numLayers = std::max(1, createInfo.LayerCount);
+ uint32 numMips = std::max(1, createInfo.MipLevelCount);
texture->SubresourceCount = numLayers * numMips;
- texture->Subresources = static_cast(Calloc(texture->SubresourceCount, sizeof(D3D12TextureSubresource)));
+ texture->Subresources =
+ static_cast(Calloc(texture->SubresourceCount, sizeof(D3D12TextureSubresource)));
for (uint32 layer = 0; layer < numLayers; ++layer)
{
@@ -499,14 +507,14 @@ namespace Juliet::D3D12
Internal::D3D12Descriptor descriptor;
if (Internal::AssignDescriptor(d3d12Driver->BindlessDescriptorHeap, descriptor))
{
- texture->SRVHandle = D3D12StagingDescriptor{};
+ texture->SRVHandle = D3D12StagingDescriptor{};
texture->SRVHandle.CpuHandleIndex = descriptor.Index;
- texture->SRVHandle.CpuHandle = descriptor.CpuHandle;
- texture->SRVHandle.Heap = descriptor.Heap;
+ texture->SRVHandle.CpuHandle = descriptor.CpuHandle;
+ texture->SRVHandle.Heap = descriptor.Heap;
D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc = {};
- srvDesc.Format = desc.Format;
-
+ srvDesc.Format = desc.Format;
+
// Fix SRV format for Depth Buffers (TypeLess -> Typed)
if (createInfo.Format == TextureFormat::D32_FLOAT)
srvDesc.Format = DXGI_FORMAT_R32_FLOAT;
@@ -517,11 +525,11 @@ namespace Juliet::D3D12
else if (createInfo.Format == TextureFormat::D32_FLOAT_S8_UINT)
srvDesc.Format = DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS;
- srvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
- srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D;
- srvDesc.Texture2D.MostDetailedMip = 0;
- srvDesc.Texture2D.MipLevels = numMips;
- srvDesc.Texture2D.PlaneSlice = 0;
+ srvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
+ srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D;
+ srvDesc.Texture2D.MostDetailedMip = 0;
+ srvDesc.Texture2D.MipLevels = numMips;
+ srvDesc.Texture2D.PlaneSlice = 0;
srvDesc.Texture2D.ResourceMinLODClamp = 0.0f;
d3d12Driver->D3D12Device->CreateShaderResourceView(resource, &srvDesc, descriptor.CpuHandle);
@@ -529,7 +537,6 @@ namespace Juliet::D3D12
}
return reinterpret_cast(textureContainer);
-
}
void DestroyTexture(NonNullPtr driver, NonNullPtr texture)
diff --git a/Juliet/src/Graphics/GraphicsDevice.h b/Juliet/src/Graphics/GraphicsDevice.h
index 60d1617..b740855 100644
--- a/Juliet/src/Graphics/GraphicsDevice.h
+++ b/Juliet/src/Graphics/GraphicsDevice.h
@@ -83,7 +83,7 @@ namespace Juliet
// Fences
bool (*WaitUntilGPUIsIdle)(NonNullPtr driver);
bool (*QueryFence)(NonNullPtr driver, NonNullPtr fence);
- void (*ReleaseFence)(NonNullPtr driver, NonNullPtr fence);
+ void (*ReleaseFence)(NonNullPtr driver, NonNullPtr fence JULIET_DEBUG_PARAM(String querier));
// Shaders
Shader* (*CreateShader)(NonNullPtr driver, ByteBuffer shaderByteCode, ShaderCreateInfo& shaderCreateInfo);
diff --git a/Juliet/src/Graphics/Mesh.cpp b/Juliet/src/Graphics/Mesh.cpp
index af5d3fc..e399355 100644
--- a/Juliet/src/Graphics/Mesh.cpp
+++ b/Juliet/src/Graphics/Mesh.cpp
@@ -5,95 +5,5 @@
namespace Juliet
{
- Mesh* CreateCubeMesh(NonNullPtr arena)
- {
- Mesh* result = ArenaPushStruct(arena.Get());
-
- constexpr Vertex vertexData[] = {
- // Front Face (Z = -0.5f)
- { { -0.5f, 0.5f, -0.5f }, { 0.0f, 0.0f } }, // 0: Top Left
- { { 0.5f, 0.5f, -0.5f }, { 1.0f, 0.0f } }, // 1: Top Right
- { { 0.5f, -0.5f, -0.5f }, { 1.0f, 1.0f } }, // 2: Bottom Right
- { { -0.5f, -0.5f, -0.5f }, { 0.0f, 1.0f } }, // 3: Bottom Left
-
- // Back Face (Z = 0.5f)
- { { 0.5f, 0.5f, 0.5f }, { 0.0f, 0.0f } }, // 4: Top Left
- { { -0.5f, 0.5f, 0.5f }, { 1.0f, 0.0f } }, // 5: Top Right
- { { -0.5f, -0.5f, 0.5f }, { 1.0f, 1.0f } }, // 6: Bottom Right
- { { 0.5f, -0.5f, 0.5f }, { 0.0f, 1.0f } }, // 7: Bottom Left
-
- // Top Face (Y = 0.5f)
- { { -0.5f, 0.5f, 0.5f }, { 0.0f, 0.0f } }, // 8: Top Left
- { { 0.5f, 0.5f, 0.5f }, { 1.0f, 0.0f } }, // 9: Top Right
- { { 0.5f, 0.5f, -0.5f }, { 1.0f, 1.0f } }, // 10: Bottom Right
- { { -0.5f, 0.5f, -0.5f }, { 0.0f, 1.0f } }, // 11: Bottom Left
-
- // Bottom Face (Y = -0.5f)
- { { -0.5f, -0.5f, -0.5f }, { 0.0f, 0.0f } }, // 12: Top Left
- { { 0.5f, -0.5f, -0.5f }, { 1.0f, 0.0f } }, // 13: Top Right
- { { 0.5f, -0.5f, 0.5f }, { 1.0f, 1.0f } }, // 14: Bottom Right
- { { -0.5f, -0.5f, 0.5f }, { 0.0f, 1.0f } }, // 15: Bottom Left
-
- // Right Face (X = 0.5f)
- { { 0.5f, 0.5f, -0.5f }, { 0.0f, 0.0f } }, // 16: Top Left
- { { 0.5f, 0.5f, 0.5f }, { 1.0f, 0.0f } }, // 17: Top Right
- { { 0.5f, -0.5f, 0.5f }, { 1.0f, 1.0f } }, // 18: Bottom Right
- { { 0.5f, -0.5f, -0.5f }, { 0.0f, 1.0f } }, // 19: Bottom Left
-
- // Left Face (X = -0.5f)
- { { -0.5f, 0.5f, 0.5f }, { 0.0f, 0.0f } }, // 20: Top Left
- { { -0.5f, 0.5f, -0.5f }, { 1.0f, 0.0f } }, // 21: Top Right
- { { -0.5f, -0.5f, -0.5f }, { 1.0f, 1.0f } }, // 22: Bottom Right
- { { -0.5f, -0.5f, 0.5f }, { 0.0f, 1.0f } } // 23: Bottom Left
- };
- constexpr size_t cubeVertexCount = ArraySize(vertexData);
- result->VertexCount = cubeVertexCount;
- result->Vertices = ArenaPushArray(arena.Get(), cubeVertexCount);
- MemCopy(result->Vertices, vertexData, sizeof(Vertex) * cubeVertexCount);
-
- constexpr uint16 indices[] = { 0, 1, 2, 0, 2, 3, // Front
- 4, 5, 6, 4, 6, 7, // Back
- 8, 9, 10, 8, 10, 11, // Top
- 12, 13, 14, 12, 14, 15, // Bottom
- 16, 17, 18, 16, 18, 19, // Right
- 20, 21, 22, 20, 22, 23 }; // Left
- constexpr size_t indexCubeCount = ArraySize(indices);
- result->IndexCount = indexCubeCount;
- result->Indices = ArenaPushArray(arena.Get(), indexCubeCount JULIET_DEBUG_PARAM("Indices"));
- MemCopy(result->Indices, indices, sizeof(uint16) * indexCubeCount);
-
- return result;
- }
-
- Mesh* CreateQuadMesh(NonNullPtr arena)
- {
- Mesh* result = ArenaPushStruct(arena.Get());
-
- // Using the exact 6 vertices from the working triangles!
- constexpr Vertex vertexData[] = {
- // Triangle 1 (Clockwise)
- { { -0.5f, -0.5f, 0.0f }, { 1.0f, 0.0f, 0.0f, 1.0f } }, // 0: Red
- { { 0.0f, 0.5f, 0.0f }, { 0.0f, 1.0f, 0.0f, 1.0f } }, // 1: Green
- { { 0.5f, -0.5f, 0.0f }, { 0.0f, 0.0f, 1.0f, 1.0f } }, // 2: Blue
-
- // Triangle 2 (Clockwise)
- { { -0.5f, 0.5f, 0.0f }, { 1.0f, 1.0f, 0.0f, 1.0f } }, // 3: Yellow
- { { 0.0f, 0.8f, 0.0f }, { 0.0f, 1.0f, 1.0f, 1.0f } }, // 4: Cyan
- { { 0.5f, 0.5f, 0.0f }, { 1.0f, 0.0f, 1.0f, 1.0f } } // 5: Magenta
- };
- constexpr size_t triVertexCount = ArraySize(vertexData);
- result->VertexCount = triVertexCount;
- result->Vertices = ArenaPushArray(arena.Get(), triVertexCount);
- MemCopy(result->Vertices, vertexData, sizeof(Vertex) * triVertexCount);
-
- // Just the 6 indices for the two triangles
- constexpr uint16 indices[] = { 0, 1, 2, 3, 4, 5 };
- constexpr size_t triIndexCount = ArraySize(indices);
- result->IndexCount = triIndexCount;
- result->Indices = ArenaPushArray(arena.Get(), triIndexCount JULIET_DEBUG_PARAM("Indices"));
- MemCopy(result->Indices, indices, sizeof(uint16) * triIndexCount);
-
- return result;
- }
} // namespace Juliet
diff --git a/Juliet/src/Graphics/MeshRenderer.cpp b/Juliet/src/Graphics/MeshRenderer.cpp
new file mode 100644
index 0000000..9e2bde4
--- /dev/null
+++ b/Juliet/src/Graphics/MeshRenderer.cpp
@@ -0,0 +1,315 @@
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+namespace Juliet
+{
+ namespace
+ {
+ MeshRenderer g_MeshRenderer;
+ } // namespace
+
+ bool InitializeMeshRenderer(NonNullPtr arena, NonNullPtr device, NonNullPtr window)
+ {
+ (void)arena;
+ (void)device;
+ (void)window;
+ return true;
+ // bool result = true;
+ //
+ // g_MeshRenderer.Meshes.Create(arena JULIET_DEBUG_PARAM("Meshes"));
+ // g_MeshRenderer.Vertices.Create(arena JULIET_DEBUG_PARAM("Vertices"));
+ // g_MeshRenderer.Indices.Create(arena JULIET_DEBUG_PARAM("Indices"));
+ //
+ // GraphicsDevice* graphicsDevice = g_MeshRenderer.Device = device.Get();
+ //
+ // // Create graphics pipeline
+ // String entryPoint = WrapString("main");
+ // ShaderCreateInfo shaderCI = {};
+ // shaderCI.EntryPoint = entryPoint;
+ //
+ // // TODO: Assets management that handles path to assets or something.
+ // String shaderPath = WrapString("../../Assets/compiled/Triangle.vert.dxil");
+ // shaderCI.Stage = ShaderStage::Vertex;
+ // Shader* vertexShader = CreateShader(graphicsDevice, shaderPath, shaderCI);
+ //
+ // shaderPath = WrapString("../../Assets/compiled/SolidColor.frag.dxil");
+ // shaderCI.Stage = ShaderStage::Fragment;
+ // Shader* fragmentShader = CreateShader(graphicsDevice, shaderPath, shaderCI);
+ //
+ // ColorTargetDescription colorTargetDescription = {};
+ // colorTargetDescription.Format = GetSwapChainTextureFormat(graphicsDevice, window);
+ //
+ // GraphicsPipelineCreateInfo pipelineCI = {};
+ // pipelineCI.VertexShader = vertexShader;
+ // pipelineCI.FragmentShader = fragmentShader;
+ // pipelineCI.PrimitiveType = PrimitiveType::TriangleList;
+ // pipelineCI.TargetInfo = { .ColorTargetDescriptions = &colorTargetDescription,
+ // .NumColorTargets = 1,
+ // .DepthStencilFormat = TextureFormat::D32_FLOAT,
+ // .HasDepthStencilTarget = true };
+ // pipelineCI.RasterizerState.FillMode = FillMode::Solid;
+ // pipelineCI.DepthStencilState.EnableDepthTest = true;
+ // pipelineCI.DepthStencilState.EnableDepthWrite = true;
+ // pipelineCI.DepthStencilState.CompareOperation = CompareOperation::Less;
+ //
+ // g_MeshRenderer.Pipeline = CreateGraphicsPipeline(graphicsDevice, pipelineCI);
+ // if (g_MeshRenderer.Pipeline == nullptr)
+ // {
+ // LogError(LogCategory::Graphics, "Failed to create graphics pipeline!");
+ // result = false;
+ // }
+ //
+ // // Create the vertex and index buffers
+ // BufferCreateInfo vertexBufferCI = {};
+ // vertexBufferCI.Size = kGeometryPage;
+ // vertexBufferCI.Usage = BufferUsage::VertexBuffer;
+ // g_MeshRenderer.VertexBuffer = CreateGraphicsBuffer(graphicsDevice, vertexBufferCI);
+ //
+ // BufferCreateInfo indexBufferCI = {};
+ // indexBufferCI.Size = kIndexPage;
+ // indexBufferCI.Usage = BufferUsage::IndexBuffer;
+ // g_MeshRenderer.IndexBuffer = CreateGraphicsBuffer(graphicsDevice, indexBufferCI);
+ //
+ // if (vertexShader)
+ // {
+ // DestroyShader(graphicsDevice, vertexShader);
+ // }
+ // if (fragmentShader)
+ // {
+ // DestroyShader(graphicsDevice, fragmentShader);
+ // }
+ //
+ // return result;
+ }
+
+ void ShutdownMeshRenderer()
+ {
+ return;
+ // DestroyGraphicsBuffer(g_MeshRenderer.Device, g_MeshRenderer.IndexBuffer);
+ // DestroyGraphicsBuffer(g_MeshRenderer.Device, g_MeshRenderer.VertexBuffer);
+ //
+ // g_MeshRenderer.Indices.Destroy();
+ // g_MeshRenderer.Vertices.Destroy();
+ // g_MeshRenderer.Meshes.Destroy();
+ }
+
+ void LoadMeshesOnGPU(NonNullPtr cmdList)
+ {
+ if (g_MeshRenderer.Meshes.IsEmpty())
+ {
+ return;
+ }
+
+ // Loading everything in one go.
+ // Destroy the buffer at the end
+
+ TransferBufferCreateInfo uploadBCI = {};
+ uploadBCI.Usage = TransferBufferUsage::Upload;
+ uploadBCI.Size = kGeometryPage + kIndexPage;
+ g_MeshRenderer.LoadCopyBuffer = CreateGraphicsTransferBuffer(g_MeshRenderer.Device, uploadBCI);
+
+ void* map = MapGraphicsTransferBuffer(g_MeshRenderer.Device, g_MeshRenderer.LoadCopyBuffer);
+
+ Vertex* vertices = g_MeshRenderer.Vertices.Data;
+ if (!vertices)
+ {
+ return;
+ }
+
+ Index* indices = g_MeshRenderer.Indices.Data;
+ if (!indices)
+ {
+ return;
+ }
+
+ // Copy all meshes! This supports only one page for now
+ // Copy ALL Vertices in one block
+ size_t totalVertexBytes = g_MeshRenderer.Vertices.Count * sizeof(Vertex);
+ MemCopy(map, g_MeshRenderer.Vertices.Data, totalVertexBytes);
+
+ // Copy ALL Indices in one block
+ size_t indexOfByteOffset = (kGeometryPage + 255) & static_cast(~255);
+ uint8* ptrOneByte = static_cast(map);
+ size_t totalIndexBytes = g_MeshRenderer.Indices.Count * sizeof(Index);
+
+ MemCopy(ptrOneByte + indexOfByteOffset, g_MeshRenderer.Indices.Data, totalIndexBytes);
+
+ // index_t index = 0;
+ // for (Mesh& mesh : g_MeshRenderer.Meshes)
+ // {
+ // // Vertices first
+ // Vertex* mapVertices = static_cast(map);
+ // MemCopy(mapVertices + index, vertices + mesh.VertexOffset, mesh.VertexCount * sizeOfVertex);
+ //
+ // // Indices next
+ // uint8* ptrOneByte = static_cast(map);
+ // uint16* dst = reinterpret_cast(ptrOneByte + indexOfByteOffset);
+ // MemCopy(dst, indices, mesh.IndexCount * sizeOfIndex);
+ //
+ // ++index;
+ // }
+
+ CopyBuffer(cmdList, g_MeshRenderer.VertexBuffer, g_MeshRenderer.LoadCopyBuffer, totalVertexBytes, 0, 0);
+ CopyBuffer(cmdList, g_MeshRenderer.IndexBuffer, g_MeshRenderer.LoadCopyBuffer, totalIndexBytes, 0, indexOfByteOffset);
+
+ // Transition vertex buffer to SRV state (this barrier waits for copy to complete)
+ TransitionBufferToReadable(cmdList, g_MeshRenderer.VertexBuffer);
+ TransitionBufferToReadable(cmdList, g_MeshRenderer.IndexBuffer);
+ }
+
+ void RenderMeshes(NonNullPtr pass, NonNullPtr cmdList, PushData& pushData)
+ {
+ // First destroy any buffer that needs to be
+ if (g_MeshRenderer.LoadCopyBuffer)
+ {
+ WaitUntilGPUIsIdle(g_MeshRenderer.Device);
+ UnmapGraphicsTransferBuffer(g_MeshRenderer.Device, g_MeshRenderer.LoadCopyBuffer);
+ DestroyGraphicsTransferBuffer(g_MeshRenderer.Device, g_MeshRenderer.LoadCopyBuffer);
+ g_MeshRenderer.LoadCopyBuffer = nullptr;
+ }
+
+ BindGraphicsPipeline(pass, g_MeshRenderer.Pipeline);
+
+ uint32 vertexDescriptorIndex = GetDescriptorIndex(g_MeshRenderer.Device, g_MeshRenderer.VertexBuffer);
+
+ pushData.BufferIndex = vertexDescriptorIndex;
+ SetPushConstants(cmdList, ShaderStage::Vertex, 0, sizeof(pushData) / 4, &pushData);
+
+ for (Mesh& mesh : g_MeshRenderer.Meshes)
+ {
+ SetIndexBuffer(cmdList, g_MeshRenderer.IndexBuffer, IndexFormat::UInt16, mesh.IndexCount, 0);
+ // DrawIndexedPrimitives(pass, static_cast(mesh.IndexCount), 1, static_cast(mesh.IndexOffset),
+ // static_cast(mesh.VertexOffset), 0);
+ }
+ }
+
+ MeshID AddCube()
+ {
+ Mesh result = {};
+
+ constexpr Vertex vertexData[] = {
+ // Front Face (Z = -0.5f)
+ { { -0.5f, 0.5f, -0.5f }, { 0.0f, 0.0f } }, // 0: Top Left
+ { { 0.5f, 0.5f, -0.5f }, { 1.0f, 0.0f } }, // 1: Top Right
+ { { 0.5f, -0.5f, -0.5f }, { 1.0f, 1.0f } }, // 2: Bottom Right
+ { { -0.5f, -0.5f, -0.5f }, { 0.0f, 1.0f } }, // 3: Bottom Left
+
+ // Back Face (Z = 0.5f)
+ { { 0.5f, 0.5f, 0.5f }, { 0.0f, 0.0f } }, // 4: Top Left
+ { { -0.5f, 0.5f, 0.5f }, { 1.0f, 0.0f } }, // 5: Top Right
+ { { -0.5f, -0.5f, 0.5f }, { 1.0f, 1.0f } }, // 6: Bottom Right
+ { { 0.5f, -0.5f, 0.5f }, { 0.0f, 1.0f } }, // 7: Bottom Left
+
+ // Top Face (Y = 0.5f)
+ { { -0.5f, 0.5f, 0.5f }, { 0.0f, 0.0f } }, // 8: Top Left
+ { { 0.5f, 0.5f, 0.5f }, { 1.0f, 0.0f } }, // 9: Top Right
+ { { 0.5f, 0.5f, -0.5f }, { 1.0f, 1.0f } }, // 10: Bottom Right
+ { { -0.5f, 0.5f, -0.5f }, { 0.0f, 1.0f } }, // 11: Bottom Left
+
+ // Bottom Face (Y = -0.5f)
+ { { -0.5f, -0.5f, -0.5f }, { 0.0f, 0.0f } }, // 12: Top Left
+ { { 0.5f, -0.5f, -0.5f }, { 1.0f, 0.0f } }, // 13: Top Right
+ { { 0.5f, -0.5f, 0.5f }, { 1.0f, 1.0f } }, // 14: Bottom Right
+ { { -0.5f, -0.5f, 0.5f }, { 0.0f, 1.0f } }, // 15: Bottom Left
+
+ // Right Face (X = 0.5f)
+ { { 0.5f, 0.5f, -0.5f }, { 0.0f, 0.0f } }, // 16: Top Left
+ { { 0.5f, 0.5f, 0.5f }, { 1.0f, 0.0f } }, // 17: Top Right
+ { { 0.5f, -0.5f, 0.5f }, { 1.0f, 1.0f } }, // 18: Bottom Right
+ { { 0.5f, -0.5f, -0.5f }, { 0.0f, 1.0f } }, // 19: Bottom Left
+
+ // Left Face (X = -0.5f)
+ { { -0.5f, 0.5f, 0.5f }, { 0.0f, 0.0f } }, // 20: Top Left
+ { { -0.5f, 0.5f, -0.5f }, { 1.0f, 0.0f } }, // 21: Top Right
+ { { -0.5f, -0.5f, -0.5f }, { 1.0f, 1.0f } }, // 22: Bottom Right
+ { { -0.5f, -0.5f, 0.5f }, { 0.0f, 1.0f } } // 23: Bottom Left
+ };
+ constexpr size_t cubeVertexCount = ArraySize(vertexData);
+ result.VertexCount = cubeVertexCount;
+ result.VertexOffset = g_MeshRenderer.Vertices.Count;
+ g_MeshRenderer.Vertices.PushBack(vertexData, cubeVertexCount);
+
+ constexpr uint16 indices[] = { 0, 1, 2, 0, 2, 3, // Front
+ 4, 5, 6, 4, 6, 7, // Back
+ 8, 9, 10, 8, 10, 11, // Top
+ 12, 13, 14, 12, 14, 15, // Bottom
+ 16, 17, 18, 16, 18, 19, // Right
+ 20, 21, 22, 20, 22, 23 }; // Left
+ constexpr size_t indexCubeCount = ArraySize(indices);
+ result.IndexCount = indexCubeCount;
+ result.IndexOffset = g_MeshRenderer.Indices.Count;
+ g_MeshRenderer.Indices.PushBack(indices, indexCubeCount);
+
+ MeshID id = g_MeshRenderer.Meshes.Count;
+ g_MeshRenderer.Meshes.PushBack(result);
+ return id;
+ }
+
+ MeshID AddQuad()
+ {
+ // Mesh result = {};
+
+ // // Using the exact 6 vertices from the working triangles!
+ // constexpr Vertex vertexData[] = {
+ // // Triangle 1 (Clockwise)
+ // { { -0.5f, -0.5f, 0.0f }, { 1.0f, 0.0f, 0.0f, 1.0f } }, // 0: Red
+ // { { 0.0f, 0.5f, 0.0f }, { 0.0f, 1.0f, 0.0f, 1.0f } }, // 1: Green
+ // { { 0.5f, -0.5f, 0.0f }, { 0.0f, 0.0f, 1.0f, 1.0f } }, // 2: Blue
+ //
+ // // Triangle 2 (Clockwise)
+ // { { -0.5f, 0.5f, 0.0f }, { 1.0f, 1.0f, 0.0f, 1.0f } }, // 3: Yellow
+ // { { 0.0f, 0.8f, 0.0f }, { 0.0f, 1.0f, 1.0f, 1.0f } }, // 4: Cyan
+ // { { 0.5f, 0.5f, 0.0f }, { 1.0f, 0.0f, 1.0f, 1.0f } } // 5: Magenta
+ // };
+ // constexpr size_t triVertexCount = ArraySize(vertexData);
+ // result.VertexCount = triVertexCount;
+ // result.Vertices = ArenaPushArray(arena.Get(), triVertexCount);
+ // MemCopy(result.Vertices, vertexData, sizeof(Vertex) * triVertexCount);
+ //
+ // // Just the 6 indices for the two triangles
+ // constexpr uint16 indices[] = { 0, 1, 2, 3, 4, 5 };
+ // constexpr size_t triIndexCount = ArraySize(indices);
+ // result.IndexCount = triIndexCount;
+ // result.Indices = ArenaPushArray(arena.Get(), triIndexCount JULIET_DEBUG_PARAM("Indices"));
+ // MemCopy(result.Indices, indices, sizeof(uint16) * triIndexCount);
+ //
+ // g_MeshRenderer.Meshes.PushBack(std::move(result));
+ return g_MeshRenderer.Meshes.Count - 1;
+ }
+
+#if ALLOW_SHADER_HOT_RELOAD
+ void ReloadMeshRendererShaders()
+ {
+ auto* pipeline = g_MeshRenderer.Pipeline;
+ auto* device = g_MeshRenderer.Device;
+
+ String entryPoint = WrapString("main");
+ ShaderCreateInfo shaderCI = {};
+ shaderCI.EntryPoint = entryPoint;
+ String shaderPath = WrapString("../../Assets/compiled/Triangle.vert.dxil");
+ shaderCI.Stage = ShaderStage::Vertex;
+ Shader* vertexShader = CreateShader(device, shaderPath, shaderCI);
+
+ shaderPath = WrapString("../../Assets/compiled/SolidColor.frag.dxil");
+ shaderCI.Stage = ShaderStage::Fragment;
+ Shader* fragmentShader = CreateShader(device, shaderPath, shaderCI);
+
+ UpdateGraphicsPipelineShaders(device, pipeline, vertexShader, fragmentShader);
+
+ if (vertexShader)
+ {
+ DestroyShader(device, vertexShader);
+ }
+ if (fragmentShader)
+ {
+ DestroyShader(device, fragmentShader);
+ }
+ }
+#endif
+} // namespace Juliet
diff --git a/JulietApp/main.cpp b/JulietApp/main.cpp
index adb5874..8cdbaa9 100644
--- a/JulietApp/main.cpp
+++ b/JulietApp/main.cpp
@@ -21,6 +21,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -63,6 +64,8 @@ namespace
} Game;
const char* GameFunctionTable[] = { "GameInit", "GameShutdown", "GameUpdate" };
+
+ Arena* PlatformArena = nullptr;
} // namespace
void JulietApplication::Init()
@@ -71,6 +74,8 @@ void JulietApplication::Init()
Log(LogLevel::Message, LogCategory::Tool, "%s", CStr(GetBasePath()));
+ PlatformArena = ArenaAllocate({ .AllowRealloc = true } JULIET_DEBUG_PARAM("Platform Arena"));
+
GraphicsConfig config;
#if JULIET_DEBUG
config.EnableDebug = true;
@@ -85,42 +90,7 @@ void JulietApplication::Init()
{
AttachToWindow(GraphicsDevice, MainWindow);
{
- // Create graphics pipeline
- String entryPoint = WrapString("main");
- ShaderCreateInfo shaderCI = {};
- shaderCI.EntryPoint = entryPoint;
-
- // TODO: Assets management that handles path to assets or something.
- String shaderPath = WrapString("../../Assets/compiled/Triangle.vert.dxil");
- shaderCI.Stage = ShaderStage::Vertex;
- Shader* vertexShader = CreateShader(GraphicsDevice, shaderPath, shaderCI);
-
- shaderPath = WrapString("../../Assets/compiled/SolidColor.frag.dxil");
- shaderCI.Stage = ShaderStage::Fragment;
- Shader* fragmentShader = CreateShader(GraphicsDevice, shaderPath, shaderCI);
-
- ColorTargetDescription colorTargetDescription = {};
- colorTargetDescription.Format = GetSwapChainTextureFormat(GraphicsDevice, MainWindow);
-
- GraphicsPipelineCreateInfo pipelineCI = {};
- pipelineCI.VertexShader = vertexShader;
- pipelineCI.FragmentShader = fragmentShader;
- pipelineCI.PrimitiveType = PrimitiveType::TriangleList;
- pipelineCI.TargetInfo = { .ColorTargetDescriptions = &colorTargetDescription,
- .NumColorTargets = 1,
- .DepthStencilFormat = TextureFormat::D32_FLOAT,
- .HasDepthStencilTarget = true };
- pipelineCI.RasterizerState.FillMode = FillMode::Solid;
- pipelineCI.DepthStencilState.EnableDepthTest = true;
- pipelineCI.DepthStencilState.EnableDepthWrite = true;
- pipelineCI.DepthStencilState.CompareOperation = CompareOperation::Less;
-
- GraphicsPipeline = CreateGraphicsPipeline(GraphicsDevice, pipelineCI);
- if (GraphicsPipeline == nullptr)
- {
- LogError(LogCategory::Game, "Failed to create graphics pipeline!");
- Running = false;
- }
+ Running = InitializeMeshRenderer(PlatformArena, GraphicsDevice, MainWindow);
// Create Depth Buffer
TextureCreateInfo depthCI = {};
@@ -139,50 +109,11 @@ void JulietApplication::Init()
Running = false;
}
- // Create Buffers - Using StructuredBuffer for bindless SRV access in shader
- BufferCreateInfo bufferCI = {};
- bufferCI.Size = 1024;
- bufferCI.Usage = BufferUsage::StructuredBuffer; // SRV for ResourceDescriptorHeap access
- StructuredBuffer = CreateGraphicsBuffer(GraphicsDevice, bufferCI);
-
- TransferBufferCreateInfo transferCI = {};
- transferCI.Size = 1024;
- transferCI.Usage = TransferBufferUsage::Upload;
- TransferBuffer = CreateGraphicsTransferBuffer(GraphicsDevice, transferCI);
-
- // Upload Static Data for Test
- if (TransferBuffer && StructuredBuffer)
- {
- void* data = MapGraphicsTransferBuffer(GraphicsDevice, TransferBuffer);
- if (data)
- {
- Matrix projection = PerspectiveFov(60.0f * (3.14159f / 180.0f), 1200.0f / 800.0f, 0.1f, 1000.0f);
- Matrix view = LookAt({ 30.0f, 0.0f, 10.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 1.0f });
- Matrix model = Matrix::Identity();
- Matrix mvp = projection * view * model;
-
- MemCopy(data, &mvp, sizeof(Matrix));
- UnmapGraphicsTransferBuffer(GraphicsDevice, TransferBuffer);
-
- CommandList* initCmd = AcquireCommandList(GraphicsDevice);
- CopyBuffer(initCmd, StructuredBuffer, TransferBuffer, 256);
- TransitionBufferToReadable(initCmd, StructuredBuffer);
- SubmitCommandLists(initCmd);
- }
- }
-
- CubeArena = ArenaAllocate({ .ReserveSize = Kilobytes(1llu), .CommitSize = Kilobytes(1llu) } JULIET_DEBUG_PARAM("CubeArena"));
- CubeMesh = CreateCubeMesh(CubeArena);
- // CubeMesh = CreateQuadMesh(CubeArena);
-
- if (vertexShader)
- {
- DestroyShader(GraphicsDevice, vertexShader);
- }
- if (fragmentShader)
- {
- DestroyShader(GraphicsDevice, fragmentShader);
- }
+ // std::ignore = AddCube();
+ //
+ // CommandList* loadCmd = AcquireCommandList(GraphicsDevice);
+ // LoadMeshesOnGPU(loadCmd);
+ // SubmitCommandLists(loadCmd);
if (Running == false)
{
@@ -208,8 +139,6 @@ void JulietApplication::Shutdown()
{
Log(LogLevel::Message, LogCategory::Tool, "Shutting down Juliet Application...");
- ArenaRelease(CubeArena);
-
if (GameCode.IsValid)
{
Game.Shutdown();
@@ -220,19 +149,14 @@ void JulietApplication::Shutdown()
{
DestroyGraphicsPipeline(GraphicsDevice, GraphicsPipeline);
}
- if (StructuredBuffer)
- {
- DestroyGraphicsBuffer(GraphicsDevice, StructuredBuffer);
- }
- if (TransferBuffer)
- {
- DestroyGraphicsTransferBuffer(GraphicsDevice, TransferBuffer);
- }
+
if (DepthBuffer)
{
DestroyTexture(GraphicsDevice, DepthBuffer);
}
+ ShutdownMeshRenderer();
+
if (MainWindow && GraphicsDevice)
{
DetachFromWindow(GraphicsDevice, MainWindow);
@@ -248,6 +172,8 @@ void JulietApplication::Shutdown()
DestroyGraphicsDevice(GraphicsDevice);
}
+ ArenaRelease(PlatformArena);
+
Log(LogLevel::Message, LogCategory::Tool, "Juliet App shutdown Completed");
}
@@ -281,7 +207,7 @@ void JulietApplication::Update()
}
#ifdef JULIET_ENABLE_IMGUI
- ImGui::ShowDemoWindow();
+ // ImGui::ShowDemoWindow();
#endif
DebugDisplay_DrawLine({ 0.0f, 0.0f, 0.0f }, { 1.0f, 0.0f, 0.0f }, { 1.0f, 0.0f, 0.0f, 1.0f }, false);
@@ -301,27 +227,7 @@ void JulietApplication::Update()
WaitUntilGPUIsIdle(GraphicsDevice);
#if ALLOW_SHADER_HOT_RELOAD
- String entryPoint = WrapString("main");
- ShaderCreateInfo shaderCI = {};
- shaderCI.EntryPoint = entryPoint;
- String shaderPath = WrapString("../../Assets/compiled/Triangle.vert.dxil");
- shaderCI.Stage = ShaderStage::Vertex;
- Shader* vertexShader = CreateShader(GraphicsDevice, shaderPath, shaderCI);
-
- shaderPath = WrapString("../../Assets/compiled/SolidColor.frag.dxil");
- shaderCI.Stage = ShaderStage::Fragment;
- Shader* fragmentShader = CreateShader(GraphicsDevice, shaderPath, shaderCI);
-
- UpdateGraphicsPipelineShaders(GraphicsDevice, GraphicsPipeline, vertexShader, fragmentShader);
-
- if (vertexShader)
- {
- DestroyShader(GraphicsDevice, vertexShader);
- }
- if (fragmentShader)
- {
- DestroyShader(GraphicsDevice, fragmentShader);
- }
+ ReloadMeshRendererShaders();
#endif
}
@@ -361,76 +267,16 @@ void JulietApplication::Update()
ArenaClear(GameScratchArena);
}
-void JulietApplication::OnPreRender(CommandList* cmd)
+void JulietApplication::OnPreRender(CommandList* /*cmd*/) {}
+
+void JulietApplication::OnRender(RenderPass*, CommandList*)
{
- index_t index = 0;
+ // PushData pushData = {};
+ // pushData.ViewProjection = Camera_GetViewProjectionMatrix(GetDebugCamera());
- // Buffer uploads
- if (StructuredBuffer && TransferBuffer)
- {
- void* ptr = MapGraphicsTransferBuffer(GraphicsDevice, TransferBuffer);
- if (ptr)
- {
- Vertex* vertices = static_cast(ptr);
+ // RenderMeshes(pass, cmd, pushData);
- // // Triangle 1
- // vertices[index++] = { { -0.5f, -0.5f, 0.0f }, { 1.0f, 0.0f, 0.0f, 1.0f } }; // Red
- // vertices[index++] = { { 0.0f, 0.5f, 0.0f }, { 0.0f, 1.0f, 0.0f, 1.0f } }; // Green
- // vertices[index++] = { { 0.5f, -0.5f, 0.0f }, { 0.0f, 0.0f, 1.0f, 1.0f } }; // Blue
- //
- // // Triangle 2
- // vertices[index++] = { { -0.5f, 0.5f, 0.0f }, { 1.0f, 1.0f, 0.0f, 1.0f } }; // Yellow
- // vertices[index++] = { { 0.0f, 0.8f, 0.0f }, { 0.0f, 1.0f, 1.0f, 1.0f } }; // Cyan
- // vertices[index++] = { { 0.5f, 0.5f, 0.0f }, { 1.0f, 0.0f, 1.0f, 1.0f } }; // Magenta
-
- if (CubeMesh)
- {
- CubeMesh->VertexOffset = index;
- size_t vertexSize = CubeMesh->VertexCount * sizeof(Vertex);
- MemCopy(vertices + index, CubeMesh->Vertices, vertexSize);
-
- CubeMesh->IndexByteOffset = (index + CubeMesh->VertexCount) * sizeof(Vertex);
- // Align
- CubeMesh->IndexByteOffset = (CubeMesh->IndexByteOffset + 255) & static_cast(~255);
-
- size_t indexSize = CubeMesh->IndexCount * sizeof(uint16);
-
- CubeMesh->IndexOffset = 0;
-
- uint8* ptrOneByte = static_cast(ptr);
- uint16* dst = reinterpret_cast(ptrOneByte + CubeMesh->IndexByteOffset);
- MemCopy(dst, CubeMesh->Indices, indexSize);
- }
-
- UnmapGraphicsTransferBuffer(GraphicsDevice, TransferBuffer);
- }
-
- CopyBuffer(cmd, StructuredBuffer, TransferBuffer, CubeMesh->IndexByteOffset + (CubeMesh->IndexCount * sizeof(uint16)));
- TransitionBufferToReadable(cmd, StructuredBuffer);
- }
-}
-
-void JulietApplication::OnRender(RenderPass* pass, CommandList* cmd)
-{
- BindGraphicsPipeline(pass, GraphicsPipeline);
-
- uint32 descriptorIndex = GetDescriptorIndex(GraphicsDevice, StructuredBuffer);
-
- struct PushData
- {
- Matrix ViewProjection;
- uint32 BufferIndex;
- } pushData = {};
- pushData.BufferIndex = descriptorIndex;
- pushData.ViewProjection = Camera_GetViewProjectionMatrix(GetDebugCamera());
-
- SetPushConstants(cmd, ShaderStage::Vertex, 0, sizeof(pushData) / 4, &pushData);
-
- SetIndexBuffer(cmd, StructuredBuffer, IndexFormat::UInt16, CubeMesh->IndexCount, CubeMesh->IndexByteOffset);
- // DrawIndexedPrimitives(pass, static_cast(CubeMesh->IndexCount), 1, 0, 0, 0);
-
- DrawIndexedPrimitives(pass, static_cast(CubeMesh->IndexCount), 1,
- static_cast(CubeMesh->IndexOffset), static_cast(CubeMesh->VertexOffset), 0);
+ // SetPushConstants(cmd, ShaderStage::Vertex, 0, sizeof(pushData) / 4, &pushData);
}
ColorTargetInfo JulietApplication::GetColorTargetInfo(Texture* swapchainTexture)
diff --git a/JulietApp/main.h b/JulietApp/main.h
index 32a3358..8ab5e8e 100644
--- a/JulietApp/main.h
+++ b/JulietApp/main.h
@@ -38,19 +38,13 @@ class JulietApplication : public Juliet::IApplication
int GetAutoCloseFrameCount() const { return AutoCloseFrameCount; }
private:
- Juliet::Window* MainWindow = {};
- Juliet::GraphicsDevice* GraphicsDevice = {};
- Juliet::HotReloadCode GameCode = {};
- Juliet::GraphicsPipeline* GraphicsPipeline = {};
- Juliet::GraphicsBuffer* StructuredBuffer = {};
- Juliet::GraphicsTransferBuffer* TransferBuffer = {};
- Juliet::Texture* DepthBuffer = {};
-
- Juliet::Mesh* CubeMesh = {};
- Juliet::Arena* CubeArena = nullptr;
-
- Juliet::Arena* GameArena = nullptr;
- Juliet::Arena* GameScratchArena = nullptr;
+ Juliet::Window* MainWindow = {};
+ Juliet::GraphicsDevice* GraphicsDevice = {};
+ Juliet::HotReloadCode GameCode = {};
+ Juliet::GraphicsPipeline* GraphicsPipeline = {};
+ Juliet::Texture* DepthBuffer = {};
+ Juliet::Arena* GameArena = nullptr;
+ Juliet::Arena* GameScratchArena = nullptr;
int AutoCloseFrameCount = -1;
bool Running = false;