Refactor rendering frame execution contracts
This commit is contained in:
@@ -143,58 +143,31 @@ RHI::InputLayoutDesc BuiltinForwardPipeline::BuildInputLayout() {
|
||||
|
||||
bool BuiltinForwardPipeline::Initialize(const RenderContext& context) {
|
||||
return EnsureInitialized(context) &&
|
||||
m_gaussianSplatPass != nullptr &&
|
||||
m_gaussianSplatPass->Initialize(context) &&
|
||||
m_volumetricPass != nullptr &&
|
||||
m_volumetricPass->Initialize(context);
|
||||
InitializeForwardSceneFeaturePasses(context);
|
||||
}
|
||||
|
||||
void BuiltinForwardPipeline::Shutdown() {
|
||||
if (m_gaussianSplatPass != nullptr) {
|
||||
m_gaussianSplatPass->Shutdown();
|
||||
}
|
||||
if (m_volumetricPass != nullptr) {
|
||||
m_volumetricPass->Shutdown();
|
||||
}
|
||||
ShutdownForwardSceneFeaturePasses();
|
||||
DestroyPipelineResources();
|
||||
}
|
||||
|
||||
bool BuiltinForwardPipeline::Render(
|
||||
const RenderContext& context,
|
||||
const RenderSurface& surface,
|
||||
const RenderSceneData& sceneData) {
|
||||
if (!Initialize(context)) {
|
||||
const FrameExecutionContext& executionContext) {
|
||||
if (!Initialize(executionContext.renderContext)) {
|
||||
Debug::Logger::Get().Error(
|
||||
Debug::LogCategory::Rendering,
|
||||
"BuiltinForwardPipeline::Render failed: Initialize returned false");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_volumetricPass != nullptr &&
|
||||
!sceneData.visibleVolumes.empty() &&
|
||||
!m_volumetricPass->PrepareVolumeResources(context, sceneData)) {
|
||||
if (!PrepareForwardSceneFeaturePasses(executionContext)) {
|
||||
Debug::Logger::Get().Error(
|
||||
Debug::LogCategory::Rendering,
|
||||
"BuiltinForwardPipeline::Render failed: PrepareVolumeResources returned false");
|
||||
return false;
|
||||
}
|
||||
if (m_gaussianSplatPass != nullptr &&
|
||||
!sceneData.visibleGaussianSplats.empty() &&
|
||||
!m_gaussianSplatPass->PrepareGaussianSplatResources(context, sceneData)) {
|
||||
Debug::Logger::Get().Error(
|
||||
Debug::LogCategory::Rendering,
|
||||
"BuiltinForwardPipeline::Render failed: PrepareGaussianSplatResources returned false");
|
||||
"BuiltinForwardPipeline::Render failed: PrepareForwardSceneFeaturePasses returned false");
|
||||
return false;
|
||||
}
|
||||
|
||||
const RenderPassContext passContext = {
|
||||
context,
|
||||
surface,
|
||||
sceneData,
|
||||
nullptr,
|
||||
nullptr,
|
||||
RHI::ResourceStates::Common
|
||||
};
|
||||
const RenderPassContext passContext = BuildRenderPassContext(executionContext);
|
||||
|
||||
if (!BeginForwardScenePass(passContext)) {
|
||||
Debug::Logger::Get().Error(
|
||||
@@ -203,53 +176,33 @@ bool BuiltinForwardPipeline::Render(
|
||||
return false;
|
||||
}
|
||||
|
||||
const bool sampledDirectionalShadow = ShouldSampleMainDirectionalShadowMap(sceneData);
|
||||
const bool sampledDirectionalShadow =
|
||||
ShouldSampleMainDirectionalShadowMap(executionContext.sceneData);
|
||||
if (sampledDirectionalShadow) {
|
||||
TransitionMainDirectionalShadowForSampling(context, sceneData);
|
||||
TransitionMainDirectionalShadowForSampling(
|
||||
executionContext.renderContext,
|
||||
executionContext.sceneData);
|
||||
}
|
||||
|
||||
bool renderResult = ExecuteForwardOpaquePass(passContext);
|
||||
if (renderResult) {
|
||||
renderResult = ExecuteForwardSkyboxPass(passContext);
|
||||
if (!renderResult) {
|
||||
Debug::Logger::Get().Error(
|
||||
Debug::LogCategory::Rendering,
|
||||
"BuiltinForwardPipeline::Render failed: ExecuteForwardSkyboxPass returned false");
|
||||
}
|
||||
}
|
||||
if (renderResult && m_gaussianSplatPass != nullptr) {
|
||||
renderResult = m_gaussianSplatPass->Execute(passContext);
|
||||
if (!renderResult) {
|
||||
Debug::Logger::Get().Error(
|
||||
Debug::LogCategory::Rendering,
|
||||
"BuiltinForwardPipeline::Render failed: BuiltinGaussianSplatPass::Execute returned false");
|
||||
}
|
||||
}
|
||||
if (renderResult && m_volumetricPass != nullptr) {
|
||||
renderResult = m_volumetricPass->Execute(passContext);
|
||||
if (!renderResult) {
|
||||
Debug::Logger::Get().Error(
|
||||
Debug::LogCategory::Rendering,
|
||||
"BuiltinForwardPipeline::Render failed: BuiltinVolumetricPass::Execute returned false");
|
||||
}
|
||||
}
|
||||
if (renderResult) {
|
||||
renderResult = ExecuteForwardTransparentPass(passContext);
|
||||
if (!renderResult) {
|
||||
Debug::Logger::Get().Error(
|
||||
Debug::LogCategory::Rendering,
|
||||
"BuiltinForwardPipeline::Render failed: ExecuteForwardTransparentPass returned false");
|
||||
}
|
||||
}
|
||||
const bool renderResult = ExecuteForwardScene(executionContext);
|
||||
|
||||
if (sampledDirectionalShadow) {
|
||||
RestoreMainDirectionalShadowAfterSampling(context, sceneData);
|
||||
RestoreMainDirectionalShadowAfterSampling(
|
||||
executionContext.renderContext,
|
||||
executionContext.sceneData);
|
||||
}
|
||||
EndForwardScenePass(passContext);
|
||||
|
||||
return renderResult;
|
||||
}
|
||||
|
||||
bool BuiltinForwardPipeline::Render(
|
||||
const RenderContext& context,
|
||||
const RenderSurface& surface,
|
||||
const RenderSceneData& sceneData) {
|
||||
return Render(FrameExecutionContext(context, surface, sceneData));
|
||||
}
|
||||
|
||||
bool BuiltinForwardPipeline::BeginForwardScenePass(const RenderPassContext& passContext) {
|
||||
const RenderContext& context = passContext.renderContext;
|
||||
const RenderSurface& surface = passContext.surface;
|
||||
@@ -358,20 +311,18 @@ void BuiltinForwardPipeline::EndForwardScenePass(const RenderPassContext& passCo
|
||||
}
|
||||
}
|
||||
|
||||
bool BuiltinForwardPipeline::ExecuteForwardOpaquePass(const RenderPassContext& passContext) {
|
||||
const RenderContext& context = passContext.renderContext;
|
||||
const RenderSurface& surface = passContext.surface;
|
||||
const RenderSceneData& sceneData = passContext.sceneData;
|
||||
|
||||
return DrawVisibleItems(context, surface, sceneData, false);
|
||||
bool BuiltinForwardPipeline::ExecuteForwardOpaquePass(
|
||||
const ScenePhaseExecutionContext& executionContext) {
|
||||
return DrawVisibleItems(
|
||||
executionContext.frameContext,
|
||||
BuildDrawSettings(executionContext.scenePhase));
|
||||
}
|
||||
|
||||
bool BuiltinForwardPipeline::ExecuteForwardTransparentPass(const RenderPassContext& passContext) {
|
||||
const RenderContext& context = passContext.renderContext;
|
||||
const RenderSurface& surface = passContext.surface;
|
||||
const RenderSceneData& sceneData = passContext.sceneData;
|
||||
|
||||
return DrawVisibleItems(context, surface, sceneData, true);
|
||||
bool BuiltinForwardPipeline::ExecuteForwardTransparentPass(
|
||||
const ScenePhaseExecutionContext& executionContext) {
|
||||
return DrawVisibleItems(
|
||||
executionContext.frameContext,
|
||||
BuildDrawSettings(executionContext.scenePhase));
|
||||
}
|
||||
|
||||
bool BuiltinForwardPipeline::EnsureInitialized(const RenderContext& context) {
|
||||
@@ -392,6 +343,146 @@ bool BuiltinForwardPipeline::EnsureInitialized(const RenderContext& context) {
|
||||
return m_initialized;
|
||||
}
|
||||
|
||||
BuiltinForwardPipeline::ForwardSceneFeaturePassArray
|
||||
BuiltinForwardPipeline::CollectForwardSceneFeaturePasses() const {
|
||||
return {
|
||||
m_gaussianSplatPass.get(),
|
||||
m_volumetricPass.get()
|
||||
};
|
||||
}
|
||||
|
||||
bool BuiltinForwardPipeline::InitializeForwardSceneFeaturePasses(const RenderContext& context) {
|
||||
for (SceneRenderFeaturePass* featurePass : CollectForwardSceneFeaturePasses()) {
|
||||
if (featurePass == nullptr || !featurePass->Initialize(context)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void BuiltinForwardPipeline::ShutdownForwardSceneFeaturePasses() {
|
||||
for (SceneRenderFeaturePass* featurePass : CollectForwardSceneFeaturePasses()) {
|
||||
if (featurePass != nullptr) {
|
||||
featurePass->Shutdown();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool BuiltinForwardPipeline::PrepareForwardSceneFeaturePasses(
|
||||
const FrameExecutionContext& executionContext) const {
|
||||
for (SceneRenderFeaturePass* featurePass : CollectForwardSceneFeaturePasses()) {
|
||||
if (featurePass == nullptr || !featurePass->IsActive(executionContext.sceneData)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!featurePass->Prepare(
|
||||
executionContext.renderContext,
|
||||
executionContext.sceneData)) {
|
||||
Debug::Logger::Get().Error(
|
||||
Debug::LogCategory::Rendering,
|
||||
(Containers::String("BuiltinForwardPipeline feature prepare failed: ") +
|
||||
featurePass->GetName()).CStr());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BuiltinForwardPipeline::ExecuteForwardSceneFeaturePasses(
|
||||
const ScenePhaseExecutionContext& executionContext) const {
|
||||
const RenderPassContext passContext = BuildRenderPassContext(executionContext);
|
||||
|
||||
for (SceneRenderFeaturePass* featurePass : CollectForwardSceneFeaturePasses()) {
|
||||
if (featurePass == nullptr ||
|
||||
!featurePass->IsActive(executionContext.frameContext.sceneData)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!featurePass->Execute(passContext)) {
|
||||
Debug::Logger::Get().Error(
|
||||
Debug::LogCategory::Rendering,
|
||||
(Containers::String("BuiltinForwardPipeline feature execute failed: ") +
|
||||
featurePass->GetName()).CStr());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
ScenePhaseExecutionContext BuiltinForwardPipeline::BuildScenePhaseExecutionContext(
|
||||
const FrameExecutionContext& executionContext,
|
||||
ScenePhase scenePhase) const {
|
||||
return ScenePhaseExecutionContext(
|
||||
executionContext,
|
||||
scenePhase,
|
||||
ShouldSampleMainDirectionalShadowMap(executionContext.sceneData));
|
||||
}
|
||||
|
||||
DrawSettings BuiltinForwardPipeline::BuildDrawSettings(ScenePhase scenePhase) const {
|
||||
DrawSettings drawSettings = {};
|
||||
drawSettings.scenePhase = scenePhase;
|
||||
switch (scenePhase) {
|
||||
case ScenePhase::Opaque:
|
||||
drawSettings.rendererListType = RendererListType::Opaque;
|
||||
break;
|
||||
case ScenePhase::Transparent:
|
||||
drawSettings.rendererListType = RendererListType::Transparent;
|
||||
break;
|
||||
default:
|
||||
drawSettings.rendererListType = RendererListType::AllVisible;
|
||||
break;
|
||||
}
|
||||
|
||||
return drawSettings;
|
||||
}
|
||||
|
||||
bool BuiltinForwardPipeline::ExecuteScenePhase(
|
||||
const ScenePhaseExecutionContext& executionContext) {
|
||||
switch (executionContext.scenePhase) {
|
||||
case ScenePhase::Opaque:
|
||||
return ExecuteForwardOpaquePass(executionContext);
|
||||
case ScenePhase::Skybox:
|
||||
return ExecuteForwardSkyboxPass(BuildRenderPassContext(executionContext));
|
||||
case ScenePhase::Feature:
|
||||
return ExecuteForwardSceneFeaturePasses(executionContext);
|
||||
case ScenePhase::Transparent:
|
||||
return ExecuteForwardTransparentPass(executionContext);
|
||||
default:
|
||||
Debug::Logger::Get().Error(
|
||||
Debug::LogCategory::Rendering,
|
||||
(Containers::String("BuiltinForwardPipeline::ExecuteScenePhase does not support scene phase: ") +
|
||||
ToString(executionContext.scenePhase)).CStr());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool BuiltinForwardPipeline::ExecuteForwardScene(
|
||||
const FrameExecutionContext& executionContext) {
|
||||
static constexpr ScenePhase kForwardScenePhases[] = {
|
||||
ScenePhase::Opaque,
|
||||
ScenePhase::Skybox,
|
||||
ScenePhase::Feature,
|
||||
ScenePhase::Transparent
|
||||
};
|
||||
|
||||
for (ScenePhase scenePhase : kForwardScenePhases) {
|
||||
const ScenePhaseExecutionContext scenePhaseExecutionContext =
|
||||
BuildScenePhaseExecutionContext(executionContext, scenePhase);
|
||||
if (!ExecuteScenePhase(scenePhaseExecutionContext)) {
|
||||
Debug::Logger::Get().Error(
|
||||
Debug::LogCategory::Rendering,
|
||||
(Containers::String("BuiltinForwardPipeline::ExecuteForwardScene failed during phase: ") +
|
||||
ToString(scenePhase)).CStr());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BuiltinForwardPipeline::CreatePipelineResources(const RenderContext& context) {
|
||||
m_builtinForwardShader = Resources::ResourceManager::Get().Load<Resources::Shader>(
|
||||
Resources::GetBuiltinForwardLitShaderPath());
|
||||
|
||||
Reference in New Issue
Block a user