diff --git a/docs/used/SRP_UniversalFullscreenStageHeuristicCleanupPlan_完成归档_2026-04-21.md b/docs/used/SRP_UniversalFullscreenStageHeuristicCleanupPlan_完成归档_2026-04-21.md new file mode 100644 index 00000000..21b41b3b --- /dev/null +++ b/docs/used/SRP_UniversalFullscreenStageHeuristicCleanupPlan_完成归档_2026-04-21.md @@ -0,0 +1,58 @@ +# SRP Universal Fullscreen Stage Heuristic Cleanup Plan 2026-04-21 + +## Goal + +Remove the native fullscreen-stage support heuristic from `CameraFramePlanBuilder` so managed URP stage planning no longer depends on hidden native inference from pipeline render-graph capability. + +## Why This Stage + +The current SRP split already gives managed URP explicit fullscreen-stage planning seams: + +1. `ScriptableRenderPipelineAsset.ConfigureCameraFramePlan(...)` +2. `ScriptableRendererData.ConfigureCameraFramePlan(...)` +3. `ScriptableRenderer.ConfigureCameraFramePlan(...)` +4. `ScriptableRendererFeature.ConfigureCameraFramePlan(...)` + +But `CameraFramePlanBuilder` still probes `pipeline->SupportsStageRenderGraph(...)` and silently upgrades that into requested `PostProcess` / `FinalOutput` stages. + +That keeps one native hidden decision path alive after managed URP already became capable of requesting those stages itself. + +## Scope + +Included: + +1. remove pipeline-support probing from `CameraFramePlanBuilder`; +2. keep legacy fullscreen pass-sequence requests working; +3. simplify `CameraFramePlanBuilder` interface so it no longer depends on `RenderPipeline`; +4. rebuild `XCEditor` and run old editor smoke. + +Not included: + +1. changing managed URP pass authoring APIs; +2. moving native fullscreen pass-sequence construction into C#; +3. deferred rendering work; +4. renderer inspector/editor integration. + +## Acceptance + +This stage is complete when: + +1. fullscreen stage requests are no longer inferred from `SupportsStageRenderGraph(...)` inside `CameraFramePlanBuilder`; +2. managed URP remains the explicit owner of renderer-driven fullscreen stages; +3. legacy native fullscreen pass sequences still request their stages correctly; +4. `XCEditor` build and old editor smoke both pass. + +## Result + +Completed. + +`CameraFramePlanBuilder` no longer probes pipeline stage support to infer `PostProcess` or `FinalOutput`. +It now only bridges already-authored legacy fullscreen pass-sequence requests into runtime stage requests, while managed URP keeps explicit ownership of renderer-driven fullscreen stage planning. + +The builder interface was also narrowed so it no longer takes a `RenderPipeline*`, which makes the class boundary reflect its actual responsibility. + +## Validation + +1. `cmake --build . --config Debug --target XCEditor` +2. launched `editor/bin/Debug/XCEngine.exe` for about 12 seconds +3. verified `editor/bin/Debug/editor.log` contains new `SceneReady` at `2026-04-21 12:35:36` diff --git a/engine/src/Rendering/Execution/RenderPipelineHost.cpp b/engine/src/Rendering/Execution/RenderPipelineHost.cpp index ea7b6b39..86bf5ff2 100644 --- a/engine/src/Rendering/Execution/RenderPipelineHost.cpp +++ b/engine/src/Rendering/Execution/RenderPipelineHost.cpp @@ -47,8 +47,7 @@ std::vector RenderPipelineHost::BuildFramePlans( return m_framePlanBuilder != nullptr ? m_framePlanBuilder->BuildPlans( requests, - GetPipelineAsset(), - GetPipeline()) + GetPipelineAsset()) : std::vector(); } diff --git a/engine/src/Rendering/Planning/CameraFramePlanBuilder.cpp b/engine/src/Rendering/Planning/CameraFramePlanBuilder.cpp index 41489ddb..6bc35e7c 100644 --- a/engine/src/Rendering/Planning/CameraFramePlanBuilder.cpp +++ b/engine/src/Rendering/Planning/CameraFramePlanBuilder.cpp @@ -1,6 +1,5 @@ #include "Rendering/Planning/CameraFramePlanBuilder.h" -#include "Rendering/RenderPipeline.h" #include "Rendering/RenderPipelineAsset.h" namespace XCEngine { @@ -15,41 +14,18 @@ bool UsesExplicitFullscreenSource( HasValidColorTarget(request.sourceSurface); } -RenderPipelineStageSupportContext BuildStageSupportContext( - const CameraFramePlan& plan, - CameraFrameStage stage) { - return RenderPipelineStageSupportContext{ - stage, - plan.request.rendererIndex }; -} - -void ConfigureFullscreenStagesFromPipeline( - CameraFramePlan& plan, - const RenderPipeline* pipeline) { +void ConfigureLegacyFullscreenStageRequests( + CameraFramePlan& plan) { const bool postProcessExplicitlyConfigured = plan.HasExplicitFullscreenStageConfiguration( CameraFrameStage::PostProcess); const bool finalOutputExplicitlyConfigured = plan.HasExplicitFullscreenStageConfiguration( CameraFrameStage::FinalOutput); - const bool supportsPostProcess = - pipeline != nullptr && - pipeline->SupportsStageRenderGraph( - BuildStageSupportContext( - plan, - CameraFrameStage::PostProcess)); - const bool supportsFinalOutput = - pipeline != nullptr && - pipeline->SupportsStageRenderGraph( - BuildStageSupportContext( - plan, - CameraFrameStage::FinalOutput)); const bool hasPostProcess = - plan.postProcess.IsRequested() || - supportsPostProcess; + plan.postProcess.IsRequested(); const bool hasFinalOutput = - plan.finalOutput.IsRequested() || - supportsFinalOutput; + plan.finalOutput.IsRequested(); if (!postProcessExplicitlyConfigured && hasPostProcess && @@ -87,10 +63,9 @@ void ConfigureFullscreenStagesFromPipeline( std::vector CameraFramePlanBuilder::BuildPlans( const std::vector& requests, - const RenderPipelineAsset* pipelineAsset, - const RenderPipeline* pipeline) { + const RenderPipelineAsset* pipelineAsset) { std::vector plans = CreatePlansFromRequests(requests); - ConfigurePlans(plans, pipelineAsset, pipeline); + ConfigurePlans(plans, pipelineAsset); return plans; } @@ -107,8 +82,7 @@ std::vector CameraFramePlanBuilder::CreatePlansFromRequests( void CameraFramePlanBuilder::ConfigurePlans( std::vector& plans, - const RenderPipelineAsset* pipelineAsset, - const RenderPipeline* pipeline) const { + const RenderPipelineAsset* pipelineAsset) const { for (CameraFramePlan& plan : plans) { if (pipelineAsset != nullptr) { pipelineAsset->ConfigureCameraFramePlan(plan); @@ -116,9 +90,7 @@ void CameraFramePlanBuilder::ConfigurePlans( ApplyDefaultRenderPipelineAssetCameraFramePlanPolicy(plan); } - ConfigureFullscreenStagesFromPipeline( - plan, - pipeline); + ConfigureLegacyFullscreenStageRequests(plan); } } diff --git a/engine/src/Rendering/Planning/CameraFramePlanBuilder.h b/engine/src/Rendering/Planning/CameraFramePlanBuilder.h index d87786d3..28a2515c 100644 --- a/engine/src/Rendering/Planning/CameraFramePlanBuilder.h +++ b/engine/src/Rendering/Planning/CameraFramePlanBuilder.h @@ -8,7 +8,6 @@ namespace XCEngine { namespace Rendering { class RenderPipelineAsset; -class RenderPipeline; class CameraFramePlanBuilder { public: @@ -19,16 +18,14 @@ public: std::vector BuildPlans( const std::vector& requests, - const RenderPipelineAsset* pipelineAsset, - const RenderPipeline* pipeline); + const RenderPipelineAsset* pipelineAsset); private: std::vector CreatePlansFromRequests( const std::vector& requests) const; void ConfigurePlans( std::vector& plans, - const RenderPipelineAsset* pipelineAsset, - const RenderPipeline* pipeline) const; + const RenderPipelineAsset* pipelineAsset) const; }; } // namespace Rendering