From 8eb1f8c5a2f3e49a7a247a45b653a46545785d13 Mon Sep 17 00:00:00 2001 From: ssdfasd <2156608475@qq.com> Date: Sun, 26 Apr 2026 01:59:21 +0800 Subject: [PATCH] rendering: extract default native scene backend --- ...模块长期目标与下一阶段执行计划_2026-04-26.md | 2 + .../Pipelines/BuiltinForwardPipeline.h | 3 + .../Internal/RenderPipelineFactory.cpp | 79 ++++++++++++++----- .../Internal/RenderPipelineFactory.h | 4 + .../Internal/BuiltinForwardSceneSetup.cpp | 17 +++- .../Internal/BuiltinForwardSceneSetup.h | 5 ++ .../ScriptableRenderPipelineHost.cpp | 23 +----- .../src/Scripting/Mono/MonoScriptRuntime.cpp | 15 ++-- .../unit/test_camera_scene_renderer.cpp | 49 ++++++++++++ 9 files changed, 152 insertions(+), 45 deletions(-) diff --git a/docs/plan/渲染模块长期目标与下一阶段执行计划_2026-04-26.md b/docs/plan/渲染模块长期目标与下一阶段执行计划_2026-04-26.md index 2933847d..bd4de3eb 100644 --- a/docs/plan/渲染模块长期目标与下一阶段执行计划_2026-04-26.md +++ b/docs/plan/渲染模块长期目标与下一阶段执行计划_2026-04-26.md @@ -64,6 +64,8 @@ ### 4.2 从 `BuiltinForwardPipeline` 中抽出可复用的 native scene backend +状态: `Completed` (`2026-04-26`) + 目标: 减轻 `BuiltinForwardPipeline` 的三重职责,让 host fallback 和 scene draw backend 可以独立演进。 执行: diff --git a/engine/include/XCEngine/Rendering/Pipelines/BuiltinForwardPipeline.h b/engine/include/XCEngine/Rendering/Pipelines/BuiltinForwardPipeline.h index e79981a5..5108fa64 100644 --- a/engine/include/XCEngine/Rendering/Pipelines/BuiltinForwardPipeline.h +++ b/engine/include/XCEngine/Rendering/Pipelines/BuiltinForwardPipeline.h @@ -411,6 +411,9 @@ private: class BuiltinForwardPipelineAsset final : public RenderPipelineAsset { public: + // Explicit builtin-forward pipeline selection. The default native backend + // is resolved through Internal::CreateDefaultPipelineBackendAsset() so the + // host/backend policy can evolve independently from this asset type. std::unique_ptr CreatePipeline() const override; FinalColorSettings GetDefaultFinalColorSettings() const override { return {}; } }; diff --git a/engine/src/Rendering/Internal/RenderPipelineFactory.cpp b/engine/src/Rendering/Internal/RenderPipelineFactory.cpp index 0111da97..af615c80 100644 --- a/engine/src/Rendering/Internal/RenderPipelineFactory.cpp +++ b/engine/src/Rendering/Internal/RenderPipelineFactory.cpp @@ -15,32 +15,49 @@ namespace Internal { namespace { +class DefaultNativePipelineBackendAsset final : public RenderPipelineAsset { +public: + std::unique_ptr CreatePipeline() const override { + return Pipelines::Internal::CreateConfiguredBuiltinForwardPipeline(); + } + + FinalColorSettings GetDefaultFinalColorSettings() const override { + return {}; + } +}; + std::shared_ptr -CreateBuiltinForwardPipelineRendererAsset() { +CreateDefaultNativePipelineBackendAsset() { static const std::shared_ptr - s_builtinForwardPipelineAsset = - std::make_shared(); - return s_builtinForwardPipelineAsset; + s_defaultNativePipelineBackendAsset = + std::make_shared(); + return s_defaultNativePipelineBackendAsset; } -std::unique_ptr TryCreateSceneDrawBackendFromAsset( +std::unique_ptr TryCreatePipelineBackendFromAsset( const std::shared_ptr& asset) { if (asset == nullptr) { return nullptr; } - std::unique_ptr pipeline = asset->CreatePipeline(); - if (pipeline == nullptr) { + return asset->CreatePipeline(); +} + +std::unique_ptr TryCreateSceneDrawBackendFromAsset( + const std::shared_ptr& asset) { + std::unique_ptr pipelineBackend = + TryCreatePipelineBackendFromAsset(asset); + if (pipelineBackend == nullptr) { return nullptr; } SceneDrawBackend* const sceneDrawBackend = - dynamic_cast(pipeline.get()); + dynamic_cast(pipelineBackend.get()); if (sceneDrawBackend == nullptr) { return nullptr; } - (void)pipeline.release(); + (void)pipelineBackend.release(); return std::unique_ptr(sceneDrawBackend); } @@ -56,7 +73,7 @@ std::shared_ptr CreateFallbackRenderPipelineAsset() { std::shared_ptr CreateDefaultPipelineBackendAsset() { static const std::shared_ptr s_defaultAsset = - CreateBuiltinForwardPipelineRendererAsset(); + CreateDefaultNativePipelineBackendAsset(); return s_defaultAsset; } @@ -128,6 +145,39 @@ std::unique_ptr CreateRenderPipelineOrDefault( return std::make_unique(); } +std::unique_ptr CreatePipelineBackendFromAsset( + const std::shared_ptr& preferredAsset, + std::shared_ptr* outResolvedAsset) { + if (std::unique_ptr pipelineBackend = + TryCreatePipelineBackendFromAsset(preferredAsset)) { + if (outResolvedAsset != nullptr) { + *outResolvedAsset = preferredAsset; + } + return pipelineBackend; + } + + const std::shared_ptr defaultAsset = + CreateDefaultPipelineBackendAsset(); + if (defaultAsset != nullptr && + defaultAsset != preferredAsset) { + if (std::unique_ptr pipelineBackend = + TryCreatePipelineBackendFromAsset(defaultAsset)) { + if (outResolvedAsset != nullptr) { + *outResolvedAsset = defaultAsset; + } + return pipelineBackend; + } + } + + if (outResolvedAsset != nullptr) { + *outResolvedAsset = + defaultAsset != nullptr + ? defaultAsset + : preferredAsset; + } + return Pipelines::Internal::CreateConfiguredBuiltinForwardPipeline(); +} + std::unique_ptr CreateSceneDrawBackendFromAsset( const std::shared_ptr& preferredAsset, std::shared_ptr* outResolvedAsset) { @@ -146,14 +196,7 @@ std::unique_ptr CreateSceneDrawBackendFromAsset( } std::unique_ptr CreateDefaultSceneDrawBackend() { - if (std::unique_ptr sceneDrawBackend = - TryCreateSceneDrawBackendFromAsset( - CreateDefaultPipelineBackendAsset()); - sceneDrawBackend != nullptr) { - return sceneDrawBackend; - } - - return Pipelines::Internal::CreateConfiguredBuiltinForwardPipeline(); + return Pipelines::Internal::CreateConfiguredBuiltinForwardSceneDrawBackend(); } } // namespace Internal diff --git a/engine/src/Rendering/Internal/RenderPipelineFactory.h b/engine/src/Rendering/Internal/RenderPipelineFactory.h index 64386a0a..103a4c5e 100644 --- a/engine/src/Rendering/Internal/RenderPipelineFactory.h +++ b/engine/src/Rendering/Internal/RenderPipelineFactory.h @@ -8,6 +8,7 @@ namespace Rendering { class SceneDrawBackend; class RenderPipeline; class RenderPipelineAsset; +class RenderPipelineBackend; namespace Internal { @@ -21,6 +22,9 @@ std::shared_ptr ResolveRenderPipelineAssetOrDefault( std::unique_ptr CreateRenderPipelineOrDefault( const std::shared_ptr& preferredAsset, std::shared_ptr* outResolvedAsset = nullptr); +std::unique_ptr CreatePipelineBackendFromAsset( + const std::shared_ptr& preferredAsset, + std::shared_ptr* outResolvedAsset = nullptr); std::unique_ptr CreateSceneDrawBackendFromAsset( const std::shared_ptr& preferredAsset, std::shared_ptr* outResolvedAsset = nullptr); diff --git a/engine/src/Rendering/Pipelines/Internal/BuiltinForwardSceneSetup.cpp b/engine/src/Rendering/Pipelines/Internal/BuiltinForwardSceneSetup.cpp index f4cb8641..b3a8536b 100644 --- a/engine/src/Rendering/Pipelines/Internal/BuiltinForwardSceneSetup.cpp +++ b/engine/src/Rendering/Pipelines/Internal/BuiltinForwardSceneSetup.cpp @@ -27,15 +27,28 @@ void ConfigureBuiltinForwardStandalonePasses( } // namespace -void ConfigureBuiltinForwardPipeline( +void ConfigureBuiltinForwardSceneDrawBackend( BuiltinForwardPipeline& pipeline) { - ConfigureBuiltinForwardStandalonePasses(pipeline); pipeline.AddForwardSceneFeaturePass( std::make_unique()); pipeline.AddForwardSceneFeaturePass( std::make_unique()); } +std::unique_ptr +CreateConfiguredBuiltinForwardSceneDrawBackend() { + std::unique_ptr pipeline = + std::make_unique(); + ConfigureBuiltinForwardSceneDrawBackend(*pipeline); + return pipeline; +} + +void ConfigureBuiltinForwardPipeline( + BuiltinForwardPipeline& pipeline) { + ConfigureBuiltinForwardStandalonePasses(pipeline); + ConfigureBuiltinForwardSceneDrawBackend(pipeline); +} + std::unique_ptr CreateConfiguredBuiltinForwardPipeline() { std::unique_ptr pipeline = diff --git a/engine/src/Rendering/Pipelines/Internal/BuiltinForwardSceneSetup.h b/engine/src/Rendering/Pipelines/Internal/BuiltinForwardSceneSetup.h index b09d2e82..2d4550cc 100644 --- a/engine/src/Rendering/Pipelines/Internal/BuiltinForwardSceneSetup.h +++ b/engine/src/Rendering/Pipelines/Internal/BuiltinForwardSceneSetup.h @@ -10,6 +10,11 @@ class BuiltinForwardPipeline; namespace Internal { +void ConfigureBuiltinForwardSceneDrawBackend( + BuiltinForwardPipeline& pipeline); +std::unique_ptr +CreateConfiguredBuiltinForwardSceneDrawBackend(); + void ConfigureBuiltinForwardPipeline( BuiltinForwardPipeline& pipeline); std::unique_ptr diff --git a/engine/src/Rendering/Pipelines/ScriptableRenderPipelineHost.cpp b/engine/src/Rendering/Pipelines/ScriptableRenderPipelineHost.cpp index ddc5dcbe..44eb7c25 100644 --- a/engine/src/Rendering/Pipelines/ScriptableRenderPipelineHost.cpp +++ b/engine/src/Rendering/Pipelines/ScriptableRenderPipelineHost.cpp @@ -2,8 +2,6 @@ #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" namespace XCEngine { @@ -16,21 +14,6 @@ std::shared_ptr CreateDefaultPipelineBackendAsset() { return Rendering::Internal::CreateDefaultPipelineBackendAsset(); } -std::unique_ptr CreatePipelineBackendFromAsset( - const std::shared_ptr& pipelineBackendAsset) { - const std::shared_ptr resolvedAsset = - pipelineBackendAsset != nullptr - ? pipelineBackendAsset - : CreateDefaultPipelineBackendAsset(); - if (resolvedAsset != nullptr) { - if (std::unique_ptr pipeline = resolvedAsset->CreatePipeline()) { - return pipeline; - } - } - - return Internal::CreateConfiguredBuiltinForwardPipeline(); -} - } // namespace ScriptableRenderPipelineHost::ScriptableRenderPipelineHost() @@ -59,7 +42,7 @@ ScriptableRenderPipelineHost::ScriptableRenderPipelineHost( : CreateDefaultPipelineBackendAsset()) , m_managedAssetRuntime(std::move(managedAssetRuntime)) { ResetPipelineBackend( - CreatePipelineBackendFromAsset(m_pipelineBackendAsset)); + Internal::CreatePipelineBackendFromAsset(m_pipelineBackendAsset)); } ScriptableRenderPipelineHost::~ScriptableRenderPipelineHost() { @@ -84,7 +67,7 @@ void ScriptableRenderPipelineHost::SetPipelineBackendAsset( ? std::move(pipelineBackendAsset) : CreateDefaultPipelineBackendAsset(); ResetPipelineBackend( - CreatePipelineBackendFromAsset(m_pipelineBackendAsset)); + Internal::CreatePipelineBackendFromAsset(m_pipelineBackendAsset)); } void ScriptableRenderPipelineHost::SetManagedAssetRuntime( @@ -340,7 +323,7 @@ void ScriptableRenderPipelineHost::ResetPipelineBackend( m_pipelineBackendAsset = CreateDefaultPipelineBackendAsset(); } m_pipelineBackend = - CreatePipelineBackendFromAsset(m_pipelineBackendAsset); + Internal::CreatePipelineBackendFromAsset(m_pipelineBackendAsset); } m_pipelineBackendInitialized = false; diff --git a/engine/src/Scripting/Mono/MonoScriptRuntime.cpp b/engine/src/Scripting/Mono/MonoScriptRuntime.cpp index 045ce2c4..38a6c66d 100644 --- a/engine/src/Scripting/Mono/MonoScriptRuntime.cpp +++ b/engine/src/Scripting/Mono/MonoScriptRuntime.cpp @@ -2040,13 +2040,16 @@ private: return m_boundSceneDrawBackend; } + const bool useDefaultNativeBackend = + m_assetRuntime != nullptr && + m_assetRuntime->GetPipelineRendererAssetPolicy() == + Rendering::Pipelines::ManagedPipelineRendererAssetPolicy:: + DefaultNativeBackend; const std::shared_ptr resolvedPipelineBackendAsset = m_assetRuntime == nullptr ? nullptr - : m_assetRuntime->GetPipelineRendererAssetPolicy() == - Rendering::Pipelines::ManagedPipelineRendererAssetPolicy:: - DefaultNativeBackend + : useDefaultNativeBackend ? Rendering::Internal::CreateDefaultPipelineBackendAsset() : m_assetRuntime->GetSharedPipelineBackendAsset(); if (resolvedPipelineBackendAsset == nullptr) { @@ -2060,8 +2063,10 @@ private: m_ownedSceneDrawBackend->Shutdown(); } m_ownedSceneDrawBackend = - Rendering::Internal::CreateSceneDrawBackendFromAsset( - resolvedPipelineBackendAsset); + useDefaultNativeBackend + ? Rendering::Internal::CreateDefaultSceneDrawBackend() + : Rendering::Internal::CreateSceneDrawBackendFromAsset( + resolvedPipelineBackendAsset); m_ownedSharedPipelineBackendAsset = resolvedPipelineBackendAsset; } diff --git a/tests/Rendering/unit/test_camera_scene_renderer.cpp b/tests/Rendering/unit/test_camera_scene_renderer.cpp index 1a0cad04..54158336 100644 --- a/tests/Rendering/unit/test_camera_scene_renderer.cpp +++ b/tests/Rendering/unit/test_camera_scene_renderer.cpp @@ -4833,6 +4833,55 @@ TEST( Pipelines::ClearManagedRenderPipelineBridge(); } +TEST( + DefaultNativeSceneBackend_Test, + ReusesBuiltinForwardFeaturesWithoutInstallingFallbackStandalonePasses) { + std::unique_ptr sceneDrawBackend = + Internal::CreateDefaultSceneDrawBackend(); + ASSERT_NE(sceneDrawBackend, nullptr); + + SceneRenderFeatureHost* const featureHost = + sceneDrawBackend->GetSceneFeatureHost(); + ASSERT_NE(featureHost, nullptr); + EXPECT_EQ(featureHost->GetFeaturePassCount(), 2u); + + auto* pipeline = + dynamic_cast(sceneDrawBackend.get()); + ASSERT_NE(pipeline, nullptr); + EXPECT_EQ( + pipeline->GetCameraFrameStandalonePass(CameraFrameStage::DepthOnly), + nullptr); + EXPECT_EQ( + pipeline->GetCameraFrameStandalonePass(CameraFrameStage::ShadowCaster), + nullptr); +} + +TEST( + DefaultPipelineBackendAsset_Test, + CreatesFallbackPipelineWithSameDefaultNativeFeatureHost) { + const std::shared_ptr backendAsset = + Internal::CreateDefaultPipelineBackendAsset(); + ASSERT_NE(backendAsset, nullptr); + + std::unique_ptr pipeline = backendAsset->CreatePipeline(); + ASSERT_NE(pipeline, nullptr); + + auto* sceneDrawBackend = + dynamic_cast(pipeline.get()); + ASSERT_NE(sceneDrawBackend, nullptr); + SceneRenderFeatureHost* const featureHost = + sceneDrawBackend->GetSceneFeatureHost(); + ASSERT_NE(featureHost, nullptr); + EXPECT_EQ(featureHost->GetFeaturePassCount(), 2u); + + EXPECT_NE( + pipeline->GetCameraFrameStandalonePass(CameraFrameStage::DepthOnly), + nullptr); + EXPECT_NE( + pipeline->GetCameraFrameStandalonePass(CameraFrameStage::ShadowCaster), + nullptr); +} + TEST(ManagedScriptableRenderPipelineAsset_Test, LetsManagedBridgeConfigureCameraRenderRequests) { Pipelines::ClearManagedRenderPipelineBridge();