diff --git a/sample/App/SampleApp.cpp b/sample/App/SampleApp.cpp index 5b171bc..854795b 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,270 +44,230 @@ 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}}; - renderPasses.shadowPassDesc = {{}, GraphicsFormat::D32_FLOAT}; -} - -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)}); -} - -void SampleApp::CreatePipelines() -{ - CreateForwardPipeline(); - CreateShadowmapPipeline(); -} - -void SampleApp::CreateDefaultResources() -{ - using namespace gore::gfx; +// void SampleApp::CreateRenderPassDesc() +// { +// renderPasses.forwardPassDesc = {{GraphicsFormat::BGRA8_SRGB}}; +// renderPasses.shadowPassDesc = {{}, GraphicsFormat::D32_FLOAT}; +// } + +// 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)}); +// } + +// void SampleApp::CreatePipelines() +// { +// CreateForwardPipeline(); +// CreateShadowmapPipeline(); +// } + +// 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); - 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::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() { m_GraphicsCaps = m_RenderSystem->GetGraphicsCaps(); - InitializeRpsSystem(); - - PrepareGraphics(); + // PrepareGraphics(); Material forwardMat; forwardMat.SetAlphaMode(AlphaMode::Opaque); forwardMat.AddPass(Pass{ .name = "ShadowCaster", - .shader = pipelines.shadowPipeline, - .bindGroup = {m_GlobalBindGroup}}); + /*.shader = pipelines.shadowPipeline, + .bindGroup = {m_GlobalBindGroup}*/}); forwardMat.AddPass(Pass{ .name = "ForwardPass", - .shader = pipelines.forwardPipeline, - .bindGroup = {m_GlobalBindGroup}}); + /*.shader = pipelines.forwardPipeline, + .bindGroup = {m_GlobalBindGroup}*/}); gore::gfx::RenderContext& renderContext = m_RenderSystem->GetRenderContext(); @@ -352,8 +309,8 @@ void SampleApp::Initialize() gore::gfx::MeshRenderer* meshRenderer = gameObject->AddComponent(); meshRenderer->LoadMesh("cube.gltf"); meshRenderer->SetMaterial(forwardMat); - meshRenderer->SetDynamicBuffer(m_UnifiedDynamicBufferHandle); - meshRenderer->SetDynamicBufferOffset(0); + // meshRenderer->SetDynamicBuffer(m_UnifiedDynamicBufferHandle); + // meshRenderer->SetDynamicBufferOffset(0); gore::Transform* transform = gameObject->GetTransform(); transform->SetLocalPosition(gore::Vector3::Right * 20.0f); @@ -527,35 +484,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..e7b1c14 100644 --- a/sample/App/SampleApp.h +++ b/sample/App/SampleApp.h @@ -34,56 +34,55 @@ class SampleApp final : public gore::App void PreRender(); // Temporary RenderPassDesc for pipeline creation - void InitializeRpsSystem(); - 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/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); diff --git a/src/Rendering/BindGroup.h b/src/Rendering/BindGroup.h index 23e3b00..5ad7720 100644 --- a/src/Rendering/BindGroup.h +++ b/src/Rendering/BindGroup.h @@ -14,12 +14,11 @@ namespace gore::gfx enum class UpdateFrequency : uint8_t { - None, - PerFrame, + Persistent, PerBatch, - // We should never use this, but it's here for completeness PerDraw, - Count + Count, + PerFrame // deprecated }; struct TextureBinding final @@ -52,10 +51,17 @@ 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; - UpdateFrequency updateFrequency = UpdateFrequency::None; + UpdateFrequency updateFrequency = UpdateFrequency::Persistent; std::vector textures = {}; std::vector buffers = {}; std::vector samplers = {}; 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 b93d053..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,16 +29,16 @@ 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) 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/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/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/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 diff --git a/src/Rendering/RawBindGroupUpdateDesc.h b/src/Rendering/RawBindGroupUpdateDesc.h deleted file mode 100644 index 730ac8e..0000000 --- a/src/Rendering/RawBindGroupUpdateDesc.h +++ /dev/null @@ -1,41 +0,0 @@ -#pragma once - -#include "Graphics/Vulkan/VulkanIncludes.h" - -#include "Texture.h" -#include "BindLayout.h" - -namespace gore::gfx -{ -struct RawTextureBinding final -{ - uint32_t binding = 0; - vk::ImageView imageView = {}; - BindType bindType = BindType::SampledImage; - vk::Sampler sampler = {}; -}; - -struct RawBufferBinding final -{ - uint32_t binding = 0; - vk::Buffer buffer = {}; - uint32_t offset = 0; - uint32_t range = 0; - BindType bindType = BindType::UniformBuffer; -}; - -struct RawSamplerBinding final -{ - uint32_t binding = 0; - vk::Sampler sampler = {}; - BindType bindType = BindType::Sampler; -}; - -struct RawBindGroupUpdateDesc final -{ - std::vector textures; - std::vector buffers; - std::vector samplers; -}; - -} // namespace gore::gfx \ No newline at end of file diff --git a/src/Rendering/RenderContext.cpp b/src/Rendering/RenderContext.cpp index ada7519..82a8079 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,20 +193,24 @@ void RenderContext::CreateDescriptorPools() vk::DescriptorPoolCreateInfo poolCreateInfo( {}, - 1, + 1024, static_cast(std::size(poolSizes)), poolSizes); - m_DescriptorPool[(uint32_t)UpdateFrequency::None] = static_cast(VULKAN_DEVICE.createDescriptorPool(poolCreateInfo)); - - poolCreateInfo.maxSets = 100; - m_DescriptorPool[(uint32_t)UpdateFrequency::PerFrame] = static_cast(VULKAN_DEVICE.createDescriptorPool(poolCreateInfo)); + 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)); + } - poolCreateInfo.maxSets = 100; + m_DescriptorPool[(uint32_t)UpdateFrequency::Persistent] = 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"); - poolCreateInfo.maxSets = 100; 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({}); } @@ -214,8 +219,12 @@ 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::PerFrame]); + 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::PerBatch]); VULKAN_DEVICE.destroyDescriptorPool(m_DescriptorPool[(uint32_t)UpdateFrequency::PerDraw]); } @@ -637,10 +646,23 @@ void RenderContext::DestroySampler(SamplerHandle handle) m_SamplerPool.destroy(handle); } +void RenderContext::ResetDescriptorPool(UpdateFrequency poolType) +{ + 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]; @@ -753,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); @@ -769,6 +791,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 = GetDescriptorPool(desc.updateFrequency); + + vk::DescriptorSet descriptorSet = VULKAN_DEVICE.allocateDescriptorSets({pool, 1, &setLayout})[0]; + + SetObjectDebugName(descriptorSet, desc.debugName); + + return TransientBindGroup{descriptorSet}; +} + void RenderContext::PrepareRendering() { CreateDescriptorPools(); @@ -820,6 +854,170 @@ 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(descriptorSet) + .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 = { @@ -835,7 +1033,7 @@ DynamicBufferHandle RenderContext::CreateDynamicBuffer(DynamicBufferDesc&& desc) vk::DescriptorSetLayout setLayout = bindLayout.layout; - vk::DescriptorPool pool = m_DescriptorPool[(uint32_t)UpdateFrequency::PerDraw]; + vk::DescriptorPool pool = GetDescriptorPool(UpdateFrequency::Persistent); vk::DescriptorSetAllocateInfo allocInfo( pool, @@ -890,7 +1088,7 @@ void RenderContext::DestroyDynamicBuffer(DynamicBufferHandle handle) { auto dynamicBuffer = m_DynamicBufferPool.getObject(handle); - vk::DescriptorPool pool = m_DescriptorPool[(uint32_t)UpdateFrequency::PerDraw]; + vk::DescriptorPool pool = GetDescriptorPool(UpdateFrequency::Persistent); VULKAN_DEVICE.freeDescriptorSets(pool, dynamicBuffer.set); m_DynamicBufferPool.destroy(handle); @@ -1127,76 +1325,4 @@ void RenderContext::DestroyRenderPass(RenderPass& renderPass) { VULKAN_DEVICE.destroyRenderPass(renderPass.renderPass); } - -void RenderContext::UpdateBindGroup(BindGroupHandle handle, const RawBindGroupUpdateDesc& 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 f258953..5760a56 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 @@ -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, @@ -124,13 +134,18 @@ 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); const BindGroupDesc& GetBindGroupDesc(BindGroupHandle handle); + TransientBindGroup CreateTransientBindGroup(BindGroupDesc&& desc); + // BindGroup Update for RPSL - void UpdateBindGroup(BindGroupHandle handle, const RawBindGroupUpdateDesc& desc); + void UpdateBindGroup(TransientBindGroup& bindGroup, BindGroupUpdateDesc&& desc, TransientBindGroupUpdateDesc&& transientDesc); + void UpdateBindGroup(BindGroupHandle handle, BindGroupUpdateDesc&& desc, TransientBindGroupUpdateDesc&& transientDesc); DynamicBufferHandle CreateDynamicBuffer(DynamicBufferDesc&& desc); const DynamicBufferDesc& GetDynamicBufferDesc(DynamicBufferHandle handle); @@ -206,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; diff --git a/src/Rendering/RenderSystem.cpp b/src/Rendering/RenderSystem.cpp index 0362114..09aa58d 100644 --- a/src/Rendering/RenderSystem.cpp +++ b/src/Rendering/RenderSystem.cpp @@ -21,8 +21,13 @@ #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" #include #include @@ -30,6 +35,11 @@ #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 { @@ -77,6 +87,8 @@ RenderSystem::~RenderSystem() void RenderSystem::Initialize() { + MICROPROFILE_SCOPE(g_RenderSystemInit); + Window* window = m_App->GetWindow(); int width, height; window->GetSize(&width, &height); @@ -129,27 +141,31 @@ void RenderSystem::Initialize() } }); + CreateDefaultResources(); + CreateDepthBuffer(); CreateTextureObjects(); CreateGlobalDescriptorSets(); + CreateShadowPassObject(); CreateUVQuadDescriptorSets(); CreateDynamicUniformBuffer(); + CreateRpsPipelines(); CreatePipeline(); GetQueues(); 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); @@ -159,6 +175,8 @@ static void PrepareDrawStreamByDrawInfo(std::unordered_map& void RenderSystem::PrepareDrawData() { + MICROPROFILE_SCOPE(g_PrepareDrawData); + DrawCreateInfo info = {}; info.passName = "ForwardPass"; info.alphaMode = AlphaMode::Opaque; @@ -170,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() @@ -417,7 +435,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; @@ -525,7 +543,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() @@ -540,9 +563,13 @@ void RenderSystem::RunRpsSystem() return; UpdateRenderGraph(); - + WaitForSwapChainBuffer(); + UpdateGlobalConstantBuffer(); + + ResetPerFrameDescriptorPool(); + ResetCommandPools(); ExecuteRenderGraph(m_FrameCounter, *m_RpsSystem->rpsRDG); @@ -565,6 +592,8 @@ void RenderSystem::RunRpsSystem() void RenderSystem::UpdateRenderGraph() { + MICROPROFILE_SCOPE(g_RenderGraphUpdate); + if (IsRpsReady() == false) return; @@ -617,6 +646,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; @@ -1001,6 +1032,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() @@ -1074,17 +1133,37 @@ void RenderSystem::CreateDepthBuffer() m_Device.SetName(m_DepthImageView, "Depth Buffer ImageView"); } +void RenderSystem::CreateShadowPassObject() +{ + 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); + + m_ShadowmapSamplerHandler = m_RenderContext->CreateSampler({ + .debugName = "Shadowmap Sampler" + }); +} + 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 }); std::vector bindings { - {0, BindType::UniformBuffer, 1, ShaderStage::Vertex} + {0, BindType::UniformBuffer, 1, ShaderStage::Vertex | ShaderStage::Fragment} }; BindLayoutCreateInfo bindLayoutCreateInfo = @@ -1097,9 +1176,9 @@ void RenderSystem::CreateGlobalDescriptorSets() m_GlobalBindGroup = m_RenderContext->CreateBindGroup({ .debugName = "Global BindGroup", - .updateFrequency = UpdateFrequency::PerFrame, + .updateFrequency = UpdateFrequency::Persistent, .textures = {}, - .buffers = {{0, m_GlobalConstantBuffer, 0, sizeof(GlobalConstantBuffer), BindType::UniformBuffer}}, + .buffers = {{0, m_GlobalConstantBuffer, 0, sizeof(PerframeData), BindType::UniformBuffer}}, .samplers = {}, .bindLayout = &m_GlobalBindLayout, }); @@ -1121,7 +1200,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 = {}, @@ -1131,7 +1210,7 @@ void RenderSystem:: CreateUVQuadDescriptorSets() struct PerDrawData { - Matrix4x4 modelMatrix; + Matrix4x4 modelMatrix[128]; }; void RenderSystem::CreateDynamicUniformBuffer() @@ -1144,7 +1223,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( @@ -1441,4 +1520,202 @@ 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, m_ShadowPassBindLayout }, + .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 + } + }); + + 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() +{ + 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, + }); +} + +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); + vk::CommandBuffer cmd = rpsVKCommandBufferFromHandle(pContext->hCommandBuffer); + + DrawKey key = {"ShadowCaster", AlphaMode::Opaque}; + + renderSystem.DrawRenderer(key, cmd, renderSystem.m_RpsPipelines.shadowPipeline); +} + +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) + { + auto& renderContext = renderSystem.m_RenderContext; + + auto shadowmapBindGroup = renderContext->CreateTransientBindGroup({ + .debugName = "Shadowmap BindGroup", + .updateFrequency = UpdateFrequency::PerFrame, + .bindLayout = &renderSystem.m_ShadowPassBindLayout, + }); + + renderContext->UpdateBindGroup(shadowmapBindGroup, + { + .samplers = {{1, renderSystem.m_ShadowmapSamplerHandler}}, + }, + { + .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); +} + +void RenderSystem::ResetPerFrameDescriptorPool() +{ + m_RenderContext->ResetDescriptorPool(UpdateFrequency::PerFrame); +} +} // namespace gore + diff --git a/src/Rendering/RenderSystem.h b/src/Rendering/RenderSystem.h index fb52759..f7951b0 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 @@ -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); @@ -159,15 +157,19 @@ ENGINE_CLASS(RenderSystem) final : System void EndCmdList(ActiveCommandList& cmdList); void RecycleCmdList(ActiveCommandList& cmdList); + void ResetPerFrameDescriptorPool(); + void ResetCommandPools(); void ReserveSemaphores(uint32_t numSyncs); uint64_t CalcGuaranteedCompletedFrameindexForRps() const; + + void UpdateGlobalConstantBuffer(); // 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; @@ -181,6 +183,27 @@ ENGINE_CLASS(RenderSystem) final : System // Surface & Swapchain Swapchain m_Swapchain; + struct RPSPipelines + { + GraphicsPipelineHandle forwardPipeline; + GraphicsPipelineHandle shadowPipeline; + } m_RpsPipelines; + + struct RPSMaterial + { + Material forward; + } m_RpsMaterial; + + void CreateRpsPipelines(); + + struct DefaultResources + { + TextureHandle whiteTexture; + TextureHandle blackTexture; + } m_DefaultResources; + + void CreateDefaultResources(); + GraphicsPipelineHandle m_CubePipelineHandle; GraphicsPipelineHandle m_UnLitPipelineHandle; GraphicsPipelineHandle m_TrianglePipelineHandle; @@ -218,6 +241,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; @@ -249,6 +276,7 @@ ENGINE_CLASS(RenderSystem) final : System void CreateSwapchain(uint32_t imageCount, uint32_t width, uint32_t height); void CreateDepthBuffer(); void CreateGlobalDescriptorSets(); + void CreateShadowPassObject(); void CreateUVQuadDescriptorSets(); void CreateDynamicUniformBuffer(); void CreatePipeline(); diff --git a/src/Rendering/TransientBindGroupUpdateDesc.h b/src/Rendering/TransientBindGroupUpdateDesc.h new file mode 100644 index 0000000..a8a8ba9 --- /dev/null +++ b/src/Rendering/TransientBindGroupUpdateDesc.h @@ -0,0 +1,47 @@ +#pragma once + +#include "Graphics/Vulkan/VulkanIncludes.h" + +#include "Texture.h" +#include "BindLayout.h" + +namespace gore::gfx +{ +struct TransientBindGroup +{ + vk::DescriptorSet descriptorSet = {}; +}; + +struct TransientTextureBinding final +{ + uint32_t binding = 0; + vk::ImageView imageView = {}; + vk::ImageLayout imageLayout = vk::ImageLayout::eShaderReadOnlyOptimal; + vk::DescriptorType descriptorType = vk::DescriptorType::eSampledImage; + vk::Sampler sampler = {}; +}; + +struct TransientBufferBinding final +{ + uint32_t binding = 0; + vk::Buffer buffer = {}; + vk::DescriptorType descriptorType = vk::DescriptorType::eUniformBuffer; + uint32_t offset = 0; + uint32_t range = 0; +}; + +struct TransientSamplerBinding final +{ + uint32_t binding = 0; + vk::Sampler sampler = {}; + BindType bindType = BindType::Sampler; +}; + +struct TransientBindGroupUpdateDesc final +{ + std::vector textures; + std::vector buffers; + std::vector samplers; +}; + +} // namespace gore::gfx \ No newline at end of file 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 {