diff --git a/engine/src/Scripting/Mono/MonoScriptRuntime.cpp b/engine/src/Scripting/Mono/MonoScriptRuntime.cpp index 45d07589..2cd776bc 100644 --- a/engine/src/Scripting/Mono/MonoScriptRuntime.cpp +++ b/engine/src/Scripting/Mono/MonoScriptRuntime.cpp @@ -13,6 +13,7 @@ #include "Rendering/Execution/CameraFramePlan.h" #include "Rendering/Internal/RenderPipelineFactory.h" #include "Rendering/Passes/BuiltinColorScalePostProcessPass.h" +#include "Rendering/Planning/CameraPostProcessDesc.h" #include "Rendering/Pipelines/NativeSceneRecorder.h" #include "Rendering/Pipelines/ManagedScriptableRenderPipelineAsset.h" #include "Rendering/RenderPipelineStageGraphContract.h" @@ -93,7 +94,7 @@ struct ManagedScriptableRenderContextState { Rendering::CameraFrameStage stage = Rendering::CameraFrameStage::MainScene; const Rendering::RenderPipelineStageRenderGraphContext* graphContext = nullptr; Rendering::Pipelines::NativeSceneRecorder* sceneRecorder = nullptr; - std::vector queuedColorScaleFullscreenPasses = {}; + std::vector queuedFullscreenPasses = {}; }; struct ManagedScriptableRenderPipelineCameraRequestContextState { @@ -322,6 +323,36 @@ bool SupportsManagedRenderPipelineStageGraphRecording( Rendering::IsCameraFrameFullscreenSequenceStage(stage); } +Rendering::RenderPass* ConfigureManagedFullscreenPass( + std::vector>& passPool, + size_t passIndex, + const Rendering::CameraPostProcessPassDesc& passDesc) { + while (passPool.size() <= passIndex) { + passPool.push_back(nullptr); + } + + std::unique_ptr& passSlot = passPool[passIndex]; + switch (passDesc.type) { + case Rendering::CameraPostProcessPassType::ColorScale: { + Rendering::Passes::BuiltinColorScalePostProcessPass* colorScalePass = + dynamic_cast( + passSlot.get()); + if (colorScalePass == nullptr) { + passSlot = + std::make_unique(); + colorScalePass = + static_cast( + passSlot.get()); + } + + colorScalePass->SetColorScale(passDesc.colorScale.scale); + return colorScalePass; + } + default: + return nullptr; + } +} + } // namespace class MonoManagedRenderPipelineAssetRuntime final @@ -406,13 +437,13 @@ public: } void Shutdown() override { - for (std::unique_ptr& pass : - m_colorScalePassPool) { + for (std::unique_ptr& pass : + m_fullscreenPassPool) { if (pass != nullptr) { pass->Shutdown(); } } - m_colorScalePassPool.clear(); + m_fullscreenPassPool.clear(); if (m_defaultSceneRenderer != nullptr) { m_defaultSceneRenderer->Shutdown(); } @@ -568,29 +599,27 @@ private: bool FlushManagedFullscreenPasses( const Rendering::RenderPipelineStageRenderGraphContext& context, const ManagedScriptableRenderContextState& managedContextState) { - if (managedContextState.queuedColorScaleFullscreenPasses.empty()) { + if (managedContextState.queuedFullscreenPasses.empty()) { return true; } if (!Rendering::IsCameraFrameFullscreenSequenceStage(context.stage)) { return false; } - while (m_colorScalePassPool.size() < - managedContextState.queuedColorScaleFullscreenPasses.size()) { - m_colorScalePassPool.push_back( - std::make_unique()); - } - std::vector passes = {}; passes.reserve( - managedContextState.queuedColorScaleFullscreenPasses.size()); + managedContextState.queuedFullscreenPasses.size()); for (size_t passIndex = 0u; - passIndex < managedContextState.queuedColorScaleFullscreenPasses.size(); + passIndex < managedContextState.queuedFullscreenPasses.size(); ++passIndex) { - Rendering::Passes::BuiltinColorScalePostProcessPass* const pass = - m_colorScalePassPool[passIndex].get(); - pass->SetColorScale( - managedContextState.queuedColorScaleFullscreenPasses[passIndex]); + Rendering::RenderPass* const pass = + ConfigureManagedFullscreenPass( + m_fullscreenPassPool, + passIndex, + managedContextState.queuedFullscreenPasses[passIndex]); + if (pass == nullptr) { + return false; + } passes.push_back(pass); } @@ -605,8 +634,7 @@ private: mutable MonoMethod* m_supportsStageMethod = nullptr; mutable MonoMethod* m_recordStageMethod = nullptr; mutable bool m_pipelineCreationAttempted = false; - std::vector> - m_colorScalePassPool = {}; + std::vector> m_fullscreenPassPool = {}; std::unique_ptr m_defaultSceneRenderer = nullptr; }; @@ -2621,19 +2649,32 @@ InternalCall_Rendering_ScriptableRenderContext_RecordSceneInjectionPoint( } mono_bool -InternalCall_Rendering_ScriptableRenderContext_RecordColorScaleFullscreenPass( +InternalCall_Rendering_ScriptableRenderContext_RecordFullscreenPass( uint64_t nativeHandle, - XCEngine::Math::Vector4* colorScale) { + int32_t passType, + XCEngine::Math::Vector4* vectorPayload) { ManagedScriptableRenderContextState* const state = FindManagedScriptableRenderContextState(nativeHandle); if (state == nullptr || state->graphContext == nullptr || - colorScale == nullptr || !Rendering::IsCameraFrameFullscreenSequenceStage(state->stage)) { return 0; } - state->queuedColorScaleFullscreenPasses.push_back(*colorScale); + Rendering::CameraPostProcessPassDesc passDesc = {}; + switch (static_cast(passType)) { + case Rendering::CameraPostProcessPassType::ColorScale: + if (vectorPayload == nullptr) { + return 0; + } + passDesc = + Rendering::CameraPostProcessPassDesc::MakeColorScale(*vectorPayload); + break; + default: + return 0; + } + + state->queuedFullscreenPasses.push_back(passDesc); return 1; } @@ -2874,7 +2915,7 @@ void RegisterInternalCalls() { mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderContext_RecordScene", reinterpret_cast(&InternalCall_Rendering_ScriptableRenderContext_RecordScene)); mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderContext_RecordScenePhase", reinterpret_cast(&InternalCall_Rendering_ScriptableRenderContext_RecordScenePhase)); mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderContext_RecordSceneInjectionPoint", reinterpret_cast(&InternalCall_Rendering_ScriptableRenderContext_RecordSceneInjectionPoint)); - mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderContext_RecordColorScaleFullscreenPass", reinterpret_cast(&InternalCall_Rendering_ScriptableRenderContext_RecordColorScaleFullscreenPass)); + mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderContext_RecordFullscreenPass", reinterpret_cast(&InternalCall_Rendering_ScriptableRenderContext_RecordFullscreenPass)); mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderPipelineCameraRequestContext_GetRenderedBaseCameraCount", reinterpret_cast(&InternalCall_Rendering_ScriptableRenderPipelineCameraRequestContext_GetRenderedBaseCameraCount)); 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)); diff --git a/managed/CMakeLists.txt b/managed/CMakeLists.txt index ea387736..7b30c92e 100644 --- a/managed/CMakeLists.txt +++ b/managed/CMakeLists.txt @@ -106,6 +106,7 @@ set(XCENGINE_SCRIPT_CORE_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/XCEngine.ScriptCore/Component.cs ${CMAKE_CURRENT_SOURCE_DIR}/XCEngine.ScriptCore/Debug.cs ${CMAKE_CURRENT_SOURCE_DIR}/XCEngine.ScriptCore/ForceMode.cs + ${CMAKE_CURRENT_SOURCE_DIR}/XCEngine.ScriptCore/FullscreenPassDescriptor.cs ${CMAKE_CURRENT_SOURCE_DIR}/XCEngine.ScriptCore/GraphicsSettings.cs ${CMAKE_CURRENT_SOURCE_DIR}/XCEngine.ScriptCore/GameObject.cs ${CMAKE_CURRENT_SOURCE_DIR}/XCEngine.ScriptCore/Input.cs diff --git a/managed/GameScripts/RenderPipelineApiProbe.cs b/managed/GameScripts/RenderPipelineApiProbe.cs index d06efbad..7a62e21a 100644 --- a/managed/GameScripts/RenderPipelineApiProbe.cs +++ b/managed/GameScripts/RenderPipelineApiProbe.cs @@ -138,10 +138,12 @@ namespace Gameplay { return context != null && context.stage == CameraFrameStage.PostProcess && - context.RecordColorScaleFullscreenPass( - new Vector4(1.10f, 0.95f, 0.90f, 1.0f)) && - context.RecordColorScaleFullscreenPass( - new Vector4(0.95f, 1.05f, 1.10f, 1.0f)); + context.RecordFullscreenPass( + FullscreenPassDescriptor.CreateColorScale( + new Vector4(1.10f, 0.95f, 0.90f, 1.0f))) && + context.RecordFullscreenPass( + FullscreenPassDescriptor.CreateColorScale( + new Vector4(0.95f, 1.05f, 1.10f, 1.0f))); } } @@ -195,8 +197,9 @@ namespace Gameplay if (context.stage == CameraFrameStage.PostProcess) { RecordPostProcessCallCount++; - return context.RecordColorScaleFullscreenPass( - new Vector4(1.03f, 0.98f, 0.94f, 1.0f)); + return context.RecordFullscreenPass( + FullscreenPassDescriptor.CreateColorScale( + new Vector4(1.03f, 0.98f, 0.94f, 1.0f))); } return false; @@ -219,8 +222,9 @@ namespace Gameplay return context != null && (context.stage == CameraFrameStage.PostProcess || context.stage == CameraFrameStage.FinalOutput) && - context.RecordColorScaleFullscreenPass( - new Vector4(1.05f, 1.0f, 0.95f, 1.0f)); + context.RecordFullscreenPass( + FullscreenPassDescriptor.CreateColorScale( + new Vector4(1.05f, 1.0f, 0.95f, 1.0f))); } } diff --git a/managed/XCEngine.ScriptCore/FullscreenPassDescriptor.cs b/managed/XCEngine.ScriptCore/FullscreenPassDescriptor.cs new file mode 100644 index 00000000..d969ab26 --- /dev/null +++ b/managed/XCEngine.ScriptCore/FullscreenPassDescriptor.cs @@ -0,0 +1,33 @@ +namespace XCEngine +{ + public enum FullscreenPassType + { + ColorScale = 0 + } + + public struct FullscreenPassDescriptor + { + public FullscreenPassType type; + public Vector4 vectorPayload; + + public static FullscreenPassDescriptor CreateColorScale( + Vector4 colorScale) + { + FullscreenPassDescriptor descriptor = new FullscreenPassDescriptor(); + descriptor.type = FullscreenPassType.ColorScale; + descriptor.vectorPayload = colorScale; + return descriptor; + } + + public bool IsValid() + { + switch (type) + { + case FullscreenPassType.ColorScale: + return true; + default: + return false; + } + } + } +} diff --git a/managed/XCEngine.ScriptCore/InternalCalls.cs b/managed/XCEngine.ScriptCore/InternalCalls.cs index 66fe21a2..1aeca7b5 100644 --- a/managed/XCEngine.ScriptCore/InternalCalls.cs +++ b/managed/XCEngine.ScriptCore/InternalCalls.cs @@ -405,9 +405,10 @@ namespace XCEngine [MethodImpl(MethodImplOptions.InternalCall)] internal static extern bool - Rendering_ScriptableRenderContext_RecordColorScaleFullscreenPass( + Rendering_ScriptableRenderContext_RecordFullscreenPass( ulong nativeHandle, - ref Vector4 colorScale); + int passType, + ref Vector4 vectorPayload); [MethodImpl(MethodImplOptions.InternalCall)] internal static extern int diff --git a/managed/XCEngine.ScriptCore/ScriptableRenderContext.cs b/managed/XCEngine.ScriptCore/ScriptableRenderContext.cs index 8513c199..0900c613 100644 --- a/managed/XCEngine.ScriptCore/ScriptableRenderContext.cs +++ b/managed/XCEngine.ScriptCore/ScriptableRenderContext.cs @@ -1,3 +1,5 @@ +using System; + namespace XCEngine { public sealed class ScriptableRenderContext @@ -42,13 +44,22 @@ namespace XCEngine (int)injectionPoint); } - public bool RecordColorScaleFullscreenPass( - Vector4 colorScale) + public bool RecordFullscreenPass( + FullscreenPassDescriptor pass) { + if (!pass.IsValid()) + { + throw new ArgumentException( + "Invalid fullscreen pass descriptor.", + nameof(pass)); + } + + Vector4 vectorPayload = pass.vectorPayload; return InternalCalls - .Rendering_ScriptableRenderContext_RecordColorScaleFullscreenPass( + .Rendering_ScriptableRenderContext_RecordFullscreenPass( m_nativeHandle, - ref colorScale); + (int)pass.type, + ref vectorPayload); } } }