diff --git a/docs/used/SRP_URP_NativeSceneFeatureRegistrationOwnershipPlan_2026-04-21_完成归档.md b/docs/used/SRP_URP_NativeSceneFeatureRegistrationOwnershipPlan_2026-04-21_完成归档.md new file mode 100644 index 00000000..29a422ad --- /dev/null +++ b/docs/used/SRP_URP_NativeSceneFeatureRegistrationOwnershipPlan_2026-04-21_完成归档.md @@ -0,0 +1,86 @@ +# SRP / URP Native Scene Feature Registration Ownership Plan + +## Background + +Current native gaussian splat / volumetric scene feature passes have already +been lifted into a managed URP-facing wrapper layer: + +- `UniversalRendererData` owns the default feature list +- managed URP records native scene features explicitly +- native dispatch now uses stable `NativeSceneFeaturePassId` + +But one C++ ownership seam is still dirty: + +- `BuiltinForwardPipeline` constructor silently registers default native scene + feature passes +- that means pipeline instantiation itself still decides which first-party + native scene features exist +- the default backend asset / scene draw backend factory do not own that policy + +This keeps an avoidable hidden side effect inside the pipeline runtime object. + +## Goal + +Move default native scene feature registration out of +`BuiltinForwardPipeline` construction and into explicit backend +configuration/factory ownership. + +After this phase: + +- `BuiltinForwardPipeline` only owns execution/runtime state +- default native scene feature availability is configured by + backend asset/factory code +- default backend asset creation and default scene draw backend creation share + the same setup path + +## Scope + +### Step 1. Remove constructor-side feature registration + +- stop registering default scene features inside + `BuiltinForwardPipeline::BuiltinForwardPipeline()` + +### Step 2. Centralize configured builtin forward creation + +- introduce one explicit setup path for default builtin forward scene features +- use that path from `BuiltinForwardPipelineAsset` +- use that path from default scene draw backend creation / fallback creation + +### Step 3. Verify no behavior regression + +- rebuild old `XCEditor` +- run old editor smoke until `SceneReady` + +## Non-goals + +- changing gaussian splat runtime logic +- changing volumetric runtime logic +- moving shadow runtime in this phase +- deferred renderer work +- editor / new_editor work + +## Exit Criteria + +- `BuiltinForwardPipeline` constructor no longer performs implicit native scene + feature registration +- default builtin forward backend creation still exposes gaussian splat / + volumetric native features through the explicit factory path +- old editor `XCEditor` Debug build passes +- old editor smoke reaches `SceneReady` + +## Result + +Completed on 2026-04-21. + +- removed constructor-side default native scene feature registration from + `BuiltinForwardPipeline` +- centralized configured builtin forward creation in + `BuiltinForwardSceneSetup` +- routed builtin forward asset creation, default scene draw backend creation, + and host fallback creation through the same configured pipeline path + +## Verification + +- `cmake --build . --config Debug --target XCEditor` +- old editor smoke passed +- `SceneReady elapsed_ms=5493 first_frame_ms=614` diff --git a/engine/src/Rendering/Internal/RenderPipelineFactory.cpp b/engine/src/Rendering/Internal/RenderPipelineFactory.cpp index d473f116..4d34959b 100644 --- a/engine/src/Rendering/Internal/RenderPipelineFactory.cpp +++ b/engine/src/Rendering/Internal/RenderPipelineFactory.cpp @@ -5,6 +5,7 @@ #include "Rendering/Execution/DirectionalShadowExecutionState.h" #include "Rendering/Pipelines/BuiltinForwardPipeline.h" +#include "Rendering/Pipelines/Internal/BuiltinForwardSceneSetup.h" #include "Rendering/Pipelines/ManagedScriptableRenderPipelineAsset.h" #include "Rendering/Pipelines/ScriptableRenderPipelineHost.h" #include "Rendering/Passes/BuiltinDepthOnlyPass.h" @@ -160,7 +161,14 @@ std::unique_ptr CreateSceneDrawBackendFromAsset( } std::unique_ptr CreateDefaultSceneDrawBackend() { - return std::make_unique(); + if (std::unique_ptr sceneDrawBackend = + TryCreateSceneDrawBackendFromAsset( + CreateDefaultPipelineBackendAsset()); + sceneDrawBackend != nullptr) { + return sceneDrawBackend; + } + + return Pipelines::Internal::CreateConfiguredBuiltinForwardPipeline(); } } // namespace Internal diff --git a/engine/src/Rendering/Pipelines/BuiltinForwardPipeline.cpp b/engine/src/Rendering/Pipelines/BuiltinForwardPipeline.cpp index 735ed316..545bca16 100644 --- a/engine/src/Rendering/Pipelines/BuiltinForwardPipeline.cpp +++ b/engine/src/Rendering/Pipelines/BuiltinForwardPipeline.cpp @@ -6,9 +6,7 @@ namespace XCEngine { namespace Rendering { namespace Pipelines { -BuiltinForwardPipeline::BuiltinForwardPipeline() { - Internal::RegisterBuiltinForwardSceneFeatures(m_forwardSceneFeatureHost); -} +BuiltinForwardPipeline::BuiltinForwardPipeline() = default; BuiltinForwardPipeline::~BuiltinForwardPipeline() { Shutdown(); @@ -28,7 +26,7 @@ SceneRenderFeaturePass* BuiltinForwardPipeline::GetForwardSceneFeaturePass(size_ } std::unique_ptr BuiltinForwardPipelineAsset::CreatePipeline() const { - return std::make_unique(); + return Internal::CreateConfiguredBuiltinForwardPipeline(); } } // namespace Pipelines diff --git a/engine/src/Rendering/Pipelines/Internal/BuiltinForwardSceneSetup.cpp b/engine/src/Rendering/Pipelines/Internal/BuiltinForwardSceneSetup.cpp index 48145cbf..78541641 100644 --- a/engine/src/Rendering/Pipelines/Internal/BuiltinForwardSceneSetup.cpp +++ b/engine/src/Rendering/Pipelines/Internal/BuiltinForwardSceneSetup.cpp @@ -2,7 +2,7 @@ #include "Rendering/Features/BuiltinGaussianSplatPass.h" #include "Rendering/Features/BuiltinVolumetricPass.h" -#include "Rendering/SceneRenderFeatureHost.h" +#include "Rendering/Pipelines/BuiltinForwardPipeline.h" #include @@ -11,9 +11,20 @@ namespace Rendering { namespace Pipelines { namespace Internal { -void RegisterBuiltinForwardSceneFeatures(SceneRenderFeatureHost& featureHost) { - featureHost.AddFeaturePass(std::make_unique()); - featureHost.AddFeaturePass(std::make_unique()); +void ConfigureBuiltinForwardPipeline( + BuiltinForwardPipeline& pipeline) { + pipeline.AddForwardSceneFeaturePass( + std::make_unique()); + pipeline.AddForwardSceneFeaturePass( + std::make_unique()); +} + +std::unique_ptr +CreateConfiguredBuiltinForwardPipeline() { + std::unique_ptr pipeline = + std::make_unique(); + ConfigureBuiltinForwardPipeline(*pipeline); + return pipeline; } } // namespace Internal diff --git a/engine/src/Rendering/Pipelines/Internal/BuiltinForwardSceneSetup.h b/engine/src/Rendering/Pipelines/Internal/BuiltinForwardSceneSetup.h index 31e0ee04..b09d2e82 100644 --- a/engine/src/Rendering/Pipelines/Internal/BuiltinForwardSceneSetup.h +++ b/engine/src/Rendering/Pipelines/Internal/BuiltinForwardSceneSetup.h @@ -1,14 +1,19 @@ #pragma once +#include + namespace XCEngine { namespace Rendering { -class SceneRenderFeatureHost; - namespace Pipelines { +class BuiltinForwardPipeline; + namespace Internal { -void RegisterBuiltinForwardSceneFeatures(SceneRenderFeatureHost& featureHost); +void ConfigureBuiltinForwardPipeline( + BuiltinForwardPipeline& pipeline); +std::unique_ptr +CreateConfiguredBuiltinForwardPipeline(); } // namespace Internal } // namespace Pipelines diff --git a/engine/src/Rendering/Pipelines/ScriptableRenderPipelineHost.cpp b/engine/src/Rendering/Pipelines/ScriptableRenderPipelineHost.cpp index 63af7735..4f98da51 100644 --- a/engine/src/Rendering/Pipelines/ScriptableRenderPipelineHost.cpp +++ b/engine/src/Rendering/Pipelines/ScriptableRenderPipelineHost.cpp @@ -3,6 +3,7 @@ #include "Rendering/Execution/DirectionalShadowExecutionState.h" #include "Rendering/Internal/RenderPipelineFactory.h" #include "Rendering/Pipelines/BuiltinForwardPipeline.h" +#include "Rendering/Pipelines/Internal/BuiltinForwardSceneSetup.h" #include "Rendering/Pipelines/ManagedScriptableRenderPipelineAsset.h" #include "Rendering/Passes/BuiltinDepthOnlyPass.h" #include "Rendering/Passes/BuiltinObjectIdPass.h" @@ -30,7 +31,7 @@ std::unique_ptr CreatePipelineBackendFromAsset( } } - return std::make_unique(); + return Internal::CreateConfiguredBuiltinForwardPipeline(); } } // namespace