From 3e5b7287c7d7ce98fa08d0816f238e42966ff55f Mon Sep 17 00:00:00 2001 From: ssdfasd <2156608475@qq.com> Date: Tue, 14 Apr 2026 23:33:35 +0800 Subject: [PATCH] Split camera frame render-graph stage recording helpers --- engine/CMakeLists.txt | 5 + ...meraFrameRenderGraphStagePassRecording.cpp | 384 ++++++++++ ...CameraFrameRenderGraphStagePassRecording.h | 45 ++ .../CameraFrameRenderGraphStageRecording.cpp | 654 +----------------- .../CameraFrameRenderGraphStageRecording.h | 53 -- .../CameraFrameRenderGraphStageRuntime.h | 60 ++ ...FrameRenderGraphStageSequenceRecording.cpp | 298 ++++++++ ...raFrameRenderGraphStageSequenceRecording.h | 24 + ...Bridge.cpp => EditorHostCommandBridge.cpp} | 0 ...mandBridge.h => EditorHostCommandBridge.h} | 0 ...uctEditorContext.cpp => EditorContext.cpp} | 0 ...ProductEditorContext.h => EditorContext.h} | 0 ...uctEditorSession.cpp => EditorSession.cpp} | 0 ...ProductEditorSession.h => EditorSession.h} | 0 .../Console/ConsolePanel.cpp} | 0 .../Console/ConsolePanel.h} | 0 .../Hierarchy/HierarchyModel.cpp} | 0 .../Hierarchy/HierarchyModel.h} | 0 .../Hierarchy/HierarchyPanel.cpp} | 0 .../Hierarchy/HierarchyPanel.h} | 0 .../Inspector/InspectorPanel.cpp} | 0 .../Inspector/InspectorPanel.h} | 0 .../Project/ProjectBrowserModel.cpp} | 0 .../Project/ProjectBrowserModel.h} | 0 .../Project/ProjectPanel.cpp} | 0 .../Project/ProjectPanel.h} | 0 .../Shared/BuiltInIcons.cpp} | 0 .../Shared/BuiltInIcons.h} | 0 .../Shared/EditorTreeViewStyle.h} | 0 ...lAsset.cpp => EditorShellAssetBuilder.cpp} | 0 ...ShellAsset.h => EditorShellAssetBuilder.h} | 0 ...ostService.cpp => ViewportHostService.cpp} | 0 ...ortHostService.h => ViewportHostService.h} | 0 ...er.cpp => ViewportRenderTargetManager.cpp} | 0 ...rTargets.cpp => ViewportRenderTargets.cpp} | 0 ...enderTargets.h => ViewportRenderTargets.h} | 0 ...tSurfaceUtils.h => ViewportSurfaceUtils.h} | 0 ...ProductViewportTypes.h => ViewportTypes.h} | 0 ...ditorWorkspace.cpp => EditorWorkspace.cpp} | 0 ...uctEditorWorkspace.h => EditorWorkspace.h} | 0 ...ter.cpp => EditorWorkspaceEventRouter.cpp} | 0 ...tRouter.h => EditorWorkspaceEventRouter.h} | 0 42 files changed, 820 insertions(+), 703 deletions(-) create mode 100644 engine/src/Rendering/Execution/Internal/CameraFrameRenderGraphStagePassRecording.cpp create mode 100644 engine/src/Rendering/Execution/Internal/CameraFrameRenderGraphStagePassRecording.h create mode 100644 engine/src/Rendering/Execution/Internal/CameraFrameRenderGraphStageRuntime.h create mode 100644 engine/src/Rendering/Execution/Internal/CameraFrameRenderGraphStageSequenceRecording.cpp create mode 100644 engine/src/Rendering/Execution/Internal/CameraFrameRenderGraphStageSequenceRecording.h rename new_editor/app/Commands/{ProductEditorHostCommandBridge.cpp => EditorHostCommandBridge.cpp} (100%) rename new_editor/app/Commands/{ProductEditorHostCommandBridge.h => EditorHostCommandBridge.h} (100%) rename new_editor/app/Core/{ProductEditorContext.cpp => EditorContext.cpp} (100%) rename new_editor/app/Core/{ProductEditorContext.h => EditorContext.h} (100%) rename new_editor/app/Core/{ProductEditorSession.cpp => EditorSession.cpp} (100%) rename new_editor/app/Core/{ProductEditorSession.h => EditorSession.h} (100%) rename new_editor/app/{Panels/ProductConsolePanel.cpp => Features/Console/ConsolePanel.cpp} (100%) rename new_editor/app/{Panels/ProductConsolePanel.h => Features/Console/ConsolePanel.h} (100%) rename new_editor/app/{Hierarchy/ProductHierarchyModel.cpp => Features/Hierarchy/HierarchyModel.cpp} (100%) rename new_editor/app/{Hierarchy/ProductHierarchyModel.h => Features/Hierarchy/HierarchyModel.h} (100%) rename new_editor/app/{Panels/ProductHierarchyPanel.cpp => Features/Hierarchy/HierarchyPanel.cpp} (100%) rename new_editor/app/{Panels/ProductHierarchyPanel.h => Features/Hierarchy/HierarchyPanel.h} (100%) rename new_editor/app/{Panels/ProductInspectorPanel.cpp => Features/Inspector/InspectorPanel.cpp} (100%) rename new_editor/app/{Panels/ProductInspectorPanel.h => Features/Inspector/InspectorPanel.h} (100%) rename new_editor/app/{Project/ProductProjectBrowserModel.cpp => Features/Project/ProjectBrowserModel.cpp} (100%) rename new_editor/app/{Project/ProductProjectBrowserModel.h => Features/Project/ProjectBrowserModel.h} (100%) rename new_editor/app/{Panels/ProductProjectPanel.cpp => Features/Project/ProjectPanel.cpp} (100%) rename new_editor/app/{Panels/ProductProjectPanel.h => Features/Project/ProjectPanel.h} (100%) rename new_editor/app/{Icons/ProductBuiltInIcons.cpp => Features/Shared/BuiltInIcons.cpp} (100%) rename new_editor/app/{Icons/ProductBuiltInIcons.h => Features/Shared/BuiltInIcons.h} (100%) rename new_editor/app/{Panels/ProductTreeViewStyle.h => Features/Shared/EditorTreeViewStyle.h} (100%) rename new_editor/app/Shell/{ProductShellAsset.cpp => EditorShellAssetBuilder.cpp} (100%) rename new_editor/app/Shell/{ProductShellAsset.h => EditorShellAssetBuilder.h} (100%) rename new_editor/app/Viewport/{ProductViewportHostService.cpp => ViewportHostService.cpp} (100%) rename new_editor/app/Viewport/{ProductViewportHostService.h => ViewportHostService.h} (100%) rename new_editor/app/Viewport/{ProductViewportRenderTargetManager.cpp => ViewportRenderTargetManager.cpp} (100%) rename new_editor/app/Viewport/{ProductViewportRenderTargets.cpp => ViewportRenderTargets.cpp} (100%) rename new_editor/app/Viewport/{ProductViewportRenderTargets.h => ViewportRenderTargets.h} (100%) rename new_editor/app/Viewport/{ProductViewportSurfaceUtils.h => ViewportSurfaceUtils.h} (100%) rename new_editor/app/Viewport/{ProductViewportTypes.h => ViewportTypes.h} (100%) rename new_editor/app/Workspace/{ProductEditorWorkspace.cpp => EditorWorkspace.cpp} (100%) rename new_editor/app/Workspace/{ProductEditorWorkspace.h => EditorWorkspace.h} (100%) rename new_editor/app/Workspace/{ProductEditorWorkspaceEventRouter.cpp => EditorWorkspaceEventRouter.cpp} (100%) rename new_editor/app/Workspace/{ProductEditorWorkspaceEventRouter.h => EditorWorkspaceEventRouter.h} (100%) diff --git a/engine/CMakeLists.txt b/engine/CMakeLists.txt index 6f71b783..fa682ce7 100644 --- a/engine/CMakeLists.txt +++ b/engine/CMakeLists.txt @@ -536,8 +536,13 @@ add_library(XCEngine STATIC ${CMAKE_CURRENT_SOURCE_DIR}/src/Rendering/Execution/CameraRenderer.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/Rendering/Execution/Internal/CameraFrameRenderGraphExecution.h ${CMAKE_CURRENT_SOURCE_DIR}/src/Rendering/Execution/Internal/CameraFrameRenderGraphExecution.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/src/Rendering/Execution/Internal/CameraFrameRenderGraphStageRuntime.h ${CMAKE_CURRENT_SOURCE_DIR}/src/Rendering/Execution/Internal/CameraFrameRenderGraphStageRecording.h ${CMAKE_CURRENT_SOURCE_DIR}/src/Rendering/Execution/Internal/CameraFrameRenderGraphStageRecording.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/src/Rendering/Execution/Internal/CameraFrameRenderGraphStageSequenceRecording.h + ${CMAKE_CURRENT_SOURCE_DIR}/src/Rendering/Execution/Internal/CameraFrameRenderGraphStageSequenceRecording.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/src/Rendering/Execution/Internal/CameraFrameRenderGraphStagePassRecording.h + ${CMAKE_CURRENT_SOURCE_DIR}/src/Rendering/Execution/Internal/CameraFrameRenderGraphStagePassRecording.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/Rendering/Execution/Internal/CameraFrameRenderGraphStageState.h ${CMAKE_CURRENT_SOURCE_DIR}/src/Rendering/Execution/Internal/CameraFrameRenderGraphStageState.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/Rendering/Execution/Internal/CameraFrameRenderGraphSurfaceUtils.h diff --git a/engine/src/Rendering/Execution/Internal/CameraFrameRenderGraphStagePassRecording.cpp b/engine/src/Rendering/Execution/Internal/CameraFrameRenderGraphStagePassRecording.cpp new file mode 100644 index 00000000..49d844d9 --- /dev/null +++ b/engine/src/Rendering/Execution/Internal/CameraFrameRenderGraphStagePassRecording.cpp @@ -0,0 +1,384 @@ +#include "Rendering/Execution/Internal/CameraFrameRenderGraphStagePassRecording.h" + +#include "Debug/Logger.h" +#include "Rendering/Execution/CameraFrameRenderGraphStagePolicy.h" +#include "Rendering/Execution/DirectionalShadowExecutionState.h" +#include "Rendering/Execution/Internal/CameraFrameRenderGraphStageRuntime.h" +#include "Rendering/Execution/Internal/CameraFrameRenderGraphStageState.h" +#include "Rendering/Execution/Internal/CameraFrameRenderGraphSurfaceUtils.h" +#include "Rendering/Graph/RenderGraph.h" + +namespace XCEngine { +namespace Rendering { + +namespace { + +bool InitializeStandalonePass( + RenderPass* pass, + const RenderContext& context) { + if (pass == nullptr) { + return false; + } + + if (pass->Initialize(context)) { + return true; + } + + pass->Shutdown(); + return false; +} + +RenderSceneData BuildScenePassRequestSceneData( + const ScenePassRenderRequest& request, + const RenderSurface& requestSurface, + const RenderSceneData& baseSceneData) { + RenderSceneData sceneData = baseSceneData; + if (request.hasCameraDataOverride) { + sceneData.cameraData = request.cameraDataOverride; + } + + sceneData.cameraData.viewportWidth = requestSurface.GetRenderAreaWidth(); + sceneData.cameraData.viewportHeight = requestSurface.GetRenderAreaHeight(); + sceneData.cameraData.clearFlags = request.clearFlags; + if (request.hasClearColorOverride) { + sceneData.cameraData.clearColor = request.clearColorOverride; + } + + return sceneData; +} + +bool ExecuteScenePassRequest( + RenderPass* pass, + const ScenePassRenderRequest& request, + const RenderContext& context, + const RenderSceneData& baseSceneData, + const RenderSurface* surfaceOverride = nullptr) { + if (!request.IsRequested()) { + return true; + } + + if (!InitializeStandalonePass(pass, context)) { + return false; + } + + const RenderSurface& requestSurface = + surfaceOverride != nullptr ? *surfaceOverride : request.surface; + const RenderSceneData sceneData = + BuildScenePassRequestSceneData( + request, + requestSurface, + baseSceneData); + + const RenderPassContext passContext = { + context, + requestSurface, + sceneData, + nullptr, + nullptr, + RHI::ResourceStates::Common + }; + return pass->Execute(passContext); +} + +bool ExecuteStandalonePass( + RenderPass* pass, + const RenderContext& context, + const RenderSurface& surface, + const RenderSceneData& sceneData) { + if (pass == nullptr) { + return false; + } + + if (!InitializeStandalonePass(pass, context)) { + return false; + } + + const RenderPassContext passContext = { + context, + surface, + sceneData, + nullptr, + nullptr, + RHI::ResourceStates::Common + }; + return pass->Execute(passContext); +} + +RenderSceneData BuildStandaloneStageSceneData( + CameraFrameStage stage, + const CameraFramePlan& plan, + const DirectionalShadowExecutionState& shadowState, + const RenderSceneData& baseSceneData, + const RenderSurface& stageSurface) { + if (stage == CameraFrameStage::ShadowCaster && + shadowState.shadowCasterRequest.IsRequested()) { + return BuildScenePassRequestSceneData( + shadowState.shadowCasterRequest, + stageSurface, + baseSceneData); + } + + if (const ScenePassRenderRequest* request = plan.GetScenePassRequest(stage); + request != nullptr) { + return BuildScenePassRequestSceneData( + *request, + stageSurface, + baseSceneData); + } + + return baseSceneData; +} + +RenderPass* ResolveStandaloneStagePass( + CameraFrameStage stage, + CameraFrameExecutionState& executionState) { + switch (stage) { + case CameraFrameStage::ShadowCaster: + return executionState.shadowCasterPass; + case CameraFrameStage::DepthOnly: + return executionState.depthOnlyPass; + case CameraFrameStage::ObjectId: + return executionState.objectIdPass; + default: + return nullptr; + } +} + +bool ExecuteRecordedFrameStage( + CameraFrameStage stage, + const CameraFramePlan& plan, + const DirectionalShadowExecutionState& shadowState, + const RenderSceneData& sceneData, + CameraFrameExecutionState& executionState, + const RenderPassContext& passContext) { + switch (stage) { + case CameraFrameStage::ShadowCaster: + return ExecuteScenePassRequest( + executionState.shadowCasterPass, + shadowState.shadowCasterRequest, + plan.request.context, + sceneData, + &passContext.surface); + case CameraFrameStage::DepthOnly: + return ExecuteScenePassRequest( + executionState.depthOnlyPass, + plan.request.depthOnly, + plan.request.context, + sceneData, + &passContext.surface); + case CameraFrameStage::MainScene: + return executionState.pipeline != nullptr && + executionState.pipeline->Render( + FrameExecutionContext( + plan.request.context, + passContext.surface, + sceneData, + passContext.sourceSurface, + passContext.sourceColorView, + passContext.sourceColorState)); + case CameraFrameStage::ObjectId: + return !plan.request.objectId.IsRequested() || + ExecuteStandalonePass( + executionState.objectIdPass, + plan.request.context, + passContext.surface, + sceneData); + default: + return false; + } +} + +} // namespace + +bool TryRecordCameraFrameStageStandaloneRenderGraphPass( + const CameraFrameStageGraphBuildState& stageState, + const CameraFramePlan& plan, + const DirectionalShadowExecutionState& shadowState, + const RenderSceneData& sceneData, + CameraFrameExecutionState& executionState, + RenderGraphBuilder& graphBuilder, + RenderGraphBlackboard& blackboard, + bool& stageExecutionSucceeded, + bool& handled) { + RenderPass* const standaloneStagePass = + ResolveStandaloneStagePass(stageState.stage, executionState); + if (standaloneStagePass == nullptr || + !standaloneStagePass->SupportsRenderGraph()) { + handled = false; + return true; + } + + handled = true; + const RenderSceneData stageSceneData = + BuildStandaloneStageSceneData( + stageState.stage, + plan, + shadowState, + sceneData, + stageState.surfaceTemplate); + const RenderPassGraphBeginCallback beginStandalonePass = + [&, standaloneStagePass](const RenderPassContext&) -> bool { + if (!InitializeStandalonePass( + standaloneStagePass, + plan.request.context)) { + stageExecutionSucceeded = false; + return false; + } + + return true; + }; + const RenderPassRenderGraphContext standalonePassContext = { + graphBuilder, + stageState.stageName, + plan.request.context, + stageSceneData, + stageState.surfaceTemplate, + stageState.hasSourceSurface + ? &stageState.sourceSurfaceTemplate + : nullptr, + stageState.sourceColorView, + stageState.sourceColorState, + GetPrimaryColorTexture(stageState.sourceSurface), + std::vector{ stageState.outputColor }, + stageState.outputSurface.depthTexture, + &stageExecutionSucceeded, + beginStandalonePass, + {}, + &blackboard + }; + if (!standaloneStagePass->RecordRenderGraph(standalonePassContext)) { + Debug::Logger::Get().Error( + Debug::LogCategory::Rendering, + Containers::String("CameraRenderer::Render failed: RenderPass::RecordRenderGraph returned false for ") + + stageState.stageName); + return false; + } + + return true; +} + +bool TryRecordCameraFrameMainSceneGraphPass( + const CameraFrameStageGraphBuildState& stageState, + const CameraFramePlan& plan, + const RenderSceneData& sceneData, + CameraFrameExecutionState& executionState, + RenderGraphBuilder& graphBuilder, + RenderGraphBlackboard& blackboard, + bool& stageExecutionSucceeded, + bool& handled) { + if (stageState.stage != CameraFrameStage::MainScene || + executionState.pipeline == nullptr || + !executionState.pipeline->SupportsMainSceneRenderGraph()) { + handled = false; + return true; + } + + handled = true; + const RenderPipelineMainSceneRenderGraphContext mainSceneContext = { + graphBuilder, + stageState.stageName, + plan.request.context, + sceneData, + stageState.surfaceTemplate, + stageState.hasSourceSurface + ? &stageState.sourceSurfaceTemplate + : nullptr, + stageState.sourceColorView, + stageState.sourceColorState, + std::vector{ stageState.outputColor }, + stageState.outputSurface.depthTexture, + &stageExecutionSucceeded, + &blackboard + }; + if (!executionState.pipeline->RecordMainSceneRenderGraph(mainSceneContext)) { + Debug::Logger::Get().Error( + Debug::LogCategory::Rendering, + "CameraRenderer::Render failed: RenderPipeline::RecordMainSceneRenderGraph returned false"); + return false; + } + + return true; +} + +void AddCameraFrameStageFallbackRasterPass( + const CameraFrameStageGraphBuildState& stageState, + const CameraFramePlan& plan, + const DirectionalShadowExecutionState& shadowState, + const RenderSceneData& sceneData, + CameraFrameExecutionState& executionState, + RenderGraphBuilder& graphBuilder, + bool& stageExecutionSucceeded) { + const CameraFrameStageGraphBuildState capturedStageState = stageState; + graphBuilder.AddRasterPass( + capturedStageState.stageName, + [&, capturedStageState](RenderGraphPassBuilder& passBuilder) { + if (IsCameraFrameFullscreenSequenceStage(capturedStageState.stage)) { + ReadRenderGraphColorSurface(passBuilder, capturedStageState.sourceSurface); + WriteRenderGraphColorSurface(passBuilder, capturedStageState.outputSurface); + } else { + ReadRenderGraphSurface(passBuilder, capturedStageState.sourceSurface); + WriteRenderGraphSurface(passBuilder, capturedStageState.outputSurface); + } + passBuilder.SetExecuteCallback( + [&, capturedStageState]( + const RenderGraphExecutionContext& executionContext) { + if (!stageExecutionSucceeded) { + return; + } + + const RenderSurface* resolvedSourceSurface = + capturedStageState.hasSourceSurface + ? &capturedStageState.sourceSurfaceTemplate + : nullptr; + RHI::RHIResourceView* resolvedSourceColorView = + capturedStageState.sourceColorView; + RHI::ResourceStates resolvedSourceColorState = + capturedStageState.sourceColorState; + RenderSurface graphManagedSourceSurface = {}; + if (IsCameraFrameFullscreenSequenceStage(capturedStageState.stage) && + capturedStageState.hasSourceSurface && + CanUseGraphManagedImportedSurface( + capturedStageState.sourceSurface, + executionContext)) { + graphManagedSourceSurface = + BuildGraphManagedImportedSurface( + capturedStageState.sourceSurfaceTemplate, + RHI::ResourceStates::PixelShaderResource, + RHI::ResourceStates::PixelShaderResource); + resolvedSourceSurface = &graphManagedSourceSurface; + resolvedSourceColorState = RHI::ResourceStates::PixelShaderResource; + } + + const RenderSurface* resolvedOutputSurface = + &capturedStageState.surfaceTemplate; + RenderSurface graphManagedOutputSurface = {}; + if (CanUseGraphManagedImportedSurface( + capturedStageState.outputSurface, + executionContext)) { + graphManagedOutputSurface = + BuildGraphManagedPassSurface( + capturedStageState.surfaceTemplate); + resolvedOutputSurface = &graphManagedOutputSurface; + } + + const RenderPassContext passContextOverride = { + plan.request.context, + *resolvedOutputSurface, + sceneData, + resolvedSourceSurface, + resolvedSourceColorView, + resolvedSourceColorState + }; + stageExecutionSucceeded = ExecuteRecordedFrameStage( + capturedStageState.stage, + plan, + shadowState, + sceneData, + executionState, + passContextOverride); + }); + }); +} + +} // namespace Rendering +} // namespace XCEngine diff --git a/engine/src/Rendering/Execution/Internal/CameraFrameRenderGraphStagePassRecording.h b/engine/src/Rendering/Execution/Internal/CameraFrameRenderGraphStagePassRecording.h new file mode 100644 index 00000000..51783308 --- /dev/null +++ b/engine/src/Rendering/Execution/Internal/CameraFrameRenderGraphStagePassRecording.h @@ -0,0 +1,45 @@ +#pragma once + +namespace XCEngine { +namespace Rendering { + +struct CameraFrameExecutionState; +struct CameraFramePlan; +struct CameraFrameStageGraphBuildState; +struct DirectionalShadowExecutionState; +struct RenderSceneData; +class RenderGraphBuilder; +class RenderGraphBlackboard; + +bool TryRecordCameraFrameStageStandaloneRenderGraphPass( + const CameraFrameStageGraphBuildState& stageState, + const CameraFramePlan& plan, + const DirectionalShadowExecutionState& shadowState, + const RenderSceneData& sceneData, + CameraFrameExecutionState& executionState, + RenderGraphBuilder& graphBuilder, + RenderGraphBlackboard& blackboard, + bool& stageExecutionSucceeded, + bool& handled); + +bool TryRecordCameraFrameMainSceneGraphPass( + const CameraFrameStageGraphBuildState& stageState, + const CameraFramePlan& plan, + const RenderSceneData& sceneData, + CameraFrameExecutionState& executionState, + RenderGraphBuilder& graphBuilder, + RenderGraphBlackboard& blackboard, + bool& stageExecutionSucceeded, + bool& handled); + +void AddCameraFrameStageFallbackRasterPass( + const CameraFrameStageGraphBuildState& stageState, + const CameraFramePlan& plan, + const DirectionalShadowExecutionState& shadowState, + const RenderSceneData& sceneData, + CameraFrameExecutionState& executionState, + RenderGraphBuilder& graphBuilder, + bool& stageExecutionSucceeded); + +} // namespace Rendering +} // namespace XCEngine diff --git a/engine/src/Rendering/Execution/Internal/CameraFrameRenderGraphStageRecording.cpp b/engine/src/Rendering/Execution/Internal/CameraFrameRenderGraphStageRecording.cpp index 7db3bfda..dbe3e52a 100644 --- a/engine/src/Rendering/Execution/Internal/CameraFrameRenderGraphStageRecording.cpp +++ b/engine/src/Rendering/Execution/Internal/CameraFrameRenderGraphStageRecording.cpp @@ -1,664 +1,19 @@ #include "Rendering/Execution/Internal/CameraFrameRenderGraphStageRecording.h" #include "Debug/Logger.h" +#include "Rendering/Execution/CameraFrameRenderGraphResources.h" #include "Rendering/Execution/CameraFrameRenderGraphStagePolicy.h" -#include "Rendering/Execution/DirectionalShadowExecutionState.h" +#include "Rendering/Execution/Internal/CameraFrameRenderGraphStagePassRecording.h" +#include "Rendering/Execution/Internal/CameraFrameRenderGraphStageRuntime.h" +#include "Rendering/Execution/Internal/CameraFrameRenderGraphStageSequenceRecording.h" #include "Rendering/Execution/Internal/CameraFrameRenderGraphStageState.h" -#include "Rendering/Execution/Internal/CameraFrameRenderGraphSurfaceUtils.h" #include "Rendering/Graph/RenderGraph.h" #include "Rendering/Graph/RenderGraphCompiler.h" #include "Rendering/Graph/RenderGraphExecutor.h" -#include "Rendering/Internal/RenderPassGraphUtils.h" namespace XCEngine { namespace Rendering { -namespace { - -bool InitializeStandalonePass( - RenderPass* pass, - const RenderContext& context) { - if (pass == nullptr) { - return false; - } - - if (pass->Initialize(context)) { - return true; - } - - pass->Shutdown(); - return false; -} - -RenderSceneData BuildScenePassRequestSceneData( - const ScenePassRenderRequest& request, - const RenderSurface& requestSurface, - const RenderSceneData& baseSceneData) { - RenderSceneData sceneData = baseSceneData; - if (request.hasCameraDataOverride) { - sceneData.cameraData = request.cameraDataOverride; - } - - sceneData.cameraData.viewportWidth = requestSurface.GetRenderAreaWidth(); - sceneData.cameraData.viewportHeight = requestSurface.GetRenderAreaHeight(); - sceneData.cameraData.clearFlags = request.clearFlags; - if (request.hasClearColorOverride) { - sceneData.cameraData.clearColor = request.clearColorOverride; - } - - return sceneData; -} - -bool ExecuteScenePassRequest( - RenderPass* pass, - const ScenePassRenderRequest& request, - const RenderContext& context, - const RenderSceneData& baseSceneData, - const RenderSurface* surfaceOverride = nullptr) { - if (!request.IsRequested()) { - return true; - } - - if (!InitializeStandalonePass(pass, context)) { - return false; - } - - const RenderSurface& requestSurface = - surfaceOverride != nullptr ? *surfaceOverride : request.surface; - const RenderSceneData sceneData = - BuildScenePassRequestSceneData( - request, - requestSurface, - baseSceneData); - - const RenderPassContext passContext = { - context, - requestSurface, - sceneData, - nullptr, - nullptr, - RHI::ResourceStates::Common - }; - return pass->Execute(passContext); -} - -bool ExecuteStandalonePass( - RenderPass* pass, - const RenderContext& context, - const RenderSurface& surface, - const RenderSceneData& sceneData) { - if (pass == nullptr) { - return false; - } - - if (!InitializeStandalonePass(pass, context)) { - return false; - } - - const RenderPassContext passContext = { - context, - surface, - sceneData, - nullptr, - nullptr, - RHI::ResourceStates::Common - }; - return pass->Execute(passContext); -} - -RenderSceneData BuildStandaloneStageSceneData( - CameraFrameStage stage, - const CameraFramePlan& plan, - const DirectionalShadowExecutionState& shadowState, - const RenderSceneData& baseSceneData, - const RenderSurface& stageSurface) { - if (stage == CameraFrameStage::ShadowCaster && - shadowState.shadowCasterRequest.IsRequested()) { - return BuildScenePassRequestSceneData( - shadowState.shadowCasterRequest, - stageSurface, - baseSceneData); - } - - if (const ScenePassRenderRequest* request = plan.GetScenePassRequest(stage); - request != nullptr) { - return BuildScenePassRequestSceneData( - *request, - stageSurface, - baseSceneData); - } - - return baseSceneData; -} - -bool EnsureInitializedPassSequence( - std::unique_ptr& activeSequence, - RenderPassSequence* sequence, - const RenderContext& context) { - if (activeSequence == nullptr) { - activeSequence = std::make_unique(sequence, context); - } - - return activeSequence->IsReady(); -} -RenderPass* ResolveStandaloneStagePass( - CameraFrameStage stage, - CameraFrameExecutionState& executionState) { - switch (stage) { - case CameraFrameStage::ShadowCaster: - return executionState.shadowCasterPass; - case CameraFrameStage::DepthOnly: - return executionState.depthOnlyPass; - case CameraFrameStage::ObjectId: - return executionState.objectIdPass; - default: - return nullptr; - } -} - -std::unique_ptr* 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 ExecuteRecordedFrameStage( - CameraFrameStage stage, - const CameraFramePlan& plan, - const DirectionalShadowExecutionState& shadowState, - const RenderSceneData& sceneData, - CameraFrameExecutionState& executionState, - const RenderPassContext& passContext) { - switch (stage) { - case CameraFrameStage::ShadowCaster: - return ExecuteScenePassRequest( - executionState.shadowCasterPass, - shadowState.shadowCasterRequest, - plan.request.context, - sceneData, - &passContext.surface); - case CameraFrameStage::DepthOnly: - return ExecuteScenePassRequest( - executionState.depthOnlyPass, - plan.request.depthOnly, - plan.request.context, - sceneData, - &passContext.surface); - case CameraFrameStage::MainScene: - return executionState.pipeline != nullptr && - executionState.pipeline->Render( - FrameExecutionContext( - plan.request.context, - passContext.surface, - sceneData, - passContext.sourceSurface, - passContext.sourceColorView, - passContext.sourceColorState)); - case CameraFrameStage::ObjectId: - return !plan.request.objectId.IsRequested() || - ExecuteStandalonePass( - executionState.objectIdPass, - plan.request.context, - passContext.surface, - sceneData); - default: - return false; - } -} - -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* 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 CameraFrameRenderGraphSourceBinding& binding, - RenderGraphTextureHandle finalOutputColor, - const RenderSceneData& sceneData, - RenderPassSequence* stageSequence, - CameraFrameExecutionState& executionState, - RenderGraphBuilder& graphBuilder, - RenderGraphBlackboard& blackboard, - bool& stageExecutionSucceeded) { - if (stageSequence == nullptr || stageSequence->GetPassCount() == 0u) { - return true; - } - - std::unique_ptr* 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 = binding.sourceColor; - 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 - ? binding.sourceSurfaceTemplate - : &stagePassContext.surface; - RHI::RHIResourceView* const sourceColorView = - passIndex == 0u - ? binding.sourceColorView - : nullptr; - const RHI::ResourceStates sourceColorState = - passIndex == 0u - ? binding.sourceColorState - : RHI::ResourceStates::PixelShaderResource; - const RenderPassRenderGraphContext passContext = { - graphBuilder, - passName, - stagePassContext.renderContext, - sceneData, - stagePassContext.surface, - sourceSurfaceTemplate, - sourceColorView, - sourceColorState, - currentSourceColor, - std::vector{ passOutputColor }, - {}, - &stageExecutionSucceeded, - beginSequencePass, - {}, - &blackboard - }; - if (!RecordSequencePass( - *pass, - passContext, - { - true, - true, - false - })) { - return false; - } - - currentSourceColor = passOutputColor; - } - - return true; -} - -bool TryRecordCameraFrameStageSequence( - const CameraFrameStageGraphBuildState& stageState, - const CameraFramePlan& plan, - const RenderSceneData& sceneData, - CameraFrameExecutionState& executionState, - RenderGraphBuilder& graphBuilder, - RenderGraphBlackboard& blackboard, - bool& stageExecutionSucceeded, - bool& handled) { - if (stageState.stageSequence == nullptr) { - handled = false; - return true; - } - - handled = true; - const RenderPassContext stagePassContext = - BuildCameraFrameStageGraphPassContext(plan, stageState, sceneData); - const bool recordResult = - IsCameraFrameFullscreenSequenceStage(stageState.stage) - ? RecordFullscreenPassSequenceStage( - stageState.stage, - stageState.stageName, - stagePassContext, - ResolveCameraFrameFullscreenStageGraphSourceBinding( - plan, - stageState.stage, - stageState.surfaceTemplate, - stagePassContext.sourceSurface, - stagePassContext.sourceColorView, - stagePassContext.sourceColorState, - GetPrimaryColorTexture(stageState.sourceSurface), - &blackboard), - stageState.outputColor, - sceneData, - stageState.stageSequence, - executionState, - graphBuilder, - blackboard, - stageExecutionSucceeded) - : RecordRegularPassSequenceStage( - stageState.stage, - stageState.stageName, - stagePassContext, - stageState.outputSurface, - sceneData, - stageState.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 ") + - stageState.stageName); - return false; - } - - return true; -} - -bool TryRecordCameraFrameStageStandaloneRenderGraphPass( - const CameraFrameStageGraphBuildState& stageState, - const CameraFramePlan& plan, - const DirectionalShadowExecutionState& shadowState, - const RenderSceneData& sceneData, - CameraFrameExecutionState& executionState, - RenderGraphBuilder& graphBuilder, - RenderGraphBlackboard& blackboard, - bool& stageExecutionSucceeded, - bool& handled) { - RenderPass* const standaloneStagePass = - ResolveStandaloneStagePass(stageState.stage, executionState); - if (standaloneStagePass == nullptr || - !standaloneStagePass->SupportsRenderGraph()) { - handled = false; - return true; - } - - handled = true; - const RenderSceneData stageSceneData = - BuildStandaloneStageSceneData( - stageState.stage, - plan, - shadowState, - sceneData, - stageState.surfaceTemplate); - const RenderPassGraphBeginCallback beginStandalonePass = - [&, standaloneStagePass](const RenderPassContext&) -> bool { - if (!InitializeStandalonePass( - standaloneStagePass, - plan.request.context)) { - stageExecutionSucceeded = false; - return false; - } - - return true; - }; - const RenderPassRenderGraphContext standalonePassContext = { - graphBuilder, - stageState.stageName, - plan.request.context, - stageSceneData, - stageState.surfaceTemplate, - stageState.hasSourceSurface - ? &stageState.sourceSurfaceTemplate - : nullptr, - stageState.sourceColorView, - stageState.sourceColorState, - GetPrimaryColorTexture(stageState.sourceSurface), - std::vector{ stageState.outputColor }, - stageState.outputSurface.depthTexture, - &stageExecutionSucceeded, - beginStandalonePass, - {}, - &blackboard - }; - if (!standaloneStagePass->RecordRenderGraph(standalonePassContext)) { - Debug::Logger::Get().Error( - Debug::LogCategory::Rendering, - Containers::String("CameraRenderer::Render failed: RenderPass::RecordRenderGraph returned false for ") + - stageState.stageName); - return false; - } - - return true; -} - -bool TryRecordCameraFrameMainSceneGraphPass( - const CameraFrameStageGraphBuildState& stageState, - const CameraFramePlan& plan, - const RenderSceneData& sceneData, - CameraFrameExecutionState& executionState, - RenderGraphBuilder& graphBuilder, - RenderGraphBlackboard& blackboard, - bool& stageExecutionSucceeded, - bool& handled) { - if (stageState.stage != CameraFrameStage::MainScene || - executionState.pipeline == nullptr || - !executionState.pipeline->SupportsMainSceneRenderGraph()) { - handled = false; - return true; - } - - handled = true; - const RenderPipelineMainSceneRenderGraphContext mainSceneContext = { - graphBuilder, - stageState.stageName, - plan.request.context, - sceneData, - stageState.surfaceTemplate, - stageState.hasSourceSurface - ? &stageState.sourceSurfaceTemplate - : nullptr, - stageState.sourceColorView, - stageState.sourceColorState, - std::vector{ stageState.outputColor }, - stageState.outputSurface.depthTexture, - &stageExecutionSucceeded, - &blackboard - }; - if (!executionState.pipeline->RecordMainSceneRenderGraph(mainSceneContext)) { - Debug::Logger::Get().Error( - Debug::LogCategory::Rendering, - "CameraRenderer::Render failed: RenderPipeline::RecordMainSceneRenderGraph returned false"); - return false; - } - - return true; -} - -void AddCameraFrameStageFallbackRasterPass( - const CameraFrameStageGraphBuildState& stageState, - const CameraFramePlan& plan, - const DirectionalShadowExecutionState& shadowState, - const RenderSceneData& sceneData, - CameraFrameExecutionState& executionState, - RenderGraphBuilder& graphBuilder, - bool& stageExecutionSucceeded) { - const CameraFrameStageGraphBuildState capturedStageState = stageState; - graphBuilder.AddRasterPass( - capturedStageState.stageName, - [&, capturedStageState](RenderGraphPassBuilder& passBuilder) { - if (IsCameraFrameFullscreenSequenceStage(capturedStageState.stage)) { - ReadRenderGraphColorSurface(passBuilder, capturedStageState.sourceSurface); - WriteRenderGraphColorSurface(passBuilder, capturedStageState.outputSurface); - } else { - ReadRenderGraphSurface(passBuilder, capturedStageState.sourceSurface); - WriteRenderGraphSurface(passBuilder, capturedStageState.outputSurface); - } - passBuilder.SetExecuteCallback( - [&, capturedStageState]( - const RenderGraphExecutionContext& executionContext) { - if (!stageExecutionSucceeded) { - return; - } - - const RenderSurface* resolvedSourceSurface = - capturedStageState.hasSourceSurface - ? &capturedStageState.sourceSurfaceTemplate - : nullptr; - RHI::RHIResourceView* resolvedSourceColorView = - capturedStageState.sourceColorView; - RHI::ResourceStates resolvedSourceColorState = - capturedStageState.sourceColorState; - RenderSurface graphManagedSourceSurface = {}; - if (IsCameraFrameFullscreenSequenceStage(capturedStageState.stage) && - capturedStageState.hasSourceSurface && - CanUseGraphManagedImportedSurface( - capturedStageState.sourceSurface, - executionContext)) { - graphManagedSourceSurface = - BuildGraphManagedImportedSurface( - capturedStageState.sourceSurfaceTemplate, - RHI::ResourceStates::PixelShaderResource, - RHI::ResourceStates::PixelShaderResource); - resolvedSourceSurface = &graphManagedSourceSurface; - resolvedSourceColorState = RHI::ResourceStates::PixelShaderResource; - } - - const RenderSurface* resolvedOutputSurface = - &capturedStageState.surfaceTemplate; - RenderSurface graphManagedOutputSurface = {}; - if (CanUseGraphManagedImportedSurface( - capturedStageState.outputSurface, - executionContext)) { - graphManagedOutputSurface = - BuildGraphManagedPassSurface( - capturedStageState.surfaceTemplate); - resolvedOutputSurface = &graphManagedOutputSurface; - } - - const RenderPassContext passContextOverride = { - plan.request.context, - *resolvedOutputSurface, - sceneData, - resolvedSourceSurface, - resolvedSourceColorView, - resolvedSourceColorState - }; - stageExecutionSucceeded = ExecuteRecordedFrameStage( - capturedStageState.stage, - plan, - shadowState, - sceneData, - executionState, - passContextOverride); - }); - }); -} - -} // namespace - bool ExecuteCameraFrameRenderGraphStages( const CameraFramePlan& plan, const DirectionalShadowExecutionState& shadowState, @@ -681,7 +36,6 @@ bool ExecuteCameraFrameRenderGraphStages( RenderGraphImportedTextureRegistry importedTextures = {}; bool stageExecutionSucceeded = true; - stageExecutionSucceeded = true; for (const CameraFrameStageInfo& stageInfo : kOrderedCameraFrameStages) { if (!plan.HasFrameStage(stageInfo.stage) && stageInfo.stage != CameraFrameStage::MainScene) { diff --git a/engine/src/Rendering/Execution/Internal/CameraFrameRenderGraphStageRecording.h b/engine/src/Rendering/Execution/Internal/CameraFrameRenderGraphStageRecording.h index 0f556550..5ee076f1 100644 --- a/engine/src/Rendering/Execution/Internal/CameraFrameRenderGraphStageRecording.h +++ b/engine/src/Rendering/Execution/Internal/CameraFrameRenderGraphStageRecording.h @@ -4,63 +4,10 @@ #include #include -#include - namespace XCEngine { namespace Rendering { -struct CameraFrameRenderGraphResources; struct DirectionalShadowExecutionState; -class RenderGraphBuilder; -class RenderGraphBlackboard; - -class ScopedInitializedPassSequence { -public: - ScopedInitializedPassSequence( - RenderPassSequence* sequence, - const RenderContext& context) - : m_sequence(sequence) { - if (m_sequence == nullptr) { - return; - } - - if (!m_sequence->Initialize(context)) { - m_failed = true; - m_sequence->Shutdown(); - m_sequence = nullptr; - } - } - - ScopedInitializedPassSequence(const ScopedInitializedPassSequence&) = delete; - ScopedInitializedPassSequence& operator=(const ScopedInitializedPassSequence&) = delete; - - ~ScopedInitializedPassSequence() { - // Request-owned pass sequences may record GPU work that executes only after the - // caller closes/submits the command list. Do not destroy sequence-owned GPU - // resources here; the sequence owner must shut them down explicitly when the - // sequence is no longer needed. - } - - bool IsReady() const { - return !m_failed; - } - -private: - RenderPassSequence* m_sequence = nullptr; - bool m_failed = false; -}; - -struct CameraFrameExecutionState { - RenderPipeline* pipeline = nullptr; - RenderPass* objectIdPass = nullptr; - RenderPass* depthOnlyPass = nullptr; - RenderPass* shadowCasterPass = nullptr; - std::unique_ptr preScenePasses; - std::unique_ptr postProcessPasses; - std::unique_ptr finalOutputPasses; - std::unique_ptr postScenePasses; - std::unique_ptr overlayPasses; -}; bool ExecuteCameraFrameRenderGraphStages( const CameraFramePlan& plan, diff --git a/engine/src/Rendering/Execution/Internal/CameraFrameRenderGraphStageRuntime.h b/engine/src/Rendering/Execution/Internal/CameraFrameRenderGraphStageRuntime.h new file mode 100644 index 00000000..ea2ecedf --- /dev/null +++ b/engine/src/Rendering/Execution/Internal/CameraFrameRenderGraphStageRuntime.h @@ -0,0 +1,60 @@ +#pragma once + +#include +#include + +#include + +namespace XCEngine { +namespace Rendering { + +class ScopedInitializedPassSequence { +public: + ScopedInitializedPassSequence( + RenderPassSequence* sequence, + const RenderContext& context) + : m_sequence(sequence) { + if (m_sequence == nullptr) { + return; + } + + if (!m_sequence->Initialize(context)) { + m_failed = true; + m_sequence->Shutdown(); + m_sequence = nullptr; + } + } + + ScopedInitializedPassSequence(const ScopedInitializedPassSequence&) = delete; + ScopedInitializedPassSequence& operator=(const ScopedInitializedPassSequence&) = delete; + + ~ScopedInitializedPassSequence() { + // Request-owned pass sequences may record GPU work that executes only after the + // caller closes/submits the command list. Do not destroy sequence-owned GPU + // resources here; the sequence owner must shut them down explicitly when the + // sequence is no longer needed. + } + + bool IsReady() const { + return !m_failed; + } + +private: + RenderPassSequence* m_sequence = nullptr; + bool m_failed = false; +}; + +struct CameraFrameExecutionState { + RenderPipeline* pipeline = nullptr; + RenderPass* objectIdPass = nullptr; + RenderPass* depthOnlyPass = nullptr; + RenderPass* shadowCasterPass = nullptr; + std::unique_ptr preScenePasses; + std::unique_ptr postProcessPasses; + std::unique_ptr finalOutputPasses; + std::unique_ptr postScenePasses; + std::unique_ptr overlayPasses; +}; + +} // namespace Rendering +} // namespace XCEngine diff --git a/engine/src/Rendering/Execution/Internal/CameraFrameRenderGraphStageSequenceRecording.cpp b/engine/src/Rendering/Execution/Internal/CameraFrameRenderGraphStageSequenceRecording.cpp new file mode 100644 index 00000000..d206cee5 --- /dev/null +++ b/engine/src/Rendering/Execution/Internal/CameraFrameRenderGraphStageSequenceRecording.cpp @@ -0,0 +1,298 @@ +#include "Rendering/Execution/Internal/CameraFrameRenderGraphStageSequenceRecording.h" + +#include "Debug/Logger.h" +#include "Rendering/Execution/CameraFrameRenderGraphStagePolicy.h" +#include "Rendering/Execution/Internal/CameraFrameRenderGraphStageRuntime.h" +#include "Rendering/Execution/Internal/CameraFrameRenderGraphStageState.h" +#include "Rendering/Execution/Internal/CameraFrameRenderGraphSurfaceUtils.h" +#include "Rendering/Graph/RenderGraph.h" +#include "Rendering/Internal/RenderPassGraphUtils.h" + +namespace XCEngine { +namespace Rendering { + +namespace { + +bool EnsureInitializedPassSequence( + std::unique_ptr& activeSequence, + RenderPassSequence* sequence, + const RenderContext& context) { + if (activeSequence == nullptr) { + activeSequence = + std::make_unique(sequence, context); + } + + return activeSequence->IsReady(); +} + +std::unique_ptr* 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 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* 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 CameraFrameRenderGraphSourceBinding& binding, + RenderGraphTextureHandle finalOutputColor, + const RenderSceneData& sceneData, + RenderPassSequence* stageSequence, + CameraFrameExecutionState& executionState, + RenderGraphBuilder& graphBuilder, + RenderGraphBlackboard& blackboard, + bool& stageExecutionSucceeded) { + if (stageSequence == nullptr || stageSequence->GetPassCount() == 0u) { + return true; + } + + std::unique_ptr* 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 = binding.sourceColor; + 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 + ? binding.sourceSurfaceTemplate + : &stagePassContext.surface; + RHI::RHIResourceView* const sourceColorView = + passIndex == 0u + ? binding.sourceColorView + : nullptr; + const RHI::ResourceStates sourceColorState = + passIndex == 0u + ? binding.sourceColorState + : RHI::ResourceStates::PixelShaderResource; + const RenderPassRenderGraphContext passContext = { + graphBuilder, + passName, + stagePassContext.renderContext, + sceneData, + stagePassContext.surface, + sourceSurfaceTemplate, + sourceColorView, + sourceColorState, + currentSourceColor, + std::vector{ passOutputColor }, + {}, + &stageExecutionSucceeded, + beginSequencePass, + {}, + &blackboard + }; + if (!RecordSequencePass( + *pass, + passContext, + { + true, + true, + false + })) { + return false; + } + + currentSourceColor = passOutputColor; + } + + return true; +} + +} // namespace + +bool TryRecordCameraFrameStageSequence( + const CameraFrameStageGraphBuildState& stageState, + const CameraFramePlan& plan, + const RenderSceneData& sceneData, + CameraFrameExecutionState& executionState, + RenderGraphBuilder& graphBuilder, + RenderGraphBlackboard& blackboard, + bool& stageExecutionSucceeded, + bool& handled) { + if (stageState.stageSequence == nullptr) { + handled = false; + return true; + } + + handled = true; + const RenderPassContext stagePassContext = + BuildCameraFrameStageGraphPassContext(plan, stageState, sceneData); + const bool recordResult = + IsCameraFrameFullscreenSequenceStage(stageState.stage) + ? RecordFullscreenPassSequenceStage( + stageState.stage, + stageState.stageName, + stagePassContext, + ResolveCameraFrameFullscreenStageGraphSourceBinding( + plan, + stageState.stage, + stageState.surfaceTemplate, + stagePassContext.sourceSurface, + stagePassContext.sourceColorView, + stagePassContext.sourceColorState, + GetPrimaryColorTexture(stageState.sourceSurface), + &blackboard), + stageState.outputColor, + sceneData, + stageState.stageSequence, + executionState, + graphBuilder, + blackboard, + stageExecutionSucceeded) + : RecordRegularPassSequenceStage( + stageState.stage, + stageState.stageName, + stagePassContext, + stageState.outputSurface, + sceneData, + stageState.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 ") + + stageState.stageName); + return false; + } + + return true; +} + +} // namespace Rendering +} // namespace XCEngine diff --git a/engine/src/Rendering/Execution/Internal/CameraFrameRenderGraphStageSequenceRecording.h b/engine/src/Rendering/Execution/Internal/CameraFrameRenderGraphStageSequenceRecording.h new file mode 100644 index 00000000..f62ba39b --- /dev/null +++ b/engine/src/Rendering/Execution/Internal/CameraFrameRenderGraphStageSequenceRecording.h @@ -0,0 +1,24 @@ +#pragma once + +namespace XCEngine { +namespace Rendering { + +struct CameraFrameExecutionState; +struct CameraFramePlan; +struct CameraFrameStageGraphBuildState; +struct RenderSceneData; +class RenderGraphBuilder; +class RenderGraphBlackboard; + +bool TryRecordCameraFrameStageSequence( + const CameraFrameStageGraphBuildState& stageState, + const CameraFramePlan& plan, + const RenderSceneData& sceneData, + CameraFrameExecutionState& executionState, + RenderGraphBuilder& graphBuilder, + RenderGraphBlackboard& blackboard, + bool& stageExecutionSucceeded, + bool& handled); + +} // namespace Rendering +} // namespace XCEngine diff --git a/new_editor/app/Commands/ProductEditorHostCommandBridge.cpp b/new_editor/app/Commands/EditorHostCommandBridge.cpp similarity index 100% rename from new_editor/app/Commands/ProductEditorHostCommandBridge.cpp rename to new_editor/app/Commands/EditorHostCommandBridge.cpp diff --git a/new_editor/app/Commands/ProductEditorHostCommandBridge.h b/new_editor/app/Commands/EditorHostCommandBridge.h similarity index 100% rename from new_editor/app/Commands/ProductEditorHostCommandBridge.h rename to new_editor/app/Commands/EditorHostCommandBridge.h diff --git a/new_editor/app/Core/ProductEditorContext.cpp b/new_editor/app/Core/EditorContext.cpp similarity index 100% rename from new_editor/app/Core/ProductEditorContext.cpp rename to new_editor/app/Core/EditorContext.cpp diff --git a/new_editor/app/Core/ProductEditorContext.h b/new_editor/app/Core/EditorContext.h similarity index 100% rename from new_editor/app/Core/ProductEditorContext.h rename to new_editor/app/Core/EditorContext.h diff --git a/new_editor/app/Core/ProductEditorSession.cpp b/new_editor/app/Core/EditorSession.cpp similarity index 100% rename from new_editor/app/Core/ProductEditorSession.cpp rename to new_editor/app/Core/EditorSession.cpp diff --git a/new_editor/app/Core/ProductEditorSession.h b/new_editor/app/Core/EditorSession.h similarity index 100% rename from new_editor/app/Core/ProductEditorSession.h rename to new_editor/app/Core/EditorSession.h diff --git a/new_editor/app/Panels/ProductConsolePanel.cpp b/new_editor/app/Features/Console/ConsolePanel.cpp similarity index 100% rename from new_editor/app/Panels/ProductConsolePanel.cpp rename to new_editor/app/Features/Console/ConsolePanel.cpp diff --git a/new_editor/app/Panels/ProductConsolePanel.h b/new_editor/app/Features/Console/ConsolePanel.h similarity index 100% rename from new_editor/app/Panels/ProductConsolePanel.h rename to new_editor/app/Features/Console/ConsolePanel.h diff --git a/new_editor/app/Hierarchy/ProductHierarchyModel.cpp b/new_editor/app/Features/Hierarchy/HierarchyModel.cpp similarity index 100% rename from new_editor/app/Hierarchy/ProductHierarchyModel.cpp rename to new_editor/app/Features/Hierarchy/HierarchyModel.cpp diff --git a/new_editor/app/Hierarchy/ProductHierarchyModel.h b/new_editor/app/Features/Hierarchy/HierarchyModel.h similarity index 100% rename from new_editor/app/Hierarchy/ProductHierarchyModel.h rename to new_editor/app/Features/Hierarchy/HierarchyModel.h diff --git a/new_editor/app/Panels/ProductHierarchyPanel.cpp b/new_editor/app/Features/Hierarchy/HierarchyPanel.cpp similarity index 100% rename from new_editor/app/Panels/ProductHierarchyPanel.cpp rename to new_editor/app/Features/Hierarchy/HierarchyPanel.cpp diff --git a/new_editor/app/Panels/ProductHierarchyPanel.h b/new_editor/app/Features/Hierarchy/HierarchyPanel.h similarity index 100% rename from new_editor/app/Panels/ProductHierarchyPanel.h rename to new_editor/app/Features/Hierarchy/HierarchyPanel.h diff --git a/new_editor/app/Panels/ProductInspectorPanel.cpp b/new_editor/app/Features/Inspector/InspectorPanel.cpp similarity index 100% rename from new_editor/app/Panels/ProductInspectorPanel.cpp rename to new_editor/app/Features/Inspector/InspectorPanel.cpp diff --git a/new_editor/app/Panels/ProductInspectorPanel.h b/new_editor/app/Features/Inspector/InspectorPanel.h similarity index 100% rename from new_editor/app/Panels/ProductInspectorPanel.h rename to new_editor/app/Features/Inspector/InspectorPanel.h diff --git a/new_editor/app/Project/ProductProjectBrowserModel.cpp b/new_editor/app/Features/Project/ProjectBrowserModel.cpp similarity index 100% rename from new_editor/app/Project/ProductProjectBrowserModel.cpp rename to new_editor/app/Features/Project/ProjectBrowserModel.cpp diff --git a/new_editor/app/Project/ProductProjectBrowserModel.h b/new_editor/app/Features/Project/ProjectBrowserModel.h similarity index 100% rename from new_editor/app/Project/ProductProjectBrowserModel.h rename to new_editor/app/Features/Project/ProjectBrowserModel.h diff --git a/new_editor/app/Panels/ProductProjectPanel.cpp b/new_editor/app/Features/Project/ProjectPanel.cpp similarity index 100% rename from new_editor/app/Panels/ProductProjectPanel.cpp rename to new_editor/app/Features/Project/ProjectPanel.cpp diff --git a/new_editor/app/Panels/ProductProjectPanel.h b/new_editor/app/Features/Project/ProjectPanel.h similarity index 100% rename from new_editor/app/Panels/ProductProjectPanel.h rename to new_editor/app/Features/Project/ProjectPanel.h diff --git a/new_editor/app/Icons/ProductBuiltInIcons.cpp b/new_editor/app/Features/Shared/BuiltInIcons.cpp similarity index 100% rename from new_editor/app/Icons/ProductBuiltInIcons.cpp rename to new_editor/app/Features/Shared/BuiltInIcons.cpp diff --git a/new_editor/app/Icons/ProductBuiltInIcons.h b/new_editor/app/Features/Shared/BuiltInIcons.h similarity index 100% rename from new_editor/app/Icons/ProductBuiltInIcons.h rename to new_editor/app/Features/Shared/BuiltInIcons.h diff --git a/new_editor/app/Panels/ProductTreeViewStyle.h b/new_editor/app/Features/Shared/EditorTreeViewStyle.h similarity index 100% rename from new_editor/app/Panels/ProductTreeViewStyle.h rename to new_editor/app/Features/Shared/EditorTreeViewStyle.h diff --git a/new_editor/app/Shell/ProductShellAsset.cpp b/new_editor/app/Shell/EditorShellAssetBuilder.cpp similarity index 100% rename from new_editor/app/Shell/ProductShellAsset.cpp rename to new_editor/app/Shell/EditorShellAssetBuilder.cpp diff --git a/new_editor/app/Shell/ProductShellAsset.h b/new_editor/app/Shell/EditorShellAssetBuilder.h similarity index 100% rename from new_editor/app/Shell/ProductShellAsset.h rename to new_editor/app/Shell/EditorShellAssetBuilder.h diff --git a/new_editor/app/Viewport/ProductViewportHostService.cpp b/new_editor/app/Viewport/ViewportHostService.cpp similarity index 100% rename from new_editor/app/Viewport/ProductViewportHostService.cpp rename to new_editor/app/Viewport/ViewportHostService.cpp diff --git a/new_editor/app/Viewport/ProductViewportHostService.h b/new_editor/app/Viewport/ViewportHostService.h similarity index 100% rename from new_editor/app/Viewport/ProductViewportHostService.h rename to new_editor/app/Viewport/ViewportHostService.h diff --git a/new_editor/app/Viewport/ProductViewportRenderTargetManager.cpp b/new_editor/app/Viewport/ViewportRenderTargetManager.cpp similarity index 100% rename from new_editor/app/Viewport/ProductViewportRenderTargetManager.cpp rename to new_editor/app/Viewport/ViewportRenderTargetManager.cpp diff --git a/new_editor/app/Viewport/ProductViewportRenderTargets.cpp b/new_editor/app/Viewport/ViewportRenderTargets.cpp similarity index 100% rename from new_editor/app/Viewport/ProductViewportRenderTargets.cpp rename to new_editor/app/Viewport/ViewportRenderTargets.cpp diff --git a/new_editor/app/Viewport/ProductViewportRenderTargets.h b/new_editor/app/Viewport/ViewportRenderTargets.h similarity index 100% rename from new_editor/app/Viewport/ProductViewportRenderTargets.h rename to new_editor/app/Viewport/ViewportRenderTargets.h diff --git a/new_editor/app/Viewport/ProductViewportSurfaceUtils.h b/new_editor/app/Viewport/ViewportSurfaceUtils.h similarity index 100% rename from new_editor/app/Viewport/ProductViewportSurfaceUtils.h rename to new_editor/app/Viewport/ViewportSurfaceUtils.h diff --git a/new_editor/app/Viewport/ProductViewportTypes.h b/new_editor/app/Viewport/ViewportTypes.h similarity index 100% rename from new_editor/app/Viewport/ProductViewportTypes.h rename to new_editor/app/Viewport/ViewportTypes.h diff --git a/new_editor/app/Workspace/ProductEditorWorkspace.cpp b/new_editor/app/Workspace/EditorWorkspace.cpp similarity index 100% rename from new_editor/app/Workspace/ProductEditorWorkspace.cpp rename to new_editor/app/Workspace/EditorWorkspace.cpp diff --git a/new_editor/app/Workspace/ProductEditorWorkspace.h b/new_editor/app/Workspace/EditorWorkspace.h similarity index 100% rename from new_editor/app/Workspace/ProductEditorWorkspace.h rename to new_editor/app/Workspace/EditorWorkspace.h diff --git a/new_editor/app/Workspace/ProductEditorWorkspaceEventRouter.cpp b/new_editor/app/Workspace/EditorWorkspaceEventRouter.cpp similarity index 100% rename from new_editor/app/Workspace/ProductEditorWorkspaceEventRouter.cpp rename to new_editor/app/Workspace/EditorWorkspaceEventRouter.cpp diff --git a/new_editor/app/Workspace/ProductEditorWorkspaceEventRouter.h b/new_editor/app/Workspace/EditorWorkspaceEventRouter.h similarity index 100% rename from new_editor/app/Workspace/ProductEditorWorkspaceEventRouter.h rename to new_editor/app/Workspace/EditorWorkspaceEventRouter.h