From c9cd01bb31e533daa64590d51b929e75d7f8caff Mon Sep 17 00:00:00 2001 From: Patedam Date: Sat, 15 Mar 2025 19:55:41 -0400 Subject: [PATCH] Prepare shader reload. - Expose wait until gpus is idle to api - Alt+R to reload --- Juliet/include/Core/HAL/Keyboard/Keyboard.h | 6 ++--- Juliet/include/Graphics/Graphics.h | 3 +++ .../Graphics/D3D12/D3D12GraphicsDevice.cpp | 4 +-- .../Graphics/D3D12/D3D12Synchronization.cpp | 2 +- .../src/Graphics/D3D12/D3D12Synchronization.h | 2 +- Juliet/src/Graphics/Graphics.cpp | 7 ++++- Juliet/src/Graphics/GraphicsDevice.h | 2 +- JulietApp/main.cpp | 27 +++++++++++++++++++ 8 files changed, 44 insertions(+), 9 deletions(-) diff --git a/Juliet/include/Core/HAL/Keyboard/Keyboard.h b/Juliet/include/Core/HAL/Keyboard/Keyboard.h index fbb6c56..fc86432 100644 --- a/Juliet/include/Core/HAL/Keyboard/Keyboard.h +++ b/Juliet/include/Core/HAL/Keyboard/Keyboard.h @@ -20,8 +20,8 @@ namespace Juliet uint16 Raw; }; - extern bool IsKeyDown(ScanCode scanCode); + extern JULIET_API bool IsKeyDown(ScanCode scanCode); - extern KeyMod GetKeyModState(); - extern KeyCode GetKeyCodeFromScanCode(ScanCode scanCode, KeyMod keyModState); + extern JULIET_API KeyMod GetKeyModState(); + extern JULIET_API KeyCode GetKeyCodeFromScanCode(ScanCode scanCode, KeyMod keyModState); } // namespace Juliet diff --git a/Juliet/include/Graphics/Graphics.h b/Juliet/include/Graphics/Graphics.h index d804f75..be3a915 100644 --- a/Juliet/include/Graphics/Graphics.h +++ b/Juliet/include/Graphics/Graphics.h @@ -118,6 +118,9 @@ namespace Juliet extern JULIET_API void DrawPrimitives(NonNullPtr renderPass, uint32 numVertices, uint32 numInstances, uint32 firstVertex, uint32 firstInstance); + // Fences + extern JULIET_API bool WaitUntilGPUIsIdle(NonNullPtr device); + // Shaders extern JULIET_API Shader* CreateShader(NonNullPtr device, String filename, ShaderCreateInfo& shaderCreateInfo); extern JULIET_API void DestroyShader(NonNullPtr device, NonNullPtr shader); diff --git a/Juliet/src/Graphics/D3D12/D3D12GraphicsDevice.cpp b/Juliet/src/Graphics/D3D12/D3D12GraphicsDevice.cpp index 2d893f8..14e27e0 100644 --- a/Juliet/src/Graphics/D3D12/D3D12GraphicsDevice.cpp +++ b/Juliet/src/Graphics/D3D12/D3D12GraphicsDevice.cpp @@ -406,7 +406,7 @@ namespace Juliet::D3D12 auto* windowData = d3d12Driver->WindowData; Assert(windowData && "Trying to destroy a swapchain but no Window Data exists"); - Wait(driver); + WaitUntilGPUIsIdle(driver); for (uint32 idx = 0; idx < GPUDriver::kMaxFramesInFlight; idx += 1) { @@ -748,7 +748,7 @@ namespace Juliet::D3D12 device->SetStencilReference = SetStencilReference; device->BindGraphicsPipeline = BindGraphicsPipeline; device->DrawPrimitives = DrawPrimitives; - device->Wait = Wait; + device->WaitUntilGPUIsIdle = WaitUntilGPUIsIdle; device->QueryFence = QueryFence; device->ReleaseFence = ReleaseFence; device->CreateShader = CreateShader; diff --git a/Juliet/src/Graphics/D3D12/D3D12Synchronization.cpp b/Juliet/src/Graphics/D3D12/D3D12Synchronization.cpp index 345e8cf..24f2662 100644 --- a/Juliet/src/Graphics/D3D12/D3D12Synchronization.cpp +++ b/Juliet/src/Graphics/D3D12/D3D12Synchronization.cpp @@ -23,7 +23,7 @@ namespace Juliet::D3D12 } } // namespace - bool Wait(NonNullPtr driver) + bool WaitUntilGPUIsIdle(NonNullPtr driver) { auto d3d12driver = static_cast(driver.Get()); D3D12Fence* fence = Internal::AcquireFence(d3d12driver); diff --git a/Juliet/src/Graphics/D3D12/D3D12Synchronization.h b/Juliet/src/Graphics/D3D12/D3D12Synchronization.h index ab23f61..fd1c7e7 100644 --- a/Juliet/src/Graphics/D3D12/D3D12Synchronization.h +++ b/Juliet/src/Graphics/D3D12/D3D12Synchronization.h @@ -25,7 +25,7 @@ namespace Juliet::D3D12 int32 ReferenceCount; // TODO : Atomic }; - extern bool Wait(NonNullPtr driver); + extern bool WaitUntilGPUIsIdle(NonNullPtr driver); extern bool Wait(NonNullPtr driver, bool waitForAll, Fence* const* fences, uint32 numFences); extern bool QueryFence(NonNullPtr driver, NonNullPtr fence); extern void ReleaseFence(NonNullPtr driver, NonNullPtr fence); diff --git a/Juliet/src/Graphics/Graphics.cpp b/Juliet/src/Graphics/Graphics.cpp index 8d439e2..0bcb8d6 100644 --- a/Juliet/src/Graphics/Graphics.cpp +++ b/Juliet/src/Graphics/Graphics.cpp @@ -258,6 +258,12 @@ namespace Juliet commandListHeader->Device->DrawPrimitives(commandList, numVertices, numInstances, firstVertex, firstInstance); } + // Fences + bool WaitUntilGPUIsIdle(NonNullPtr device) + { + return device->WaitUntilGPUIsIdle(device->Driver); + } + // Shaders Shader* CreateShader(NonNullPtr device, String filename, ShaderCreateInfo& shaderCreateInfo) { @@ -304,5 +310,4 @@ namespace Juliet { device->DestroyGraphicsPipeline(device->Driver, graphicsPipeline); } - } // namespace Juliet diff --git a/Juliet/src/Graphics/GraphicsDevice.h b/Juliet/src/Graphics/GraphicsDevice.h index abed932..ea51b31 100644 --- a/Juliet/src/Graphics/GraphicsDevice.h +++ b/Juliet/src/Graphics/GraphicsDevice.h @@ -69,7 +69,7 @@ namespace Juliet uint32 firstVertex, uint32 firstInstance); // Fences - bool (*Wait)(NonNullPtr driver); + bool (*WaitUntilGPUIsIdle)(NonNullPtr driver); bool (*QueryFence)(NonNullPtr driver, NonNullPtr fence); void (*ReleaseFence)(NonNullPtr driver, NonNullPtr fence); diff --git a/JulietApp/main.cpp b/JulietApp/main.cpp index 0086a4c..67b67a8 100644 --- a/JulietApp/main.cpp +++ b/JulietApp/main.cpp @@ -1,6 +1,7 @@ #include #include +#include #include #include #include @@ -158,6 +159,9 @@ void JulietApplication::Shutdown() void JulietApplication::Update() { + bool reloadShaders = false; + static bool reloadShadersDebounce = false; + SystemEvent evt; while (GetEvent(evt)) { @@ -168,6 +172,23 @@ void JulietApplication::Update() Running = false; } } + + if (evt.Type == EventType::Key_Down) + { + } + + // Shader hot reload using keyboard. + // TODO: Add Input debounce in the library. (Just pressed vs pressed) + if (!reloadShadersDebounce && ((GetKeyModState() & KeyMod::Alt) != KeyMod::None) && IsKeyDown(ScanCode::R)) + { + reloadShaders = true; + reloadShadersDebounce = true; + } + + if (reloadShadersDebounce && !IsKeyDown(ScanCode::R)) + { + reloadShadersDebounce = false; + } } Game.Update(0.0f); @@ -177,6 +198,12 @@ void JulietApplication::Update() ReloadCode(GameCode); } + if (reloadShaders) + { + // We need to wait for the gpu to be idle to recreate our graphics pipelines + WaitUntilGPUIsIdle(GraphicsDevice); + } + // Draw here for now // 1) Acquire a Command Buffer CommandList* cmdList = AcquireCommandList(GraphicsDevice, QueueType::Graphics);