From 537d7d99fc3a48bf5efaf37a84d0410444523277 Mon Sep 17 00:00:00 2001 From: ssdfasd <2156608475@qq.com> Date: Sun, 19 Apr 2026 13:47:20 +0800 Subject: [PATCH] refactor(srp): remove managed frame planning hook - derive fullscreen stage planning from pipeline render-graph support - trim planning-only APIs from the managed SRP bridge and public surface - update probes and tests to lock the slimmer SRP API boundary --- .../ManagedScriptableRenderPipelineAsset.h | 5 - .../Scripting/Mono/MonoScriptRuntime.h | 4 - .../Execution/RenderPipelineHost.cpp | 5 +- .../ManagedScriptableRenderPipelineAsset.cpp | 11 - .../Planning/CameraFramePlanBuilder.cpp | 72 +++++- .../Planning/CameraFramePlanBuilder.h | 7 +- .../src/Scripting/Mono/MonoScriptRuntime.cpp | 213 ------------------ managed/CMakeLists.txt | 1 - managed/GameScripts/RenderPipelineApiProbe.cs | 35 --- .../ScriptableRenderContextApiSurfaceProbe.cs | 23 ++ managed/XCEngine.ScriptCore/InternalCalls.cs | 13 -- .../Core/ScriptableRenderPipelineAsset.cs | 5 - ...ScriptableRenderPipelinePlanningContext.cs | 69 ------ .../ColorScalePostProcessRendererFeature.cs | 13 -- .../RendererBackedRenderPipelineAsset.cs | 12 - .../Renderer/ScriptableRendererData.cs | 27 --- .../Renderer/ScriptableRendererFeature.cs | 5 - .../unit/test_camera_scene_renderer.cpp | 138 ++++-------- tests/scripting/test_mono_script_runtime.cpp | 38 +++- 19 files changed, 179 insertions(+), 517 deletions(-) delete mode 100644 managed/XCEngine.ScriptCore/Rendering/Core/ScriptableRenderPipelinePlanningContext.cs diff --git a/engine/include/XCEngine/Rendering/Pipelines/ManagedScriptableRenderPipelineAsset.h b/engine/include/XCEngine/Rendering/Pipelines/ManagedScriptableRenderPipelineAsset.h index f0812a54..f4a3206f 100644 --- a/engine/include/XCEngine/Rendering/Pipelines/ManagedScriptableRenderPipelineAsset.h +++ b/engine/include/XCEngine/Rendering/Pipelines/ManagedScriptableRenderPipelineAsset.h @@ -11,7 +11,6 @@ namespace XCEngine { namespace Rendering { struct CameraRenderRequest; -struct CameraFramePlan; struct DirectionalShadowPlanningSettings; namespace Pipelines { @@ -54,7 +53,6 @@ public: const DirectionalShadowPlanningSettings& directionalShadowSettings) const override; FinalColorSettings GetDefaultFinalColorSettings() const override; - void ConfigureCameraFramePlan(CameraFramePlan& plan) const override; private: std::shared_ptr @@ -85,9 +83,6 @@ public: virtual bool TryGetDefaultFinalColorSettings(FinalColorSettings&) const { return false; } - - virtual void ConfigureCameraFramePlan(CameraFramePlan&) const { - } }; class ManagedRenderPipelineBridge { diff --git a/engine/include/XCEngine/Scripting/Mono/MonoScriptRuntime.h b/engine/include/XCEngine/Scripting/Mono/MonoScriptRuntime.h index ea871a18..269e81ea 100644 --- a/engine/include/XCEngine/Scripting/Mono/MonoScriptRuntime.h +++ b/engine/include/XCEngine/Scripting/Mono/MonoScriptRuntime.h @@ -266,8 +266,6 @@ private: MonoObject* CreateManagedScriptableRenderContext(uint64_t nativeHandle); MonoObject* CreateManagedScriptableRenderPipelineCameraRequestContext( uint64_t nativeHandle); - MonoObject* CreateManagedScriptableRenderPipelinePlanningContext( - uint64_t nativeHandle); MonoObject* GetManagedObject(uint32_t gcHandle) const; MonoMethod* ResolveManagedMethod( MonoClass* monoClass, @@ -308,13 +306,11 @@ private: MonoClass* m_scriptableRenderPipelineClass = nullptr; MonoClass* m_scriptableRenderContextClass = nullptr; MonoClass* m_scriptableRenderPipelineCameraRequestContextClass = nullptr; - MonoClass* m_scriptableRenderPipelinePlanningContextClass = nullptr; MonoClass* m_serializeFieldAttributeClass = nullptr; MonoMethod* m_gameObjectConstructor = nullptr; MonoMethod* m_scriptableRenderContextConstructor = nullptr; MonoMethod* m_scriptableRenderPipelineCameraRequestContextConstructor = nullptr; - MonoMethod* m_scriptableRenderPipelinePlanningContextConstructor = nullptr; MonoClassField* m_managedGameObjectUUIDField = nullptr; MonoClassField* m_gameObjectUUIDField = nullptr; MonoClassField* m_scriptComponentUUIDField = nullptr; diff --git a/engine/src/Rendering/Execution/RenderPipelineHost.cpp b/engine/src/Rendering/Execution/RenderPipelineHost.cpp index 0257404f..ea7b6b39 100644 --- a/engine/src/Rendering/Execution/RenderPipelineHost.cpp +++ b/engine/src/Rendering/Execution/RenderPipelineHost.cpp @@ -45,7 +45,10 @@ void RenderPipelineHost::SetPipelineAsset(std::shared_ptr RenderPipelineHost::BuildFramePlans( const std::vector& requests) { return m_framePlanBuilder != nullptr - ? m_framePlanBuilder->BuildPlans(requests, GetPipelineAsset()) + ? m_framePlanBuilder->BuildPlans( + requests, + GetPipelineAsset(), + GetPipeline()) : std::vector(); } diff --git a/engine/src/Rendering/Pipelines/ManagedScriptableRenderPipelineAsset.cpp b/engine/src/Rendering/Pipelines/ManagedScriptableRenderPipelineAsset.cpp index b1b26d66..096ab03d 100644 --- a/engine/src/Rendering/Pipelines/ManagedScriptableRenderPipelineAsset.cpp +++ b/engine/src/Rendering/Pipelines/ManagedScriptableRenderPipelineAsset.cpp @@ -89,17 +89,6 @@ FinalColorSettings ManagedScriptableRenderPipelineAsset::GetDefaultFinalColorSet return m_executionHostAsset.GetDefaultFinalColorSettings(); } -void ManagedScriptableRenderPipelineAsset::ConfigureCameraFramePlan( - CameraFramePlan& plan) const { - RenderPipelineAsset::ConfigureCameraFramePlan(plan); - - if (const std::shared_ptr runtime = - ResolveManagedAssetRuntime(); - runtime != nullptr) { - runtime->ConfigureCameraFramePlan(plan); - } -} - void SetManagedRenderPipelineBridge( std::shared_ptr bridge) { GetGraphicsSettingsState().SetManagedRenderPipelineBridge( diff --git a/engine/src/Rendering/Planning/CameraFramePlanBuilder.cpp b/engine/src/Rendering/Planning/CameraFramePlanBuilder.cpp index 1feb3033..2901f861 100644 --- a/engine/src/Rendering/Planning/CameraFramePlanBuilder.cpp +++ b/engine/src/Rendering/Planning/CameraFramePlanBuilder.cpp @@ -1,15 +1,76 @@ #include "Rendering/Planning/CameraFramePlanBuilder.h" +#include "Rendering/RenderPipeline.h" #include "Rendering/RenderPipelineAsset.h" namespace XCEngine { namespace Rendering { +namespace { + +bool UsesExplicitFullscreenSource( + const FullscreenPassRenderRequest& request, + CameraFrameColorSource source) { + return source == CameraFrameColorSource::ExplicitSurface && + HasValidColorTarget(request.sourceSurface); +} + +void ConfigureFullscreenStagesFromPipeline( + CameraFramePlan& plan, + const RenderPipeline* pipeline) { + const bool supportsPostProcess = + pipeline != nullptr && + pipeline->SupportsStageRenderGraph( + CameraFrameStage::PostProcess); + const bool supportsFinalOutput = + pipeline != nullptr && + pipeline->SupportsStageRenderGraph( + CameraFrameStage::FinalOutput); + const bool hasPostProcess = + plan.postProcess.IsRequested() || + supportsPostProcess; + const bool hasFinalOutput = + plan.finalOutput.IsRequested() || + supportsFinalOutput; + + if (hasPostProcess && + !UsesExplicitFullscreenSource( + plan.postProcess, + plan.ResolveStageColorSource( + CameraFrameStage::PostProcess))) { + plan.RequestFullscreenStage( + CameraFrameStage::PostProcess, + CameraFrameColorSource::MainSceneColor, + hasFinalOutput); + } + + const bool canChainFromPostProcess = + hasPostProcess && + !UsesExplicitFullscreenSource( + plan.postProcess, + plan.ResolveStageColorSource( + CameraFrameStage::PostProcess)); + if (hasFinalOutput && + !UsesExplicitFullscreenSource( + plan.finalOutput, + plan.ResolveStageColorSource( + CameraFrameStage::FinalOutput))) { + plan.RequestFullscreenStage( + CameraFrameStage::FinalOutput, + canChainFromPostProcess + ? CameraFrameColorSource::PostProcessColor + : CameraFrameColorSource::MainSceneColor); + } +} + +} // namespace + std::vector CameraFramePlanBuilder::BuildPlans( const std::vector& requests, - const RenderPipelineAsset* pipelineAsset) { + const RenderPipelineAsset* pipelineAsset, + const RenderPipeline* pipeline) { std::vector plans = CreatePlansFromRequests(requests); - ConfigurePlans(plans, pipelineAsset); + ConfigurePlans(plans, pipelineAsset, pipeline); return plans; } @@ -26,13 +87,18 @@ std::vector CameraFramePlanBuilder::CreatePlansFromRequests( void CameraFramePlanBuilder::ConfigurePlans( std::vector& plans, - const RenderPipelineAsset* pipelineAsset) const { + const RenderPipelineAsset* pipelineAsset, + const RenderPipeline* pipeline) const { for (CameraFramePlan& plan : plans) { if (pipelineAsset != nullptr) { pipelineAsset->ConfigureCameraFramePlan(plan); } else { ApplyDefaultRenderPipelineAssetCameraFramePlanPolicy(plan); } + + ConfigureFullscreenStagesFromPipeline( + plan, + pipeline); } } diff --git a/engine/src/Rendering/Planning/CameraFramePlanBuilder.h b/engine/src/Rendering/Planning/CameraFramePlanBuilder.h index 28a2515c..d87786d3 100644 --- a/engine/src/Rendering/Planning/CameraFramePlanBuilder.h +++ b/engine/src/Rendering/Planning/CameraFramePlanBuilder.h @@ -8,6 +8,7 @@ namespace XCEngine { namespace Rendering { class RenderPipelineAsset; +class RenderPipeline; class CameraFramePlanBuilder { public: @@ -18,14 +19,16 @@ public: std::vector BuildPlans( const std::vector& requests, - const RenderPipelineAsset* pipelineAsset); + const RenderPipelineAsset* pipelineAsset, + const RenderPipeline* pipeline); private: std::vector CreatePlansFromRequests( const std::vector& requests) const; void ConfigurePlans( std::vector& plans, - const RenderPipelineAsset* pipelineAsset) const; + const RenderPipelineAsset* pipelineAsset, + const RenderPipeline* pipeline) const; }; } // namespace Rendering diff --git a/engine/src/Scripting/Mono/MonoScriptRuntime.cpp b/engine/src/Scripting/Mono/MonoScriptRuntime.cpp index 65d064b4..e91cc391 100644 --- a/engine/src/Scripting/Mono/MonoScriptRuntime.cpp +++ b/engine/src/Scripting/Mono/MonoScriptRuntime.cpp @@ -111,11 +111,6 @@ struct ManagedScriptableRenderPipelineCameraRequestContextState { size_t renderedRequestCount = 0u; }; -struct ManagedScriptableRenderPipelinePlanningContextState { - uint64_t handle = 0; - Rendering::CameraFramePlan* plan = nullptr; -}; - uint64_t& GetManagedScriptableRenderContextNextHandle() { static uint64_t nextHandle = 1; return nextHandle; @@ -279,49 +274,6 @@ void UnregisterManagedScriptableRenderPipelineCameraRequestContextState( GetManagedScriptableRenderPipelineCameraRequestContextRegistry().erase(handle); } -uint64_t& GetManagedScriptableRenderPipelinePlanningContextNextHandle() { - static uint64_t nextHandle = 1; - return nextHandle; -} - -std::unordered_map& -GetManagedScriptableRenderPipelinePlanningContextRegistry() { - static std::unordered_map - registry; - return registry; -} - -ManagedScriptableRenderPipelinePlanningContextState* -FindManagedScriptableRenderPipelinePlanningContextState( - uint64_t handle) { - const auto it = - GetManagedScriptableRenderPipelinePlanningContextRegistry().find(handle); - return it != GetManagedScriptableRenderPipelinePlanningContextRegistry().end() - ? it->second - : nullptr; -} - -uint64_t RegisterManagedScriptableRenderPipelinePlanningContextState( - ManagedScriptableRenderPipelinePlanningContextState& state) { - uint64_t handle = - GetManagedScriptableRenderPipelinePlanningContextNextHandle()++; - if (handle == 0) { - handle = GetManagedScriptableRenderPipelinePlanningContextNextHandle()++; - } - - state.handle = handle; - GetManagedScriptableRenderPipelinePlanningContextRegistry()[handle] = &state; - return handle; -} - -void UnregisterManagedScriptableRenderPipelinePlanningContextState(uint64_t handle) { - if (handle == 0) { - return; - } - - GetManagedScriptableRenderPipelinePlanningContextRegistry().erase(handle); -} - void CleanupMonoRootDomainAtExit() { MonoRootState& rootState = GetMonoRootState(); if (!rootState.rootDomain) { @@ -764,9 +716,6 @@ public: const Rendering::DirectionalShadowPlanningSettings& directionalShadowSettings) const override; - void ConfigureCameraFramePlan( - Rendering::CameraFramePlan& plan) const override; - bool TryGetDefaultFinalColorSettings( Rendering::FinalColorSettings& settings) const override; @@ -789,8 +738,6 @@ private: MonoMethod* ResolveCreatePipelineMethod(MonoObject* assetObject) const; MonoMethod* ResolveConfigureCameraRenderRequestMethod( MonoObject* assetObject) const; - MonoMethod* ResolveConfigureCameraFramePlanMethod( - MonoObject* assetObject) const; MonoMethod* ResolveGetDefaultFinalColorSettingsMethod( MonoObject* assetObject) const; @@ -800,7 +747,6 @@ private: mutable uint32_t m_assetHandle = 0; mutable MonoMethod* m_createPipelineMethod = nullptr; mutable MonoMethod* m_configureCameraRenderRequestMethod = nullptr; - mutable MonoMethod* m_configureCameraFramePlanMethod = nullptr; mutable MonoMethod* m_getDefaultFinalColorSettingsMethod = nullptr; mutable bool m_ownsManagedAssetHandle = false; mutable bool m_assetCreationAttempted = false; @@ -1081,43 +1027,6 @@ void MonoManagedRenderPipelineAssetRuntime::ConfigureCameraRenderRequest( requestContextHandle); } -void MonoManagedRenderPipelineAssetRuntime::ConfigureCameraFramePlan( - Rendering::CameraFramePlan& plan) const { - if (!EnsureManagedAsset()) { - return; - } - - MonoObject* const assetObject = GetManagedAssetObject(); - MonoMethod* const method = - ResolveConfigureCameraFramePlanMethod(assetObject); - if (assetObject == nullptr || method == nullptr) { - return; - } - - ManagedScriptableRenderPipelinePlanningContextState planningContextState = {}; - planningContextState.plan = &plan; - const uint64_t planningContextHandle = - RegisterManagedScriptableRenderPipelinePlanningContextState( - planningContextState); - MonoObject* const planningContextObject = - m_runtime->CreateManagedScriptableRenderPipelinePlanningContext( - planningContextHandle); - if (planningContextObject == nullptr) { - UnregisterManagedScriptableRenderPipelinePlanningContextState( - planningContextHandle); - return; - } - - void* args[1] = { planningContextObject }; - m_runtime->InvokeManagedMethod( - assetObject, - method, - args, - nullptr); - UnregisterManagedScriptableRenderPipelinePlanningContextState( - planningContextHandle); -} - bool MonoManagedRenderPipelineAssetRuntime::TryGetDefaultFinalColorSettings( Rendering::FinalColorSettings& settings) const { settings = {}; @@ -1252,7 +1161,6 @@ bool MonoManagedRenderPipelineAssetRuntime::EnsureManagedAsset() const { void MonoManagedRenderPipelineAssetRuntime::ReleaseManagedAsset() const { m_createPipelineMethod = nullptr; m_configureCameraRenderRequestMethod = nullptr; - m_configureCameraFramePlanMethod = nullptr; m_getDefaultFinalColorSettingsMethod = nullptr; const bool ownsManagedAssetHandle = m_ownsManagedAssetHandle; m_ownsManagedAssetHandle = false; @@ -1303,20 +1211,6 @@ MonoManagedRenderPipelineAssetRuntime::ResolveConfigureCameraRenderRequestMethod return m_configureCameraRenderRequestMethod; } -MonoMethod* -MonoManagedRenderPipelineAssetRuntime::ResolveConfigureCameraFramePlanMethod( - MonoObject* assetObject) const { - if (m_configureCameraFramePlanMethod == nullptr) { - m_configureCameraFramePlanMethod = - m_runtime->ResolveManagedMethod( - assetObject, - "ConfigureCameraFramePlan", - 1); - } - - return m_configureCameraFramePlanMethod; -} - MonoMethod* MonoManagedRenderPipelineAssetRuntime::ResolveGetDefaultFinalColorSettingsMethod( MonoObject* assetObject) const { @@ -3747,47 +3641,6 @@ void InternalCall_Rendering_ScriptableRenderPipelineCameraRequestContext_ClearDi state->request->directionalShadow = {}; } -void InternalCall_Rendering_ScriptableRenderPipelinePlanningContext_ClearFullscreenStage( - uint64_t nativeHandle, - int32_t stage) { - ManagedScriptableRenderPipelinePlanningContextState* const state = - FindManagedScriptableRenderPipelinePlanningContextState(nativeHandle); - const Rendering::CameraFrameStage frameStage = - static_cast(stage); - if (state == nullptr || - state->plan == nullptr || - !Rendering::IsCameraFrameFullscreenSequenceStage(frameStage)) { - return; - } - - state->plan->ClearFullscreenStage(frameStage); -} - -mono_bool -InternalCall_Rendering_ScriptableRenderPipelinePlanningContext_RequestFullscreenStage( - uint64_t nativeHandle, - int32_t stage, - int32_t source, - mono_bool usesGraphManagedOutputColor) { - ManagedScriptableRenderPipelinePlanningContextState* const state = - FindManagedScriptableRenderPipelinePlanningContextState(nativeHandle); - const Rendering::CameraFrameStage frameStage = - static_cast(stage); - if (state == nullptr || - state->plan == nullptr || - !Rendering::IsCameraFrameFullscreenSequenceStage(frameStage) || - source == static_cast(Rendering::CameraFrameColorSource::ExplicitSurface)) { - return 0; - } - - return state->plan->RequestFullscreenStage( - frameStage, - static_cast(source), - usesGraphManagedOutputColor != 0) - ? 1 - : 0; -} - void RegisterInternalCalls() { if (GetInternalCallRegistrationState()) { return; @@ -3975,8 +3828,6 @@ void RegisterInternalCalls() { mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderPipelineCameraRequestContext_GetRenderedRequestCount", reinterpret_cast(&InternalCall_Rendering_ScriptableRenderPipelineCameraRequestContext_GetRenderedRequestCount)); mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderPipelineCameraRequestContext_GetHasDirectionalShadow", reinterpret_cast(&InternalCall_Rendering_ScriptableRenderPipelineCameraRequestContext_GetHasDirectionalShadow)); mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderPipelineCameraRequestContext_ClearDirectionalShadow", reinterpret_cast(&InternalCall_Rendering_ScriptableRenderPipelineCameraRequestContext_ClearDirectionalShadow)); - mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderPipelinePlanningContext_ClearFullscreenStage", reinterpret_cast(&InternalCall_Rendering_ScriptableRenderPipelinePlanningContext_ClearFullscreenStage)); - mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderPipelinePlanningContext_RequestFullscreenStage", reinterpret_cast(&InternalCall_Rendering_ScriptableRenderPipelinePlanningContext_RequestFullscreenStage)); GetInternalCallRegistrationState() = true; } @@ -4036,8 +3887,6 @@ void MonoScriptRuntime::Shutdown() { GetManagedScriptableRenderContextNextHandle() = 1; GetManagedScriptableRenderPipelineCameraRequestContextRegistry().clear(); GetManagedScriptableRenderPipelineCameraRequestContextNextHandle() = 1; - GetManagedScriptableRenderPipelinePlanningContextRegistry().clear(); - GetManagedScriptableRenderPipelinePlanningContextNextHandle() = 1; ClearManagedInstances(); ClearExternalManagedObjects(); ClearClassCache(); @@ -4055,12 +3904,10 @@ void MonoScriptRuntime::Shutdown() { m_scriptableRenderPipelineClass = nullptr; m_scriptableRenderContextClass = nullptr; m_scriptableRenderPipelineCameraRequestContextClass = nullptr; - m_scriptableRenderPipelinePlanningContextClass = nullptr; m_serializeFieldAttributeClass = nullptr; m_gameObjectConstructor = nullptr; m_scriptableRenderContextConstructor = nullptr; m_scriptableRenderPipelineCameraRequestContextConstructor = nullptr; - m_scriptableRenderPipelinePlanningContextConstructor = nullptr; m_managedGameObjectUUIDField = nullptr; m_gameObjectUUIDField = nullptr; m_scriptComponentUUIDField = nullptr; @@ -4854,27 +4701,6 @@ bool MonoScriptRuntime::DiscoverScriptClasses() { return false; } - m_scriptableRenderPipelinePlanningContextClass = mono_class_from_name( - m_coreImage, - kManagedRenderingNamespace, - "ScriptableRenderPipelinePlanningContext"); - if (!m_scriptableRenderPipelinePlanningContextClass) { - SetError( - "Failed to locate the managed ScriptableRenderPipelinePlanningContext type."); - return false; - } - - m_scriptableRenderPipelinePlanningContextConstructor = - mono_class_get_method_from_name( - m_scriptableRenderPipelinePlanningContextClass, - ".ctor", - 1); - if (!m_scriptableRenderPipelinePlanningContextConstructor) { - SetError( - "Failed to locate the managed ScriptableRenderPipelinePlanningContext constructor."); - return false; - } - m_serializeFieldAttributeClass = mono_class_from_name( m_coreImage, m_settings.baseNamespace.c_str(), @@ -5470,45 +5296,6 @@ MonoScriptRuntime::CreateManagedScriptableRenderPipelineCameraRequestContext( return contextObject; } -MonoObject* MonoScriptRuntime::CreateManagedScriptableRenderPipelinePlanningContext( - uint64_t nativeHandle) { - if (!m_initialized || - nativeHandle == 0 || - m_scriptableRenderPipelinePlanningContextClass == nullptr || - m_scriptableRenderPipelinePlanningContextConstructor == nullptr) { - return nullptr; - } - - SetCurrentDomain(); - - MonoObject* const contextObject = - mono_object_new( - m_appDomain, - m_scriptableRenderPipelinePlanningContextClass); - if (contextObject == nullptr) { - SetError( - "Mono failed to allocate a managed ScriptableRenderPipelinePlanningContext."); - return nullptr; - } - - void* args[1]; - uint64_t nativeHandleArgument = nativeHandle; - args[0] = &nativeHandleArgument; - - MonoObject* exception = nullptr; - mono_runtime_invoke( - m_scriptableRenderPipelinePlanningContextConstructor, - contextObject, - args, - &exception); - if (exception != nullptr) { - RecordException(exception); - return nullptr; - } - - return contextObject; -} - MonoScriptRuntime::InstanceData* MonoScriptRuntime::FindInstance(const ScriptRuntimeContext& context) { const auto it = m_instances.find(InstanceKey{context.gameObjectUUID, context.scriptComponentUUID}); return it != m_instances.end() ? &it->second : nullptr; diff --git a/managed/CMakeLists.txt b/managed/CMakeLists.txt index bd3f850d..3a09b9b0 100644 --- a/managed/CMakeLists.txt +++ b/managed/CMakeLists.txt @@ -183,7 +183,6 @@ set(XCENGINE_SCRIPT_CORE_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/XCEngine.ScriptCore/Rendering/Core/ScriptableRenderPipeline.cs ${CMAKE_CURRENT_SOURCE_DIR}/XCEngine.ScriptCore/Rendering/Core/ScriptableRenderPipelineAsset.cs ${CMAKE_CURRENT_SOURCE_DIR}/XCEngine.ScriptCore/Rendering/Core/ScriptableRenderPipelineCameraRequestContext.cs - ${CMAKE_CURRENT_SOURCE_DIR}/XCEngine.ScriptCore/Rendering/Core/ScriptableRenderPipelinePlanningContext.cs # Rendering shared data ${CMAKE_CURRENT_SOURCE_DIR}/XCEngine.ScriptCore/Rendering/Data/CameraData.cs ${CMAKE_CURRENT_SOURCE_DIR}/XCEngine.ScriptCore/Rendering/Data/DirectionalLightData.cs diff --git a/managed/GameScripts/RenderPipelineApiProbe.cs b/managed/GameScripts/RenderPipelineApiProbe.cs index 8f5772ce..f53d4242 100644 --- a/managed/GameScripts/RenderPipelineApiProbe.cs +++ b/managed/GameScripts/RenderPipelineApiProbe.cs @@ -766,15 +766,6 @@ namespace Gameplay postProcessScale); } - protected override void ConfigureCameraFramePlan( - ScriptableRenderPipelinePlanningContext context) - { - context.ClearFullscreenStage(CameraFrameStage.PostProcess); - context.RequestFullscreenStage( - CameraFrameStage.PostProcess, - CameraFrameColorSource.MainSceneColor, - false); - } } public sealed class ManagedPlannedFullscreenRenderPipelineProbeAsset @@ -785,19 +776,6 @@ namespace Gameplay return new ManagedPlannedFullscreenRenderPipelineProbe(); } - protected override void ConfigureCameraFramePlan( - ScriptableRenderPipelinePlanningContext context) - { - context.ClearFullscreenStage(CameraFrameStage.PostProcess); - context.ClearFullscreenStage(CameraFrameStage.FinalOutput); - context.RequestFullscreenStage( - CameraFrameStage.PostProcess, - CameraFrameColorSource.MainSceneColor, - true); - context.RequestFullscreenStage( - CameraFrameStage.FinalOutput, - CameraFrameColorSource.PostProcessColor); - } } internal sealed class ManagedCameraRequestConfiguredRendererData @@ -877,19 +855,6 @@ namespace Gameplay return new ManagedRenderContextStageColorDataProbe(); } - protected override void ConfigureCameraFramePlan( - ScriptableRenderPipelinePlanningContext context) - { - context.ClearFullscreenStage(CameraFrameStage.PostProcess); - context.ClearFullscreenStage(CameraFrameStage.FinalOutput); - context.RequestFullscreenStage( - CameraFrameStage.PostProcess, - CameraFrameColorSource.MainSceneColor, - true); - context.RequestFullscreenStage( - CameraFrameStage.FinalOutput, - CameraFrameColorSource.PostProcessColor); - } } public sealed class ManagedRenderPipelineProbe diff --git a/managed/GameScripts/ScriptableRenderContextApiSurfaceProbe.cs b/managed/GameScripts/ScriptableRenderContextApiSurfaceProbe.cs index 14421969..bc1e2e17 100644 --- a/managed/GameScripts/ScriptableRenderContextApiSurfaceProbe.cs +++ b/managed/GameScripts/ScriptableRenderContextApiSurfaceProbe.cs @@ -1,6 +1,7 @@ using System.Reflection; using XCEngine; using XCEngine.Rendering; +using XCEngine.Rendering.Renderer; namespace Gameplay { @@ -19,6 +20,9 @@ namespace Gameplay public bool HasPublicContextStageColorData; public bool HasPublicCameraRequestContextHasDirectionalShadow; public bool HasPublicCameraRequestContextClearDirectionalShadow; + public bool HasPublicPipelineAssetConfigureCameraFramePlan; + public bool HasPlanningContextType; + public bool HasRendererFeatureConfigureCameraFramePlan; public bool HasRendererRecordingContextType; public bool HasRendererCameraRequestContextType; @@ -30,6 +34,10 @@ namespace Gameplay typeof(ScriptableRenderContext); System.Type cameraRequestContextType = typeof(ScriptableRenderPipelineCameraRequestContext); + System.Type pipelineAssetType = + typeof(ScriptableRenderPipelineAsset); + System.Type rendererFeatureType = + typeof(ScriptableRendererFeature); HasPublicContextRecordScene = contextType.GetMethod( @@ -79,6 +87,21 @@ namespace Gameplay cameraRequestContextType.GetMethod( "ClearDirectionalShadow", PublicInstanceMethodFlags) != null; + HasPublicPipelineAssetConfigureCameraFramePlan = + pipelineAssetType.GetMethod( + "ConfigureCameraFramePlan", + BindingFlags.Instance | + BindingFlags.Public | + BindingFlags.NonPublic) != null; + HasPlanningContextType = + contextType.Assembly.GetType( + "XCEngine.Rendering.ScriptableRenderPipelinePlanningContext") != null; + HasRendererFeatureConfigureCameraFramePlan = + rendererFeatureType.GetMethod( + "ConfigureCameraFramePlan", + BindingFlags.Instance | + BindingFlags.Public | + BindingFlags.NonPublic) != null; HasRendererRecordingContextType = System.Type.GetType( "XCEngine.Rendering.Renderer.RendererRecordingContext, XCEngine.RenderPipelines.Universal") != null; diff --git a/managed/XCEngine.ScriptCore/InternalCalls.cs b/managed/XCEngine.ScriptCore/InternalCalls.cs index e25e135c..b012faa1 100644 --- a/managed/XCEngine.ScriptCore/InternalCalls.cs +++ b/managed/XCEngine.ScriptCore/InternalCalls.cs @@ -700,19 +700,6 @@ namespace XCEngine Rendering_ScriptableRenderPipelineCameraRequestContext_ClearDirectionalShadow( ulong nativeHandle); - [MethodImpl(MethodImplOptions.InternalCall)] - internal static extern void - Rendering_ScriptableRenderPipelinePlanningContext_ClearFullscreenStage( - ulong nativeHandle, - int stage); - - [MethodImpl(MethodImplOptions.InternalCall)] - internal static extern bool - Rendering_ScriptableRenderPipelinePlanningContext_RequestFullscreenStage( - ulong nativeHandle, - int stage, - int source, - bool usesGraphManagedOutputColor); } } diff --git a/managed/XCEngine.ScriptCore/Rendering/Core/ScriptableRenderPipelineAsset.cs b/managed/XCEngine.ScriptCore/Rendering/Core/ScriptableRenderPipelineAsset.cs index 5edec546..6774060c 100644 --- a/managed/XCEngine.ScriptCore/Rendering/Core/ScriptableRenderPipelineAsset.cs +++ b/managed/XCEngine.ScriptCore/Rendering/Core/ScriptableRenderPipelineAsset.cs @@ -18,11 +18,6 @@ namespace XCEngine.Rendering { } - protected virtual void ConfigureCameraFramePlan( - ScriptableRenderPipelinePlanningContext context) - { - } - protected virtual FinalColorSettings GetDefaultFinalColorSettings() { return FinalColorSettings.CreateDefault(); diff --git a/managed/XCEngine.ScriptCore/Rendering/Core/ScriptableRenderPipelinePlanningContext.cs b/managed/XCEngine.ScriptCore/Rendering/Core/ScriptableRenderPipelinePlanningContext.cs deleted file mode 100644 index 924767be..00000000 --- a/managed/XCEngine.ScriptCore/Rendering/Core/ScriptableRenderPipelinePlanningContext.cs +++ /dev/null @@ -1,69 +0,0 @@ -using System; -using XCEngine; - -namespace XCEngine.Rendering -{ - public sealed class ScriptableRenderPipelinePlanningContext - { - private readonly ulong m_nativeHandle; - - internal ScriptableRenderPipelinePlanningContext(ulong nativeHandle) - { - m_nativeHandle = nativeHandle; - } - - public void ClearFullscreenStage( - CameraFrameStage stage) - { - ValidateFullscreenStage(stage); - InternalCalls.Rendering_ScriptableRenderPipelinePlanningContext_ClearFullscreenStage( - m_nativeHandle, - (int)stage); - } - - public void RequestFullscreenStage( - CameraFrameStage stage, - CameraFrameColorSource source, - bool usesGraphManagedOutputColor = false) - { - ValidateFullscreenStage(stage); - if (source == CameraFrameColorSource.ExplicitSurface) - { - throw new ArgumentException( - "Managed planning currently requires a graph-managed color source for fullscreen stages.", - nameof(source)); - } - - if (stage == CameraFrameStage.FinalOutput && usesGraphManagedOutputColor) - { - throw new ArgumentException( - "FinalOutput fullscreen stages cannot publish a graph-managed output color.", - nameof(usesGraphManagedOutputColor)); - } - - if (!InternalCalls - .Rendering_ScriptableRenderPipelinePlanningContext_RequestFullscreenStage( - m_nativeHandle, - (int)stage, - (int)source, - usesGraphManagedOutputColor)) - { - throw new InvalidOperationException( - $"Failed to request the managed fullscreen stage '{stage}'."); - } - } - - private static void ValidateFullscreenStage( - CameraFrameStage stage) - { - if (stage != CameraFrameStage.PostProcess && - stage != CameraFrameStage.FinalOutput) - { - throw new ArgumentException( - "Managed planning currently supports only fullscreen sequence stages.", - nameof(stage)); - } - } - } -} - diff --git a/managed/XCEngine.ScriptCore/Rendering/FirstParty/ColorScalePostProcessRendererFeature.cs b/managed/XCEngine.ScriptCore/Rendering/FirstParty/ColorScalePostProcessRendererFeature.cs index d912ea6d..80ec609d 100644 --- a/managed/XCEngine.ScriptCore/Rendering/FirstParty/ColorScalePostProcessRendererFeature.cs +++ b/managed/XCEngine.ScriptCore/Rendering/FirstParty/ColorScalePostProcessRendererFeature.cs @@ -47,19 +47,6 @@ namespace XCEngine.Rendering.FirstParty new ColorScalePostProcessPass(this); } - public override void ConfigureCameraFramePlan( - ScriptableRenderPipelinePlanningContext context) - { - if (context == null) - { - return; - } - - context.RequestFullscreenStage( - CameraFrameStage.PostProcess, - CameraFrameColorSource.MainSceneColor); - } - public override void AddRenderPasses( ScriptableRenderer renderer, RenderingData renderingData) diff --git a/managed/XCEngine.ScriptCore/Rendering/Renderer/RendererBackedRenderPipelineAsset.cs b/managed/XCEngine.ScriptCore/Rendering/Renderer/RendererBackedRenderPipelineAsset.cs index 2f7454a5..7661d2df 100644 --- a/managed/XCEngine.ScriptCore/Rendering/Renderer/RendererBackedRenderPipelineAsset.cs +++ b/managed/XCEngine.ScriptCore/Rendering/Renderer/RendererBackedRenderPipelineAsset.cs @@ -31,18 +31,6 @@ namespace XCEngine.Rendering.Renderer } } - protected override void ConfigureCameraFramePlan( - ScriptableRenderPipelinePlanningContext context) - { - ScriptableRendererData rendererData = - ResolveRendererData(); - if (rendererData != null) - { - rendererData.ConfigureCameraFramePlanInstance( - context); - } - } - protected abstract ScriptableRendererData GetRendererData(); private ScriptableRendererData ResolveRendererData() diff --git a/managed/XCEngine.ScriptCore/Rendering/Renderer/ScriptableRendererData.cs b/managed/XCEngine.ScriptCore/Rendering/Renderer/ScriptableRendererData.cs index db8a2a21..bc6440a8 100644 --- a/managed/XCEngine.ScriptCore/Rendering/Renderer/ScriptableRendererData.cs +++ b/managed/XCEngine.ScriptCore/Rendering/Renderer/ScriptableRendererData.cs @@ -44,28 +44,6 @@ namespace XCEngine.Rendering.Renderer } } - internal void ConfigureCameraFramePlanInstance( - ScriptableRenderPipelinePlanningContext context) - { - ConfigureCameraFramePlan(context); - - ScriptableRendererFeature[] rendererFeatures = - GetRendererFeatures(); - for (int i = 0; i < rendererFeatures.Length; ++i) - { - ScriptableRendererFeature rendererFeature = - rendererFeatures[i]; - if (rendererFeature == null || - !rendererFeature.isActive) - { - continue; - } - - rendererFeature.ConfigureCameraFramePlan( - context); - } - } - protected virtual ScriptableRenderer CreateRenderer() { return null; @@ -76,11 +54,6 @@ namespace XCEngine.Rendering.Renderer { } - protected virtual void ConfigureCameraFramePlan( - ScriptableRenderPipelinePlanningContext context) - { - } - protected virtual ScriptableRendererFeature[] CreateRendererFeatures() { return Array.Empty(); diff --git a/managed/XCEngine.ScriptCore/Rendering/Renderer/ScriptableRendererFeature.cs b/managed/XCEngine.ScriptCore/Rendering/Renderer/ScriptableRendererFeature.cs index 0e259ef1..108b3a8d 100644 --- a/managed/XCEngine.ScriptCore/Rendering/Renderer/ScriptableRendererFeature.cs +++ b/managed/XCEngine.ScriptCore/Rendering/Renderer/ScriptableRendererFeature.cs @@ -20,11 +20,6 @@ namespace XCEngine.Rendering.Renderer { } - public virtual void ConfigureCameraFramePlan( - ScriptableRenderPipelinePlanningContext context) - { - } - public virtual void AddRenderPasses( ScriptableRenderer renderer, RenderingData renderingData) diff --git a/tests/Rendering/unit/test_camera_scene_renderer.cpp b/tests/Rendering/unit/test_camera_scene_renderer.cpp index ea2dc992..5d8238f9 100644 --- a/tests/Rendering/unit/test_camera_scene_renderer.cpp +++ b/tests/Rendering/unit/test_camera_scene_renderer.cpp @@ -775,7 +775,6 @@ private: struct MockManagedRenderPipelineAssetRuntimeState { int createStageRecorderCalls = 0; int configureCameraRenderRequestCalls = 0; - int configureCameraFramePlanCalls = 0; int getDefaultFinalColorSettingsCalls = 0; bool hasDefaultFinalColorSettings = false; FinalColorSettings defaultFinalColorSettings = {}; @@ -787,7 +786,6 @@ struct MockManagedRenderPipelineAssetRuntimeState { size_t, size_t, const DirectionalShadowPlanningSettings&)> configureCameraRenderRequest = {}; - std::function configureCameraFramePlan = {}; }; class MockManagedRenderPipelineAssetRuntime final @@ -824,13 +822,6 @@ public: } } - void ConfigureCameraFramePlan(CameraFramePlan& plan) const override { - ++m_state->configureCameraFramePlanCalls; - if (m_state->configureCameraFramePlan) { - m_state->configureCameraFramePlan(plan); - } - } - bool TryGetDefaultFinalColorSettings( FinalColorSettings& settings) const override { ++m_state->getDefaultFinalColorSettingsCalls; @@ -857,7 +848,6 @@ struct MockManagedRenderPipelineBridgeState { size_t, size_t, const DirectionalShadowPlanningSettings&)> configureCameraRenderRequest = {}; - std::function configureCameraFramePlan = {}; }; class MockManagedRenderPipelineBridge final @@ -881,8 +871,6 @@ public: m_state->defaultFinalColorSettings; m_state->lastCreatedRuntimeState->configureCameraRenderRequest = m_state->configureCameraRenderRequest; - m_state->lastCreatedRuntimeState->configureCameraFramePlan = - m_state->configureCameraFramePlan; return std::make_shared( m_state->lastCreatedRuntimeState); } @@ -4184,6 +4172,51 @@ TEST(RenderPipelineHost_Test, BuildsFramePlansFromRequestsUsingPipelineAssetDefa EXPECT_FLOAT_EQ(plan.finalColorPolicy.exposureValue, 1.8f); } +TEST(RenderPipelineHost_Test, PlansFullscreenStagesFromPipelineRenderGraphSupport) { + auto state = std::make_shared(); + state->supportsPostProcessRenderGraph = true; + state->supportsFinalOutputRenderGraph = true; + + auto allocationState = std::make_shared(); + MockShadowView colorView( + allocationState, + XCEngine::RHI::ResourceViewType::RenderTarget, + XCEngine::RHI::Format::R8G8B8A8_UNorm, + XCEngine::RHI::ResourceViewDimension::Texture2D); + MockShadowView depthView( + allocationState, + XCEngine::RHI::ResourceViewType::DepthStencil, + XCEngine::RHI::Format::D24_UNorm_S8_UInt, + XCEngine::RHI::ResourceViewDimension::Texture2D); + + CameraRenderRequest request = {}; + request.context = CreateValidContext(); + request.surface = RenderSurface(320, 180); + request.surface.SetColorAttachment(&colorView); + request.surface.SetDepthAttachment(&depthView); + + RenderPipelineHost host(std::make_unique(state)); + const std::vector plans = + host.BuildFramePlans({ request }); + + ASSERT_EQ(plans.size(), 1u); + const CameraFramePlan& plan = plans[0]; + EXPECT_TRUE(plan.IsFullscreenStageRequested(CameraFrameStage::PostProcess)); + EXPECT_TRUE(plan.IsFullscreenStageRequested(CameraFrameStage::FinalOutput)); + EXPECT_EQ(plan.postProcess.passes, nullptr); + EXPECT_EQ(plan.finalOutput.passes, nullptr); + EXPECT_TRUE(plan.UsesGraphManagedSceneColor()); + EXPECT_TRUE(plan.UsesGraphManagedOutputColor(CameraFrameStage::PostProcess)); + EXPECT_EQ( + plan.ResolveStageColorSource(CameraFrameStage::PostProcess), + CameraFrameColorSource::MainSceneColor); + EXPECT_EQ( + plan.ResolveStageColorSource(CameraFrameStage::FinalOutput), + CameraFrameColorSource::PostProcessColor); + EXPECT_TRUE(plan.IsPostProcessStageValid()); + EXPECT_TRUE(plan.IsFinalOutputStageValid()); +} + TEST(RenderPipelineHost_Test, ForwardsPipelineLifetimeAndRenderCallsToCameraRenderer) { Scene scene("RenderPipelineHostScene"); @@ -4569,80 +4602,6 @@ TEST(ManagedScriptableRenderPipelineAsset_Test, CreatesHostWithStageRecorderFrom Pipelines::ClearManagedRenderPipelineBridge(); } -TEST(ManagedScriptableRenderPipelineAsset_Test, LetsManagedBridgeRequestFullscreenStagesDuringPlanConfiguration) { - Pipelines::ClearManagedRenderPipelineBridge(); - - const Pipelines::ManagedRenderPipelineAssetDescriptor descriptor = { - "GameScripts", - "Gameplay", - "ManagedPlannedFullscreenRenderPipelineProbeAsset" - }; - auto bridgeState = std::make_shared(); - bridgeState->configureCameraFramePlan = []( - CameraFramePlan& plan) { - plan.ClearFullscreenStage(CameraFrameStage::PostProcess); - plan.ClearFullscreenStage(CameraFrameStage::FinalOutput); - EXPECT_TRUE( - plan.RequestFullscreenStage( - CameraFrameStage::PostProcess, - CameraFrameColorSource::MainSceneColor, - true)); - EXPECT_TRUE( - plan.RequestFullscreenStage( - CameraFrameStage::FinalOutput, - CameraFrameColorSource::PostProcessColor)); - }; - Pipelines::SetManagedRenderPipelineBridge( - std::make_shared(bridgeState)); - - auto allocationState = std::make_shared(); - MockShadowView colorView( - allocationState, - XCEngine::RHI::ResourceViewType::RenderTarget, - XCEngine::RHI::Format::R8G8B8A8_UNorm, - XCEngine::RHI::ResourceViewDimension::Texture2D); - MockShadowView depthView( - allocationState, - XCEngine::RHI::ResourceViewType::DepthStencil, - XCEngine::RHI::Format::D24_UNorm_S8_UInt, - XCEngine::RHI::ResourceViewDimension::Texture2D); - - CameraRenderRequest request = {}; - request.context = CreateValidContext(); - request.surface = RenderSurface(320, 180); - request.surface.SetColorAttachment(&colorView); - request.surface.SetDepthAttachment(&depthView); - - CameraFramePlan plan = CameraFramePlan::FromRequest(request); - Pipelines::ManagedScriptableRenderPipelineAsset asset(descriptor); - asset.ConfigureCameraFramePlan(plan); - - EXPECT_EQ(bridgeState->createAssetRuntimeCalls, 1); - ASSERT_NE(bridgeState->lastCreatedRuntimeState, nullptr); - EXPECT_EQ( - bridgeState->lastCreatedRuntimeState->configureCameraFramePlanCalls, - 1); - EXPECT_EQ(bridgeState->lastDescriptor.assemblyName, "GameScripts"); - EXPECT_EQ(bridgeState->lastDescriptor.namespaceName, "Gameplay"); - EXPECT_EQ(bridgeState->lastDescriptor.className, "ManagedPlannedFullscreenRenderPipelineProbeAsset"); - EXPECT_TRUE(plan.IsFullscreenStageRequested(CameraFrameStage::PostProcess)); - EXPECT_TRUE(plan.IsFullscreenStageRequested(CameraFrameStage::FinalOutput)); - EXPECT_EQ(plan.postProcess.passes, nullptr); - EXPECT_EQ(plan.finalOutput.passes, nullptr); - EXPECT_TRUE(plan.UsesGraphManagedSceneColor()); - EXPECT_TRUE(plan.UsesGraphManagedOutputColor(CameraFrameStage::PostProcess)); - EXPECT_EQ( - plan.ResolveStageColorSource(CameraFrameStage::PostProcess), - CameraFrameColorSource::MainSceneColor); - EXPECT_EQ( - plan.ResolveStageColorSource(CameraFrameStage::FinalOutput), - CameraFrameColorSource::PostProcessColor); - EXPECT_TRUE(plan.IsPostProcessStageValid()); - EXPECT_TRUE(plan.IsFinalOutputStageValid()); - - Pipelines::ClearManagedRenderPipelineBridge(); -} - TEST(ManagedScriptableRenderPipelineAsset_Test, LetsManagedBridgeConfigureCameraRenderRequests) { Pipelines::ClearManagedRenderPipelineBridge(); @@ -4755,7 +4714,7 @@ TEST(ManagedScriptableRenderPipelineAsset_Test, LetsManagedBridgeProvideDefaultF Pipelines::ClearManagedRenderPipelineBridge(); } -TEST(ManagedScriptableRenderPipelineAsset_Test, ReusesManagedAssetRuntimeAcrossPipelineRequestAndPlanRequests) { +TEST(ManagedScriptableRenderPipelineAsset_Test, ReusesManagedAssetRuntimeAcrossPipelineAndRequestCalls) { Pipelines::ClearManagedRenderPipelineBridge(); const Pipelines::ManagedRenderPipelineAssetDescriptor descriptor = { @@ -4796,16 +4755,11 @@ TEST(ManagedScriptableRenderPipelineAsset_Test, ReusesManagedAssetRuntimeAcrossP 1u, 2u, DirectionalShadowPlanningSettings{}); - CameraFramePlan firstPlan = CameraFramePlan::FromRequest(request); - CameraFramePlan secondPlan = CameraFramePlan::FromRequest(request); - asset.ConfigureCameraFramePlan(firstPlan); - asset.ConfigureCameraFramePlan(secondPlan); EXPECT_EQ(bridgeState->createAssetRuntimeCalls, 1); EXPECT_EQ(runtimeState->configureCameraRenderRequestCalls, 1); EXPECT_EQ(runtimeState->lastRenderedBaseCameraCount, 1u); EXPECT_EQ(runtimeState->lastRenderedRequestCount, 2u); - EXPECT_EQ(runtimeState->configureCameraFramePlanCalls, 2); Pipelines::ClearManagedRenderPipelineBridge(); } diff --git a/tests/scripting/test_mono_script_runtime.cpp b/tests/scripting/test_mono_script_runtime.cpp index a6dac4e7..34f63e4b 100644 --- a/tests/scripting/test_mono_script_runtime.cpp +++ b/tests/scripting/test_mono_script_runtime.cpp @@ -1163,6 +1163,9 @@ TEST_F( bool hasPublicContextStageColorData = false; bool hasPublicCameraRequestContextHasDirectionalShadow = false; bool hasPublicCameraRequestContextClearDirectionalShadow = false; + bool hasPublicPipelineAssetConfigureCameraFramePlan = false; + bool hasPlanningContextType = false; + bool hasRendererFeatureConfigureCameraFramePlan = false; bool hasRendererRecordingContextType = false; bool hasRendererCameraRequestContextType = false; @@ -1214,6 +1217,18 @@ TEST_F( selectionScript, "HasPublicCameraRequestContextClearDirectionalShadow", hasPublicCameraRequestContextClearDirectionalShadow)); + EXPECT_TRUE(runtime->TryGetFieldValue( + selectionScript, + "HasPublicPipelineAssetConfigureCameraFramePlan", + hasPublicPipelineAssetConfigureCameraFramePlan)); + EXPECT_TRUE(runtime->TryGetFieldValue( + selectionScript, + "HasPlanningContextType", + hasPlanningContextType)); + EXPECT_TRUE(runtime->TryGetFieldValue( + selectionScript, + "HasRendererFeatureConfigureCameraFramePlan", + hasRendererFeatureConfigureCameraFramePlan)); EXPECT_TRUE(runtime->TryGetFieldValue( selectionScript, "HasRendererRecordingContextType", @@ -1235,6 +1250,9 @@ TEST_F( EXPECT_FALSE(hasPublicContextStageColorData); EXPECT_TRUE(hasPublicCameraRequestContextHasDirectionalShadow); EXPECT_TRUE(hasPublicCameraRequestContextClearDirectionalShadow); + EXPECT_FALSE(hasPublicPipelineAssetConfigureCameraFramePlan); + EXPECT_FALSE(hasPlanningContextType); + EXPECT_FALSE(hasRendererFeatureConfigureCameraFramePlan); EXPECT_FALSE(hasRendererRecordingContextType); EXPECT_FALSE(hasRendererCameraRequestContextType); } @@ -2529,24 +2547,32 @@ TEST_F( TEST_F( MonoScriptRuntimeTest, - ManagedRenderPipelineAssetConfiguresFullscreenStagesThroughPlanningContext) { + ManagedRenderPipelineAssetPlansFullscreenStagesFromPipelineStageSupport) { const XCEngine::Rendering::Pipelines::ManagedRenderPipelineAssetDescriptor descriptor = { "GameScripts", "Gameplay", "ManagedPlannedFullscreenRenderPipelineProbeAsset" }; - XCEngine::Rendering::Pipelines::ManagedScriptableRenderPipelineAsset asset( - descriptor); + auto asset = + std::make_shared< + XCEngine::Rendering::Pipelines::ManagedScriptableRenderPipelineAsset>( + descriptor); XCEngine::Rendering::CameraRenderRequest request = {}; + request.context = {}; request.surface = XCEngine::Rendering::RenderSurface(64u, 64u); request.surface.SetColorAttachment( reinterpret_cast(1)); + request.surface.SetDepthAttachment( + reinterpret_cast(2)); - XCEngine::Rendering::CameraFramePlan plan = - XCEngine::Rendering::CameraFramePlan::FromRequest(request); - asset.ConfigureCameraFramePlan(plan); + XCEngine::Rendering::RenderPipelineHost host(asset); + const std::vector plans = + host.BuildFramePlans({ request }); + + ASSERT_EQ(plans.size(), 1u); + const XCEngine::Rendering::CameraFramePlan& plan = plans[0]; EXPECT_TRUE( plan.IsFullscreenStageRequested(