From 8edc68f02be5d167bef330cbd3f3577ffef22f1d Mon Sep 17 00:00:00 2001 From: ssdfasd <2156608475@qq.com> Date: Sun, 19 Apr 2026 14:42:57 +0800 Subject: [PATCH] refactor(srp): move recording helpers into universal extensions --- managed/CMakeLists.txt | 2 + managed/GameScripts/RenderPipelineApiProbe.cs | 2 +- .../ScriptableRenderContextApiSurfaceProbe.cs | 46 +++++ .../Rendering/Core/ScriptableRenderContext.cs | 148 -------------- ...tableRenderPipelineCameraRequestContext.cs | 13 +- ...DisableDirectionalShadowRendererFeature.cs | 2 +- .../ScriptableRenderContextExtensions.cs | 185 ++++++++++++++++++ ...rPipelineCameraRequestContextExtensions.cs | 30 +++ tests/scripting/test_mono_script_runtime.cpp | 48 ++++- 9 files changed, 309 insertions(+), 167 deletions(-) create mode 100644 managed/XCEngine.ScriptCore/Rendering/Universal/ScriptableRenderContextExtensions.cs create mode 100644 managed/XCEngine.ScriptCore/Rendering/Universal/ScriptableRenderPipelineCameraRequestContextExtensions.cs diff --git a/managed/CMakeLists.txt b/managed/CMakeLists.txt index 6f082539..dba75f54 100644 --- a/managed/CMakeLists.txt +++ b/managed/CMakeLists.txt @@ -205,9 +205,11 @@ set(XCENGINE_RENDER_PIPELINES_UNIVERSAL_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/XCEngine.ScriptCore/Rendering/Universal/RenderingDataResolver.cs ${CMAKE_CURRENT_SOURCE_DIR}/XCEngine.ScriptCore/Rendering/Universal/ShadowData.cs ${CMAKE_CURRENT_SOURCE_DIR}/XCEngine.ScriptCore/Rendering/Universal/ScriptableRenderPass.cs + ${CMAKE_CURRENT_SOURCE_DIR}/XCEngine.ScriptCore/Rendering/Universal/ScriptableRenderContextExtensions.cs ${CMAKE_CURRENT_SOURCE_DIR}/XCEngine.ScriptCore/Rendering/Universal/ScriptableRenderer.cs ${CMAKE_CURRENT_SOURCE_DIR}/XCEngine.ScriptCore/Rendering/Universal/ScriptableRendererData.cs ${CMAKE_CURRENT_SOURCE_DIR}/XCEngine.ScriptCore/Rendering/Universal/ScriptableRendererFeature.cs + ${CMAKE_CURRENT_SOURCE_DIR}/XCEngine.ScriptCore/Rendering/Universal/ScriptableRenderPipelineCameraRequestContextExtensions.cs ${CMAKE_CURRENT_SOURCE_DIR}/XCEngine.ScriptCore/Rendering/Universal/StageColorData.cs ${CMAKE_CURRENT_SOURCE_DIR}/XCEngine.ScriptCore/Rendering/Universal/UniversalRenderer.cs ${CMAKE_CURRENT_SOURCE_DIR}/XCEngine.ScriptCore/Rendering/Universal/UniversalRendererData.cs diff --git a/managed/GameScripts/RenderPipelineApiProbe.cs b/managed/GameScripts/RenderPipelineApiProbe.cs index 54908884..ac6d2ca5 100644 --- a/managed/GameScripts/RenderPipelineApiProbe.cs +++ b/managed/GameScripts/RenderPipelineApiProbe.cs @@ -789,7 +789,7 @@ namespace Gameplay ScriptableRenderPipelineCameraRequestContext context) { if (context != null && - context.hasDirectionalShadow) + context.HasDirectionalShadow()) { context.ClearDirectionalShadow(); } diff --git a/managed/GameScripts/ScriptableRenderContextApiSurfaceProbe.cs b/managed/GameScripts/ScriptableRenderContextApiSurfaceProbe.cs index de38cacb..c893c18d 100644 --- a/managed/GameScripts/ScriptableRenderContextApiSurfaceProbe.cs +++ b/managed/GameScripts/ScriptableRenderContextApiSurfaceProbe.cs @@ -20,6 +20,12 @@ namespace Gameplay public bool HasPublicContextStageColorData; public bool HasPublicCameraRequestContextHasDirectionalShadow; public bool HasPublicCameraRequestContextClearDirectionalShadow; + public bool HasUniversalContextRecordSceneExtension; + public bool HasUniversalContextRecordOpaqueScenePhaseExtension; + public bool HasUniversalContextRecordBeforeOpaqueInjectionExtension; + public bool HasUniversalContextRecordShaderVectorFullscreenPassExtension; + public bool HasUniversalCameraRequestContextHasDirectionalShadowExtension; + public bool HasUniversalCameraRequestContextClearDirectionalShadowExtension; public bool HasPublicPipelineAssetConfigureCameraFramePlan; public bool HasPlanningContextType; public bool HasRendererFeatureConfigureCameraFramePlan; @@ -38,6 +44,16 @@ namespace Gameplay typeof(ScriptableRenderPipelineAsset); System.Type rendererFeatureType = typeof(ScriptableRendererFeature); + System.Type universalAssemblyType = + typeof(ScriptableRendererFeature); + System.Reflection.Assembly universalAssembly = + universalAssemblyType.Assembly; + System.Type renderContextExtensionsType = + universalAssembly.GetType( + "XCEngine.Rendering.Universal.ScriptableRenderContextExtensions"); + System.Type cameraRequestContextExtensionsType = + universalAssembly.GetType( + "XCEngine.Rendering.Universal.ScriptableRenderPipelineCameraRequestContextExtensions"); HasPublicContextRecordScene = contextType.GetMethod( @@ -87,6 +103,36 @@ namespace Gameplay cameraRequestContextType.GetMethod( "ClearDirectionalShadow", PublicInstanceMethodFlags) != null; + HasUniversalContextRecordSceneExtension = + renderContextExtensionsType != null && + renderContextExtensionsType.GetMethod( + "RecordScene", + BindingFlags.Static | BindingFlags.Public) != null; + HasUniversalContextRecordOpaqueScenePhaseExtension = + renderContextExtensionsType != null && + renderContextExtensionsType.GetMethod( + "RecordOpaqueScenePhase", + BindingFlags.Static | BindingFlags.Public) != null; + HasUniversalContextRecordBeforeOpaqueInjectionExtension = + renderContextExtensionsType != null && + renderContextExtensionsType.GetMethod( + "RecordBeforeOpaqueInjection", + BindingFlags.Static | BindingFlags.Public) != null; + HasUniversalContextRecordShaderVectorFullscreenPassExtension = + renderContextExtensionsType != null && + renderContextExtensionsType.GetMethod( + "RecordShaderVectorFullscreenPass", + BindingFlags.Static | BindingFlags.Public) != null; + HasUniversalCameraRequestContextHasDirectionalShadowExtension = + cameraRequestContextExtensionsType != null && + cameraRequestContextExtensionsType.GetMethod( + "HasDirectionalShadow", + BindingFlags.Static | BindingFlags.Public) != null; + HasUniversalCameraRequestContextClearDirectionalShadowExtension = + cameraRequestContextExtensionsType != null && + cameraRequestContextExtensionsType.GetMethod( + "ClearDirectionalShadow", + BindingFlags.Static | BindingFlags.Public) != null; HasPublicPipelineAssetConfigureCameraFramePlan = pipelineAssetType.GetMethod( "ConfigureCameraFramePlan", diff --git a/managed/XCEngine.ScriptCore/Rendering/Core/ScriptableRenderContext.cs b/managed/XCEngine.ScriptCore/Rendering/Core/ScriptableRenderContext.cs index 865af9c7..7174121d 100644 --- a/managed/XCEngine.ScriptCore/Rendering/Core/ScriptableRenderContext.cs +++ b/managed/XCEngine.ScriptCore/Rendering/Core/ScriptableRenderContext.cs @@ -1,33 +1,9 @@ -using System; using XCEngine; namespace XCEngine.Rendering { public sealed class ScriptableRenderContext { - private enum RecordedScenePhase - { - Opaque = 0, - Skybox = 1, - Transparent = 3 - } - - private enum RecordedSceneInjectionPoint - { - BeforeOpaque = 0, - AfterOpaque = 1, - BeforeSkybox = 2, - AfterSkybox = 3, - BeforeTransparent = 4, - AfterTransparent = 5 - } - - private enum RecordedFullscreenPassType - { - ColorScale = 0, - ShaderVector = 1 - } - private readonly ulong m_nativeHandle; internal ScriptableRenderContext(ulong nativeHandle) @@ -41,130 +17,6 @@ namespace XCEngine.Rendering internal ulong nativeHandle => m_nativeHandle; - - public bool RecordScene() - { - return InternalCalls - .Rendering_ScriptableRenderContext_RecordScene( - m_nativeHandle); - } - - public bool RecordOpaqueScenePhase() - { - return RecordScenePhaseInternal( - RecordedScenePhase.Opaque); - } - - public bool RecordSkyboxScenePhase() - { - return RecordScenePhaseInternal( - RecordedScenePhase.Skybox); - } - - public bool RecordTransparentScenePhase() - { - return RecordScenePhaseInternal( - RecordedScenePhase.Transparent); - } - - public bool RecordBeforeOpaqueInjection() - { - return RecordSceneInjectionPointInternal( - RecordedSceneInjectionPoint.BeforeOpaque); - } - - public bool RecordAfterOpaqueInjection() - { - return RecordSceneInjectionPointInternal( - RecordedSceneInjectionPoint.AfterOpaque); - } - - public bool RecordBeforeSkyboxInjection() - { - return RecordSceneInjectionPointInternal( - RecordedSceneInjectionPoint.BeforeSkybox); - } - - public bool RecordAfterSkyboxInjection() - { - return RecordSceneInjectionPointInternal( - RecordedSceneInjectionPoint.AfterSkybox); - } - - public bool RecordBeforeTransparentInjection() - { - return RecordSceneInjectionPointInternal( - RecordedSceneInjectionPoint.BeforeTransparent); - } - - public bool RecordAfterTransparentInjection() - { - return RecordSceneInjectionPointInternal( - RecordedSceneInjectionPoint.AfterTransparent); - } - - public bool RecordColorScaleFullscreenPass( - Vector4 colorScale) - { - return RecordFullscreenPassInternal( - RecordedFullscreenPassType.ColorScale, - string.Empty, - string.Empty, - colorScale); - } - - public bool RecordShaderVectorFullscreenPass( - string shaderPath, - Vector4 vectorPayload, - string passName = null) - { - if (string.IsNullOrEmpty(shaderPath)) - { - throw new ArgumentException( - "Fullscreen shader path cannot be null or empty.", - nameof(shaderPath)); - } - - return RecordFullscreenPassInternal( - RecordedFullscreenPassType.ShaderVector, - shaderPath, - passName ?? string.Empty, - vectorPayload); - } - - private bool RecordScenePhaseInternal( - RecordedScenePhase scenePhase) - { - return InternalCalls - .Rendering_ScriptableRenderContext_RecordScenePhase( - m_nativeHandle, - (int)scenePhase); - } - - private bool RecordSceneInjectionPointInternal( - RecordedSceneInjectionPoint injectionPoint) - { - return InternalCalls - .Rendering_ScriptableRenderContext_RecordSceneInjectionPoint( - m_nativeHandle, - (int)injectionPoint); - } - - private bool RecordFullscreenPassInternal( - RecordedFullscreenPassType passType, - string shaderPath, - string passName, - Vector4 vectorPayload) - { - return InternalCalls - .Rendering_ScriptableRenderContext_RecordFullscreenPass( - m_nativeHandle, - (int)passType, - shaderPath, - passName, - ref vectorPayload); - } - } } diff --git a/managed/XCEngine.ScriptCore/Rendering/Core/ScriptableRenderPipelineCameraRequestContext.cs b/managed/XCEngine.ScriptCore/Rendering/Core/ScriptableRenderPipelineCameraRequestContext.cs index 76690f87..9a0c918f 100644 --- a/managed/XCEngine.ScriptCore/Rendering/Core/ScriptableRenderPipelineCameraRequestContext.cs +++ b/managed/XCEngine.ScriptCore/Rendering/Core/ScriptableRenderPipelineCameraRequestContext.cs @@ -21,17 +21,8 @@ namespace XCEngine.Rendering .Rendering_ScriptableRenderPipelineCameraRequestContext_GetRenderedRequestCount( m_nativeHandle); - public bool hasDirectionalShadow => - InternalCalls - .Rendering_ScriptableRenderPipelineCameraRequestContext_GetHasDirectionalShadow( - m_nativeHandle); - - public void ClearDirectionalShadow() - { - InternalCalls - .Rendering_ScriptableRenderPipelineCameraRequestContext_ClearDirectionalShadow( - m_nativeHandle); - } + internal ulong nativeHandle => + m_nativeHandle; } } diff --git a/managed/XCEngine.ScriptCore/Rendering/Universal/DisableDirectionalShadowRendererFeature.cs b/managed/XCEngine.ScriptCore/Rendering/Universal/DisableDirectionalShadowRendererFeature.cs index 03b02600..c10c4c9b 100644 --- a/managed/XCEngine.ScriptCore/Rendering/Universal/DisableDirectionalShadowRendererFeature.cs +++ b/managed/XCEngine.ScriptCore/Rendering/Universal/DisableDirectionalShadowRendererFeature.cs @@ -10,7 +10,7 @@ namespace XCEngine.Rendering.Universal ScriptableRenderPipelineCameraRequestContext context) { if (context != null && - context.hasDirectionalShadow) + context.HasDirectionalShadow()) { context.ClearDirectionalShadow(); } diff --git a/managed/XCEngine.ScriptCore/Rendering/Universal/ScriptableRenderContextExtensions.cs b/managed/XCEngine.ScriptCore/Rendering/Universal/ScriptableRenderContextExtensions.cs new file mode 100644 index 00000000..e201b396 --- /dev/null +++ b/managed/XCEngine.ScriptCore/Rendering/Universal/ScriptableRenderContextExtensions.cs @@ -0,0 +1,185 @@ +using System; +using XCEngine; +using XCEngine.Rendering; + +namespace XCEngine.Rendering.Universal +{ + public static class ScriptableRenderContextExtensions + { + private enum RecordedScenePhase + { + Opaque = 0, + Skybox = 1, + Transparent = 3 + } + + private enum RecordedSceneInjectionPoint + { + BeforeOpaque = 0, + AfterOpaque = 1, + BeforeSkybox = 2, + AfterSkybox = 3, + BeforeTransparent = 4, + AfterTransparent = 5 + } + + private enum RecordedFullscreenPassType + { + ColorScale = 0, + ShaderVector = 1 + } + + public static bool RecordScene( + this ScriptableRenderContext context) + { + return context != null && + InternalCalls + .Rendering_ScriptableRenderContext_RecordScene( + context.nativeHandle); + } + + public static bool RecordOpaqueScenePhase( + this ScriptableRenderContext context) + { + return RecordScenePhaseInternal( + context, + RecordedScenePhase.Opaque); + } + + public static bool RecordSkyboxScenePhase( + this ScriptableRenderContext context) + { + return RecordScenePhaseInternal( + context, + RecordedScenePhase.Skybox); + } + + public static bool RecordTransparentScenePhase( + this ScriptableRenderContext context) + { + return RecordScenePhaseInternal( + context, + RecordedScenePhase.Transparent); + } + + public static bool RecordBeforeOpaqueInjection( + this ScriptableRenderContext context) + { + return RecordSceneInjectionPointInternal( + context, + RecordedSceneInjectionPoint.BeforeOpaque); + } + + public static bool RecordAfterOpaqueInjection( + this ScriptableRenderContext context) + { + return RecordSceneInjectionPointInternal( + context, + RecordedSceneInjectionPoint.AfterOpaque); + } + + public static bool RecordBeforeSkyboxInjection( + this ScriptableRenderContext context) + { + return RecordSceneInjectionPointInternal( + context, + RecordedSceneInjectionPoint.BeforeSkybox); + } + + public static bool RecordAfterSkyboxInjection( + this ScriptableRenderContext context) + { + return RecordSceneInjectionPointInternal( + context, + RecordedSceneInjectionPoint.AfterSkybox); + } + + public static bool RecordBeforeTransparentInjection( + this ScriptableRenderContext context) + { + return RecordSceneInjectionPointInternal( + context, + RecordedSceneInjectionPoint.BeforeTransparent); + } + + public static bool RecordAfterTransparentInjection( + this ScriptableRenderContext context) + { + return RecordSceneInjectionPointInternal( + context, + RecordedSceneInjectionPoint.AfterTransparent); + } + + public static bool RecordColorScaleFullscreenPass( + this ScriptableRenderContext context, + Vector4 colorScale) + { + return RecordFullscreenPassInternal( + context, + RecordedFullscreenPassType.ColorScale, + string.Empty, + string.Empty, + colorScale); + } + + public static bool RecordShaderVectorFullscreenPass( + this ScriptableRenderContext context, + string shaderPath, + Vector4 vectorPayload, + string passName = null) + { + if (string.IsNullOrEmpty(shaderPath)) + { + throw new ArgumentException( + "Fullscreen shader path cannot be null or empty.", + nameof(shaderPath)); + } + + return RecordFullscreenPassInternal( + context, + RecordedFullscreenPassType.ShaderVector, + shaderPath, + passName ?? string.Empty, + vectorPayload); + } + + private static bool RecordScenePhaseInternal( + ScriptableRenderContext context, + RecordedScenePhase scenePhase) + { + return context != null && + InternalCalls + .Rendering_ScriptableRenderContext_RecordScenePhase( + context.nativeHandle, + (int)scenePhase); + } + + private static bool RecordSceneInjectionPointInternal( + ScriptableRenderContext context, + RecordedSceneInjectionPoint injectionPoint) + { + return context != null && + InternalCalls + .Rendering_ScriptableRenderContext_RecordSceneInjectionPoint( + context.nativeHandle, + (int)injectionPoint); + } + + private static bool RecordFullscreenPassInternal( + ScriptableRenderContext context, + RecordedFullscreenPassType passType, + string shaderPath, + string passName, + Vector4 vectorPayload) + { + return context != null && + InternalCalls + .Rendering_ScriptableRenderContext_RecordFullscreenPass( + context.nativeHandle, + (int)passType, + shaderPath, + passName, + ref vectorPayload); + } + } +} diff --git a/managed/XCEngine.ScriptCore/Rendering/Universal/ScriptableRenderPipelineCameraRequestContextExtensions.cs b/managed/XCEngine.ScriptCore/Rendering/Universal/ScriptableRenderPipelineCameraRequestContextExtensions.cs new file mode 100644 index 00000000..1396846d --- /dev/null +++ b/managed/XCEngine.ScriptCore/Rendering/Universal/ScriptableRenderPipelineCameraRequestContextExtensions.cs @@ -0,0 +1,30 @@ +using XCEngine; +using XCEngine.Rendering; + +namespace XCEngine.Rendering.Universal +{ + public static class ScriptableRenderPipelineCameraRequestContextExtensions + { + public static bool HasDirectionalShadow( + this ScriptableRenderPipelineCameraRequestContext context) + { + return context != null && + InternalCalls + .Rendering_ScriptableRenderPipelineCameraRequestContext_GetHasDirectionalShadow( + context.nativeHandle); + } + + public static void ClearDirectionalShadow( + this ScriptableRenderPipelineCameraRequestContext context) + { + if (context == null) + { + return; + } + + InternalCalls + .Rendering_ScriptableRenderPipelineCameraRequestContext_ClearDirectionalShadow( + context.nativeHandle); + } + } +} diff --git a/tests/scripting/test_mono_script_runtime.cpp b/tests/scripting/test_mono_script_runtime.cpp index 146004af..c15fd249 100644 --- a/tests/scripting/test_mono_script_runtime.cpp +++ b/tests/scripting/test_mono_script_runtime.cpp @@ -1163,6 +1163,12 @@ TEST_F( bool hasPublicContextStageColorData = false; bool hasPublicCameraRequestContextHasDirectionalShadow = false; bool hasPublicCameraRequestContextClearDirectionalShadow = false; + bool hasUniversalContextRecordSceneExtension = false; + bool hasUniversalContextRecordOpaqueScenePhaseExtension = false; + bool hasUniversalContextRecordBeforeOpaqueInjectionExtension = false; + bool hasUniversalContextRecordShaderVectorFullscreenPassExtension = false; + bool hasUniversalCameraRequestContextHasDirectionalShadowExtension = false; + bool hasUniversalCameraRequestContextClearDirectionalShadowExtension = false; bool hasPublicPipelineAssetConfigureCameraFramePlan = false; bool hasPlanningContextType = false; bool hasRendererFeatureConfigureCameraFramePlan = false; @@ -1217,6 +1223,30 @@ TEST_F( selectionScript, "HasPublicCameraRequestContextClearDirectionalShadow", hasPublicCameraRequestContextClearDirectionalShadow)); + EXPECT_TRUE(runtime->TryGetFieldValue( + selectionScript, + "HasUniversalContextRecordSceneExtension", + hasUniversalContextRecordSceneExtension)); + EXPECT_TRUE(runtime->TryGetFieldValue( + selectionScript, + "HasUniversalContextRecordOpaqueScenePhaseExtension", + hasUniversalContextRecordOpaqueScenePhaseExtension)); + EXPECT_TRUE(runtime->TryGetFieldValue( + selectionScript, + "HasUniversalContextRecordBeforeOpaqueInjectionExtension", + hasUniversalContextRecordBeforeOpaqueInjectionExtension)); + EXPECT_TRUE(runtime->TryGetFieldValue( + selectionScript, + "HasUniversalContextRecordShaderVectorFullscreenPassExtension", + hasUniversalContextRecordShaderVectorFullscreenPassExtension)); + EXPECT_TRUE(runtime->TryGetFieldValue( + selectionScript, + "HasUniversalCameraRequestContextHasDirectionalShadowExtension", + hasUniversalCameraRequestContextHasDirectionalShadowExtension)); + EXPECT_TRUE(runtime->TryGetFieldValue( + selectionScript, + "HasUniversalCameraRequestContextClearDirectionalShadowExtension", + hasUniversalCameraRequestContextClearDirectionalShadowExtension)); EXPECT_TRUE(runtime->TryGetFieldValue( selectionScript, "HasPublicPipelineAssetConfigureCameraFramePlan", @@ -1238,18 +1268,24 @@ TEST_F( "HasRendererCameraRequestContextType", hasRendererCameraRequestContextType)); - EXPECT_TRUE(hasPublicContextRecordScene); - EXPECT_TRUE(hasPublicContextRecordOpaqueScenePhase); - EXPECT_TRUE(hasPublicContextRecordBeforeOpaqueInjection); - EXPECT_TRUE(hasPublicContextRecordShaderVectorFullscreenPass); + EXPECT_FALSE(hasPublicContextRecordScene); + EXPECT_FALSE(hasPublicContextRecordOpaqueScenePhase); + EXPECT_FALSE(hasPublicContextRecordBeforeOpaqueInjection); + EXPECT_FALSE(hasPublicContextRecordShaderVectorFullscreenPass); EXPECT_FALSE(hasPublicContextCameraData); EXPECT_FALSE(hasPublicContextLightingData); EXPECT_FALSE(hasPublicContextShadowData); EXPECT_FALSE(hasPublicContextEnvironmentData); EXPECT_FALSE(hasPublicContextFinalColorData); EXPECT_FALSE(hasPublicContextStageColorData); - EXPECT_TRUE(hasPublicCameraRequestContextHasDirectionalShadow); - EXPECT_TRUE(hasPublicCameraRequestContextClearDirectionalShadow); + EXPECT_FALSE(hasPublicCameraRequestContextHasDirectionalShadow); + EXPECT_FALSE(hasPublicCameraRequestContextClearDirectionalShadow); + EXPECT_TRUE(hasUniversalContextRecordSceneExtension); + EXPECT_TRUE(hasUniversalContextRecordOpaqueScenePhaseExtension); + EXPECT_TRUE(hasUniversalContextRecordBeforeOpaqueInjectionExtension); + EXPECT_TRUE(hasUniversalContextRecordShaderVectorFullscreenPassExtension); + EXPECT_TRUE(hasUniversalCameraRequestContextHasDirectionalShadowExtension); + EXPECT_TRUE(hasUniversalCameraRequestContextClearDirectionalShadowExtension); EXPECT_FALSE(hasPublicPipelineAssetConfigureCameraFramePlan); EXPECT_FALSE(hasPlanningContextType); EXPECT_FALSE(hasRendererFeatureConfigureCameraFramePlan);