diff --git a/engine/include/XCEngine/Rendering/RenderPipeline.h b/engine/include/XCEngine/Rendering/RenderPipeline.h index 095f4d74..ebff0164 100644 --- a/engine/include/XCEngine/Rendering/RenderPipeline.h +++ b/engine/include/XCEngine/Rendering/RenderPipeline.h @@ -15,14 +15,32 @@ namespace Rendering { class RenderGraphBuilder; -struct CameraFrameRenderGraphResources { - RenderGraphTextureHandle mainSceneColor = {}; - RenderGraphTextureHandle mainSceneDepth = {}; - RenderGraphTextureHandle postProcessColor = {}; - RenderGraphTextureHandle mainDirectionalShadow = {}; - RenderGraphTextureHandle objectIdColor = {}; +struct CameraFrameRenderGraphSurfaceResources { + RenderGraphTextureHandle color = {}; + RenderGraphTextureHandle depth = {}; }; +struct CameraFrameRenderGraphResources { + CameraFrameRenderGraphSurfaceResources mainScene = {}; + CameraFrameRenderGraphSurfaceResources postProcess = {}; + CameraFrameRenderGraphSurfaceResources objectId = {}; + RenderGraphTextureHandle mainDirectionalShadow = {}; +}; + +inline CameraFrameRenderGraphResources* TryGetCameraFrameRenderGraphResources( + RenderGraphBlackboard* blackboard) { + return blackboard != nullptr + ? blackboard->TryGet() + : nullptr; +} + +inline const CameraFrameRenderGraphResources* TryGetCameraFrameRenderGraphResources( + const RenderGraphBlackboard* blackboard) { + return blackboard != nullptr + ? blackboard->TryGet() + : nullptr; +} + struct RenderPipelineMainSceneRenderGraphContext { RenderGraphBuilder& graphBuilder; Containers::String passName = {}; @@ -34,7 +52,6 @@ struct RenderPipelineMainSceneRenderGraphContext { RHI::ResourceStates sourceColorState = RHI::ResourceStates::Common; std::vector colorTargets = {}; RenderGraphTextureHandle depthTarget = {}; - RenderGraphTextureHandle mainDirectionalShadowTexture = {}; bool* executionSucceeded = nullptr; RenderGraphBlackboard* blackboard = nullptr; }; diff --git a/engine/src/Rendering/Execution/CameraRenderer.cpp b/engine/src/Rendering/Execution/CameraRenderer.cpp index 44e2d3ad..28eb9fcd 100644 --- a/engine/src/Rendering/Execution/CameraRenderer.cpp +++ b/engine/src/Rendering/Execution/CameraRenderer.cpp @@ -621,16 +621,30 @@ RenderGraphTextureHandle ResolveStageOutputColorHandle( if (stage == CameraFrameStage::PostProcess && plan.usesGraphManagedPostProcessColor) { - frameResources.postProcessColor = + frameResources.postProcess.color = graphBuilder.CreateTransientTexture( stageName + ".Color", BuildFullscreenTransientTextureDesc(stagePassContext.surface)); - return frameResources.postProcessColor; + return frameResources.postProcess.color; } return GetPrimaryColorTexture(outputSurface); } +RenderGraphTextureHandle ResolveFrameResourceColorSource( + const CameraFrameRenderGraphResources& frameResources, + CameraFrameColorSource source) { + switch (source) { + case CameraFrameColorSource::MainSceneColor: + return frameResources.mainScene.color; + case CameraFrameColorSource::PostProcessColor: + return frameResources.postProcess.color; + case CameraFrameColorSource::ExplicitSurface: + default: + return {}; + } +} + FullscreenStageGraphBinding ResolveFullscreenStageGraphBinding( CameraFrameStage stage, const CameraFramePlan& plan, @@ -650,20 +664,22 @@ FullscreenStageGraphBinding ResolveFullscreenStageGraphBinding( binding.sourceSurfaceTemplate = &stagePassContext.surface; binding.sourceColorView = nullptr; binding.sourceColorState = RHI::ResourceStates::PixelShaderResource; - binding.sourceColor = frameResources.mainSceneColor; + binding.sourceColor = + ResolveFrameResourceColorSource( + frameResources, + plan.postProcessSource); } if (stage == CameraFrameStage::FinalOutput) { - if (plan.finalOutputSource == CameraFrameColorSource::MainSceneColor) { + if (plan.finalOutputSource == CameraFrameColorSource::MainSceneColor || + plan.finalOutputSource == CameraFrameColorSource::PostProcessColor) { binding.sourceSurfaceTemplate = &stagePassContext.surface; binding.sourceColorView = nullptr; binding.sourceColorState = RHI::ResourceStates::PixelShaderResource; - binding.sourceColor = frameResources.mainSceneColor; - } else if (plan.finalOutputSource == CameraFrameColorSource::PostProcessColor) { - binding.sourceSurfaceTemplate = &stagePassContext.surface; - binding.sourceColorView = nullptr; - binding.sourceColorState = RHI::ResourceStates::PixelShaderResource; - binding.sourceColor = frameResources.postProcessColor; + binding.sourceColor = + ResolveFrameResourceColorSource( + frameResources, + plan.finalOutputSource); } } @@ -927,7 +943,6 @@ bool ExecuteRenderGraphPlan( blackboard.Emplace(); bool stageExecutionSucceeded = true; - RenderGraphTextureHandle mainDirectionalShadowTexture = {}; for (const CameraFrameStageInfo& stageInfo : kOrderedCameraFrameStages) { if (!plan.HasFrameStage(stageInfo.stage) && stageInfo.stage != CameraFrameStage::MainScene) { @@ -969,15 +984,19 @@ bool ExecuteRenderGraphPlan( if (stage == CameraFrameStage::ShadowCaster && shadowState.HasShadowSampling() && outputSurface.depthTexture.IsValid()) { - mainDirectionalShadowTexture = outputSurface.depthTexture; frameResources.mainDirectionalShadow = outputSurface.depthTexture; } if (stage == CameraFrameStage::MainScene) { - frameResources.mainSceneColor = stageOutputColor; - frameResources.mainSceneDepth = outputSurface.depthTexture; + frameResources.mainScene.color = stageOutputColor; + frameResources.mainScene.depth = outputSurface.depthTexture; + } + if (stage == CameraFrameStage::PostProcess) { + frameResources.postProcess.color = stageOutputColor; + frameResources.postProcess.depth = outputSurface.depthTexture; } if (stage == CameraFrameStage::ObjectId) { - frameResources.objectIdColor = stageOutputColor; + frameResources.objectId.color = stageOutputColor; + frameResources.objectId.depth = outputSurface.depthTexture; } const RenderSurface stageSurfaceTemplate = stagePassContext.surface; const bool hasStageSourceSurface = stagePassContext.sourceSurface != nullptr; @@ -1093,7 +1112,6 @@ bool ExecuteRenderGraphPlan( stageSourceColorState, std::vector{ stageOutputColor }, outputSurface.depthTexture, - mainDirectionalShadowTexture, &stageExecutionSucceeded, &blackboard }; diff --git a/engine/src/Rendering/Pipelines/Internal/BuiltinForwardPipelineFrame.cpp b/engine/src/Rendering/Pipelines/Internal/BuiltinForwardPipelineFrame.cpp index 1c44794c..2050c875 100644 --- a/engine/src/Rendering/Pipelines/Internal/BuiltinForwardPipelineFrame.cpp +++ b/engine/src/Rendering/Pipelines/Internal/BuiltinForwardPipelineFrame.cpp @@ -107,8 +107,12 @@ bool BuiltinForwardPipeline::RecordMainSceneRenderGraph( 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 = - context.mainDirectionalShadowTexture; + frameResources != nullptr + ? frameResources->mainDirectionalShadow + : RenderGraphTextureHandle{}; bool* const executionSucceeded = context.executionSucceeded; const std::shared_ptr graphExecutionState = std::make_shared(); diff --git a/tests/Rendering/unit/test_builtin_forward_pipeline.cpp b/tests/Rendering/unit/test_builtin_forward_pipeline.cpp index 8cd22a94..238d8f6d 100644 --- a/tests/Rendering/unit/test_builtin_forward_pipeline.cpp +++ b/tests/Rendering/unit/test_builtin_forward_pipeline.cpp @@ -617,6 +617,12 @@ TEST(BuiltinForwardPipeline_Test, RecordsMainSceneGraphPassWithSampledShadowDepe RenderContext renderContext = {}; RenderSceneData sceneData = {}; + RenderGraphBlackboard blackboard = {}; + CameraFrameRenderGraphResources& frameResources = + blackboard.Emplace(); + frameResources.mainScene.color = colorTarget; + frameResources.mainScene.depth = depthTarget; + frameResources.mainDirectionalShadow = shadowTarget; bool executionSucceeded = true; const RenderPipelineMainSceneRenderGraphContext context = { graphBuilder, @@ -629,8 +635,8 @@ TEST(BuiltinForwardPipeline_Test, RecordsMainSceneGraphPassWithSampledShadowDepe ResourceStates::Common, { colorTarget }, depthTarget, - shadowTarget, - &executionSucceeded + &executionSucceeded, + &blackboard }; ASSERT_TRUE(pipeline.RecordMainSceneRenderGraph(context)); @@ -1142,6 +1148,11 @@ TEST(BuiltinForwardPipeline_Test, RecordsActiveFeatureInjectionPassesIntoMainSce RenderSceneData sceneData = {}; sceneData.visibleGaussianSplats.push_back({}); sceneData.visibleVolumes.push_back({}); + RenderGraphBlackboard blackboard = {}; + CameraFrameRenderGraphResources& frameResources = + blackboard.Emplace(); + frameResources.mainScene.color = colorTarget; + frameResources.mainScene.depth = depthTarget; bool executionSucceeded = true; const RenderPipelineMainSceneRenderGraphContext context = { graphBuilder, @@ -1154,8 +1165,8 @@ TEST(BuiltinForwardPipeline_Test, RecordsActiveFeatureInjectionPassesIntoMainSce ResourceStates::Common, { colorTarget }, depthTarget, - {}, - &executionSucceeded + &executionSucceeded, + &blackboard }; ASSERT_TRUE(pipeline.RecordMainSceneRenderGraph(context)); diff --git a/tests/Rendering/unit/test_camera_scene_renderer.cpp b/tests/Rendering/unit/test_camera_scene_renderer.cpp index 7ffa9e96..d01f2dde 100644 --- a/tests/Rendering/unit/test_camera_scene_renderer.cpp +++ b/tests/Rendering/unit/test_camera_scene_renderer.cpp @@ -419,21 +419,19 @@ public: bool RecordMainSceneRenderGraph( const RenderPipelineMainSceneRenderGraphContext& context) override { ++m_state->recordMainSceneCalls; - m_state->lastRecordedMainSceneShadowHandleValid = - context.mainDirectionalShadowTexture.IsValid(); m_state->lastReceivedRenderGraphBlackboard = context.blackboard != nullptr; - if (context.blackboard != nullptr) { - if (const CameraFrameRenderGraphResources* frameResources = - context.blackboard->TryGet()) { - m_state->lastBlackboardMainSceneColorValid = - frameResources->mainSceneColor.IsValid(); - m_state->lastBlackboardMainSceneDepthValid = - frameResources->mainSceneDepth.IsValid(); - m_state->lastBlackboardMainDirectionalShadowValid = - frameResources->mainDirectionalShadow.IsValid(); - m_state->lastBlackboardObjectIdColorValid = - frameResources->objectIdColor.IsValid(); - } + if (const CameraFrameRenderGraphResources* frameResources = + TryGetCameraFrameRenderGraphResources(context.blackboard)) { + m_state->lastBlackboardMainSceneColorValid = + frameResources->mainScene.color.IsValid(); + m_state->lastBlackboardMainSceneDepthValid = + frameResources->mainScene.depth.IsValid(); + m_state->lastBlackboardMainDirectionalShadowValid = + frameResources->mainDirectionalShadow.IsValid(); + m_state->lastBlackboardObjectIdColorValid = + frameResources->objectId.color.IsValid(); + m_state->lastRecordedMainSceneShadowHandleValid = + frameResources->mainDirectionalShadow.IsValid(); } if (!m_state->recordMainSceneResult) { return false; @@ -444,8 +442,12 @@ public: surface.SetAutoTransitionEnabled(false); const std::vector colorTargets = context.colorTargets; const RenderGraphTextureHandle depthTarget = context.depthTarget; + const CameraFrameRenderGraphResources* const frameResources = + TryGetCameraFrameRenderGraphResources(context.blackboard); const RenderGraphTextureHandle mainDirectionalShadowTexture = - context.mainDirectionalShadowTexture; + frameResources != nullptr + ? frameResources->mainDirectionalShadow + : RenderGraphTextureHandle{}; bool* const executionSucceeded = context.executionSucceeded; const std::shared_ptr state = m_state;