From 49fc0a24d1237a2a58fe3196f9045923d190219a Mon Sep 17 00:00:00 2001 From: Patedam Date: Sat, 21 Feb 2026 14:04:02 -0500 Subject: [PATCH] Meshrenderer first step. Adding logs to debug a weird crash since the add of mesh renderer and some clean up. --- Juliet/Juliet.vcxproj | 4 + Juliet/include/Core/Container/Vector.h | 30 ++ Juliet/include/Graphics/Mesh.h | 8 - Juliet/include/Graphics/MeshRenderer.h | 63 ++++ Juliet/include/Graphics/VertexData.h | 2 + Juliet/src/Engine/Engine.cpp | 22 +- Juliet/src/Graphics/D3D12/D3D12Buffer.cpp | 4 +- .../src/Graphics/D3D12/D3D12CommandList.cpp | 6 +- .../Graphics/D3D12/D3D12GraphicsDevice.cpp | 3 +- Juliet/src/Graphics/D3D12/D3D12SwapChain.cpp | 9 +- .../Graphics/D3D12/D3D12Synchronization.cpp | 38 ++- .../src/Graphics/D3D12/D3D12Synchronization.h | 7 +- Juliet/src/Graphics/D3D12/D3D12Texture.cpp | 273 +++++++-------- Juliet/src/Graphics/GraphicsDevice.h | 2 +- Juliet/src/Graphics/Mesh.cpp | 90 ----- Juliet/src/Graphics/MeshRenderer.cpp | 315 ++++++++++++++++++ JulietApp/main.cpp | 204 ++---------- JulietApp/main.h | 20 +- 18 files changed, 646 insertions(+), 454 deletions(-) create mode 100644 Juliet/include/Graphics/MeshRenderer.h create mode 100644 Juliet/src/Graphics/MeshRenderer.cpp 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;