feat(rendering): add managed camera request planning seam

This commit is contained in:
2026-04-18 00:07:13 +08:00
parent fa9a5ffb00
commit a6c78af54c
11 changed files with 514 additions and 1 deletions

View File

@@ -97,6 +97,13 @@ struct ManagedScriptableRenderContextState {
std::vector<Math::Vector4> queuedBuiltinColorScaleFullscreenPasses = {};
};
struct ManagedScriptableRenderPipelineCameraRequestContextState {
uint64_t handle = 0;
Rendering::CameraRenderRequest* request = nullptr;
size_t renderedBaseCameraCount = 0u;
size_t renderedRequestCount = 0u;
};
struct ManagedScriptableRenderPipelinePlanningContextState {
uint64_t handle = 0;
Rendering::CameraFramePlan* plan = nullptr;
@@ -141,6 +148,52 @@ void UnregisterManagedScriptableRenderContextState(uint64_t handle) {
GetManagedScriptableRenderContextRegistry().erase(handle);
}
uint64_t& GetManagedScriptableRenderPipelineCameraRequestContextNextHandle() {
static uint64_t nextHandle = 1;
return nextHandle;
}
std::unordered_map<uint64_t, ManagedScriptableRenderPipelineCameraRequestContextState*>&
GetManagedScriptableRenderPipelineCameraRequestContextRegistry() {
static std::unordered_map<uint64_t, ManagedScriptableRenderPipelineCameraRequestContextState*>
registry;
return registry;
}
ManagedScriptableRenderPipelineCameraRequestContextState*
FindManagedScriptableRenderPipelineCameraRequestContextState(
uint64_t handle) {
const auto it =
GetManagedScriptableRenderPipelineCameraRequestContextRegistry().find(handle);
return it != GetManagedScriptableRenderPipelineCameraRequestContextRegistry().end()
? it->second
: nullptr;
}
uint64_t RegisterManagedScriptableRenderPipelineCameraRequestContextState(
ManagedScriptableRenderPipelineCameraRequestContextState& state) {
uint64_t handle =
GetManagedScriptableRenderPipelineCameraRequestContextNextHandle()++;
if (handle == 0) {
handle =
GetManagedScriptableRenderPipelineCameraRequestContextNextHandle()++;
}
state.handle = handle;
GetManagedScriptableRenderPipelineCameraRequestContextRegistry()[handle] =
&state;
return handle;
}
void UnregisterManagedScriptableRenderPipelineCameraRequestContextState(
uint64_t handle) {
if (handle == 0) {
return;
}
GetManagedScriptableRenderPipelineCameraRequestContextRegistry().erase(handle);
}
uint64_t& GetManagedScriptableRenderPipelinePlanningContextNextHandle() {
static uint64_t nextHandle = 1;
return nextHandle;
@@ -291,6 +344,13 @@ public:
std::unique_ptr<Rendering::RenderPipelineStageRecorder> CreateStageRecorder() const override;
void ConfigureCameraRenderRequest(
Rendering::CameraRenderRequest& request,
size_t renderedBaseCameraCount,
size_t renderedRequestCount,
const Rendering::DirectionalShadowPlanningSettings&
directionalShadowSettings) const override;
void ConfigureCameraFramePlan(
Rendering::CameraFramePlan& plan) const override;
@@ -311,6 +371,8 @@ private:
void ReleaseManagedAsset() const;
MonoObject* GetManagedAssetObject() const;
MonoMethod* ResolveCreatePipelineMethod(MonoObject* assetObject) const;
MonoMethod* ResolveConfigureCameraRenderRequestMethod(
MonoObject* assetObject) const;
MonoMethod* ResolveConfigureCameraFramePlanMethod(
MonoObject* assetObject) const;
@@ -319,6 +381,7 @@ private:
Rendering::Pipelines::ManagedRenderPipelineAssetDescriptor m_descriptor;
mutable uint32_t m_assetHandle = 0;
mutable MonoMethod* m_createPipelineMethod = nullptr;
mutable MonoMethod* m_configureCameraRenderRequestMethod = nullptr;
mutable MonoMethod* m_configureCameraFramePlanMethod = nullptr;
mutable bool m_assetCreationAttempted = false;
};
@@ -550,6 +613,49 @@ MonoManagedRenderPipelineAssetRuntime::CreateStageRecorder() const {
shared_from_this());
}
void MonoManagedRenderPipelineAssetRuntime::ConfigureCameraRenderRequest(
Rendering::CameraRenderRequest& request,
size_t renderedBaseCameraCount,
size_t renderedRequestCount,
const Rendering::DirectionalShadowPlanningSettings&) const {
if (!EnsureManagedAsset()) {
return;
}
MonoObject* const assetObject = GetManagedAssetObject();
MonoMethod* const method =
ResolveConfigureCameraRenderRequestMethod(assetObject);
if (assetObject == nullptr || method == nullptr) {
return;
}
ManagedScriptableRenderPipelineCameraRequestContextState requestContextState =
{};
requestContextState.request = &request;
requestContextState.renderedBaseCameraCount = renderedBaseCameraCount;
requestContextState.renderedRequestCount = renderedRequestCount;
const uint64_t requestContextHandle =
RegisterManagedScriptableRenderPipelineCameraRequestContextState(
requestContextState);
MonoObject* const requestContextObject =
m_runtime->CreateManagedScriptableRenderPipelineCameraRequestContext(
requestContextHandle);
if (requestContextObject == nullptr) {
UnregisterManagedScriptableRenderPipelineCameraRequestContextState(
requestContextHandle);
return;
}
void* args[1] = { requestContextObject };
m_runtime->InvokeManagedMethod(
assetObject,
method,
args,
nullptr);
UnregisterManagedScriptableRenderPipelineCameraRequestContextState(
requestContextHandle);
}
void MonoManagedRenderPipelineAssetRuntime::ConfigureCameraFramePlan(
Rendering::CameraFramePlan& plan) const {
if (!EnsureManagedAsset()) {
@@ -659,6 +765,7 @@ bool MonoManagedRenderPipelineAssetRuntime::EnsureManagedAsset() const {
void MonoManagedRenderPipelineAssetRuntime::ReleaseManagedAsset() const {
m_createPipelineMethod = nullptr;
m_configureCameraRenderRequestMethod = nullptr;
m_configureCameraFramePlanMethod = nullptr;
m_assetCreationAttempted = false;
@@ -692,6 +799,20 @@ MonoMethod* MonoManagedRenderPipelineAssetRuntime::ResolveCreatePipelineMethod(
return m_createPipelineMethod;
}
MonoMethod*
MonoManagedRenderPipelineAssetRuntime::ResolveConfigureCameraRenderRequestMethod(
MonoObject* assetObject) const {
if (m_configureCameraRenderRequestMethod == nullptr) {
m_configureCameraRenderRequestMethod =
m_runtime->ResolveManagedMethod(
assetObject,
"ConfigureCameraRenderRequest",
1);
}
return m_configureCameraRenderRequestMethod;
}
MonoMethod*
MonoManagedRenderPipelineAssetRuntime::ResolveConfigureCameraFramePlanMethod(
MonoObject* assetObject) const {
@@ -2509,6 +2630,49 @@ InternalCall_Rendering_ScriptableRenderContext_RecordBuiltinColorScaleFullscreen
return 1;
}
int32_t
InternalCall_Rendering_ScriptableRenderPipelineCameraRequestContext_GetRenderedBaseCameraCount(
uint64_t nativeHandle) {
const ManagedScriptableRenderPipelineCameraRequestContextState* const state =
FindManagedScriptableRenderPipelineCameraRequestContextState(nativeHandle);
return state != nullptr
? static_cast<int32_t>(state->renderedBaseCameraCount)
: 0;
}
int32_t
InternalCall_Rendering_ScriptableRenderPipelineCameraRequestContext_GetRenderedRequestCount(
uint64_t nativeHandle) {
const ManagedScriptableRenderPipelineCameraRequestContextState* const state =
FindManagedScriptableRenderPipelineCameraRequestContextState(nativeHandle);
return state != nullptr
? static_cast<int32_t>(state->renderedRequestCount)
: 0;
}
mono_bool
InternalCall_Rendering_ScriptableRenderPipelineCameraRequestContext_GetHasDirectionalShadow(
uint64_t nativeHandle) {
const ManagedScriptableRenderPipelineCameraRequestContextState* const state =
FindManagedScriptableRenderPipelineCameraRequestContextState(nativeHandle);
return state != nullptr &&
state->request != nullptr &&
state->request->directionalShadow.IsValid()
? 1
: 0;
}
void InternalCall_Rendering_ScriptableRenderPipelineCameraRequestContext_ClearDirectionalShadow(
uint64_t nativeHandle) {
ManagedScriptableRenderPipelineCameraRequestContextState* const state =
FindManagedScriptableRenderPipelineCameraRequestContextState(nativeHandle);
if (state == nullptr || state->request == nullptr) {
return;
}
state->request->directionalShadow = {};
}
void InternalCall_Rendering_ScriptableRenderPipelinePlanningContext_ClearPostProcessStage(
uint64_t nativeHandle) {
ManagedScriptableRenderPipelinePlanningContextState* const state =
@@ -2704,6 +2868,10 @@ void RegisterInternalCalls() {
mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderContext_RecordBuiltinForwardScenePhase", reinterpret_cast<const void*>(&InternalCall_Rendering_ScriptableRenderContext_RecordBuiltinForwardScenePhase));
mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderContext_RecordBuiltinForwardInjectionPoint", reinterpret_cast<const void*>(&InternalCall_Rendering_ScriptableRenderContext_RecordBuiltinForwardInjectionPoint));
mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderContext_RecordBuiltinColorScaleFullscreenPass", reinterpret_cast<const void*>(&InternalCall_Rendering_ScriptableRenderContext_RecordBuiltinColorScaleFullscreenPass));
mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderPipelineCameraRequestContext_GetRenderedBaseCameraCount", reinterpret_cast<const void*>(&InternalCall_Rendering_ScriptableRenderPipelineCameraRequestContext_GetRenderedBaseCameraCount));
mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderPipelineCameraRequestContext_GetRenderedRequestCount", reinterpret_cast<const void*>(&InternalCall_Rendering_ScriptableRenderPipelineCameraRequestContext_GetRenderedRequestCount));
mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderPipelineCameraRequestContext_GetHasDirectionalShadow", reinterpret_cast<const void*>(&InternalCall_Rendering_ScriptableRenderPipelineCameraRequestContext_GetHasDirectionalShadow));
mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderPipelineCameraRequestContext_ClearDirectionalShadow", reinterpret_cast<const void*>(&InternalCall_Rendering_ScriptableRenderPipelineCameraRequestContext_ClearDirectionalShadow));
mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderPipelinePlanningContext_ClearPostProcessStage", reinterpret_cast<const void*>(&InternalCall_Rendering_ScriptableRenderPipelinePlanningContext_ClearPostProcessStage));
mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderPipelinePlanningContext_RequestPostProcessStage", reinterpret_cast<const void*>(&InternalCall_Rendering_ScriptableRenderPipelinePlanningContext_RequestPostProcessStage));
mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderPipelinePlanningContext_ClearFinalOutputStage", reinterpret_cast<const void*>(&InternalCall_Rendering_ScriptableRenderPipelinePlanningContext_ClearFinalOutputStage));
@@ -2762,6 +2930,8 @@ void MonoScriptRuntime::Shutdown() {
Rendering::Pipelines::ClearManagedRenderPipelineBridge();
GetManagedScriptableRenderContextRegistry().clear();
GetManagedScriptableRenderContextNextHandle() = 1;
GetManagedScriptableRenderPipelineCameraRequestContextRegistry().clear();
GetManagedScriptableRenderPipelineCameraRequestContextNextHandle() = 1;
GetManagedScriptableRenderPipelinePlanningContextRegistry().clear();
GetManagedScriptableRenderPipelinePlanningContextNextHandle() = 1;
ClearManagedInstances();
@@ -2779,10 +2949,12 @@ void MonoScriptRuntime::Shutdown() {
m_scriptableRenderPipelineAssetClass = nullptr;
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;
@@ -3415,6 +3587,27 @@ bool MonoScriptRuntime::DiscoverScriptClasses() {
return false;
}
m_scriptableRenderPipelineCameraRequestContextClass = mono_class_from_name(
m_coreImage,
m_settings.baseNamespace.c_str(),
"ScriptableRenderPipelineCameraRequestContext");
if (!m_scriptableRenderPipelineCameraRequestContextClass) {
SetError(
"Failed to locate the managed ScriptableRenderPipelineCameraRequestContext type.");
return false;
}
m_scriptableRenderPipelineCameraRequestContextConstructor =
mono_class_get_method_from_name(
m_scriptableRenderPipelineCameraRequestContextClass,
".ctor",
1);
if (!m_scriptableRenderPipelineCameraRequestContextConstructor) {
SetError(
"Failed to locate the managed ScriptableRenderPipelineCameraRequestContext constructor.");
return false;
}
m_scriptableRenderPipelinePlanningContextClass = mono_class_from_name(
m_coreImage,
m_settings.baseNamespace.c_str(),
@@ -3887,6 +4080,46 @@ MonoObject* MonoScriptRuntime::CreateManagedScriptableRenderContext(
return contextObject;
}
MonoObject*
MonoScriptRuntime::CreateManagedScriptableRenderPipelineCameraRequestContext(
uint64_t nativeHandle) {
if (!m_initialized ||
nativeHandle == 0 ||
m_scriptableRenderPipelineCameraRequestContextClass == nullptr ||
m_scriptableRenderPipelineCameraRequestContextConstructor == nullptr) {
return nullptr;
}
SetCurrentDomain();
MonoObject* const contextObject =
mono_object_new(
m_appDomain,
m_scriptableRenderPipelineCameraRequestContextClass);
if (contextObject == nullptr) {
SetError(
"Mono failed to allocate a managed ScriptableRenderPipelineCameraRequestContext.");
return nullptr;
}
void* args[1];
uint64_t nativeHandleArgument = nativeHandle;
args[0] = &nativeHandleArgument;
MonoObject* exception = nullptr;
mono_runtime_invoke(
m_scriptableRenderPipelineCameraRequestContextConstructor,
contextObject,
args,
&exception);
if (exception != nullptr) {
RecordException(exception);
return nullptr;
}
return contextObject;
}
MonoObject* MonoScriptRuntime::CreateManagedScriptableRenderPipelinePlanningContext(
uint64_t nativeHandle) {
if (!m_initialized ||