Group camera frame fullscreen color chain intent

This commit is contained in:
2026-04-15 00:32:23 +08:00
parent ac836ae961
commit 00fa6fffa0
7 changed files with 108 additions and 60 deletions

View File

@@ -12,6 +12,17 @@ enum class CameraFrameColorSource {
PostProcessColor
};
struct CameraFrameFullscreenStagePlan {
bool usesGraphManagedOutputColor = false;
CameraFrameColorSource source = CameraFrameColorSource::ExplicitSurface;
};
struct CameraFrameColorChainPlan {
bool usesGraphManagedMainSceneColor = false;
CameraFrameFullscreenStagePlan postProcess = {};
CameraFrameFullscreenStagePlan finalOutput = {};
};
struct CameraFramePlan {
static RenderSurface BuildGraphManagedIntermediateSurfaceTemplate(
const RenderSurface& surface) {
@@ -32,10 +43,7 @@ struct CameraFramePlan {
RenderPassSequence* preScenePasses = nullptr;
RenderPassSequence* postScenePasses = nullptr;
RenderPassSequence* overlayPasses = nullptr;
bool usesGraphManagedMainSceneColor = false;
bool usesGraphManagedPostProcessColor = false;
CameraFrameColorSource postProcessSource = CameraFrameColorSource::ExplicitSurface;
CameraFrameColorSource finalOutputSource = CameraFrameColorSource::ExplicitSurface;
CameraFrameColorChainPlan colorChain = {};
RenderSurface graphManagedMainSceneSurface = {};
static CameraFramePlan FromRequest(const CameraRenderRequest& request) {
@@ -61,20 +69,45 @@ struct CameraFramePlan {
BuildGraphManagedIntermediateSurfaceTemplate(request.surface);
}
bool UsesGraphManagedMainSceneColor() const {
return colorChain.usesGraphManagedMainSceneColor;
}
bool UsesGraphManagedOutputColor(CameraFrameStage stage) const {
switch (stage) {
case CameraFrameStage::PostProcess:
return colorChain.postProcess.usesGraphManagedOutputColor;
default:
return false;
}
}
CameraFrameColorSource ResolveStageColorSource(CameraFrameStage stage) const {
switch (stage) {
case CameraFrameStage::PostProcess:
return colorChain.postProcess.source;
case CameraFrameStage::FinalOutput:
return colorChain.finalOutput.source;
default:
return CameraFrameColorSource::ExplicitSurface;
}
}
bool IsPostProcessStageValid() const {
if (!postProcess.IsRequested()) {
return true;
}
if (postProcessSource == CameraFrameColorSource::ExplicitSurface) {
if (ResolveStageColorSource(CameraFrameStage::PostProcess) ==
CameraFrameColorSource::ExplicitSurface) {
return postProcess.IsValid();
}
const bool hasUsableDestination =
usesGraphManagedPostProcessColor ||
UsesGraphManagedOutputColor(CameraFrameStage::PostProcess) ||
(HasValidColorTarget(postProcess.destinationSurface) &&
HasValidSurfaceSampleDescription(postProcess.destinationSurface));
return usesGraphManagedMainSceneColor &&
return UsesGraphManagedMainSceneColor() &&
postProcess.passes != nullptr &&
HasValidSingleSampleColorSource(request.surface) &&
hasUsableDestination;
@@ -85,14 +118,16 @@ struct CameraFramePlan {
return true;
}
const CameraFrameColorSource finalOutputSource =
ResolveStageColorSource(CameraFrameStage::FinalOutput);
if (finalOutputSource == CameraFrameColorSource::ExplicitSurface) {
return finalOutput.IsValid();
}
const bool hasUsableSource =
finalOutputSource == CameraFrameColorSource::MainSceneColor
? usesGraphManagedMainSceneColor
: usesGraphManagedPostProcessColor;
? UsesGraphManagedMainSceneColor()
: UsesGraphManagedOutputColor(CameraFrameStage::PostProcess);
return hasUsableSource &&
finalOutput.passes != nullptr &&
HasValidColorTarget(finalOutput.destinationSurface) &&
@@ -157,7 +192,7 @@ struct CameraFramePlan {
}
const RenderSurface& GetMainSceneSurface() const {
if (usesGraphManagedMainSceneColor &&
if (UsesGraphManagedMainSceneColor() &&
graphManagedMainSceneSurface.GetWidth() > 0u &&
graphManagedMainSceneSurface.GetHeight() > 0u) {
return graphManagedMainSceneSurface;

View File

@@ -40,25 +40,16 @@ inline bool UsesCameraFrameStageGraphManagedOutputColor(
CameraFrameStage stage) {
switch (stage) {
case CameraFrameStage::MainScene:
return plan.usesGraphManagedMainSceneColor;
case CameraFrameStage::PostProcess:
return plan.usesGraphManagedPostProcessColor;
return plan.UsesGraphManagedMainSceneColor();
default:
return false;
return plan.UsesGraphManagedOutputColor(stage);
}
}
inline CameraFrameColorSource ResolveCameraFrameStageGraphManagedColorSource(
const CameraFramePlan& plan,
CameraFrameStage stage) {
switch (stage) {
case CameraFrameStage::PostProcess:
return plan.postProcessSource;
case CameraFrameStage::FinalOutput:
return plan.finalOutputSource;
default:
return CameraFrameColorSource::ExplicitSurface;
}
return plan.ResolveStageColorSource(stage);
}
inline CameraFrameRenderGraphSourceBinding ResolveCameraFrameFullscreenStageGraphSourceBinding(

View File

@@ -264,7 +264,7 @@ bool CameraRenderer::Render(
"CameraRenderer::Render failed: post-process request invalid");
return false;
}
if (plan.usesGraphManagedMainSceneColor &&
if (plan.UsesGraphManagedMainSceneColor() &&
(m_pipeline == nullptr || !m_pipeline->SupportsMainSceneRenderGraph())) {
Debug::Logger::Get().Error(
Debug::LogCategory::Rendering,

View File

@@ -57,7 +57,8 @@ inline CameraFrameStageSourceBinding ResolveCameraFrameStageSourceBinding(
switch (stage) {
case CameraFrameStage::PostProcess:
return plan.postProcess.IsRequested() &&
plan.postProcessSource == CameraFrameColorSource::ExplicitSurface
plan.ResolveStageColorSource(CameraFrameStage::PostProcess) ==
CameraFrameColorSource::ExplicitSurface
? CameraFrameStageSourceBinding{
&plan.postProcess.sourceSurface,
plan.postProcess.sourceColorView,
@@ -65,7 +66,8 @@ inline CameraFrameStageSourceBinding ResolveCameraFrameStageSourceBinding(
: CameraFrameStageSourceBinding{};
case CameraFrameStage::FinalOutput:
return plan.finalOutput.IsRequested() &&
plan.finalOutputSource == CameraFrameColorSource::ExplicitSurface
plan.ResolveStageColorSource(CameraFrameStage::FinalOutput) ==
CameraFrameColorSource::ExplicitSurface
? CameraFrameStageSourceBinding{
&plan.finalOutput.sourceSurface,
plan.finalOutput.sourceColorView,

View File

@@ -84,9 +84,9 @@ void CameraFramePlanBuilder::AttachFullscreenStageRequests(
if (hasPostProcess) {
m_ownedPostProcessSequences[index] = std::move(postProcessSequence);
plan.postProcess.passes = m_ownedPostProcessSequences[index].get();
plan.usesGraphManagedMainSceneColor = true;
plan.postProcessSource = CameraFrameColorSource::MainSceneColor;
plan.usesGraphManagedPostProcessColor = hasFinalOutput;
plan.colorChain.usesGraphManagedMainSceneColor = true;
plan.colorChain.postProcess.source = CameraFrameColorSource::MainSceneColor;
plan.colorChain.postProcess.usesGraphManagedOutputColor = hasFinalOutput;
if (!hasFinalOutput) {
plan.postProcess.destinationSurface = plan.request.surface;
}
@@ -95,15 +95,15 @@ void CameraFramePlanBuilder::AttachFullscreenStageRequests(
if (hasFinalOutput) {
m_ownedFinalOutputSequences[index] = std::move(finalOutputSequence);
plan.finalOutput.passes = m_ownedFinalOutputSequences[index].get();
plan.usesGraphManagedMainSceneColor = true;
plan.finalOutputSource =
plan.colorChain.usesGraphManagedMainSceneColor = true;
plan.colorChain.finalOutput.source =
hasPostProcess
? CameraFrameColorSource::PostProcessColor
: CameraFrameColorSource::MainSceneColor;
plan.finalOutput.destinationSurface = plan.request.surface;
}
if (plan.usesGraphManagedMainSceneColor) {
if (plan.UsesGraphManagedMainSceneColor()) {
plan.ConfigureGraphManagedMainSceneSurface();
}
}

View File

@@ -33,8 +33,8 @@ TEST(CameraFrameRenderGraphStagePolicy_Test, ReportsStageFullscreenAndTransition
TEST(CameraFrameRenderGraphStagePolicy_Test, ReportsGraphManagedOutputColorStagesFromPlan) {
CameraFramePlan plan = {};
plan.usesGraphManagedMainSceneColor = true;
plan.usesGraphManagedPostProcessColor = true;
plan.colorChain.usesGraphManagedMainSceneColor = true;
plan.colorChain.postProcess.usesGraphManagedOutputColor = true;
EXPECT_TRUE(UsesCameraFrameStageGraphManagedOutputColor(plan, CameraFrameStage::MainScene));
EXPECT_TRUE(UsesCameraFrameStageGraphManagedOutputColor(plan, CameraFrameStage::PostProcess));
@@ -71,7 +71,7 @@ TEST(CameraFrameRenderGraphStagePolicy_Test, KeepsExplicitFullscreenSourceBindin
TEST(CameraFrameRenderGraphStagePolicy_Test, ResolvesGraphManagedPostProcessSourceFromBlackboard) {
CameraFramePlan plan = {};
plan.postProcessSource = CameraFrameColorSource::MainSceneColor;
plan.colorChain.postProcess.source = CameraFrameColorSource::MainSceneColor;
RenderGraphBlackboard blackboard = {};
CameraFrameRenderGraphResources& frameResources =
@@ -98,7 +98,7 @@ TEST(CameraFrameRenderGraphStagePolicy_Test, ResolvesGraphManagedPostProcessSour
TEST(CameraFrameRenderGraphStagePolicy_Test, ResolvesGraphManagedFinalOutputSourceFromBlackboard) {
CameraFramePlan plan = {};
plan.finalOutputSource = CameraFrameColorSource::PostProcessColor;
plan.colorChain.finalOutput.source = CameraFrameColorSource::PostProcessColor;
RenderGraphBlackboard blackboard = {};
CameraFrameRenderGraphResources& frameResources =

View File

@@ -1877,11 +1877,11 @@ TEST(CameraRenderer_Test, ResolvesGraphManagedFullscreenSequenceSourcesFromFrame
request.finalOutput.destinationSurface = request.surface;
CameraFramePlan plan = CameraFramePlan::FromRequest(request);
plan.usesGraphManagedMainSceneColor = true;
plan.colorChain.usesGraphManagedMainSceneColor = true;
plan.ConfigureGraphManagedMainSceneSurface();
plan.usesGraphManagedPostProcessColor = true;
plan.postProcessSource = CameraFrameColorSource::MainSceneColor;
plan.finalOutputSource = CameraFrameColorSource::PostProcessColor;
plan.colorChain.postProcess.usesGraphManagedOutputColor = true;
plan.colorChain.postProcess.source = CameraFrameColorSource::MainSceneColor;
plan.colorChain.finalOutput.source = CameraFrameColorSource::PostProcessColor;
ASSERT_TRUE(plan.IsPostProcessStageValid());
ASSERT_TRUE(plan.IsFinalOutputStageValid());
@@ -2877,9 +2877,11 @@ TEST(SceneRenderer_Test, BuildsCameraColorScalePostProcessRequestFromCameraPassS
EXPECT_TRUE(plan.IsPostProcessStageValid());
EXPECT_NE(plan.postProcess.passes, nullptr);
ASSERT_EQ(plan.postProcess.passes->GetPassCount(), 2u);
EXPECT_TRUE(plan.usesGraphManagedMainSceneColor);
EXPECT_FALSE(plan.usesGraphManagedPostProcessColor);
EXPECT_EQ(plan.postProcessSource, CameraFrameColorSource::MainSceneColor);
EXPECT_TRUE(plan.UsesGraphManagedMainSceneColor());
EXPECT_FALSE(plan.UsesGraphManagedOutputColor(CameraFrameStage::PostProcess));
EXPECT_EQ(
plan.ResolveStageColorSource(CameraFrameStage::PostProcess),
CameraFrameColorSource::MainSceneColor);
EXPECT_EQ(plan.postProcess.destinationSurface.GetColorAttachments()[0], backBufferColorView);
EXPECT_EQ(plan.postProcess.destinationSurface.GetDepthAttachment(), depthView);
EXPECT_EQ(
@@ -3015,8 +3017,10 @@ TEST(SceneRenderer_Test, BuildsFinalOutputRequestFromResolvedFinalColorPolicy) {
EXPECT_TRUE(plan.IsFinalOutputStageValid());
ASSERT_NE(plan.finalOutput.passes, nullptr);
EXPECT_EQ(plan.finalOutput.passes->GetPassCount(), 1u);
EXPECT_TRUE(plan.usesGraphManagedMainSceneColor);
EXPECT_EQ(plan.finalOutputSource, CameraFrameColorSource::MainSceneColor);
EXPECT_TRUE(plan.UsesGraphManagedMainSceneColor());
EXPECT_EQ(
plan.ResolveStageColorSource(CameraFrameStage::FinalOutput),
CameraFrameColorSource::MainSceneColor);
EXPECT_EQ(plan.finalOutput.destinationSurface.GetColorAttachments()[0], backBufferColorView);
EXPECT_EQ(plan.finalOutput.destinationSurface.GetDepthAttachment(), depthView);
EXPECT_EQ(
@@ -3106,10 +3110,14 @@ TEST(SceneRenderer_Test, RoutesPostProcessIntoIntermediateSurfaceBeforeFinalOutp
ASSERT_NE(plan.finalOutput.passes, nullptr);
EXPECT_EQ(plan.postProcess.passes->GetPassCount(), 1u);
EXPECT_EQ(plan.finalOutput.passes->GetPassCount(), 1u);
EXPECT_TRUE(plan.usesGraphManagedMainSceneColor);
EXPECT_TRUE(plan.usesGraphManagedPostProcessColor);
EXPECT_EQ(plan.postProcessSource, CameraFrameColorSource::MainSceneColor);
EXPECT_EQ(plan.finalOutputSource, CameraFrameColorSource::PostProcessColor);
EXPECT_TRUE(plan.UsesGraphManagedMainSceneColor());
EXPECT_TRUE(plan.UsesGraphManagedOutputColor(CameraFrameStage::PostProcess));
EXPECT_EQ(
plan.ResolveStageColorSource(CameraFrameStage::PostProcess),
CameraFrameColorSource::MainSceneColor);
EXPECT_EQ(
plan.ResolveStageColorSource(CameraFrameStage::FinalOutput),
CameraFrameColorSource::PostProcessColor);
const CameraFrameStageSourceBinding postProcessSource =
ResolveStageSourceBinding(CameraFrameStage::PostProcess, plan);
@@ -3251,8 +3259,10 @@ TEST(SceneRenderer_Test, KeepsMainSceneGraphManagedWhenPostProcessIsEnabledAcros
renderer.BuildFramePlans(scene, nullptr, context, surface);
ASSERT_EQ(firstFramePlans.size(), 1u);
CameraFramePlan firstFramePlan = firstFramePlans[0];
EXPECT_TRUE(firstFramePlan.usesGraphManagedMainSceneColor);
EXPECT_EQ(firstFramePlan.postProcessSource, CameraFrameColorSource::MainSceneColor);
EXPECT_TRUE(firstFramePlan.UsesGraphManagedMainSceneColor());
EXPECT_EQ(
firstFramePlan.ResolveStageColorSource(CameraFrameStage::PostProcess),
CameraFrameColorSource::MainSceneColor);
EXPECT_EQ(
firstFramePlan.GetMainSceneSurface().GetColorStateBefore(),
XCEngine::RHI::ResourceStates::Common);
@@ -3271,8 +3281,10 @@ TEST(SceneRenderer_Test, KeepsMainSceneGraphManagedWhenPostProcessIsEnabledAcros
renderer.BuildFramePlans(scene, nullptr, context, surface);
ASSERT_EQ(secondFramePlans.size(), 1u);
const CameraFramePlan secondFramePlan = secondFramePlans[0];
EXPECT_TRUE(secondFramePlan.usesGraphManagedMainSceneColor);
EXPECT_EQ(secondFramePlan.postProcessSource, CameraFrameColorSource::MainSceneColor);
EXPECT_TRUE(secondFramePlan.UsesGraphManagedMainSceneColor());
EXPECT_EQ(
secondFramePlan.ResolveStageColorSource(CameraFrameStage::PostProcess),
CameraFrameColorSource::MainSceneColor);
EXPECT_EQ(
secondFramePlan.GetMainSceneSurface().GetColorStateBefore(),
XCEngine::RHI::ResourceStates::Common);
@@ -3334,10 +3346,14 @@ TEST(SceneRenderer_Test, KeepsPostProcessOutputGraphManagedWhenFinalOutputIsEnab
CameraFramePlan firstFramePlan = firstFramePlans[0];
EXPECT_TRUE(firstFramePlans[0].postProcess.IsRequested());
EXPECT_TRUE(firstFramePlans[0].finalOutput.IsRequested());
EXPECT_TRUE(firstFramePlan.usesGraphManagedMainSceneColor);
EXPECT_TRUE(firstFramePlan.usesGraphManagedPostProcessColor);
EXPECT_EQ(firstFramePlan.postProcessSource, CameraFrameColorSource::MainSceneColor);
EXPECT_EQ(firstFramePlan.finalOutputSource, CameraFrameColorSource::PostProcessColor);
EXPECT_TRUE(firstFramePlan.UsesGraphManagedMainSceneColor());
EXPECT_TRUE(firstFramePlan.UsesGraphManagedOutputColor(CameraFrameStage::PostProcess));
EXPECT_EQ(
firstFramePlan.ResolveStageColorSource(CameraFrameStage::PostProcess),
CameraFrameColorSource::MainSceneColor);
EXPECT_EQ(
firstFramePlan.ResolveStageColorSource(CameraFrameStage::FinalOutput),
CameraFrameColorSource::PostProcessColor);
EXPECT_EQ(
firstFramePlan.GetMainSceneSurface().GetColorStateBefore(),
XCEngine::RHI::ResourceStates::Common);
@@ -3362,10 +3378,14 @@ TEST(SceneRenderer_Test, KeepsPostProcessOutputGraphManagedWhenFinalOutputIsEnab
renderer.BuildFramePlans(scene, nullptr, context, surface);
ASSERT_EQ(secondFramePlans.size(), 1u);
const CameraFramePlan secondFramePlan = secondFramePlans[0];
EXPECT_TRUE(secondFramePlan.usesGraphManagedMainSceneColor);
EXPECT_TRUE(secondFramePlan.usesGraphManagedPostProcessColor);
EXPECT_EQ(secondFramePlan.postProcessSource, CameraFrameColorSource::MainSceneColor);
EXPECT_EQ(secondFramePlan.finalOutputSource, CameraFrameColorSource::PostProcessColor);
EXPECT_TRUE(secondFramePlan.UsesGraphManagedMainSceneColor());
EXPECT_TRUE(secondFramePlan.UsesGraphManagedOutputColor(CameraFrameStage::PostProcess));
EXPECT_EQ(
secondFramePlan.ResolveStageColorSource(CameraFrameStage::PostProcess),
CameraFrameColorSource::MainSceneColor);
EXPECT_EQ(
secondFramePlan.ResolveStageColorSource(CameraFrameStage::FinalOutput),
CameraFrameColorSource::PostProcessColor);
EXPECT_EQ(
secondFramePlan.GetMainSceneSurface().GetColorStateBefore(),
XCEngine::RHI::ResourceStates::Common);