refactor(rendering): queue managed fullscreen pass descriptors

This commit is contained in:
2026-04-18 13:51:09 +08:00
parent 788b1b971e
commit c91e87f2e2
6 changed files with 129 additions and 38 deletions

View File

@@ -13,6 +13,7 @@
#include "Rendering/Execution/CameraFramePlan.h"
#include "Rendering/Internal/RenderPipelineFactory.h"
#include "Rendering/Passes/BuiltinColorScalePostProcessPass.h"
#include "Rendering/Planning/CameraPostProcessDesc.h"
#include "Rendering/Pipelines/NativeSceneRecorder.h"
#include "Rendering/Pipelines/ManagedScriptableRenderPipelineAsset.h"
#include "Rendering/RenderPipelineStageGraphContract.h"
@@ -93,7 +94,7 @@ struct ManagedScriptableRenderContextState {
Rendering::CameraFrameStage stage = Rendering::CameraFrameStage::MainScene;
const Rendering::RenderPipelineStageRenderGraphContext* graphContext = nullptr;
Rendering::Pipelines::NativeSceneRecorder* sceneRecorder = nullptr;
std::vector<Math::Vector4> queuedColorScaleFullscreenPasses = {};
std::vector<Rendering::CameraPostProcessPassDesc> queuedFullscreenPasses = {};
};
struct ManagedScriptableRenderPipelineCameraRequestContextState {
@@ -322,6 +323,36 @@ bool SupportsManagedRenderPipelineStageGraphRecording(
Rendering::IsCameraFrameFullscreenSequenceStage(stage);
}
Rendering::RenderPass* ConfigureManagedFullscreenPass(
std::vector<std::unique_ptr<Rendering::RenderPass>>& passPool,
size_t passIndex,
const Rendering::CameraPostProcessPassDesc& passDesc) {
while (passPool.size() <= passIndex) {
passPool.push_back(nullptr);
}
std::unique_ptr<Rendering::RenderPass>& passSlot = passPool[passIndex];
switch (passDesc.type) {
case Rendering::CameraPostProcessPassType::ColorScale: {
Rendering::Passes::BuiltinColorScalePostProcessPass* colorScalePass =
dynamic_cast<Rendering::Passes::BuiltinColorScalePostProcessPass*>(
passSlot.get());
if (colorScalePass == nullptr) {
passSlot =
std::make_unique<Rendering::Passes::BuiltinColorScalePostProcessPass>();
colorScalePass =
static_cast<Rendering::Passes::BuiltinColorScalePostProcessPass*>(
passSlot.get());
}
colorScalePass->SetColorScale(passDesc.colorScale.scale);
return colorScalePass;
}
default:
return nullptr;
}
}
} // namespace
class MonoManagedRenderPipelineAssetRuntime final
@@ -406,13 +437,13 @@ public:
}
void Shutdown() override {
for (std::unique_ptr<Rendering::Passes::BuiltinColorScalePostProcessPass>& pass :
m_colorScalePassPool) {
for (std::unique_ptr<Rendering::RenderPass>& pass :
m_fullscreenPassPool) {
if (pass != nullptr) {
pass->Shutdown();
}
}
m_colorScalePassPool.clear();
m_fullscreenPassPool.clear();
if (m_defaultSceneRenderer != nullptr) {
m_defaultSceneRenderer->Shutdown();
}
@@ -568,29 +599,27 @@ private:
bool FlushManagedFullscreenPasses(
const Rendering::RenderPipelineStageRenderGraphContext& context,
const ManagedScriptableRenderContextState& managedContextState) {
if (managedContextState.queuedColorScaleFullscreenPasses.empty()) {
if (managedContextState.queuedFullscreenPasses.empty()) {
return true;
}
if (!Rendering::IsCameraFrameFullscreenSequenceStage(context.stage)) {
return false;
}
while (m_colorScalePassPool.size() <
managedContextState.queuedColorScaleFullscreenPasses.size()) {
m_colorScalePassPool.push_back(
std::make_unique<Rendering::Passes::BuiltinColorScalePostProcessPass>());
}
std::vector<Rendering::RenderPass*> passes = {};
passes.reserve(
managedContextState.queuedColorScaleFullscreenPasses.size());
managedContextState.queuedFullscreenPasses.size());
for (size_t passIndex = 0u;
passIndex < managedContextState.queuedColorScaleFullscreenPasses.size();
passIndex < managedContextState.queuedFullscreenPasses.size();
++passIndex) {
Rendering::Passes::BuiltinColorScalePostProcessPass* const pass =
m_colorScalePassPool[passIndex].get();
pass->SetColorScale(
managedContextState.queuedColorScaleFullscreenPasses[passIndex]);
Rendering::RenderPass* const pass =
ConfigureManagedFullscreenPass(
m_fullscreenPassPool,
passIndex,
managedContextState.queuedFullscreenPasses[passIndex]);
if (pass == nullptr) {
return false;
}
passes.push_back(pass);
}
@@ -605,8 +634,7 @@ 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_colorScalePassPool = {};
std::vector<std::unique_ptr<Rendering::RenderPass>> m_fullscreenPassPool = {};
std::unique_ptr<Rendering::NativeSceneRenderer> m_defaultSceneRenderer = nullptr;
};
@@ -2621,19 +2649,32 @@ InternalCall_Rendering_ScriptableRenderContext_RecordSceneInjectionPoint(
}
mono_bool
InternalCall_Rendering_ScriptableRenderContext_RecordColorScaleFullscreenPass(
InternalCall_Rendering_ScriptableRenderContext_RecordFullscreenPass(
uint64_t nativeHandle,
XCEngine::Math::Vector4* colorScale) {
int32_t passType,
XCEngine::Math::Vector4* vectorPayload) {
ManagedScriptableRenderContextState* const state =
FindManagedScriptableRenderContextState(nativeHandle);
if (state == nullptr ||
state->graphContext == nullptr ||
colorScale == nullptr ||
!Rendering::IsCameraFrameFullscreenSequenceStage(state->stage)) {
return 0;
}
state->queuedColorScaleFullscreenPasses.push_back(*colorScale);
Rendering::CameraPostProcessPassDesc passDesc = {};
switch (static_cast<Rendering::CameraPostProcessPassType>(passType)) {
case Rendering::CameraPostProcessPassType::ColorScale:
if (vectorPayload == nullptr) {
return 0;
}
passDesc =
Rendering::CameraPostProcessPassDesc::MakeColorScale(*vectorPayload);
break;
default:
return 0;
}
state->queuedFullscreenPasses.push_back(passDesc);
return 1;
}
@@ -2874,7 +2915,7 @@ void RegisterInternalCalls() {
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));
mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderContext_RecordSceneInjectionPoint", reinterpret_cast<const void*>(&InternalCall_Rendering_ScriptableRenderContext_RecordSceneInjectionPoint));
mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderContext_RecordColorScaleFullscreenPass", reinterpret_cast<const void*>(&InternalCall_Rendering_ScriptableRenderContext_RecordColorScaleFullscreenPass));
mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderContext_RecordFullscreenPass", reinterpret_cast<const void*>(&InternalCall_Rendering_ScriptableRenderContext_RecordFullscreenPass));
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));

