diff --git a/SHADE_Application/src/Application/SBApplication.cpp b/SHADE_Application/src/Application/SBApplication.cpp index da13491b..58b6cb84 100644 --- a/SHADE_Application/src/Application/SBApplication.cpp +++ b/SHADE_Application/src/Application/SBApplication.cpp @@ -37,6 +37,7 @@ namespace Sandbox window.Create(hInstance, hPrevInstance, lpCmdLine, nCmdShow); SHADE::SHSystemManager::CreateSystem(); SHADE::SHGraphicsSystem* graphicsSystem = static_cast(SHADE::SHSystemManager::GetSystem()); + SHADE::SHSystemManager::RegisterRoutine(1); SHADE::SHSystemManager::RegisterRoutine(1); SHADE::SHSystemManager::RegisterRoutine(1); SHADE::SHSystemManager::RegisterRoutine(1); diff --git a/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.cpp b/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.cpp index da4947f2..8252929d 100644 --- a/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.cpp +++ b/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.cpp @@ -486,7 +486,7 @@ namespace SHADE */ /***************************************************************************/ - Handle SHVkLogicalDevice::CreatePipeline(Handle const& pipelineLayoutHdl, SHVkPipelineState const* const state, Handle const& renderpassHdl, uint32_t subpass, SH_PIPELINE_TYPE type) noexcept + Handle SHVkLogicalDevice::CreatePipeline(Handle const& pipelineLayoutHdl, SHVkPipelineState const* const state, Handle const& renderpassHdl, Handle subpass, SH_PIPELINE_TYPE type) noexcept { return SHVkInstance::GetResourceManager().Create (GetHandle(), pipelineLayoutHdl, state, renderpassHdl, subpass, type); diff --git a/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.h b/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.h index c359d1d3..01764e80 100644 --- a/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.h +++ b/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.h @@ -39,6 +39,7 @@ namespace SHADE class SHVkImageView; class SHShaderBlockInterface; class SHVkDescriptorSetGroup; + class SHSubpass; /***************************************************************************/ /*! @@ -167,7 +168,7 @@ namespace SHADE Handle const& pipelineLayoutHdl, SHVkPipelineState const* const state, Handle const& renderpassHdl, - uint32_t subpass, + Handle subpass, SH_PIPELINE_TYPE type ) noexcept; diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp index f4a229bb..e7c2f9ef 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp @@ -29,7 +29,7 @@ namespace SHADE /* SHBatch - Usage Functions */ /*---------------------------------------------------------------------------------*/ SHBatch::SHBatch(Handle pipeline) - : pipeline { pipeline } + : pipeline{ pipeline } { if (!pipeline) throw std::invalid_argument("Attempted to create a SHBatch with an invalid SHPipeline!"); @@ -59,8 +59,8 @@ namespace SHADE // Check if we have a SubBatch with the same mesh yet auto subBatch = std::find_if(subBatches.begin(), subBatches.end(), [&](const SHSubBatch& batch) { - return batch.Mesh == renderable->Mesh; - }); + return batch.Mesh == renderable->Mesh; + }); // Attempt to remove if it exists if (subBatch == subBatches.end()) @@ -127,13 +127,13 @@ namespace SHADE { // Create command drawData.emplace_back(vk::DrawIndexedIndirectCommand - { - .indexCount = subBatch.Mesh->IndexCount, - .instanceCount = static_cast(subBatch.Renderables.size()), - .firstIndex = subBatch.Mesh->FirstIndex, - .vertexOffset = subBatch.Mesh->FirstVertex, - .firstInstance = nextInstanceIndex - }); + { + .indexCount = subBatch.Mesh->IndexCount, + .instanceCount = static_cast(subBatch.Renderables.size()), + .firstIndex = subBatch.Mesh->FirstIndex, + .vertexOffset = subBatch.Mesh->FirstVertex, + .firstInstance = nextInstanceIndex + }); // Fill in buffers (CPU) for (const SHRenderable* renderable : subBatch.Renderables) diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatcher.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatcher.cpp index 2843ebb6..a37bbe72 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatcher.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatcher.cpp @@ -22,16 +22,16 @@ of DigiPen Institute of Technology is prohibited. #include "Graphics/MiddleEnd/Interface/SHMaterialInstance.h" #include "Graphics/Pipeline/SHVkPipeline.h" #include "ECS_Base/Managers/SHComponentManager.h" +#include "Tools/SHLogger.h" namespace SHADE { /*---------------------------------------------------------------------------------*/ /* Lifecycle Functions */ /*---------------------------------------------------------------------------------*/ - void SHBatcher::Init(const std::vector& _renderables, Handle _renderGraph) + void SHBatcher::Init(Handle _renderGraph) { - renderables = &_renderables; - renderGraph = _renderGraph; + renderGraph = _renderGraph; } /*---------------------------------------------------------------------------------*/ @@ -39,53 +39,56 @@ namespace SHADE /*---------------------------------------------------------------------------------*/ void SHBatcher::PrepareBatches() { - // Iterate through all renderables and send it into the batching - auto& renderables = SHComponentManager::GetDense(); + // Iterate through all renderables and send it into the batching + auto& renderables = SHComponentManager::GetDense(); for (auto iter = renderables.cbegin(); iter != renderables.cend(); ++iter) { - AddToBatch(iter->GetHandle()); + AddToBatch(&(*iter)); } } - void SHBatcher::AddToBatch(Handle renderable) + void SHBatcher::AddToBatch(SHRenderable const* renderable) { // Get Subpass Index for this renderables pipeline - const SHSubPassIndex SUB_PASS_IDX = renderable->GetMaterial()->GetBaseMaterial()->GetPipeline()->GetPipelineState().GetSubpassIndex(); + const Handle SUBPASS = renderable->GetMaterial()->GetBaseMaterial()->GetPipeline()->GetPipelineState().GetSubpass(); - // Check if there is a SuperBatch for the specific RenderPass - auto superBatch = std::find_if(superBatches.begin(), superBatches.end(), [&](const SHSuperBatch& superBatch) + // Check if there is a SuperBatch for the specific Subpass + auto superBatch = std::find_if(superBatches.begin(), superBatches.end(), [&](Handle superBatch) { - return superBatch.GetSubpassId() == SUB_PASS_IDX; + return superBatch->GetSubpass() == SUBPASS; }); - // Create if it doesn't exist + // Ignore and emit a warning if it doesn't exist if (superBatch == superBatches.end()) { - superBatches.emplace_back(SUB_PASS_IDX); - superBatch = superBatches.end(); + SHLOG_WARNING("A renderable was attempted to be added to a SuperBatch which does not exist."); + return; } // Add the Renderable - superBatch->Add(renderable->GetHandle()); + (*superBatch)->Add(renderable); } - void SHBatcher::RemoveFromBatch(Handle renderable) + void SHBatcher::RemoveFromBatch(SHRenderable const* renderable) { // Get Subpass Index for this renderables pipeline - const SHSubPassIndex SUB_PASS_IDX = renderable->GetMaterial()->GetBaseMaterial()->GetPipeline()->GetPipelineState().GetSubpassIndex(); + const Handle SUBPASS = renderable->GetMaterial()->GetBaseMaterial()->GetPipeline()->GetPipelineState().GetSubpass(); // Check if there is a SuperBatch for the specific RenderPass - auto superBatch = std::find_if(superBatches.begin(), superBatches.end(), [&](const SHSuperBatch& superBatch) + auto superBatch = std::find_if(superBatches.begin(), superBatches.end(), [&](Handle superBatch) { - return superBatch.GetSubpassId() == SUB_PASS_IDX; + return superBatch->GetSubpass() == SUBPASS; }); // Remove if it exists if (superBatch == superBatches.end()) + { + SHLOG_WARNING("A renderable was attempted to be removed from a SuperBatch which does not exist."); return; + } - superBatch->Remove(renderable); + (*superBatch)->Remove(renderable); } void SHBatcher::FinaliseBatches(Handle device, Handle cmdBuffer) @@ -93,7 +96,7 @@ namespace SHADE // Build SuperBatches for (auto& batch : superBatches) { - batch.Build(device, cmdBuffer); + batch->Build(device, cmdBuffer); } } @@ -101,9 +104,23 @@ namespace SHADE { for (auto& batch : superBatches) { - batch.Clear(); + batch->Clear(); } superBatches.clear(); } + void SHBatcher::RegisterSuperBatch(Handle superBatch) + { + superBatches.emplace_back(superBatch); + } + + void SHBatcher::DeregisterSuperBatch(Handle superBatch) + { + auto sbIter = std::find(superBatches.begin(), superBatches.end(), superBatch); + if (sbIter == superBatches.end()) + return; + + superBatches.erase(sbIter); + } + } diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatcher.h b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatcher.h index ccbbd1d0..60cc0c56 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatcher.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatcher.h @@ -43,21 +43,23 @@ namespace SHADE /*-----------------------------------------------------------------------------*/ /* Lifecycle Functions */ /*-----------------------------------------------------------------------------*/ - void Init(const std::vector& _renderables, Handle _renderGraph); + void Init(Handle _renderGraph); /*-----------------------------------------------------------------------------*/ /* Usage Functions */ /*-----------------------------------------------------------------------------*/ void PrepareBatches(); - void AddToBatch(Handle renderable); - void RemoveFromBatch(Handle renderable); + void AddToBatch(SHRenderable const* renderable); + void RemoveFromBatch(SHRenderable const* renderable); void FinaliseBatches(Handle device, Handle cmdBuffer); void ClearBatches(); + void RegisterSuperBatch(Handle superBatch); + void DeregisterSuperBatch(Handle superBatch); private: const std::vector* renderables = nullptr; Handle renderGraph; // Children - std::vector superBatches; + std::vector> superBatches; }; } \ No newline at end of file diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.cpp index 34887b12..4d05dec7 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.cpp @@ -23,8 +23,8 @@ namespace SHADE /* Constructor/Destructors */ /*---------------------------------------------------------------------------------*/ - SHSuperBatch::SHSuperBatch(SHSubPassIndex subPass) - : subpassIndex { subPass } + SHSuperBatch::SHSuperBatch(Handle sp) + : subpass { sp } {} /*---------------------------------------------------------------------------------*/ diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.h b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.h index dbae5bc9..f70fd6d3 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.h @@ -47,7 +47,7 @@ namespace SHADE /*-----------------------------------------------------------------------------*/ /* Constructor/Destructors */ /*-----------------------------------------------------------------------------*/ - SHSuperBatch(SHSubPassIndex subPass); + SHSuperBatch(Handle sp); /*-----------------------------------------------------------------------------*/ /* Usage Functions */ @@ -61,16 +61,15 @@ namespace SHADE /*-----------------------------------------------------------------------------*/ /* Getter Functions */ /*-----------------------------------------------------------------------------*/ - SHSubPassIndex GetSubpassId() const noexcept { return subpassIndex; }; + Handle GetSubpass() const noexcept { return subpass; }; private: /*-----------------------------------------------------------------------------*/ /* Data Members */ /*-----------------------------------------------------------------------------*/ // Batch Properties - SHSubPassIndex subpassIndex; + Handle subpass; // Children std::vector batches; }; } - diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp index fdbf1753..09177993 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp @@ -24,6 +24,9 @@ of DigiPen Institute of Technology is prohibited. #include "Graphics/Pipeline/SHVkPipeline.h" #include "Graphics/MiddleEnd/Interface/SHMaterial.h" #include "Graphics/MiddleEnd/Interface/SHMaterialInstance.h" +#include "ECS_Base/Managers/SHComponentManager.h" +#include "Graphics/MiddleEnd/Interface/SHRenderable.h" +#include "Graphics/MiddleEnd/Batching/SHSuperBatch.h" namespace SHADE { @@ -322,7 +325,7 @@ namespace SHADE viewports.erase(iter); } - Handle SHGraphicsSystem::AddMaterial(Handle vertShader, Handle fragShader, Handle subpass) + Handle SHGraphicsSystem::AddMaterial(Handle vertShader, Handle fragShader, Handle subpass) { // Retrieve pipeline from pipeline storage or create if unavailable auto shaderPair = std::make_pair(vertShader, fragShader); @@ -331,7 +334,7 @@ namespace SHADE auto mat = resourceManager.Create(); auto renderGraphNode = subpass->GetParentNode(); - auto pipeline = renderGraphNode->GetOrCreatePipeline(std::make_pair(vertShader, fragShader), subpass->GetIndex()); + auto pipeline = renderGraphNode->GetOrCreatePipeline(std::make_pair(vertShader, fragShader), subpass); mat->SetPipeline(pipeline); @@ -449,10 +452,27 @@ namespace SHADE { reinterpret_cast(system)->Run(dt); } - + void SHGraphicsSystem::EndRoutine::Execute(double) noexcept { reinterpret_cast(system)->EndRender(); } + void SHGraphicsSystem::BatcherDispatcherRoutine::Execute(double) noexcept + { + auto& renderables = SHComponentManager::GetDense(); + for (auto& renderable : renderables) + { + if (!renderable.WasMaterialChanged()) + continue; + + // Remove from old material's SuperBatch + Handle oldSuperBatch = renderable.GetPrevMaterial()->GetPipeline()->GetPipelineState().GetSubpass()->GetSuperBatch(); + oldSuperBatch->Remove(&renderable); + + // Add to new SuperBatch + Handle newSuperBatch = renderable.GetMaterial()->GetBaseMaterial()->GetPipeline()->GetPipelineState().GetSubpass()->GetSuperBatch(); + newSuperBatch->Add(&renderable); + } + } } diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h index af8e98a6..1c1d7710 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h @@ -75,6 +75,11 @@ namespace SHADE public: virtual void Execute(double dt) noexcept override final; }; + class SH_API BatcherDispatcherRoutine final : public SHSystemRoutine + { + public: + virtual void Execute(double dt) noexcept override final; + }; public: /*-----------------------------------------------------------------------------*/ @@ -110,7 +115,7 @@ namespace SHADE /*-----------------------------------------------------------------------------*/ /* Material Creation Functions */ /*-----------------------------------------------------------------------------*/ - Handle AddMaterial(Handle vertShader, Handle fragShader, Handle subpass); + Handle AddMaterial(Handle vertShader, Handle fragShader, Handle subpass); void RemoveMaterial(Handle material);; Handle AddMaterialInstance(Handle material); void RemoveMaterialInstance(Handle materialInstance); diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderable.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderable.cpp index eb59ee14..bf681a81 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderable.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderable.cpp @@ -18,7 +18,19 @@ of DigiPen Institute of Technology is prohibited. namespace SHADE { - void SHRenderable::SetMaterial(Handle materialInstance) + /*-----------------------------------------------------------------------------------*/ + /* SHComponent Lifecycle Functions */ + /*-----------------------------------------------------------------------------------*/ + void SHRenderable::OnCreate() + { + materialChanged = true; + sharedMaterial = {}; + material = {}; + oldMaterial = {}; + + } + + void SHRenderable::OnDestroy() { if (material) { @@ -26,7 +38,33 @@ namespace SHADE material = {}; } - sharedMaterial = materialInstance; + // Remove from SuperBatch + Handle superBatch = sharedMaterial->GetBaseMaterial()->GetPipeline()->GetPipelineState().GetSubpass()->GetSuperBatch(); + superBatch->Remove(this); + } + + /*-----------------------------------------------------------------------------------*/ + /* Material Functions */ + /*-----------------------------------------------------------------------------------*/ + void SHRenderable::SetMaterial(Handle materialInstance) + { + // Ignore if same material set + if (!material && sharedMaterial == materialInstance) + return; + + // Free copies of materials if any + if (material) + { + material.Free(); + material = {}; + } + + // Flag that material was changed + materialChanged = true; + oldMaterial = sharedMaterial->GetBaseMaterial(); + + // Update the material + sharedMaterial = materialInstance; } Handle SHRenderable::GetMaterial() const diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderable.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderable.h index 4d85abd8..eda27925 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderable.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderable.h @@ -23,6 +23,7 @@ namespace SHADE /* Forward Declarations */ /*-----------------------------------------------------------------------------------*/ class SHMaterialInstance; + class SHMaterial; class SHMesh; /*-----------------------------------------------------------------------------------*/ /* Type Definitions */ @@ -33,16 +34,28 @@ namespace SHADE Represents an object that should be rendered. */ /*************************************************************************************/ - class SHRenderable : public SHComponent, public ISelfHandle + class SHRenderable final : public SHComponent { public: /*-------------------------------------------------------------------------------*/ - /* Usage Functions */ + /* SHComponent Lifecycle Functions */ /*-------------------------------------------------------------------------------*/ - void SetMaterial(Handle materialInstance); + void OnCreate() override final; + void OnDestroy() override final; + + /*-------------------------------------------------------------------------------*/ + /* Material Functions */ + /*-------------------------------------------------------------------------------*/ + void SetMaterial(Handle materialInstance); Handle GetMaterial() const; Handle GetModifiableMaterial(); + /*-------------------------------------------------------------------------------*/ + /* Getter Functions */ + /*-------------------------------------------------------------------------------*/ + bool WasMaterialChanged() const noexcept { return materialChanged; } + Handle GetPrevMaterial() const noexcept { return oldMaterial; } + /*-------------------------------------------------------------------------------*/ /* Data Members */ /*-------------------------------------------------------------------------------*/ @@ -55,6 +68,8 @@ namespace SHADE /*-------------------------------------------------------------------------------*/ Handle sharedMaterial; Handle material; + bool materialChanged = true; + Handle oldMaterial; }; } diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Pipeline/SHPipelineLibrary.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Pipeline/SHPipelineLibrary.cpp index 7e9c2cbd..636b8e68 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Pipeline/SHPipelineLibrary.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Pipeline/SHPipelineLibrary.cpp @@ -5,7 +5,7 @@ namespace SHADE { - Handle SHPipelineLibrary::CreateDrawPipeline(std::pair, Handle> const& vsFsPair, Handle renderpass, uint32_t subpass) noexcept + Handle SHPipelineLibrary::CreateDrawPipeline(std::pair, Handle> const& vsFsPair, Handle renderpass, Handle subpass) noexcept { SHPipelineLayoutParams params { diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Pipeline/SHPipelineLibrary.h b/SHADE_Engine/src/Graphics/MiddleEnd/Pipeline/SHPipelineLibrary.h index c2a5a916..8f41781a 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Pipeline/SHPipelineLibrary.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Pipeline/SHPipelineLibrary.h @@ -9,6 +9,7 @@ namespace SHADE class SHVRenderpass; class SHVkDescriptorSetLayouts; class SHVkPipeline; + class SHSubpass; // Pipeline library is a PURELY MIDDLE END SYSTEM. It is responsible for only creating pipelines from shaders and caching @@ -37,7 +38,7 @@ namespace SHADE Handle CreateDrawPipeline ( std::pair, Handle> const& vsFsPair, Handle renderpass, - uint32_t subpass + Handle subpass ) noexcept; Handle GetDrawPipline (std::pair, Handle> const& vsFsPair) noexcept; bool CheckDrawPipelineExistence (std::pair, Handle> const& vsFsPair) noexcept; diff --git a/SHADE_Engine/src/Graphics/Pipeline/SHPipelineState.cpp b/SHADE_Engine/src/Graphics/Pipeline/SHPipelineState.cpp index 0b4f033f..e7c245db 100644 --- a/SHADE_Engine/src/Graphics/Pipeline/SHPipelineState.cpp +++ b/SHADE_Engine/src/Graphics/Pipeline/SHPipelineState.cpp @@ -1,5 +1,6 @@ #include "SHPch.h" #include "SHPipelineState.h" +#include "Graphics/RenderGraph/SHRenderGraph.h" namespace SHADE { @@ -61,10 +62,10 @@ namespace SHADE renderpassHdl = inRenderpassHdl; } - void SHVkPipelineState::SetSubpassIndex(uint32_t index) noexcept + void SHVkPipelineState::SetSubpass(Handle sp) noexcept { dirty = true; - subpassIndex = index; + subpass = sp; } SHVertexInputState const& SHVkPipelineState::GetVertexInputState(void) const noexcept @@ -107,9 +108,9 @@ namespace SHADE return renderpassHdl; } - SHSubPassIndex SHVkPipelineState::GetSubpassIndex(void) const noexcept + Handle SHVkPipelineState::GetSubpass(void) noexcept { - return subpassIndex; + return subpass; } void SHVkPipelineState::SetDirty(bool isDirty) noexcept diff --git a/SHADE_Engine/src/Graphics/Pipeline/SHPipelineState.h b/SHADE_Engine/src/Graphics/Pipeline/SHPipelineState.h index 08c35060..559ccc88 100644 --- a/SHADE_Engine/src/Graphics/Pipeline/SHPipelineState.h +++ b/SHADE_Engine/src/Graphics/Pipeline/SHPipelineState.h @@ -8,6 +8,8 @@ namespace SHADE { + class SHSubpass; + // This is mainly for non-interleaved attributes where we have a separate buffer for // each vertex attribute. struct SHVertexInputState @@ -152,31 +154,31 @@ namespace SHADE bool dirty{ false }; //! Vertex input state - SHVertexInputState vertexInputState; + SHVertexInputState vertexInputState; //! Input assembly - SHInputAssemblyState inputAssemblyState; + SHInputAssemblyState inputAssemblyState; //! Rasterization state - SHRasterizationState rasterizationState; + SHRasterizationState rasterizationState; //! Viewport state - SHViewportState viewportState; + SHViewportState viewportState; //! Multisample state - SHMultisampleState multisampleState; + SHMultisampleState multisampleState; //! Depth Stencil state - SHDepthStencilState depthStencilState; + SHDepthStencilState depthStencilState; //! Color blend state - SHColorBlendState colorBlendState; + SHColorBlendState colorBlendState; //! Renderpass that is compatible with the pipeline - Handle renderpassHdl; + Handle renderpassHdl; //! Subpass index - uint32_t subpassIndex; + Handle subpass; friend class SHVkPipeline; public: @@ -198,17 +200,17 @@ namespace SHADE void SetDepthStencilState (SHDepthStencilState const& state) noexcept; void SetColorBlenState (SHColorBlendState const& state) noexcept; void SetRenderpass (Handle const& inRenderpassHdl) noexcept; - void SetSubpassIndex (uint32_t index) noexcept; + void SetSubpass (Handle sp) noexcept; - SHVertexInputState const& GetVertexInputState (void) const noexcept; - SHInputAssemblyState const& GetInputAssemblyState (void) const noexcept; - SHRasterizationState const& GetRasterizationState (void) const noexcept; - SHViewportState const& GetViewportState (void) const noexcept; - SHMultisampleState const& GetMultisampleState (void) const noexcept; - SHDepthStencilState const& GetDepthStencilState (void) const noexcept; - SHColorBlendState const& GetColorBlenState (void) const noexcept; - Handle const& GetRenderpass (void) const noexcept; - SHSubPassIndex GetSubpassIndex (void) const noexcept; + SHVertexInputState const& GetVertexInputState (void) const noexcept; + SHInputAssemblyState const& GetInputAssemblyState (void) const noexcept; + SHRasterizationState const& GetRasterizationState (void) const noexcept; + SHViewportState const& GetViewportState (void) const noexcept; + SHMultisampleState const& GetMultisampleState (void) const noexcept; + SHDepthStencilState const& GetDepthStencilState (void) const noexcept; + SHColorBlendState const& GetColorBlenState (void) const noexcept; + Handle const& GetRenderpass (void) const noexcept; + Handle GetSubpass (void) noexcept; void SetDirty(bool isDirty) noexcept; }; diff --git a/SHADE_Engine/src/Graphics/Pipeline/SHVkPipeline.cpp b/SHADE_Engine/src/Graphics/Pipeline/SHVkPipeline.cpp index 263ae578..6a20ab55 100644 --- a/SHADE_Engine/src/Graphics/Pipeline/SHVkPipeline.cpp +++ b/SHADE_Engine/src/Graphics/Pipeline/SHVkPipeline.cpp @@ -3,6 +3,7 @@ #include "Graphics/Devices/SHVkLogicalDevice.h" #include "Graphics/Shaders/SHVkShaderModule.h" #include "Graphics/Debugging/SHVulkanDebugUtil.h" +#include "Graphics/RenderGraph/SHRenderGraph.h" namespace SHADE { @@ -154,7 +155,7 @@ namespace SHADE gpCreateInfo.layout = pipelineLayout->GetVkPipelineLayout(); gpCreateInfo.renderPass = pipelineState.GetRenderpass()->GetVkRenderpass(); - gpCreateInfo.subpass = pipelineState.GetSubpassIndex(); + gpCreateInfo.subpass = pipelineState.GetSubpass()->GetIndex(); gpCreateInfo.basePipelineHandle = VK_NULL_HANDLE; gpCreateInfo.basePipelineIndex = -1; @@ -204,7 +205,7 @@ namespace SHADE */ /***************************************************************************/ - SHVkPipeline::SHVkPipeline(Handle const& inLogicalDeviceHdl, Handle const& inPipelineLayout, SHVkPipelineState const* const state, Handle const& renderpassHdl, uint32_t subpass, SH_PIPELINE_TYPE type) noexcept + SHVkPipeline::SHVkPipeline(Handle const& inLogicalDeviceHdl, Handle const& inPipelineLayout, SHVkPipelineState const* const state, Handle const& renderpassHdl, Handle subpass, SH_PIPELINE_TYPE type) noexcept : pipelineState{ } // copy the pipeline state , pipelineType {type} , vkPipeline {VK_NULL_HANDLE} @@ -222,8 +223,8 @@ namespace SHADE } else { - pipelineState.SetRenderpass(renderpassHdl); - pipelineState.SetSubpassIndex(subpass); + pipelineState.SetRenderpass (renderpassHdl); + pipelineState.SetSubpass (subpass); } } diff --git a/SHADE_Engine/src/Graphics/Pipeline/SHVkPipeline.h b/SHADE_Engine/src/Graphics/Pipeline/SHVkPipeline.h index 9a9d78f4..6edf0e98 100644 --- a/SHADE_Engine/src/Graphics/Pipeline/SHVkPipeline.h +++ b/SHADE_Engine/src/Graphics/Pipeline/SHVkPipeline.h @@ -9,6 +9,7 @@ namespace SHADE { class SHVkLogicalDevice; + class SHSubpass; class SHVkPipeline { @@ -50,7 +51,7 @@ namespace SHADE Handle const& inPipelineLayout, SHVkPipelineState const* const state, Handle const& renderpassHdl, - uint32_t subpass, + Handle subpass, SH_PIPELINE_TYPE type) noexcept; SHVkPipeline (SHVkPipeline&& rhs) noexcept; diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp index ba456b78..1c995e12 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp @@ -209,13 +209,13 @@ namespace SHADE */ /***************************************************************************/ - SHRenderGraphNode::SHSubpass::SHSubpass(Handle const& parent, uint32_t index, std::unordered_map const* mapping, std::unordered_map> const* resources) noexcept + SHSubpass::SHSubpass(ResourceManager& rm, Handle const& parent, uint32_t index, std::unordered_map const* mapping, std::unordered_map> const* resources) noexcept : resourceAttachmentMapping{ mapping } , ptrToResources{ resources } , parentNode{ parent } , subpassIndex {index} { - + superBatch = rm.Create(GetHandle()); } /***************************************************************************/ @@ -229,7 +229,7 @@ namespace SHADE */ /***************************************************************************/ - SHRenderGraphNode::SHSubpass::SHSubpass(SHSubpass&& rhs) noexcept + SHSubpass::SHSubpass(SHSubpass&& rhs) noexcept : colorReferences{ std::move(rhs.colorReferences) } , depthReferences{ std::move(rhs.depthReferences) } , inputReferences{ std::move(rhs.inputReferences) } @@ -250,7 +250,7 @@ namespace SHADE */ /***************************************************************************/ - SHRenderGraphNode::SHSubpass& SHRenderGraphNode::SHSubpass::operator=(SHSubpass&& rhs) noexcept + SHSubpass& SHSubpass::operator=(SHSubpass&& rhs) noexcept { if (this == &rhs) return *this; @@ -276,7 +276,7 @@ namespace SHADE */ /***************************************************************************/ - void SHRenderGraphNode::SHSubpass::AddColorOutput(std::string resourceToReference) noexcept + void SHSubpass::AddColorOutput(std::string resourceToReference) noexcept { colorReferences.push_back({ resourceAttachmentMapping->at(ptrToResources->at(resourceToReference).GetId().Raw), vk::ImageLayout::eColorAttachmentOptimal }); } @@ -297,7 +297,7 @@ namespace SHADE */ /***************************************************************************/ - void SHRenderGraphNode::SHSubpass::AddDepthOutput(std::string resourceToReference, SH_ATT_DESC_TYPE attachmentDescriptionType) noexcept + void SHSubpass::AddDepthOutput(std::string resourceToReference, SH_ATT_DESC_TYPE attachmentDescriptionType) noexcept { vk::ImageLayout imageLayout; switch (attachmentDescriptionType) @@ -330,12 +330,12 @@ namespace SHADE */ /***************************************************************************/ - void SHRenderGraphNode::SHSubpass::AddInput(std::string resourceToReference) noexcept + void SHSubpass::AddInput(std::string resourceToReference) noexcept { inputReferences.push_back({ resourceAttachmentMapping->at(ptrToResources->at(resourceToReference).GetId().Raw), vk::ImageLayout::eShaderReadOnlyOptimal }); } - void SHRenderGraphNode::SHSubpass::Execute(Handle& commandBuffer) noexcept + void SHSubpass::Execute(Handle& commandBuffer) noexcept { // Draw all the batches @@ -346,7 +346,7 @@ namespace SHADE } } - void SHRenderGraphNode::SHSubpass::AddExteriorDrawCalls(std::function&)> const& newDrawCall) noexcept + void SHSubpass::AddExteriorDrawCalls(std::function&)> const& newDrawCall) noexcept { exteriorDrawCalls.push_back(newDrawCall); } @@ -362,16 +362,21 @@ namespace SHADE */ /***************************************************************************/ - Handle const& SHRenderGraphNode::SHSubpass::GetParentNode(void) const noexcept + Handle const& SHSubpass::GetParentNode(void) const noexcept { return parentNode; } - SHADE::SHSubPassIndex SHRenderGraphNode::SHSubpass::GetIndex() const noexcept + SHADE::SHSubPassIndex SHSubpass::GetIndex() const noexcept { return subpassIndex; } + Handle SHSubpass::GetSuperBatch(void) const noexcept + { + return superBatch; + } + /***************************************************************************/ /*! @@ -544,7 +549,7 @@ namespace SHADE */ /***************************************************************************/ - Handle SHRenderGraphNode::AddSubpass(std::string subpassName) noexcept + Handle SHRenderGraphNode::AddSubpass(std::string subpassName) noexcept { // if subpass already exists, don't add. if (subpassIndexing.contains(subpassName)) @@ -554,7 +559,7 @@ namespace SHADE } // Add subpass to container and create mapping for it - subpasses.emplace_back(resourceManager.Create(GetHandle(), subpasses.size(), &resourceAttachmentMapping, ptrToResources)); + subpasses.emplace_back(resourceManager.Create(resourceManager, GetHandle(), subpasses.size(), &resourceAttachmentMapping, ptrToResources)); subpassIndexing.try_emplace(subpassName, static_cast(subpasses.size()) - 1u); return subpasses.at(subpassIndexing[subpassName]); } @@ -576,10 +581,10 @@ namespace SHADE commandBuffer->EndRenderpass(); } - Handle SHRenderGraphNode::GetOrCreatePipeline(std::pair, Handle> const& vsFsPair, uint32_t subpassIndex) noexcept + Handle SHRenderGraphNode::GetOrCreatePipeline(std::pair, Handle> const& vsFsPair, Handle subpass) noexcept { // verify subpass exists - if (subpassIndex >= subpasses.size() - 1) + if (subpass->GetIndex() >= subpasses.size() - 1) { SHLOG_ERROR("Subpass index passed in is not valid. RenderGraphNode does not have that many passes. "); return {}; @@ -592,7 +597,7 @@ namespace SHADE ( vsFsPair, renderpass, - subpassIndex + subpass ); } @@ -615,7 +620,7 @@ namespace SHADE return renderpass; } - Handle SHRenderGraphNode::GetSubpass(std::string_view subpassName) const noexcept + Handle SHRenderGraphNode::GetSubpass(std::string_view subpassName) const noexcept { return subpasses[subpassIndexing.at(subpassName.data())]; } diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h index 3353e0a0..f563841e 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h @@ -5,6 +5,7 @@ #include "Resource/ResourceLibrary.h" #include "SH_API.h" #include "Graphics/MiddleEnd/Pipeline/SHPipelineLibrary.h" +#include "Graphics/MiddleEnd/Batching/SHSuperBatch.h" #include #include @@ -19,6 +20,7 @@ namespace SHADE class SHVkFramebuffer; class SHVkCommandPool; class SHVkCommandBuffer; + class SHRenderGraphNode; // Used for attachment description creation for renderpass node enum class SH_ATT_DESC_TYPE @@ -30,6 +32,7 @@ namespace SHADE DEPTH_STENCIL, }; + class SH_API SHRenderGraphResource { private: @@ -70,7 +73,78 @@ namespace SHADE SHRenderGraphResource(Handle const& logicalDevice, Handle const& swapchain, std::string const& name, SH_ATT_DESC_TYPE type, vk::Format format, uint32_t w, uint32_t h, uint8_t levels, vk::ImageCreateFlagBits createFlags) noexcept; SHRenderGraphResource(SHRenderGraphResource&& rhs) noexcept; SHRenderGraphResource& operator=(SHRenderGraphResource&& rhs) noexcept; - ~SHRenderGraphResource (void) noexcept; + ~SHRenderGraphResource(void) noexcept; + + friend class SHRenderGraphNode; + friend class SHRenderGraph; + }; + + + class SH_API SHSubpass : public ISelfHandle + { + private: + /*---------------------------------------------------------------------*/ + /* PRIVATE MEMBER VARIABLES */ + /*---------------------------------------------------------------------*/ + //! The index of the subpass in the render graph + uint32_t subpassIndex; + + //! The parent renderpass that this subpass belongs to + Handle parentNode; + + //! + Handle superBatch; + + //! Color attachments + std::vector colorReferences; + + //! Depth attachments + std::vector depthReferences; + + //! Input attachments + std::vector inputReferences; + + //! For getting attachment reference indices using handles + std::unordered_map const* resourceAttachmentMapping; + + //! Pointer to resources in the render graph (for getting handle IDs) + std::unordered_map> const* ptrToResources; + + //! Sometimes there exists entities that we want to render onto a render target + //! but don't want it to come from the batching system. An example would be ImGUI. + //! For these entities we want to link a function from the outside and draw them + //! after we draw everything from the batch. Because of this, these draw calls + //! are always the last things drawn, so DO NOT USE THIS FUNCTIONALITY FOR ANYTHING + //! COMPLEX. + std::vector&)>> exteriorDrawCalls; + + public: + /*-----------------------------------------------------------------------*/ + /* CTORS AND DTORS */ + /*-----------------------------------------------------------------------*/ + SHSubpass(ResourceManager& rm, Handle const& parent, uint32_t index, std::unordered_map const* mapping, std::unordered_map> const* ptrToResources) noexcept; + SHSubpass(SHSubpass&& rhs) noexcept; + SHSubpass& operator=(SHSubpass&& rhs) noexcept; + + /*-----------------------------------------------------------------------*/ + /* PUBLIC MEMBER FUNCTIONS */ + /*-----------------------------------------------------------------------*/ + // Preparation functions + void AddColorOutput(std::string resourceToReference) noexcept; + void AddDepthOutput(std::string resourceToReference, SH_ATT_DESC_TYPE attachmentDescriptionType = SH_ATT_DESC_TYPE::DEPTH_STENCIL) noexcept; + void AddInput(std::string resourceToReference) noexcept; + + // Runtime functions + void Execute(Handle& commandBuffer) noexcept; + void AddExteriorDrawCalls(std::function&)> const& newDrawCall) noexcept; + + /*-----------------------------------------------------------------------*/ + /* GETTERS AND SETTERS */ + /*-----------------------------------------------------------------------*/ + Handle const& GetParentNode(void) const noexcept; + SHSubPassIndex GetIndex() const noexcept; + Handle GetSuperBatch (void) const noexcept; + friend class SHRenderGraphNode; friend class SHRenderGraph; @@ -78,74 +152,6 @@ namespace SHADE class SH_API SHRenderGraphNode : public ISelfHandle { - public: - - class SH_API SHSubpass - { - public: - /*-----------------------------------------------------------------------*/ - /* CTORS AND DTORS */ - /*-----------------------------------------------------------------------*/ - SHSubpass(Handle const& parent, uint32_t index, std::unordered_map const* mapping, std::unordered_map> const* ptrToResources) noexcept; - SHSubpass(SHSubpass&& rhs) noexcept; - SHSubpass& operator=(SHSubpass&& rhs) noexcept; - - /*-----------------------------------------------------------------------*/ - /* PUBLIC MEMBER FUNCTIONS */ - /*-----------------------------------------------------------------------*/ - // Preparation functions - void AddColorOutput (std::string resourceToReference) noexcept; - void AddDepthOutput (std::string resourceToReference, SH_ATT_DESC_TYPE attachmentDescriptionType = SH_ATT_DESC_TYPE::DEPTH_STENCIL) noexcept; - void AddInput (std::string resourceToReference) noexcept; - - // Runtime functions - void Execute (Handle& commandBuffer) noexcept; - void AddExteriorDrawCalls (std::function&)> const& newDrawCall) noexcept; - - /*-----------------------------------------------------------------------*/ - /* GETTERS AND SETTERS */ - /*-----------------------------------------------------------------------*/ - Handle const& GetParentNode (void) const noexcept; - SHSubPassIndex GetIndex() const noexcept; - - private: - /*---------------------------------------------------------------------*/ - /* PRIVATE MEMBER VARIABLES */ - /*---------------------------------------------------------------------*/ - //! The index of the subpass in the render graph - uint32_t subpassIndex; - - //! The parent renderpass that this subpass belongs to - Handle parentNode; - - //! Color attachments - std::vector colorReferences; - - //! Depth attachments - std::vector depthReferences; - - //! Input attachments - std::vector inputReferences; - - //! For getting attachment reference indices using handles - std::unordered_map const* resourceAttachmentMapping; - - //! Pointer to resources in the render graph (for getting handle IDs) - std::unordered_map> const* ptrToResources; - - //! Sometimes there exists entities that we want to render onto a render target - //! but don't want it to come from the batching system. An example would be ImGUI. - //! For these entities we want to link a function from the outside and draw them - //! after we draw everything from the batch. Because of this, these draw calls - //! are always the last things drawn, so DO NOT USE THIS FUNCTIONALITY FOR ANYTHING - //! COMPLEX. - std::vector&)>> exteriorDrawCalls; - - - friend class SHRenderGraphNode; - friend class SHRenderGraph; - }; - private: /*-----------------------------------------------------------------------*/ /* PRIVATE MEMBER VARIABLES */ @@ -219,7 +225,7 @@ namespace SHADE /*-----------------------------------------------------------------------*/ Handle AddSubpass (std::string subpassName) noexcept; void Execute (Handle& commandBuffer, uint32_t frameIndex) noexcept; - Handle GetOrCreatePipeline (std::pair, Handle> const& vsFsPair, uint32_t subpassIndex) noexcept; + Handle GetOrCreatePipeline (std::pair, Handle> const& vsFsPair, Handle subpass) noexcept; /*-----------------------------------------------------------------------*/ /* SETTERS AND GETTERS */