2026-04-15 01:00:40 +08:00
|
|
|
#include <XCEngine/Rendering/Execution/CameraFramePlan.h>
|
|
|
|
|
|
|
|
|
|
namespace XCEngine {
|
|
|
|
|
namespace Rendering {
|
|
|
|
|
|
|
|
|
|
RenderSurface CameraFramePlan::BuildGraphManagedIntermediateSurfaceTemplate(
|
|
|
|
|
const RenderSurface& surface) {
|
|
|
|
|
RenderSurface graphManagedSurface = surface;
|
|
|
|
|
graphManagedSurface.SetColorAttachments({});
|
|
|
|
|
graphManagedSurface.SetAutoTransitionEnabled(false);
|
|
|
|
|
graphManagedSurface.SetColorStateBefore(RHI::ResourceStates::Common);
|
|
|
|
|
graphManagedSurface.SetColorStateAfter(RHI::ResourceStates::Common);
|
|
|
|
|
return graphManagedSurface;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CameraFramePlan CameraFramePlan::FromRequest(const CameraRenderRequest& request) {
|
|
|
|
|
CameraFramePlan plan = {};
|
|
|
|
|
plan.request = request;
|
|
|
|
|
plan.shadowCaster = request.shadowCaster;
|
|
|
|
|
plan.directionalShadow = request.directionalShadow;
|
|
|
|
|
plan.postProcess = request.postProcess;
|
|
|
|
|
plan.finalOutput = request.finalOutput;
|
|
|
|
|
plan.finalColorPolicy = request.finalColorPolicy;
|
|
|
|
|
plan.preScenePasses = request.preScenePasses;
|
|
|
|
|
plan.postScenePasses = request.postScenePasses;
|
|
|
|
|
plan.overlayPasses = request.overlayPasses;
|
|
|
|
|
return plan;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool CameraFramePlan::IsValid() const {
|
|
|
|
|
return request.IsValid();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CameraFramePlan::ConfigureGraphManagedMainSceneSurface() {
|
|
|
|
|
graphManagedMainSceneSurface =
|
|
|
|
|
BuildGraphManagedIntermediateSurfaceTemplate(request.surface);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool CameraFramePlan::UsesGraphManagedMainSceneColor() const {
|
|
|
|
|
return colorChain.usesGraphManagedMainSceneColor;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool CameraFramePlan::UsesGraphManagedOutputColor(CameraFrameStage stage) const {
|
|
|
|
|
switch (stage) {
|
|
|
|
|
case CameraFrameStage::PostProcess:
|
|
|
|
|
return colorChain.postProcess.usesGraphManagedOutputColor;
|
|
|
|
|
default:
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CameraFrameColorSource CameraFramePlan::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 CameraFramePlan::IsPostProcessStageValid() const {
|
|
|
|
|
if (!postProcess.IsRequested()) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (ResolveStageColorSource(CameraFrameStage::PostProcess) ==
|
|
|
|
|
CameraFrameColorSource::ExplicitSurface) {
|
|
|
|
|
return postProcess.IsValid();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const bool hasUsableDestination =
|
|
|
|
|
UsesGraphManagedOutputColor(CameraFrameStage::PostProcess) ||
|
|
|
|
|
(HasValidColorTarget(postProcess.destinationSurface) &&
|
|
|
|
|
HasValidSurfaceSampleDescription(postProcess.destinationSurface));
|
|
|
|
|
return UsesGraphManagedMainSceneColor() &&
|
|
|
|
|
postProcess.passes != nullptr &&
|
|
|
|
|
HasValidSingleSampleColorSource(request.surface) &&
|
|
|
|
|
hasUsableDestination;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool CameraFramePlan::IsFinalOutputStageValid() const {
|
|
|
|
|
if (!finalOutput.IsRequested()) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const CameraFrameColorSource finalOutputSource =
|
|
|
|
|
ResolveStageColorSource(CameraFrameStage::FinalOutput);
|
|
|
|
|
if (finalOutputSource == CameraFrameColorSource::ExplicitSurface) {
|
|
|
|
|
return finalOutput.IsValid();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const bool hasUsableSource =
|
|
|
|
|
finalOutputSource == CameraFrameColorSource::MainSceneColor
|
|
|
|
|
? UsesGraphManagedMainSceneColor()
|
|
|
|
|
: UsesGraphManagedOutputColor(CameraFrameStage::PostProcess);
|
|
|
|
|
return hasUsableSource &&
|
|
|
|
|
finalOutput.passes != nullptr &&
|
|
|
|
|
HasValidColorTarget(finalOutput.destinationSurface) &&
|
|
|
|
|
HasValidSurfaceSampleDescription(finalOutput.destinationSurface);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool CameraFramePlan::HasFrameStage(CameraFrameStage stage) const {
|
2026-04-15 15:14:06 +08:00
|
|
|
if (stage == CameraFrameStage::MainScene) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (IsCameraFrameSequenceStage(stage)) {
|
|
|
|
|
return GetPassSequence(stage) != nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
switch (GetCameraFrameStageRequestKind(stage)) {
|
|
|
|
|
case CameraFrameStageRequestKind::ShadowCaster:
|
2026-04-15 01:00:40 +08:00
|
|
|
return shadowCaster.IsRequested() || directionalShadow.IsValid();
|
2026-04-15 15:14:06 +08:00
|
|
|
case CameraFrameStageRequestKind::DepthOnly:
|
2026-04-15 01:00:40 +08:00
|
|
|
return request.depthOnly.IsRequested();
|
2026-04-15 15:14:06 +08:00
|
|
|
case CameraFrameStageRequestKind::ObjectId:
|
2026-04-15 01:00:40 +08:00
|
|
|
return request.objectId.IsRequested();
|
|
|
|
|
default:
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
RenderPassSequence* CameraFramePlan::GetPassSequence(CameraFrameStage stage) const {
|
2026-04-15 15:14:06 +08:00
|
|
|
if (!IsCameraFrameSequenceStage(stage)) {
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-15 01:00:40 +08:00
|
|
|
switch (stage) {
|
|
|
|
|
case CameraFrameStage::PreScenePasses:
|
|
|
|
|
return preScenePasses;
|
|
|
|
|
case CameraFrameStage::PostProcess:
|
|
|
|
|
return postProcess.passes;
|
|
|
|
|
case CameraFrameStage::FinalOutput:
|
|
|
|
|
return finalOutput.passes;
|
|
|
|
|
case CameraFrameStage::PostScenePasses:
|
|
|
|
|
return postScenePasses;
|
|
|
|
|
case CameraFrameStage::OverlayPasses:
|
|
|
|
|
return overlayPasses;
|
|
|
|
|
default:
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const ScenePassRenderRequest* CameraFramePlan::GetScenePassRequest(CameraFrameStage stage) const {
|
2026-04-15 15:14:06 +08:00
|
|
|
switch (GetCameraFrameStageRequestKind(stage)) {
|
|
|
|
|
case CameraFrameStageRequestKind::ShadowCaster:
|
2026-04-15 01:00:40 +08:00
|
|
|
return &shadowCaster;
|
2026-04-15 15:14:06 +08:00
|
|
|
case CameraFrameStageRequestKind::DepthOnly:
|
2026-04-15 01:00:40 +08:00
|
|
|
return &request.depthOnly;
|
|
|
|
|
default:
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const ObjectIdRenderRequest* CameraFramePlan::GetObjectIdRequest(CameraFrameStage stage) const {
|
2026-04-15 15:14:06 +08:00
|
|
|
return GetCameraFrameStageRequestKind(stage) ==
|
|
|
|
|
CameraFrameStageRequestKind::ObjectId
|
|
|
|
|
? &request.objectId
|
|
|
|
|
: nullptr;
|
2026-04-15 01:00:40 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const RenderSurface& CameraFramePlan::GetMainSceneSurface() const {
|
|
|
|
|
if (UsesGraphManagedMainSceneColor() &&
|
|
|
|
|
graphManagedMainSceneSurface.GetWidth() > 0u &&
|
|
|
|
|
graphManagedMainSceneSurface.GetHeight() > 0u) {
|
|
|
|
|
return graphManagedMainSceneSurface;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (postProcess.IsRequested() &&
|
|
|
|
|
HasValidColorTarget(postProcess.sourceSurface)) {
|
|
|
|
|
return postProcess.sourceSurface;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (finalOutput.IsRequested() &&
|
|
|
|
|
HasValidColorTarget(finalOutput.sourceSurface)) {
|
|
|
|
|
return finalOutput.sourceSurface;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return request.surface;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const RenderSurface& CameraFramePlan::GetFinalCompositedSurface() const {
|
|
|
|
|
if (finalOutput.IsRequested() &&
|
|
|
|
|
HasValidColorTarget(finalOutput.destinationSurface)) {
|
|
|
|
|
return finalOutput.destinationSurface;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (postProcess.IsRequested() &&
|
|
|
|
|
HasValidColorTarget(postProcess.destinationSurface)) {
|
|
|
|
|
return postProcess.destinationSurface;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return request.surface;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool CameraFramePlan::RequiresIntermediateSceneColor() const {
|
|
|
|
|
return postProcess.IsRequested() || finalOutput.IsRequested();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} // namespace Rendering
|
|
|
|
|
} // namespace XCEngine
|