diff --git a/engine/CMakeLists.txt b/engine/CMakeLists.txt index 65830451..67b821e8 100644 --- a/engine/CMakeLists.txt +++ b/engine/CMakeLists.txt @@ -594,6 +594,8 @@ add_library(XCEngine STATIC ${CMAKE_CURRENT_SOURCE_DIR}/src/Rendering/Pipelines/BuiltinForwardPipeline.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/Rendering/Pipelines/Internal/BuiltinForwardSceneSetup.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/Rendering/Pipelines/Internal/BuiltinForwardPipelineFrame.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/src/Rendering/Pipelines/Internal/BuiltinForwardMainSceneGraphBuilder.h + ${CMAKE_CURRENT_SOURCE_DIR}/src/Rendering/Pipelines/Internal/BuiltinForwardMainSceneGraphBuilder.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/Rendering/Pipelines/Internal/BuiltinForwardPipelineLifecycle.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/Rendering/Pipelines/Internal/BuiltinForwardPipelineScenePhases.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/Rendering/Pipelines/Internal/BuiltinForwardPipelineSkybox.cpp diff --git a/engine/include/XCEngine/Rendering/Pipelines/BuiltinForwardPipeline.h b/engine/include/XCEngine/Rendering/Pipelines/BuiltinForwardPipeline.h index 53bc250e..49b176c0 100644 --- a/engine/include/XCEngine/Rendering/Pipelines/BuiltinForwardPipeline.h +++ b/engine/include/XCEngine/Rendering/Pipelines/BuiltinForwardPipeline.h @@ -39,6 +39,9 @@ namespace Rendering { class RenderSurface; namespace Pipelines { +namespace Internal { +struct BuiltinForwardMainSceneGraphBuilder; +} // namespace Internal } // namespace Pipelines namespace Pipelines { @@ -381,6 +384,8 @@ private: RHI::RHIResourceView* m_skyboxBoundPanoramicTextureView = nullptr; RHI::RHIResourceView* m_skyboxBoundCubemapTextureView = nullptr; SceneRenderFeatureHost m_forwardSceneFeatureHost; + + friend struct Internal::BuiltinForwardMainSceneGraphBuilder; }; class BuiltinForwardPipelineAsset final : public RenderPipelineAsset { diff --git a/engine/src/Rendering/Pipelines/Internal/BuiltinForwardMainSceneGraphBuilder.cpp b/engine/src/Rendering/Pipelines/Internal/BuiltinForwardMainSceneGraphBuilder.cpp new file mode 100644 index 00000000..1983722d --- /dev/null +++ b/engine/src/Rendering/Pipelines/Internal/BuiltinForwardMainSceneGraphBuilder.cpp @@ -0,0 +1,229 @@ +#include "Rendering/Pipelines/Internal/BuiltinForwardMainSceneGraphBuilder.h" + +#include "Debug/Logger.h" +#include "Rendering/Graph/RenderGraph.h" +#include "Rendering/Internal/RenderPassGraphUtils.h" +#include "Rendering/Pipelines/BuiltinForwardPipeline.h" +#include "Rendering/Pipelines/Internal/BuiltinForwardSceneSetup.h" +#include "Rendering/RenderSurface.h" + +#include +#include + +namespace XCEngine { +namespace Rendering { +namespace Pipelines { +namespace Internal { + +namespace { + +RenderSurface BuildGraphManagedForwardSceneSurface(const RenderSurface& templateSurface) { + RenderSurface surface = templateSurface; + surface.SetAutoTransitionEnabled(false); + return surface; +} + +struct ForwardSceneGraphExecutionState { + bool initialized = false; +}; + +Containers::String BuildForwardScenePhasePassName( + const Containers::String& baseName, + ScenePhase scenePhase) { + std::string name = baseName.CStr(); + name += '.'; + name += ToString(scenePhase); + return Containers::String(name.c_str()); +} + +bool ScenePhaseSamplesMainDirectionalShadow(ScenePhase scenePhase) { + return scenePhase == ScenePhase::Opaque || + scenePhase == ScenePhase::Transparent; +} + +} // namespace + +bool BuiltinForwardMainSceneGraphBuilder::Record( + BuiltinForwardPipeline& pipeline, + const RenderPipelineMainSceneRenderGraphContext& context) { + const Containers::String passName = context.passName; + const RenderContext renderContext = context.renderContext; + const std::shared_ptr sceneData = + std::make_shared(context.sceneData); + const RenderSurface surfaceTemplate = + BuildGraphManagedForwardSceneSurface(context.surfaceTemplate); + const bool hasSourceSurface = context.sourceSurface != nullptr; + const RenderSurface sourceSurface = + hasSourceSurface ? *context.sourceSurface : RenderSurface(); + RHI::RHIResourceView* const sourceColorView = context.sourceColorView; + const RHI::ResourceStates sourceColorState = context.sourceColorState; + const std::vector colorTargets = context.colorTargets; + const RenderGraphTextureHandle depthTarget = context.depthTarget; + const CameraFrameRenderGraphResources* const frameResources = + TryGetCameraFrameRenderGraphResources(context.blackboard); + const RenderGraphTextureHandle mainDirectionalShadowTexture = + frameResources != nullptr + ? frameResources->mainDirectionalShadow + : RenderGraphTextureHandle{}; + bool* const executionSucceeded = context.executionSucceeded; + const std::shared_ptr graphExecutionState = + std::make_shared(); + const SceneRenderFeaturePassBeginCallback beginRecordedPass = + [&pipeline, + graphExecutionState, + renderContext, + sceneData, + hasSourceSurface, + sourceSurface, + sourceColorView, + sourceColorState, + executionSucceeded]( + const RenderPassContext& passContext, + bool clearAttachments) -> bool { + if (executionSucceeded != nullptr && !(*executionSucceeded)) { + return false; + } + + if (!graphExecutionState->initialized) { + if (!pipeline.Initialize(renderContext)) { + Debug::Logger::Get().Error( + Debug::LogCategory::Rendering, + "BuiltinForwardPipeline::RecordMainSceneRenderGraph failed during execution: Initialize returned false"); + if (executionSucceeded != nullptr) { + *executionSucceeded = false; + } + return false; + } + + const FrameExecutionContext executionContext( + renderContext, + passContext.surface, + *sceneData, + hasSourceSurface ? &sourceSurface : nullptr, + sourceColorView, + sourceColorState); + if (!pipeline.m_forwardSceneFeatureHost.Prepare(executionContext)) { + Debug::Logger::Get().Error( + Debug::LogCategory::Rendering, + "BuiltinForwardPipeline::RecordMainSceneRenderGraph failed during execution: SceneRenderFeatureHost::Prepare returned false"); + if (executionSucceeded != nullptr) { + *executionSucceeded = false; + } + return false; + } + + graphExecutionState->initialized = true; + } + + if (!pipeline.BeginForwardScenePass(passContext, clearAttachments)) { + Debug::Logger::Get().Error( + Debug::LogCategory::Rendering, + "BuiltinForwardPipeline::RecordMainSceneRenderGraph failed during execution: BeginForwardScenePass returned false"); + if (executionSucceeded != nullptr) { + *executionSucceeded = false; + } + return false; + } + + return true; + }; + const SceneRenderFeaturePassEndCallback endRecordedPass = + [&pipeline](const RenderPassContext& passContext) { + pipeline.EndForwardScenePass(passContext); + }; + + bool clearAttachments = true; + for (const ForwardSceneStep& step : GetBuiltinForwardSceneSteps()) { + if (step.type == ForwardSceneStepType::InjectionPoint) { + const SceneRenderFeaturePassRenderGraphContext featureContext = { + context.graphBuilder, + passName, + renderContext, + *sceneData, + surfaceTemplate, + hasSourceSurface ? &sourceSurface : nullptr, + sourceColorView, + sourceColorState, + {}, + colorTargets, + depthTarget, + clearAttachments, + executionSucceeded, + beginRecordedPass, + endRecordedPass, + context.blackboard + }; + bool recordedAnyPass = false; + if (!pipeline.m_forwardSceneFeatureHost.Record( + featureContext, + step.injectionPoint, + &recordedAnyPass)) { + return false; + } + + if (recordedAnyPass) { + clearAttachments = false; + } + continue; + } + + const Containers::String phasePassName = + BuildForwardScenePhasePassName(passName, step.scenePhase); + const RenderPassGraphBeginCallback beginPhasePass = + [beginRecordedPass, clearAttachments](const RenderPassContext& passContext) { + return beginRecordedPass(passContext, clearAttachments); + }; + const std::vector additionalReadTextures = + ScenePhaseSamplesMainDirectionalShadow(step.scenePhase) && + mainDirectionalShadowTexture.IsValid() + ? std::vector{ mainDirectionalShadowTexture } + : std::vector{}; + const RenderPassRenderGraphContext phaseContext = { + context.graphBuilder, + phasePassName, + renderContext, + *sceneData, + surfaceTemplate, + hasSourceSurface ? &sourceSurface : nullptr, + sourceColorView, + sourceColorState, + {}, + colorTargets, + depthTarget, + executionSucceeded, + beginPhasePass, + endRecordedPass, + context.blackboard + }; + if (!::XCEngine::Rendering::Internal::RecordCallbackRasterRenderPass( + phaseContext, + { + false, + true, + depthTarget.IsValid() + }, + [&pipeline, scenePhase = step.scenePhase](const RenderPassContext& passContext) { + const FrameExecutionContext executionContext( + passContext.renderContext, + passContext.surface, + passContext.sceneData, + passContext.sourceSurface, + passContext.sourceColorView, + passContext.sourceColorState); + const ScenePhaseExecutionContext scenePhaseExecutionContext = + pipeline.BuildScenePhaseExecutionContext(executionContext, scenePhase); + return pipeline.ExecuteBuiltinScenePhase(scenePhaseExecutionContext); + }, + additionalReadTextures)) { + return false; + } + clearAttachments = false; + } + + return true; +} + +} // namespace Internal +} // namespace Pipelines +} // namespace Rendering +} // namespace XCEngine diff --git a/engine/src/Rendering/Pipelines/Internal/BuiltinForwardMainSceneGraphBuilder.h b/engine/src/Rendering/Pipelines/Internal/BuiltinForwardMainSceneGraphBuilder.h new file mode 100644 index 00000000..c576eec5 --- /dev/null +++ b/engine/src/Rendering/Pipelines/Internal/BuiltinForwardMainSceneGraphBuilder.h @@ -0,0 +1,23 @@ +#pragma once + +namespace XCEngine { +namespace Rendering { + +struct RenderPipelineMainSceneRenderGraphContext; + +namespace Pipelines { + +class BuiltinForwardPipeline; + +namespace Internal { + +struct BuiltinForwardMainSceneGraphBuilder { + static bool Record( + BuiltinForwardPipeline& pipeline, + const RenderPipelineMainSceneRenderGraphContext& context); +}; + +} // namespace Internal +} // namespace Pipelines +} // namespace Rendering +} // namespace XCEngine diff --git a/engine/src/Rendering/Pipelines/Internal/BuiltinForwardPipelineFrame.cpp b/engine/src/Rendering/Pipelines/Internal/BuiltinForwardPipelineFrame.cpp index 4178af9c..70776207 100644 --- a/engine/src/Rendering/Pipelines/Internal/BuiltinForwardPipelineFrame.cpp +++ b/engine/src/Rendering/Pipelines/Internal/BuiltinForwardPipelineFrame.cpp @@ -1,15 +1,10 @@ #include "Rendering/Pipelines/BuiltinForwardPipeline.h" #include "Debug/Logger.h" -#include "Rendering/Graph/RenderGraph.h" -#include "Rendering/Internal/RenderPassGraphUtils.h" -#include "Rendering/Pipelines/Internal/BuiltinForwardSceneSetup.h" -#include "RHI/RHICommandList.h" +#include "Rendering/Pipelines/Internal/BuiltinForwardMainSceneGraphBuilder.h" #include "Rendering/Internal/RenderSurfacePipelineUtils.h" #include "Rendering/RenderSurface.h" - -#include -#include +#include "RHI/RHICommandList.h" namespace XCEngine { namespace Rendering { @@ -56,30 +51,6 @@ std::vector CollectSurfaceColorAttachments(const RenderSu return renderTargets; } -RenderSurface BuildGraphManagedForwardSceneSurface(const RenderSurface& templateSurface) { - RenderSurface surface = templateSurface; - surface.SetAutoTransitionEnabled(false); - return surface; -} - -struct ForwardSceneGraphExecutionState { - bool initialized = false; -}; - -Containers::String BuildForwardScenePhasePassName( - const Containers::String& baseName, - ScenePhase scenePhase) { - std::string name = baseName.CStr(); - name += '.'; - name += ToString(scenePhase); - return Containers::String(name.c_str()); -} - -bool ScenePhaseSamplesMainDirectionalShadow(ScenePhase scenePhase) { - return scenePhase == ScenePhase::Opaque || - scenePhase == ScenePhase::Transparent; -} - } // namespace bool BuiltinForwardPipeline::ShouldSampleMainDirectionalShadowMap(const RenderSceneData& sceneData) { @@ -94,181 +65,7 @@ bool BuiltinForwardPipeline::SupportsMainSceneRenderGraph() const { bool BuiltinForwardPipeline::RecordMainSceneRenderGraph( const RenderPipelineMainSceneRenderGraphContext& context) { - const Containers::String passName = context.passName; - const RenderContext renderContext = context.renderContext; - const std::shared_ptr sceneData = - std::make_shared(context.sceneData); - const RenderSurface surfaceTemplate = - BuildGraphManagedForwardSceneSurface(context.surfaceTemplate); - const bool hasSourceSurface = context.sourceSurface != nullptr; - const RenderSurface sourceSurface = - hasSourceSurface ? *context.sourceSurface : RenderSurface(); - RHI::RHIResourceView* const sourceColorView = context.sourceColorView; - const RHI::ResourceStates sourceColorState = context.sourceColorState; - const std::vector colorTargets = context.colorTargets; - const RenderGraphTextureHandle depthTarget = context.depthTarget; - const CameraFrameRenderGraphResources* const frameResources = - TryGetCameraFrameRenderGraphResources(context.blackboard); - const RenderGraphTextureHandle mainDirectionalShadowTexture = - frameResources != nullptr - ? frameResources->mainDirectionalShadow - : RenderGraphTextureHandle{}; - bool* const executionSucceeded = context.executionSucceeded; - const std::shared_ptr graphExecutionState = - std::make_shared(); - const SceneRenderFeaturePassBeginCallback beginRecordedPass = - [this, - graphExecutionState, - renderContext, - sceneData, - hasSourceSurface, - sourceSurface, - sourceColorView, - sourceColorState, - executionSucceeded]( - const RenderPassContext& passContext, - bool clearAttachments) -> bool { - if (executionSucceeded != nullptr && !(*executionSucceeded)) { - return false; - } - - if (!graphExecutionState->initialized) { - if (!Initialize(renderContext)) { - Debug::Logger::Get().Error( - Debug::LogCategory::Rendering, - "BuiltinForwardPipeline::RecordMainSceneRenderGraph failed during execution: Initialize returned false"); - if (executionSucceeded != nullptr) { - *executionSucceeded = false; - } - return false; - } - - const FrameExecutionContext executionContext( - renderContext, - passContext.surface, - *sceneData, - hasSourceSurface ? &sourceSurface : nullptr, - sourceColorView, - sourceColorState); - if (!m_forwardSceneFeatureHost.Prepare(executionContext)) { - Debug::Logger::Get().Error( - Debug::LogCategory::Rendering, - "BuiltinForwardPipeline::RecordMainSceneRenderGraph failed during execution: SceneRenderFeatureHost::Prepare returned false"); - if (executionSucceeded != nullptr) { - *executionSucceeded = false; - } - return false; - } - - graphExecutionState->initialized = true; - } - - if (!BeginForwardScenePass(passContext, clearAttachments)) { - Debug::Logger::Get().Error( - Debug::LogCategory::Rendering, - "BuiltinForwardPipeline::RecordMainSceneRenderGraph failed during execution: BeginForwardScenePass returned false"); - if (executionSucceeded != nullptr) { - *executionSucceeded = false; - } - return false; - } - - return true; - }; - const SceneRenderFeaturePassEndCallback endRecordedPass = - [this](const RenderPassContext& passContext) { - EndForwardScenePass(passContext); - }; - - bool clearAttachments = true; - for (const Pipelines::Internal::ForwardSceneStep& step : Pipelines::Internal::GetBuiltinForwardSceneSteps()) { - if (step.type == Pipelines::Internal::ForwardSceneStepType::InjectionPoint) { - const SceneRenderFeaturePassRenderGraphContext featureContext = { - context.graphBuilder, - passName, - renderContext, - *sceneData, - surfaceTemplate, - hasSourceSurface ? &sourceSurface : nullptr, - sourceColorView, - sourceColorState, - {}, - colorTargets, - depthTarget, - clearAttachments, - executionSucceeded, - beginRecordedPass, - endRecordedPass, - context.blackboard - }; - bool recordedAnyPass = false; - if (!m_forwardSceneFeatureHost.Record( - featureContext, - step.injectionPoint, - &recordedAnyPass)) { - return false; - } - - if (recordedAnyPass) { - clearAttachments = false; - } - continue; - } - - const Containers::String phasePassName = - BuildForwardScenePhasePassName(passName, step.scenePhase); - const RenderPassGraphBeginCallback beginPhasePass = - [beginRecordedPass, clearAttachments](const RenderPassContext& passContext) { - return beginRecordedPass(passContext, clearAttachments); - }; - const std::vector additionalReadTextures = - ScenePhaseSamplesMainDirectionalShadow(step.scenePhase) && - mainDirectionalShadowTexture.IsValid() - ? std::vector{ mainDirectionalShadowTexture } - : std::vector{}; - const RenderPassRenderGraphContext phaseContext = { - context.graphBuilder, - phasePassName, - renderContext, - *sceneData, - surfaceTemplate, - hasSourceSurface ? &sourceSurface : nullptr, - sourceColorView, - sourceColorState, - {}, - colorTargets, - depthTarget, - executionSucceeded, - beginPhasePass, - endRecordedPass, - context.blackboard - }; - if (!::XCEngine::Rendering::Internal::RecordCallbackRasterRenderPass( - phaseContext, - { - false, - true, - depthTarget.IsValid() - }, - [this, scenePhase = step.scenePhase](const RenderPassContext& passContext) { - const FrameExecutionContext executionContext( - passContext.renderContext, - passContext.surface, - passContext.sceneData, - passContext.sourceSurface, - passContext.sourceColorView, - passContext.sourceColorState); - const ScenePhaseExecutionContext scenePhaseExecutionContext = - BuildScenePhaseExecutionContext(executionContext, scenePhase); - return ExecuteBuiltinScenePhase(scenePhaseExecutionContext); - }, - additionalReadTextures)) { - return false; - } - clearAttachments = false; - } - - return true; + return Internal::BuiltinForwardMainSceneGraphBuilder::Record(*this, context); } bool BuiltinForwardPipeline::Render(