View File

@@ -106,6 +106,7 @@ set(XCENGINE_SCRIPT_CORE_SOURCES
${CMAKE_CURRENT_SOURCE_DIR}/XCEngine.ScriptCore/Component.cs
${CMAKE_CURRENT_SOURCE_DIR}/XCEngine.ScriptCore/Debug.cs
${CMAKE_CURRENT_SOURCE_DIR}/XCEngine.ScriptCore/ForceMode.cs
${CMAKE_CURRENT_SOURCE_DIR}/XCEngine.ScriptCore/FullscreenPassDescriptor.cs
${CMAKE_CURRENT_SOURCE_DIR}/XCEngine.ScriptCore/GraphicsSettings.cs
${CMAKE_CURRENT_SOURCE_DIR}/XCEngine.ScriptCore/GameObject.cs
${CMAKE_CURRENT_SOURCE_DIR}/XCEngine.ScriptCore/Input.cs

View File

@@ -138,10 +138,12 @@ namespace Gameplay
{
return context != null &&
context.stage == CameraFrameStage.PostProcess &&
context.RecordColorScaleFullscreenPass(
new Vector4(1.10f, 0.95f, 0.90f, 1.0f)) &&
context.RecordColorScaleFullscreenPass(
new Vector4(0.95f, 1.05f, 1.10f, 1.0f));
context.RecordFullscreenPass(
FullscreenPassDescriptor.CreateColorScale(
new Vector4(1.10f, 0.95f, 0.90f, 1.0f))) &&
context.RecordFullscreenPass(
FullscreenPassDescriptor.CreateColorScale(
new Vector4(0.95f, 1.05f, 1.10f, 1.0f)));
}
}
@@ -195,8 +197,9 @@ namespace Gameplay
if (context.stage == CameraFrameStage.PostProcess)
{
RecordPostProcessCallCount++;
return context.RecordColorScaleFullscreenPass(
new Vector4(1.03f, 0.98f, 0.94f, 1.0f));
return context.RecordFullscreenPass(
FullscreenPassDescriptor.CreateColorScale(
new Vector4(1.03f, 0.98f, 0.94f, 1.0f)));
}
return false;
@@ -219,8 +222,9 @@ namespace Gameplay
return context != null &&
(context.stage == CameraFrameStage.PostProcess ||
context.stage == CameraFrameStage.FinalOutput) &&
context.RecordColorScaleFullscreenPass(
new Vector4(1.05f, 1.0f, 0.95f, 1.0f));
context.RecordFullscreenPass(
FullscreenPassDescriptor.CreateColorScale(
new Vector4(1.05f, 1.0f, 0.95f, 1.0f)));
}
}

