Refactor rendering frame execution contracts

This commit is contained in:
2026-04-13 22:16:04 +08:00
parent 48daaa1bd0
commit 712f99e723
30 changed files with 1398 additions and 247 deletions

View File

@@ -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());