diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp index 98c897f3..19a24e0c 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp @@ -262,7 +262,7 @@ namespace SHADE /*-----------------------------------------------------------------------*/ // Shadow map pass will have no resources bound at first. Lighting system will add resources to the node. // It will initially also not have any subpasses since they will be added for each light that casts shadows. - auto shadowMapPass = renderGraph->AddNode(SHGraphicsConstants::RenderGraphNodeNames::SHADOW_MAP_PASS.data(), {}, {}); + auto shadowMapPassNode = renderGraph->AddNode(SHGraphicsConstants::RenderGraphNodeNames::SHADOW_MAP_PASS.data(), {}, {}); /*-----------------------------------------------------------------------*/ /* DEFERRED COMPOSITE NODE */ @@ -279,17 +279,16 @@ namespace SHADE }, { SHGraphicsConstants::RenderGraphNodeNames::GBUFFER_PASS .data()}); - // Add subpass with exterior draw call to transition shadow maps - //auto shadowMapTransitionSubpass = deferredCompositeNode->AddSubpass("Shadow Map Transition", {}, {}); - //shadowMapTransitionSubpass->AddExteriorDrawCalls([=](Handle cmdBuffer, Handle renderer, uint32_t frameIndex) - // { - // lightingSubSystem->PrepareShadowMapsForRead(cmdBuffer); - // }); /*-----------------------------------------------------------------------*/ /* DEFERRED COMPOSITE SUBPASS INIT */ /*-----------------------------------------------------------------------*/ - deferredCompositeNode->AddNodeCompute("Deferred Composite", deferredCompositeShader, { "Position", "Normals", "Albedo", "Light Layer Indices", "SSAO Blur", "Scene" }); + auto deferredCompositeCompute = deferredCompositeNode->AddNodeCompute("Deferred Composite", deferredCompositeShader, { "Position", "Normals", "Albedo", "Light Layer Indices", "SSAO Blur", "Scene" }); + deferredCompositeCompute->AddPreComputeFunction([=](Handle cmdBuffer, uint32_t frameIndex) + { + lightingSubSystem->PrepareShadowMapsForRead(cmdBuffer); + }); + /*-----------------------------------------------------------------------*/ /* DEBUG DRAW PASS INIT */ diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.cpp index 122f41da..cf4623e6 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.cpp @@ -129,20 +129,25 @@ namespace SHADE if (subpasses.empty()) return; + uint32_t numValidSubpasses = std::count_if(subpasses.begin(), subpasses.end(), [](Handle subpass) {return !subpass->HasNoAttachments();}); + // Create subpass description and dependencies based on number of subpasses - spDescs.resize(subpasses.size()); - spDeps.resize(subpasses.size()); + spDescs.resize(numValidSubpasses); + spDeps.resize(numValidSubpasses); // Now we want to loop through all attachments in all subpasses in the node and query // the resources being used. For each resource we want to query the type and record it // in bit fields (1 bit for each subpass). uint32_t colorRead = 0, colorWrite = 0, depthRead = 0, depthWrite = 0, inputDependencies = 0; - uint32_t i = 0; // For all subpasses (see above description about bit field for this). - for (auto& subpass : subpasses) + for (uint32_t i = 0; auto& subpass : subpasses) { + // skip if subpass is not valid + if (subpass->HasNoAttachments()) + continue; + // Configure subpass description auto& desc = spDescs[i]; desc.pColorAttachments = subpass->colorReferences.data(); @@ -198,8 +203,11 @@ namespace SHADE // Loop through all subpasses again but this time we use the bit field to initialize // the dependencies. - for (i = 0; i < subpasses.size(); ++i) + for (uint32_t i = 0; auto & subpass : subpasses) { + if (subpass->HasNoAttachments()) + continue; + vk::PipelineStageFlags srcStage; vk::PipelineStageFlags dstStage; vk::AccessFlags srcAccess; @@ -257,6 +265,8 @@ namespace SHADE // initialize input descriptors subpasses[i]->CreateInputDescriptors(); + + ++i; } } @@ -639,7 +649,7 @@ namespace SHADE subpasses[i]->Execute(commandBuffer, descPool, frameIndex); // Go to next subpass if not last subpass - if (i != static_cast(subpasses.size()) - 1u) + if (i != static_cast(subpasses.size()) - 1u && !subpasses[i]->HasNoAttachments()) commandBuffer->NextSubpass(); } diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNodeCompute.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNodeCompute.cpp index fd46cfe7..55f8a9c9 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNodeCompute.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNodeCompute.cpp @@ -152,6 +152,11 @@ namespace SHADE void SHRenderGraphNodeCompute::Execute(Handle cmdBuffer, uint32_t frameIndex) noexcept { + for (auto& fn : preComputeFunctions) + { + fn (cmdBuffer, frameIndex); + } + // bind the compute pipeline cmdBuffer->BindPipeline(computePipeline); @@ -252,4 +257,9 @@ namespace SHADE } + void SHRenderGraphNodeCompute::AddPreComputeFunction(PreComputeFunction const& fn) noexcept + { + preComputeFunctions.push_back(fn); + } + } diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNodeCompute.h b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNodeCompute.h index 5f68cf2c..9352f1d9 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNodeCompute.h +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNodeCompute.h @@ -25,6 +25,10 @@ namespace SHADE class SHRenderGraphNodeCompute { + public: + using PreComputeFunction = std::function, uint32_t)>; + + private: // Binding of set SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_NODE_COMPUTE_RESOURCE struct ComputeResource @@ -73,6 +77,9 @@ namespace SHADE //! Name of this node std::string name; + std::vector preComputeFunctions; + + private: /*-----------------------------------------------------------------------*/ /* PRIVATE MEMBER FUNCTIONS */ @@ -97,6 +104,7 @@ namespace SHADE void ModifyWriteDescBufferComputeResource (uint32_t binding, std::span> const& buffers, uint32_t offset, uint32_t range) noexcept; void ModifyWriteDescImageComputeResource(uint32_t binding, std::span const& viewSamplerLayouts) noexcept; + void AddPreComputeFunction (PreComputeFunction const& fn) noexcept; friend class SHRenderGraph; friend class SHRenderGraphNode; diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.cpp index 1f03bbc4..c7982906 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.cpp @@ -211,25 +211,28 @@ namespace SHADE { commandBuffer->BeginLabeledSegment(name); - // Ensure correct transforms are provided - superBatch->UpdateBuffers(frameIndex, descPool); - - if (viewport) + if (!HasNoAttachments()) { - // set viewport and scissor - uint32_t w = static_cast(viewport->GetWidth()); - uint32_t h = static_cast(viewport->GetHeight()); - commandBuffer->SetViewportScissor(static_cast(w), static_cast(h), w, h); + // Ensure correct transforms are provided + superBatch->UpdateBuffers(frameIndex, descPool); + + if (viewport) + { + // set viewport and scissor + uint32_t w = static_cast(viewport->GetWidth()); + uint32_t h = static_cast(viewport->GetHeight()); + commandBuffer->SetViewportScissor(static_cast(w), static_cast(h), w, h); + } + + auto const& descMappings = SHGraphicsPredefinedData::GetMappings(SHGraphicsPredefinedData::SystemType::BATCHING); + + if (renderer) + renderer->BindDescriptorSet(commandBuffer, SH_PIPELINE_TYPE::GRAPHICS, descMappings.at(SHPredefinedDescriptorTypes::CAMERA), frameIndex); + + // Draw all the batches + superBatch->Draw(commandBuffer, frameIndex); } - auto const& descMappings = SHGraphicsPredefinedData::GetMappings(SHGraphicsPredefinedData::SystemType::BATCHING); - - if (renderer) - renderer->BindDescriptorSet(commandBuffer, SH_PIPELINE_TYPE::GRAPHICS, descMappings.at(SHPredefinedDescriptorTypes::CAMERA), frameIndex); - - // Draw all the batches - superBatch->Draw(commandBuffer, frameIndex); - // Draw all the exterior draw calls for (auto& drawCall : exteriorDrawCalls) {