View File

@@ -0,0 +1,33 @@
namespace XCEngine
{
public enum FullscreenPassType
{
ColorScale = 0
}
public struct FullscreenPassDescriptor
{
public FullscreenPassType type;
public Vector4 vectorPayload;
public static FullscreenPassDescriptor CreateColorScale(
Vector4 colorScale)
{
FullscreenPassDescriptor descriptor = new FullscreenPassDescriptor();
descriptor.type = FullscreenPassType.ColorScale;
descriptor.vectorPayload = colorScale;
return descriptor;
}
public bool IsValid()
{
switch (type)
{
case FullscreenPassType.ColorScale:
return true;
default:
return false;
}
}
}
}

View File

@@ -405,9 +405,10 @@ namespace XCEngine
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern bool
Rendering_ScriptableRenderContext_RecordColorScaleFullscreenPass(
Rendering_ScriptableRenderContext_RecordFullscreenPass(
ulong nativeHandle,
ref Vector4 colorScale);
int passType,
ref Vector4 vectorPayload);
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern int

View File

@@ -1,3 +1,5 @@
using System;
namespace XCEngine
{
public sealed class ScriptableRenderContext
@@ -42,13 +44,22 @@ namespace XCEngine
(int)injectionPoint);
}
public bool RecordColorScaleFullscreenPass(
Vector4 colorScale)
public bool RecordFullscreenPass(
FullscreenPassDescriptor pass)
{
if (!pass.IsValid())
{
throw new ArgumentException(
"Invalid fullscreen pass descriptor.",
nameof(pass));
}
Vector4 vectorPayload = pass.vectorPayload;
return InternalCalls
.Rendering_ScriptableRenderContext_RecordColorScaleFullscreenPass(
.Rendering_ScriptableRenderContext_RecordFullscreenPass(
m_nativeHandle,
ref colorScale);
(int)pass.type,
ref vectorPayload);
}
}
}