diff --git a/engine/CMakeLists.txt b/engine/CMakeLists.txt index dc57cc0f..65830451 100644 --- a/engine/CMakeLists.txt +++ b/engine/CMakeLists.txt @@ -533,6 +533,7 @@ add_library(XCEngine STATIC ${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/Rendering/Features/BuiltinGaussianSplatPass.h ${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/Rendering/Features/BuiltinVolumetricPass.h ${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/Rendering/Pipelines/BuiltinForwardPipeline.h + ${CMAKE_CURRENT_SOURCE_DIR}/src/Rendering/Execution/CameraFramePlan.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/Rendering/Execution/CameraRenderer.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/Rendering/Execution/Internal/CameraFrameRenderGraphExecution.h ${CMAKE_CURRENT_SOURCE_DIR}/src/Rendering/Execution/Internal/CameraFrameRenderGraphExecution.cpp diff --git a/engine/include/XCEngine/Rendering/Execution/CameraFramePlan.h b/engine/include/XCEngine/Rendering/Execution/CameraFramePlan.h index ce6b48c1..50524b21 100644 --- a/engine/include/XCEngine/Rendering/Execution/CameraFramePlan.h +++ b/engine/include/XCEngine/Rendering/Execution/CameraFramePlan.h @@ -25,14 +25,7 @@ struct CameraFrameColorChainPlan { struct CameraFramePlan { static RenderSurface BuildGraphManagedIntermediateSurfaceTemplate( - const RenderSurface& surface) { - RenderSurface graphManagedSurface = surface; - graphManagedSurface.SetColorAttachments({}); - graphManagedSurface.SetAutoTransitionEnabled(false); - graphManagedSurface.SetColorStateBefore(RHI::ResourceStates::Common); - graphManagedSurface.SetColorStateAfter(RHI::ResourceStates::Common); - return graphManagedSurface; - } + const RenderSurface& surface); CameraRenderRequest request = {}; ShadowCasterRenderRequest shadowCaster = {}; @@ -46,188 +39,22 @@ struct CameraFramePlan { CameraFrameColorChainPlan colorChain = {}; RenderSurface graphManagedMainSceneSurface = {}; - static CameraFramePlan FromRequest(const CameraRenderRequest& request) { - CameraFramePlan plan = {}; - plan.request = request; - plan.shadowCaster = request.shadowCaster; - plan.directionalShadow = request.directionalShadow; - plan.postProcess = request.postProcess; - plan.finalOutput = request.finalOutput; - plan.finalColorPolicy = request.finalColorPolicy; - plan.preScenePasses = request.preScenePasses; - plan.postScenePasses = request.postScenePasses; - plan.overlayPasses = request.overlayPasses; - return plan; - } + static CameraFramePlan FromRequest(const CameraRenderRequest& request); - bool IsValid() const { - return request.IsValid(); - } - - void ConfigureGraphManagedMainSceneSurface() { - graphManagedMainSceneSurface = - BuildGraphManagedIntermediateSurfaceTemplate(request.surface); - } - - bool UsesGraphManagedMainSceneColor() const { - return colorChain.usesGraphManagedMainSceneColor; - } - - bool UsesGraphManagedOutputColor(CameraFrameStage stage) const { - switch (stage) { - case CameraFrameStage::PostProcess: - return colorChain.postProcess.usesGraphManagedOutputColor; - default: - return false; - } - } - - CameraFrameColorSource ResolveStageColorSource(CameraFrameStage stage) const { - switch (stage) { - case CameraFrameStage::PostProcess: - return colorChain.postProcess.source; - case CameraFrameStage::FinalOutput: - return colorChain.finalOutput.source; - default: - return CameraFrameColorSource::ExplicitSurface; - } - } - - bool IsPostProcessStageValid() const { - if (!postProcess.IsRequested()) { - return true; - } - - if (ResolveStageColorSource(CameraFrameStage::PostProcess) == - CameraFrameColorSource::ExplicitSurface) { - return postProcess.IsValid(); - } - - const bool hasUsableDestination = - UsesGraphManagedOutputColor(CameraFrameStage::PostProcess) || - (HasValidColorTarget(postProcess.destinationSurface) && - HasValidSurfaceSampleDescription(postProcess.destinationSurface)); - return UsesGraphManagedMainSceneColor() && - postProcess.passes != nullptr && - HasValidSingleSampleColorSource(request.surface) && - hasUsableDestination; - } - - bool IsFinalOutputStageValid() const { - if (!finalOutput.IsRequested()) { - return true; - } - - const CameraFrameColorSource finalOutputSource = - ResolveStageColorSource(CameraFrameStage::FinalOutput); - if (finalOutputSource == CameraFrameColorSource::ExplicitSurface) { - return finalOutput.IsValid(); - } - - const bool hasUsableSource = - finalOutputSource == CameraFrameColorSource::MainSceneColor - ? UsesGraphManagedMainSceneColor() - : UsesGraphManagedOutputColor(CameraFrameStage::PostProcess); - return hasUsableSource && - finalOutput.passes != nullptr && - HasValidColorTarget(finalOutput.destinationSurface) && - HasValidSurfaceSampleDescription(finalOutput.destinationSurface); - } - - bool HasFrameStage(CameraFrameStage stage) const { - switch (stage) { - case CameraFrameStage::PreScenePasses: - return preScenePasses != nullptr; - case CameraFrameStage::ShadowCaster: - return shadowCaster.IsRequested() || directionalShadow.IsValid(); - case CameraFrameStage::DepthOnly: - return request.depthOnly.IsRequested(); - case CameraFrameStage::MainScene: - return true; - case CameraFrameStage::PostProcess: - return postProcess.IsRequested(); - case CameraFrameStage::FinalOutput: - return finalOutput.IsRequested(); - case CameraFrameStage::ObjectId: - return request.objectId.IsRequested(); - case CameraFrameStage::PostScenePasses: - return postScenePasses != nullptr; - case CameraFrameStage::OverlayPasses: - return overlayPasses != nullptr; - default: - return false; - } - } - - RenderPassSequence* GetPassSequence(CameraFrameStage stage) const { - switch (stage) { - case CameraFrameStage::PreScenePasses: - return preScenePasses; - case CameraFrameStage::PostProcess: - return postProcess.passes; - case CameraFrameStage::FinalOutput: - return finalOutput.passes; - case CameraFrameStage::PostScenePasses: - return postScenePasses; - case CameraFrameStage::OverlayPasses: - return overlayPasses; - default: - return nullptr; - } - } - - const ScenePassRenderRequest* GetScenePassRequest(CameraFrameStage stage) const { - switch (stage) { - case CameraFrameStage::ShadowCaster: - return &shadowCaster; - case CameraFrameStage::DepthOnly: - return &request.depthOnly; - default: - return nullptr; - } - } - - const ObjectIdRenderRequest* GetObjectIdRequest(CameraFrameStage stage) const { - return stage == CameraFrameStage::ObjectId ? &request.objectId : nullptr; - } - - const RenderSurface& GetMainSceneSurface() const { - if (UsesGraphManagedMainSceneColor() && - graphManagedMainSceneSurface.GetWidth() > 0u && - graphManagedMainSceneSurface.GetHeight() > 0u) { - return graphManagedMainSceneSurface; - } - - if (postProcess.IsRequested() && - HasValidColorTarget(postProcess.sourceSurface)) { - return postProcess.sourceSurface; - } - - if (finalOutput.IsRequested() && - HasValidColorTarget(finalOutput.sourceSurface)) { - return finalOutput.sourceSurface; - } - - return request.surface; - } - - const RenderSurface& GetFinalCompositedSurface() const { - if (finalOutput.IsRequested() && - HasValidColorTarget(finalOutput.destinationSurface)) { - return finalOutput.destinationSurface; - } - - if (postProcess.IsRequested() && - HasValidColorTarget(postProcess.destinationSurface)) { - return postProcess.destinationSurface; - } - - return request.surface; - } - - bool RequiresIntermediateSceneColor() const { - return postProcess.IsRequested() || finalOutput.IsRequested(); - } + bool IsValid() const; + void ConfigureGraphManagedMainSceneSurface(); + bool UsesGraphManagedMainSceneColor() const; + bool UsesGraphManagedOutputColor(CameraFrameStage stage) const; + CameraFrameColorSource ResolveStageColorSource(CameraFrameStage stage) const; + bool IsPostProcessStageValid() const; + bool IsFinalOutputStageValid() const; + bool HasFrameStage(CameraFrameStage stage) const; + RenderPassSequence* GetPassSequence(CameraFrameStage stage) const; + const ScenePassRenderRequest* GetScenePassRequest(CameraFrameStage stage) const; + const ObjectIdRenderRequest* GetObjectIdRequest(CameraFrameStage stage) const; + const RenderSurface& GetMainSceneSurface() const; + const RenderSurface& GetFinalCompositedSurface() const; + bool RequiresIntermediateSceneColor() const; }; } // namespace Rendering diff --git a/engine/src/Rendering/Execution/CameraFramePlan.cpp b/engine/src/Rendering/Execution/CameraFramePlan.cpp new file mode 100644 index 00000000..63da37d9 --- /dev/null +++ b/engine/src/Rendering/Execution/CameraFramePlan.cpp @@ -0,0 +1,200 @@ +#include + +namespace XCEngine { +namespace Rendering { + +RenderSurface CameraFramePlan::BuildGraphManagedIntermediateSurfaceTemplate( + const RenderSurface& surface) { + RenderSurface graphManagedSurface = surface; + graphManagedSurface.SetColorAttachments({}); + graphManagedSurface.SetAutoTransitionEnabled(false); + graphManagedSurface.SetColorStateBefore(RHI::ResourceStates::Common); + graphManagedSurface.SetColorStateAfter(RHI::ResourceStates::Common); + return graphManagedSurface; +} + +CameraFramePlan CameraFramePlan::FromRequest(const CameraRenderRequest& request) { + CameraFramePlan plan = {}; + plan.request = request; + plan.shadowCaster = request.shadowCaster; + plan.directionalShadow = request.directionalShadow; + plan.postProcess = request.postProcess; + plan.finalOutput = request.finalOutput; + plan.finalColorPolicy = request.finalColorPolicy; + plan.preScenePasses = request.preScenePasses; + plan.postScenePasses = request.postScenePasses; + plan.overlayPasses = request.overlayPasses; + return plan; +} + +bool CameraFramePlan::IsValid() const { + return request.IsValid(); +} + +void CameraFramePlan::ConfigureGraphManagedMainSceneSurface() { + graphManagedMainSceneSurface = + BuildGraphManagedIntermediateSurfaceTemplate(request.surface); +} + +bool CameraFramePlan::UsesGraphManagedMainSceneColor() const { + return colorChain.usesGraphManagedMainSceneColor; +} + +bool CameraFramePlan::UsesGraphManagedOutputColor(CameraFrameStage stage) const { + switch (stage) { + case CameraFrameStage::PostProcess: + return colorChain.postProcess.usesGraphManagedOutputColor; + default: + return false; + } +} + +CameraFrameColorSource CameraFramePlan::ResolveStageColorSource(CameraFrameStage stage) const { + switch (stage) { + case CameraFrameStage::PostProcess: + return colorChain.postProcess.source; + case CameraFrameStage::FinalOutput: + return colorChain.finalOutput.source; + default: + return CameraFrameColorSource::ExplicitSurface; + } +} + +bool CameraFramePlan::IsPostProcessStageValid() const { + if (!postProcess.IsRequested()) { + return true; + } + + if (ResolveStageColorSource(CameraFrameStage::PostProcess) == + CameraFrameColorSource::ExplicitSurface) { + return postProcess.IsValid(); + } + + const bool hasUsableDestination = + UsesGraphManagedOutputColor(CameraFrameStage::PostProcess) || + (HasValidColorTarget(postProcess.destinationSurface) && + HasValidSurfaceSampleDescription(postProcess.destinationSurface)); + return UsesGraphManagedMainSceneColor() && + postProcess.passes != nullptr && + HasValidSingleSampleColorSource(request.surface) && + hasUsableDestination; +} + +bool CameraFramePlan::IsFinalOutputStageValid() const { + if (!finalOutput.IsRequested()) { + return true; + } + + const CameraFrameColorSource finalOutputSource = + ResolveStageColorSource(CameraFrameStage::FinalOutput); + if (finalOutputSource == CameraFrameColorSource::ExplicitSurface) { + return finalOutput.IsValid(); + } + + const bool hasUsableSource = + finalOutputSource == CameraFrameColorSource::MainSceneColor + ? UsesGraphManagedMainSceneColor() + : UsesGraphManagedOutputColor(CameraFrameStage::PostProcess); + return hasUsableSource && + finalOutput.passes != nullptr && + HasValidColorTarget(finalOutput.destinationSurface) && + HasValidSurfaceSampleDescription(finalOutput.destinationSurface); +} + +bool CameraFramePlan::HasFrameStage(CameraFrameStage stage) const { + switch (stage) { + case CameraFrameStage::PreScenePasses: + return preScenePasses != nullptr; + case CameraFrameStage::ShadowCaster: + return shadowCaster.IsRequested() || directionalShadow.IsValid(); + case CameraFrameStage::DepthOnly: + return request.depthOnly.IsRequested(); + case CameraFrameStage::MainScene: + return true; + case CameraFrameStage::PostProcess: + return postProcess.IsRequested(); + case CameraFrameStage::FinalOutput: + return finalOutput.IsRequested(); + case CameraFrameStage::ObjectId: + return request.objectId.IsRequested(); + case CameraFrameStage::PostScenePasses: + return postScenePasses != nullptr; + case CameraFrameStage::OverlayPasses: + return overlayPasses != nullptr; + default: + return false; + } +} + +RenderPassSequence* CameraFramePlan::GetPassSequence(CameraFrameStage stage) const { + switch (stage) { + case CameraFrameStage::PreScenePasses: + return preScenePasses; + case CameraFrameStage::PostProcess: + return postProcess.passes; + case CameraFrameStage::FinalOutput: + return finalOutput.passes; + case CameraFrameStage::PostScenePasses: + return postScenePasses; + case CameraFrameStage::OverlayPasses: + return overlayPasses; + default: + return nullptr; + } +} + +const ScenePassRenderRequest* CameraFramePlan::GetScenePassRequest(CameraFrameStage stage) const { + switch (stage) { + case CameraFrameStage::ShadowCaster: + return &shadowCaster; + case CameraFrameStage::DepthOnly: + return &request.depthOnly; + default: + return nullptr; + } +} + +const ObjectIdRenderRequest* CameraFramePlan::GetObjectIdRequest(CameraFrameStage stage) const { + return stage == CameraFrameStage::ObjectId ? &request.objectId : nullptr; +} + +const RenderSurface& CameraFramePlan::GetMainSceneSurface() const { + if (UsesGraphManagedMainSceneColor() && + graphManagedMainSceneSurface.GetWidth() > 0u && + graphManagedMainSceneSurface.GetHeight() > 0u) { + return graphManagedMainSceneSurface; + } + + if (postProcess.IsRequested() && + HasValidColorTarget(postProcess.sourceSurface)) { + return postProcess.sourceSurface; + } + + if (finalOutput.IsRequested() && + HasValidColorTarget(finalOutput.sourceSurface)) { + return finalOutput.sourceSurface; + } + + return request.surface; +} + +const RenderSurface& CameraFramePlan::GetFinalCompositedSurface() const { + if (finalOutput.IsRequested() && + HasValidColorTarget(finalOutput.destinationSurface)) { + return finalOutput.destinationSurface; + } + + if (postProcess.IsRequested() && + HasValidColorTarget(postProcess.destinationSurface)) { + return postProcess.destinationSurface; + } + + return request.surface; +} + +bool CameraFramePlan::RequiresIntermediateSceneColor() const { + return postProcess.IsRequested() || finalOutput.IsRequested(); +} + +} // namespace Rendering +} // namespace XCEngine