From ac836ae9618e77a5078b195eb492de53228cd888 Mon Sep 17 00:00:00 2001 From: ssdfasd <2156608475@qq.com> Date: Wed, 15 Apr 2026 00:25:19 +0800 Subject: [PATCH] Extract camera frame stage surface resolver --- .../Rendering/Execution/CameraFramePlan.h | 80 --------------- .../CameraFrameRenderGraphStageState.cpp | 46 +-------- .../CameraFrameStageSurfaceResolver.h | 99 +++++++++++++++++++ .../unit/test_camera_scene_renderer.cpp | 90 ++++++++++++----- 4 files changed, 165 insertions(+), 150 deletions(-) create mode 100644 engine/src/Rendering/Execution/Internal/CameraFrameStageSurfaceResolver.h diff --git a/engine/include/XCEngine/Rendering/Execution/CameraFramePlan.h b/engine/include/XCEngine/Rendering/Execution/CameraFramePlan.h index a25335d3..ce44010e 100644 --- a/engine/include/XCEngine/Rendering/Execution/CameraFramePlan.h +++ b/engine/include/XCEngine/Rendering/Execution/CameraFramePlan.h @@ -190,86 +190,6 @@ struct CameraFramePlan { return request.surface; } - const RenderSurface* GetOutputSurface(CameraFrameStage stage) const { - switch (stage) { - case CameraFrameStage::PreScenePasses: - case CameraFrameStage::MainScene: - return &GetMainSceneSurface(); - case CameraFrameStage::ShadowCaster: - return shadowCaster.IsRequested() ? &shadowCaster.surface : nullptr; - case CameraFrameStage::DepthOnly: - return request.depthOnly.IsRequested() ? &request.depthOnly.surface : nullptr; - case CameraFrameStage::PostProcess: - return postProcess.IsRequested() && - HasValidColorTarget(postProcess.destinationSurface) - ? &postProcess.destinationSurface - : nullptr; - case CameraFrameStage::FinalOutput: - return finalOutput.IsRequested() && - HasValidColorTarget(finalOutput.destinationSurface) - ? &finalOutput.destinationSurface - : nullptr; - case CameraFrameStage::ObjectId: - return request.objectId.IsRequested() ? &request.objectId.surface : nullptr; - case CameraFrameStage::PostScenePasses: - case CameraFrameStage::OverlayPasses: - return &GetFinalCompositedSurface(); - default: - return nullptr; - } - } - - const RenderSurface* GetSourceSurface(CameraFrameStage stage) const { - switch (stage) { - case CameraFrameStage::PostProcess: - return postProcess.IsRequested() && - postProcessSource == CameraFrameColorSource::ExplicitSurface - ? &postProcess.sourceSurface - : nullptr; - case CameraFrameStage::FinalOutput: - return finalOutput.IsRequested() && - finalOutputSource == CameraFrameColorSource::ExplicitSurface - ? &finalOutput.sourceSurface - : nullptr; - default: - return nullptr; - } - } - - RHI::RHIResourceView* GetSourceColorView(CameraFrameStage stage) const { - switch (stage) { - case CameraFrameStage::PostProcess: - return postProcess.IsRequested() && - postProcessSource == CameraFrameColorSource::ExplicitSurface - ? postProcess.sourceColorView - : nullptr; - case CameraFrameStage::FinalOutput: - return finalOutput.IsRequested() && - finalOutputSource == CameraFrameColorSource::ExplicitSurface - ? finalOutput.sourceColorView - : nullptr; - default: - return nullptr; - } - } - - RHI::ResourceStates GetSourceColorState(CameraFrameStage stage) const { - switch (stage) { - case CameraFrameStage::PostProcess: - return postProcess.IsRequested() && - postProcessSource == CameraFrameColorSource::ExplicitSurface - ? postProcess.sourceColorState - : RHI::ResourceStates::Common; - case CameraFrameStage::FinalOutput: - return finalOutput.IsRequested() && - finalOutputSource == CameraFrameColorSource::ExplicitSurface - ? finalOutput.sourceColorState - : RHI::ResourceStates::Common; - default: - return RHI::ResourceStates::Common; - } - } - bool RequiresIntermediateSceneColor() const { return postProcess.IsRequested() || finalOutput.IsRequested(); } diff --git a/engine/src/Rendering/Execution/Internal/CameraFrameRenderGraphStageState.cpp b/engine/src/Rendering/Execution/Internal/CameraFrameRenderGraphStageState.cpp index a83e7998..7bbac8dd 100644 --- a/engine/src/Rendering/Execution/Internal/CameraFrameRenderGraphStageState.cpp +++ b/engine/src/Rendering/Execution/Internal/CameraFrameRenderGraphStageState.cpp @@ -4,53 +4,11 @@ #include "Rendering/Execution/CameraFrameRenderGraphStagePolicy.h" #include "Rendering/Execution/DirectionalShadowExecutionState.h" #include "Rendering/Execution/Internal/CameraFrameRenderGraphStageRecordContext.h" +#include "Rendering/Execution/Internal/CameraFrameStageSurfaceResolver.h" namespace XCEngine { namespace Rendering { -namespace { - -const RenderSurface* ResolveFrameStageOutputSurface( - CameraFrameStage stage, - const CameraFramePlan& plan, - const DirectionalShadowExecutionState& shadowState) { - switch (stage) { - case CameraFrameStage::ShadowCaster: - return shadowState.shadowCasterRequest.IsRequested() - ? &shadowState.shadowCasterRequest.surface - : nullptr; - case CameraFrameStage::DepthOnly: - return plan.request.depthOnly.IsRequested() - ? &plan.request.depthOnly.surface - : nullptr; - case CameraFrameStage::ObjectId: - return plan.request.objectId.IsRequested() - ? &plan.request.objectId.surface - : nullptr; - default: - return plan.GetOutputSurface(stage); - } -} - -RenderPassContext BuildFrameStagePassContext( - CameraFrameStage stage, - const CameraFramePlan& plan, - const DirectionalShadowExecutionState& shadowState, - const RenderSceneData& sceneData) { - const RenderSurface* outputSurface = - ResolveFrameStageOutputSurface(stage, plan, shadowState); - return { - plan.request.context, - outputSurface != nullptr ? *outputSurface : plan.request.surface, - sceneData, - plan.GetSourceSurface(stage), - plan.GetSourceColorView(stage), - plan.GetSourceColorState(stage) - }; -} - -} // namespace - RenderPassContext BuildCameraFrameStageGraphPassContext( const CameraFrameRenderGraphStageRecordContext& context, const CameraFrameStageGraphBuildState& stageState, @@ -76,7 +34,7 @@ CameraFrameStageGraphBuildState BuildCameraFrameStageGraphBuildState( stageState.stageSequence = context.plan.GetPassSequence(stage); const RenderPassContext stagePassContext = - BuildFrameStagePassContext( + BuildCameraFrameStagePassContext( stage, context.plan, context.shadowState, diff --git a/engine/src/Rendering/Execution/Internal/CameraFrameStageSurfaceResolver.h b/engine/src/Rendering/Execution/Internal/CameraFrameStageSurfaceResolver.h new file mode 100644 index 00000000..2acfd822 --- /dev/null +++ b/engine/src/Rendering/Execution/Internal/CameraFrameStageSurfaceResolver.h @@ -0,0 +1,99 @@ +#pragma once + +#include +#include +#include + +namespace XCEngine { +namespace Rendering { + +struct CameraFrameStageSourceBinding { + const RenderSurface* sourceSurface = nullptr; + RHI::RHIResourceView* sourceColorView = nullptr; + RHI::ResourceStates sourceColorState = RHI::ResourceStates::Common; +}; + +inline const RenderSurface* ResolveCameraFrameStageOutputSurface( + CameraFrameStage stage, + const CameraFramePlan& plan, + const DirectionalShadowExecutionState& shadowState) { + switch (stage) { + case CameraFrameStage::PreScenePasses: + case CameraFrameStage::MainScene: + return &plan.GetMainSceneSurface(); + case CameraFrameStage::ShadowCaster: + return shadowState.shadowCasterRequest.IsRequested() + ? &shadowState.shadowCasterRequest.surface + : nullptr; + case CameraFrameStage::DepthOnly: + return plan.request.depthOnly.IsRequested() + ? &plan.request.depthOnly.surface + : nullptr; + case CameraFrameStage::PostProcess: + return plan.postProcess.IsRequested() && + HasValidColorTarget(plan.postProcess.destinationSurface) + ? &plan.postProcess.destinationSurface + : nullptr; + case CameraFrameStage::FinalOutput: + return plan.finalOutput.IsRequested() && + HasValidColorTarget(plan.finalOutput.destinationSurface) + ? &plan.finalOutput.destinationSurface + : nullptr; + case CameraFrameStage::ObjectId: + return plan.request.objectId.IsRequested() + ? &plan.request.objectId.surface + : nullptr; + case CameraFrameStage::PostScenePasses: + case CameraFrameStage::OverlayPasses: + return &plan.GetFinalCompositedSurface(); + default: + return nullptr; + } +} + +inline CameraFrameStageSourceBinding ResolveCameraFrameStageSourceBinding( + CameraFrameStage stage, + const CameraFramePlan& plan) { + switch (stage) { + case CameraFrameStage::PostProcess: + return plan.postProcess.IsRequested() && + plan.postProcessSource == CameraFrameColorSource::ExplicitSurface + ? CameraFrameStageSourceBinding{ + &plan.postProcess.sourceSurface, + plan.postProcess.sourceColorView, + plan.postProcess.sourceColorState } + : CameraFrameStageSourceBinding{}; + case CameraFrameStage::FinalOutput: + return plan.finalOutput.IsRequested() && + plan.finalOutputSource == CameraFrameColorSource::ExplicitSurface + ? CameraFrameStageSourceBinding{ + &plan.finalOutput.sourceSurface, + plan.finalOutput.sourceColorView, + plan.finalOutput.sourceColorState } + : CameraFrameStageSourceBinding{}; + default: + return {}; + } +} + +inline RenderPassContext BuildCameraFrameStagePassContext( + CameraFrameStage stage, + const CameraFramePlan& plan, + const DirectionalShadowExecutionState& shadowState, + const RenderSceneData& sceneData) { + const RenderSurface* outputSurface = + ResolveCameraFrameStageOutputSurface(stage, plan, shadowState); + const CameraFrameStageSourceBinding sourceBinding = + ResolveCameraFrameStageSourceBinding(stage, plan); + return { + plan.request.context, + outputSurface != nullptr ? *outputSurface : plan.request.surface, + sceneData, + sourceBinding.sourceSurface, + sourceBinding.sourceColorView, + sourceBinding.sourceColorState + }; +} + +} // namespace Rendering +} // namespace XCEngine diff --git a/tests/Rendering/unit/test_camera_scene_renderer.cpp b/tests/Rendering/unit/test_camera_scene_renderer.cpp index 67fb8d7f..efb8b715 100644 --- a/tests/Rendering/unit/test_camera_scene_renderer.cpp +++ b/tests/Rendering/unit/test_camera_scene_renderer.cpp @@ -16,6 +16,7 @@ #include #include +#include "Rendering/Execution/Internal/CameraFrameStageSurfaceResolver.h" #include "Rendering/Internal/RenderPassGraphUtils.h" #include @@ -27,6 +28,21 @@ using namespace XCEngine::Rendering; namespace { +const RenderSurface* ResolveStageOutputSurface( + CameraFrameStage stage, + const CameraFramePlan& plan) { + return ResolveCameraFrameStageOutputSurface( + stage, + plan, + DirectionalShadowExecutionState{}); +} + +CameraFrameStageSourceBinding ResolveStageSourceBinding( + CameraFrameStage stage, + const CameraFramePlan& plan) { + return ResolveCameraFrameStageSourceBinding(stage, plan); +} + struct MockPipelineState { int initializeCalls = 0; int shutdownCalls = 0; @@ -928,23 +944,29 @@ TEST(CameraRenderRequest_Test, ReportsFormalFrameStageContract) { EXPECT_EQ(plan.GetMainSceneSurface().GetRenderAreaHeight(), 128u); EXPECT_EQ(plan.GetFinalCompositedSurface().GetRenderAreaWidth(), 640u); EXPECT_EQ(plan.GetFinalCompositedSurface().GetRenderAreaHeight(), 360u); - ASSERT_NE(plan.GetOutputSurface(CameraFrameStage::PostProcess), nullptr); - EXPECT_EQ(plan.GetOutputSurface(CameraFrameStage::PostProcess)->GetRenderAreaWidth(), 512u); - ASSERT_NE(plan.GetSourceSurface(CameraFrameStage::PostProcess), nullptr); - EXPECT_EQ(plan.GetSourceSurface(CameraFrameStage::PostProcess)->GetRenderAreaWidth(), 256u); + const RenderSurface* const postProcessOutput = + ResolveStageOutputSurface(CameraFrameStage::PostProcess, plan); + const CameraFrameStageSourceBinding postProcessSource = + ResolveStageSourceBinding(CameraFrameStage::PostProcess, plan); + ASSERT_NE(postProcessOutput, nullptr); + EXPECT_EQ(postProcessOutput->GetRenderAreaWidth(), 512u); + ASSERT_NE(postProcessSource.sourceSurface, nullptr); + EXPECT_EQ(postProcessSource.sourceSurface->GetRenderAreaWidth(), 256u); EXPECT_EQ( - plan.GetSourceColorView(CameraFrameStage::PostProcess), + postProcessSource.sourceColorView, reinterpret_cast(20)); EXPECT_EQ( - plan.GetSourceColorState(CameraFrameStage::PostProcess), + postProcessSource.sourceColorState, XCEngine::RHI::ResourceStates::PixelShaderResource); - ASSERT_NE(plan.GetSourceSurface(CameraFrameStage::FinalOutput), nullptr); - EXPECT_EQ(plan.GetSourceSurface(CameraFrameStage::FinalOutput)->GetRenderAreaWidth(), 512u); + const CameraFrameStageSourceBinding finalOutputSource = + ResolveStageSourceBinding(CameraFrameStage::FinalOutput, plan); + ASSERT_NE(finalOutputSource.sourceSurface, nullptr); + EXPECT_EQ(finalOutputSource.sourceSurface->GetRenderAreaWidth(), 512u); EXPECT_EQ( - plan.GetSourceColorView(CameraFrameStage::FinalOutput), + finalOutputSource.sourceColorView, reinterpret_cast(40)); EXPECT_EQ( - plan.GetSourceColorState(CameraFrameStage::FinalOutput), + finalOutputSource.sourceColorState, XCEngine::RHI::ResourceStates::PixelShaderResource); } @@ -2880,10 +2902,12 @@ TEST(SceneRenderer_Test, BuildsCameraColorScalePostProcessRequestFromCameraPassS EXPECT_EQ(sourceRenderArea.y, 75); EXPECT_EQ(sourceRenderArea.width, 400); EXPECT_EQ(sourceRenderArea.height, 375); - EXPECT_EQ(plan.GetSourceSurface(CameraFrameStage::PostProcess), nullptr); - EXPECT_EQ(plan.GetSourceColorView(CameraFrameStage::PostProcess), nullptr); + const CameraFrameStageSourceBinding postProcessSource = + ResolveStageSourceBinding(CameraFrameStage::PostProcess, plan); + EXPECT_EQ(postProcessSource.sourceSurface, nullptr); + EXPECT_EQ(postProcessSource.sourceColorView, nullptr); EXPECT_EQ( - plan.GetSourceColorState(CameraFrameStage::PostProcess), + postProcessSource.sourceColorState, XCEngine::RHI::ResourceStates::Common); EXPECT_EQ(allocationState->createTextureCalls, 0); EXPECT_EQ(allocationState->createRenderTargetViewCalls, 0); @@ -3010,10 +3034,12 @@ TEST(SceneRenderer_Test, BuildsFinalOutputRequestFromResolvedFinalColorPolicy) { XCEngine::RHI::ResourceStates::PixelShaderResource); EXPECT_EQ(plan.GetMainSceneSurface().GetWidth(), 800u); EXPECT_EQ(plan.GetMainSceneSurface().GetHeight(), 600u); - EXPECT_EQ(plan.GetSourceSurface(CameraFrameStage::FinalOutput), nullptr); - EXPECT_EQ(plan.GetSourceColorView(CameraFrameStage::FinalOutput), nullptr); + const CameraFrameStageSourceBinding finalOutputSource = + ResolveStageSourceBinding(CameraFrameStage::FinalOutput, plan); + EXPECT_EQ(finalOutputSource.sourceSurface, nullptr); + EXPECT_EQ(finalOutputSource.sourceColorView, nullptr); EXPECT_EQ( - plan.GetSourceColorState(CameraFrameStage::FinalOutput), + finalOutputSource.sourceColorState, XCEngine::RHI::ResourceStates::Common); EXPECT_EQ(allocationState->createTextureCalls, 0); EXPECT_EQ(allocationState->createRenderTargetViewCalls, 0); @@ -3085,9 +3111,15 @@ TEST(SceneRenderer_Test, RoutesPostProcessIntoIntermediateSurfaceBeforeFinalOutp EXPECT_EQ(plan.postProcessSource, CameraFrameColorSource::MainSceneColor); EXPECT_EQ(plan.finalOutputSource, CameraFrameColorSource::PostProcessColor); - EXPECT_EQ(plan.GetSourceSurface(CameraFrameStage::PostProcess), nullptr); - EXPECT_EQ(plan.GetOutputSurface(CameraFrameStage::PostProcess), nullptr); - EXPECT_EQ(plan.GetSourceSurface(CameraFrameStage::FinalOutput), nullptr); + const CameraFrameStageSourceBinding postProcessSource = + ResolveStageSourceBinding(CameraFrameStage::PostProcess, plan); + const RenderSurface* const postProcessOutput = + ResolveStageOutputSurface(CameraFrameStage::PostProcess, plan); + const CameraFrameStageSourceBinding finalOutputSource = + ResolveStageSourceBinding(CameraFrameStage::FinalOutput, plan); + EXPECT_EQ(postProcessSource.sourceSurface, nullptr); + EXPECT_EQ(postProcessOutput, nullptr); + EXPECT_EQ(finalOutputSource.sourceSurface, nullptr); EXPECT_EQ(plan.finalOutput.destinationSurface.GetColorAttachments()[0], backBufferColorView); EXPECT_EQ(plan.finalOutput.destinationSurface.GetDepthAttachment(), depthView); EXPECT_EQ( @@ -3106,13 +3138,13 @@ TEST(SceneRenderer_Test, RoutesPostProcessIntoIntermediateSurfaceBeforeFinalOutp EXPECT_EQ(finalOutputSourceArea.y, 75); EXPECT_EQ(finalOutputSourceArea.width, 400); EXPECT_EQ(finalOutputSourceArea.height, 375); - EXPECT_EQ(plan.GetSourceColorView(CameraFrameStage::PostProcess), nullptr); - EXPECT_EQ(plan.GetSourceColorView(CameraFrameStage::FinalOutput), nullptr); + EXPECT_EQ(postProcessSource.sourceColorView, nullptr); + EXPECT_EQ(finalOutputSource.sourceColorView, nullptr); EXPECT_EQ( - plan.GetSourceColorState(CameraFrameStage::PostProcess), + postProcessSource.sourceColorState, XCEngine::RHI::ResourceStates::Common); EXPECT_EQ( - plan.GetSourceColorState(CameraFrameStage::FinalOutput), + finalOutputSource.sourceColorState, XCEngine::RHI::ResourceStates::Common); EXPECT_EQ(allocationState->createTextureCalls, 0); EXPECT_EQ(allocationState->createRenderTargetViewCalls, 0); @@ -3309,7 +3341,9 @@ TEST(SceneRenderer_Test, KeepsPostProcessOutputGraphManagedWhenFinalOutputIsEnab EXPECT_EQ( firstFramePlan.GetMainSceneSurface().GetColorStateBefore(), XCEngine::RHI::ResourceStates::Common); - EXPECT_EQ(firstFramePlan.GetOutputSurface(CameraFrameStage::PostProcess), nullptr); + EXPECT_EQ( + ResolveStageOutputSurface(CameraFrameStage::PostProcess, firstFramePlan), + nullptr); RenderPassSequence postProcessPasses; postProcessPasses.AddPass(std::make_unique(pipelineState, "postProcess")); @@ -3335,8 +3369,12 @@ TEST(SceneRenderer_Test, KeepsPostProcessOutputGraphManagedWhenFinalOutputIsEnab EXPECT_EQ( secondFramePlan.GetMainSceneSurface().GetColorStateBefore(), XCEngine::RHI::ResourceStates::Common); - EXPECT_EQ(secondFramePlan.GetOutputSurface(CameraFrameStage::PostProcess), nullptr); - EXPECT_EQ(secondFramePlan.GetSourceSurface(CameraFrameStage::FinalOutput), nullptr); + EXPECT_EQ( + ResolveStageOutputSurface(CameraFrameStage::PostProcess, secondFramePlan), + nullptr); + EXPECT_EQ( + ResolveStageSourceBinding(CameraFrameStage::FinalOutput, secondFramePlan).sourceSurface, + nullptr); EXPECT_EQ(allocationState->createTextureCalls, createTextureCallsAfterFirstRender); EXPECT_EQ( allocationState->createRenderTargetViewCalls,