From e388b6fbe3b033012ad7ade4bc1e78758a83c9be Mon Sep 17 00:00:00 2001 From: ssdfasd <2156608475@qq.com> Date: Sat, 18 Apr 2026 01:01:30 +0800 Subject: [PATCH] fix(rendering): rebind managed srp asset runtime after bridge reset --- .../ManagedScriptableRenderPipelineAsset.h | 1 + .../ManagedScriptableRenderPipelineAsset.cpp | 15 ++++++- .../unit/test_camera_scene_renderer.cpp | 42 +++++++++++++++++++ 3 files changed, 57 insertions(+), 1 deletion(-) diff --git a/engine/include/XCEngine/Rendering/Pipelines/ManagedScriptableRenderPipelineAsset.h b/engine/include/XCEngine/Rendering/Pipelines/ManagedScriptableRenderPipelineAsset.h index 5bf549a5..689d741b 100644 --- a/engine/include/XCEngine/Rendering/Pipelines/ManagedScriptableRenderPipelineAsset.h +++ b/engine/include/XCEngine/Rendering/Pipelines/ManagedScriptableRenderPipelineAsset.h @@ -58,6 +58,7 @@ private: ScriptableRenderPipelineHostAsset m_fallbackAsset; mutable std::shared_ptr m_managedAssetRuntime = nullptr; + mutable size_t m_managedAssetRuntimeBridgeGeneration = 0u; }; class ManagedRenderPipelineAssetRuntime { diff --git a/engine/src/Rendering/Pipelines/ManagedScriptableRenderPipelineAsset.cpp b/engine/src/Rendering/Pipelines/ManagedScriptableRenderPipelineAsset.cpp index a15735c6..9f6a4e8a 100644 --- a/engine/src/Rendering/Pipelines/ManagedScriptableRenderPipelineAsset.cpp +++ b/engine/src/Rendering/Pipelines/ManagedScriptableRenderPipelineAsset.cpp @@ -18,6 +18,11 @@ std::shared_ptr& GetManagedRenderPipelineBrid return s_bridge; } +size_t& GetManagedRenderPipelineBridgeGenerationStorage() { + static size_t s_generation = 1u; + return s_generation; +} + } // namespace ManagedScriptableRenderPipelineAsset::ManagedScriptableRenderPipelineAsset( @@ -27,10 +32,16 @@ ManagedScriptableRenderPipelineAsset::ManagedScriptableRenderPipelineAsset( std::shared_ptr ManagedScriptableRenderPipelineAsset::ResolveManagedAssetRuntime() const { - if (m_managedAssetRuntime != nullptr) { + const size_t bridgeGeneration = + GetManagedRenderPipelineBridgeGenerationStorage(); + if (m_managedAssetRuntime != nullptr && + m_managedAssetRuntimeBridgeGeneration == bridgeGeneration) { return m_managedAssetRuntime; } + m_managedAssetRuntime.reset(); + m_managedAssetRuntimeBridgeGeneration = bridgeGeneration; + const std::shared_ptr bridge = GetManagedRenderPipelineBridgeStorage(); if (bridge == nullptr) { @@ -97,10 +108,12 @@ void ManagedScriptableRenderPipelineAsset::ConfigureCameraFramePlan( void SetManagedRenderPipelineBridge( std::shared_ptr bridge) { GetManagedRenderPipelineBridgeStorage() = std::move(bridge); + ++GetManagedRenderPipelineBridgeGenerationStorage(); } void ClearManagedRenderPipelineBridge() { GetManagedRenderPipelineBridgeStorage().reset(); + ++GetManagedRenderPipelineBridgeGenerationStorage(); } std::shared_ptr diff --git a/tests/Rendering/unit/test_camera_scene_renderer.cpp b/tests/Rendering/unit/test_camera_scene_renderer.cpp index 410c7033..c03b1629 100644 --- a/tests/Rendering/unit/test_camera_scene_renderer.cpp +++ b/tests/Rendering/unit/test_camera_scene_renderer.cpp @@ -4745,6 +4745,48 @@ TEST(ManagedScriptableRenderPipelineAsset_Test, ReusesManagedAssetRuntimeAcrossP Pipelines::ClearManagedRenderPipelineBridge(); } +TEST(ManagedScriptableRenderPipelineAsset_Test, RebindsManagedAssetRuntimeWhenBridgeChanges) { + Pipelines::ClearManagedRenderPipelineBridge(); + + const Pipelines::ManagedRenderPipelineAssetDescriptor descriptor = { + "GameScripts", + "Gameplay", + "ManagedRenderPipelineProbeAsset" + }; + + auto firstBridgeState = std::make_shared(); + Pipelines::SetManagedRenderPipelineBridge( + std::make_shared(firstBridgeState)); + + Pipelines::ManagedScriptableRenderPipelineAsset asset(descriptor); + + std::unique_ptr firstPipeline = asset.CreatePipeline(); + ASSERT_NE(firstPipeline, nullptr); + ASSERT_NE(firstBridgeState->lastCreatedRuntimeState, nullptr); + EXPECT_EQ(firstBridgeState->createAssetRuntimeCalls, 1); + EXPECT_EQ(firstBridgeState->lastCreatedRuntimeState->createStageRecorderCalls, 1); + + auto secondBridgeState = std::make_shared(); + Pipelines::SetManagedRenderPipelineBridge( + std::make_shared(secondBridgeState)); + + std::unique_ptr secondPipeline = asset.CreatePipeline(); + ASSERT_NE(secondPipeline, nullptr); + ASSERT_NE(secondBridgeState->lastCreatedRuntimeState, nullptr); + EXPECT_EQ(secondBridgeState->createAssetRuntimeCalls, 1); + EXPECT_EQ(secondBridgeState->lastCreatedRuntimeState->createStageRecorderCalls, 1); + EXPECT_NE( + secondBridgeState->lastCreatedRuntimeState.get(), + firstBridgeState->lastCreatedRuntimeState.get()); + + auto* secondHost = + dynamic_cast(secondPipeline.get()); + ASSERT_NE(secondHost, nullptr); + EXPECT_NE(secondHost->GetStageRecorder(), nullptr); + + Pipelines::ClearManagedRenderPipelineBridge(); +} + TEST(CameraRenderer_Test, RendersManagedRequestedPostProcessWithoutLegacySequence) { Scene scene("CameraRendererManagedRequestedPostProcessScene");