From 93d8a80a2e9bee6dd6c208c9efe721efd27f9cd2 Mon Sep 17 00:00:00 2001 From: Top61ly Date: Wed, 2 Apr 2025 19:09:23 +0800 Subject: [PATCH 01/25] feat: add RPS pipeline and default resource creation methods in RenderSystem --- src/Rendering/RenderSystem.cpp | 9 +++++++++ src/Rendering/RenderSystem.h | 16 ++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/src/Rendering/RenderSystem.cpp b/src/Rendering/RenderSystem.cpp index 0362114..0b15244 100644 --- a/src/Rendering/RenderSystem.cpp +++ b/src/Rendering/RenderSystem.cpp @@ -1441,4 +1441,13 @@ const PhysicalDevice& RenderSystem::GetBestDevice(const std::vector Date: Thu, 3 Apr 2025 18:32:14 +0800 Subject: [PATCH 02/25] feat: implement forward and shadow pipelines in RenderSystem --- src/Rendering/RenderSystem.cpp | 91 ++++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) diff --git a/src/Rendering/RenderSystem.cpp b/src/Rendering/RenderSystem.cpp index 0b15244..278004d 100644 --- a/src/Rendering/RenderSystem.cpp +++ b/src/Rendering/RenderSystem.cpp @@ -22,6 +22,7 @@ #include "Utilities/Math/MathHelpers.h" #include "Rendering/GPUData/GlobalConstantBuffer.h" +#include "Rendering/AutoRenderPass.h" #include "RenderContextHelper.h" #include @@ -1444,10 +1445,100 @@ const PhysicalDevice& RenderSystem::GetBestDevice(const std::vector vertexShaderByteCode = LoadShaderBytecode("sample/SimpleLit", ShaderStage::Vertex, "main"); + std::vector fragmentShaderByteCode = LoadShaderBytecode("sample/SimpleLit", ShaderStage::Fragment, "main"); + + m_RpsPipelines.forwardPipeline = m_RenderContext->CreateGraphicsPipeline( + GraphicsPipelineDesc{ + .debugName = "SimpleLit", + .VS{ + .byteCode = reinterpret_cast(vertexShaderByteCode.data()), + .byteSize = static_cast(vertexShaderByteCode.size()), + .entryFunc = "vs"}, + .PS{ + .byteCode = reinterpret_cast(fragmentShaderByteCode.data()), + .byteSize = static_cast(fragmentShaderByteCode.size()), + .entryFunc = "ps"}, + .colorFormats = {GraphicsFormat::BGRA8_SRGB}, + .depthFormat = GraphicsFormat::D32_FLOAT, + .stencilFormat = GraphicsFormat::Undefined, + .vertexBufferBindings{ + {.byteStride = sizeof(Vector3) + sizeof(Vector2) + sizeof(Vector3), + .attributes = + { + {.byteOffset = 0, .format = GraphicsFormat::RGB32_FLOAT}, + {.byteOffset = 12, .format = GraphicsFormat::RG32_FLOAT}, + {.byteOffset = 20, .format = GraphicsFormat::RGB32_FLOAT}}}}, + .bindLayouts = { m_GlobalBindLayout }, + .dynamicBuffer = m_DynamicBufferHandle, + .renderPass = forwardPass.GetRenderPass().renderPass, + .subpassIndex = 0 + }); + + // Shadow Pipeline + RenderPassDesc shadowPassDesc = {{}, GraphicsFormat::D32_FLOAT}; + AutoRenderPass shadowPass(m_RenderContext.get(), shadowPassDesc); + + std::vector vertexShaderBytecode = LoadShaderBytecode("sample/Shadowmap", ShaderStage::Vertex, "main"); + std::vector fragmentShaderBytecode = LoadShaderBytecode("sample/Shadowmap", ShaderStage::Fragment, "main"); + + m_RpsPipelines.shadowPipeline = m_RenderContext->CreateGraphicsPipeline({ + GraphicsPipelineDesc{ + .debugName = "Shadowmap Pipeline", + .VS{ + .byteCode = reinterpret_cast(vertexShaderBytecode.data()), + .byteSize = static_cast(vertexShaderBytecode.size()), + .entryFunc = "vs"}, + .PS{ + .byteCode = reinterpret_cast(fragmentShaderBytecode.data()), + .byteSize = static_cast(fragmentShaderBytecode.size()), + .entryFunc = "ps"}, + .colorFormats = {}, + .depthFormat = GraphicsFormat::D32_FLOAT, + .stencilFormat = GraphicsFormat::Undefined, + .vertexBufferBindings{ + {.byteStride = sizeof(Vector3) + sizeof(Vector2) + sizeof(Vector3), + .attributes = + { + {.byteOffset = 0, .format = GraphicsFormat::RGB32_FLOAT}, + {.byteOffset = 12, .format = GraphicsFormat::RG32_FLOAT}, + {.byteOffset = 20, .format = GraphicsFormat::RGB32_FLOAT}}}}, + .bindLayouts = { m_GlobalBindLayout }, + .dynamicBuffer = m_DynamicBufferHandle, + .renderPass = shadowPass.GetRenderPass().renderPass, + .subpassIndex = 0 + } + }); } void RenderSystem::CreateDefaultResources() { + std::vector blackTextureData(4, 0); + std::vector whiteTextureData(4, 255); + + m_DefaultResources.blackTexture = m_RenderContext->CreateTextureHandle( + TextureDesc + { + .debugName = "Black Texture", + .width = 1, + .height = 1, + .data = blackTextureData.data(), + .dataSize = 4, + }); + + m_DefaultResources.whiteTexture = m_RenderContext->CreateTextureHandle( + TextureDesc + { + .debugName = "White Texture", + .width = 1, + .height = 1, + .data = whiteTextureData.data(), + .dataSize = 4, + }); } } // namespace gore \ No newline at end of file From 5e796784b32f8776a1af72b6ab3dd357163cacdf Mon Sep 17 00:00:00 2001 From: Top61ly Date: Thu, 3 Apr 2025 18:58:46 +0800 Subject: [PATCH 03/25] feat: add static wrapper functions for shadowmap and forward opaque passes in RenderSystem --- src/Rendering/RenderSystem.cpp | 8 ++++++++ src/Rendering/RenderSystem.h | 4 ++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/Rendering/RenderSystem.cpp b/src/Rendering/RenderSystem.cpp index 278004d..e6a76d1 100644 --- a/src/Rendering/RenderSystem.cpp +++ b/src/Rendering/RenderSystem.cpp @@ -1541,4 +1541,12 @@ void RenderSystem::CreateDefaultResources() }); } +void RenderSystem::ShadowmapPassWithRPSWrapper(const RpsCmdCallbackContext* pContext) +{ +} + +void RenderSystem::ForwardOpaquePassWithRPSWrapper(const RpsCmdCallbackContext* pContext) +{ +} + } // namespace gore \ No newline at end of file diff --git a/src/Rendering/RenderSystem.h b/src/Rendering/RenderSystem.h index 49d6781..a361694 100644 --- a/src/Rendering/RenderSystem.h +++ b/src/Rendering/RenderSystem.h @@ -166,8 +166,8 @@ ENGINE_CLASS(RenderSystem) final : System uint64_t CalcGuaranteedCompletedFrameindexForRps() const; // static void DrawTriangleWithRPSWrapper(const RpsCmdCallbackContext* pContext); - // static void ShadowmapPassWithRPSWrapper(const RpsCmdCallbackContext* pContext); - // static void ForwardOpaquePassWithRPSWrapper(const RpsCmdCallbackContext* pContext); + static void ShadowmapPassWithRPSWrapper(const RpsCmdCallbackContext* pContext); + static void ForwardOpaquePassWithRPSWrapper(const RpsCmdCallbackContext* pContext); // void DrawTriangle(vk::CommandBuffer commandBuffer); private: std::unique_ptr m_RenderContext; From 51fa74c874828f6b80156838a58b01095cf5bbe9 Mon Sep 17 00:00:00 2001 From: Top61ly Date: Wed, 2 Apr 2025 19:09:23 +0800 Subject: [PATCH 04/25] feat: add RPS pipeline and default resource creation methods in RenderSystem --- src/Rendering/RenderSystem.cpp | 9 +++++++++ src/Rendering/RenderSystem.h | 16 ++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/src/Rendering/RenderSystem.cpp b/src/Rendering/RenderSystem.cpp index 0362114..0b15244 100644 --- a/src/Rendering/RenderSystem.cpp +++ b/src/Rendering/RenderSystem.cpp @@ -1441,4 +1441,13 @@ const PhysicalDevice& RenderSystem::GetBestDevice(const std::vector Date: Thu, 3 Apr 2025 18:32:14 +0800 Subject: [PATCH 05/25] feat: implement forward and shadow pipelines in RenderSystem --- src/Rendering/RenderSystem.cpp | 91 ++++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) diff --git a/src/Rendering/RenderSystem.cpp b/src/Rendering/RenderSystem.cpp index 0b15244..278004d 100644 --- a/src/Rendering/RenderSystem.cpp +++ b/src/Rendering/RenderSystem.cpp @@ -22,6 +22,7 @@ #include "Utilities/Math/MathHelpers.h" #include "Rendering/GPUData/GlobalConstantBuffer.h" +#include "Rendering/AutoRenderPass.h" #include "RenderContextHelper.h" #include @@ -1444,10 +1445,100 @@ const PhysicalDevice& RenderSystem::GetBestDevice(const std::vector vertexShaderByteCode = LoadShaderBytecode("sample/SimpleLit", ShaderStage::Vertex, "main"); + std::vector fragmentShaderByteCode = LoadShaderBytecode("sample/SimpleLit", ShaderStage::Fragment, "main"); + + m_RpsPipelines.forwardPipeline = m_RenderContext->CreateGraphicsPipeline( + GraphicsPipelineDesc{ + .debugName = "SimpleLit", + .VS{ + .byteCode = reinterpret_cast(vertexShaderByteCode.data()), + .byteSize = static_cast(vertexShaderByteCode.size()), + .entryFunc = "vs"}, + .PS{ + .byteCode = reinterpret_cast(fragmentShaderByteCode.data()), + .byteSize = static_cast(fragmentShaderByteCode.size()), + .entryFunc = "ps"}, + .colorFormats = {GraphicsFormat::BGRA8_SRGB}, + .depthFormat = GraphicsFormat::D32_FLOAT, + .stencilFormat = GraphicsFormat::Undefined, + .vertexBufferBindings{ + {.byteStride = sizeof(Vector3) + sizeof(Vector2) + sizeof(Vector3), + .attributes = + { + {.byteOffset = 0, .format = GraphicsFormat::RGB32_FLOAT}, + {.byteOffset = 12, .format = GraphicsFormat::RG32_FLOAT}, + {.byteOffset = 20, .format = GraphicsFormat::RGB32_FLOAT}}}}, + .bindLayouts = { m_GlobalBindLayout }, + .dynamicBuffer = m_DynamicBufferHandle, + .renderPass = forwardPass.GetRenderPass().renderPass, + .subpassIndex = 0 + }); + + // Shadow Pipeline + RenderPassDesc shadowPassDesc = {{}, GraphicsFormat::D32_FLOAT}; + AutoRenderPass shadowPass(m_RenderContext.get(), shadowPassDesc); + + std::vector vertexShaderBytecode = LoadShaderBytecode("sample/Shadowmap", ShaderStage::Vertex, "main"); + std::vector fragmentShaderBytecode = LoadShaderBytecode("sample/Shadowmap", ShaderStage::Fragment, "main"); + + m_RpsPipelines.shadowPipeline = m_RenderContext->CreateGraphicsPipeline({ + GraphicsPipelineDesc{ + .debugName = "Shadowmap Pipeline", + .VS{ + .byteCode = reinterpret_cast(vertexShaderBytecode.data()), + .byteSize = static_cast(vertexShaderBytecode.size()), + .entryFunc = "vs"}, + .PS{ + .byteCode = reinterpret_cast(fragmentShaderBytecode.data()), + .byteSize = static_cast(fragmentShaderBytecode.size()), + .entryFunc = "ps"}, + .colorFormats = {}, + .depthFormat = GraphicsFormat::D32_FLOAT, + .stencilFormat = GraphicsFormat::Undefined, + .vertexBufferBindings{ + {.byteStride = sizeof(Vector3) + sizeof(Vector2) + sizeof(Vector3), + .attributes = + { + {.byteOffset = 0, .format = GraphicsFormat::RGB32_FLOAT}, + {.byteOffset = 12, .format = GraphicsFormat::RG32_FLOAT}, + {.byteOffset = 20, .format = GraphicsFormat::RGB32_FLOAT}}}}, + .bindLayouts = { m_GlobalBindLayout }, + .dynamicBuffer = m_DynamicBufferHandle, + .renderPass = shadowPass.GetRenderPass().renderPass, + .subpassIndex = 0 + } + }); } void RenderSystem::CreateDefaultResources() { + std::vector blackTextureData(4, 0); + std::vector whiteTextureData(4, 255); + + m_DefaultResources.blackTexture = m_RenderContext->CreateTextureHandle( + TextureDesc + { + .debugName = "Black Texture", + .width = 1, + .height = 1, + .data = blackTextureData.data(), + .dataSize = 4, + }); + + m_DefaultResources.whiteTexture = m_RenderContext->CreateTextureHandle( + TextureDesc + { + .debugName = "White Texture", + .width = 1, + .height = 1, + .data = whiteTextureData.data(), + .dataSize = 4, + }); } } // namespace gore \ No newline at end of file From 1d31a8d2ced6578800e524175e35e799dd3430e1 Mon Sep 17 00:00:00 2001 From: Top61ly Date: Thu, 3 Apr 2025 18:58:46 +0800 Subject: [PATCH 06/25] feat: add static wrapper functions for shadowmap and forward opaque passes in RenderSystem --- src/Rendering/RenderSystem.cpp | 8 ++++++++ src/Rendering/RenderSystem.h | 4 ++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/Rendering/RenderSystem.cpp b/src/Rendering/RenderSystem.cpp index 278004d..e6a76d1 100644 --- a/src/Rendering/RenderSystem.cpp +++ b/src/Rendering/RenderSystem.cpp @@ -1541,4 +1541,12 @@ void RenderSystem::CreateDefaultResources() }); } +void RenderSystem::ShadowmapPassWithRPSWrapper(const RpsCmdCallbackContext* pContext) +{ +} + +void RenderSystem::ForwardOpaquePassWithRPSWrapper(const RpsCmdCallbackContext* pContext) +{ +} + } // namespace gore \ No newline at end of file diff --git a/src/Rendering/RenderSystem.h b/src/Rendering/RenderSystem.h index 49d6781..a361694 100644 --- a/src/Rendering/RenderSystem.h +++ b/src/Rendering/RenderSystem.h @@ -166,8 +166,8 @@ ENGINE_CLASS(RenderSystem) final : System uint64_t CalcGuaranteedCompletedFrameindexForRps() const; // static void DrawTriangleWithRPSWrapper(const RpsCmdCallbackContext* pContext); - // static void ShadowmapPassWithRPSWrapper(const RpsCmdCallbackContext* pContext); - // static void ForwardOpaquePassWithRPSWrapper(const RpsCmdCallbackContext* pContext); + static void ShadowmapPassWithRPSWrapper(const RpsCmdCallbackContext* pContext); + static void ForwardOpaquePassWithRPSWrapper(const RpsCmdCallbackContext* pContext); // void DrawTriangle(vk::CommandBuffer commandBuffer); private: std::unique_ptr m_RenderContext; From 9ecd19808b2ed94eaac7d62feb3112e7fc7640df Mon Sep 17 00:00:00 2001 From: Top61ly Date: Sun, 6 Apr 2025 23:18:05 +0800 Subject: [PATCH 07/25] feat: add profiling scopes to RenderSystem methods for performance tracking --- src/Rendering/RenderSystem.cpp | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/src/Rendering/RenderSystem.cpp b/src/Rendering/RenderSystem.cpp index e6a76d1..16add63 100644 --- a/src/Rendering/RenderSystem.cpp +++ b/src/Rendering/RenderSystem.cpp @@ -25,12 +25,19 @@ #include "Rendering/AutoRenderPass.h" #include "RenderContextHelper.h" +#include "Profiler/microprofile.h" + #include #include #include #include #include +MICROPROFILE_DEFINE(g_RenderSystemInit, "System", "RenderSystemInit", MP_AUTO); +MICROPROFILE_DEFINE(g_PrepareDrawData, "RenderSystemLoop", "PrepareDrawData", MP_BLUE); +MICROPROFILE_DEFINE(g_RenderGraphUpdate, "RenderSystemLoop", "RenderGraphUpdate", MP_BLUE); +MICROPROFILE_DEFINE(g_ExecuteRenderGraph, "RenderSystemLoop", "ExecuteRenderGraph", MP_BLUE); + namespace gore { @@ -78,6 +85,8 @@ RenderSystem::~RenderSystem() void RenderSystem::Initialize() { + MICROPROFILE_SCOPE(g_RenderSystemInit); + Window* window = m_App->GetWindow(); int width, height; window->GetSize(&width, &height); @@ -160,6 +169,8 @@ static void PrepareDrawStreamByDrawInfo(std::unordered_map& void RenderSystem::PrepareDrawData() { + MICROPROFILE_SCOPE(g_PrepareDrawData); + DrawCreateInfo info = {}; info.passName = "ForwardPass"; info.alphaMode = AlphaMode::Opaque; @@ -526,7 +537,12 @@ void RenderSystem::CreateRpsRuntimeDeivce() createInfo.pfnRecordDebugMarker = &RecordDebugMarker; createInfo.pfnSetDebugName = &SetDebugName; - m_RpsSystem = InitializeRpsSystem(createInfo); + m_RpsSystem = InitializeRpsSystem(createInfo); + + RpsRenderGraph& renderGraph = *m_RpsSystem->rpsRDG; + + AssertIfRpsFailed(rpsProgramBindNode(rpsRenderGraphGetMainEntry(renderGraph), "Shadowmap", &ShadowmapPassWithRPSWrapper, this)); + AssertIfRpsFailed(rpsProgramBindNode(rpsRenderGraphGetMainEntry(renderGraph), "ForwardOpaque", &ForwardOpaquePassWithRPSWrapper, this)); } void RenderSystem::DestroyRpsRuntimeDevice() @@ -566,6 +582,8 @@ void RenderSystem::RunRpsSystem() void RenderSystem::UpdateRenderGraph() { + MICROPROFILE_SCOPE(g_RenderGraphUpdate); + if (IsRpsReady() == false) return; @@ -618,6 +636,8 @@ RpsResult RenderSystem::ExecuteRenderGraph( bool bWaitSwapChain, bool frameEnd) { + MICROPROFILE_SCOPE(g_ExecuteRenderGraph); + if (IsRpsReady() == false) { LOG_STREAM(FATAL) << "RPS system is not ready." << std::endl; From 29df4a71f833849d7d1561c249610f497d040bee Mon Sep 17 00:00:00 2001 From: Top61ly Date: Thu, 10 Apr 2025 00:17:32 +0800 Subject: [PATCH 08/25] feat: add PerDrawData and PerframeData structures for rendering data management --- src/Rendering/GPUData/GlobalConstantBuffer.h | 17 ----------------- .../Rendering/GPUData}/PerDrawData.h | 0 .../Rendering/GPUData}/PerframeData.h | 0 3 files changed, 17 deletions(-) delete mode 100644 src/Rendering/GPUData/GlobalConstantBuffer.h rename {sample/Scripts/Rendering => src/Rendering/GPUData}/PerDrawData.h (100%) rename {sample/Scripts/Rendering => src/Rendering/GPUData}/PerframeData.h (100%) diff --git a/src/Rendering/GPUData/GlobalConstantBuffer.h b/src/Rendering/GPUData/GlobalConstantBuffer.h deleted file mode 100644 index a7bcac7..0000000 --- a/src/Rendering/GPUData/GlobalConstantBuffer.h +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once - -#include "Math/Matrix4x4.h" -#include "Math/Vector3.h" -#include "Math/Vector4.h" - -namespace gore::gfx -{ -struct GlobalConstantBuffer -{ - Matrix4x4 vpMatrix; - - Matrix4x4 directionalLightVPMatrix; - Vector3 directionalLightColor; - float directionalLightIntensity; -}; -} // namespace gore::gfx \ No newline at end of file diff --git a/sample/Scripts/Rendering/PerDrawData.h b/src/Rendering/GPUData/PerDrawData.h similarity index 100% rename from sample/Scripts/Rendering/PerDrawData.h rename to src/Rendering/GPUData/PerDrawData.h diff --git a/sample/Scripts/Rendering/PerframeData.h b/src/Rendering/GPUData/PerframeData.h similarity index 100% rename from sample/Scripts/Rendering/PerframeData.h rename to src/Rendering/GPUData/PerframeData.h From 62fc8d8015ed3b774e3bf015b0c05cbe258ea74c Mon Sep 17 00:00:00 2001 From: Top61ly Date: Thu, 10 Apr 2025 00:17:41 +0800 Subject: [PATCH 09/25] refactor: remove unused RPS initialization and related data structures from SampleApp feat: implement per-frame data upload in RenderSystem for improved rendering --- sample/App/SampleApp.cpp | 148 ++++++++++++--------------------- sample/App/SampleApp.h | 1 - src/Rendering/RenderSystem.cpp | 36 +++++++- 3 files changed, 86 insertions(+), 99 deletions(-) diff --git a/sample/App/SampleApp.cpp b/sample/App/SampleApp.cpp index 5b171bc..241b237 100644 --- a/sample/App/SampleApp.cpp +++ b/sample/App/SampleApp.cpp @@ -35,9 +35,6 @@ #include "Scripts/Math/BitUtils.h" -#include "Scripts/Rendering/PerframeData.h" -#include "Scripts/Rendering/PerDrawData.h" - SampleApp::SampleApp(int argc, char** argv) : App(argc, argv) { @@ -47,14 +44,6 @@ SampleApp::~SampleApp() { } -void SampleApp::InitializeRpsSystem() -{ - RpsRenderGraph& renderGraph = *m_RenderSystem->GetRpsSystem()->rpsRDG; - // AssertIfRpsFailed(rpsProgramBindNode(rpsRenderGraphGetMainEntry(renderGraph), "Triangle", &DrawTriangleWithRPSWrapper, this)); - AssertIfRpsFailed(rpsProgramBindNode(rpsRenderGraphGetMainEntry(renderGraph), "Shadowmap", &ShadowmapPassWithRPSWrapper, this)); - AssertIfRpsFailed(rpsProgramBindNode(rpsRenderGraphGetMainEntry(renderGraph), "ForwardOpaque", &ForwardOpaquePassWithRPSWrapper, this)); -} - void SampleApp::CreateRenderPassDesc() { renderPasses.forwardPassDesc = {{GraphicsFormat::BGRA8_SRGB}}; @@ -63,31 +52,31 @@ void SampleApp::CreateRenderPassDesc() void SampleApp::CreateUnifiedGlobalDynamicBuffer() { - auto& renderContext = m_RenderSystem->GetRenderContext(); - - size_t alignmentSize = MathUtils::AlignUp(sizeof(PerDrawData), m_GraphicsCaps.minUniformBufferOffsetAlignment); - - size_t renderCount = 4; - std::vector dynamicUniformBufferData(alignmentSize * renderCount); - - for (size_t i = 0; i < renderCount; ++i) - { - PerDrawData* perDrawData = reinterpret_cast(dynamicUniformBufferData.data() + (i * alignmentSize)); - perDrawData->model[0] = Matrix4x4(1.f, 0.f, 0.f, 0.f, 0.f, 1.f, 0.f, 0.f, 0.f, 0.f, 1.f, 0.f, i, 0.f, 0.f, 1.f); - } - - m_UnifiedDynamicBuffer = renderContext.CreateBuffer( - {.debugName = "Dynamic Uniform Buffer", - .byteSize = static_cast(dynamicUniformBufferData.size()), - .usage = BufferUsage::Uniform, - .memUsage = MemoryUsage::GPU, - .data = dynamicUniformBufferData.data()}); - - m_UnifiedDynamicBufferHandle = renderContext.CreateDynamicBuffer( - {.debugName = "Dynamic Uniform Buffer", - .buffer = m_UnifiedDynamicBuffer, - .offset = 0, - .range = sizeof(PerDrawData)}); + // auto& renderContext = m_RenderSystem->GetRenderContext(); + + // size_t alignmentSize = MathUtils::AlignUp(sizeof(PerDrawData), m_GraphicsCaps.minUniformBufferOffsetAlignment); + + // size_t renderCount = 4; + // std::vector dynamicUniformBufferData(alignmentSize * renderCount); + + // for (size_t i = 0; i < renderCount; ++i) + // { + // PerDrawData* perDrawData = reinterpret_cast(dynamicUniformBufferData.data() + (i * alignmentSize)); + // perDrawData->model[0] = Matrix4x4(1.f, 0.f, 0.f, 0.f, 0.f, 1.f, 0.f, 0.f, 0.f, 0.f, 1.f, 0.f, i, 0.f, 0.f, 1.f); + // } + + // m_UnifiedDynamicBuffer = renderContext.CreateBuffer( + // {.debugName = "Dynamic Uniform Buffer", + // .byteSize = static_cast(dynamicUniformBufferData.size()), + // .usage = BufferUsage::Uniform, + // .memUsage = MemoryUsage::GPU, + // .data = dynamicUniformBufferData.data()}); + + // m_UnifiedDynamicBufferHandle = renderContext.CreateDynamicBuffer( + // {.debugName = "Dynamic Uniform Buffer", + // .buffer = m_UnifiedDynamicBuffer, + // .offset = 0, + // .range = sizeof(PerDrawData)}); } void SampleApp::CreatePipelines() @@ -260,44 +249,42 @@ void SampleApp::PrepareGraphics() void SampleApp::CreateGlobalBindGroup() { - using namespace gore::gfx; + // using namespace gore::gfx; - RenderContext& renderContext = m_RenderSystem->GetRenderContext(); - m_GlobalConstantBuffer = renderContext.CreateBuffer({.debugName = "Global Constant Buffer", - .byteSize = sizeof(PerframeData), - .usage = BufferUsage::Uniform, - .memUsage = MemoryUsage::CPU_TO_GPU}); + // RenderContext& renderContext = m_RenderSystem->GetRenderContext(); + // m_GlobalConstantBuffer = renderContext.CreateBuffer({.debugName = "Global Constant Buffer", + // .byteSize = sizeof(PerframeData), + // .usage = BufferUsage::Uniform, + // .memUsage = MemoryUsage::CPU_TO_GPU}); - m_ShadowmapSampler = renderContext.CreateSampler({ - .debugName = "Shadowmap Sampler", - }); - - std::vector bindings{ - {0, BindType::UniformBuffer, 1, ShaderStage::Vertex | ShaderStage::Fragment}, - {1, BindType::SampledImage, 1, ShaderStage::Fragment}, - {2, BindType::Sampler, 1, ShaderStage::Fragment}, - }; - - BindLayoutCreateInfo bindLayoutCreateInfo = {.name = "Global Descriptor Set Layout", .bindings = bindings}; - - m_GlobalBindLayout = renderContext.GetOrCreateBindLayout(bindLayoutCreateInfo); - - m_GlobalBindGroup = renderContext.CreateBindGroup({ - .debugName = "Global BindGroup", - .updateFrequency = UpdateFrequency::PerFrame, - .textures = {{1, defaultResources.blackTexture}}, - .buffers = {{0, m_GlobalConstantBuffer, 0, sizeof(PerframeData), BindType::UniformBuffer}}, - .samplers = {{2, m_ShadowmapSampler}}, - .bindLayout = &m_GlobalBindLayout, - }); + // m_ShadowmapSampler = renderContext.CreateSampler({ + // .debugName = "Shadowmap Sampler", + // }); + + // std::vector bindings{ + // {0, BindType::UniformBuffer, 1, ShaderStage::Vertex | ShaderStage::Fragment}, + // {1, BindType::SampledImage, 1, ShaderStage::Fragment}, + // {2, BindType::Sampler, 1, ShaderStage::Fragment}, + // }; + + // BindLayoutCreateInfo bindLayoutCreateInfo = {.name = "Global Descriptor Set Layout", .bindings = bindings}; + + // m_GlobalBindLayout = renderContext.GetOrCreateBindLayout(bindLayoutCreateInfo); + + // m_GlobalBindGroup = renderContext.CreateBindGroup({ + // .debugName = "Global BindGroup", + // .updateFrequency = UpdateFrequency::PerFrame, + // .textures = {{1, defaultResources.blackTexture}}, + // .buffers = {{0, m_GlobalConstantBuffer, 0, sizeof(PerframeData), BindType::UniformBuffer}}, + // .samplers = {{2, m_ShadowmapSampler}}, + // .bindLayout = &m_GlobalBindLayout, + // }); } void SampleApp::Initialize() { m_GraphicsCaps = m_RenderSystem->GetGraphicsCaps(); - InitializeRpsSystem(); - PrepareGraphics(); Material forwardMat; @@ -527,35 +514,6 @@ static int frameCount = 0; void SampleApp::PreRender() { - Camera* mainCamera = Camera::Main; - if (mainCamera == nullptr) - { - return; - } - - PerframeData perframeData; - perframeData.vpMatrix = mainCamera->GetViewProjectionMatrix(); - - // Update Main Light - auto& gameObjects = scene->GetActiveScene()->GetGameObjects(); - for (auto& gameObject : gameObjects) - { - Light* light = gameObject->GetComponent(); - if (light == nullptr) - continue; - - Matrix4x4 lightMatrix = gameObject->GetTransform()->GetWorldToLocalMatrixIgnoreScale(); - Matrix4x4 orthoMatrix = Matrix4x4::CreateOrthographicLH(100.0f, 100.0f, .1f, 100.0f); - perframeData.directionalLightVPMatrix = lightMatrix * orthoMatrix; - - LightData lightData = light->GetData(); - perframeData.directionalLightColor = lightData.color; - perframeData.directionalLightIntensity = lightData.intensity; - break; - } - - gore::gfx::RenderContext& renderContext = m_RenderSystem->GetRenderContext(); - renderContext.CopyDataToBuffer(m_GlobalConstantBuffer, perframeData); } void SampleApp::UpdateFPSText(float deltaTime) diff --git a/sample/App/SampleApp.h b/sample/App/SampleApp.h index e53be64..bd7ea59 100644 --- a/sample/App/SampleApp.h +++ b/sample/App/SampleApp.h @@ -34,7 +34,6 @@ class SampleApp final : public gore::App void PreRender(); // Temporary RenderPassDesc for pipeline creation - void InitializeRpsSystem(); void CreateRenderPassDesc(); void CreateUnifiedGlobalDynamicBuffer(); void CreateGlobalBindGroup(); diff --git a/src/Rendering/RenderSystem.cpp b/src/Rendering/RenderSystem.cpp index 16add63..7f07b34 100644 --- a/src/Rendering/RenderSystem.cpp +++ b/src/Rendering/RenderSystem.cpp @@ -21,9 +21,11 @@ #include "Utilities/GLTFLoader.h" #include "Utilities/Math/MathHelpers.h" -#include "Rendering/GPUData/GlobalConstantBuffer.h" #include "Rendering/AutoRenderPass.h" #include "RenderContextHelper.h" +#include "Rendering/Components/Light.h" +#include "Rendering/GPUData/PerDrawData.h" +#include "Rendering/GPUData/PerFrameData.h" #include "Profiler/microprofile.h" @@ -1022,6 +1024,34 @@ uint64_t RenderSystem::CalcGuaranteedCompletedFrameindexForRps() const void RenderSystem::UploadPerframeGlobalConstantBuffer(uint32_t imageIndex) { + Camera* mainCamera = Camera::Main; + if (mainCamera == nullptr) + { + return; + } + + PerframeData perframeData; + perframeData.vpMatrix = mainCamera->GetViewProjectionMatrix(); + + // Update Main Light + auto& gameObjects = Scene::GetActiveScene()->GetGameObjects(); + for (auto& gameObject : gameObjects) + { + Light* light = gameObject->GetComponent(); + if (light == nullptr) + continue; + + Matrix4x4 lightMatrix = gameObject->GetTransform()->GetWorldToLocalMatrixIgnoreScale(); + Matrix4x4 orthoMatrix = Matrix4x4::CreateOrthographicLH(100.0f, 100.0f, .1f, 100.0f); + perframeData.directionalLightVPMatrix = lightMatrix * orthoMatrix; + + LightData lightData = light->GetData(); + perframeData.directionalLightColor = lightData.color; + perframeData.directionalLightIntensity = lightData.intensity; + break; + } + + m_RenderContext->CopyDataToBuffer(m_GlobalConstantBuffer, perframeData); } void RenderSystem::CreateDepthBuffer() @@ -1099,7 +1129,7 @@ void RenderSystem::CreateGlobalDescriptorSets() { m_GlobalConstantBuffer = m_RenderContext->CreateBuffer({ .debugName = "Global Constant Buffer", - .byteSize = sizeof(GlobalConstantBuffer), + .byteSize = sizeof(PerframeData), .usage = BufferUsage::Uniform, .memUsage = MemoryUsage::CPU_TO_GPU }); @@ -1120,7 +1150,7 @@ void RenderSystem::CreateGlobalDescriptorSets() .debugName = "Global BindGroup", .updateFrequency = UpdateFrequency::PerFrame, .textures = {}, - .buffers = {{0, m_GlobalConstantBuffer, 0, sizeof(GlobalConstantBuffer), BindType::UniformBuffer}}, + .buffers = {{0, m_GlobalConstantBuffer, 0, sizeof(PerframeData), BindType::UniformBuffer}}, .samplers = {}, .bindLayout = &m_GlobalBindLayout, }); From f90396fbe8000c06264e47ea285232cabe84275b Mon Sep 17 00:00:00 2001 From: Top61ly Date: Sun, 13 Apr 2025 00:34:14 +0800 Subject: [PATCH 10/25] feat: implement shadowmap and forward opaque rendering wrappers in RenderSystem --- sample/App/SampleApp.cpp | 320 ++++++++++++++++----------------- src/Rendering/RenderSystem.cpp | 26 +++ 2 files changed, 186 insertions(+), 160 deletions(-) diff --git a/sample/App/SampleApp.cpp b/sample/App/SampleApp.cpp index 241b237..62a723f 100644 --- a/sample/App/SampleApp.cpp +++ b/sample/App/SampleApp.cpp @@ -115,171 +115,171 @@ void SampleApp::CreateDefaultResources() }); } -void SampleApp::CreateForwardPipeline() -{ - using namespace gore::gfx; - - RenderContext& renderContext = m_RenderSystem->GetRenderContext(); - AutoRenderPass forwardPass(&renderContext, renderPasses.forwardPassDesc); - - // Create a pipeline for the forward rendering - std::vector vertexShaderBytecode = sample::utils::LoadShaderBytecode("sample/SimpleLit", ShaderStage::Vertex, "main"); - std::vector fragmentShaderBytecode = sample::utils::LoadShaderBytecode("sample/SimpleLit", ShaderStage::Fragment, "main"); - - pipelines.forwardPipeline = renderContext.CreateGraphicsPipeline( - GraphicsPipelineDesc{ - .debugName = "UnLit Pipeline", - .VS{ - .byteCode = reinterpret_cast(vertexShaderBytecode.data()), - .byteSize = static_cast(vertexShaderBytecode.size()), - .entryFunc = "vs"}, - .PS{ - .byteCode = reinterpret_cast(fragmentShaderBytecode.data()), - .byteSize = static_cast(fragmentShaderBytecode.size()), - .entryFunc = "ps"}, - .colorFormats = {GraphicsFormat::BGRA8_SRGB}, - .depthFormat = GraphicsFormat::D32_FLOAT, - .stencilFormat = GraphicsFormat::Undefined, - .vertexBufferBindings{ - {.byteStride = sizeof(Vector3) + sizeof(Vector2) + sizeof(Vector3), - .attributes = - { - {.byteOffset = 0, .format = GraphicsFormat::RGB32_FLOAT}, - {.byteOffset = 12, .format = GraphicsFormat::RG32_FLOAT}, - {.byteOffset = 20, .format = GraphicsFormat::RGB32_FLOAT}}}}, - .bindLayouts = {m_GlobalBindLayout}, - .dynamicBuffer = m_UnifiedDynamicBufferHandle, - .renderPass = forwardPass.GetRenderPass().renderPass, - .subpassIndex = 0 - }); -} - -void SampleApp::CreateShadowmapPipeline() -{ - using namespace gore::gfx; - - RenderContext& renderContext = m_RenderSystem->GetRenderContext(); - AutoRenderPass shadowPass(&renderContext, renderPasses.shadowPassDesc); - - // Create a pipeline for the shadowmap rendering - std::vector vertexShaderBytecode = sample::utils::LoadShaderBytecode("sample/Shadowmap", ShaderStage::Vertex, "main"); - std::vector fragmentShaderBytecode = sample::utils::LoadShaderBytecode("sample/Shadowmap", ShaderStage::Fragment, "main"); - - pipelines.shadowPipeline = renderContext.CreateGraphicsPipeline({ - GraphicsPipelineDesc{ - .debugName = "Shadowmap Pipeline", - .VS{ - .byteCode = reinterpret_cast(vertexShaderBytecode.data()), - .byteSize = static_cast(vertexShaderBytecode.size()), - .entryFunc = "vs"}, - .PS{ - .byteCode = reinterpret_cast(fragmentShaderBytecode.data()), - .byteSize = static_cast(fragmentShaderBytecode.size()), - .entryFunc = "ps"}, - .colorFormats = {}, - .depthFormat = GraphicsFormat::D32_FLOAT, - .stencilFormat = GraphicsFormat::Undefined, - .vertexBufferBindings{ - {.byteStride = sizeof(Vector3) + sizeof(Vector2) + sizeof(Vector3), - .attributes = - { - {.byteOffset = 0, .format = GraphicsFormat::RGB32_FLOAT}, - {.byteOffset = 12, .format = GraphicsFormat::RG32_FLOAT}, - {.byteOffset = 20, .format = GraphicsFormat::RGB32_FLOAT}}}}, - .bindLayouts = {m_GlobalBindLayout}, - .dynamicBuffer = m_UnifiedDynamicBufferHandle, - .renderPass = shadowPass.GetRenderPass().renderPass, - .subpassIndex = 0 - } - }); -} - -void SampleApp::DrawTriangleWithRPSWrapper(const RpsCmdCallbackContext* pContext) -{ - RenderSystem& renderSystem = *reinterpret_cast(pContext->pUserRecordContext); - vk::CommandBuffer cmd = rpsVKCommandBufferFromHandle(pContext->hCommandBuffer); - - DrawKey key = {"ForwardPass", AlphaMode::Opaque}; - - renderSystem.DrawRenderer(key, cmd); -} - -void SampleApp::ShadowmapPassWithRPSWrapper(const RpsCmdCallbackContext* pContext) -{ - RenderSystem& renderSystem = *reinterpret_cast(pContext->pUserRecordContext); - vk::CommandBuffer cmd = rpsVKCommandBufferFromHandle(pContext->hCommandBuffer); +// void SampleApp::CreateForwardPipeline() +// { +// using namespace gore::gfx; + +// RenderContext& renderContext = m_RenderSystem->GetRenderContext(); +// AutoRenderPass forwardPass(&renderContext, renderPasses.forwardPassDesc); + +// // Create a pipeline for the forward rendering +// std::vector vertexShaderBytecode = sample::utils::LoadShaderBytecode("sample/SimpleLit", ShaderStage::Vertex, "main"); +// std::vector fragmentShaderBytecode = sample::utils::LoadShaderBytecode("sample/SimpleLit", ShaderStage::Fragment, "main"); + +// pipelines.forwardPipeline = renderContext.CreateGraphicsPipeline( +// GraphicsPipelineDesc{ +// .debugName = "UnLit Pipeline", +// .VS{ +// .byteCode = reinterpret_cast(vertexShaderBytecode.data()), +// .byteSize = static_cast(vertexShaderBytecode.size()), +// .entryFunc = "vs"}, +// .PS{ +// .byteCode = reinterpret_cast(fragmentShaderBytecode.data()), +// .byteSize = static_cast(fragmentShaderBytecode.size()), +// .entryFunc = "ps"}, +// .colorFormats = {GraphicsFormat::BGRA8_SRGB}, +// .depthFormat = GraphicsFormat::D32_FLOAT, +// .stencilFormat = GraphicsFormat::Undefined, +// .vertexBufferBindings{ +// {.byteStride = sizeof(Vector3) + sizeof(Vector2) + sizeof(Vector3), +// .attributes = +// { +// {.byteOffset = 0, .format = GraphicsFormat::RGB32_FLOAT}, +// {.byteOffset = 12, .format = GraphicsFormat::RG32_FLOAT}, +// {.byteOffset = 20, .format = GraphicsFormat::RGB32_FLOAT}}}}, +// .bindLayouts = {m_GlobalBindLayout}, +// .dynamicBuffer = m_UnifiedDynamicBufferHandle, +// .renderPass = forwardPass.GetRenderPass().renderPass, +// .subpassIndex = 0 +// }); +// } + +// void SampleApp::CreateShadowmapPipeline() +// { +// using namespace gore::gfx; + +// RenderContext& renderContext = m_RenderSystem->GetRenderContext(); +// AutoRenderPass shadowPass(&renderContext, renderPasses.shadowPassDesc); + +// // Create a pipeline for the shadowmap rendering +// std::vector vertexShaderBytecode = sample::utils::LoadShaderBytecode("sample/Shadowmap", ShaderStage::Vertex, "main"); +// std::vector fragmentShaderBytecode = sample::utils::LoadShaderBytecode("sample/Shadowmap", ShaderStage::Fragment, "main"); + +// pipelines.shadowPipeline = renderContext.CreateGraphicsPipeline({ +// GraphicsPipelineDesc{ +// .debugName = "Shadowmap Pipeline", +// .VS{ +// .byteCode = reinterpret_cast(vertexShaderBytecode.data()), +// .byteSize = static_cast(vertexShaderBytecode.size()), +// .entryFunc = "vs"}, +// .PS{ +// .byteCode = reinterpret_cast(fragmentShaderBytecode.data()), +// .byteSize = static_cast(fragmentShaderBytecode.size()), +// .entryFunc = "ps"}, +// .colorFormats = {}, +// .depthFormat = GraphicsFormat::D32_FLOAT, +// .stencilFormat = GraphicsFormat::Undefined, +// .vertexBufferBindings{ +// {.byteStride = sizeof(Vector3) + sizeof(Vector2) + sizeof(Vector3), +// .attributes = +// { +// {.byteOffset = 0, .format = GraphicsFormat::RGB32_FLOAT}, +// {.byteOffset = 12, .format = GraphicsFormat::RG32_FLOAT}, +// {.byteOffset = 20, .format = GraphicsFormat::RGB32_FLOAT}}}}, +// .bindLayouts = {m_GlobalBindLayout}, +// .dynamicBuffer = m_UnifiedDynamicBufferHandle, +// .renderPass = shadowPass.GetRenderPass().renderPass, +// .subpassIndex = 0 +// } +// }); +// } + +// void SampleApp::DrawTriangleWithRPSWrapper(const RpsCmdCallbackContext* pContext) +// { +// RenderSystem& renderSystem = *reinterpret_cast(pContext->pUserRecordContext); +// vk::CommandBuffer cmd = rpsVKCommandBufferFromHandle(pContext->hCommandBuffer); + +// DrawKey key = {"ForwardPass", AlphaMode::Opaque}; + +// renderSystem.DrawRenderer(key, cmd); +// } + +// void SampleApp::ShadowmapPassWithRPSWrapper(const RpsCmdCallbackContext* pContext) +// { +// RenderSystem& renderSystem = *reinterpret_cast(pContext->pUserRecordContext); +// vk::CommandBuffer cmd = rpsVKCommandBufferFromHandle(pContext->hCommandBuffer); - DrawKey key = {"ShadowCaster", AlphaMode::Opaque}; +// DrawKey key = {"ShadowCaster", AlphaMode::Opaque}; - renderSystem.DrawRenderer(key, cmd); -} +// renderSystem.DrawRenderer(key, cmd); +// } -void SampleApp::ForwardOpaquePassWithRPSWrapper(const RpsCmdCallbackContext* pContext) -{ - RenderSystem& renderSystem = *reinterpret_cast(pContext->pUserRecordContext); - vk::CommandBuffer cmd = rpsVKCommandBufferFromHandle(pContext->hCommandBuffer); +// void SampleApp::ForwardOpaquePassWithRPSWrapper(const RpsCmdCallbackContext* pContext) +// { +// RenderSystem& renderSystem = *reinterpret_cast(pContext->pUserRecordContext); +// vk::CommandBuffer cmd = rpsVKCommandBufferFromHandle(pContext->hCommandBuffer); - // Update ShadowMap Descriptor Set - VkImageView shadowmapView; - RpsResult result = rpsVKGetCmdArgImageView(pContext, 0, &shadowmapView); - if (RPS_SUCCEEDED(result) == true) - { - SampleApp* app = dynamic_cast(App::Get()); - - RawBindGroupUpdateDesc updateDesc = { - .textures = {{1, shadowmapView, BindType::SampledImage}}, - }; - - renderSystem.GetRenderContext().UpdateBindGroup(app->m_GlobalBindGroup, updateDesc); - } - - DrawKey key = {"ForwardPass", AlphaMode::Opaque}; - - renderSystem.DrawRenderer(key, cmd); -} - -void SampleApp::PrepareGraphics() -{ - CreateDefaultResources(); - CreateRenderPassDesc(); - CreateUnifiedGlobalDynamicBuffer(); - CreateGlobalBindGroup(); - CreatePipelines(); -} - -void SampleApp::CreateGlobalBindGroup() -{ - // using namespace gore::gfx; - - // RenderContext& renderContext = m_RenderSystem->GetRenderContext(); - // m_GlobalConstantBuffer = renderContext.CreateBuffer({.debugName = "Global Constant Buffer", - // .byteSize = sizeof(PerframeData), - // .usage = BufferUsage::Uniform, - // .memUsage = MemoryUsage::CPU_TO_GPU}); +// // Update ShadowMap Descriptor Set +// VkImageView shadowmapView; +// RpsResult result = rpsVKGetCmdArgImageView(pContext, 0, &shadowmapView); +// if (RPS_SUCCEEDED(result) == true) +// { +// SampleApp* app = dynamic_cast(App::Get()); + +// RawBindGroupUpdateDesc updateDesc = { +// .textures = {{1, shadowmapView, BindType::SampledImage}}, +// }; + +// renderSystem.GetRenderContext().UpdateBindGroup(app->m_GlobalBindGroup, updateDesc); +// } + +// DrawKey key = {"ForwardPass", AlphaMode::Opaque}; + +// renderSystem.DrawRenderer(key, cmd); +// } + +// void SampleApp::PrepareGraphics() +// { +// CreateDefaultResources(); +// CreateRenderPassDesc(); +// CreateUnifiedGlobalDynamicBuffer(); +// CreateGlobalBindGroup(); +// CreatePipelines(); +// } + +// void SampleApp::CreateGlobalBindGroup() +// { +// using namespace gore::gfx; + +// RenderContext& renderContext = m_RenderSystem->GetRenderContext(); +// m_GlobalConstantBuffer = renderContext.CreateBuffer({.debugName = "Global Constant Buffer", +// .byteSize = sizeof(PerframeData), +// .usage = BufferUsage::Uniform, +// .memUsage = MemoryUsage::CPU_TO_GPU}); - // m_ShadowmapSampler = renderContext.CreateSampler({ - // .debugName = "Shadowmap Sampler", - // }); - - // std::vector bindings{ - // {0, BindType::UniformBuffer, 1, ShaderStage::Vertex | ShaderStage::Fragment}, - // {1, BindType::SampledImage, 1, ShaderStage::Fragment}, - // {2, BindType::Sampler, 1, ShaderStage::Fragment}, - // }; - - // BindLayoutCreateInfo bindLayoutCreateInfo = {.name = "Global Descriptor Set Layout", .bindings = bindings}; - - // m_GlobalBindLayout = renderContext.GetOrCreateBindLayout(bindLayoutCreateInfo); - - // m_GlobalBindGroup = renderContext.CreateBindGroup({ - // .debugName = "Global BindGroup", - // .updateFrequency = UpdateFrequency::PerFrame, - // .textures = {{1, defaultResources.blackTexture}}, - // .buffers = {{0, m_GlobalConstantBuffer, 0, sizeof(PerframeData), BindType::UniformBuffer}}, - // .samplers = {{2, m_ShadowmapSampler}}, - // .bindLayout = &m_GlobalBindLayout, - // }); -} +// m_ShadowmapSampler = renderContext.CreateSampler({ +// .debugName = "Shadowmap Sampler", +// }); + +// std::vector bindings{ +// {0, BindType::UniformBuffer, 1, ShaderStage::Vertex | ShaderStage::Fragment}, +// {1, BindType::SampledImage, 1, ShaderStage::Fragment}, +// {2, BindType::Sampler, 1, ShaderStage::Fragment}, +// }; + +// BindLayoutCreateInfo bindLayoutCreateInfo = {.name = "Global Descriptor Set Layout", .bindings = bindings}; + +// m_GlobalBindLayout = renderContext.GetOrCreateBindLayout(bindLayoutCreateInfo); + +// m_GlobalBindGroup = renderContext.CreateBindGroup({ +// .debugName = "Global BindGroup", +// .updateFrequency = UpdateFrequency::PerFrame, +// .textures = {{1, defaultResources.blackTexture}}, +// .buffers = {{0, m_GlobalConstantBuffer, 0, sizeof(PerframeData), BindType::UniformBuffer}}, +// .samplers = {{2, m_ShadowmapSampler}}, +// .bindLayout = &m_GlobalBindLayout, +// }); +// } void SampleApp::Initialize() { diff --git a/src/Rendering/RenderSystem.cpp b/src/Rendering/RenderSystem.cpp index 7f07b34..0390d09 100644 --- a/src/Rendering/RenderSystem.cpp +++ b/src/Rendering/RenderSystem.cpp @@ -1593,10 +1593,36 @@ void RenderSystem::CreateDefaultResources() void RenderSystem::ShadowmapPassWithRPSWrapper(const RpsCmdCallbackContext* pContext) { + RenderSystem& renderSystem = *reinterpret_cast(pContext->pUserRecordContext); + vk::CommandBuffer cmd = rpsVKCommandBufferFromHandle(pContext->hCommandBuffer); + + DrawKey key = {"ShadowCaster", AlphaMode::Opaque}; + + renderSystem.DrawRenderer(key, cmd); } void RenderSystem::ForwardOpaquePassWithRPSWrapper(const RpsCmdCallbackContext* pContext) { + RenderSystem& renderSystem = *reinterpret_cast(pContext->pUserRecordContext); + vk::CommandBuffer cmd = rpsVKCommandBufferFromHandle(pContext->hCommandBuffer); + + // Update ShadowMap Descriptor Set + // VkImageView shadowmapView; + // RpsResult result = rpsVKGetCmdArgImageView(pContext, 0, &shadowmapView); + // if (RPS_SUCCEEDED(result) == true) + // { + // // SampleApp* app = dynamic_cast(App::Get()); + + // RawBindGroupUpdateDesc updateDesc = { + // .textures = {{1, shadowmapView, BindType::SampledImage}}, + // }; + + // renderSystem.GetRenderContext().UpdateBindGroup(app->m_GlobalBindGroup, updateDesc); + // } + + DrawKey key = {"ForwardPass", AlphaMode::Opaque}; + + renderSystem.DrawRenderer(key, cmd); } } // namespace gore \ No newline at end of file From bd6a9a81f0b109d3c65a84e052c45007e95c21e1 Mon Sep 17 00:00:00 2001 From: Top61ly Date: Sun, 13 Apr 2025 21:57:03 +0800 Subject: [PATCH 11/25] feat: add overridePipeline parameter to DrawRenderer and ScheduleDrawStream functions --- sample/App/SampleApp.cpp | 84 ++++++++----------------- sample/App/SampleApp.h | 78 +++++++++++------------ src/Rendering/DrawStream/Draw.cpp | 2 +- src/Rendering/DrawStream/DrawStream.cpp | 4 +- src/Rendering/DrawStream/DrawStream.h | 2 +- src/Rendering/RenderSystem.cpp | 6 +- src/Rendering/RenderSystem.h | 2 +- 7 files changed, 74 insertions(+), 104 deletions(-) diff --git a/sample/App/SampleApp.cpp b/sample/App/SampleApp.cpp index 62a723f..b573cd7 100644 --- a/sample/App/SampleApp.cpp +++ b/sample/App/SampleApp.cpp @@ -44,14 +44,14 @@ SampleApp::~SampleApp() { } -void SampleApp::CreateRenderPassDesc() -{ - renderPasses.forwardPassDesc = {{GraphicsFormat::BGRA8_SRGB}}; - renderPasses.shadowPassDesc = {{}, GraphicsFormat::D32_FLOAT}; -} +// void SampleApp::CreateRenderPassDesc() +// { +// renderPasses.forwardPassDesc = {{GraphicsFormat::BGRA8_SRGB}}; +// renderPasses.shadowPassDesc = {{}, GraphicsFormat::D32_FLOAT}; +// } -void SampleApp::CreateUnifiedGlobalDynamicBuffer() -{ +// void SampleApp::CreateUnifiedGlobalDynamicBuffer() +// { // auto& renderContext = m_RenderSystem->GetRenderContext(); // size_t alignmentSize = MathUtils::AlignUp(sizeof(PerDrawData), m_GraphicsCaps.minUniformBufferOffsetAlignment); @@ -77,43 +77,13 @@ void SampleApp::CreateUnifiedGlobalDynamicBuffer() // .buffer = m_UnifiedDynamicBuffer, // .offset = 0, // .range = sizeof(PerDrawData)}); -} - -void SampleApp::CreatePipelines() -{ - CreateForwardPipeline(); - CreateShadowmapPipeline(); -} +// } -void SampleApp::CreateDefaultResources() -{ - using namespace gore::gfx; - - RenderContext& renderContext = m_RenderSystem->GetRenderContext(); - - std::vector blackTextureData(4, 0); - std::vector whiteTextureData(4, 255); - - defaultResources.blackTexture = renderContext.CreateTextureHandle( - TextureDesc - { - .debugName = "Black Texture", - .width = 1, - .height = 1, - .data = blackTextureData.data(), - .dataSize = 4, - }); - - defaultResources.whiteTexture = renderContext.CreateTextureHandle( - TextureDesc - { - .debugName = "White Texture", - .width = 1, - .height = 1, - .data = whiteTextureData.data(), - .dataSize = 4, - }); -} +// void SampleApp::CreatePipelines() +// { +// CreateForwardPipeline(); +// CreateShadowmapPipeline(); +// } // void SampleApp::CreateForwardPipeline() // { @@ -285,19 +255,19 @@ void SampleApp::Initialize() { m_GraphicsCaps = m_RenderSystem->GetGraphicsCaps(); - PrepareGraphics(); + // PrepareGraphics(); - Material forwardMat; - forwardMat.SetAlphaMode(AlphaMode::Opaque); - forwardMat.AddPass(Pass{ - .name = "ShadowCaster", - .shader = pipelines.shadowPipeline, - .bindGroup = {m_GlobalBindGroup}}); + // Material forwardMat; + // forwardMat.SetAlphaMode(AlphaMode::Opaque); + // forwardMat.AddPass(Pass{ + // .name = "ShadowCaster", + // .shader = pipelines.shadowPipeline, + // .bindGroup = {m_GlobalBindGroup}}); - forwardMat.AddPass(Pass{ - .name = "ForwardPass", - .shader = pipelines.forwardPipeline, - .bindGroup = {m_GlobalBindGroup}}); + // forwardMat.AddPass(Pass{ + // .name = "ForwardPass", + // .shader = pipelines.forwardPipeline, + // .bindGroup = {m_GlobalBindGroup}}); gore::gfx::RenderContext& renderContext = m_RenderSystem->GetRenderContext(); @@ -338,9 +308,9 @@ void SampleApp::Initialize() gameObject->SetName("cube"); gore::gfx::MeshRenderer* meshRenderer = gameObject->AddComponent(); meshRenderer->LoadMesh("cube.gltf"); - meshRenderer->SetMaterial(forwardMat); - meshRenderer->SetDynamicBuffer(m_UnifiedDynamicBufferHandle); - meshRenderer->SetDynamicBufferOffset(0); + // meshRenderer->SetMaterial(forwardMat); + // meshRenderer->SetDynamicBuffer(m_UnifiedDynamicBufferHandle); + // meshRenderer->SetDynamicBufferOffset(0); gore::Transform* transform = gameObject->GetTransform(); transform->SetLocalPosition(gore::Vector3::Right * 20.0f); diff --git a/sample/App/SampleApp.h b/sample/App/SampleApp.h index bd7ea59..e7b1c14 100644 --- a/sample/App/SampleApp.h +++ b/sample/App/SampleApp.h @@ -34,55 +34,55 @@ class SampleApp final : public gore::App void PreRender(); // Temporary RenderPassDesc for pipeline creation - void CreateRenderPassDesc(); - void CreateUnifiedGlobalDynamicBuffer(); - void CreateGlobalBindGroup(); - void CreatePipelines(); + // void CreateRenderPassDesc(); + // void CreateUnifiedGlobalDynamicBuffer(); + // void CreateGlobalBindGroup(); + // void CreatePipelines(); - void CreateDefaultResources(); + // void CreateDefaultResources(); - void CreateForwardPipeline(); - void CreateShadowmapPipeline(); + // void CreateForwardPipeline(); + // void CreateShadowmapPipeline(); - const int K_OBJECT_BATCH_COUNT = 128; + // const int K_OBJECT_BATCH_COUNT = 128; - void UpdateAllGameObjectsGPUPerObjectData(); + // // void UpdateAllGameObjectsGPUPerObjectData(); - static void DrawTriangleWithRPSWrapper(const RpsCmdCallbackContext* pContext); - static void ShadowmapPassWithRPSWrapper(const RpsCmdCallbackContext* pContext); - static void ForwardOpaquePassWithRPSWrapper(const RpsCmdCallbackContext* pContext); + // static void DrawTriangleWithRPSWrapper(const RpsCmdCallbackContext* pContext); + // static void ShadowmapPassWithRPSWrapper(const RpsCmdCallbackContext* pContext); + // static void ForwardOpaquePassWithRPSWrapper(const RpsCmdCallbackContext* pContext); private: void UpdateFPSText(float deltaTime); gore::gfx::GraphicsCaps m_GraphicsCaps; - struct SampleRenderPass - { - RenderPassDesc forwardPassDesc; - RenderPassDesc shadowPassDesc; - } renderPasses; - - struct SamplePipeline - { - GraphicsPipelineHandle blankPipeline; - GraphicsPipelineHandle forwardPipeline; - GraphicsPipelineHandle shadowPipeline; - GraphicsPipelineHandle gbuffferPipeline; - } pipelines; - - struct DefaultResources - { - gore::gfx::TextureHandle whiteTexture; - gore::gfx::TextureHandle blackTexture; - } defaultResources; - - gore::gfx::BufferHandle m_UnifiedDynamicBuffer; - gore::gfx::SamplerHandle m_ShadowmapSampler; - gore::gfx::DynamicBufferHandle m_UnifiedDynamicBufferHandle; - - gore::gfx::BindLayout m_GlobalBindLayout; - gore::gfx::BindGroupHandle m_GlobalBindGroup; - gore::gfx::BufferHandle m_GlobalConstantBuffer; + // struct SampleRenderPass + // { + // RenderPassDesc forwardPassDesc; + // RenderPassDesc shadowPassDesc; + // } renderPasses; + + // struct SamplePipeline + // { + // GraphicsPipelineHandle blankPipeline; + // GraphicsPipelineHandle forwardPipeline; + // GraphicsPipelineHandle shadowPipeline; + // GraphicsPipelineHandle gbuffferPipeline; + // } pipelines; + + // struct DefaultResources + // { + // gore::gfx::TextureHandle whiteTexture; + // gore::gfx::TextureHandle blackTexture; + // } defaultResources; + + // gore::gfx::BufferHandle m_UnifiedDynamicBuffer; + // gore::gfx::SamplerHandle m_ShadowmapSampler; + // gore::gfx::DynamicBufferHandle m_UnifiedDynamicBufferHandle; + + // gore::gfx::BindLayout m_GlobalBindLayout; + // gore::gfx::BindGroupHandle m_GlobalBindGroup; + // gore::gfx::BufferHandle m_GlobalConstantBuffer; private: gore::Scene* scene; }; diff --git a/src/Rendering/DrawStream/Draw.cpp b/src/Rendering/DrawStream/Draw.cpp index b93d053..9c8dae6 100644 --- a/src/Rendering/DrawStream/Draw.cpp +++ b/src/Rendering/DrawStream/Draw.cpp @@ -35,7 +35,7 @@ void PrepareDrawDataAndSort(DrawCreateInfo& info, std::vector& game continue; Draw draw; - assert(pass.shader.empty() == false); + // assert(pass.shader.empty() == false); draw.shader = pass.shader; draw.bindGroup[0] = pass.bindGroup[0]; diff --git a/src/Rendering/DrawStream/DrawStream.cpp b/src/Rendering/DrawStream/DrawStream.cpp index 9997a4c..28d81d7 100644 --- a/src/Rendering/DrawStream/DrawStream.cpp +++ b/src/Rendering/DrawStream/DrawStream.cpp @@ -150,7 +150,7 @@ void CreateDrawStreamFromDrawData(const std::vector& drawData, DrawStream& drawStream.data.assign(writer.GetData(), writer.GetData() + writer.GetByteWritten()); } -void ScheduleDrawStream(RenderContext& renderContext, DrawStream& drawStream, vk::CommandBuffer commandBuffer) +void ScheduleDrawStream(RenderContext& renderContext, DrawStream& drawStream, vk::CommandBuffer commandBuffer, GraphicsPipelineHandle overridePipeline) { BitReader reader(drawStream.data.data(), drawStream.data.size()); @@ -170,7 +170,7 @@ void ScheduleDrawStream(RenderContext& renderContext, DrawStream& drawStream, vk if (mask.shader != 0) { - auto shaderHandle = reader.Read(); + auto shaderHandle = overridePipeline.empty() ? reader.Read() : overridePipeline; graphicsPipeline = renderContext.GetGraphicsPipeline(shaderHandle); commandBuffer.bindPipeline(vk::PipelineBindPoint::eGraphics, graphicsPipeline.pipeline); } diff --git a/src/Rendering/DrawStream/DrawStream.h b/src/Rendering/DrawStream/DrawStream.h index 158a318..71f40c7 100644 --- a/src/Rendering/DrawStream/DrawStream.h +++ b/src/Rendering/DrawStream/DrawStream.h @@ -39,5 +39,5 @@ struct DrawStream final }; void CreateDrawStreamFromDrawData(const std::vector& drawData, DrawStream& drawStream); -void ScheduleDrawStream(RenderContext& renderContext, DrawStream& drawStream, vk::CommandBuffer commandBuffer); +void ScheduleDrawStream(RenderContext& renderContext, DrawStream& drawStream, vk::CommandBuffer commandBuffer, GraphicsPipelineHandle overridePipeline = {}); } // namespace gore::renderer \ No newline at end of file diff --git a/src/Rendering/RenderSystem.cpp b/src/Rendering/RenderSystem.cpp index 0390d09..f10d60b 100644 --- a/src/Rendering/RenderSystem.cpp +++ b/src/Rendering/RenderSystem.cpp @@ -431,7 +431,7 @@ void RenderSystem::OnResize(Window* window, int width, int height) CreateDepthBuffer(); } -void RenderSystem::DrawRenderer(DrawKey key, vk::CommandBuffer cmd) +void RenderSystem::DrawRenderer(DrawKey key, vk::CommandBuffer cmd, GraphicsPipelineHandle overridePipeline) { if (m_DrawData.find(key) == m_DrawData.end()) return; @@ -1598,7 +1598,7 @@ void RenderSystem::ShadowmapPassWithRPSWrapper(const RpsCmdCallbackContext* pCon DrawKey key = {"ShadowCaster", AlphaMode::Opaque}; - renderSystem.DrawRenderer(key, cmd); + renderSystem.DrawRenderer(key, cmd, renderSystem.m_RpsPipelines.shadowPipeline); } void RenderSystem::ForwardOpaquePassWithRPSWrapper(const RpsCmdCallbackContext* pContext) @@ -1622,7 +1622,7 @@ void RenderSystem::ForwardOpaquePassWithRPSWrapper(const RpsCmdCallbackContext* DrawKey key = {"ForwardPass", AlphaMode::Opaque}; - renderSystem.DrawRenderer(key, cmd); + renderSystem.DrawRenderer(key, cmd, renderSystem.m_RpsPipelines.forwardPipeline); } } // namespace gore \ No newline at end of file diff --git a/src/Rendering/RenderSystem.h b/src/Rendering/RenderSystem.h index a361694..70c1170 100644 --- a/src/Rendering/RenderSystem.h +++ b/src/Rendering/RenderSystem.h @@ -97,7 +97,7 @@ ENGINE_CLASS(RenderSystem) final : System public: GraphicsCaps GetGraphicsCaps() const { return m_GraphicsCaps; } - void DrawRenderer(DrawKey key, vk::CommandBuffer cmd); + void DrawRenderer(DrawKey key, vk::CommandBuffer cmd, GraphicsPipelineHandle overridePipeline = {}); private: // Imgui From 409b179fcb8d4f245e729817c4867181d441f729 Mon Sep 17 00:00:00 2001 From: Top61ly Date: Mon, 14 Apr 2025 00:23:36 +0800 Subject: [PATCH 12/25] fix: correct scope definition placement for application initialization profiling --- src/Core/App.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Core/App.cpp b/src/Core/App.cpp index 2fb5829..debf952 100644 --- a/src/Core/App.cpp +++ b/src/Core/App.cpp @@ -58,8 +58,8 @@ int App::Run(int width, int height, const char* title) MicroProfileSetEnableAllGroups(true); MicroProfileSetForceMetaCounters(true); - MICROPROFILE_SCOPE(g_AppInitialize); { + MICROPROFILE_SCOPE(g_AppInitialize); glfwInit(); m_Window = new Window(this, width, height); From 1bcfa88773b9568be1558bd164cb820f38f5811a Mon Sep 17 00:00:00 2001 From: Top61ly Date: Tue, 15 Apr 2025 01:01:06 +0800 Subject: [PATCH 13/25] feat: implement shadow mapping support with new shader bindings and rendering adjustments --- sample/App/SampleApp.cpp | 22 +++++++++---------- src/Rendering/RenderSystem.cpp | 19 ++++++++++++++++ src/Rendering/RenderSystem.h | 5 +++++ src/Shaders/ShaderLibrary/GlobalBinding.hlsl | 3 --- .../ShaderLibrary/ShadowPassBinding.hlsl | 5 +++++ src/Shaders/sample/SimpleLit.hlsl | 1 + 6 files changed, 41 insertions(+), 14 deletions(-) create mode 100644 src/Shaders/ShaderLibrary/ShadowPassBinding.hlsl diff --git a/sample/App/SampleApp.cpp b/sample/App/SampleApp.cpp index b573cd7..854795b 100644 --- a/sample/App/SampleApp.cpp +++ b/sample/App/SampleApp.cpp @@ -257,17 +257,17 @@ void SampleApp::Initialize() // PrepareGraphics(); - // Material forwardMat; - // forwardMat.SetAlphaMode(AlphaMode::Opaque); - // forwardMat.AddPass(Pass{ - // .name = "ShadowCaster", - // .shader = pipelines.shadowPipeline, - // .bindGroup = {m_GlobalBindGroup}}); + Material forwardMat; + forwardMat.SetAlphaMode(AlphaMode::Opaque); + forwardMat.AddPass(Pass{ + .name = "ShadowCaster", + /*.shader = pipelines.shadowPipeline, + .bindGroup = {m_GlobalBindGroup}*/}); - // forwardMat.AddPass(Pass{ - // .name = "ForwardPass", - // .shader = pipelines.forwardPipeline, - // .bindGroup = {m_GlobalBindGroup}}); + forwardMat.AddPass(Pass{ + .name = "ForwardPass", + /*.shader = pipelines.forwardPipeline, + .bindGroup = {m_GlobalBindGroup}*/}); gore::gfx::RenderContext& renderContext = m_RenderSystem->GetRenderContext(); @@ -308,7 +308,7 @@ void SampleApp::Initialize() gameObject->SetName("cube"); gore::gfx::MeshRenderer* meshRenderer = gameObject->AddComponent(); meshRenderer->LoadMesh("cube.gltf"); - // meshRenderer->SetMaterial(forwardMat); + meshRenderer->SetMaterial(forwardMat); // meshRenderer->SetDynamicBuffer(m_UnifiedDynamicBufferHandle); // meshRenderer->SetDynamicBufferOffset(0); diff --git a/src/Rendering/RenderSystem.cpp b/src/Rendering/RenderSystem.cpp index f10d60b..626ba86 100644 --- a/src/Rendering/RenderSystem.cpp +++ b/src/Rendering/RenderSystem.cpp @@ -141,6 +141,8 @@ void RenderSystem::Initialize() } }); + CreateDefaultResources(); + CreateDepthBuffer(); CreateTextureObjects(); @@ -148,6 +150,7 @@ void RenderSystem::Initialize() CreateGlobalDescriptorSets(); CreateUVQuadDescriptorSets(); CreateDynamicUniformBuffer(); + CreateRpsPipelines(); CreatePipeline(); GetQueues(); @@ -1156,6 +1159,22 @@ void RenderSystem::CreateGlobalDescriptorSets() }); } +void RenderSystem::CreateShadowPassBindLayout() +{ + std::vector bindings { + {0, BindType::SampledImage, 1, ShaderStage::Fragment}, + {1, BindType::Sampler, 1, ShaderStage::Fragment} + }; + + BindLayoutCreateInfo bindLayoutCreateInfo = + { + .name = "Shadow Pass Descriptor Set Layout", + .bindings = bindings + }; + + m_ShadowPassBindLayout = m_RenderContext->GetOrCreateBindLayout(bindLayoutCreateInfo); +} + void RenderSystem:: CreateUVQuadDescriptorSets() { std::vector bindings { diff --git a/src/Rendering/RenderSystem.h b/src/Rendering/RenderSystem.h index 70c1170..4969b71 100644 --- a/src/Rendering/RenderSystem.h +++ b/src/Rendering/RenderSystem.h @@ -234,6 +234,10 @@ ENGINE_CLASS(RenderSystem) final : System BindGroupHandle m_GlobalBindGroup; BufferHandle m_GlobalConstantBuffer; + // Pass Binding + BindLayout m_ShadowPassBindLayout; + SamplerHandle m_ShadowmapSamplerHandler; + // Material Descriptors BindLayout m_UVQuadBindLayout; BindGroupHandle m_UVQuadBindGroup; @@ -265,6 +269,7 @@ ENGINE_CLASS(RenderSystem) final : System void CreateSwapchain(uint32_t imageCount, uint32_t width, uint32_t height); void CreateDepthBuffer(); void CreateGlobalDescriptorSets(); + void CreateShadowPassBindLayout(); void CreateUVQuadDescriptorSets(); void CreateDynamicUniformBuffer(); void CreatePipeline(); diff --git a/src/Shaders/ShaderLibrary/GlobalBinding.hlsl b/src/Shaders/ShaderLibrary/GlobalBinding.hlsl index 278685f..21fc94b 100644 --- a/src/Shaders/ShaderLibrary/GlobalBinding.hlsl +++ b/src/Shaders/ShaderLibrary/GlobalBinding.hlsl @@ -1,5 +1,2 @@ #include "Core/Common.hlsl" #include "Core/GlobalConstantBuffer.hlsl" - -TEXTURE_2D(GLOBAL, 1, _DirectionalShadowmap, float4); -SAMPLER(GLOBAL, 2, _DirectionalShadowmapSampler); \ No newline at end of file diff --git a/src/Shaders/ShaderLibrary/ShadowPassBinding.hlsl b/src/Shaders/ShaderLibrary/ShadowPassBinding.hlsl new file mode 100644 index 0000000..65579ba --- /dev/null +++ b/src/Shaders/ShaderLibrary/ShadowPassBinding.hlsl @@ -0,0 +1,5 @@ +#pragma once +#include "Core/Common.hlsl" + +TEXTURE_2D(SHADER, 0, _DirectionalShadowmap, float4); +SAMPLER(SHADER, 1, _DirectionalShadowmapSampler); \ No newline at end of file diff --git a/src/Shaders/sample/SimpleLit.hlsl b/src/Shaders/sample/SimpleLit.hlsl index de303c4..58e230c 100644 --- a/src/Shaders/sample/SimpleLit.hlsl +++ b/src/Shaders/sample/SimpleLit.hlsl @@ -1,4 +1,5 @@ #include "../ShaderLibrary/GlobalBinding.hlsl" +#include "../ShaderLibrary/ShadowPassBinding.hlsl" struct Attributes { From 6a14bd02c105753cc431cb2f2ddd61ac4d8a3a39 Mon Sep 17 00:00:00 2001 From: Top61ly Date: Sun, 20 Apr 2025 23:27:53 +0800 Subject: [PATCH 14/25] feat: enhance rendering system with dynamic buffer support and shadow pass integration --- src/Rendering/Components/Material.cpp | 3 +- src/Rendering/Components/Material.h | 5 +- src/Rendering/DrawStream/Draw.cpp | 9 ++-- src/Rendering/DrawStream/Draw.h | 2 +- src/Rendering/RenderSystem.cpp | 66 +++++++++++++++++---------- src/Rendering/RenderSystem.h | 5 ++ 6 files changed, 58 insertions(+), 32 deletions(-) diff --git a/src/Rendering/Components/Material.cpp b/src/Rendering/Components/Material.cpp index 6013c59..8483532 100644 --- a/src/Rendering/Components/Material.cpp +++ b/src/Rendering/Components/Material.cpp @@ -6,7 +6,8 @@ namespace gore::renderer { Material::Material() noexcept : m_Passes(), - m_AlphaMode(AlphaMode::Opaque) + m_AlphaMode(AlphaMode::Opaque), + m_DynamicBuffer() { } diff --git a/src/Rendering/Components/Material.h b/src/Rendering/Components/Material.h index a3e33e1..4ff1e0b 100644 --- a/src/Rendering/Components/Material.h +++ b/src/Rendering/Components/Material.h @@ -5,7 +5,7 @@ #include "Rendering/Pipeline.h" #include "Rendering/BindGroup.h" - +#include "Rendering/DynamicBuffer.h" namespace gore::renderer { using namespace gore::gfx; @@ -69,9 +69,10 @@ ENGINE_CLASS(Material) final } GETTER_SETTER(AlphaMode, AlphaMode) - + GETTER_SETTER(DynamicBufferHandle, DynamicBuffer) private: std::vector m_Passes; + DynamicBufferHandle m_DynamicBuffer; AlphaMode m_AlphaMode; }; } // namespace gore::renderer \ No newline at end of file diff --git a/src/Rendering/DrawStream/Draw.cpp b/src/Rendering/DrawStream/Draw.cpp index 9c8dae6..ca6be68 100644 --- a/src/Rendering/DrawStream/Draw.cpp +++ b/src/Rendering/DrawStream/Draw.cpp @@ -13,7 +13,10 @@ bool MatchDrawFilter(const Pass& pass, const DrawCreateInfo& info) return pass.name == info.passName; } -void PrepareDrawDataAndSort(DrawCreateInfo& info, std::vector& gameObjects, std::vector& sortedDrawData) +void PrepareDrawDataAndSort(DrawCreateInfo& info + , std::vector& gameObjects + , std::vector& sortedDrawData + , Material* overrideMaterial) { auto& renderContext = *RenderContext::GetInstance(); @@ -26,9 +29,9 @@ void PrepareDrawDataAndSort(DrawCreateInfo& info, std::vector& game if (renderer->IsValid() == false) continue; - auto handle = renderer->GetDynamicBuffer(); + auto handle = overrideMaterial? overrideMaterial->GetDynamicBuffer() : renderer->GetDynamicBuffer(); - Material& material = renderer->GetMaterial(); + Material& material = overrideMaterial ? *overrideMaterial : renderer->GetMaterial(); for (const auto& pass : material.GetPasses()) { if (MatchDrawFilter(pass, info) == false) diff --git a/src/Rendering/DrawStream/Draw.h b/src/Rendering/DrawStream/Draw.h index 5c2aecc..f97b1bd 100644 --- a/src/Rendering/DrawStream/Draw.h +++ b/src/Rendering/DrawStream/Draw.h @@ -115,7 +115,7 @@ struct DrawSorter } }; -void PrepareDrawDataAndSort(DrawCreateInfo& info, std::vector& gameObjects, std::vector& sortedDrawData); +void PrepareDrawDataAndSort(DrawCreateInfo& info, std::vector& gameObjects, std::vector& sortedDrawData, Material* overrideMaterial = nullptr); bool MatchDrawFilter(const Pass& pass, const DrawCreateInfo& info); void ScheduleDraws(RenderContext& renderContext, const std::unordered_map>& drawData, const DrawKey& key, vk::CommandBuffer commandBuffer); } // namespace gore::renderer diff --git a/src/Rendering/RenderSystem.cpp b/src/Rendering/RenderSystem.cpp index 626ba86..4de7742 100644 --- a/src/Rendering/RenderSystem.cpp +++ b/src/Rendering/RenderSystem.cpp @@ -148,6 +148,7 @@ void RenderSystem::Initialize() CreateTextureObjects(); CreateGlobalDescriptorSets(); + CreateShadowPassBindLayout(); CreateUVQuadDescriptorSets(); CreateDynamicUniformBuffer(); CreateRpsPipelines(); @@ -157,14 +158,14 @@ void RenderSystem::Initialize() InitImgui(); } -static void PrepareDrawStreamByDrawInfo(std::unordered_map& map, DrawCreateInfo info, std::vector& gameObjects) +static void PrepareDrawStreamByDrawInfo(std::unordered_map& map, DrawCreateInfo info, std::vector& gameObjects, Material* overrideMaterial) { DrawKey key = {}; key.passName = info.passName; key.alphaMode = info.alphaMode; std::vector sortedDrawData; - PrepareDrawDataAndSort(info, gameObjects, sortedDrawData); + PrepareDrawDataAndSort(info, gameObjects, sortedDrawData, overrideMaterial); DrawStream drawStream; CreateDrawStreamFromDrawData(sortedDrawData, drawStream); @@ -187,8 +188,8 @@ void RenderSystem::PrepareDrawData() std::vector gameObjects = Scene::GetActiveScene()->GetGameObjects(); m_DrawData.clear(); - PrepareDrawStreamByDrawInfo(m_DrawData, info, gameObjects); - PrepareDrawStreamByDrawInfo(m_DrawData, shadowInfo, gameObjects); + PrepareDrawStreamByDrawInfo(m_DrawData, info, gameObjects, &m_RpsMaterial.forward); + PrepareDrawStreamByDrawInfo(m_DrawData, shadowInfo, gameObjects, &m_RpsMaterial.forward); } void RenderSystem::Update() @@ -1128,6 +1129,22 @@ void RenderSystem::CreateDepthBuffer() m_Device.SetName(m_DepthImageView, "Depth Buffer ImageView"); } +void RenderSystem::CreateShadowPassBindLayout() +{ + std::vector bindings{ + {0, BindType::SampledImage, 1, ShaderStage::Fragment}, + {1, BindType::Sampler, 1, ShaderStage::Fragment} + }; + + BindLayoutCreateInfo bindLayoutCreateInfo = + { + .name = "Shadow Pass Descriptor Set Layout", + .bindings = bindings + }; + + m_ShadowPassBindLayout = m_RenderContext->GetOrCreateBindLayout(bindLayoutCreateInfo); +} + void RenderSystem::CreateGlobalDescriptorSets() { m_GlobalConstantBuffer = m_RenderContext->CreateBuffer({ @@ -1138,7 +1155,7 @@ void RenderSystem::CreateGlobalDescriptorSets() }); std::vector bindings { - {0, BindType::UniformBuffer, 1, ShaderStage::Vertex} + {0, BindType::UniformBuffer, 1, ShaderStage::Vertex | ShaderStage::Fragment} }; BindLayoutCreateInfo bindLayoutCreateInfo = @@ -1159,22 +1176,6 @@ void RenderSystem::CreateGlobalDescriptorSets() }); } -void RenderSystem::CreateShadowPassBindLayout() -{ - std::vector bindings { - {0, BindType::SampledImage, 1, ShaderStage::Fragment}, - {1, BindType::Sampler, 1, ShaderStage::Fragment} - }; - - BindLayoutCreateInfo bindLayoutCreateInfo = - { - .name = "Shadow Pass Descriptor Set Layout", - .bindings = bindings - }; - - m_ShadowPassBindLayout = m_RenderContext->GetOrCreateBindLayout(bindLayoutCreateInfo); -} - void RenderSystem:: CreateUVQuadDescriptorSets() { std::vector bindings { @@ -1201,7 +1202,7 @@ void RenderSystem:: CreateUVQuadDescriptorSets() struct PerDrawData { - Matrix4x4 modelMatrix; + Matrix4x4 modelMatrix[128]; }; void RenderSystem::CreateDynamicUniformBuffer() @@ -1214,7 +1215,7 @@ void RenderSystem::CreateDynamicUniformBuffer() for (size_t i = 0; i < renderCount; ++i) { PerDrawData* perDrawData = reinterpret_cast(dynamicUniformBufferData.data() + (i * alignmentSize)); - perDrawData->modelMatrix = Matrix4x4(1.f, 0.f, 0.f, 0.f, 0.f, 1.f, 0.f, 0.f, 0.f, 0.f, 1.f, 0.f, i, 0.f, 0.f, 1.f); + perDrawData->modelMatrix[0] = Matrix4x4(1.f, 0.f, 0.f, 0.f, 0.f, 1.f, 0.f, 0.f, 0.f, 0.f, 1.f, 0.f, i, 0.f, 0.f, 1.f); } m_DynamicUniformBuffer = m_RenderContext->CreateBuffer( @@ -1542,7 +1543,7 @@ void RenderSystem::CreateRpsPipelines() {.byteOffset = 0, .format = GraphicsFormat::RGB32_FLOAT}, {.byteOffset = 12, .format = GraphicsFormat::RG32_FLOAT}, {.byteOffset = 20, .format = GraphicsFormat::RGB32_FLOAT}}}}, - .bindLayouts = { m_GlobalBindLayout }, + .bindLayouts = { m_GlobalBindLayout, m_ShadowPassBindLayout }, .dynamicBuffer = m_DynamicBufferHandle, .renderPass = forwardPass.GetRenderPass().renderPass, .subpassIndex = 0 @@ -1582,6 +1583,21 @@ void RenderSystem::CreateRpsPipelines() .subpassIndex = 0 } }); + + Material& forwardMat = m_RpsMaterial.forward; + forwardMat.SetAlphaMode(AlphaMode::Opaque); + forwardMat.SetDynamicBuffer(m_DynamicBufferHandle); + forwardMat.AddPass(Pass{ + .name = "ShadowCaster", + .shader = m_RpsPipelines.shadowPipeline, + .bindGroup = {m_GlobalBindGroup}, + }); + + forwardMat.AddPass(Pass{ + .name = "ForwardPass", + .shader = m_RpsPipelines.forwardPipeline, + .bindGroup = {m_GlobalBindGroup}, + }); } void RenderSystem::CreateDefaultResources() @@ -1622,6 +1638,7 @@ void RenderSystem::ShadowmapPassWithRPSWrapper(const RpsCmdCallbackContext* pCon void RenderSystem::ForwardOpaquePassWithRPSWrapper(const RpsCmdCallbackContext* pContext) { + return; RenderSystem& renderSystem = *reinterpret_cast(pContext->pUserRecordContext); vk::CommandBuffer cmd = rpsVKCommandBufferFromHandle(pContext->hCommandBuffer); @@ -1643,5 +1660,4 @@ void RenderSystem::ForwardOpaquePassWithRPSWrapper(const RpsCmdCallbackContext* renderSystem.DrawRenderer(key, cmd, renderSystem.m_RpsPipelines.forwardPipeline); } - } // namespace gore \ No newline at end of file diff --git a/src/Rendering/RenderSystem.h b/src/Rendering/RenderSystem.h index 4969b71..12995ae 100644 --- a/src/Rendering/RenderSystem.h +++ b/src/Rendering/RenderSystem.h @@ -187,6 +187,11 @@ ENGINE_CLASS(RenderSystem) final : System GraphicsPipelineHandle shadowPipeline; } m_RpsPipelines; + struct RPSMaterial + { + Material forward; + } m_RpsMaterial; + void CreateRpsPipelines(); struct DefaultResources From ddb0e1926b99aa5447dd1d430108f6bca3a2820c Mon Sep 17 00:00:00 2001 From: Top61ly Date: Mon, 21 Apr 2025 22:09:39 +0800 Subject: [PATCH 15/25] feat: introduce TransientBindGroupUpdateDesc structure and update binding method signature --- src/Rendering/RenderContext.cpp | 2 +- src/Rendering/RenderContext.h | 4 ++-- ...UpdateDesc.h => TransientBindGroupUpdateDesc.h} | 14 +++++++------- 3 files changed, 10 insertions(+), 10 deletions(-) rename src/Rendering/{RawBindGroupUpdateDesc.h => TransientBindGroupUpdateDesc.h} (66%) diff --git a/src/Rendering/RenderContext.cpp b/src/Rendering/RenderContext.cpp index ada7519..8620b0b 100644 --- a/src/Rendering/RenderContext.cpp +++ b/src/Rendering/RenderContext.cpp @@ -1128,7 +1128,7 @@ void RenderContext::DestroyRenderPass(RenderPass& renderPass) VULKAN_DEVICE.destroyRenderPass(renderPass.renderPass); } -void RenderContext::UpdateBindGroup(BindGroupHandle handle, const RawBindGroupUpdateDesc& desc) +void RenderContext::UpdateBindGroup(BindGroupHandle handle, const TransientBindGroupUpdateDesc& desc) { const int updateCount = static_cast(desc.buffers.size() + desc.textures.size() + desc.samplers.size()); diff --git a/src/Rendering/RenderContext.h b/src/Rendering/RenderContext.h index f258953..255e5b6 100644 --- a/src/Rendering/RenderContext.h +++ b/src/Rendering/RenderContext.h @@ -27,7 +27,7 @@ #include "DescriptorPoolHolder.h" #include "Pool.h" -#include "RawBindGroupUpdateDesc.h" +#include "TransientBindGroupUpdateDesc.h" #include @@ -130,7 +130,7 @@ ENGINE_CLASS(RenderContext) final const BindGroupDesc& GetBindGroupDesc(BindGroupHandle handle); // BindGroup Update for RPSL - void UpdateBindGroup(BindGroupHandle handle, const RawBindGroupUpdateDesc& desc); + void UpdateBindGroup(BindGroupHandle handle, const TransientBindGroupUpdateDesc& desc); DynamicBufferHandle CreateDynamicBuffer(DynamicBufferDesc&& desc); const DynamicBufferDesc& GetDynamicBufferDesc(DynamicBufferHandle handle); diff --git a/src/Rendering/RawBindGroupUpdateDesc.h b/src/Rendering/TransientBindGroupUpdateDesc.h similarity index 66% rename from src/Rendering/RawBindGroupUpdateDesc.h rename to src/Rendering/TransientBindGroupUpdateDesc.h index 730ac8e..8990553 100644 --- a/src/Rendering/RawBindGroupUpdateDesc.h +++ b/src/Rendering/TransientBindGroupUpdateDesc.h @@ -7,7 +7,7 @@ namespace gore::gfx { -struct RawTextureBinding final +struct TransientTextureBinding final { uint32_t binding = 0; vk::ImageView imageView = {}; @@ -15,7 +15,7 @@ struct RawTextureBinding final vk::Sampler sampler = {}; }; -struct RawBufferBinding final +struct TransientBufferBinding final { uint32_t binding = 0; vk::Buffer buffer = {}; @@ -24,18 +24,18 @@ struct RawBufferBinding final BindType bindType = BindType::UniformBuffer; }; -struct RawSamplerBinding final +struct TransientSamplerBinding final { uint32_t binding = 0; vk::Sampler sampler = {}; BindType bindType = BindType::Sampler; }; -struct RawBindGroupUpdateDesc final +struct TransientBindGroupUpdateDesc final { - std::vector textures; - std::vector buffers; - std::vector samplers; + std::vector textures; + std::vector buffers; + std::vector samplers; }; } // namespace gore::gfx \ No newline at end of file From 39d2fbcfdb5ed33bfab2f28e862e36ad9444fa9d Mon Sep 17 00:00:00 2001 From: Top61ly Date: Thu, 24 Apr 2025 00:08:01 +0800 Subject: [PATCH 16/25] refactor: rename CreateShadowPassBindLayout to CreateShadowPassObject for clarity --- src/Rendering/RenderSystem.cpp | 18 +++++++++++------- src/Rendering/RenderSystem.h | 2 +- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/src/Rendering/RenderSystem.cpp b/src/Rendering/RenderSystem.cpp index 4de7742..d098c25 100644 --- a/src/Rendering/RenderSystem.cpp +++ b/src/Rendering/RenderSystem.cpp @@ -148,7 +148,7 @@ void RenderSystem::Initialize() CreateTextureObjects(); CreateGlobalDescriptorSets(); - CreateShadowPassBindLayout(); + CreateShadowPassObject(); CreateUVQuadDescriptorSets(); CreateDynamicUniformBuffer(); CreateRpsPipelines(); @@ -1129,7 +1129,7 @@ void RenderSystem::CreateDepthBuffer() m_Device.SetName(m_DepthImageView, "Depth Buffer ImageView"); } -void RenderSystem::CreateShadowPassBindLayout() +void RenderSystem::CreateShadowPassObject() { std::vector bindings{ {0, BindType::SampledImage, 1, ShaderStage::Fragment}, @@ -1143,6 +1143,10 @@ void RenderSystem::CreateShadowPassBindLayout() }; m_ShadowPassBindLayout = m_RenderContext->GetOrCreateBindLayout(bindLayoutCreateInfo); + + m_ShadowmapSamplerHandler = m_RenderContext->CreateSampler({ + .debugName = "Shadowmap Sampler" + }); } void RenderSystem::CreateGlobalDescriptorSets() @@ -1643,10 +1647,10 @@ void RenderSystem::ForwardOpaquePassWithRPSWrapper(const RpsCmdCallbackContext* vk::CommandBuffer cmd = rpsVKCommandBufferFromHandle(pContext->hCommandBuffer); // Update ShadowMap Descriptor Set - // VkImageView shadowmapView; - // RpsResult result = rpsVKGetCmdArgImageView(pContext, 0, &shadowmapView); - // if (RPS_SUCCEEDED(result) == true) - // { + VkImageView shadowmapView; + RpsResult result = rpsVKGetCmdArgImageView(pContext, 0, &shadowmapView); + if (RPS_SUCCEEDED(result) == true) + { // // SampleApp* app = dynamic_cast(App::Get()); // RawBindGroupUpdateDesc updateDesc = { @@ -1654,7 +1658,7 @@ void RenderSystem::ForwardOpaquePassWithRPSWrapper(const RpsCmdCallbackContext* // }; // renderSystem.GetRenderContext().UpdateBindGroup(app->m_GlobalBindGroup, updateDesc); - // } + } DrawKey key = {"ForwardPass", AlphaMode::Opaque}; diff --git a/src/Rendering/RenderSystem.h b/src/Rendering/RenderSystem.h index 12995ae..797f127 100644 --- a/src/Rendering/RenderSystem.h +++ b/src/Rendering/RenderSystem.h @@ -274,7 +274,7 @@ ENGINE_CLASS(RenderSystem) final : System void CreateSwapchain(uint32_t imageCount, uint32_t width, uint32_t height); void CreateDepthBuffer(); void CreateGlobalDescriptorSets(); - void CreateShadowPassBindLayout(); + void CreateShadowPassObject(); void CreateUVQuadDescriptorSets(); void CreateDynamicUniformBuffer(); void CreatePipeline(); From 93297bc72c8366072aee93575ec68eb2ae2bea0b Mon Sep 17 00:00:00 2001 From: Top61ly Date: Sat, 26 Apr 2025 23:03:07 +0800 Subject: [PATCH 17/25] feat: add BindGroupUpdateDesc structure for improved binding management --- src/Rendering/BindGroup.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/Rendering/BindGroup.h b/src/Rendering/BindGroup.h index 23e3b00..b5f9ea2 100644 --- a/src/Rendering/BindGroup.h +++ b/src/Rendering/BindGroup.h @@ -52,6 +52,13 @@ struct SamplerBinding final BindType bindType = BindType::Sampler; }; +struct BindGroupUpdateDesc final +{ + std::vector textures = {}; + std::vector buffers = {}; + std::vector samplers = {}; +}; + struct BindGroupDesc final { const char* debugName = nullptr; From 8246fbf90e6ad5f88fc7fde162eeb687d99fe131 Mon Sep 17 00:00:00 2001 From: Top61ly Date: Sat, 26 Apr 2025 23:03:17 +0800 Subject: [PATCH 18/25] refactor: update TransientTextureBinding and TransientBufferBinding to use Vulkan descriptor types --- src/Rendering/TransientBindGroupUpdateDesc.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Rendering/TransientBindGroupUpdateDesc.h b/src/Rendering/TransientBindGroupUpdateDesc.h index 8990553..1cbe297 100644 --- a/src/Rendering/TransientBindGroupUpdateDesc.h +++ b/src/Rendering/TransientBindGroupUpdateDesc.h @@ -11,7 +11,8 @@ struct TransientTextureBinding final { uint32_t binding = 0; vk::ImageView imageView = {}; - BindType bindType = BindType::SampledImage; + vk::ImageLayout imageLayout = vk::ImageLayout::eShaderReadOnlyOptimal; + vk::DescriptorType descriptorType = vk::DescriptorType::eSampledImage; vk::Sampler sampler = {}; }; @@ -19,9 +20,9 @@ struct TransientBufferBinding final { uint32_t binding = 0; vk::Buffer buffer = {}; + vk::DescriptorType descriptorType = vk::DescriptorType::eUniformBuffer; uint32_t offset = 0; uint32_t range = 0; - BindType bindType = BindType::UniformBuffer; }; struct TransientSamplerBinding final From 51f293f20939957e31309596104d70d2305a42e8 Mon Sep 17 00:00:00 2001 From: Top61ly Date: Sat, 26 Apr 2025 23:03:52 +0800 Subject: [PATCH 19/25] feat: implement UpdateBindGroup method for enhanced binding updates --- src/Rendering/RenderContext.cpp | 227 ++++++++++++++++++++++---------- src/Rendering/RenderContext.h | 12 +- 2 files changed, 166 insertions(+), 73 deletions(-) diff --git a/src/Rendering/RenderContext.cpp b/src/Rendering/RenderContext.cpp index 8620b0b..c004816 100644 --- a/src/Rendering/RenderContext.cpp +++ b/src/Rendering/RenderContext.cpp @@ -820,6 +820,161 @@ PipelineLayout RenderContext::GetOrCreatePipelineLayout(const std::vector descriptorImageInfos; + descriptorImageInfos.reserve(c_MaxBindingsPerLayout); + + std::vector descriptorBufferInfos; + descriptorBufferInfos.reserve(c_MaxBindingsPerLayout); + + std::vector writeDescriptorSets; + writeDescriptorSets.reserve(c_MaxBindingsPerLayout); + + auto generateWriteDescriptorData = + [&](uint32_t binding + , vk::DescriptorType descriptorType + , vk::DescriptorImageInfo* imageInfo + , vk::DescriptorBufferInfo* bufferInfo + , vk::BufferView* texelBufferView + , const void* pNext = nullptr) + { + writeDescriptorSets.push_back( + vk::WriteDescriptorSet() + .setDstSet(descirptorSet) + .setDstBinding(binding) + .setDstArrayElement(0) + .setDescriptorCount(1) + .setDescriptorType(descriptorType) + .setPImageInfo(imageInfo) + .setPBufferInfo(bufferInfo) + .setPTexelBufferView(texelBufferView) + .setPNext(pNext)); + }; + + // update persistent bindgroup update + for (const auto& textureBinding : bindGroupDesc.textures) + { + TextureHandle handle = textureBinding.handle; + + const TextureDesc& textureDesc = GetTextureDesc(handle); + const Texture& textureInfo = GetTexture(handle); + + vk::ImageView imageView = VK_NULL_HANDLE; + + if (HasFlag(textureBinding.usage, TextureUsageBits::Sampled)) + { + imageView = textureInfo.srv; + } + + if (HasFlag(textureBinding.usage, TextureUsageBits::Storage)) + { + imageView = textureInfo.uav[0]; + } + + vk::DescriptorImageInfo imageInfo; + imageInfo.imageLayout = vk::ImageLayout::eShaderReadOnlyOptimal; + imageInfo.imageView = imageView; + imageInfo.sampler = textureBinding.bindType == BindType::CombinedSampledImage ? GetSampler(textureBinding.samplerHandle).vkSampler : VK_NULL_HANDLE; + + descriptorImageInfos.push_back(imageInfo); + + generateWriteDescriptorData( + textureBinding.binding, + VulkanHelper::GetVkDescriptorType(textureBinding.bindType), + &descriptorImageInfos.back(), + nullptr, + nullptr); + } + for (const auto& bufferBinding : bindGroupDesc.buffers) + { + const BufferDesc& bufferDesc = GetBufferDesc(bufferBinding.handle); + const Buffer& bufferInfo = GetBuffer(bufferBinding.handle); + + descriptorBufferInfos.push_back({GetBuffer(bufferBinding.handle).vkBuffer, + bufferBinding.offset, + bufferBinding.range == 0 ? bufferDesc.byteSize : bufferBinding.range}); + + generateWriteDescriptorData( + bufferBinding.binding, + VulkanHelper::GetVkDescriptorType(bufferBinding.bindType), + nullptr, + &descriptorBufferInfos.back(), + nullptr); + } + for (const auto& samplerBinding : bindGroupDesc.samplers) + { + SamplerHandle handle = samplerBinding.handle; + + const SamplerDesc& samplerDesc = GetSamplerDesc(handle); + const Sampler& samplerInfo = GetSampler(handle); + + vk::DescriptorImageInfo imageInfo; + imageInfo.sampler = samplerInfo.vkSampler; + + descriptorImageInfos.push_back(imageInfo); + + generateWriteDescriptorData( + samplerBinding.binding, + VulkanHelper::GetVkDescriptorType(samplerBinding.bindType), + &descriptorImageInfos.back(), + nullptr, + nullptr); + } + // update transient bindgroup update + for (const auto& textureBinding : transientDesc.textures) + { + vk::DescriptorImageInfo imageInfo; + imageInfo.imageLayout = textureBinding.imageLayout; + imageInfo.imageView = textureBinding.imageView; + + descriptorImageInfos.push_back(imageInfo); + + generateWriteDescriptorData( + textureBinding.binding, + textureBinding.descriptorType, + &descriptorImageInfos.back(), + nullptr, + nullptr); + } + + for (const auto& bufferBinding : transientDesc.buffers) + { + descriptorBufferInfos.push_back({bufferBinding.buffer, + bufferBinding.offset, + bufferBinding.range}); + + generateWriteDescriptorData( + bufferBinding.binding, + bufferBinding.descriptorType, + nullptr, + &descriptorBufferInfos.back(), + nullptr); + } + + for (const auto& samplerBinding : transientDesc.samplers) + { + vk::DescriptorImageInfo imageInfo; + imageInfo.sampler = samplerBinding.sampler; + + descriptorImageInfos.push_back(imageInfo); + + generateWriteDescriptorData( + samplerBinding.binding, + vk::DescriptorType::eSampler, + &descriptorImageInfos.back(), + nullptr, + nullptr); + } + + VULKAN_DEVICE.updateDescriptorSets(writeDescriptorSets, {}); +} + DynamicBufferHandle RenderContext::CreateDynamicBuffer(DynamicBufferDesc&& desc) { std::vector bindings = { @@ -1127,76 +1282,4 @@ void RenderContext::DestroyRenderPass(RenderPass& renderPass) { VULKAN_DEVICE.destroyRenderPass(renderPass.renderPass); } - -void RenderContext::UpdateBindGroup(BindGroupHandle handle, const TransientBindGroupUpdateDesc& desc) -{ - const int updateCount = static_cast(desc.buffers.size() + desc.textures.size() + desc.samplers.size()); - - std::vector writeDescriptorSets; - writeDescriptorSets.reserve(updateCount); - - vk::DescriptorSet descriptorSet = m_BindGroupPool.getObject(handle).set; - - for (const auto& rawBuffer : desc.buffers) - { - vk::Buffer vkBuffer = rawBuffer.buffer; - - vk::DescriptorBufferInfo bufferInfoDesc = { - vkBuffer, - rawBuffer.offset, - rawBuffer.range == 0 ? VK_WHOLE_SIZE : rawBuffer.range}; - - vk::WriteDescriptorSet writeDescriptorSet( - descriptorSet, - rawBuffer.binding, - 0, - 1, - VulkanHelper::GetVkDescriptorType(rawBuffer.bindType), - nullptr, - &bufferInfoDesc, - nullptr); - writeDescriptorSets.push_back(writeDescriptorSet); - } - - for (const auto& rawTexture : desc.textures) - { - vk::DescriptorImageInfo imageInfo; - imageInfo.imageLayout = vk::ImageLayout::eShaderReadOnlyOptimal; - imageInfo.imageView = rawTexture.imageView; - imageInfo.sampler = rawTexture.bindType == BindType::CombinedSampledImage ? rawTexture.sampler : VK_NULL_HANDLE; - - vk::WriteDescriptorSet writeDescriptorSet( - descriptorSet, - rawTexture.binding, - 0, - 1, - VulkanHelper::GetVkDescriptorType(rawTexture.bindType), - &imageInfo, - nullptr, - nullptr); - - writeDescriptorSets.push_back(writeDescriptorSet); - } - - for (const auto& rawSampler : desc.samplers) - { - vk::DescriptorImageInfo imageInfo; - imageInfo.sampler = rawSampler.sampler; - - vk::WriteDescriptorSet writeDescriptorSet( - descriptorSet, - rawSampler.binding, - 0, - 1, - VulkanHelper::GetVkDescriptorType(rawSampler.bindType), - &imageInfo, - nullptr, - nullptr); - - writeDescriptorSets.push_back(writeDescriptorSet); - } - - VULKAN_DEVICE.updateDescriptorSets(writeDescriptorSets, {}); -} - } // namespace gore::gfx \ No newline at end of file diff --git a/src/Rendering/RenderContext.h b/src/Rendering/RenderContext.h index 255e5b6..1c946c1 100644 --- a/src/Rendering/RenderContext.h +++ b/src/Rendering/RenderContext.h @@ -35,6 +35,16 @@ namespace gore::gfx { using namespace gore::renderer; +static constexpr uint32_t c_MaxRenderTargets = 8; +static constexpr uint32_t c_MaxViewports = 16; +static constexpr uint32_t c_MaxVertexAttributes = 16; +static constexpr uint32_t c_MaxBindingLayouts = 5; +static constexpr uint32_t c_MaxBindingsPerLayout = 128; +static constexpr uint32_t c_MaxVolatileConstantBuffersPerLayout = 6; +static constexpr uint32_t c_MaxVolatileConstantBuffers = 32; +static constexpr uint32_t c_MaxPushConstantSize = 128; +static constexpr uint32_t c_ConstantBufferOffsetSizeAlignment = 256; // Partially bound constant buffers must have offsets aligned to this and sizes multiple of this + enum PSOCreateRuntimeFlagBits { PSO_CREATE_FLAG_NONE = 0, @@ -130,7 +140,7 @@ ENGINE_CLASS(RenderContext) final const BindGroupDesc& GetBindGroupDesc(BindGroupHandle handle); // BindGroup Update for RPSL - void UpdateBindGroup(BindGroupHandle handle, const TransientBindGroupUpdateDesc& desc); + void UpdateBindGroup(BindGroupHandle handle, BindGroupUpdateDesc&& desc, TransientBindGroupUpdateDesc&& transientDesc); DynamicBufferHandle CreateDynamicBuffer(DynamicBufferDesc&& desc); const DynamicBufferDesc& GetDynamicBufferDesc(DynamicBufferHandle handle); From 408d95b7b64f79aa346e0135ebbde1fe4ca8b93a Mon Sep 17 00:00:00 2001 From: Top61ly Date: Sat, 26 Apr 2025 23:04:36 +0800 Subject: [PATCH 20/25] fix: correct typo in UpdateBindGroup method for descriptorSet variable --- src/Rendering/RenderContext.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Rendering/RenderContext.cpp b/src/Rendering/RenderContext.cpp index c004816..df80861 100644 --- a/src/Rendering/RenderContext.cpp +++ b/src/Rendering/RenderContext.cpp @@ -825,7 +825,7 @@ void RenderContext::UpdateBindGroup(BindGroupHandle handle , BindGroupUpdateDesc&& bindGroupDesc , TransientBindGroupUpdateDesc&& transientDesc) { - auto descirptorSet = GetBindGroup(handle).set; + auto descriptorSet = GetBindGroup(handle).set; std::vector descriptorImageInfos; descriptorImageInfos.reserve(c_MaxBindingsPerLayout); @@ -846,7 +846,7 @@ void RenderContext::UpdateBindGroup(BindGroupHandle handle { writeDescriptorSets.push_back( vk::WriteDescriptorSet() - .setDstSet(descirptorSet) + .setDstSet(descriptorSet) .setDstBinding(binding) .setDstArrayElement(0) .setDescriptorCount(1) From c7df500494d63c2e0544f22a46df444a91fe58dc Mon Sep 17 00:00:00 2001 From: Top61ly Date: Mon, 28 Apr 2025 00:02:14 +0800 Subject: [PATCH 21/25] feat: add CreateTransientBindGroup method and update BindGroup handling for improved resource management --- src/Rendering/RenderContext.cpp | 21 ++++++++++++++++++ src/Rendering/RenderContext.h | 3 +++ src/Rendering/RenderSystem.cpp | 23 ++++++++++++++------ src/Rendering/TransientBindGroupUpdateDesc.h | 5 +++++ 4 files changed, 45 insertions(+), 7 deletions(-) diff --git a/src/Rendering/RenderContext.cpp b/src/Rendering/RenderContext.cpp index df80861..645d28f 100644 --- a/src/Rendering/RenderContext.cpp +++ b/src/Rendering/RenderContext.cpp @@ -769,6 +769,18 @@ const BindGroupDesc& RenderContext::GetBindGroupDesc(BindGroupHandle handle) return m_BindGroupPool.getObjectDesc(handle); } +TransientBindGroup RenderContext::CreateTransientBindGroup(BindGroupDesc&& desc) +{ + vk::DescriptorSetLayout setLayout = desc.bindLayout->layout; + vk::DescriptorPool pool = m_DescriptorPool[(uint32_t)desc.updateFrequency]; + + vk::DescriptorSet descriptorSet = VULKAN_DEVICE.allocateDescriptorSets({pool, 1, &setLayout})[0]; + + SetObjectDebugName(descriptorSet, desc.debugName); + + return TransientBindGroup{descriptorSet}; +} + void RenderContext::PrepareRendering() { CreateDescriptorPools(); @@ -827,6 +839,15 @@ void RenderContext::UpdateBindGroup(BindGroupHandle handle { auto descriptorSet = GetBindGroup(handle).set; + TransientBindGroup bindGroup = TransientBindGroup{descriptorSet}; + + UpdateBindGroup(bindGroup, std::move(bindGroupDesc), std::move(transientDesc)); +} + +void RenderContext::UpdateBindGroup(TransientBindGroup& bindGroup, BindGroupUpdateDesc&& bindGroupDesc, TransientBindGroupUpdateDesc&& transientDesc) +{ + auto descriptorSet = bindGroup.descriptorSet; + std::vector descriptorImageInfos; descriptorImageInfos.reserve(c_MaxBindingsPerLayout); diff --git a/src/Rendering/RenderContext.h b/src/Rendering/RenderContext.h index 1c946c1..ceb048c 100644 --- a/src/Rendering/RenderContext.h +++ b/src/Rendering/RenderContext.h @@ -139,7 +139,10 @@ ENGINE_CLASS(RenderContext) final const BindGroup& GetBindGroup(BindGroupHandle handle); const BindGroupDesc& GetBindGroupDesc(BindGroupHandle handle); + TransientBindGroup CreateTransientBindGroup(BindGroupDesc&& desc); + // BindGroup Update for RPSL + void UpdateBindGroup(TransientBindGroup& bindGroup, BindGroupUpdateDesc&& desc, TransientBindGroupUpdateDesc&& transientDesc); void UpdateBindGroup(BindGroupHandle handle, BindGroupUpdateDesc&& desc, TransientBindGroupUpdateDesc&& transientDesc); DynamicBufferHandle CreateDynamicBuffer(DynamicBufferDesc&& desc); diff --git a/src/Rendering/RenderSystem.cpp b/src/Rendering/RenderSystem.cpp index d098c25..a4b317d 100644 --- a/src/Rendering/RenderSystem.cpp +++ b/src/Rendering/RenderSystem.cpp @@ -1642,7 +1642,6 @@ void RenderSystem::ShadowmapPassWithRPSWrapper(const RpsCmdCallbackContext* pCon void RenderSystem::ForwardOpaquePassWithRPSWrapper(const RpsCmdCallbackContext* pContext) { - return; RenderSystem& renderSystem = *reinterpret_cast(pContext->pUserRecordContext); vk::CommandBuffer cmd = rpsVKCommandBufferFromHandle(pContext->hCommandBuffer); @@ -1650,14 +1649,24 @@ void RenderSystem::ForwardOpaquePassWithRPSWrapper(const RpsCmdCallbackContext* VkImageView shadowmapView; RpsResult result = rpsVKGetCmdArgImageView(pContext, 0, &shadowmapView); if (RPS_SUCCEEDED(result) == true) - { - // // SampleApp* app = dynamic_cast(App::Get()); + { + auto& renderContext = renderSystem.m_RenderContext; + + auto shadowmapBindGroup = renderContext->CreateTransientBindGroup({ + .debugName = "Shadowmap BindGroup", + .updateFrequency = UpdateFrequency::PerFrame, + .bindLayout = &renderSystem.m_ShadowPassBindLayout, + }); - // RawBindGroupUpdateDesc updateDesc = { - // .textures = {{1, shadowmapView, BindType::SampledImage}}, - // }; - // renderSystem.GetRenderContext().UpdateBindGroup(app->m_GlobalBindGroup, updateDesc); + renderContext->UpdateBindGroup(shadowmapBindGroup, + { + .samplers = {{1, renderSystem.m_ShadowmapSamplerHandler}}, + }, + { + .textures = {{0, shadowmapView}}, + } + ); } DrawKey key = {"ForwardPass", AlphaMode::Opaque}; diff --git a/src/Rendering/TransientBindGroupUpdateDesc.h b/src/Rendering/TransientBindGroupUpdateDesc.h index 1cbe297..a8a8ba9 100644 --- a/src/Rendering/TransientBindGroupUpdateDesc.h +++ b/src/Rendering/TransientBindGroupUpdateDesc.h @@ -7,6 +7,11 @@ namespace gore::gfx { +struct TransientBindGroup +{ + vk::DescriptorSet descriptorSet = {}; +}; + struct TransientTextureBinding final { uint32_t binding = 0; From 1b5957f7517a1549dab3cf51c37e09a49e0178e7 Mon Sep 17 00:00:00 2001 From: Top61ly Date: Mon, 28 Apr 2025 22:08:07 +0800 Subject: [PATCH 22/25] fix: update UpdateFrequency from None to Persistent in BindGroup and RenderContext for consistency --- src/Rendering/BindGroup.h | 4 ++-- src/Rendering/RenderContext.cpp | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Rendering/BindGroup.h b/src/Rendering/BindGroup.h index b5f9ea2..0a8d83a 100644 --- a/src/Rendering/BindGroup.h +++ b/src/Rendering/BindGroup.h @@ -14,7 +14,7 @@ namespace gore::gfx enum class UpdateFrequency : uint8_t { - None, + Persistent, PerFrame, PerBatch, // We should never use this, but it's here for completeness @@ -62,7 +62,7 @@ struct BindGroupUpdateDesc final struct BindGroupDesc final { const char* debugName = nullptr; - UpdateFrequency updateFrequency = UpdateFrequency::None; + UpdateFrequency updateFrequency = UpdateFrequency::Persistent; std::vector textures = {}; std::vector buffers = {}; std::vector samplers = {}; diff --git a/src/Rendering/RenderContext.cpp b/src/Rendering/RenderContext.cpp index 645d28f..d6c991d 100644 --- a/src/Rendering/RenderContext.cpp +++ b/src/Rendering/RenderContext.cpp @@ -196,7 +196,7 @@ void RenderContext::CreateDescriptorPools() static_cast(std::size(poolSizes)), poolSizes); - m_DescriptorPool[(uint32_t)UpdateFrequency::None] = static_cast(VULKAN_DEVICE.createDescriptorPool(poolCreateInfo)); + m_DescriptorPool[(uint32_t)UpdateFrequency::Persistent] = static_cast(VULKAN_DEVICE.createDescriptorPool(poolCreateInfo)); poolCreateInfo.maxSets = 100; m_DescriptorPool[(uint32_t)UpdateFrequency::PerFrame] = static_cast(VULKAN_DEVICE.createDescriptorPool(poolCreateInfo)); @@ -214,7 +214,7 @@ void RenderContext::ClearDescriptorPools() { VULKAN_DEVICE.destroyDescriptorSetLayout(m_EmptySetLayout); - VULKAN_DEVICE.destroyDescriptorPool(m_DescriptorPool[(uint32_t)UpdateFrequency::None]); + VULKAN_DEVICE.destroyDescriptorPool(m_DescriptorPool[(uint32_t)UpdateFrequency::Persistent]); VULKAN_DEVICE.destroyDescriptorPool(m_DescriptorPool[(uint32_t)UpdateFrequency::PerFrame]); VULKAN_DEVICE.destroyDescriptorPool(m_DescriptorPool[(uint32_t)UpdateFrequency::PerBatch]); VULKAN_DEVICE.destroyDescriptorPool(m_DescriptorPool[(uint32_t)UpdateFrequency::PerDraw]); @@ -1011,7 +1011,7 @@ DynamicBufferHandle RenderContext::CreateDynamicBuffer(DynamicBufferDesc&& desc) vk::DescriptorSetLayout setLayout = bindLayout.layout; - vk::DescriptorPool pool = m_DescriptorPool[(uint32_t)UpdateFrequency::PerDraw]; + vk::DescriptorPool pool = m_DescriptorPool[(uint32_t)UpdateFrequency::Persistent]; vk::DescriptorSetAllocateInfo allocInfo( pool, From d5122aab3c46e533129cd6858b52860d7af3a28e Mon Sep 17 00:00:00 2001 From: Top61ly Date: Mon, 28 Apr 2025 22:52:45 +0800 Subject: [PATCH 23/25] feat: add ResetDescriptorPool method and integrate it into RenderSystem for better resource management --- src/Rendering/RenderContext.cpp | 18 ++++++++++-------- src/Rendering/RenderContext.h | 2 ++ src/Rendering/RenderSystem.cpp | 19 +++++++++++++++---- src/Rendering/RenderSystem.h | 2 ++ 4 files changed, 29 insertions(+), 12 deletions(-) diff --git a/src/Rendering/RenderContext.cpp b/src/Rendering/RenderContext.cpp index d6c991d..51fbce9 100644 --- a/src/Rendering/RenderContext.cpp +++ b/src/Rendering/RenderContext.cpp @@ -184,6 +184,7 @@ void RenderContext::CreateDescriptorPools() vk::DescriptorPoolSize poolSizes[] = { { vk::DescriptorType::eUniformBuffer, 1000}, {vk::DescriptorType::eCombinedImageSampler, 1000}, + { vk::DescriptorType::eSampledImage, 1000}, { vk::DescriptorType::eStorageBuffer, 1000}, { vk::DescriptorType::eStorageImage, 1000}, { vk::DescriptorType::eSampler, 1000}, @@ -192,19 +193,13 @@ void RenderContext::CreateDescriptorPools() vk::DescriptorPoolCreateInfo poolCreateInfo( {}, - 1, + 1024, static_cast(std::size(poolSizes)), poolSizes); m_DescriptorPool[(uint32_t)UpdateFrequency::Persistent] = static_cast(VULKAN_DEVICE.createDescriptorPool(poolCreateInfo)); - - poolCreateInfo.maxSets = 100; m_DescriptorPool[(uint32_t)UpdateFrequency::PerFrame] = static_cast(VULKAN_DEVICE.createDescriptorPool(poolCreateInfo)); - - poolCreateInfo.maxSets = 100; m_DescriptorPool[(uint32_t)UpdateFrequency::PerBatch] = static_cast(VULKAN_DEVICE.createDescriptorPool(poolCreateInfo)); - - poolCreateInfo.maxSets = 100; m_DescriptorPool[(uint32_t)UpdateFrequency::PerDraw] = static_cast(VULKAN_DEVICE.createDescriptorPool(poolCreateInfo)); m_EmptySetLayout = VULKAN_DEVICE.createDescriptorSetLayout({}); @@ -637,6 +632,13 @@ void RenderContext::DestroySampler(SamplerHandle handle) m_SamplerPool.destroy(handle); } +void RenderContext::ResetDescriptorPool(UpdateFrequency poolType) +{ + vk::DescriptorPool pool = m_DescriptorPool[(uint32_t)poolType]; + + VULKAN_DEVICE.resetDescriptorPool(pool, {}); +} + BindGroupHandle RenderContext::CreateBindGroup(BindGroupDesc&& desc) { vk::DescriptorSetLayout setLayout = desc.bindLayout->layout; @@ -1066,7 +1068,7 @@ void RenderContext::DestroyDynamicBuffer(DynamicBufferHandle handle) { auto dynamicBuffer = m_DynamicBufferPool.getObject(handle); - vk::DescriptorPool pool = m_DescriptorPool[(uint32_t)UpdateFrequency::PerDraw]; + vk::DescriptorPool pool = m_DescriptorPool[(uint32_t)UpdateFrequency::Persistent]; VULKAN_DEVICE.freeDescriptorSets(pool, dynamicBuffer.set); m_DynamicBufferPool.destroy(handle); diff --git a/src/Rendering/RenderContext.h b/src/Rendering/RenderContext.h index ceb048c..9acc73d 100644 --- a/src/Rendering/RenderContext.h +++ b/src/Rendering/RenderContext.h @@ -134,6 +134,8 @@ ENGINE_CLASS(RenderContext) final const Sampler& GetSampler(SamplerHandle handle); void DestroySampler(SamplerHandle handle); + void ResetDescriptorPool(UpdateFrequency poolType = UpdateFrequency::PerFrame); + BindGroupHandle CreateBindGroup(BindGroupDesc&& desc); void DestroyBindGroup(BindGroupHandle handle); const BindGroup& GetBindGroup(BindGroupHandle handle); diff --git a/src/Rendering/RenderSystem.cpp b/src/Rendering/RenderSystem.cpp index a4b317d..407db99 100644 --- a/src/Rendering/RenderSystem.cpp +++ b/src/Rendering/RenderSystem.cpp @@ -566,6 +566,8 @@ void RenderSystem::RunRpsSystem() WaitForSwapChainBuffer(); + ResetPerFrameDescriptorPool(); + ResetCommandPools(); ExecuteRenderGraph(m_FrameCounter, *m_RpsSystem->rpsRDG); @@ -1172,7 +1174,7 @@ void RenderSystem::CreateGlobalDescriptorSets() m_GlobalBindGroup = m_RenderContext->CreateBindGroup({ .debugName = "Global BindGroup", - .updateFrequency = UpdateFrequency::PerFrame, + .updateFrequency = UpdateFrequency::Persistent, .textures = {}, .buffers = {{0, m_GlobalConstantBuffer, 0, sizeof(PerframeData), BindType::UniformBuffer}}, .samplers = {}, @@ -1196,7 +1198,7 @@ void RenderSystem:: CreateUVQuadDescriptorSets() m_UVQuadBindGroup = m_RenderContext->CreateBindGroup({ .debugName = "UV Quad BindGroup", - .updateFrequency = UpdateFrequency::PerFrame, + .updateFrequency = UpdateFrequency::Persistent, .textures = { {0, m_UVCheckTextureHandle, TextureUsageBits::Sampled, 0, 0, BindType::CombinedSampledImage, m_UVCheckSamplerHandle}}, .buffers = {}, .samplers = {}, @@ -1658,7 +1660,6 @@ void RenderSystem::ForwardOpaquePassWithRPSWrapper(const RpsCmdCallbackContext* .bindLayout = &renderSystem.m_ShadowPassBindLayout, }); - renderContext->UpdateBindGroup(shadowmapBindGroup, { .samplers = {{1, renderSystem.m_ShadowmapSamplerHandler}}, @@ -1667,10 +1668,20 @@ void RenderSystem::ForwardOpaquePassWithRPSWrapper(const RpsCmdCallbackContext* .textures = {{0, shadowmapView}}, } ); + + auto& pipeline = renderContext->GetGraphicsPipeline(renderSystem.m_RpsPipelines.forwardPipeline); + + cmd.bindDescriptorSets(vk::PipelineBindPoint::eGraphics, pipeline.layout, 1, {shadowmapBindGroup.descriptorSet}, {}); } DrawKey key = {"ForwardPass", AlphaMode::Opaque}; renderSystem.DrawRenderer(key, cmd, renderSystem.m_RpsPipelines.forwardPipeline); } -} // namespace gore \ No newline at end of file + +void RenderSystem::ResetPerFrameDescriptorPool() +{ + m_RenderContext->ResetDescriptorPool(UpdateFrequency::PerFrame); +} +} // namespace gore + diff --git a/src/Rendering/RenderSystem.h b/src/Rendering/RenderSystem.h index 797f127..5f73de3 100644 --- a/src/Rendering/RenderSystem.h +++ b/src/Rendering/RenderSystem.h @@ -159,6 +159,8 @@ ENGINE_CLASS(RenderSystem) final : System void EndCmdList(ActiveCommandList& cmdList); void RecycleCmdList(ActiveCommandList& cmdList); + void ResetPerFrameDescriptorPool(); + void ResetCommandPools(); void ReserveSemaphores(uint32_t numSyncs); From 2d5d93e61330489477f10ec914036f4ade12aa05 Mon Sep 17 00:00:00 2001 From: Top61ly Date: Tue, 29 Apr 2025 22:49:26 +0800 Subject: [PATCH 24/25] feat: refactor descriptor pool management to support framed pools and deprecate PerFrame frequency --- src/Rendering/BindGroup.h | 5 ++--- src/Rendering/RenderContext.cpp | 40 ++++++++++++++++++++++++--------- src/Rendering/RenderContext.h | 14 ++++++++++++ 3 files changed, 46 insertions(+), 13 deletions(-) diff --git a/src/Rendering/BindGroup.h b/src/Rendering/BindGroup.h index 0a8d83a..5ad7720 100644 --- a/src/Rendering/BindGroup.h +++ b/src/Rendering/BindGroup.h @@ -15,11 +15,10 @@ namespace gore::gfx enum class UpdateFrequency : uint8_t { Persistent, - PerFrame, PerBatch, - // We should never use this, but it's here for completeness PerDraw, - Count + Count, + PerFrame // deprecated }; struct TextureBinding final diff --git a/src/Rendering/RenderContext.cpp b/src/Rendering/RenderContext.cpp index 51fbce9..82a8079 100644 --- a/src/Rendering/RenderContext.cpp +++ b/src/Rendering/RenderContext.cpp @@ -197,10 +197,20 @@ void RenderContext::CreateDescriptorPools() static_cast(std::size(poolSizes)), poolSizes); + for (int i = 0; i < FramedDescriptorPool::c_MaxFrames; i++) + { + m_FramedDescriptorPool.pools.emplace_back(static_cast(VULKAN_DEVICE.createDescriptorPool(poolCreateInfo))); + SetObjectDebugName(m_FramedDescriptorPool.pools[i].pool, "RenderContext PerFrame DescriptorPool " + std::to_string(i)); + } + m_DescriptorPool[(uint32_t)UpdateFrequency::Persistent] = static_cast(VULKAN_DEVICE.createDescriptorPool(poolCreateInfo)); - m_DescriptorPool[(uint32_t)UpdateFrequency::PerFrame] = static_cast(VULKAN_DEVICE.createDescriptorPool(poolCreateInfo)); + SetObjectDebugName(m_DescriptorPool[(uint32_t)UpdateFrequency::Persistent].pool, "RenderContext Persistent DescriptorPool"); + m_DescriptorPool[(uint32_t)UpdateFrequency::PerBatch] = static_cast(VULKAN_DEVICE.createDescriptorPool(poolCreateInfo)); + SetObjectDebugName(m_DescriptorPool[(uint32_t)UpdateFrequency::PerBatch].pool, "RenderContext PerBatch DescriptorPool"); + m_DescriptorPool[(uint32_t)UpdateFrequency::PerDraw] = static_cast(VULKAN_DEVICE.createDescriptorPool(poolCreateInfo)); + SetObjectDebugName(m_DescriptorPool[(uint32_t)UpdateFrequency::PerDraw].pool, "RenderContext PerDraw DescriptorPool"); m_EmptySetLayout = VULKAN_DEVICE.createDescriptorSetLayout({}); } @@ -209,8 +219,12 @@ void RenderContext::ClearDescriptorPools() { VULKAN_DEVICE.destroyDescriptorSetLayout(m_EmptySetLayout); + for (int i = 0; i < FramedDescriptorPool::c_MaxFrames; i++) + { + VULKAN_DEVICE.destroyDescriptorPool(m_FramedDescriptorPool.pools[i]); + } + VULKAN_DEVICE.destroyDescriptorPool(m_DescriptorPool[(uint32_t)UpdateFrequency::Persistent]); - VULKAN_DEVICE.destroyDescriptorPool(m_DescriptorPool[(uint32_t)UpdateFrequency::PerFrame]); VULKAN_DEVICE.destroyDescriptorPool(m_DescriptorPool[(uint32_t)UpdateFrequency::PerBatch]); VULKAN_DEVICE.destroyDescriptorPool(m_DescriptorPool[(uint32_t)UpdateFrequency::PerDraw]); } @@ -634,15 +648,21 @@ void RenderContext::DestroySampler(SamplerHandle handle) void RenderContext::ResetDescriptorPool(UpdateFrequency poolType) { - vk::DescriptorPool pool = m_DescriptorPool[(uint32_t)poolType]; - - VULKAN_DEVICE.resetDescriptorPool(pool, {}); + if (poolType == UpdateFrequency::PerFrame) + { + m_FramedDescriptorPool.currentPoolIndex = (m_FramedDescriptorPool.currentPoolIndex + 1) % FramedDescriptorPool::c_MaxFrames; + VULKAN_DEVICE.resetDescriptorPool(m_FramedDescriptorPool.pools[m_FramedDescriptorPool.currentPoolIndex], {}); + return; + } + + assert(poolType < UpdateFrequency::Count && poolType != UpdateFrequency::PerFrame); + VULKAN_DEVICE.resetDescriptorPool(m_DescriptorPool[(uint32_t)poolType], {}); } BindGroupHandle RenderContext::CreateBindGroup(BindGroupDesc&& desc) { vk::DescriptorSetLayout setLayout = desc.bindLayout->layout; - vk::DescriptorPool pool = m_DescriptorPool[(uint32_t)desc.updateFrequency]; + vk::DescriptorPool pool = GetDescriptorPool(desc.updateFrequency); vk::DescriptorSet descriptorSet = VULKAN_DEVICE.allocateDescriptorSets({pool, 1, &setLayout})[0]; @@ -755,7 +775,7 @@ void RenderContext::DestroyBindGroup(BindGroupHandle handle) auto bindGroupDesc = m_BindGroupPool.getObjectDesc(handle); auto bindGroup = m_BindGroupPool.getObject(handle); - vk::DescriptorPool pool = m_DescriptorPool[(uint32_t)bindGroupDesc.updateFrequency]; + vk::DescriptorPool pool = GetDescriptorPool(bindGroupDesc.updateFrequency); VULKAN_DEVICE.freeDescriptorSets(pool, bindGroup.set); m_BindGroupPool.destroy(handle); @@ -774,7 +794,7 @@ const BindGroupDesc& RenderContext::GetBindGroupDesc(BindGroupHandle handle) TransientBindGroup RenderContext::CreateTransientBindGroup(BindGroupDesc&& desc) { vk::DescriptorSetLayout setLayout = desc.bindLayout->layout; - vk::DescriptorPool pool = m_DescriptorPool[(uint32_t)desc.updateFrequency]; + vk::DescriptorPool pool = GetDescriptorPool(desc.updateFrequency); vk::DescriptorSet descriptorSet = VULKAN_DEVICE.allocateDescriptorSets({pool, 1, &setLayout})[0]; @@ -1013,7 +1033,7 @@ DynamicBufferHandle RenderContext::CreateDynamicBuffer(DynamicBufferDesc&& desc) vk::DescriptorSetLayout setLayout = bindLayout.layout; - vk::DescriptorPool pool = m_DescriptorPool[(uint32_t)UpdateFrequency::Persistent]; + vk::DescriptorPool pool = GetDescriptorPool(UpdateFrequency::Persistent); vk::DescriptorSetAllocateInfo allocInfo( pool, @@ -1068,7 +1088,7 @@ void RenderContext::DestroyDynamicBuffer(DynamicBufferHandle handle) { auto dynamicBuffer = m_DynamicBufferPool.getObject(handle); - vk::DescriptorPool pool = m_DescriptorPool[(uint32_t)UpdateFrequency::Persistent]; + vk::DescriptorPool pool = GetDescriptorPool(UpdateFrequency::Persistent); VULKAN_DEVICE.freeDescriptorSets(pool, dynamicBuffer.set); m_DynamicBufferPool.destroy(handle); diff --git a/src/Rendering/RenderContext.h b/src/Rendering/RenderContext.h index 9acc73d..5760a56 100644 --- a/src/Rendering/RenderContext.h +++ b/src/Rendering/RenderContext.h @@ -221,8 +221,22 @@ ENGINE_CLASS(RenderContext) final vk::DescriptorSetLayout m_EmptySetLayout; + struct FramedDescriptorPool + { + static const uint32_t c_MaxFrames = 3; + + std::vector pools; + uint32_t currentPoolIndex = 0; + } m_FramedDescriptorPool; + DescriptorPoolHolder m_DescriptorPool[(uint32_t)UpdateFrequency::Count]; + DescriptorPoolHolder GetDescriptorPool(UpdateFrequency poolType = UpdateFrequency::PerFrame) + { + return poolType == UpdateFrequency::PerFrame ? + m_FramedDescriptorPool.pools[m_FramedDescriptorPool.currentPoolIndex] : m_DescriptorPool[(uint32_t)poolType]; + } + ResourceCache m_ResourceCache; vk::raii::CommandPool m_CommandPool; From 84fe75a72439fffeb03089b26bd0ed5b24340236 Mon Sep 17 00:00:00 2001 From: Top61ly Date: Tue, 6 May 2025 21:17:31 +0800 Subject: [PATCH 25/25] feat: add UpdateGlobalConstantBuffer method to enhance global constant buffer management --- src/Rendering/RenderSystem.cpp | 36 +++++++++++++++++++++++++++++++++- src/Rendering/RenderSystem.h | 4 ++-- 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/src/Rendering/RenderSystem.cpp b/src/Rendering/RenderSystem.cpp index 407db99..09aa58d 100644 --- a/src/Rendering/RenderSystem.cpp +++ b/src/Rendering/RenderSystem.cpp @@ -563,9 +563,11 @@ void RenderSystem::RunRpsSystem() return; UpdateRenderGraph(); - + WaitForSwapChainBuffer(); + UpdateGlobalConstantBuffer(); + ResetPerFrameDescriptorPool(); ResetCommandPools(); @@ -1632,6 +1634,38 @@ void RenderSystem::CreateDefaultResources() }); } +void RenderSystem::UpdateGlobalConstantBuffer() +{ + Camera* mainCamera = Camera::Main; + if (mainCamera == nullptr) + { + return; + } + + PerframeData perframeData; + perframeData.vpMatrix = mainCamera->GetViewProjectionMatrix(); + + // Update Main Light + auto& gameObjects = Scene::GetActiveScene()->GetGameObjects(); + for (auto& gameObject : gameObjects) + { + Light* light = gameObject->GetComponent(); + if (light == nullptr) + continue; + + Matrix4x4 lightMatrix = gameObject->GetTransform()->GetWorldToLocalMatrixIgnoreScale(); + Matrix4x4 orthoMatrix = Matrix4x4::CreateOrthographicLH(100.0f, 100.0f, .1f, 100.0f); + perframeData.directionalLightVPMatrix = lightMatrix * orthoMatrix; + + LightData lightData = light->GetData(); + perframeData.directionalLightColor = lightData.color; + perframeData.directionalLightIntensity = lightData.intensity; + break; + } + + m_RenderContext->CopyDataToBuffer(m_GlobalConstantBuffer, perframeData); +} + void RenderSystem::ShadowmapPassWithRPSWrapper(const RpsCmdCallbackContext* pContext) { RenderSystem& renderSystem = *reinterpret_cast(pContext->pUserRecordContext); diff --git a/src/Rendering/RenderSystem.h b/src/Rendering/RenderSystem.h index 5f73de3..f7951b0 100644 --- a/src/Rendering/RenderSystem.h +++ b/src/Rendering/RenderSystem.h @@ -108,8 +108,6 @@ ENGINE_CLASS(RenderSystem) final : System vk::raii::DescriptorPool m_ImguiDescriptorPool; private: - void PrepareGPUSceneData(); - static void RecordDebugMarker(void* pUserContext, const RpsRuntimeOpRecordDebugMarkerArgs* pArgs); static void SetDebugName(void* pUserContext, const RpsRuntimeOpSetDebugNameArgs* pArgs); @@ -166,6 +164,8 @@ ENGINE_CLASS(RenderSystem) final : System void ReserveSemaphores(uint32_t numSyncs); uint64_t CalcGuaranteedCompletedFrameindexForRps() const; + + void UpdateGlobalConstantBuffer(); // static void DrawTriangleWithRPSWrapper(const RpsCmdCallbackContext* pContext); static void ShadowmapPassWithRPSWrapper(const RpsCmdCallbackContext* pContext);