feat(rendering): expose builtin forward scene steps to srp context
This commit is contained in:
243
engine/src/Rendering/Pipelines/BuiltinForwardSceneRecorder.cpp
Normal file
243
engine/src/Rendering/Pipelines/BuiltinForwardSceneRecorder.cpp
Normal file
@@ -0,0 +1,243 @@
|
||||
#include <XCEngine/Rendering/Pipelines/BuiltinForwardSceneRecorder.h>
|
||||
|
||||
#include "Debug/Logger.h"
|
||||
#include "Rendering/Pipelines/Internal/BuiltinForwardSceneSetup.h"
|
||||
|
||||
#include <XCEngine/Rendering/Execution/CameraFrameRenderGraphFrameData.h>
|
||||
#include <XCEngine/Rendering/Graph/RenderGraphRecordingContext.h>
|
||||
#include <XCEngine/Rendering/Pipelines/BuiltinForwardPipeline.h>
|
||||
#include <XCEngine/Rendering/RenderPipelineStageGraphContract.h>
|
||||
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
namespace XCEngine {
|
||||
namespace Rendering {
|
||||
namespace Pipelines {
|
||||
|
||||
struct BuiltinForwardSceneRecorderState {
|
||||
bool initialized = false;
|
||||
};
|
||||
|
||||
namespace {
|
||||
|
||||
bool ScenePhaseSamplesMainDirectionalShadow(ScenePhase scenePhase) {
|
||||
return scenePhase == ScenePhase::Opaque ||
|
||||
scenePhase == ScenePhase::Transparent;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
BuiltinForwardSceneRecorder::BuiltinForwardSceneRecorder(
|
||||
BuiltinForwardPipeline& pipeline,
|
||||
const RenderPipelineStageRenderGraphContext& context)
|
||||
: m_pipeline(pipeline)
|
||||
, m_context(context)
|
||||
, m_graphManagedSurface(
|
||||
BuildRenderGraphManagedSurfaceTemplate(context.surfaceTemplate))
|
||||
, m_state(std::make_shared<BuiltinForwardSceneRecorderState>()) {
|
||||
const CameraFrameRenderGraphResources* const frameResources =
|
||||
TryGetCameraFrameRenderGraphResources(context.blackboard);
|
||||
if (frameResources != nullptr) {
|
||||
m_mainDirectionalShadowTexture = frameResources->mainDirectionalShadow;
|
||||
}
|
||||
}
|
||||
|
||||
BuiltinForwardSceneRecorder::~BuiltinForwardSceneRecorder() = default;
|
||||
|
||||
SceneRenderFeaturePassBeginCallback
|
||||
BuiltinForwardSceneRecorder::BuildBeginRecordedPassCallback(
|
||||
bool* executionSucceeded) const {
|
||||
BuiltinForwardPipeline& pipeline = m_pipeline;
|
||||
const std::shared_ptr<BuiltinForwardSceneRecorderState> state = m_state;
|
||||
return [&pipeline, state, executionSucceeded](
|
||||
const RenderPassContext& passContext,
|
||||
bool clearAttachments) -> bool {
|
||||
if (executionSucceeded != nullptr &&
|
||||
!(*executionSucceeded)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!state->initialized) {
|
||||
if (!pipeline.Initialize(passContext.renderContext)) {
|
||||
Debug::Logger::Get().Error(
|
||||
Debug::LogCategory::Rendering,
|
||||
"BuiltinForwardSceneRecorder failed during execution: Initialize returned false");
|
||||
if (executionSucceeded != nullptr) {
|
||||
*executionSucceeded = false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
const FrameExecutionContext executionContext(
|
||||
passContext.renderContext,
|
||||
passContext.surface,
|
||||
passContext.sceneData,
|
||||
passContext.sourceSurface,
|
||||
passContext.sourceColorView,
|
||||
passContext.sourceColorState);
|
||||
if (!pipeline.m_forwardSceneFeatureHost.Prepare(executionContext)) {
|
||||
Debug::Logger::Get().Error(
|
||||
Debug::LogCategory::Rendering,
|
||||
"BuiltinForwardSceneRecorder failed during execution: SceneRenderFeatureHost::Prepare returned false");
|
||||
if (executionSucceeded != nullptr) {
|
||||
*executionSucceeded = false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
state->initialized = true;
|
||||
}
|
||||
|
||||
if (!pipeline.BeginForwardScenePass(
|
||||
passContext,
|
||||
clearAttachments)) {
|
||||
Debug::Logger::Get().Error(
|
||||
Debug::LogCategory::Rendering,
|
||||
"BuiltinForwardSceneRecorder failed during execution: BeginForwardScenePass returned false");
|
||||
if (executionSucceeded != nullptr) {
|
||||
*executionSucceeded = false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
}
|
||||
|
||||
SceneRenderFeaturePassEndCallback
|
||||
BuiltinForwardSceneRecorder::BuildEndRecordedPassCallback() const {
|
||||
BuiltinForwardPipeline& pipeline = m_pipeline;
|
||||
return [&pipeline](const RenderPassContext& passContext) {
|
||||
pipeline.EndForwardScenePass(passContext);
|
||||
};
|
||||
}
|
||||
|
||||
bool BuiltinForwardSceneRecorder::RecordDefaultScene() {
|
||||
if (m_context.stage != CameraFrameStage::MainScene) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (const Internal::ForwardSceneStep& step :
|
||||
Internal::GetBuiltinForwardSceneSteps()) {
|
||||
if (step.type == Internal::ForwardSceneStepType::InjectionPoint) {
|
||||
if (!RecordInjectionPoint(step.injectionPoint)) {
|
||||
return false;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!RecordScenePhase(step.scenePhase)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BuiltinForwardSceneRecorder::RecordScenePhase(
|
||||
ScenePhase scenePhase) {
|
||||
if (m_context.stage != CameraFrameStage::MainScene) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const RenderPipelineStageRenderGraphContext graphContext =
|
||||
BuildGraphContext();
|
||||
const bool clearAttachments = m_clearAttachments;
|
||||
const SceneRenderFeaturePassBeginCallback beginRecordedPass =
|
||||
BuildBeginRecordedPassCallback(graphContext.executionSucceeded);
|
||||
const SceneRenderFeaturePassEndCallback endRecordedPass =
|
||||
BuildEndRecordedPassCallback();
|
||||
const RenderPassGraphBeginCallback beginPhasePass =
|
||||
[beginRecordedPass, clearAttachments](
|
||||
const RenderPassContext& passContext) {
|
||||
return beginRecordedPass(
|
||||
passContext,
|
||||
clearAttachments);
|
||||
};
|
||||
const std::vector<RenderGraphTextureHandle> additionalReadTextures =
|
||||
ScenePhaseSamplesMainDirectionalShadow(scenePhase) &&
|
||||
m_mainDirectionalShadowTexture.IsValid()
|
||||
? std::vector<RenderGraphTextureHandle>{ m_mainDirectionalShadowTexture }
|
||||
: std::vector<RenderGraphTextureHandle>{};
|
||||
if (!::XCEngine::Rendering::RecordRenderPipelineStagePhasePass(
|
||||
graphContext,
|
||||
scenePhase,
|
||||
[&pipeline = m_pipeline, scenePhase](
|
||||
const RenderPassContext& passContext) {
|
||||
const FrameExecutionContext executionContext(
|
||||
passContext.renderContext,
|
||||
passContext.surface,
|
||||
passContext.sceneData,
|
||||
passContext.sourceSurface,
|
||||
passContext.sourceColorView,
|
||||
passContext.sourceColorState);
|
||||
const ScenePhaseExecutionContext scenePhaseExecutionContext =
|
||||
pipeline.BuildScenePhaseExecutionContext(
|
||||
executionContext,
|
||||
scenePhase);
|
||||
return pipeline.ExecuteBuiltinScenePhase(
|
||||
scenePhaseExecutionContext);
|
||||
},
|
||||
beginPhasePass,
|
||||
endRecordedPass,
|
||||
additionalReadTextures)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
m_clearAttachments = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BuiltinForwardSceneRecorder::RecordInjectionPoint(
|
||||
SceneRenderInjectionPoint injectionPoint) {
|
||||
if (m_context.stage != CameraFrameStage::MainScene) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const RenderPipelineStageRenderGraphContext graphContext =
|
||||
BuildGraphContext();
|
||||
const SceneRenderFeaturePassBeginCallback beginRecordedPass =
|
||||
BuildBeginRecordedPassCallback(graphContext.executionSucceeded);
|
||||
const SceneRenderFeaturePassEndCallback endRecordedPass =
|
||||
BuildEndRecordedPassCallback();
|
||||
bool recordedAnyPass = false;
|
||||
if (!::XCEngine::Rendering::RecordRenderPipelineStageFeaturePasses(
|
||||
graphContext,
|
||||
m_pipeline.m_forwardSceneFeatureHost,
|
||||
injectionPoint,
|
||||
m_clearAttachments,
|
||||
beginRecordedPass,
|
||||
endRecordedPass,
|
||||
&recordedAnyPass)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (recordedAnyPass) {
|
||||
m_clearAttachments = false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
RenderPipelineStageRenderGraphContext
|
||||
BuiltinForwardSceneRecorder::BuildGraphContext() const {
|
||||
const RenderGraphRecordingContext baseRecordingContext =
|
||||
BuildRenderGraphRecordingContext(m_context);
|
||||
RenderGraphRecordingContextBuildParams recordingParams = {};
|
||||
recordingParams.surface = &m_graphManagedSurface;
|
||||
recordingParams.overrideSourceBinding = true;
|
||||
recordingParams.sourceBinding =
|
||||
BuildRenderGraphRecordingSourceBinding(baseRecordingContext);
|
||||
const RenderGraphRecordingContext recordingContext =
|
||||
BuildRenderGraphRecordingContext(
|
||||
baseRecordingContext,
|
||||
std::move(recordingParams));
|
||||
return BuildRenderPipelineStageRenderGraphContext(
|
||||
recordingContext,
|
||||
m_context.stage);
|
||||
}
|
||||
|
||||
} // namespace Pipelines
|
||||
} // namespace Rendering
|
||||
} // namespace XCEngine
|
||||
Reference in New Issue
Block a user