From 5d54799f054efd512f9fb073ee2aa56866f7f0c0 Mon Sep 17 00:00:00 2001 From: ssdfasd <2156608475@qq.com> Date: Wed, 15 Apr 2026 15:46:27 +0800 Subject: [PATCH] refactor(rendering): unify stage runtime request dispatch --- .../CameraFrameGraph/StageContract.cpp | 199 ++++++++++-------- ...test_camera_frame_graph_stage_contract.cpp | 29 +++ 2 files changed, 136 insertions(+), 92 deletions(-) diff --git a/engine/src/Rendering/Execution/Internal/CameraFrameGraph/StageContract.cpp b/engine/src/Rendering/Execution/Internal/CameraFrameGraph/StageContract.cpp index 3382a282..96f65a5b 100644 --- a/engine/src/Rendering/Execution/Internal/CameraFrameGraph/StageContract.cpp +++ b/engine/src/Rendering/Execution/Internal/CameraFrameGraph/StageContract.cpp @@ -12,33 +12,79 @@ namespace Rendering { namespace { -bool ExecuteCameraFrameScenePassRequestStage( - RenderPass* pass, - const ScenePassRenderRequest& request, - const RenderContext& renderContext, - const RenderSceneData& baseSceneData, - const RenderSurface& passSurface) { - if (!request.IsRequested()) { - return true; +struct CameraFrameStageRuntimeRequestBinding { + CameraFrameStageRequestKind requestKind = + CameraFrameStageRequestKind::None; + const ScenePassRenderRequest* scenePassRequest = nullptr; + const ObjectIdRenderRequest* objectIdRequest = nullptr; + + bool IsRequested() const { + switch (requestKind) { + case CameraFrameStageRequestKind::ShadowCaster: + case CameraFrameStageRequestKind::DepthOnly: + return scenePassRequest != nullptr; + case CameraFrameStageRequestKind::ObjectId: + return objectIdRequest != nullptr; + default: + return false; + } + } +}; + +const ScenePassRenderRequest* ResolveRequestedScenePassRequest( + const ScenePassRenderRequest* request) { + return request != nullptr && request->IsRequested() + ? request + : nullptr; +} + +const ObjectIdRenderRequest* ResolveRequestedObjectIdRequest( + const ObjectIdRenderRequest* request) { + return request != nullptr && request->IsRequested() + ? request + : nullptr; +} + +CameraFrameStageRuntimeRequestBinding ResolveCameraFrameStageRuntimeRequestBinding( + CameraFrameStage stage, + const CameraFrameRenderGraphStageContext& context) { + CameraFrameStageRuntimeRequestBinding binding = {}; + binding.requestKind = GetCameraFrameStageRequestKind(stage); + switch (binding.requestKind) { + case CameraFrameStageRequestKind::ShadowCaster: + binding.scenePassRequest = + ResolveRequestedScenePassRequest( + &context.shadowState.shadowCasterRequest); + break; + case CameraFrameStageRequestKind::DepthOnly: + binding.scenePassRequest = + ResolveRequestedScenePassRequest( + context.plan.GetScenePassRequest(stage)); + break; + case CameraFrameStageRequestKind::ObjectId: + binding.objectIdRequest = + ResolveRequestedObjectIdRequest( + context.plan.GetObjectIdRequest(stage)); + break; + default: + break; } - if (!InitializeCameraFrameStandaloneStagePass(pass, renderContext)) { - return false; - } + return binding; +} - const RenderSceneData sceneData = - BuildCameraFrameScenePassRequestSceneData( - request, - passSurface, +RenderSceneData BuildCameraFrameStandaloneStageSceneDataFromRequestBinding( + const CameraFrameStageRuntimeRequestBinding& binding, + const RenderSurface& stageSurface, + const RenderSceneData& baseSceneData) { + if (binding.scenePassRequest != nullptr) { + return BuildCameraFrameScenePassRequestSceneData( + *binding.scenePassRequest, + stageSurface, baseSceneData); - return pass->Execute({ - renderContext, - passSurface, - sceneData, - nullptr, - nullptr, - RHI::ResourceStates::Common - }); + } + + return baseSceneData; } bool ExecuteCameraFrameStandaloneStagePass( @@ -93,28 +139,19 @@ CameraFrameRenderGraphSourceBinding BuildCameraFrameStageGraphSourceBinding( const ScenePassRenderRequest* ResolveCameraFrameStageScenePassRequest( CameraFrameStage stage, const CameraFrameRenderGraphStageContext& context) { - switch (GetCameraFrameStageRequestKind(stage)) { - case CameraFrameStageRequestKind::ShadowCaster: - return context.shadowState.shadowCasterRequest.IsRequested() - ? &context.shadowState.shadowCasterRequest - : nullptr; - case CameraFrameStageRequestKind::DepthOnly: - return context.plan.request.depthOnly.IsRequested() - ? &context.plan.request.depthOnly - : nullptr; - default: - return nullptr; - } + return ResolveCameraFrameStageRuntimeRequestBinding( + stage, + context) + .scenePassRequest; } const ObjectIdRenderRequest* ResolveCameraFrameStageObjectIdRequest( CameraFrameStage stage, const CameraFrameRenderGraphStageContext& context) { - return GetCameraFrameStageRequestKind(stage) == - CameraFrameStageRequestKind::ObjectId && - context.plan.request.objectId.IsRequested() - ? &context.plan.request.objectId - : nullptr; + return ResolveCameraFrameStageRuntimeRequestBinding( + stage, + context) + .objectIdRequest; } RenderSceneData BuildCameraFrameScenePassRequestSceneData( @@ -157,18 +194,12 @@ RenderSceneData BuildCameraFrameStandaloneStageSceneData( CameraFrameStage stage, const CameraFrameRenderGraphStageContext& context, const RenderSurface& stageSurface) { - if (const ScenePassRenderRequest* request = - ResolveCameraFrameStageScenePassRequest( - stage, - context); - request != nullptr) { - return BuildCameraFrameScenePassRequestSceneData( - *request, - stageSurface, - context.sceneData); - } - - return context.sceneData; + return BuildCameraFrameStandaloneStageSceneDataFromRequestBinding( + ResolveCameraFrameStageRuntimeRequestBinding( + stage, + context), + stageSurface, + context.sceneData); } RenderPass* ResolveCameraFrameStandaloneStagePass( @@ -199,43 +230,13 @@ bool ExecuteCameraFrameRecordedStagePass( const CameraFrameRenderGraphStageContext& context, CameraFrameExecutionState& executionState, const RenderPassContext& passContext) { - if (IsCameraFrameScenePassRequestStage(stage)) { - const ScenePassRenderRequest* const request = - ResolveCameraFrameStageScenePassRequest( - stage, - context); - if (request == nullptr) { - return true; - } - - RenderPass* const standaloneStagePass = - ResolveCameraFrameStandaloneStagePass( - stage, - executionState); - return ExecuteCameraFrameScenePassRequestStage( - standaloneStagePass, - *request, - context.plan.request.context, - context.sceneData, - passContext.surface); - } - - if (GetCameraFrameStageExecutionKind(stage) == - CameraFrameStageExecutionKind::MainScenePipeline) { - return executionState.pipeline != nullptr && - executionState.pipeline->Render( - FrameExecutionContext( - context.plan.request.context, - passContext.surface, - context.sceneData, - passContext.sourceSurface, - passContext.sourceColorView, - passContext.sourceColorState)); - } - - if (GetCameraFrameStageRequestKind(stage) == - CameraFrameStageRequestKind::ObjectId) { - if (ResolveCameraFrameStageObjectIdRequest(stage, context) == nullptr) { + const CameraFrameStageRuntimeRequestBinding requestBinding = + ResolveCameraFrameStageRuntimeRequestBinding( + stage, + context); + switch (GetCameraFrameStageExecutionKind(stage)) { + case CameraFrameStageExecutionKind::StandalonePass: { + if (!requestBinding.IsRequested()) { return true; } @@ -247,10 +248,24 @@ bool ExecuteCameraFrameRecordedStagePass( standaloneStagePass, context.plan.request.context, passContext.surface, - context.sceneData); + BuildCameraFrameStandaloneStageSceneDataFromRequestBinding( + requestBinding, + passContext.surface, + context.sceneData)); + } + case CameraFrameStageExecutionKind::MainScenePipeline: + return executionState.pipeline != nullptr && + executionState.pipeline->Render( + FrameExecutionContext( + context.plan.request.context, + passContext.surface, + context.sceneData, + passContext.sourceSurface, + passContext.sourceColorView, + passContext.sourceColorState)); + default: + return false; } - - return false; } RenderPassContext BuildCameraFrameStageGraphPassContext( diff --git a/tests/Rendering/unit/test_camera_frame_graph_stage_contract.cpp b/tests/Rendering/unit/test_camera_frame_graph_stage_contract.cpp index dd9c0721..aef757a2 100644 --- a/tests/Rendering/unit/test_camera_frame_graph_stage_contract.cpp +++ b/tests/Rendering/unit/test_camera_frame_graph_stage_contract.cpp @@ -1316,6 +1316,35 @@ TEST(CameraFrameRenderGraphStageContract_Test, SkipsObjectIdRecordedStageWhenReq EXPECT_EQ(objectIdPass->executeCalls, 0); } +TEST(CameraFrameRenderGraphStageContract_Test, SkipsShadowCasterRecordedStageWhenRequestIsMissing) { + StageContractTestContext testContext = {}; + RecordingPipeline pipeline = {}; + testContext.executionState.pipeline = &pipeline; + RecordingRenderPass* const shadowPass = + InstallStandaloneStagePass( + pipeline, + CameraFrameStage::ShadowCaster); + + const CameraFrameRenderGraphStageContext context = testContext.BuildStageContext(); + const RenderSurface outputSurface(800, 600); + const RenderPassContext passContext = { + testContext.plan.request.context, + outputSurface, + testContext.sceneData, + nullptr, + nullptr, + XCEngine::RHI::ResourceStates::Common + }; + + EXPECT_TRUE(ExecuteCameraFrameRecordedStagePass( + CameraFrameStage::ShadowCaster, + context, + testContext.executionState, + passContext)); + EXPECT_EQ(shadowPass->initializeCalls, 0); + EXPECT_EQ(shadowPass->executeCalls, 0); +} + TEST(CameraFrameRenderGraphStageContract_Test, ExecutesDepthOnlyFallbackPassUsingResolvedFallbackSurface) { StageContractTestContext testContext = {}; RecordingPipeline pipeline = {};