diff --git a/engine/include/XCEngine/Rendering/AGENTS.md b/engine/include/XCEngine/Rendering/AGENTS.md index 045186ba..3f935eb6 100644 --- a/engine/include/XCEngine/Rendering/AGENTS.md +++ b/engine/include/XCEngine/Rendering/AGENTS.md @@ -122,3 +122,4 @@ SceneRenderer - `CameraRenderRequestContext.hasDirectionalShadow` 和 `ClearDirectionalShadow()` 从 ScriptCore public surface 收回 internal,避免 core public API 泄漏 native shadow 规划控制。 - 收口 managed 相机请求策略顺序:`MonoManagedRenderPipelineAssetRuntime::ConfigureCameraRenderRequest` 先生成 native 默认方向光阴影基线给 managed / URP 观察,再按 managed 最终策略重算或清除,避免 `ClearDirectionalShadow()` 之后又被 native 默认规划补回。 - 当时验证:`xcengine_managed_assemblies`、`scripting_tests` 构建通过;聚焦 `MonoScriptRuntimeTest` 12 项 SRP / URP / API surface 测试通过。 +- 收口 SRP 创建失败语义:`ManagedScriptableRenderPipelineAsset::CreatePipeline()` 在 managed runtime、backend asset 或 stage recorder 不可用时直接创建失败;`RenderPipelineFactory::CreateRenderPipelineOrDefault()` 不再在已解析 asset 创建失败后重新走 configured SRP 默认解析,而是明确退回 builtin fallback,避免 `ScriptableRenderPipelineHost` 带 native backend 冒充 managed SRP 成功。 diff --git a/engine/src/Rendering/Internal/RenderPipelineFactory.cpp b/engine/src/Rendering/Internal/RenderPipelineFactory.cpp index c03a875a..f8834350 100644 --- a/engine/src/Rendering/Internal/RenderPipelineFactory.cpp +++ b/engine/src/Rendering/Internal/RenderPipelineFactory.cpp @@ -42,6 +42,15 @@ CreateDefaultNativePipelineBackendAsset() { return s_defaultNativePipelineBackendAsset; } +std::unique_ptr TryCreateRenderPipelineFromAsset( + const std::shared_ptr& asset) { + if (asset == nullptr) { + return nullptr; + } + + return asset->CreatePipeline(); +} + std::unique_ptr TryCreatePipelineBackendFromAsset( const std::shared_ptr& asset) { if (asset == nullptr) { @@ -111,36 +120,20 @@ std::unique_ptr CreateRenderPipelineOrDefault( std::shared_ptr* outResolvedAsset) { const std::shared_ptr resolvedAsset = ResolveRenderPipelineAssetOrDefault(preferredAsset); - if (resolvedAsset != nullptr) { - if (std::unique_ptr pipeline = - resolvedAsset->CreatePipeline()) { - if (outResolvedAsset != nullptr) { - *outResolvedAsset = resolvedAsset; - } - return pipeline; - } - } - - const std::shared_ptr defaultAsset = - ResolveRenderPipelineAssetOrDefault(nullptr); - if (defaultAsset != nullptr && - defaultAsset != resolvedAsset) { - if (std::unique_ptr pipeline = - defaultAsset->CreatePipeline()) { - if (outResolvedAsset != nullptr) { - *outResolvedAsset = defaultAsset; - } - return pipeline; + if (std::unique_ptr pipeline = + TryCreateRenderPipelineFromAsset(resolvedAsset)) { + if (outResolvedAsset != nullptr) { + *outResolvedAsset = resolvedAsset; } + return pipeline; } const std::shared_ptr fallbackAsset = CreateFallbackRenderPipelineAsset(); if (fallbackAsset != nullptr && - fallbackAsset != resolvedAsset && - fallbackAsset != defaultAsset) { + fallbackAsset != resolvedAsset) { if (std::unique_ptr pipeline = - fallbackAsset->CreatePipeline()) { + TryCreateRenderPipelineFromAsset(fallbackAsset)) { if (outResolvedAsset != nullptr) { *outResolvedAsset = fallbackAsset; } @@ -152,9 +145,7 @@ std::unique_ptr CreateRenderPipelineOrDefault( *outResolvedAsset = fallbackAsset != nullptr ? fallbackAsset - : (defaultAsset != nullptr - ? defaultAsset - : resolvedAsset); + : resolvedAsset; } return Pipelines::Internal::CreateConfiguredBuiltinForwardPipeline(); } diff --git a/engine/src/Rendering/Pipelines/ManagedScriptableRenderPipelineAsset.cpp b/engine/src/Rendering/Pipelines/ManagedScriptableRenderPipelineAsset.cpp index 7147841d..330040e5 100644 --- a/engine/src/Rendering/Pipelines/ManagedScriptableRenderPipelineAsset.cpp +++ b/engine/src/Rendering/Pipelines/ManagedScriptableRenderPipelineAsset.cpp @@ -85,8 +85,27 @@ ManagedScriptableRenderPipelineAsset::CreateExecutionHostAsset() const { } std::unique_ptr ManagedScriptableRenderPipelineAsset::CreatePipeline() const { - const ScriptableRenderPipelineHostAsset executionHostAsset = - CreateExecutionHostAsset(); + const std::shared_ptr runtime = + ResolveManagedAssetRuntime(); + if (runtime == nullptr) { + return nullptr; + } + + const std::shared_ptr pipelineBackendAsset = + ResolveManagedPipelineBackendAsset(*runtime); + if (pipelineBackendAsset == nullptr) { + return nullptr; + } + + std::unique_ptr stageRecorder = + runtime->CreateStageRecorder(); + if (stageRecorder == nullptr) { + return nullptr; + } + + const ScriptableRenderPipelineHostAsset executionHostAsset( + pipelineBackendAsset, + runtime); std::unique_ptr pipeline = executionHostAsset.CreatePipeline(); auto* host = dynamic_cast(pipeline.get()); @@ -94,11 +113,7 @@ std::unique_ptr ManagedScriptableRenderPipelineAsset::CreatePipe return pipeline; } - if (const std::shared_ptr runtime = - ResolveManagedAssetRuntime(); - runtime != nullptr) { - host->SetStageRecorder(runtime->CreateStageRecorder()); - } + host->SetStageRecorder(std::move(stageRecorder)); return pipeline; }