Graph-manage camera fullscreen stage routing

This commit is contained in:
2026-04-14 19:32:27 +08:00
parent c4fe643427
commit c710063d92
10 changed files with 337 additions and 440 deletions

View File

@@ -530,6 +530,14 @@ RenderSurface BuildGraphManagedPassSurface(
return surface;
}
struct FullscreenStageGraphBinding {
const RenderSurface* sourceSurfaceTemplate = nullptr;
RHI::RHIResourceView* sourceColorView = nullptr;
RHI::ResourceStates sourceColorState = RHI::ResourceStates::Common;
RenderGraphTextureHandle sourceColor = {};
RenderGraphTextureHandle outputColor = {};
};
const RenderSurface* ResolveFrameStageOutputSurface(
CameraFrameStage stage,
const CameraFramePlan& plan,
@@ -594,6 +602,79 @@ bool CanUseGraphManagedImportedSurface(
return hasAnyTexture;
}
RenderGraphTextureHandle ResolveStageOutputColorHandle(
CameraFrameStage stage,
const CameraFramePlan& plan,
const Containers::String& stageName,
const RenderPassContext& stagePassContext,
const RenderGraphImportedSurface& outputSurface,
RenderGraphBuilder& graphBuilder,
CameraFrameRenderGraphResources& frameResources) {
if (stage == CameraFrameStage::MainScene &&
plan.usesGraphManagedMainSceneColor) {
return graphBuilder.CreateTransientTexture(
stageName + ".Color",
BuildImportedTextureDesc(
stagePassContext.surface,
kRenderGraphImportedColorFormat));
}
if (stage == CameraFrameStage::PostProcess &&
plan.usesGraphManagedPostProcessColor) {
frameResources.postProcessColor =
graphBuilder.CreateTransientTexture(
stageName + ".Color",
BuildFullscreenTransientTextureDesc(stagePassContext.surface));
return frameResources.postProcessColor;
}
return GetPrimaryColorTexture(outputSurface);
}
FullscreenStageGraphBinding ResolveFullscreenStageGraphBinding(
CameraFrameStage stage,
const CameraFramePlan& plan,
const RenderPassContext& stagePassContext,
const RenderGraphImportedSurface& sourceSurface,
RenderGraphTextureHandle outputColor,
CameraFrameRenderGraphResources& frameResources) {
FullscreenStageGraphBinding binding = {};
binding.sourceSurfaceTemplate = stagePassContext.sourceSurface;
binding.sourceColorView = stagePassContext.sourceColorView;
binding.sourceColorState = stagePassContext.sourceColorState;
binding.sourceColor = GetPrimaryColorTexture(sourceSurface);
binding.outputColor = outputColor;
if (stage == CameraFrameStage::PostProcess &&
plan.postProcessSource == CameraFrameColorSource::MainSceneColor) {
binding.sourceSurfaceTemplate = &stagePassContext.surface;
binding.sourceColorView = nullptr;
binding.sourceColorState = RHI::ResourceStates::PixelShaderResource;
binding.sourceColor = frameResources.mainSceneColor;
}
if (stage == CameraFrameStage::FinalOutput) {
if (plan.finalOutputSource == CameraFrameColorSource::MainSceneColor) {
binding.sourceSurfaceTemplate = &stagePassContext.surface;
binding.sourceColorView = nullptr;
binding.sourceColorState = RHI::ResourceStates::PixelShaderResource;
binding.sourceColor = frameResources.mainSceneColor;
} else if (plan.finalOutputSource == CameraFrameColorSource::PostProcessColor) {
binding.sourceSurfaceTemplate = &stagePassContext.surface;
binding.sourceColorView = nullptr;
binding.sourceColorState = RHI::ResourceStates::PixelShaderResource;
binding.sourceColor = frameResources.postProcessColor;
}
}
if (binding.sourceSurfaceTemplate == nullptr &&
binding.sourceColor.IsValid()) {
binding.sourceSurfaceTemplate = &stagePassContext.surface;
}
return binding;
}
RenderPassContext BuildFrameStagePassContext(
CameraFrameStage stage,
const CameraFramePlan& plan,
@@ -736,8 +817,7 @@ bool RecordFullscreenPassSequenceStage(
CameraFrameStage stage,
const Containers::String& stageName,
const RenderPassContext& stagePassContext,
const RenderGraphImportedSurface& sourceSurface,
const RenderGraphImportedSurface& outputSurface,
const FullscreenStageGraphBinding& binding,
const RenderSceneData& sceneData,
RenderPassSequence* stageSequence,
CameraFrameExecutionState& executionState,
@@ -766,10 +846,8 @@ bool RecordFullscreenPassSequenceStage(
return true;
};
RenderGraphTextureHandle currentSourceColor =
GetPrimaryColorTexture(sourceSurface);
const RenderGraphTextureHandle finalOutputColor =
GetPrimaryColorTexture(outputSurface);
RenderGraphTextureHandle currentSourceColor = binding.sourceColor;
const RenderGraphTextureHandle finalOutputColor = binding.outputColor;
const RenderGraphTextureDesc transientDesc =
BuildFullscreenTransientTextureDesc(stagePassContext.surface);
@@ -792,15 +870,15 @@ bool RecordFullscreenPassSequenceStage(
transientDesc);
const RenderSurface* const sourceSurfaceTemplate =
passIndex == 0u
? stagePassContext.sourceSurface
? binding.sourceSurfaceTemplate
: &stagePassContext.surface;
RHI::RHIResourceView* const sourceColorView =
passIndex == 0u
? stagePassContext.sourceColorView
? binding.sourceColorView
: nullptr;
const RHI::ResourceStates sourceColorState =
passIndex == 0u
? stagePassContext.sourceColorState
? binding.sourceColorState
: RHI::ResourceStates::PixelShaderResource;
const RenderPassRenderGraphContext passContext = {
graphBuilder,
@@ -879,6 +957,15 @@ bool ExecuteRenderGraphPlan(
RenderGraphSurfaceImportUsage::Output,
ShouldGraphOwnStageColorTransitions(stage),
ShouldGraphOwnStageDepthTransitions(stage));
const RenderGraphTextureHandle stageOutputColor =
ResolveStageOutputColorHandle(
stage,
plan,
stageName,
stagePassContext,
outputSurface,
graphBuilder,
frameResources);
if (stage == CameraFrameStage::ShadowCaster &&
shadowState.HasShadowSampling() &&
outputSurface.depthTexture.IsValid()) {
@@ -886,11 +973,11 @@ bool ExecuteRenderGraphPlan(
frameResources.mainDirectionalShadow = outputSurface.depthTexture;
}
if (stage == CameraFrameStage::MainScene) {
frameResources.mainSceneColor = GetPrimaryColorTexture(outputSurface);
frameResources.mainSceneColor = stageOutputColor;
frameResources.mainSceneDepth = outputSurface.depthTexture;
}
if (stage == CameraFrameStage::ObjectId) {
frameResources.objectIdColor = GetPrimaryColorTexture(outputSurface);
frameResources.objectIdColor = stageOutputColor;
}
const RenderSurface stageSurfaceTemplate = stagePassContext.surface;
const bool hasStageSourceSurface = stagePassContext.sourceSurface != nullptr;
@@ -908,8 +995,13 @@ bool ExecuteRenderGraphPlan(
stage,
stageName,
stagePassContext,
sourceSurface,
outputSurface,
ResolveFullscreenStageGraphBinding(
stage,
plan,
stagePassContext,
sourceSurface,
stageOutputColor,
frameResources),
sceneData,
stageSequence,
executionState,
@@ -960,7 +1052,7 @@ bool ExecuteRenderGraphPlan(
return true;
};
const RenderPassRenderGraphContext standalonePassContext = {
const RenderPassRenderGraphContext standalonePassContext = {
graphBuilder,
stageName,
plan.request.context,
@@ -970,7 +1062,7 @@ bool ExecuteRenderGraphPlan(
const_cast<RHI::RHIResourceView*>(stageSourceColorView),
stageSourceColorState,
GetPrimaryColorTexture(sourceSurface),
outputSurface.colorTextures,
std::vector<RenderGraphTextureHandle>{ stageOutputColor },
outputSurface.depthTexture,
&stageExecutionSucceeded,
beginStandalonePass,
@@ -999,7 +1091,7 @@ bool ExecuteRenderGraphPlan(
hasStageSourceSurface ? &stageSourceSurfaceTemplate : nullptr,
const_cast<RHI::RHIResourceView*>(stageSourceColorView),
stageSourceColorState,
outputSurface.colorTextures,
std::vector<RenderGraphTextureHandle>{ stageOutputColor },
outputSurface.depthTexture,
mainDirectionalShadowTexture,
&stageExecutionSucceeded,
@@ -1302,14 +1394,21 @@ bool CameraRenderer::Render(
return false;
}
if (plan.postProcess.IsRequested() &&
!plan.postProcess.IsValid()) {
!plan.IsPostProcessStageValid()) {
Debug::Logger::Get().Error(
Debug::LogCategory::Rendering,
"CameraRenderer::Render failed: post-process request invalid");
return false;
}
if (plan.usesGraphManagedMainSceneColor &&
(m_pipeline == nullptr || !m_pipeline->SupportsMainSceneRenderGraph())) {
Debug::Logger::Get().Error(
Debug::LogCategory::Rendering,
"CameraRenderer::Render failed: graph-managed main scene color requires pipeline main-scene render-graph support");
return false;
}
if (plan.finalOutput.IsRequested() &&
!plan.finalOutput.IsValid()) {
!plan.IsFinalOutputStageValid()) {
Debug::Logger::Get().Error(
Debug::LogCategory::Rendering,
"CameraRenderer::Render failed: final-output request invalid");