Tighten URP pass queue snapshot ownership

This commit is contained in:
2026-04-27 15:21:57 +08:00
parent c0b829cd6a
commit 66d968c3ce
22 changed files with 849 additions and 51 deletions

View File

@@ -807,6 +807,7 @@ TEST_F(
0 }))
<< runtime->GetLastError();
const XCEngine::Rendering::RenderContext renderContext = {};
XCEngine::Rendering::RenderGraph graph;
XCEngine::Rendering::RenderGraphBuilder graphBuilder(graph);
XCEngine::Rendering::RenderGraphTextureDesc colorDesc = {};
@@ -1435,6 +1436,7 @@ TEST_F(
bool hasPublicContextEnvironmentData = false;
bool hasPublicContextFinalColorData = false;
bool hasPublicContextStageColorData = false;
bool hasPublicContextFramePlanId = false;
bool hasPublicRequestContextHasDirectionalShadow = false;
bool hasPublicRequestContextClearDirectionalShadow = false;
bool hasUniversalContextRecordSceneExtension = false;
@@ -1447,8 +1449,10 @@ TEST_F(
bool hasPipelineAssetSetDirty = false;
bool hasPipelineAssetGetRuntimeResourceVersion = false;
bool hasPlanningContextType = false;
bool hasPublicPlanningContextFramePlanId = false;
bool hasRendererFeatureConfigureCameraFramePlan = false;
bool hasRendererRecordingContextType = false;
bool hasPublicRendererRecordingContextFramePlanId = false;
bool hasRendererCameraRequestContextType = false;
bool hasRendererBackedRenderPipelineAssetType = false;
bool hasRendererBackedRenderPipelineType = false;
@@ -1473,6 +1477,7 @@ TEST_F(
bool hasRenderGraphRasterContextCommandBuffer = false;
bool hasSceneRenderPhaseType = false;
bool hasSceneRenderInjectionPointType = false;
bool hasPublicRenderingDataFramePlanId = false;
bool hasRenderPassProtectedRecordColorScaleFullscreenPass = false;
bool hasRenderPassProtectedRecordShaderVectorFullscreenPass = false;
bool hasRenderPassProtectedRecordFinalColorFullscreenPass = false;
@@ -1537,6 +1542,10 @@ TEST_F(
selectionScript,
"HasPublicContextStageColorData",
hasPublicContextStageColorData));
EXPECT_TRUE(runtime->TryGetFieldValue(
selectionScript,
"HasPublicContextFramePlanId",
hasPublicContextFramePlanId));
EXPECT_TRUE(runtime->TryGetFieldValue(
selectionScript,
"HasPublicRequestContextHasDirectionalShadow",
@@ -1585,6 +1594,10 @@ TEST_F(
selectionScript,
"HasPlanningContextType",
hasPlanningContextType));
EXPECT_TRUE(runtime->TryGetFieldValue(
selectionScript,
"HasPublicPlanningContextFramePlanId",
hasPublicPlanningContextFramePlanId));
EXPECT_TRUE(runtime->TryGetFieldValue(
selectionScript,
"HasRendererFeatureConfigureCameraFramePlan",
@@ -1593,6 +1606,10 @@ TEST_F(
selectionScript,
"HasRendererRecordingContextType",
hasRendererRecordingContextType));
EXPECT_TRUE(runtime->TryGetFieldValue(
selectionScript,
"HasPublicRendererRecordingContextFramePlanId",
hasPublicRendererRecordingContextFramePlanId));
EXPECT_TRUE(runtime->TryGetFieldValue(
selectionScript,
"HasRendererCameraRequestContextType",
@@ -1689,6 +1706,10 @@ TEST_F(
selectionScript,
"HasSceneRenderInjectionPointType",
hasSceneRenderInjectionPointType));
EXPECT_TRUE(runtime->TryGetFieldValue(
selectionScript,
"HasPublicRenderingDataFramePlanId",
hasPublicRenderingDataFramePlanId));
EXPECT_TRUE(runtime->TryGetFieldValue(
selectionScript,
"HasRenderPassProtectedRecordColorScaleFullscreenPass",
@@ -1717,6 +1738,7 @@ TEST_F(
EXPECT_FALSE(hasPublicContextEnvironmentData);
EXPECT_FALSE(hasPublicContextFinalColorData);
EXPECT_FALSE(hasPublicContextStageColorData);
EXPECT_TRUE(hasPublicContextFramePlanId);
EXPECT_FALSE(hasPublicRequestContextHasDirectionalShadow);
EXPECT_FALSE(hasPublicRequestContextClearDirectionalShadow);
EXPECT_FALSE(hasUniversalContextRecordSceneExtension);
@@ -1729,8 +1751,10 @@ TEST_F(
EXPECT_TRUE(hasPipelineAssetSetDirty);
EXPECT_TRUE(hasPipelineAssetGetRuntimeResourceVersion);
EXPECT_TRUE(hasPlanningContextType);
EXPECT_TRUE(hasPublicPlanningContextFramePlanId);
EXPECT_TRUE(hasRendererFeatureConfigureCameraFramePlan);
EXPECT_TRUE(hasRendererRecordingContextType);
EXPECT_TRUE(hasPublicRendererRecordingContextFramePlanId);
EXPECT_TRUE(hasRendererCameraRequestContextType);
EXPECT_FALSE(hasRendererBackedRenderPipelineAssetType);
EXPECT_FALSE(hasRendererBackedRenderPipelineType);
@@ -1755,6 +1779,7 @@ TEST_F(
EXPECT_TRUE(hasRenderGraphRasterContextCommandBuffer);
EXPECT_FALSE(hasSceneRenderPhaseType);
EXPECT_FALSE(hasSceneRenderInjectionPointType);
EXPECT_TRUE(hasPublicRenderingDataFramePlanId);
EXPECT_FALSE(hasRenderPassProtectedRecordColorScaleFullscreenPass);
EXPECT_FALSE(hasRenderPassProtectedRecordShaderVectorFullscreenPass);
EXPECT_FALSE(hasRenderPassProtectedRecordFinalColorFullscreenPass);
@@ -4626,8 +4651,17 @@ TEST_F(
XCEngine::Rendering::Pipelines::ManagedScriptableRenderPipelineAsset>(
descriptor);
TestRenderDevice device;
TestRenderCommandList commandList;
TestRenderCommandQueue commandQueue;
const XCEngine::Rendering::RenderContext renderContext =
CreateRenderContext(
device,
commandList,
commandQueue);
XCEngine::Rendering::CameraRenderRequest request = {};
request.context = {};
request.context = renderContext;
request.surface = XCEngine::Rendering::RenderSurface(64u, 64u);
XCTest::TestRenderResourceView colorAttachmentView(
XCEngine::RHI::ResourceViewType::RenderTarget,
@@ -4673,6 +4707,156 @@ TEST_F(
EXPECT_TRUE(plan.IsFinalOutputStageValid());
}
TEST_F(
MonoScriptRuntimeTest,
ManagedRendererPassQueueSnapshotDrivesSupportAndRecording) {
const XCEngine::Rendering::Pipelines::ManagedRenderPipelineAssetDescriptor descriptor = {
"GameScripts",
"Gameplay",
"ManagedPassQueueSnapshotProbeAsset"
};
auto asset =
std::make_shared<
XCEngine::Rendering::Pipelines::ManagedScriptableRenderPipelineAsset>(
descriptor);
TestRenderDevice device;
TestRenderCommandList commandList;
TestRenderCommandQueue commandQueue;
const XCEngine::Rendering::RenderContext renderContext =
CreateRenderContext(
device,
commandList,
commandQueue);
XCEngine::Rendering::CameraRenderRequest request = {};
request.context = renderContext;
request.surface = XCEngine::Rendering::RenderSurface(64u, 64u);
TestRenderResourceView colorAttachmentView(
XCEngine::RHI::ResourceViewType::RenderTarget,
XCEngine::RHI::ResourceViewDimension::Texture2D,
XCEngine::RHI::Format::R8G8B8A8_UNorm);
TestRenderResourceView depthAttachmentView(
XCEngine::RHI::ResourceViewType::DepthStencil,
XCEngine::RHI::ResourceViewDimension::Texture2D,
XCEngine::RHI::Format::D32_Float);
request.surface.SetColorAttachment(
&colorAttachmentView);
request.surface.SetDepthAttachment(
&depthAttachmentView);
XCEngine::Rendering::RenderPipelineHost host(asset);
const std::vector<XCEngine::Rendering::CameraFramePlan> plans =
host.BuildFramePlans({ request });
ASSERT_EQ(plans.size(), 1u);
const XCEngine::Rendering::CameraFramePlan& plan = plans[0];
ASSERT_NE(plan.framePlanId, 0u);
ASSERT_TRUE(
plan.IsFullscreenStageRequested(
XCEngine::Rendering::CameraFrameStage::PostProcess));
auto* pipelineHost =
dynamic_cast<XCEngine::Rendering::Pipelines::ScriptableRenderPipelineHost*>(
host.GetPipeline());
ASSERT_NE(pipelineHost, nullptr);
ASSERT_TRUE(
pipelineHost->Initialize(
renderContext))
<< runtime->GetLastError();
const XCEngine::Rendering::RenderPipelineStageSupportContext
supportContext = {
XCEngine::Rendering::CameraFrameStage::PostProcess,
plan.request.rendererIndex,
plan.framePlanId
};
EXPECT_TRUE(
pipelineHost->SupportsStageRenderGraph(
supportContext))
<< runtime->GetLastError();
const XCEngine::Rendering::RenderPipelineStageSupportContext
missingSnapshotSupportContext = {
XCEngine::Rendering::CameraFrameStage::PostProcess,
plan.request.rendererIndex,
plan.framePlanId + 1000u
};
EXPECT_FALSE(
pipelineHost->SupportsStageRenderGraph(
missingSnapshotSupportContext));
XCEngine::Rendering::RenderGraph graph;
XCEngine::Rendering::RenderGraphBuilder graphBuilder(graph);
XCEngine::Rendering::RenderGraphTextureDesc colorDesc = {};
colorDesc.width = 64u;
colorDesc.height = 64u;
colorDesc.format =
static_cast<XCEngine::Core::uint32>(
XCEngine::RHI::Format::R8G8B8A8_UNorm);
TestRenderResourceView sourceColorView(
XCEngine::RHI::ResourceViewType::ShaderResource,
XCEngine::RHI::ResourceViewDimension::Texture2D,
XCEngine::RHI::Format::R8G8B8A8_UNorm);
const XCEngine::Rendering::RenderGraphTextureHandle sourceColor =
graphBuilder.ImportTexture(
"ManagedPassQueueSnapshotSource",
colorDesc,
&sourceColorView,
{});
const XCEngine::Rendering::RenderGraphTextureHandle outputColor =
graphBuilder.CreateTransientTexture(
"ManagedPassQueueSnapshotOutput",
colorDesc);
const XCEngine::Rendering::RenderSceneData sceneData = {};
const XCEngine::Rendering::RenderSurface surface(64u, 64u);
bool executionSucceeded = true;
XCEngine::Rendering::RenderGraphBlackboard blackboard = {};
XCEngine::Rendering::EmplaceCameraFrameRenderGraphFrameData(blackboard)
.resources.mainScene.color = sourceColor;
XCEngine::Rendering::RenderPipelineStageRenderGraphContext graphContext = {
graphBuilder,
"ManagedPassQueueSnapshot",
XCEngine::Rendering::CameraFrameStage::PostProcess,
renderContext,
sceneData,
surface,
nullptr,
nullptr,
XCEngine::RHI::ResourceStates::Common,
{},
{ outputColor },
{},
{},
&executionSucceeded,
&blackboard
};
graphContext.rendererIndex = plan.request.rendererIndex;
graphContext.framePlanId = plan.framePlanId;
EXPECT_TRUE(
pipelineHost->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(),
"ManagedPassQueueSnapshot.PostProcess");
pipelineHost->Shutdown();
}
TEST_F(
MonoScriptRuntimeTest,
ManagedPlanningContextRejectsNonFullscreenStageRequests) {