feat(rendering): add managed fullscreen stage recording seam

This commit is contained in:
2026-04-17 22:58:39 +08:00
parent ed9b5178f8
commit b9f78c29b8
10 changed files with 541 additions and 9 deletions

View File

@@ -10,9 +10,11 @@
#include "Debug/Logger.h"
#include "Input/InputManager.h"
#include "Physics/PhysicsWorld.h"
#include "Rendering/Passes/BuiltinColorScalePostProcessPass.h"
#include "Rendering/Pipelines/BuiltinForwardPipeline.h"
#include "Rendering/Pipelines/BuiltinForwardSceneRecorder.h"
#include "Rendering/Pipelines/ManagedScriptableRenderPipelineAsset.h"
#include "Rendering/RenderPipelineStageGraphContract.h"
#include "Scene/Scene.h"
#include "Scripting/ScriptComponent.h"
#include "Scripting/ScriptEngine.h"
@@ -91,6 +93,7 @@ struct ManagedScriptableRenderContextState {
const Rendering::RenderPipelineStageRenderGraphContext* graphContext = nullptr;
Rendering::Pipelines::BuiltinForwardSceneRecorder* builtinForwardSceneRecorder =
nullptr;
std::vector<Math::Vector4> queuedBuiltinColorScaleFullscreenPasses = {};
};
uint64_t& GetManagedScriptableRenderContextNextHandle() {
@@ -212,6 +215,12 @@ bool TryUnboxManagedBoolean(MonoObject* boxedValue, bool& outValue) {
return true;
}
bool SupportsManagedRenderPipelineStageGraphRecording(
Rendering::CameraFrameStage stage) {
return Rendering::SupportsCameraFramePipelineGraphRecording(stage) ||
Rendering::IsCameraFrameFullscreenSequenceStage(stage);
}
} // namespace
class MonoManagedRenderPipelineStageRecorder final
@@ -235,6 +244,13 @@ public:
}
void Shutdown() override {
for (std::unique_ptr<Rendering::Passes::BuiltinColorScalePostProcessPass>& pass :
m_builtinColorScalePassPool) {
if (pass != nullptr) {
pass->Shutdown();
}
}
m_builtinColorScalePassPool.clear();
m_builtinForwardPipeline.Shutdown();
ReleaseManagedObjects();
m_supportsStageMethod = nullptr;
@@ -243,7 +259,7 @@ public:
}
bool SupportsStageRenderGraph(Rendering::CameraFrameStage stage) const override {
if (!Rendering::SupportsCameraFramePipelineGraphRecording(stage) ||
if (!SupportsManagedRenderPipelineStageGraphRecording(stage) ||
!EnsureManagedPipeline()) {
return false;
}
@@ -313,7 +329,13 @@ public:
}
bool recorded = false;
return TryUnboxManagedBoolean(result, recorded) && recorded;
if (!(TryUnboxManagedBoolean(result, recorded) && recorded)) {
return false;
}
return FlushManagedFullscreenPasses(
context,
managedContextState);
}
private:
@@ -441,6 +463,40 @@ private:
return m_recordStageMethod;
}
bool FlushManagedFullscreenPasses(
const Rendering::RenderPipelineStageRenderGraphContext& context,
const ManagedScriptableRenderContextState& managedContextState) {
if (managedContextState.queuedBuiltinColorScaleFullscreenPasses.empty()) {
return true;
}
if (!Rendering::IsCameraFrameFullscreenSequenceStage(context.stage)) {
return false;
}
while (m_builtinColorScalePassPool.size() <
managedContextState.queuedBuiltinColorScaleFullscreenPasses.size()) {
m_builtinColorScalePassPool.push_back(
std::make_unique<Rendering::Passes::BuiltinColorScalePostProcessPass>());
}
std::vector<Rendering::RenderPass*> passes = {};
passes.reserve(
managedContextState.queuedBuiltinColorScaleFullscreenPasses.size());
for (size_t passIndex = 0u;
passIndex < managedContextState.queuedBuiltinColorScaleFullscreenPasses.size();
++passIndex) {
Rendering::Passes::BuiltinColorScalePostProcessPass* const pass =
m_builtinColorScalePassPool[passIndex].get();
pass->SetColorScale(
managedContextState.queuedBuiltinColorScaleFullscreenPasses[passIndex]);
passes.push_back(pass);
}
return Rendering::RecordRenderPipelineStageFullscreenPassSequence(
context,
passes);
}
MonoScriptRuntime* m_runtime = nullptr;
std::weak_ptr<void> m_runtimeLifetime;
Rendering::Pipelines::ManagedRenderPipelineAssetDescriptor m_descriptor;
@@ -449,6 +505,8 @@ private:
mutable MonoMethod* m_supportsStageMethod = nullptr;
mutable MonoMethod* m_recordStageMethod = nullptr;
mutable bool m_pipelineCreationAttempted = false;
std::vector<std::unique_ptr<Rendering::Passes::BuiltinColorScalePostProcessPass>>
m_builtinColorScalePassPool = {};
Rendering::Pipelines::BuiltinForwardPipeline m_builtinForwardPipeline;
};
@@ -2232,6 +2290,23 @@ InternalCall_Rendering_ScriptableRenderContext_RecordBuiltinForwardInjectionPoin
: 0;
}
mono_bool
InternalCall_Rendering_ScriptableRenderContext_RecordBuiltinColorScaleFullscreenPass(
uint64_t nativeHandle,
XCEngine::Math::Vector4* colorScale) {
ManagedScriptableRenderContextState* const state =
FindManagedScriptableRenderContextState(nativeHandle);
if (state == nullptr ||
state->graphContext == nullptr ||
colorScale == nullptr ||
!Rendering::IsCameraFrameFullscreenSequenceStage(state->stage)) {
return 0;
}
state->queuedBuiltinColorScaleFullscreenPasses.push_back(*colorScale);
return 1;
}
void RegisterInternalCalls() {
if (GetInternalCallRegistrationState()) {
return;
@@ -2364,6 +2439,7 @@ void RegisterInternalCalls() {
mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderContext_RecordBuiltinForwardMainScene", reinterpret_cast<const void*>(&InternalCall_Rendering_ScriptableRenderContext_RecordBuiltinForwardMainScene));
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));
GetInternalCallRegistrationState() = true;
}