From 5de4848d70acb3cefe0ee60c7f386ca4ef595888 Mon Sep 17 00:00:00 2001 From: ssdfasd <2156608475@qq.com> Date: Tue, 14 Apr 2026 15:08:08 +0800 Subject: [PATCH] Graph-manage single-pass fullscreen stages --- .../Rendering/Execution/CameraRenderer.cpp | 75 +++++++++++++------ .../unit/test_camera_scene_renderer.cpp | 10 +++ 2 files changed, 62 insertions(+), 23 deletions(-) diff --git a/engine/src/Rendering/Execution/CameraRenderer.cpp b/engine/src/Rendering/Execution/CameraRenderer.cpp index 67209c9f..cf1a268c 100644 --- a/engine/src/Rendering/Execution/CameraRenderer.cpp +++ b/engine/src/Rendering/Execution/CameraRenderer.cpp @@ -617,6 +617,8 @@ const RenderSurface* ResolveFrameStageOutputSurface( bool ShouldGraphOwnStageColorTransitions( CameraFrameStage stage) { return stage == CameraFrameStage::MainScene || + stage == CameraFrameStage::PostProcess || + stage == CameraFrameStage::FinalOutput || stage == CameraFrameStage::ObjectId; } @@ -685,20 +687,13 @@ bool ExecuteFrameStage( const DirectionalShadowExecutionState& shadowState, const RenderSceneData& sceneData, CameraFrameExecutionState& executionState, - const RenderSurface* outputSurfaceOverride = nullptr) { + const RenderPassContext* passContextOverride = nullptr) { const RenderPassContext defaultPassContext = BuildFrameStagePassContext(stage, plan, shadowState, sceneData); - const RenderPassContext overridePassContext = { - defaultPassContext.renderContext, - outputSurfaceOverride != nullptr - ? *outputSurfaceOverride - : defaultPassContext.surface, - defaultPassContext.sceneData, - defaultPassContext.sourceSurface, - defaultPassContext.sourceColorView, - defaultPassContext.sourceColorState - }; - const RenderPassContext& passContext = overridePassContext; + const RenderPassContext& passContext = + passContextOverride != nullptr + ? *passContextOverride + : defaultPassContext; switch (stage) { case CameraFrameStage::PreScenePasses: @@ -713,14 +708,14 @@ bool ExecuteFrameStage( shadowState.shadowCasterRequest, plan.request.context, sceneData, - outputSurfaceOverride); + passContextOverride != nullptr ? &passContext.surface : nullptr); case CameraFrameStage::DepthOnly: return ExecuteScenePassRequest( executionState.depthOnlyPass, plan.request.depthOnly, plan.request.context, sceneData, - outputSurfaceOverride); + passContextOverride != nullptr ? &passContext.surface : nullptr); case CameraFrameStage::MainScene: return executionState.pipeline != nullptr && executionState.pipeline->Render( @@ -750,9 +745,7 @@ bool ExecuteFrameStage( ExecuteStandalonePass( executionState.objectIdPass, plan.request.context, - outputSurfaceOverride != nullptr - ? *outputSurfaceOverride - : plan.request.objectId.surface, + passContext.surface, sceneData); case CameraFrameStage::PostScenePasses: return ExecutePassSequenceStage( @@ -887,7 +880,8 @@ bool ExecuteRenderGraphPlan( importedTextures, stageName + ".Source", stagePassContext.sourceSurface, - RenderGraphSurfaceImportUsage::Source); + RenderGraphSurfaceImportUsage::Source, + IsFullscreenSequenceStage(stage)); const RenderGraphImportedSurface outputSurface = ImportRenderGraphSurface( graphBuilder, @@ -898,10 +892,17 @@ bool ExecuteRenderGraphPlan( ShouldGraphOwnStageColorTransitions(stage), ShouldGraphOwnStageDepthTransitions(stage)); const RenderSurface stageSurfaceTemplate = stagePassContext.surface; + const bool hasStageSourceSurface = stagePassContext.sourceSurface != nullptr; + const RenderSurface stageSourceSurfaceTemplate = + hasStageSourceSurface + ? *stagePassContext.sourceSurface + : RenderSurface(); + const RHI::RHIResourceView* const stageSourceColorView = stagePassContext.sourceColorView; + const RHI::ResourceStates stageSourceColorState = stagePassContext.sourceColorState; graphBuilder.AddRasterPass( stageName, - [&, sourceSurface, outputSurface, stage, stageSurfaceTemplate]( + [&, sourceSurface, outputSurface, stage, stageSurfaceTemplate, hasStageSourceSurface, stageSourceSurfaceTemplate, stageSourceColorView, stageSourceColorState]( RenderGraphPassBuilder& passBuilder) { if (IsFullscreenSequenceStage(stage)) { ReadRenderGraphColorSurface(passBuilder, sourceSurface); @@ -911,27 +912,55 @@ bool ExecuteRenderGraphPlan( WriteRenderGraphSurface(passBuilder, outputSurface); } passBuilder.SetExecuteCallback( - [&, stage, outputSurface, stageSurfaceTemplate]( + [&, stage, sourceSurface, outputSurface, stageSurfaceTemplate, hasStageSourceSurface, stageSourceSurfaceTemplate, stageSourceColorView, stageSourceColorState]( const RenderGraphExecutionContext& executionContext) { if (!stageExecutionSucceeded) { return; } - const RenderSurface* outputSurfaceOverride = nullptr; + const RenderSurface* resolvedSourceSurface = + hasStageSourceSurface + ? &stageSourceSurfaceTemplate + : nullptr; + RHI::RHIResourceView* resolvedSourceColorView = + const_cast(stageSourceColorView); + RHI::ResourceStates resolvedSourceColorState = stageSourceColorState; + RenderSurface graphManagedSourceSurface = {}; + if (IsFullscreenSequenceStage(stage) && + hasStageSourceSurface && + CanUseGraphManagedImportedSurface(sourceSurface, executionContext)) { + graphManagedSourceSurface = + BuildGraphManagedImportedSurface( + stageSourceSurfaceTemplate, + RHI::ResourceStates::PixelShaderResource, + RHI::ResourceStates::PixelShaderResource); + resolvedSourceSurface = &graphManagedSourceSurface; + resolvedSourceColorState = RHI::ResourceStates::PixelShaderResource; + } + + const RenderSurface* resolvedOutputSurface = &stageSurfaceTemplate; RenderSurface graphManagedOutputSurface = {}; if (CanUseGraphManagedImportedSurface(outputSurface, executionContext)) { graphManagedOutputSurface = BuildGraphManagedPassSurface(stageSurfaceTemplate); - outputSurfaceOverride = &graphManagedOutputSurface; + resolvedOutputSurface = &graphManagedOutputSurface; } + const RenderPassContext passContextOverride = { + plan.request.context, + *resolvedOutputSurface, + sceneData, + resolvedSourceSurface, + resolvedSourceColorView, + resolvedSourceColorState + }; stageExecutionSucceeded = ExecuteFrameStage( stage, plan, shadowState, sceneData, executionState, - outputSurfaceOverride); + &passContextOverride); }); }); } diff --git a/tests/Rendering/unit/test_camera_scene_renderer.cpp b/tests/Rendering/unit/test_camera_scene_renderer.cpp index d0e05745..a5413f11 100644 --- a/tests/Rendering/unit/test_camera_scene_renderer.cpp +++ b/tests/Rendering/unit/test_camera_scene_renderer.cpp @@ -1008,20 +1008,30 @@ TEST(CameraRenderer_Test, RoutesSceneColorThroughPostProcessAndFinalOutputStages EXPECT_TRUE(postProcessPassRaw->lastHasSourceSurface); EXPECT_EQ(postProcessPassRaw->lastSourceSurfaceWidth, 256u); EXPECT_EQ(postProcessPassRaw->lastSourceSurfaceHeight, 128u); + EXPECT_FALSE(postProcessPassRaw->lastSourceSurfaceAutoTransitionEnabled); EXPECT_EQ( postProcessPassRaw->lastSourceColorView, reinterpret_cast(20)); + EXPECT_EQ( + postProcessPassRaw->lastSourceColorState, + XCEngine::RHI::ResourceStates::PixelShaderResource); EXPECT_EQ(postProcessPassRaw->lastSurfaceWidth, 512u); EXPECT_EQ(postProcessPassRaw->lastSurfaceHeight, 256u); + EXPECT_FALSE(postProcessPassRaw->lastSurfaceAutoTransitionEnabled); ASSERT_NE(finalOutputPassRaw, nullptr); EXPECT_TRUE(finalOutputPassRaw->lastHasSourceSurface); EXPECT_EQ(finalOutputPassRaw->lastSourceSurfaceWidth, 512u); EXPECT_EQ(finalOutputPassRaw->lastSourceSurfaceHeight, 256u); + EXPECT_FALSE(finalOutputPassRaw->lastSourceSurfaceAutoTransitionEnabled); EXPECT_EQ( finalOutputPassRaw->lastSourceColorView, reinterpret_cast(30)); + EXPECT_EQ( + finalOutputPassRaw->lastSourceColorState, + XCEngine::RHI::ResourceStates::PixelShaderResource); EXPECT_EQ(finalOutputPassRaw->lastSurfaceWidth, 800u); EXPECT_EQ(finalOutputPassRaw->lastSurfaceHeight, 600u); + EXPECT_FALSE(finalOutputPassRaw->lastSurfaceAutoTransitionEnabled); EXPECT_EQ( state->eventLog, (std::vector{