refactor(srp): move urp shadow execution bridge into managed

This commit is contained in:
2026-04-21 17:41:44 +08:00
parent 578103f970
commit 1e16995757
15 changed files with 560 additions and 188 deletions

View File

@@ -10,7 +10,9 @@
#include "Debug/Logger.h"
#include "Input/InputManager.h"
#include "Physics/PhysicsWorld.h"
#include "Rendering/Caches/DirectionalShadowSurfaceCache.h"
#include "Rendering/Execution/CameraFramePlan.h"
#include "Rendering/Execution/DirectionalShadowExecutionState.h"
#include "Rendering/Execution/CameraFrameRenderGraphFrameData.h"
#include "Rendering/Execution/Internal/CameraFrameGraph/SurfaceUtils.h"
#include "Rendering/Graph/RenderGraph.h"
@@ -24,6 +26,7 @@
#include "Rendering/Pipelines/NativeSceneRecorder.h"
#include "Rendering/Pipelines/ManagedScriptableRenderPipelineAsset.h"
#include "Rendering/RenderPassGraphContract.h"
#include "Rendering/RenderPipeline.h"
#include "Rendering/RenderPipelineAsset.h"
#include "Rendering/RenderPipelineStageGraphContract.h"
#include "Resources/BuiltinResources.h"
@@ -134,6 +137,16 @@ struct ManagedCameraRenderRequestContextState {
bool suppressDirectionalShadow = false;
};
struct ManagedDirectionalShadowExecutionContextState {
uint64_t handle = 0;
const Rendering::CameraFramePlan* plan = nullptr;
const Rendering::DirectionalShadowSurfaceAllocation*
shadowAllocation = nullptr;
Rendering::DirectionalShadowExecutionState* shadowState =
nullptr;
bool explicitlyConfigured = false;
};
struct ManagedScriptableRenderPipelinePlanningContextState {
uint64_t handle = 0;
Rendering::CameraFramePlan* plan = nullptr;
@@ -516,6 +529,60 @@ void UnregisterManagedCameraRenderRequestContextState(
GetManagedCameraRenderRequestContextRegistry().erase(handle);
}
uint64_t& GetManagedDirectionalShadowExecutionContextNextHandle() {
static uint64_t nextHandle = 1;
return nextHandle;
}
std::unordered_map<
uint64_t,
ManagedDirectionalShadowExecutionContextState*>&
GetManagedDirectionalShadowExecutionContextRegistry() {
static std::unordered_map<
uint64_t,
ManagedDirectionalShadowExecutionContextState*>
registry;
return registry;
}
ManagedDirectionalShadowExecutionContextState*
FindManagedDirectionalShadowExecutionContextState(
uint64_t handle) {
const auto it =
GetManagedDirectionalShadowExecutionContextRegistry().find(
handle);
return it !=
GetManagedDirectionalShadowExecutionContextRegistry()
.end()
? it->second
: nullptr;
}
uint64_t RegisterManagedDirectionalShadowExecutionContextState(
ManagedDirectionalShadowExecutionContextState& state) {
uint64_t handle =
GetManagedDirectionalShadowExecutionContextNextHandle()++;
if (handle == 0) {
handle =
GetManagedDirectionalShadowExecutionContextNextHandle()++;
}
state.handle = handle;
GetManagedDirectionalShadowExecutionContextRegistry()[handle] =
&state;
return handle;
}
void UnregisterManagedDirectionalShadowExecutionContextState(
uint64_t handle) {
if (handle == 0) {
return;
}
GetManagedDirectionalShadowExecutionContextRegistry().erase(
handle);
}
uint64_t& GetManagedScriptableRenderPipelinePlanningContextNextHandle() {
static uint64_t nextHandle = 1;
return nextHandle;
@@ -1366,6 +1433,12 @@ public:
directionalShadowSettings) const override;
void ConfigureCameraFramePlan(
Rendering::CameraFramePlan& plan) const override;
bool ConfigureDirectionalShadowExecutionState(
const Rendering::CameraFramePlan& plan,
const Rendering::DirectionalShadowSurfaceAllocation&
shadowAllocation,
Rendering::DirectionalShadowExecutionState& shadowState)
const override;
bool TryGetDefaultFinalColorSettings(
Rendering::FinalColorSettings& settings) const override;
@@ -1382,10 +1455,6 @@ public:
int32_t rendererIndex) const override;
std::string GetDirectionalShadowPlanningPolicyAssetKey() const
override;
std::string GetDirectionalShadowExecutionPolicyAssetKey() const
override;
std::string GetDirectionalShadowExecutionPolicyAssetKey(
int32_t rendererIndex) const override;
std::string GetCameraFrameStandalonePassAssetKey(
Rendering::CameraFrameStage stage) const override;
std::string GetCameraFrameStandalonePassAssetKey(
@@ -1433,13 +1502,10 @@ private:
MonoObject* assetObject) const;
MonoMethod* ResolveGetRenderSceneSetupPolicyAssetKeyContextualMethod(
MonoObject* assetObject) const;
MonoMethod* ResolveConfigureDirectionalShadowExecutionStateMethod(
MonoObject* assetObject) const;
MonoMethod* ResolveGetDirectionalShadowPlanningPolicyAssetKeyMethod(
MonoObject* assetObject) const;
MonoMethod* ResolveGetDirectionalShadowExecutionPolicyAssetKeyMethod(
MonoObject* assetObject) const;
MonoMethod*
ResolveGetDirectionalShadowExecutionPolicyAssetKeyContextualMethod(
MonoObject* assetObject) const;
MonoMethod* ResolveGetCameraFrameStandalonePassAssetKeyMethod(
MonoObject* assetObject) const;
MonoMethod*
@@ -1471,13 +1537,10 @@ private:
mutable MonoMethod*
m_getRenderSceneSetupPolicyAssetKeyContextualMethod =
nullptr;
mutable MonoMethod*
m_configureDirectionalShadowExecutionStateMethod = nullptr;
mutable MonoMethod*
m_getDirectionalShadowPlanningPolicyAssetKeyMethod = nullptr;
mutable MonoMethod*
m_getDirectionalShadowExecutionPolicyAssetKeyMethod = nullptr;
mutable MonoMethod*
m_getDirectionalShadowExecutionPolicyAssetKeyContextualMethod =
nullptr;
mutable MonoMethod* m_getCameraFrameStandalonePassAssetKeyMethod =
nullptr;
mutable MonoMethod*
@@ -1998,6 +2061,52 @@ void MonoManagedRenderPipelineAssetRuntime::ConfigureCameraFramePlan(
planningContextHandle);
}
bool MonoManagedRenderPipelineAssetRuntime::
ConfigureDirectionalShadowExecutionState(
const Rendering::CameraFramePlan& plan,
const Rendering::DirectionalShadowSurfaceAllocation&
shadowAllocation,
Rendering::DirectionalShadowExecutionState& shadowState) const {
if (!EnsureManagedAsset()) {
return false;
}
MonoObject* const assetObject = GetManagedAssetObject();
MonoMethod* const method =
ResolveConfigureDirectionalShadowExecutionStateMethod(
assetObject);
if (assetObject == nullptr || method == nullptr) {
return false;
}
ManagedDirectionalShadowExecutionContextState executionState =
{};
executionState.plan = &plan;
executionState.shadowAllocation = &shadowAllocation;
executionState.shadowState = &shadowState;
const uint64_t executionContextHandle =
RegisterManagedDirectionalShadowExecutionContextState(
executionState);
MonoObject* const executionContextObject =
m_runtime->CreateManagedDirectionalShadowExecutionContext(
executionContextHandle);
if (executionContextObject == nullptr) {
UnregisterManagedDirectionalShadowExecutionContextState(
executionContextHandle);
return false;
}
void* args[1] = { executionContextObject };
m_runtime->InvokeManagedMethod(
assetObject,
method,
args,
nullptr);
UnregisterManagedDirectionalShadowExecutionContextState(
executionContextHandle);
return executionState.explicitlyConfigured;
}
bool MonoManagedRenderPipelineAssetRuntime::TryGetDefaultFinalColorSettings(
Rendering::FinalColorSettings& settings) const {
settings = {};
@@ -2275,61 +2384,6 @@ std::string MonoManagedRenderPipelineAssetRuntime::
reinterpret_cast<MonoString*>(managedKeyObject));
}
std::string MonoManagedRenderPipelineAssetRuntime::
GetDirectionalShadowExecutionPolicyAssetKey() const {
return GetDirectionalShadowExecutionPolicyAssetKey(-1);
}
std::string MonoManagedRenderPipelineAssetRuntime::
GetDirectionalShadowExecutionPolicyAssetKey(
int32_t rendererIndex) const {
if (!SyncManagedAssetRuntimeState()) {
return {};
}
MonoObject* const assetObject = GetManagedAssetObject();
if (assetObject == nullptr) {
return {};
}
MonoMethod* const contextualMethod =
ResolveGetDirectionalShadowExecutionPolicyAssetKeyContextualMethod(
assetObject);
if (contextualMethod != nullptr) {
void* args[1] = { &rendererIndex };
MonoObject* managedKeyObject = nullptr;
if (!m_runtime->InvokeManagedMethod(
assetObject,
contextualMethod,
args,
&managedKeyObject)) {
return {};
}
return MonoStringToUtf8(
reinterpret_cast<MonoString*>(managedKeyObject));
}
MonoMethod* const method =
ResolveGetDirectionalShadowExecutionPolicyAssetKeyMethod(
assetObject);
if (method == nullptr) {
return {};
}
MonoObject* managedKeyObject = nullptr;
if (!m_runtime->InvokeManagedMethod(
assetObject,
method,
nullptr,
&managedKeyObject)) {
return {};
}
return MonoStringToUtf8(
reinterpret_cast<MonoString*>(managedKeyObject));
}
std::string MonoManagedRenderPipelineAssetRuntime::
GetCameraFrameStandalonePassAssetKey(
Rendering::CameraFrameStage stage) const {
@@ -2607,10 +2661,8 @@ void MonoManagedRenderPipelineAssetRuntime::ReleaseManagedAsset() const {
m_usesNativeCameraFramePlanBaselineContextualMethod = nullptr;
m_getRenderSceneSetupPolicyAssetKeyMethod = nullptr;
m_getRenderSceneSetupPolicyAssetKeyContextualMethod = nullptr;
m_configureDirectionalShadowExecutionStateMethod = nullptr;
m_getDirectionalShadowPlanningPolicyAssetKeyMethod = nullptr;
m_getDirectionalShadowExecutionPolicyAssetKeyMethod = nullptr;
m_getDirectionalShadowExecutionPolicyAssetKeyContextualMethod =
nullptr;
m_getCameraFrameStandalonePassAssetKeyMethod = nullptr;
m_getCameraFrameStandalonePassAssetKeyContextualMethod = nullptr;
m_pipelineRendererAsset.reset();
@@ -2823,6 +2875,22 @@ MonoManagedRenderPipelineAssetRuntime::
return m_getRenderSceneSetupPolicyAssetKeyContextualMethod;
}
MonoMethod*
MonoManagedRenderPipelineAssetRuntime::
ResolveConfigureDirectionalShadowExecutionStateMethod(
MonoObject* assetObject) const {
if (m_configureDirectionalShadowExecutionStateMethod ==
nullptr) {
m_configureDirectionalShadowExecutionStateMethod =
m_runtime->ResolveManagedMethod(
assetObject,
"ConfigureDirectionalShadowExecutionStateInstance",
1);
}
return m_configureDirectionalShadowExecutionStateMethod;
}
MonoMethod*
MonoManagedRenderPipelineAssetRuntime::
ResolveGetDirectionalShadowPlanningPolicyAssetKeyMethod(
@@ -2839,39 +2907,6 @@ MonoManagedRenderPipelineAssetRuntime::
return m_getDirectionalShadowPlanningPolicyAssetKeyMethod;
}
MonoMethod*
MonoManagedRenderPipelineAssetRuntime::
ResolveGetDirectionalShadowExecutionPolicyAssetKeyMethod(
MonoObject* assetObject) const {
if (m_getDirectionalShadowExecutionPolicyAssetKeyMethod ==
nullptr) {
m_getDirectionalShadowExecutionPolicyAssetKeyMethod =
m_runtime->ResolveManagedMethod(
assetObject,
"GetDirectionalShadowExecutionPolicyAssetKey",
0);
}
return m_getDirectionalShadowExecutionPolicyAssetKeyMethod;
}
MonoMethod*
MonoManagedRenderPipelineAssetRuntime::
ResolveGetDirectionalShadowExecutionPolicyAssetKeyContextualMethod(
MonoObject* assetObject) const {
if (m_getDirectionalShadowExecutionPolicyAssetKeyContextualMethod ==
nullptr) {
m_getDirectionalShadowExecutionPolicyAssetKeyContextualMethod =
m_runtime->ResolveManagedMethod(
assetObject,
"GetDirectionalShadowExecutionPolicyAssetKeyContextual",
1);
}
return
m_getDirectionalShadowExecutionPolicyAssetKeyContextualMethod;
}
MonoMethod*
MonoManagedRenderPipelineAssetRuntime::
ResolveGetCameraFrameStandalonePassAssetKeyMethod(
@@ -5771,6 +5806,80 @@ void InternalCall_Rendering_CameraRenderRequestContext_ClearDirectionalShadow(
state->suppressDirectionalShadow = true;
}
mono_bool
InternalCall_Rendering_DirectionalShadowExecutionContext_GetHasPlannedMainDirectionalShadow(
uint64_t nativeHandle) {
const ManagedDirectionalShadowExecutionContextState* const state =
FindManagedDirectionalShadowExecutionContextState(
nativeHandle);
return state != nullptr &&
state->plan != nullptr &&
state->plan->directionalShadow.IsValid()
? 1
: 0;
}
int32_t
InternalCall_Rendering_DirectionalShadowExecutionContext_GetRendererIndex(
uint64_t nativeHandle) {
const ManagedDirectionalShadowExecutionContextState* const state =
FindManagedDirectionalShadowExecutionContextState(
nativeHandle);
return state != nullptr &&
state->plan != nullptr
? state->plan->request.rendererIndex
: -1;
}
mono_bool
InternalCall_Rendering_DirectionalShadowExecutionContext_GetIsConfigured(
uint64_t nativeHandle) {
const ManagedDirectionalShadowExecutionContextState* const state =
FindManagedDirectionalShadowExecutionContextState(
nativeHandle);
return state != nullptr &&
state->explicitlyConfigured
? 1
: 0;
}
mono_bool
InternalCall_Rendering_DirectionalShadowExecutionContext_UseDefaultMainDirectionalShadowExecution(
uint64_t nativeHandle) {
ManagedDirectionalShadowExecutionContextState* const state =
FindManagedDirectionalShadowExecutionContextState(
nativeHandle);
if (state == nullptr ||
state->plan == nullptr ||
state->shadowAllocation == nullptr ||
state->shadowState == nullptr) {
return 0;
}
Rendering::ApplyDefaultRenderPipelineDirectionalShadowExecutionPolicy(
*state->plan,
*state->shadowAllocation,
*state->shadowState);
state->explicitlyConfigured = true;
return state->shadowState->shadowCasterRequest.IsValid() &&
state->shadowState->shadowData.IsValid()
? 1
: 0;
}
void InternalCall_Rendering_DirectionalShadowExecutionContext_ClearDirectionalShadowExecution(
uint64_t nativeHandle) {
ManagedDirectionalShadowExecutionContextState* const state =
FindManagedDirectionalShadowExecutionContextState(
nativeHandle);
if (state == nullptr || state->shadowState == nullptr) {
return;
}
*state->shadowState = {};
state->explicitlyConfigured = true;
}
int32_t
InternalCall_Rendering_ScriptableRenderPipelinePlanningContext_GetRendererIndex(
uint64_t nativeHandle) {
@@ -6223,6 +6332,11 @@ void RegisterInternalCalls() {
mono_add_internal_call("XCEngine.InternalCalls::Rendering_CameraRenderRequestContext_GetDirectionalShadowPlanningSettings", reinterpret_cast<const void*>(&InternalCall_Rendering_CameraRenderRequestContext_GetDirectionalShadowPlanningSettings));
mono_add_internal_call("XCEngine.InternalCalls::Rendering_CameraRenderRequestContext_SetDirectionalShadowPlanningSettings", reinterpret_cast<const void*>(&InternalCall_Rendering_CameraRenderRequestContext_SetDirectionalShadowPlanningSettings));
mono_add_internal_call("XCEngine.InternalCalls::Rendering_CameraRenderRequestContext_ClearDirectionalShadow", reinterpret_cast<const void*>(&InternalCall_Rendering_CameraRenderRequestContext_ClearDirectionalShadow));
mono_add_internal_call("XCEngine.InternalCalls::Rendering_DirectionalShadowExecutionContext_GetHasPlannedMainDirectionalShadow", reinterpret_cast<const void*>(&InternalCall_Rendering_DirectionalShadowExecutionContext_GetHasPlannedMainDirectionalShadow));
mono_add_internal_call("XCEngine.InternalCalls::Rendering_DirectionalShadowExecutionContext_GetRendererIndex", reinterpret_cast<const void*>(&InternalCall_Rendering_DirectionalShadowExecutionContext_GetRendererIndex));
mono_add_internal_call("XCEngine.InternalCalls::Rendering_DirectionalShadowExecutionContext_GetIsConfigured", reinterpret_cast<const void*>(&InternalCall_Rendering_DirectionalShadowExecutionContext_GetIsConfigured));
mono_add_internal_call("XCEngine.InternalCalls::Rendering_DirectionalShadowExecutionContext_UseDefaultMainDirectionalShadowExecution", reinterpret_cast<const void*>(&InternalCall_Rendering_DirectionalShadowExecutionContext_UseDefaultMainDirectionalShadowExecution));
mono_add_internal_call("XCEngine.InternalCalls::Rendering_DirectionalShadowExecutionContext_ClearDirectionalShadowExecution", reinterpret_cast<const void*>(&InternalCall_Rendering_DirectionalShadowExecutionContext_ClearDirectionalShadowExecution));
GetInternalCallRegistrationState() = true;
}
@@ -6301,11 +6415,13 @@ void MonoScriptRuntime::Shutdown() {
m_scriptableRenderPipelineClass = nullptr;
m_scriptableRenderContextClass = nullptr;
m_cameraRenderRequestContextClass = nullptr;
m_directionalShadowExecutionContextClass = nullptr;
m_scriptableRenderPipelinePlanningContextClass = nullptr;
m_serializeFieldAttributeClass = nullptr;
m_gameObjectConstructor = nullptr;
m_scriptableRenderContextConstructor = nullptr;
m_cameraRenderRequestContextConstructor = nullptr;
m_directionalShadowExecutionContextConstructor = nullptr;
m_scriptableRenderPipelinePlanningContextConstructor = nullptr;
m_managedGameObjectUUIDField = nullptr;
m_gameObjectUUIDField = nullptr;
@@ -7100,6 +7216,27 @@ bool MonoScriptRuntime::DiscoverScriptClasses() {
return false;
}
m_directionalShadowExecutionContextClass = mono_class_from_name(
m_coreImage,
kManagedRenderingNamespace,
"DirectionalShadowExecutionContext");
if (!m_directionalShadowExecutionContextClass) {
SetError(
"Failed to locate the managed DirectionalShadowExecutionContext type.");
return false;
}
m_directionalShadowExecutionContextConstructor =
mono_class_get_method_from_name(
m_directionalShadowExecutionContextClass,
".ctor",
1);
if (!m_directionalShadowExecutionContextConstructor) {
SetError(
"Failed to locate the managed DirectionalShadowExecutionContext constructor.");
return false;
}
m_scriptableRenderPipelinePlanningContextClass = mono_class_from_name(
m_coreImage,
kManagedRenderingNamespace,
@@ -7716,6 +7853,46 @@ MonoScriptRuntime::CreateManagedCameraRenderRequestContext(
return contextObject;
}
MonoObject*
MonoScriptRuntime::CreateManagedDirectionalShadowExecutionContext(
uint64_t nativeHandle) {
if (!m_initialized ||
nativeHandle == 0 ||
m_directionalShadowExecutionContextClass == nullptr ||
m_directionalShadowExecutionContextConstructor == nullptr) {
return nullptr;
}
SetCurrentDomain();
MonoObject* const contextObject =
mono_object_new(
m_appDomain,
m_directionalShadowExecutionContextClass);
if (contextObject == nullptr) {
SetError(
"Mono failed to allocate a managed DirectionalShadowExecutionContext.");
return nullptr;
}
void* args[1];
uint64_t nativeHandleArgument = nativeHandle;
args[0] = &nativeHandleArgument;
MonoObject* exception = nullptr;
mono_runtime_invoke(
m_directionalShadowExecutionContextConstructor,
contextObject,
args,
&exception);
if (exception != nullptr) {
RecordException(exception);
return nullptr;
}
return contextObject;
}
MonoObject*
MonoScriptRuntime::CreateManagedScriptableRenderPipelinePlanningContext(
uint64_t nativeHandle) {