Graph-ify camera stage render passes

This commit is contained in:
2026-04-14 17:16:08 +08:00
parent 4fe456c1a2
commit 4c79554050
14 changed files with 893 additions and 19 deletions

View File

@@ -309,6 +309,25 @@ bool InitializeStandalonePass(
return false;
}
RenderSceneData BuildScenePassRequestSceneData(
const ScenePassRenderRequest& request,
const RenderSurface& requestSurface,
const RenderSceneData& baseSceneData) {
RenderSceneData sceneData = baseSceneData;
if (request.hasCameraDataOverride) {
sceneData.cameraData = request.cameraDataOverride;
}
sceneData.cameraData.viewportWidth = requestSurface.GetRenderAreaWidth();
sceneData.cameraData.viewportHeight = requestSurface.GetRenderAreaHeight();
sceneData.cameraData.clearFlags = request.clearFlags;
if (request.hasClearColorOverride) {
sceneData.cameraData.clearColor = request.clearColorOverride;
}
return sceneData;
}
bool ExecuteScenePassRequest(
RenderPass* pass,
const ScenePassRenderRequest& request,
@@ -323,19 +342,13 @@ bool ExecuteScenePassRequest(
return false;
}
RenderSceneData sceneData = baseSceneData;
if (request.hasCameraDataOverride) {
sceneData.cameraData = request.cameraDataOverride;
}
const RenderSurface& requestSurface =
surfaceOverride != nullptr ? *surfaceOverride : request.surface;
sceneData.cameraData.viewportWidth = requestSurface.GetRenderAreaWidth();
sceneData.cameraData.viewportHeight = requestSurface.GetRenderAreaHeight();
sceneData.cameraData.clearFlags = request.clearFlags;
if (request.hasClearColorOverride) {
sceneData.cameraData.clearColor = request.clearColorOverride;
}
const RenderSceneData sceneData =
BuildScenePassRequestSceneData(
request,
requestSurface,
baseSceneData);
const RenderPassContext passContext = {
context,
@@ -372,6 +385,31 @@ bool ExecuteStandalonePass(
return pass->Execute(passContext);
}
RenderSceneData BuildStandaloneStageSceneData(
CameraFrameStage stage,
const CameraFramePlan& plan,
const DirectionalShadowExecutionState& shadowState,
const RenderSceneData& baseSceneData,
const RenderSurface& stageSurface) {
if (stage == CameraFrameStage::ShadowCaster &&
shadowState.shadowCasterRequest.IsRequested()) {
return BuildScenePassRequestSceneData(
shadowState.shadowCasterRequest,
stageSurface,
baseSceneData);
}
if (const ScenePassRenderRequest* request = plan.GetScenePassRequest(stage);
request != nullptr) {
return BuildScenePassRequestSceneData(
*request,
stageSurface,
baseSceneData);
}
return baseSceneData;
}
class ScopedInitializedPassSequence {
public:
ScopedInitializedPassSequence(
@@ -439,6 +477,21 @@ struct CameraFrameExecutionState {
std::unique_ptr<ScopedInitializedPassSequence> overlayPasses;
};
RenderPass* ResolveStandaloneStagePass(
CameraFrameStage stage,
CameraFrameExecutionState& executionState) {
switch (stage) {
case CameraFrameStage::ShadowCaster:
return executionState.shadowCasterPass;
case CameraFrameStage::DepthOnly:
return executionState.depthOnlyPass;
case CameraFrameStage::ObjectId:
return executionState.objectIdPass;
default:
return nullptr;
}
}
bool ExecutePassSequenceStage(
std::unique_ptr<ScopedInitializedPassSequence>& activeSequence,
RenderPassSequence* sequence,
@@ -825,9 +878,72 @@ bool ExecuteRenderGraphPlan(
: graphBuilder.CreateTransientTexture(
BuildRenderGraphSequencePassName(stageName, sequencePassIndex) + ".Color",
transientDesc);
RenderPass* const sequencePass =
stageSequence->GetPass(sequencePassIndex);
const Containers::String sequencePassName =
BuildRenderGraphSequencePassName(stageName, sequencePassIndex);
const RenderSurface* const passSourceSurfaceTemplate =
sequencePassIndex == 0u
? stagePassContext.sourceSurface
: &stagePassContext.surface;
RHI::RHIResourceView* const passSourceColorView =
sequencePassIndex == 0u
? stagePassContext.sourceColorView
: nullptr;
const RHI::ResourceStates passSourceColorState =
sequencePassIndex == 0u
? stagePassContext.sourceColorState
: RHI::ResourceStates::PixelShaderResource;
if (sequencePass != nullptr &&
sequencePass->SupportsRenderGraph()) {
const RenderPassGraphBeginCallback beginSequencePass =
[&, stage](const RenderPassContext&) -> bool {
std::unique_ptr<ScopedInitializedPassSequence>& activeSequence =
stage == CameraFrameStage::PostProcess
? executionState.postProcessPasses
: executionState.finalOutputPasses;
if (!EnsureInitializedPassSequence(
activeSequence,
plan.GetPassSequence(stage),
plan.request.context)) {
stageExecutionSucceeded = false;
return false;
}
return true;
};
const RenderPassRenderGraphContext sequencePassContext = {
graphBuilder,
sequencePassName,
plan.request.context,
sceneData,
stagePassContext.surface,
passSourceSurfaceTemplate,
passSourceColorView,
passSourceColorState,
passSourceColor,
std::vector<RenderGraphTextureHandle>{ passOutputColor },
{},
&stageExecutionSucceeded,
beginSequencePass,
{},
&blackboard
};
if (!sequencePass->RecordRenderGraph(sequencePassContext)) {
Debug::Logger::Get().Error(
Debug::LogCategory::Rendering,
Containers::String("CameraRenderer::Render failed: RenderPass::RecordRenderGraph returned false for ") +
sequencePassName);
return false;
}
currentSourceColor = passOutputColor;
continue;
}
graphBuilder.AddRasterPass(
BuildRenderGraphSequencePassName(stageName, sequencePassIndex),
sequencePassName,
[&, stage, sequencePassIndex, passSourceColor, passOutputColor](
RenderGraphPassBuilder& passBuilder) {
if (passSourceColor.IsValid()) {
@@ -917,6 +1033,55 @@ bool ExecuteRenderGraphPlan(
const RHI::RHIResourceView* const stageSourceColorView = stagePassContext.sourceColorView;
const RHI::ResourceStates stageSourceColorState = stagePassContext.sourceColorState;
RenderPass* const standaloneStagePass =
ResolveStandaloneStagePass(stage, executionState);
if (standaloneStagePass != nullptr &&
standaloneStagePass->SupportsRenderGraph()) {
const RenderSceneData stageSceneData =
BuildStandaloneStageSceneData(
stage,
plan,
shadowState,
sceneData,
stageSurfaceTemplate);
const RenderPassGraphBeginCallback beginStandalonePass =
[&, standaloneStagePass](const RenderPassContext&) -> bool {
if (!InitializeStandalonePass(
standaloneStagePass,
plan.request.context)) {
stageExecutionSucceeded = false;
return false;
}
return true;
};
const RenderPassRenderGraphContext standalonePassContext = {
graphBuilder,
stageName,
plan.request.context,
stageSceneData,
stageSurfaceTemplate,
hasStageSourceSurface ? &stageSourceSurfaceTemplate : nullptr,
const_cast<RHI::RHIResourceView*>(stageSourceColorView),
stageSourceColorState,
GetPrimaryColorTexture(sourceSurface),
outputSurface.colorTextures,
outputSurface.depthTexture,
&stageExecutionSucceeded,
beginStandalonePass,
{},
&blackboard
};
if (!standaloneStagePass->RecordRenderGraph(standalonePassContext)) {
Debug::Logger::Get().Error(
Debug::LogCategory::Rendering,
Containers::String("CameraRenderer::Render failed: RenderPass::RecordRenderGraph returned false for ") +
stageName);
return false;
}
continue;
}
if (stage == CameraFrameStage::MainScene &&
executionState.pipeline != nullptr &&
executionState.pipeline->SupportsMainSceneRenderGraph()) {