From 5797a75619d1402b9c3656f6bab7710d83cb7248 Mon Sep 17 00:00:00 2001 From: ssdfasd <2156608475@qq.com> Date: Tue, 14 Apr 2026 01:01:45 +0800 Subject: [PATCH] Extract frame-plan fullscreen stage builder --- engine/CMakeLists.txt | 2 + .../Rendering/Execution/SceneRenderer.h | 12 +- .../src/Rendering/Execution/SceneRenderer.cpp | 214 ++--------------- .../Planning/CameraFramePlanBuilder.cpp | 217 ++++++++++++++++++ .../Planning/CameraFramePlanBuilder.h | 41 ++++ 5 files changed, 279 insertions(+), 207 deletions(-) create mode 100644 engine/src/Rendering/Planning/CameraFramePlanBuilder.cpp create mode 100644 engine/src/Rendering/Planning/CameraFramePlanBuilder.h diff --git a/engine/CMakeLists.txt b/engine/CMakeLists.txt index e4cbeb45..68509758 100644 --- a/engine/CMakeLists.txt +++ b/engine/CMakeLists.txt @@ -548,6 +548,8 @@ add_library(XCEngine STATIC ${CMAKE_CURRENT_SOURCE_DIR}/src/Rendering/Extraction/RenderSceneExtractor.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/Rendering/Extraction/RenderSceneUtility.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/Rendering/Caches/RenderResourceCache.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/src/Rendering/Planning/CameraFramePlanBuilder.h + ${CMAKE_CURRENT_SOURCE_DIR}/src/Rendering/Planning/CameraFramePlanBuilder.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/Rendering/Planning/SceneRenderRequestPlanner.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/Rendering/Planning/Internal/DirectionalShadowPlanning.h ${CMAKE_CURRENT_SOURCE_DIR}/src/Rendering/Planning/Internal/DirectionalShadowPlanning.cpp diff --git a/engine/include/XCEngine/Rendering/Execution/SceneRenderer.h b/engine/include/XCEngine/Rendering/Execution/SceneRenderer.h index 07338311..4f9c2f23 100644 --- a/engine/include/XCEngine/Rendering/Execution/SceneRenderer.h +++ b/engine/include/XCEngine/Rendering/Execution/SceneRenderer.h @@ -16,8 +16,8 @@ class Scene; namespace Rendering { +class CameraFramePlanBuilder; class RenderPipelineAsset; -class FullscreenPassSurfaceCache; class SceneRenderer { public: @@ -57,18 +57,10 @@ public: private: std::vector CreateFramePlansFromLegacyRequests( const std::vector& requests) const; - void PrepareOwnedFullscreenStageState(size_t requestCount); - void ResolveCameraFinalColorPolicies( - std::vector& plans) const; - void AttachFullscreenStageRequests( - const RenderContext& context, - std::vector& plans); SceneRenderRequestPlanner m_requestPlanner; CameraRenderer m_cameraRenderer; - std::vector> m_ownedPostProcessSequences; - std::vector> m_ownedFinalOutputSequences; - std::vector> m_ownedFullscreenStageSurfaces; + std::unique_ptr m_framePlanBuilder; }; } // namespace Rendering diff --git a/engine/src/Rendering/Execution/SceneRenderer.cpp b/engine/src/Rendering/Execution/SceneRenderer.cpp index 5110065a..225d58ab 100644 --- a/engine/src/Rendering/Execution/SceneRenderer.cpp +++ b/engine/src/Rendering/Execution/SceneRenderer.cpp @@ -1,12 +1,9 @@ #include "Rendering/Execution/SceneRenderer.h" #include "Components/CameraComponent.h" -#include "Debug/Logger.h" #include "Rendering/Caches/FullscreenPassSurfaceCache.h" -#include "Rendering/Planning/CameraPostProcessPassFactory.h" -#include "Rendering/Planning/FinalColorPassFactory.h" +#include "Rendering/Planning/CameraFramePlanBuilder.h" #include "Rendering/Planning/SceneRenderRequestUtils.h" -#include "Rendering/RenderPipelineAsset.h" namespace XCEngine { namespace Rendering { @@ -21,70 +18,20 @@ bool CompareCameraFramePlans( rhs.request); } -RenderSurface ConfigureFullscreenStageSurface( - const FullscreenPassSurfaceCache::SurfaceEntry& entry, - const RenderSurface& templateSurface, - bool copyDepthAttachment) { - RenderSurface surface = entry.surface; - if (copyDepthAttachment) { - surface.SetDepthAttachment(templateSurface.GetDepthAttachment()); - surface.SetDepthStateBefore(templateSurface.GetDepthStateBefore()); - surface.SetDepthStateAfter(templateSurface.GetDepthStateAfter()); - if (templateSurface.HasClearColorOverride()) { - surface.SetClearColorOverride(templateSurface.GetClearColorOverride()); - } - } - - if (templateSurface.HasCustomRenderArea()) { - surface.SetRenderArea(templateSurface.GetRenderArea()); - } else { - surface.ResetRenderArea(); - } - - surface.SetColorStateBefore(entry.currentColorState); - surface.SetColorStateAfter(RHI::ResourceStates::PixelShaderResource); - return surface; -} - -void UpdateTrackedFullscreenSurfaceState( - std::vector>& surfaceCaches, - const RenderSurface* surface) { - if (surface == nullptr || surface->GetColorAttachments().empty()) { - return; - } - - RHI::RHIResourceView* colorAttachment = surface->GetColorAttachments()[0]; - if (colorAttachment == nullptr) { - return; - } - - for (const std::unique_ptr& cache : surfaceCaches) { - if (cache == nullptr) { - continue; - } - - for (size_t entryIndex = 0; entryIndex < cache->GetSurfaceCount(); ++entryIndex) { - FullscreenPassSurfaceCache::SurfaceEntry* entry = cache->GetSurfaceEntry(entryIndex); - if (entry == nullptr || entry->renderTargetView != colorAttachment) { - continue; - } - - entry->currentColorState = surface->GetColorStateAfter(); - return; - } - } -} - } // namespace -SceneRenderer::SceneRenderer() = default; +SceneRenderer::SceneRenderer() + : m_framePlanBuilder(std::make_unique()) { +} SceneRenderer::SceneRenderer(std::unique_ptr pipeline) - : m_cameraRenderer(std::move(pipeline)) { + : m_cameraRenderer(std::move(pipeline)) + , m_framePlanBuilder(std::make_unique()) { } SceneRenderer::SceneRenderer(std::shared_ptr pipelineAsset) - : m_cameraRenderer(std::move(pipelineAsset)) { + : m_cameraRenderer(std::move(pipelineAsset)) + , m_framePlanBuilder(std::make_unique()) { } SceneRenderer::~SceneRenderer() = default; @@ -119,10 +66,9 @@ std::vector SceneRenderer::BuildFramePlans( const RenderSurface& surface) { const std::vector requests = m_requestPlanner.BuildRequests(scene, overrideCamera, context, surface); - std::vector plans = CreateFramePlansFromLegacyRequests(requests); - ResolveCameraFinalColorPolicies(plans); - AttachFullscreenStageRequests(context, plans); - return plans; + return m_framePlanBuilder != nullptr + ? m_framePlanBuilder->BuildPlans(requests, GetPipelineAsset()) + : std::vector(); } bool SceneRenderer::Render(const CameraRenderRequest& request) { @@ -161,13 +107,13 @@ bool SceneRenderer::Render(const std::vector& plans) { return false; } - UpdateTrackedFullscreenSurfaceState( - m_ownedFullscreenStageSurfaces, - &plan.GetMainSceneSurface()); + if (m_framePlanBuilder != nullptr) { + m_framePlanBuilder->UpdateTrackedSurfaceState(&plan.GetMainSceneSurface()); + } if (plan.postProcess.IsRequested()) { - UpdateTrackedFullscreenSurfaceState( - m_ownedFullscreenStageSurfaces, - &plan.postProcess.destinationSurface); + if (m_framePlanBuilder != nullptr) { + m_framePlanBuilder->UpdateTrackedSurfaceState(&plan.postProcess.destinationSurface); + } } rendered = true; @@ -195,131 +141,5 @@ std::vector SceneRenderer::CreateFramePlansFromLegacyRequests( return plans; } -void SceneRenderer::PrepareOwnedFullscreenStageState(size_t requestCount) { - m_ownedPostProcessSequences.clear(); - m_ownedPostProcessSequences.resize(requestCount); - m_ownedFinalOutputSequences.clear(); - m_ownedFinalOutputSequences.resize(requestCount); - - if (m_ownedFullscreenStageSurfaces.size() < requestCount) { - m_ownedFullscreenStageSurfaces.resize(requestCount); - } - - for (size_t index = 0; index < requestCount; ++index) { - if (m_ownedFullscreenStageSurfaces[index] == nullptr) { - m_ownedFullscreenStageSurfaces[index] = std::make_unique(); - } - } -} - -void SceneRenderer::ResolveCameraFinalColorPolicies( - std::vector& plans) const { - const RenderPipelineAsset* pipelineAsset = GetPipelineAsset(); - const FinalColorSettings pipelineDefaults = - pipelineAsset != nullptr ? pipelineAsset->GetDefaultFinalColorSettings() : FinalColorSettings(); - - for (CameraFramePlan& plan : plans) { - if (plan.request.camera == nullptr) { - continue; - } - - plan.finalColorPolicy = ResolveFinalColorPolicy( - pipelineDefaults, - &plan.request.camera->GetFinalColorOverrides()); - } -} - -void SceneRenderer::AttachFullscreenStageRequests( - const RenderContext& context, - std::vector& plans) { - PrepareOwnedFullscreenStageState(plans.size()); - - for (size_t index = 0; index < plans.size(); ++index) { - CameraFramePlan& plan = plans[index]; - if (plan.request.camera == nullptr || - plan.request.context.device == nullptr || - !HasValidColorTarget(plan.request.surface)) { - continue; - } - - std::unique_ptr postProcessSequence = - BuildCameraPostProcessPassSequence(plan.request.camera->GetPostProcessPasses()); - std::unique_ptr finalOutputSequence = - BuildFinalColorPassSequence(plan.finalColorPolicy); - - const bool hasPostProcess = - postProcessSequence != nullptr && postProcessSequence->GetPassCount() > 0u; - const bool hasFinalOutput = - finalOutputSequence != nullptr && finalOutputSequence->GetPassCount() > 0u; - if (!hasPostProcess && !hasFinalOutput) { - continue; - } - - if (plan.request.surface.GetSampleCount() > 1u) { - Debug::Logger::Get().Error( - Debug::LogCategory::Rendering, - "SceneRenderer fullscreen post-process/final-output chain currently requires a single-sample main scene surface"); - continue; - } - - const std::vector& colorAttachments = plan.request.surface.GetColorAttachments(); - const RHI::Format colorFormat = colorAttachments[0]->GetFormat(); - if (colorFormat == RHI::Format::Unknown) { - continue; - } - - const size_t fullscreenSurfaceCount = hasPostProcess && hasFinalOutput ? 2u : 1u; - FullscreenPassSurfaceCache* surfaceCache = m_ownedFullscreenStageSurfaces[index].get(); - if (surfaceCache == nullptr || - !surfaceCache->EnsureSurfaces( - context, - plan.request.surface.GetWidth(), - plan.request.surface.GetHeight(), - colorFormat, - fullscreenSurfaceCount)) { - continue; - } - - const FullscreenPassSurfaceCache::SurfaceEntry* sceneColorEntry = surfaceCache->GetSurfaceEntry(0u); - if (sceneColorEntry == nullptr || sceneColorEntry->shaderResourceView == nullptr) { - continue; - } - - const FullscreenPassSurfaceCache::SurfaceEntry* postProcessOutputEntry = - hasPostProcess && hasFinalOutput ? surfaceCache->GetSurfaceEntry(1u) : nullptr; - if (hasPostProcess && hasFinalOutput && - (postProcessOutputEntry == nullptr || postProcessOutputEntry->shaderResourceView == nullptr)) { - continue; - } - - if (hasPostProcess) { - plan.postProcess.sourceSurface = - ConfigureFullscreenStageSurface(*sceneColorEntry, plan.request.surface, true); - plan.postProcess.sourceColorView = sceneColorEntry->shaderResourceView; - plan.postProcess.sourceColorState = plan.postProcess.sourceSurface.GetColorStateAfter(); - plan.postProcess.destinationSurface = - hasFinalOutput - ? ConfigureFullscreenStageSurface(*postProcessOutputEntry, plan.request.surface, false) - : plan.request.surface; - m_ownedPostProcessSequences[index] = std::move(postProcessSequence); - plan.postProcess.passes = m_ownedPostProcessSequences[index].get(); - } - - if (hasFinalOutput) { - const FullscreenPassSurfaceCache::SurfaceEntry* finalOutputSourceEntry = - hasPostProcess ? postProcessOutputEntry : sceneColorEntry; - plan.finalOutput.sourceSurface = - hasPostProcess - ? plan.postProcess.destinationSurface - : ConfigureFullscreenStageSurface(*sceneColorEntry, plan.request.surface, true); - plan.finalOutput.sourceColorView = finalOutputSourceEntry->shaderResourceView; - plan.finalOutput.sourceColorState = plan.finalOutput.sourceSurface.GetColorStateAfter(); - plan.finalOutput.destinationSurface = plan.request.surface; - m_ownedFinalOutputSequences[index] = std::move(finalOutputSequence); - plan.finalOutput.passes = m_ownedFinalOutputSequences[index].get(); - } - } -} - } // namespace Rendering } // namespace XCEngine diff --git a/engine/src/Rendering/Planning/CameraFramePlanBuilder.cpp b/engine/src/Rendering/Planning/CameraFramePlanBuilder.cpp new file mode 100644 index 00000000..d8d89ee5 --- /dev/null +++ b/engine/src/Rendering/Planning/CameraFramePlanBuilder.cpp @@ -0,0 +1,217 @@ +#include "Rendering/Planning/CameraFramePlanBuilder.h" + +#include "Components/CameraComponent.h" +#include "Debug/Logger.h" +#include "Rendering/Caches/FullscreenPassSurfaceCache.h" +#include "Rendering/Planning/CameraPostProcessPassFactory.h" +#include "Rendering/Planning/FinalColorPassFactory.h" +#include "Rendering/RenderPipelineAsset.h" + +namespace XCEngine { +namespace Rendering { + +namespace { + +RenderSurface ConfigureFullscreenStageSurface( + const FullscreenPassSurfaceCache::SurfaceEntry& entry, + const RenderSurface& templateSurface, + bool copyDepthAttachment) { + RenderSurface surface = entry.surface; + if (copyDepthAttachment) { + surface.SetDepthAttachment(templateSurface.GetDepthAttachment()); + surface.SetDepthStateBefore(templateSurface.GetDepthStateBefore()); + surface.SetDepthStateAfter(templateSurface.GetDepthStateAfter()); + if (templateSurface.HasClearColorOverride()) { + surface.SetClearColorOverride(templateSurface.GetClearColorOverride()); + } + } + + if (templateSurface.HasCustomRenderArea()) { + surface.SetRenderArea(templateSurface.GetRenderArea()); + } else { + surface.ResetRenderArea(); + } + + surface.SetColorStateBefore(entry.currentColorState); + surface.SetColorStateAfter(RHI::ResourceStates::PixelShaderResource); + return surface; +} + +} // namespace + +std::vector CameraFramePlanBuilder::BuildPlans( + const std::vector& requests, + const RenderPipelineAsset* pipelineAsset) { + std::vector plans = CreatePlansFromCompatibilityRequests(requests); + ResolveCameraFinalColorPolicies(plans, pipelineAsset); + AttachFullscreenStageRequests(plans); + return plans; +} + +void CameraFramePlanBuilder::UpdateTrackedSurfaceState(const RenderSurface* surface) { + if (surface == nullptr || surface->GetColorAttachments().empty()) { + return; + } + + RHI::RHIResourceView* colorAttachment = surface->GetColorAttachments()[0]; + if (colorAttachment == nullptr) { + return; + } + + for (const std::unique_ptr& cache : m_ownedFullscreenStageSurfaces) { + if (cache == nullptr) { + continue; + } + + for (size_t entryIndex = 0; entryIndex < cache->GetSurfaceCount(); ++entryIndex) { + FullscreenPassSurfaceCache::SurfaceEntry* entry = cache->GetSurfaceEntry(entryIndex); + if (entry == nullptr || entry->renderTargetView != colorAttachment) { + continue; + } + + entry->currentColorState = surface->GetColorStateAfter(); + return; + } + } +} + +std::vector CameraFramePlanBuilder::CreatePlansFromCompatibilityRequests( + const std::vector& requests) const { + std::vector plans = {}; + plans.reserve(requests.size()); + for (const CameraRenderRequest& request : requests) { + plans.push_back(CameraFramePlan::FromRequest(request)); + } + + return plans; +} + +void CameraFramePlanBuilder::PrepareOwnedFullscreenStageState(size_t planCount) { + m_ownedPostProcessSequences.clear(); + m_ownedPostProcessSequences.resize(planCount); + m_ownedFinalOutputSequences.clear(); + m_ownedFinalOutputSequences.resize(planCount); + + if (m_ownedFullscreenStageSurfaces.size() < planCount) { + m_ownedFullscreenStageSurfaces.resize(planCount); + } + + for (size_t index = 0; index < planCount; ++index) { + if (m_ownedFullscreenStageSurfaces[index] == nullptr) { + m_ownedFullscreenStageSurfaces[index] = std::make_unique(); + } + } +} + +void CameraFramePlanBuilder::ResolveCameraFinalColorPolicies( + std::vector& plans, + const RenderPipelineAsset* pipelineAsset) const { + const FinalColorSettings pipelineDefaults = + pipelineAsset != nullptr ? pipelineAsset->GetDefaultFinalColorSettings() : FinalColorSettings(); + + for (CameraFramePlan& plan : plans) { + if (plan.request.camera == nullptr) { + continue; + } + + plan.finalColorPolicy = ResolveFinalColorPolicy( + pipelineDefaults, + &plan.request.camera->GetFinalColorOverrides()); + } +} + +void CameraFramePlanBuilder::AttachFullscreenStageRequests( + std::vector& plans) { + PrepareOwnedFullscreenStageState(plans.size()); + + for (size_t index = 0; index < plans.size(); ++index) { + CameraFramePlan& plan = plans[index]; + if (plan.request.camera == nullptr || + plan.request.context.device == nullptr || + !HasValidColorTarget(plan.request.surface)) { + continue; + } + + std::unique_ptr postProcessSequence = + BuildCameraPostProcessPassSequence(plan.request.camera->GetPostProcessPasses()); + std::unique_ptr finalOutputSequence = + BuildFinalColorPassSequence(plan.finalColorPolicy); + + const bool hasPostProcess = + postProcessSequence != nullptr && postProcessSequence->GetPassCount() > 0u; + const bool hasFinalOutput = + finalOutputSequence != nullptr && finalOutputSequence->GetPassCount() > 0u; + if (!hasPostProcess && !hasFinalOutput) { + continue; + } + + if (plan.request.surface.GetSampleCount() > 1u) { + Debug::Logger::Get().Error( + Debug::LogCategory::Rendering, + "SceneRenderer fullscreen post-process/final-output chain currently requires a single-sample main scene surface"); + continue; + } + + const std::vector& colorAttachments = + plan.request.surface.GetColorAttachments(); + const RHI::Format colorFormat = colorAttachments[0]->GetFormat(); + if (colorFormat == RHI::Format::Unknown) { + continue; + } + + const size_t fullscreenSurfaceCount = hasPostProcess && hasFinalOutput ? 2u : 1u; + FullscreenPassSurfaceCache* surfaceCache = m_ownedFullscreenStageSurfaces[index].get(); + if (surfaceCache == nullptr || + !surfaceCache->EnsureSurfaces( + plan.request.context, + plan.request.surface.GetWidth(), + plan.request.surface.GetHeight(), + colorFormat, + fullscreenSurfaceCount)) { + continue; + } + + const FullscreenPassSurfaceCache::SurfaceEntry* sceneColorEntry = + surfaceCache->GetSurfaceEntry(0u); + if (sceneColorEntry == nullptr || sceneColorEntry->shaderResourceView == nullptr) { + continue; + } + + const FullscreenPassSurfaceCache::SurfaceEntry* postProcessOutputEntry = + hasPostProcess && hasFinalOutput ? surfaceCache->GetSurfaceEntry(1u) : nullptr; + if (hasPostProcess && hasFinalOutput && + (postProcessOutputEntry == nullptr || postProcessOutputEntry->shaderResourceView == nullptr)) { + continue; + } + + if (hasPostProcess) { + plan.postProcess.sourceSurface = + ConfigureFullscreenStageSurface(*sceneColorEntry, plan.request.surface, true); + plan.postProcess.sourceColorView = sceneColorEntry->shaderResourceView; + plan.postProcess.sourceColorState = plan.postProcess.sourceSurface.GetColorStateAfter(); + plan.postProcess.destinationSurface = + hasFinalOutput + ? ConfigureFullscreenStageSurface(*postProcessOutputEntry, plan.request.surface, false) + : plan.request.surface; + m_ownedPostProcessSequences[index] = std::move(postProcessSequence); + plan.postProcess.passes = m_ownedPostProcessSequences[index].get(); + } + + if (hasFinalOutput) { + const FullscreenPassSurfaceCache::SurfaceEntry* finalOutputSourceEntry = + hasPostProcess ? postProcessOutputEntry : sceneColorEntry; + plan.finalOutput.sourceSurface = + hasPostProcess + ? plan.postProcess.destinationSurface + : ConfigureFullscreenStageSurface(*sceneColorEntry, plan.request.surface, true); + plan.finalOutput.sourceColorView = finalOutputSourceEntry->shaderResourceView; + plan.finalOutput.sourceColorState = plan.finalOutput.sourceSurface.GetColorStateAfter(); + plan.finalOutput.destinationSurface = plan.request.surface; + m_ownedFinalOutputSequences[index] = std::move(finalOutputSequence); + plan.finalOutput.passes = m_ownedFinalOutputSequences[index].get(); + } + } +} + +} // namespace Rendering +} // namespace XCEngine diff --git a/engine/src/Rendering/Planning/CameraFramePlanBuilder.h b/engine/src/Rendering/Planning/CameraFramePlanBuilder.h new file mode 100644 index 00000000..ac7d62b5 --- /dev/null +++ b/engine/src/Rendering/Planning/CameraFramePlanBuilder.h @@ -0,0 +1,41 @@ +#pragma once + +#include + +#include +#include + +namespace XCEngine { +namespace Rendering { + +class FullscreenPassSurfaceCache; +class RenderPipelineAsset; + +class CameraFramePlanBuilder { +public: + CameraFramePlanBuilder() = default; + CameraFramePlanBuilder(const CameraFramePlanBuilder&) = delete; + CameraFramePlanBuilder& operator=(const CameraFramePlanBuilder&) = delete; + ~CameraFramePlanBuilder() = default; + + std::vector BuildPlans( + const std::vector& requests, + const RenderPipelineAsset* pipelineAsset); + void UpdateTrackedSurfaceState(const RenderSurface* surface); + +private: + std::vector CreatePlansFromCompatibilityRequests( + const std::vector& requests) const; + void PrepareOwnedFullscreenStageState(size_t planCount); + void ResolveCameraFinalColorPolicies( + std::vector& plans, + const RenderPipelineAsset* pipelineAsset) const; + void AttachFullscreenStageRequests(std::vector& plans); + + std::vector> m_ownedPostProcessSequences; + std::vector> m_ownedFinalOutputSequences; + std::vector> m_ownedFullscreenStageSurfaces; +}; + +} // namespace Rendering +} // namespace XCEngine