feat(rendering): add managed fullscreen stage planning seam

This commit is contained in:
2026-04-17 23:39:08 +08:00
parent 4a4e921eb1
commit 6838b00d97
16 changed files with 935 additions and 18 deletions

View File

@@ -3,6 +3,42 @@
namespace XCEngine {
namespace Rendering {
namespace {
CameraFrameFullscreenStagePlan* GetMutableFullscreenStagePlan(
CameraFramePlan& plan,
CameraFrameStage stage) {
switch (stage) {
case CameraFrameStage::PostProcess:
return &plan.colorChain.postProcess;
case CameraFrameStage::FinalOutput:
return &plan.colorChain.finalOutput;
default:
return nullptr;
}
}
FullscreenPassRenderRequest* GetMutableFullscreenPassRequest(
CameraFramePlan& plan,
CameraFrameStage stage) {
switch (stage) {
case CameraFrameStage::PostProcess:
return &plan.postProcess;
case CameraFrameStage::FinalOutput:
return &plan.finalOutput;
default:
return nullptr;
}
}
bool DoesStageNeedGraphManagedSceneColor(
const CameraFrameFullscreenStagePlan& stagePlan) {
return stagePlan.requested &&
stagePlan.source == CameraFrameColorSource::MainSceneColor;
}
} // namespace
RenderSurface CameraFramePlan::BuildGraphManagedIntermediateSurfaceTemplate(
const RenderSurface& surface) {
RenderSurface graphManagedSurface = surface;
@@ -24,6 +60,8 @@ CameraFramePlan CameraFramePlan::FromRequest(const CameraRenderRequest& request)
plan.preScenePasses = request.preScenePasses;
plan.postScenePasses = request.postScenePasses;
plan.overlayPasses = request.overlayPasses;
plan.colorChain.postProcess.requested = request.postProcess.IsRequested();
plan.colorChain.finalOutput.requested = request.finalOutput.IsRequested();
return plan;
}
@@ -98,28 +136,96 @@ CameraFrameColorSource CameraFramePlan::ResolveStageColorSource(CameraFrameStage
return CameraFrameColorSource::ExplicitSurface;
}
bool CameraFramePlan::IsFullscreenStageRequested(CameraFrameStage stage) const {
if (const CameraFrameFullscreenStagePlan* fullscreenStagePlan =
GetFullscreenStagePlan(stage);
fullscreenStagePlan != nullptr) {
return fullscreenStagePlan->requested;
}
return false;
}
bool CameraFramePlan::RequestFullscreenStage(
CameraFrameStage stage,
CameraFrameColorSource source,
bool usesGraphManagedOutputColor) {
CameraFrameFullscreenStagePlan* const fullscreenStagePlan =
GetMutableFullscreenStagePlan(*this, stage);
FullscreenPassRenderRequest* const fullscreenRequest =
GetMutableFullscreenPassRequest(*this, stage);
if (fullscreenStagePlan == nullptr || fullscreenRequest == nullptr) {
return false;
}
fullscreenStagePlan->requested = true;
fullscreenStagePlan->source = source;
fullscreenStagePlan->usesGraphManagedOutputColor =
stage == CameraFrameStage::PostProcess
? usesGraphManagedOutputColor
: false;
if (source != CameraFrameColorSource::ExplicitSurface) {
fullscreenRequest->sourceSurface = {};
fullscreenRequest->sourceColorView = nullptr;
fullscreenRequest->sourceColorState = RHI::ResourceStates::Common;
}
if (stage == CameraFrameStage::PostProcess) {
fullscreenRequest->destinationSurface =
fullscreenStagePlan->usesGraphManagedOutputColor
? RenderSurface{}
: request.surface;
} else {
fullscreenRequest->destinationSurface = request.surface;
}
RefreshGraphManagedSceneSurfaceState();
return true;
}
void CameraFramePlan::ClearFullscreenStage(CameraFrameStage stage) {
if (stage == CameraFrameStage::PostProcess) {
ClearOwnedPostProcessSequence();
postProcess = {};
colorChain.postProcess = {};
} else if (stage == CameraFrameStage::FinalOutput) {
ClearOwnedFinalOutputSequence();
finalOutput = {};
colorChain.finalOutput = {};
} else {
return;
}
RefreshGraphManagedSceneSurfaceState();
}
bool CameraFramePlan::IsPostProcessStageValid() const {
if (!postProcess.IsRequested()) {
if (!IsFullscreenStageRequested(CameraFrameStage::PostProcess)) {
return true;
}
if (ResolveStageColorSource(CameraFrameStage::PostProcess) ==
CameraFrameColorSource::ExplicitSurface) {
const CameraFrameColorSource postProcessSource =
ResolveStageColorSource(CameraFrameStage::PostProcess);
if (postProcessSource == CameraFrameColorSource::ExplicitSurface) {
return postProcess.IsValid();
}
if (postProcessSource != CameraFrameColorSource::MainSceneColor) {
return false;
}
const bool hasUsableDestination =
UsesGraphManagedOutputColor(CameraFrameStage::PostProcess) ||
(HasValidColorTarget(postProcess.destinationSurface) &&
HasValidSurfaceSampleDescription(postProcess.destinationSurface));
return UsesGraphManagedOutputColor(CameraFrameStage::MainScene) &&
postProcess.passes != nullptr &&
HasValidSingleSampleColorSource(request.surface) &&
hasUsableDestination;
}
bool CameraFramePlan::IsFinalOutputStageValid() const {
if (!finalOutput.IsRequested()) {
if (!IsFullscreenStageRequested(CameraFrameStage::FinalOutput)) {
return true;
}
@@ -134,7 +240,6 @@ bool CameraFramePlan::IsFinalOutputStageValid() const {
? UsesGraphManagedOutputColor(CameraFrameStage::MainScene)
: UsesGraphManagedOutputColor(CameraFrameStage::PostProcess);
return hasUsableSource &&
finalOutput.passes != nullptr &&
HasValidColorTarget(finalOutput.destinationSurface) &&
HasValidSurfaceSampleDescription(finalOutput.destinationSurface);
}
@@ -145,6 +250,10 @@ bool CameraFramePlan::HasFrameStage(CameraFrameStage stage) const {
}
if (IsCameraFrameSequenceStage(stage)) {
if (IsCameraFrameFullscreenSequenceStage(stage)) {
return IsFullscreenStageRequested(stage);
}
if (const FullscreenPassRenderRequest* fullscreenRequest =
GetFullscreenPassRequest(stage);
fullscreenRequest != nullptr) {
@@ -248,12 +357,12 @@ const RenderSurface& CameraFramePlan::GetMainSceneSurface() const {
return graphManagedSceneSurface;
}
if (postProcess.IsRequested() &&
if (IsFullscreenStageRequested(CameraFrameStage::PostProcess) &&
HasValidColorTarget(postProcess.sourceSurface)) {
return postProcess.sourceSurface;
}
if (finalOutput.IsRequested() &&
if (IsFullscreenStageRequested(CameraFrameStage::FinalOutput) &&
HasValidColorTarget(finalOutput.sourceSurface)) {
return finalOutput.sourceSurface;
}
@@ -262,12 +371,12 @@ const RenderSurface& CameraFramePlan::GetMainSceneSurface() const {
}
const RenderSurface& CameraFramePlan::GetFinalCompositedSurface() const {
if (finalOutput.IsRequested() &&
if (IsFullscreenStageRequested(CameraFrameStage::FinalOutput) &&
HasValidColorTarget(finalOutput.destinationSurface)) {
return finalOutput.destinationSurface;
}
if (postProcess.IsRequested() &&
if (IsFullscreenStageRequested(CameraFrameStage::PostProcess) &&
HasValidColorTarget(postProcess.destinationSurface)) {
return postProcess.destinationSurface;
}
@@ -276,7 +385,20 @@ const RenderSurface& CameraFramePlan::GetFinalCompositedSurface() const {
}
bool CameraFramePlan::RequiresIntermediateSceneColor() const {
return postProcess.IsRequested() || finalOutput.IsRequested();
return IsFullscreenStageRequested(CameraFrameStage::PostProcess) ||
IsFullscreenStageRequested(CameraFrameStage::FinalOutput);
}
void CameraFramePlan::RefreshGraphManagedSceneSurfaceState() {
colorChain.usesGraphManagedSceneColor =
DoesStageNeedGraphManagedSceneColor(colorChain.postProcess) ||
DoesStageNeedGraphManagedSceneColor(colorChain.finalOutput);
if (colorChain.usesGraphManagedSceneColor) {
ConfigureGraphManagedSceneSurface();
} else {
graphManagedSceneSurface = {};
}
}
} // namespace Rendering