Rendering: formalize main-scene graph contract

This commit is contained in:
2026-04-15 07:56:00 +08:00
parent 8b156dd112
commit 2cda9fd24a
9 changed files with 276 additions and 59 deletions

View File

@@ -643,6 +643,7 @@ TEST(BuiltinForwardPipeline_Test, RecordsMainSceneGraphPassWithSampledShadowDepe
nullptr,
nullptr,
ResourceStates::Common,
{},
{ colorTarget },
depthTarget,
&executionSucceeded,
@@ -1181,6 +1182,7 @@ TEST(BuiltinForwardPipeline_Test, RecordsActiveFeatureInjectionPassesIntoMainSce
nullptr,
nullptr,
ResourceStates::Common,
{},
{ colorTarget },
depthTarget,
&executionSucceeded,
@@ -1201,6 +1203,112 @@ TEST(BuiltinForwardPipeline_Test, RecordsActiveFeatureInjectionPassesIntoMainSce
EXPECT_STREQ(compiledGraph.GetPassName(4).CStr(), "MainScene.Transparent");
}
TEST(BuiltinForwardPipeline_Test, ForwardsSourceColorTextureIntoFeatureInjectionGraphContext) {
BuiltinForwardPipeline pipeline;
pipeline.m_forwardSceneFeatureHost.m_featurePasses.clear();
auto feature = std::make_unique<TestSceneRenderFeaturePass>(
SceneRenderInjectionPoint::BeforeOpaque,
true,
nullptr,
"SourceAware");
TestSceneRenderFeaturePass* featureRaw = feature.get();
pipeline.AddForwardSceneFeaturePass(std::move(feature));
RenderGraph graph = {};
RenderGraphBuilder graphBuilder(graph);
RenderGraphTextureDesc colorDesc = {};
colorDesc.width = 320u;
colorDesc.height = 180u;
colorDesc.format = static_cast<uint32_t>(Format::R8G8B8A8_UNorm);
colorDesc.textureType = static_cast<uint32_t>(XCEngine::RHI::TextureType::Texture2D);
colorDesc.sampleCount = 1u;
RenderGraphTextureDesc depthDesc = {};
depthDesc.width = 320u;
depthDesc.height = 180u;
depthDesc.format = static_cast<uint32_t>(Format::D24_UNorm_S8_UInt);
depthDesc.textureType = static_cast<uint32_t>(XCEngine::RHI::TextureType::Texture2D);
depthDesc.sampleCount = 1u;
TestResourceView sourceRenderTargetView(
ResourceViewType::RenderTarget,
ResourceViewDimension::Texture2D,
Format::R8G8B8A8_UNorm);
TestResourceView sourceShaderView(
ResourceViewType::ShaderResource,
ResourceViewDimension::Texture2D,
Format::R8G8B8A8_UNorm);
TestResourceView colorView(
ResourceViewType::RenderTarget,
ResourceViewDimension::Texture2D,
Format::R8G8B8A8_UNorm);
TestResourceView depthView(
ResourceViewType::DepthStencil,
ResourceViewDimension::Texture2D,
Format::D24_UNorm_S8_UInt);
const RenderGraphImportedTextureOptions graphManagedImport = {
ResourceStates::Common,
ResourceStates::Common,
true
};
const RenderGraphTextureHandle sourceColor =
graphBuilder.ImportTexture("SourceColor", colorDesc, &sourceRenderTargetView, graphManagedImport);
const RenderGraphTextureHandle colorTarget =
graphBuilder.ImportTexture("MainColor", colorDesc, &colorView, graphManagedImport);
const RenderGraphTextureHandle depthTarget =
graphBuilder.ImportTexture("MainDepth", depthDesc, &depthView, graphManagedImport);
RenderSurface surface(320u, 180u);
surface.SetColorAttachment(&colorView);
surface.SetDepthAttachment(&depthView);
RenderSurface sourceSurface(320u, 180u);
sourceSurface.SetColorAttachment(&sourceRenderTargetView);
RenderContext renderContext = {};
RenderSceneData sceneData = {};
RenderGraphBlackboard blackboard = {};
bool executionSucceeded = true;
const RenderPipelineMainSceneRenderGraphContext context = {
graphBuilder,
"MainScene",
renderContext,
sceneData,
surface,
&sourceSurface,
&sourceShaderView,
ResourceStates::Common,
sourceColor,
{ colorTarget },
depthTarget,
&executionSucceeded,
&blackboard
};
ASSERT_TRUE(pipeline.RecordMainSceneRenderGraph(context));
EXPECT_EQ(featureRaw->recordGraphCallCount, 1u);
EXPECT_TRUE(featureRaw->lastReceivedSourceColorTextureValid);
CompiledRenderGraph compiledGraph = {};
String errorMessage;
ASSERT_TRUE(RenderGraphCompiler::Compile(graph, compiledGraph, &errorMessage))
<< errorMessage.CStr();
ASSERT_EQ(compiledGraph.GetPassCount(), 4u);
EXPECT_STREQ(compiledGraph.GetPassName(0).CStr(), "MainScene.BeforeOpaque.SourceAware.0");
EXPECT_STREQ(compiledGraph.GetPassName(1).CStr(), "MainScene.Opaque");
EXPECT_STREQ(compiledGraph.GetPassName(2).CStr(), "MainScene.Skybox");
EXPECT_STREQ(compiledGraph.GetPassName(3).CStr(), "MainScene.Transparent");
RenderGraphTextureLifetime sourceLifetime = {};
ASSERT_TRUE(compiledGraph.TryGetTextureLifetime(sourceColor, sourceLifetime));
EXPECT_TRUE(sourceLifetime.used);
EXPECT_EQ(sourceLifetime.firstPassIndex, 0u);
EXPECT_EQ(sourceLifetime.lastPassIndex, 0u);
}
TEST(BuiltinForwardPipeline_Test, PropagatesForwardDrawFailureWhenPipelineStateCreationFails) {
ShaderLoader loader;
LoadResult result = loader.Load(GetBuiltinForwardLitShaderPath());