Graph-ify camera pass sequences
This commit is contained in:
@@ -6,6 +6,7 @@
|
||||
#include "Rendering/Graph/RenderGraph.h"
|
||||
#include "Rendering/Graph/RenderGraphCompiler.h"
|
||||
#include "Rendering/Graph/RenderGraphExecutor.h"
|
||||
#include "Rendering/Internal/RenderPassGraphUtils.h"
|
||||
#include "Rendering/Passes/BuiltinDepthOnlyPass.h"
|
||||
#include "Rendering/Passes/BuiltinObjectIdPass.h"
|
||||
#include "Rendering/Passes/BuiltinShadowCasterPass.h"
|
||||
@@ -492,6 +493,34 @@ RenderPass* ResolveStandaloneStagePass(
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<ScopedInitializedPassSequence>* ResolveStageSequenceState(
|
||||
CameraFrameStage stage,
|
||||
CameraFrameExecutionState& executionState) {
|
||||
switch (stage) {
|
||||
case CameraFrameStage::PreScenePasses:
|
||||
return &executionState.preScenePasses;
|
||||
case CameraFrameStage::PostProcess:
|
||||
return &executionState.postProcessPasses;
|
||||
case CameraFrameStage::FinalOutput:
|
||||
return &executionState.finalOutputPasses;
|
||||
case CameraFrameStage::PostScenePasses:
|
||||
return &executionState.postScenePasses;
|
||||
case CameraFrameStage::OverlayPasses:
|
||||
return &executionState.overlayPasses;
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
bool RecordSequencePass(
|
||||
RenderPass& pass,
|
||||
const RenderPassRenderGraphContext& context,
|
||||
const Internal::RenderPassGraphIO& io) {
|
||||
return pass.SupportsRenderGraph()
|
||||
? pass.RecordRenderGraph(context)
|
||||
: Internal::RecordRasterRenderPass(pass, context, io);
|
||||
}
|
||||
|
||||
bool ExecutePassSequenceStage(
|
||||
std::unique_ptr<ScopedInitializedPassSequence>& activeSequence,
|
||||
RenderPassSequence* sequence,
|
||||
@@ -817,6 +846,187 @@ bool ExecuteFrameStage(
|
||||
}
|
||||
}
|
||||
|
||||
bool RecordRegularPassSequenceStage(
|
||||
CameraFrameStage stage,
|
||||
const Containers::String& stageName,
|
||||
const RenderPassContext& stagePassContext,
|
||||
const RenderGraphImportedSurface& outputSurface,
|
||||
const RenderSceneData& sceneData,
|
||||
RenderPassSequence* stageSequence,
|
||||
CameraFrameExecutionState& executionState,
|
||||
RenderGraphBuilder& graphBuilder,
|
||||
RenderGraphBlackboard& blackboard,
|
||||
bool& stageExecutionSucceeded) {
|
||||
if (stageSequence == nullptr || stageSequence->GetPassCount() == 0u) {
|
||||
return true;
|
||||
}
|
||||
|
||||
std::unique_ptr<ScopedInitializedPassSequence>* const activeSequence =
|
||||
ResolveStageSequenceState(stage, executionState);
|
||||
RenderPassSequence* const sequence = stageSequence;
|
||||
const RenderContext* const renderContext = &stagePassContext.renderContext;
|
||||
const RenderPassGraphBeginCallback beginSequencePass =
|
||||
[&, activeSequence, sequence, renderContext](const RenderPassContext&) -> bool {
|
||||
if (activeSequence == nullptr ||
|
||||
!EnsureInitializedPassSequence(
|
||||
*activeSequence,
|
||||
sequence,
|
||||
*renderContext)) {
|
||||
stageExecutionSucceeded = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
const bool writesColor = GetPrimaryColorTexture(outputSurface).IsValid();
|
||||
const bool writesDepth = outputSurface.depthTexture.IsValid();
|
||||
|
||||
for (size_t passIndex = 0u; passIndex < stageSequence->GetPassCount(); ++passIndex) {
|
||||
RenderPass* const pass = stageSequence->GetPass(passIndex);
|
||||
if (pass == nullptr) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const Containers::String passName =
|
||||
stageSequence->GetPassCount() == 1u
|
||||
? stageName
|
||||
: BuildRenderGraphSequencePassName(stageName, passIndex);
|
||||
const RenderPassRenderGraphContext passContext = {
|
||||
graphBuilder,
|
||||
passName,
|
||||
stagePassContext.renderContext,
|
||||
sceneData,
|
||||
stagePassContext.surface,
|
||||
stagePassContext.sourceSurface,
|
||||
stagePassContext.sourceColorView,
|
||||
stagePassContext.sourceColorState,
|
||||
{},
|
||||
outputSurface.colorTextures,
|
||||
outputSurface.depthTexture,
|
||||
&stageExecutionSucceeded,
|
||||
beginSequencePass,
|
||||
{},
|
||||
&blackboard
|
||||
};
|
||||
if (!RecordSequencePass(
|
||||
*pass,
|
||||
passContext,
|
||||
{
|
||||
false,
|
||||
writesColor,
|
||||
writesDepth
|
||||
})) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RecordFullscreenPassSequenceStage(
|
||||
CameraFrameStage stage,
|
||||
const Containers::String& stageName,
|
||||
const RenderPassContext& stagePassContext,
|
||||
const RenderGraphImportedSurface& sourceSurface,
|
||||
const RenderGraphImportedSurface& outputSurface,
|
||||
const RenderSceneData& sceneData,
|
||||
RenderPassSequence* stageSequence,
|
||||
CameraFrameExecutionState& executionState,
|
||||
RenderGraphBuilder& graphBuilder,
|
||||
RenderGraphBlackboard& blackboard,
|
||||
bool& stageExecutionSucceeded) {
|
||||
if (stageSequence == nullptr || stageSequence->GetPassCount() == 0u) {
|
||||
return true;
|
||||
}
|
||||
|
||||
std::unique_ptr<ScopedInitializedPassSequence>* const activeSequence =
|
||||
ResolveStageSequenceState(stage, executionState);
|
||||
RenderPassSequence* const sequence = stageSequence;
|
||||
const RenderContext* const renderContext = &stagePassContext.renderContext;
|
||||
const RenderPassGraphBeginCallback beginSequencePass =
|
||||
[&, activeSequence, sequence, renderContext](const RenderPassContext&) -> bool {
|
||||
if (activeSequence == nullptr ||
|
||||
!EnsureInitializedPassSequence(
|
||||
*activeSequence,
|
||||
sequence,
|
||||
*renderContext)) {
|
||||
stageExecutionSucceeded = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
RenderGraphTextureHandle currentSourceColor =
|
||||
GetPrimaryColorTexture(sourceSurface);
|
||||
const RenderGraphTextureHandle finalOutputColor =
|
||||
GetPrimaryColorTexture(outputSurface);
|
||||
const RenderGraphTextureDesc transientDesc =
|
||||
BuildFullscreenTransientTextureDesc(stagePassContext.surface);
|
||||
|
||||
for (size_t passIndex = 0u; passIndex < stageSequence->GetPassCount(); ++passIndex) {
|
||||
RenderPass* const pass = stageSequence->GetPass(passIndex);
|
||||
if (pass == nullptr) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const bool isLastPass = (passIndex + 1u) == stageSequence->GetPassCount();
|
||||
const Containers::String passName =
|
||||
stageSequence->GetPassCount() == 1u
|
||||
? stageName
|
||||
: BuildRenderGraphSequencePassName(stageName, passIndex);
|
||||
const RenderGraphTextureHandle passOutputColor =
|
||||
isLastPass
|
||||
? finalOutputColor
|
||||
: graphBuilder.CreateTransientTexture(
|
||||
passName + ".Color",
|
||||
transientDesc);
|
||||
const RenderSurface* const sourceSurfaceTemplate =
|
||||
passIndex == 0u
|
||||
? stagePassContext.sourceSurface
|
||||
: &stagePassContext.surface;
|
||||
RHI::RHIResourceView* const sourceColorView =
|
||||
passIndex == 0u
|
||||
? stagePassContext.sourceColorView
|
||||
: nullptr;
|
||||
const RHI::ResourceStates sourceColorState =
|
||||
passIndex == 0u
|
||||
? stagePassContext.sourceColorState
|
||||
: RHI::ResourceStates::PixelShaderResource;
|
||||
const RenderPassRenderGraphContext passContext = {
|
||||
graphBuilder,
|
||||
passName,
|
||||
stagePassContext.renderContext,
|
||||
sceneData,
|
||||
stagePassContext.surface,
|
||||
sourceSurfaceTemplate,
|
||||
sourceColorView,
|
||||
sourceColorState,
|
||||
currentSourceColor,
|
||||
std::vector<RenderGraphTextureHandle>{ passOutputColor },
|
||||
{},
|
||||
&stageExecutionSucceeded,
|
||||
beginSequencePass,
|
||||
{},
|
||||
&blackboard
|
||||
};
|
||||
if (!RecordSequencePass(
|
||||
*pass,
|
||||
passContext,
|
||||
{
|
||||
true,
|
||||
true,
|
||||
false
|
||||
})) {
|
||||
return false;
|
||||
}
|
||||
|
||||
currentSourceColor = passOutputColor;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ExecuteRenderGraphPlan(
|
||||
const CameraFramePlan& plan,
|
||||
const DirectionalShadowExecutionState& shadowState,
|
||||
@@ -841,157 +1051,6 @@ bool ExecuteRenderGraphPlan(
|
||||
const Containers::String stageName(GetCameraFrameStageName(stageInfo.stage));
|
||||
RenderPassSequence* const stageSequence = plan.GetPassSequence(stage);
|
||||
|
||||
if (IsFullscreenSequenceStage(stage) &&
|
||||
stageSequence != nullptr &&
|
||||
stageSequence->GetPassCount() > 1u) {
|
||||
const RenderPassContext stagePassContext =
|
||||
BuildFrameStagePassContext(stage, plan, shadowState, sceneData);
|
||||
const RenderGraphImportedSurface sourceSurface =
|
||||
ImportRenderGraphSurface(
|
||||
graphBuilder,
|
||||
importedTextures,
|
||||
stageName + ".Source",
|
||||
stagePassContext.sourceSurface,
|
||||
RenderGraphSurfaceImportUsage::Source,
|
||||
true);
|
||||
const RenderGraphImportedSurface outputSurface =
|
||||
ImportRenderGraphSurface(
|
||||
graphBuilder,
|
||||
importedTextures,
|
||||
stageName + ".Output",
|
||||
&stagePassContext.surface,
|
||||
RenderGraphSurfaceImportUsage::Output,
|
||||
true);
|
||||
RenderGraphTextureHandle currentSourceColor = GetPrimaryColorTexture(sourceSurface);
|
||||
const RenderGraphTextureHandle finalOutputColor =
|
||||
GetPrimaryColorTexture(outputSurface);
|
||||
const RenderGraphTextureDesc transientDesc =
|
||||
BuildFullscreenTransientTextureDesc(stagePassContext.surface);
|
||||
|
||||
for (size_t passIndex = 0; passIndex < stageSequence->GetPassCount(); ++passIndex) {
|
||||
const bool isLastPass = (passIndex + 1u) == stageSequence->GetPassCount();
|
||||
const size_t sequencePassIndex = passIndex;
|
||||
const RenderGraphTextureHandle passSourceColor = currentSourceColor;
|
||||
const RenderGraphTextureHandle passOutputColor =
|
||||
isLastPass
|
||||
? finalOutputColor
|
||||
: 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(
|
||||
sequencePassName,
|
||||
[&, stage, sequencePassIndex, passSourceColor, passOutputColor](
|
||||
RenderGraphPassBuilder& passBuilder) {
|
||||
if (passSourceColor.IsValid()) {
|
||||
passBuilder.ReadTexture(passSourceColor);
|
||||
}
|
||||
if (passOutputColor.IsValid()) {
|
||||
passBuilder.WriteTexture(passOutputColor);
|
||||
}
|
||||
passBuilder.SetExecuteCallback(
|
||||
[&, stage, sequencePassIndex, passSourceColor, passOutputColor](
|
||||
const RenderGraphExecutionContext& executionContext) {
|
||||
if (!stageExecutionSucceeded) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::unique_ptr<ScopedInitializedPassSequence>& activeSequence =
|
||||
stage == CameraFrameStage::PostProcess
|
||||
? executionState.postProcessPasses
|
||||
: executionState.finalOutputPasses;
|
||||
if (!EnsureInitializedPassSequence(
|
||||
activeSequence,
|
||||
plan.GetPassSequence(stage),
|
||||
plan.request.context)) {
|
||||
stageExecutionSucceeded = false;
|
||||
return;
|
||||
}
|
||||
|
||||
stageExecutionSucceeded =
|
||||
ExecuteFullscreenPassSequencePass(
|
||||
plan.GetPassSequence(stage),
|
||||
sequencePassIndex,
|
||||
BuildFrameStagePassContext(
|
||||
stage,
|
||||
plan,
|
||||
shadowState,
|
||||
sceneData),
|
||||
executionContext,
|
||||
passSourceColor,
|
||||
passOutputColor);
|
||||
});
|
||||
});
|
||||
|
||||
currentSourceColor = passOutputColor;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
const RenderPassContext stagePassContext =
|
||||
BuildFrameStagePassContext(stage, plan, shadowState, sceneData);
|
||||
const RenderGraphImportedSurface sourceSurface =
|
||||
@@ -1033,6 +1092,43 @@ bool ExecuteRenderGraphPlan(
|
||||
const RHI::RHIResourceView* const stageSourceColorView = stagePassContext.sourceColorView;
|
||||
const RHI::ResourceStates stageSourceColorState = stagePassContext.sourceColorState;
|
||||
|
||||
if (stageSequence != nullptr) {
|
||||
const bool recordResult =
|
||||
IsFullscreenSequenceStage(stage)
|
||||
? RecordFullscreenPassSequenceStage(
|
||||
stage,
|
||||
stageName,
|
||||
stagePassContext,
|
||||
sourceSurface,
|
||||
outputSurface,
|
||||
sceneData,
|
||||
stageSequence,
|
||||
executionState,
|
||||
graphBuilder,
|
||||
blackboard,
|
||||
stageExecutionSucceeded)
|
||||
: RecordRegularPassSequenceStage(
|
||||
stage,
|
||||
stageName,
|
||||
stagePassContext,
|
||||
outputSurface,
|
||||
sceneData,
|
||||
stageSequence,
|
||||
executionState,
|
||||
graphBuilder,
|
||||
blackboard,
|
||||
stageExecutionSucceeded);
|
||||
if (!recordResult) {
|
||||
Debug::Logger::Get().Error(
|
||||
Debug::LogCategory::Rendering,
|
||||
Containers::String("CameraRenderer::Render failed: pass-sequence graph recording returned false for ") +
|
||||
stageName);
|
||||
return false;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
RenderPass* const standaloneStagePass =
|
||||
ResolveStandaloneStagePass(stage, executionState);
|
||||
if (standaloneStagePass != nullptr &&
|
||||
|
||||
Reference in New Issue
Block a user