Serialize managed SRP asset graphs

This commit is contained in:
2026-04-27 19:35:17 +08:00
parent 8353da05e5
commit c0b670b052
10 changed files with 1568 additions and 25 deletions

View File

@@ -2752,24 +2752,33 @@ bool MonoManagedRenderPipelineAssetRuntime::EnsureManagedAsset() const {
? 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)) {
if (!m_descriptor.HasSerializedAssetGraph()) {
m_runtime->SetError(
"Managed render pipeline asset handle is no longer valid: " +
m_descriptor.GetFullName() + ".");
return false;
}
} else if (!IsMonoClassOrSubclass(
assetClass,
m_runtime->m_scriptableRenderPipelineAssetClass)) {
m_runtime->SetError(
"Managed render pipeline asset must derive from ScriptableRenderPipelineAsset: " +
m_descriptor.GetFullName() + ".");
return false;
} else {
m_assetHandle = m_descriptor.managedAssetHandle;
m_ownsManagedAssetHandle = false;
return true;
}
}
m_assetHandle = m_descriptor.managedAssetHandle;
m_ownsManagedAssetHandle = false;
return true;
if (m_descriptor.HasSerializedAssetGraph()) {
m_ownsManagedAssetHandle =
m_runtime->TryCreateManagedRenderPipelineAssetFromSerializedGraph(
m_descriptor.serializedAssetGraph,
m_assetHandle) &&
m_assetHandle != 0;
return m_ownsManagedAssetHandle;
}
MonoClass* assetClass = nullptr;
@@ -4896,6 +4905,17 @@ void InternalCall_Rendering_SetRenderPipelineAsset(MonoObject* assetObject) {
runtime != nullptr
? runtime->RetainExternalManagedObjectReference(assetObject)
: 0u;
if (runtime != nullptr &&
!runtime->TrySerializeManagedRenderPipelineAssetGraph(
assetObject,
descriptor.serializedAssetGraph)) {
if (descriptor.managedAssetHandle != 0u) {
runtime->ReleaseExternalManagedObject(
descriptor.managedAssetHandle);
}
return;
}
if (!descriptor.IsValid() ||
descriptor.managedAssetHandle == 0u) {
if (runtime != nullptr &&
@@ -4930,11 +4950,13 @@ MonoObject* InternalCall_Rendering_GetRenderPipelineAsset() {
return nullptr;
}
if (descriptor.managedAssetHandle == 0u) {
if (!runtime->TryEnsureManagedRenderPipelineAssetHandle(descriptor)) {
return nullptr;
}
const uint32_t previousManagedAssetHandle =
descriptor.managedAssetHandle;
if (!runtime->TryEnsureManagedRenderPipelineAssetHandle(descriptor)) {
return nullptr;
}
if (descriptor.managedAssetHandle != previousManagedAssetHandle) {
Rendering::GetGraphicsSettingsState()
.UpdateConfiguredRenderPipelineAssetRuntimeDescriptor(descriptor);
}
@@ -8531,6 +8553,127 @@ bool MonoScriptRuntime::IsScriptableRenderPipelineAssetObject(
m_scriptableRenderPipelineAssetClass);
}
bool MonoScriptRuntime::TrySerializeManagedRenderPipelineAssetGraph(
MonoObject* managedObject,
std::string& outSerializedGraph) {
outSerializedGraph.clear();
if (!m_initialized ||
!IsScriptableRenderPipelineAssetObject(managedObject) ||
m_scriptableRenderPipelineAssetClass == nullptr) {
return false;
}
MonoMethod* const serializeMethod =
ResolveManagedMethod(
m_scriptableRenderPipelineAssetClass,
"SerializeAssetGraphInstance",
1);
if (serializeMethod == nullptr) {
SetError(
"Managed ScriptableRenderPipelineAsset.SerializeAssetGraphInstance was not found.");
return false;
}
SetCurrentDomain();
void* args[1] = { managedObject };
MonoObject* exception = nullptr;
MonoObject* const result =
mono_runtime_invoke(
serializeMethod,
nullptr,
args,
&exception);
if (exception != nullptr) {
RecordException(exception);
return false;
}
MonoString* const serializedGraph =
reinterpret_cast<MonoString*>(result);
outSerializedGraph = MonoStringToUtf8(serializedGraph);
if (outSerializedGraph.empty()) {
SetError(
"Managed render pipeline asset graph serialization returned an empty snapshot.");
return false;
}
return true;
}
bool MonoScriptRuntime::TryDeserializeManagedRenderPipelineAssetGraph(
const std::string& serializedGraph,
MonoObject*& outAsset) {
outAsset = nullptr;
if (!m_initialized ||
serializedGraph.empty() ||
m_scriptableRenderPipelineAssetClass == nullptr) {
return false;
}
MonoMethod* const deserializeMethod =
ResolveManagedMethod(
m_scriptableRenderPipelineAssetClass,
"DeserializeAssetGraphInstance",
1);
if (deserializeMethod == nullptr) {
SetError(
"Managed ScriptableRenderPipelineAsset.DeserializeAssetGraphInstance was not found.");
return false;
}
SetCurrentDomain();
MonoString* const managedSerializedGraph =
mono_string_new(
m_appDomain,
serializedGraph.c_str());
void* args[1] = { managedSerializedGraph };
MonoObject* exception = nullptr;
MonoObject* const result =
mono_runtime_invoke(
deserializeMethod,
nullptr,
args,
&exception);
if (exception != nullptr) {
RecordException(exception);
return false;
}
if (!IsScriptableRenderPipelineAssetObject(result)) {
SetError(
"Managed render pipeline asset graph deserialization did not return a ScriptableRenderPipelineAsset.");
return false;
}
outAsset = result;
return true;
}
bool MonoScriptRuntime::TryCreateManagedRenderPipelineAssetFromSerializedGraph(
const std::string& serializedGraph,
uint32_t& outHandle) {
outHandle = 0u;
MonoObject* assetObject = nullptr;
if (!TryDeserializeManagedRenderPipelineAssetGraph(
serializedGraph,
assetObject) ||
assetObject == nullptr) {
return false;
}
outHandle = RetainExternalManagedObject(assetObject);
if (outHandle == 0u) {
SetError(
"Managed render pipeline asset graph deserialization returned an object that could not be retained.");
return false;
}
return true;
}
bool MonoScriptRuntime::TryEnsureManagedRenderPipelineAssetHandle(
Rendering::Pipelines::ManagedRenderPipelineAssetDescriptor& ioDescriptor) {
if (!m_initialized || !ioDescriptor.IsValid()) {
@@ -8547,6 +8690,37 @@ bool MonoScriptRuntime::TryEnsureManagedRenderPipelineAssetHandle(
ioDescriptor.managedAssetHandle = 0u;
}
if (ioDescriptor.HasSerializedAssetGraph()) {
if (!TryCreateManagedRenderPipelineAssetFromSerializedGraph(
ioDescriptor.serializedAssetGraph,
ioDescriptor.managedAssetHandle) ||
ioDescriptor.managedAssetHandle == 0u) {
return false;
}
MonoObject* const assetObject =
GetExternalManagedObject(ioDescriptor.managedAssetHandle);
MonoClass* const assetClass =
assetObject != nullptr
? mono_object_get_class(assetObject)
: nullptr;
if (assetClass != nullptr) {
MonoImage* const image =
mono_class_get_image(assetClass);
ioDescriptor.assemblyName =
TrimAssemblyName(
SafeString(
image != nullptr
? mono_image_get_name(image)
: nullptr));
ioDescriptor.namespaceName =
SafeString(mono_class_get_namespace(assetClass));
ioDescriptor.className =
SafeString(mono_class_get_name(assetClass));
}
return true;
}
MonoClass* assetClass = nullptr;
if (!ResolveManagedClass(
ioDescriptor.assemblyName,