feat(rendering): select managed SRP through asset instances

This commit is contained in:
2026-04-18 16:41:53 +08:00
parent 849625e732
commit 30ee70a4d1
7 changed files with 226 additions and 93 deletions

View File

@@ -507,6 +507,7 @@ private:
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;
};
@@ -899,6 +900,35 @@ bool MonoManagedRenderPipelineAssetRuntime::EnsureManagedAsset() const {
m_assetCreationAttempted = true;
if (m_descriptor.HasManagedAssetHandle()) {
MonoObject* const assetObject =
m_runtime->GetExternalManagedObject(
m_descriptor.managedAssetHandle);
MonoClass* const assetClass =
assetObject != nullptr
? mono_object_get_class(assetObject)
: nullptr;
if (assetClass == nullptr) {
m_runtime->SetError(
"Managed render pipeline asset handle is no longer valid: " +
m_descriptor.GetFullName() + ".");
return false;
}
if (!IsMonoClassOrSubclass(
assetClass,
m_runtime->m_scriptableRenderPipelineAssetClass)) {
m_runtime->SetError(
"Managed render pipeline asset must derive from ScriptableRenderPipelineAsset: " +
m_descriptor.GetFullName() + ".");
return false;
}
m_assetHandle = m_descriptor.managedAssetHandle;
m_ownsManagedAssetHandle = false;
return true;
}
MonoClass* assetClass = nullptr;
if (!m_runtime->ResolveManagedClass(
m_descriptor.assemblyName,
@@ -918,8 +948,10 @@ bool MonoManagedRenderPipelineAssetRuntime::EnsureManagedAsset() const {
return false;
}
return m_runtime->CreateExternalManagedObject(assetClass, m_assetHandle) &&
m_assetHandle != 0;
m_ownsManagedAssetHandle =
m_runtime->CreateExternalManagedObject(assetClass, m_assetHandle) &&
m_assetHandle != 0;
return m_ownsManagedAssetHandle;
}
void MonoManagedRenderPipelineAssetRuntime::ReleaseManagedAsset() const {
@@ -927,6 +959,8 @@ void MonoManagedRenderPipelineAssetRuntime::ReleaseManagedAsset() const {
m_configureCameraRenderRequestMethod = nullptr;
m_configureCameraFramePlanMethod = nullptr;
m_getDefaultFinalColorSettingsMethod = nullptr;
const bool ownsManagedAssetHandle = m_ownsManagedAssetHandle;
m_ownsManagedAssetHandle = false;
m_assetCreationAttempted = false;
if (!IsRuntimeAlive()) {
@@ -934,10 +968,11 @@ void MonoManagedRenderPipelineAssetRuntime::ReleaseManagedAsset() const {
return;
}
if (m_assetHandle != 0) {
if (m_assetHandle != 0 && ownsManagedAssetHandle) {
m_runtime->DestroyExternalManagedObject(m_assetHandle);
m_assetHandle = 0;
}
m_assetHandle = 0;
}
MonoObject* MonoManagedRenderPipelineAssetRuntime::GetManagedAssetObject() const {
@@ -2683,17 +2718,29 @@ mono_bool InternalCall_Physics_Raycast(
return 1;
}
void InternalCall_Rendering_SetRenderPipelineAssetType(MonoReflectionType* assetType) {
if (assetType == nullptr) {
void InternalCall_Rendering_SetRenderPipelineAsset(MonoObject* assetObject) {
MonoScriptRuntime* const runtime = GetActiveMonoScriptRuntime();
const Rendering::Pipelines::ManagedRenderPipelineAssetDescriptor currentDescriptor =
Rendering::Pipelines::GetManagedRenderPipelineAssetDescriptor();
if (assetObject == nullptr) {
if (runtime != nullptr &&
currentDescriptor.managedAssetHandle != 0u) {
runtime->ReleaseExternalManagedObject(
currentDescriptor.managedAssetHandle);
}
Rendering::Pipelines::ClearManagedRenderPipelineAssetDescriptor();
return;
}
MonoType* monoType = mono_reflection_type_get_type(assetType);
MonoClass* monoClass =
monoType != nullptr ? mono_class_from_mono_type(monoType) : nullptr;
MonoClass* const monoClass = mono_object_get_class(assetObject);
if (monoClass == nullptr) {
Rendering::Pipelines::ClearManagedRenderPipelineAssetDescriptor();
return;
}
if (runtime != nullptr &&
!runtime->IsScriptableRenderPipelineAssetObject(assetObject)) {
return;
}
@@ -2703,25 +2750,45 @@ void InternalCall_Rendering_SetRenderPipelineAssetType(MonoReflectionType* asset
TrimAssemblyName(SafeString(image != nullptr ? mono_image_get_name(image) : nullptr));
descriptor.namespaceName = SafeString(mono_class_get_namespace(monoClass));
descriptor.className = SafeString(mono_class_get_name(monoClass));
if (!descriptor.IsValid()) {
Rendering::Pipelines::ClearManagedRenderPipelineAssetDescriptor();
descriptor.managedAssetHandle =
runtime != nullptr
? runtime->RetainExternalManagedObjectReference(assetObject)
: 0u;
if (!descriptor.IsValid() ||
descriptor.managedAssetHandle == 0u) {
if (runtime != nullptr &&
descriptor.managedAssetHandle != 0u) {
runtime->ReleaseExternalManagedObject(
descriptor.managedAssetHandle);
}
return;
}
if (runtime != nullptr &&
currentDescriptor.managedAssetHandle != 0u &&
currentDescriptor.managedAssetHandle != descriptor.managedAssetHandle) {
runtime->ReleaseExternalManagedObject(
currentDescriptor.managedAssetHandle);
}
Rendering::Pipelines::SetManagedRenderPipelineAssetDescriptor(descriptor);
}
MonoString* InternalCall_Rendering_GetRenderPipelineAssetTypeName() {
const Rendering::Pipelines::ManagedRenderPipelineAssetDescriptor descriptor =
Rendering::Pipelines::GetManagedRenderPipelineAssetDescriptor();
if (!descriptor.IsValid()) {
return mono_string_new(mono_domain_get(), "");
MonoObject* InternalCall_Rendering_GetRenderPipelineAsset() {
MonoScriptRuntime* const runtime = GetActiveMonoScriptRuntime();
if (runtime == nullptr) {
return nullptr;
}
std::string assemblyQualifiedName = descriptor.GetFullName();
assemblyQualifiedName += ", ";
assemblyQualifiedName += descriptor.assemblyName;
return mono_string_new(mono_domain_get(), assemblyQualifiedName.c_str());
const Rendering::Pipelines::ManagedRenderPipelineAssetDescriptor descriptor =
Rendering::Pipelines::GetManagedRenderPipelineAssetDescriptor();
if (!descriptor.IsValid() ||
descriptor.managedAssetHandle == 0u) {
return nullptr;
}
return runtime->GetExternalManagedObject(
descriptor.managedAssetHandle);
}
int32_t InternalCall_Rendering_ScriptableRenderContext_GetStage(
@@ -3041,8 +3108,8 @@ void RegisterInternalCalls() {
mono_add_internal_call("XCEngine.InternalCalls::Rigidbody_AddForce", reinterpret_cast<const void*>(&InternalCall_Rigidbody_AddForce));
mono_add_internal_call("XCEngine.InternalCalls::Rigidbody_ClearForces", reinterpret_cast<const void*>(&InternalCall_Rigidbody_ClearForces));
mono_add_internal_call("XCEngine.InternalCalls::Physics_Raycast", reinterpret_cast<const void*>(&InternalCall_Physics_Raycast));
mono_add_internal_call("XCEngine.InternalCalls::Rendering_SetRenderPipelineAssetType", reinterpret_cast<const void*>(&InternalCall_Rendering_SetRenderPipelineAssetType));
mono_add_internal_call("XCEngine.InternalCalls::Rendering_GetRenderPipelineAssetTypeName", reinterpret_cast<const void*>(&InternalCall_Rendering_GetRenderPipelineAssetTypeName));
mono_add_internal_call("XCEngine.InternalCalls::Rendering_SetRenderPipelineAsset", reinterpret_cast<const void*>(&InternalCall_Rendering_SetRenderPipelineAsset));
mono_add_internal_call("XCEngine.InternalCalls::Rendering_GetRenderPipelineAsset", reinterpret_cast<const void*>(&InternalCall_Rendering_GetRenderPipelineAsset));
mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderContext_GetStage", reinterpret_cast<const void*>(&InternalCall_Rendering_ScriptableRenderContext_GetStage));
mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderContext_RecordScene", reinterpret_cast<const void*>(&InternalCall_Rendering_ScriptableRenderContext_RecordScene));
mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderContext_RecordScenePhase", reinterpret_cast<const void*>(&InternalCall_Rendering_ScriptableRenderContext_RecordScenePhase));
@@ -3106,6 +3173,7 @@ bool MonoScriptRuntime::Initialize() {
void MonoScriptRuntime::Shutdown() {
Rendering::Pipelines::ClearManagedRenderPipelineBridge();
Rendering::Pipelines::ClearManagedRenderPipelineAssetDescriptor();
GetManagedScriptableRenderContextRegistry().clear();
GetManagedScriptableRenderContextNextHandle() = 1;
GetManagedScriptableRenderPipelineCameraRequestContextRegistry().clear();
@@ -4206,6 +4274,28 @@ uint32_t MonoScriptRuntime::RetainExternalManagedObject(MonoObject* instance) {
return gcHandle;
}
MonoObject* MonoScriptRuntime::GetExternalManagedObject(uint32_t gcHandle) const {
return GetManagedObject(gcHandle);
}
uint32_t MonoScriptRuntime::RetainExternalManagedObjectReference(
MonoObject* managedObject) {
return RetainExternalManagedObject(managedObject);
}
void MonoScriptRuntime::ReleaseExternalManagedObject(uint32_t gcHandle) {
DestroyExternalManagedObject(gcHandle);
}
bool MonoScriptRuntime::IsScriptableRenderPipelineAssetObject(
MonoObject* managedObject) const {
return managedObject != nullptr &&
m_scriptableRenderPipelineAssetClass != nullptr &&
IsMonoClassOrSubclass(
mono_object_get_class(managedObject),
m_scriptableRenderPipelineAssetClass);
}
void MonoScriptRuntime::DestroyExternalManagedObject(uint32_t gcHandle) {
if (gcHandle == 0) {
return;