Add managed render pipeline selection bridge

This commit is contained in:
2026-04-15 01:57:14 +08:00
parent ec6965b0dd
commit aa727202af
18 changed files with 566 additions and 10 deletions

View File

@@ -7,6 +7,7 @@
#include "Rendering/Passes/BuiltinObjectIdPass.h"
#include "Rendering/Passes/BuiltinShadowCasterPass.h"
#include "Rendering/Pipelines/BuiltinForwardPipeline.h"
#include "Rendering/Pipelines/ManagedScriptableRenderPipelineAsset.h"
#include "Rendering/Pipelines/ScriptableRenderPipelineHost.h"
#include "Rendering/RenderPipelineAsset.h"
#include "Rendering/RenderSurface.h"
@@ -19,9 +20,7 @@ namespace Rendering {
namespace {
std::shared_ptr<const RenderPipelineAsset> CreateDefaultPipelineAsset() {
static const std::shared_ptr<const RenderPipelineAsset> s_defaultPipelineAsset =
std::make_shared<Pipelines::ScriptableRenderPipelineHostAsset>();
return s_defaultPipelineAsset;
return Pipelines::CreateManagedOrDefaultScriptableRenderPipelineAsset();
}
std::unique_ptr<RenderPass> CreateDefaultDepthOnlyPass() {

View File

@@ -0,0 +1,57 @@
#include "Rendering/Pipelines/ManagedScriptableRenderPipelineAsset.h"
#include <utility>
namespace XCEngine {
namespace Rendering {
namespace Pipelines {
namespace {
ManagedRenderPipelineAssetDescriptor& GetManagedRenderPipelineAssetDescriptorStorage() {
static ManagedRenderPipelineAssetDescriptor s_descriptor = {};
return s_descriptor;
}
} // namespace
ManagedScriptableRenderPipelineAsset::ManagedScriptableRenderPipelineAsset(
ManagedRenderPipelineAssetDescriptor descriptor)
: m_descriptor(std::move(descriptor)) {
}
std::unique_ptr<RenderPipeline> ManagedScriptableRenderPipelineAsset::CreatePipeline() const {
return m_fallbackAsset.CreatePipeline();
}
FinalColorSettings ManagedScriptableRenderPipelineAsset::GetDefaultFinalColorSettings() const {
return m_fallbackAsset.GetDefaultFinalColorSettings();
}
void SetManagedRenderPipelineAssetDescriptor(
const ManagedRenderPipelineAssetDescriptor& descriptor) {
GetManagedRenderPipelineAssetDescriptorStorage() = descriptor;
}
void ClearManagedRenderPipelineAssetDescriptor() {
GetManagedRenderPipelineAssetDescriptorStorage() = {};
}
ManagedRenderPipelineAssetDescriptor GetManagedRenderPipelineAssetDescriptor() {
return GetManagedRenderPipelineAssetDescriptorStorage();
}
std::shared_ptr<const RenderPipelineAsset>
CreateManagedOrDefaultScriptableRenderPipelineAsset() {
const ManagedRenderPipelineAssetDescriptor descriptor =
GetManagedRenderPipelineAssetDescriptor();
if (descriptor.IsValid()) {
return std::make_shared<ManagedScriptableRenderPipelineAsset>(descriptor);
}
return std::make_shared<ScriptableRenderPipelineHostAsset>();
}
} // namespace Pipelines
} // namespace Rendering
} // namespace XCEngine

View File

@@ -8,6 +8,7 @@
#include "Components/TransformComponent.h"
#include "Debug/Logger.h"
#include "Input/InputManager.h"
#include "Rendering/Pipelines/ManagedScriptableRenderPipelineAsset.h"
#include "Scene/Scene.h"
#include "Scripting/ScriptComponent.h"
#include "Scripting/ScriptEngine.h"
@@ -92,6 +93,16 @@ std::string SafeString(const char* value) {
return value ? std::string(value) : std::string();
}
std::string TrimAssemblyName(const std::string& assemblyName) {
constexpr const char* kDllSuffix = ".dll";
if (assemblyName.size() >= 4u &&
assemblyName.substr(assemblyName.size() - 4u) == kDllSuffix) {
return assemblyName.substr(0u, assemblyName.size() - 4u);
}
return assemblyName;
}
bool IsMonoClassOrSubclass(MonoClass* monoClass, MonoClass* potentialBaseClass) {
if (!monoClass || !potentialBaseClass) {
return false;
@@ -1522,6 +1533,47 @@ void InternalCall_MeshRenderer_SetRenderLayer(uint64_t gameObjectUUID, int32_t v
component->SetRenderLayer(static_cast<uint32_t>(std::max(value, 0)));
}
void InternalCall_Rendering_SetRenderPipelineAssetType(MonoReflectionType* assetType) {
if (assetType == nullptr) {
Rendering::Pipelines::ClearManagedRenderPipelineAssetDescriptor();
return;
}
MonoType* monoType = mono_reflection_type_get_type(assetType);
MonoClass* monoClass =
monoType != nullptr ? mono_class_from_mono_type(monoType) : nullptr;
if (monoClass == nullptr) {
Rendering::Pipelines::ClearManagedRenderPipelineAssetDescriptor();
return;
}
MonoImage* image = mono_class_get_image(monoClass);
Rendering::Pipelines::ManagedRenderPipelineAssetDescriptor descriptor = {};
descriptor.assemblyName =
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();
return;
}
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(), "");
}
std::string assemblyQualifiedName = descriptor.GetFullName();
assemblyQualifiedName += ", ";
assemblyQualifiedName += descriptor.assemblyName;
return mono_string_new(mono_domain_get(), assemblyQualifiedName.c_str());
}
void RegisterInternalCalls() {
if (GetInternalCallRegistrationState()) {
return;
@@ -1629,6 +1681,8 @@ void RegisterInternalCalls() {
mono_add_internal_call("XCEngine.InternalCalls::MeshRenderer_SetReceiveShadows", reinterpret_cast<const void*>(&InternalCall_MeshRenderer_SetReceiveShadows));
mono_add_internal_call("XCEngine.InternalCalls::MeshRenderer_GetRenderLayer", reinterpret_cast<const void*>(&InternalCall_MeshRenderer_GetRenderLayer));
mono_add_internal_call("XCEngine.InternalCalls::MeshRenderer_SetRenderLayer", reinterpret_cast<const void*>(&InternalCall_MeshRenderer_SetRenderLayer));
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));
GetInternalCallRegistrationState() = true;
}