From 1ad3bfc702e6e34a5f7bd6d787fa4f71ae27cf8c Mon Sep 17 00:00:00 2001 From: ssdfasd <2156608475@qq.com> Date: Wed, 15 Apr 2026 15:20:59 +0800 Subject: [PATCH] refactor(rendering): centralize fullscreen stage surface resolution --- .../Rendering/Execution/CameraFramePlan.h | 1 + .../Rendering/Execution/CameraFramePlan.cpp | 18 ++++ .../CameraFrameGraph/SurfaceResolver.h | 102 ++++++++++-------- .../unit/test_camera_scene_renderer.cpp | 3 + 4 files changed, 78 insertions(+), 46 deletions(-) diff --git a/engine/include/XCEngine/Rendering/Execution/CameraFramePlan.h b/engine/include/XCEngine/Rendering/Execution/CameraFramePlan.h index 50524b21..b4404b3a 100644 --- a/engine/include/XCEngine/Rendering/Execution/CameraFramePlan.h +++ b/engine/include/XCEngine/Rendering/Execution/CameraFramePlan.h @@ -50,6 +50,7 @@ struct CameraFramePlan { bool IsFinalOutputStageValid() const; bool HasFrameStage(CameraFrameStage stage) const; RenderPassSequence* GetPassSequence(CameraFrameStage stage) const; + const FullscreenPassRenderRequest* GetFullscreenPassRequest(CameraFrameStage stage) const; const ScenePassRenderRequest* GetScenePassRequest(CameraFrameStage stage) const; const ObjectIdRenderRequest* GetObjectIdRequest(CameraFrameStage stage) const; const RenderSurface& GetMainSceneSurface() const; diff --git a/engine/src/Rendering/Execution/CameraFramePlan.cpp b/engine/src/Rendering/Execution/CameraFramePlan.cpp index ac85563c..2f1ca458 100644 --- a/engine/src/Rendering/Execution/CameraFramePlan.cpp +++ b/engine/src/Rendering/Execution/CameraFramePlan.cpp @@ -107,6 +107,12 @@ bool CameraFramePlan::HasFrameStage(CameraFrameStage stage) const { } if (IsCameraFrameSequenceStage(stage)) { + if (const FullscreenPassRenderRequest* fullscreenRequest = + GetFullscreenPassRequest(stage); + fullscreenRequest != nullptr) { + return fullscreenRequest->IsRequested(); + } + return GetPassSequence(stage) != nullptr; } @@ -143,6 +149,18 @@ RenderPassSequence* CameraFramePlan::GetPassSequence(CameraFrameStage stage) con } } +const FullscreenPassRenderRequest* CameraFramePlan::GetFullscreenPassRequest( + CameraFrameStage stage) const { + switch (stage) { + case CameraFrameStage::PostProcess: + return &postProcess; + case CameraFrameStage::FinalOutput: + return &finalOutput; + default: + return nullptr; + } +} + const ScenePassRenderRequest* CameraFramePlan::GetScenePassRequest(CameraFrameStage stage) const { switch (GetCameraFrameStageRequestKind(stage)) { case CameraFrameStageRequestKind::ShadowCaster: diff --git a/engine/src/Rendering/Execution/Internal/CameraFrameGraph/SurfaceResolver.h b/engine/src/Rendering/Execution/Internal/CameraFrameGraph/SurfaceResolver.h index 0a9181ce..d4f7bb84 100644 --- a/engine/src/Rendering/Execution/Internal/CameraFrameGraph/SurfaceResolver.h +++ b/engine/src/Rendering/Execution/Internal/CameraFrameGraph/SurfaceResolver.h @@ -13,69 +13,79 @@ struct CameraFrameStageSourceBinding { RHI::ResourceStates sourceColorState = RHI::ResourceStates::Common; }; -inline const RenderSurface* ResolveCameraFrameStageOutputSurface( +inline const ScenePassRenderRequest* ResolveCameraFrameStageOutputScenePassRequest( CameraFrameStage stage, const CameraFramePlan& plan, const DirectionalShadowExecutionState& shadowState) { - switch (stage) { - case CameraFrameStage::PreScenePasses: - case CameraFrameStage::MainScene: - return &plan.GetMainSceneSurface(); - case CameraFrameStage::ShadowCaster: + switch (GetCameraFrameStageRequestKind(stage)) { + case CameraFrameStageRequestKind::ShadowCaster: return shadowState.shadowCasterRequest.IsRequested() - ? &shadowState.shadowCasterRequest.surface + ? &shadowState.shadowCasterRequest : 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(); + case CameraFrameStageRequestKind::DepthOnly: + return plan.GetScenePassRequest(stage); default: return nullptr; } } +inline const RenderSurface* ResolveCameraFrameStageOutputSurface( + CameraFrameStage stage, + const CameraFramePlan& plan, + const DirectionalShadowExecutionState& shadowState) { + if (stage == CameraFrameStage::PreScenePasses || + stage == CameraFrameStage::MainScene) { + return &plan.GetMainSceneSurface(); + } + + if (const ScenePassRenderRequest* scenePassRequest = + ResolveCameraFrameStageOutputScenePassRequest( + stage, + plan, + shadowState); + scenePassRequest != nullptr && scenePassRequest->IsRequested()) { + return &scenePassRequest->surface; + } + + if (const FullscreenPassRenderRequest* fullscreenRequest = + plan.GetFullscreenPassRequest(stage); + fullscreenRequest != nullptr && + fullscreenRequest->IsRequested() && + HasValidColorTarget(fullscreenRequest->destinationSurface)) { + return &fullscreenRequest->destinationSurface; + } + + if (const ObjectIdRenderRequest* objectIdRequest = + plan.GetObjectIdRequest(stage); + objectIdRequest != nullptr && objectIdRequest->IsRequested()) { + return &objectIdRequest->surface; + } + + if (stage == CameraFrameStage::PostScenePasses || + stage == CameraFrameStage::OverlayPasses) { + return &plan.GetFinalCompositedSurface(); + } + + return nullptr; +} + inline CameraFrameStageSourceBinding ResolveCameraFrameStageSourceBinding( CameraFrameStage stage, const CameraFramePlan& plan) { - switch (stage) { - case CameraFrameStage::PostProcess: - return plan.postProcess.IsRequested() && - plan.ResolveStageColorSource(CameraFrameStage::PostProcess) == + if (const FullscreenPassRenderRequest* fullscreenRequest = + plan.GetFullscreenPassRequest(stage); + fullscreenRequest != nullptr) { + return fullscreenRequest->IsRequested() && + plan.ResolveStageColorSource(stage) == CameraFrameColorSource::ExplicitSurface ? CameraFrameStageSourceBinding{ - &plan.postProcess.sourceSurface, - plan.postProcess.sourceColorView, - plan.postProcess.sourceColorState } + &fullscreenRequest->sourceSurface, + fullscreenRequest->sourceColorView, + fullscreenRequest->sourceColorState } : CameraFrameStageSourceBinding{}; - case CameraFrameStage::FinalOutput: - return plan.finalOutput.IsRequested() && - plan.ResolveStageColorSource(CameraFrameStage::FinalOutput) == - CameraFrameColorSource::ExplicitSurface - ? CameraFrameStageSourceBinding{ - &plan.finalOutput.sourceSurface, - plan.finalOutput.sourceColorView, - plan.finalOutput.sourceColorState } - : CameraFrameStageSourceBinding{}; - default: - return {}; } + + return {}; } inline RenderPassContext BuildCameraFrameStagePassContext( diff --git a/tests/Rendering/unit/test_camera_scene_renderer.cpp b/tests/Rendering/unit/test_camera_scene_renderer.cpp index 2e5c5cda..78b1398b 100644 --- a/tests/Rendering/unit/test_camera_scene_renderer.cpp +++ b/tests/Rendering/unit/test_camera_scene_renderer.cpp @@ -943,6 +943,9 @@ TEST(CameraRenderRequest_Test, ReportsFormalFrameStageContract) { EXPECT_EQ(plan.GetPassSequence(CameraFrameStage::FinalOutput), &finalOutputPasses); EXPECT_EQ(plan.GetPassSequence(CameraFrameStage::PostScenePasses), &postPasses); EXPECT_EQ(plan.GetPassSequence(CameraFrameStage::OverlayPasses), &overlayPasses); + EXPECT_EQ(plan.GetFullscreenPassRequest(CameraFrameStage::PostProcess), &plan.postProcess); + EXPECT_EQ(plan.GetFullscreenPassRequest(CameraFrameStage::FinalOutput), &plan.finalOutput); + EXPECT_EQ(plan.GetFullscreenPassRequest(CameraFrameStage::MainScene), nullptr); EXPECT_EQ(plan.GetScenePassRequest(CameraFrameStage::ShadowCaster), &plan.shadowCaster); EXPECT_EQ(plan.GetScenePassRequest(CameraFrameStage::DepthOnly), &plan.request.depthOnly); EXPECT_EQ(plan.GetScenePassRequest(CameraFrameStage::MainScene), nullptr);