rendering: close renderer override bridge phase 4.4

This commit is contained in:
2026-04-26 02:44:21 +08:00
parent 97f3c3486a
commit cf0b00b0d2
4 changed files with 276 additions and 3 deletions

View File

@@ -3168,6 +3168,186 @@ TEST_F(
host->GetStageRecorder()->Shutdown();
}
TEST_F(
MonoScriptRuntimeTest,
ManagedRenderPipelineBridgeUsesCameraRendererOverrideAcrossPlanningAndExecution) {
const auto bridge =
XCEngine::Rendering::Pipelines::GetManagedRenderPipelineBridge();
ASSERT_NE(bridge, nullptr);
const XCEngine::Rendering::Pipelines::ManagedRenderPipelineAssetDescriptor descriptor = {
"GameScripts",
"Gameplay",
"ManagedCameraOverrideRendererSelectionProbeAsset"
};
std::shared_ptr<const XCEngine::Rendering::Pipelines::ManagedRenderPipelineAssetRuntime>
assetRuntime = bridge->CreateAssetRuntime(descriptor);
ASSERT_NE(assetRuntime, nullptr);
EXPECT_EQ(
assetRuntime->GetPipelineRendererAssetPolicy(),
XCEngine::Rendering::Pipelines::ManagedPipelineRendererAssetPolicy::
DefaultNativeBackend);
Scene* runtimeScene =
CreateScene("ManagedCameraOverrideRendererSelectionScene");
GameObject* cameraObject = runtimeScene->CreateGameObject("Camera");
auto* camera = cameraObject->AddComponent<CameraComponent>();
ASSERT_NE(camera, nullptr);
camera->SetPrimary(true);
ScriptComponent* additionalCameraData =
cameraObject->AddComponent<ScriptComponent>();
ASSERT_NE(additionalCameraData, nullptr);
additionalCameraData->SetScriptClass(
"XCEngine.RenderPipelines.Universal",
"XCEngine.Rendering.Universal",
"UniversalAdditionalCameraData");
additionalCameraData->GetFieldStorage().SetFieldValue(
"rendererIndex",
int32_t(1));
engine->OnRuntimeStart(runtimeScene);
engine->OnUpdate(0.016f);
TestRenderDevice device;
TestRenderCommandList commandList;
TestRenderCommandQueue commandQueue;
TestRenderResourceView colorView(
XCEngine::RHI::ResourceViewType::RenderTarget,
XCEngine::RHI::ResourceViewDimension::Texture2D,
XCEngine::RHI::Format::R8G8B8A8_UNorm);
TestRenderResourceView depthView(
XCEngine::RHI::ResourceViewType::DepthStencil,
XCEngine::RHI::ResourceViewDimension::Texture2D,
XCEngine::RHI::Format::D32_Float);
const XCEngine::Rendering::RenderContext context =
CreateRenderContext(
device,
commandList,
commandQueue);
XCEngine::Rendering::RenderSurface surface(64u, 64u);
surface.SetColorAttachment(&colorView);
surface.SetDepthAttachment(&depthView);
XCEngine::Rendering::Pipelines::ManagedScriptableRenderPipelineAsset
asset(descriptor);
XCEngine::Rendering::CameraRenderRequest request = {};
request.scene = runtimeScene;
request.camera = camera;
request.context = context;
request.surface = surface;
asset.ConfigureCameraRenderRequest(
request,
0u,
0u,
XCEngine::Rendering::DirectionalShadowPlanningSettings{});
EXPECT_EQ(request.rendererIndex, 1);
XCEngine::Rendering::CameraFramePlan plan =
XCEngine::Rendering::CameraFramePlan::FromRequest(request);
asset.ConfigureCameraFramePlan(plan);
EXPECT_EQ(plan.request.rendererIndex, 1);
EXPECT_TRUE(
plan.IsFullscreenStageRequested(
XCEngine::Rendering::CameraFrameStage::PostProcess));
EXPECT_EQ(
plan.ResolveStageColorSource(
XCEngine::Rendering::CameraFrameStage::PostProcess),
XCEngine::Rendering::CameraFrameColorSource::MainSceneColor);
EXPECT_TRUE(plan.IsPostProcessStageValid());
std::unique_ptr<XCEngine::Rendering::RenderPipeline> pipeline =
asset.CreatePipeline();
ASSERT_NE(pipeline, nullptr);
auto* host =
dynamic_cast<XCEngine::Rendering::Pipelines::ScriptableRenderPipelineHost*>(
pipeline.get());
ASSERT_NE(host, nullptr);
ASSERT_NE(host->GetStageRecorder(), nullptr);
EXPECT_TRUE(host->GetStageRecorder()->Initialize(context))
<< runtime->GetLastError();
EXPECT_FALSE(
host->GetStageRecorder()->SupportsStageRenderGraph(
XCEngine::Rendering::RenderPipelineStageSupportContext{
XCEngine::Rendering::CameraFrameStage::PostProcess,
0 }));
EXPECT_TRUE(
host->GetStageRecorder()->SupportsStageRenderGraph(
XCEngine::Rendering::RenderPipelineStageSupportContext{
XCEngine::Rendering::CameraFrameStage::PostProcess,
plan.request.rendererIndex }));
XCEngine::Rendering::RenderGraph graph;
XCEngine::Rendering::RenderGraphBuilder graphBuilder(graph);
XCEngine::Rendering::RenderGraphTextureDesc postProcessColorDesc = {};
postProcessColorDesc.width = 64u;
postProcessColorDesc.height = 64u;
postProcessColorDesc.format =
static_cast<XCEngine::Core::uint32>(
XCEngine::RHI::Format::R8G8B8A8_UNorm);
const XCEngine::Rendering::RenderGraphTextureHandle sourceColor =
graphBuilder.ImportTexture(
"ManagedCameraOverrideSource",
postProcessColorDesc,
&colorView,
{});
const XCEngine::Rendering::RenderGraphTextureHandle outputColor =
graphBuilder.CreateTransientTexture(
"ManagedCameraOverrideOutput",
postProcessColorDesc);
const XCEngine::Rendering::RenderSceneData sceneData = {};
bool executionSucceeded = true;
XCEngine::Rendering::RenderGraphBlackboard blackboard = {};
XCEngine::Rendering::EmplaceCameraFrameRenderGraphFrameData(blackboard)
.resources.mainScene.color = sourceColor;
XCEngine::Rendering::RenderPipelineStageRenderGraphContext graphContext = {
graphBuilder,
"ManagedCameraOverridePostProcess",
XCEngine::Rendering::CameraFrameStage::PostProcess,
context,
sceneData,
surface,
nullptr,
nullptr,
XCEngine::RHI::ResourceStates::Common,
sourceColor,
{ outputColor },
{},
{},
&executionSucceeded,
&blackboard
};
graphContext.stageColorSource =
plan.ResolveStageColorSource(
XCEngine::Rendering::CameraFrameStage::PostProcess);
graphContext.usesGraphManagedOutputColor =
plan.UsesGraphManagedOutputColor(
XCEngine::Rendering::CameraFrameStage::PostProcess);
graphContext.rendererIndex = plan.request.rendererIndex;
EXPECT_TRUE(host->GetStageRecorder()->RecordStageRenderGraph(graphContext))
<< runtime->GetLastError();
XCEngine::Rendering::CompiledRenderGraph compiledGraph = {};
XCEngine::Containers::String errorMessage;
ASSERT_TRUE(
XCEngine::Rendering::RenderGraphCompiler::Compile(
graph,
compiledGraph,
&errorMessage))
<< errorMessage.CStr();
ASSERT_EQ(compiledGraph.GetPassCount(), 1u);
EXPECT_STREQ(
compiledGraph.GetPassName(0).CStr(),
"ManagedCameraOverridePostProcess");
host->GetStageRecorder()->Shutdown();
}
TEST_F(
MonoScriptRuntimeTest,
ManagedRenderPipelineBridgeFallsBackToDefaultSceneRecorderWhenBackendKeyIsUnknown) {