From 87bf83451b3bd2cc3fc11a041a83edf7fa643fab Mon Sep 17 00:00:00 2001 From: ssdfasd <2156608475@qq.com> Date: Tue, 14 Apr 2026 13:56:08 +0800 Subject: [PATCH] Add render graph depth access semantics --- .../XCEngine/Rendering/Graph/RenderGraph.h | 3 ++ .../Rendering/Graph/RenderGraphCompiler.h | 1 + .../Rendering/Graph/RenderGraphTypes.h | 5 +++ .../Rendering/Execution/CameraRenderer.cpp | 4 +- engine/src/Rendering/Graph/RenderGraph.cpp | 26 ++++++++++++ .../Rendering/Graph/RenderGraphCompiler.cpp | 18 ++++++-- tests/Rendering/unit/test_render_graph.cpp | 41 +++++++++++++++++++ 7 files changed, 93 insertions(+), 5 deletions(-) diff --git a/engine/include/XCEngine/Rendering/Graph/RenderGraph.h b/engine/include/XCEngine/Rendering/Graph/RenderGraph.h index a89d0eb1..188c7767 100644 --- a/engine/include/XCEngine/Rendering/Graph/RenderGraph.h +++ b/engine/include/XCEngine/Rendering/Graph/RenderGraph.h @@ -38,6 +38,7 @@ private: struct TextureAccess { RenderGraphTextureHandle texture = {}; RenderGraphAccessMode mode = RenderGraphAccessMode::Read; + RenderGraphTextureAspect aspect = RenderGraphTextureAspect::Color; }; struct PassNode { @@ -60,6 +61,8 @@ class RenderGraphPassBuilder { public: void ReadTexture(RenderGraphTextureHandle texture); void WriteTexture(RenderGraphTextureHandle texture); + void ReadDepthTexture(RenderGraphTextureHandle texture); + void WriteDepthTexture(RenderGraphTextureHandle texture); void SetExecuteCallback(RenderGraphExecuteCallback callback); private: diff --git a/engine/include/XCEngine/Rendering/Graph/RenderGraphCompiler.h b/engine/include/XCEngine/Rendering/Graph/RenderGraphCompiler.h index cfa49327..2bfb047b 100644 --- a/engine/include/XCEngine/Rendering/Graph/RenderGraphCompiler.h +++ b/engine/include/XCEngine/Rendering/Graph/RenderGraphCompiler.h @@ -31,6 +31,7 @@ private: struct CompiledTextureAccess { RenderGraphTextureHandle texture = {}; RenderGraphAccessMode mode = RenderGraphAccessMode::Read; + RenderGraphTextureAspect aspect = RenderGraphTextureAspect::Color; RHI::ResourceStates requiredState = RHI::ResourceStates::Common; }; diff --git a/engine/include/XCEngine/Rendering/Graph/RenderGraphTypes.h b/engine/include/XCEngine/Rendering/Graph/RenderGraphTypes.h index e1161261..92fac902 100644 --- a/engine/include/XCEngine/Rendering/Graph/RenderGraphTypes.h +++ b/engine/include/XCEngine/Rendering/Graph/RenderGraphTypes.h @@ -35,6 +35,11 @@ enum class RenderGraphAccessMode : Core::uint8 { Write = 1 }; +enum class RenderGraphTextureAspect : Core::uint8 { + Color = 0, + Depth = 1 +}; + enum class RenderGraphTextureViewType : Core::uint8 { RenderTarget = 0, ShaderResource = 1 diff --git a/engine/src/Rendering/Execution/CameraRenderer.cpp b/engine/src/Rendering/Execution/CameraRenderer.cpp index c02fa993..4df788c5 100644 --- a/engine/src/Rendering/Execution/CameraRenderer.cpp +++ b/engine/src/Rendering/Execution/CameraRenderer.cpp @@ -217,7 +217,7 @@ void ReadRenderGraphSurface( } if (surface.depthTexture.IsValid()) { - passBuilder.ReadTexture(surface.depthTexture); + passBuilder.ReadDepthTexture(surface.depthTexture); } } @@ -241,7 +241,7 @@ void WriteRenderGraphSurface( } if (surface.depthTexture.IsValid()) { - passBuilder.WriteTexture(surface.depthTexture); + passBuilder.WriteDepthTexture(surface.depthTexture); } } diff --git a/engine/src/Rendering/Graph/RenderGraph.cpp b/engine/src/Rendering/Graph/RenderGraph.cpp index accfba71..75daab98 100644 --- a/engine/src/Rendering/Graph/RenderGraph.cpp +++ b/engine/src/Rendering/Graph/RenderGraph.cpp @@ -25,6 +25,7 @@ void RenderGraphPassBuilder::ReadTexture(RenderGraphTextureHandle texture) { RenderGraph::TextureAccess access = {}; access.texture = texture; access.mode = RenderGraphAccessMode::Read; + access.aspect = RenderGraphTextureAspect::Color; m_graph->m_passes[m_passHandle.index].accesses.push_back(access); } @@ -36,6 +37,31 @@ void RenderGraphPassBuilder::WriteTexture(RenderGraphTextureHandle texture) { RenderGraph::TextureAccess access = {}; access.texture = texture; access.mode = RenderGraphAccessMode::Write; + access.aspect = RenderGraphTextureAspect::Color; + m_graph->m_passes[m_passHandle.index].accesses.push_back(access); +} + +void RenderGraphPassBuilder::ReadDepthTexture(RenderGraphTextureHandle texture) { + if (m_graph == nullptr || !m_passHandle.IsValid()) { + return; + } + + RenderGraph::TextureAccess access = {}; + access.texture = texture; + access.mode = RenderGraphAccessMode::Read; + access.aspect = RenderGraphTextureAspect::Depth; + m_graph->m_passes[m_passHandle.index].accesses.push_back(access); +} + +void RenderGraphPassBuilder::WriteDepthTexture(RenderGraphTextureHandle texture) { + if (m_graph == nullptr || !m_passHandle.IsValid()) { + return; + } + + RenderGraph::TextureAccess access = {}; + access.texture = texture; + access.mode = RenderGraphAccessMode::Write; + access.aspect = RenderGraphTextureAspect::Depth; m_graph->m_passes[m_passHandle.index].accesses.push_back(access); } diff --git a/engine/src/Rendering/Graph/RenderGraphCompiler.cpp b/engine/src/Rendering/Graph/RenderGraphCompiler.cpp index be80a1ae..56b71ba0 100644 --- a/engine/src/Rendering/Graph/RenderGraphCompiler.cpp +++ b/engine/src/Rendering/Graph/RenderGraphCompiler.cpp @@ -10,13 +10,24 @@ namespace { RHI::ResourceStates ResolveRequiredState( RenderGraphPassType passType, - RenderGraphAccessMode accessMode) { + RenderGraphAccessMode accessMode, + RenderGraphTextureAspect aspect) { if (accessMode == RenderGraphAccessMode::Write) { + if (passType == RenderGraphPassType::Raster && + aspect == RenderGraphTextureAspect::Depth) { + return RHI::ResourceStates::DepthWrite; + } + return passType == RenderGraphPassType::Compute ? RHI::ResourceStates::UnorderedAccess : RHI::ResourceStates::RenderTarget; } + if (passType == RenderGraphPassType::Raster && + aspect == RenderGraphTextureAspect::Depth) { + return RHI::ResourceStates::DepthRead; + } + return passType == RenderGraphPassType::Compute ? RHI::ResourceStates::GenericRead : RHI::ResourceStates::PixelShaderResource; @@ -261,8 +272,9 @@ bool RenderGraphCompiler::Compile( CompiledRenderGraph::CompiledTextureAccess compiledAccess = {}; compiledAccess.texture = access.texture; compiledAccess.mode = access.mode; + compiledAccess.aspect = access.aspect; compiledAccess.requiredState = - ResolveRequiredState(sourcePass.type, access.mode); + ResolveRequiredState(sourcePass.type, access.mode, access.aspect); compiledPass.accesses.push_back(compiledAccess); } compiledPass.executeCallback = sourcePass.executeCallback; @@ -280,7 +292,7 @@ bool RenderGraphCompiler::Compile( lifetime.lastPassIndex = compiledPassIndex; const RHI::ResourceStates accessState = - ResolveRequiredState(sourcePass.type, access.mode); + ResolveRequiredState(sourcePass.type, access.mode, access.aspect); if (!transitionPlan.hasFirstAccessState) { transitionPlan.hasFirstAccessState = true; transitionPlan.firstAccessState = accessState; diff --git a/tests/Rendering/unit/test_render_graph.cpp b/tests/Rendering/unit/test_render_graph.cpp index 41b12c1d..148eefe5 100644 --- a/tests/Rendering/unit/test_render_graph.cpp +++ b/tests/Rendering/unit/test_render_graph.cpp @@ -279,6 +279,17 @@ RenderGraphTextureDesc BuildTestTextureDesc() { return desc; } +RenderGraphTextureDesc BuildTestDepthTextureDesc() { + RenderGraphTextureDesc desc = {}; + desc.width = 1024u; + desc.height = 1024u; + desc.format = static_cast(Format::D24_UNorm_S8_UInt); + desc.textureType = static_cast(TextureType::Texture2D); + desc.sampleCount = 1u; + desc.sampleQuality = 0u; + return desc; +} + } // namespace TEST(RenderGraph_Test, CompilesDeclaredPassOrderAndTracksTextureLifetimes) { @@ -533,6 +544,36 @@ TEST(RenderGraph_Test, RejectsGraphOwnedImportedTextureWithoutView) { EXPECT_FALSE(errorMessage.Empty()); } +TEST(RenderGraph_Test, TracksDepthAttachmentTransitionPlan) { + RenderGraph graph; + RenderGraphBuilder builder(graph); + + const RenderGraphTextureDesc depthDesc = BuildTestDepthTextureDesc(); + const RenderGraphTextureHandle depthTexture = + builder.CreateTransientTexture("SceneDepth", depthDesc); + + builder.AddRasterPass( + "DepthPrepass", + [&](RenderGraphPassBuilder& pass) { + pass.WriteDepthTexture(depthTexture); + }); + + CompiledRenderGraph compiledGraph; + XCEngine::Containers::String errorMessage; + ASSERT_TRUE(RenderGraphCompiler::Compile(graph, compiledGraph, &errorMessage)) + << errorMessage.CStr(); + + RenderGraphTextureTransitionPlan transitionPlan = {}; + ASSERT_TRUE(compiledGraph.TryGetTextureTransitionPlan(depthTexture, transitionPlan)); + EXPECT_TRUE(transitionPlan.graphOwnsTransitions); + EXPECT_TRUE(transitionPlan.hasFirstAccessState); + EXPECT_TRUE(transitionPlan.hasLastAccessState); + EXPECT_EQ(transitionPlan.initialState, ResourceStates::Common); + EXPECT_EQ(transitionPlan.firstAccessState, ResourceStates::DepthWrite); + EXPECT_EQ(transitionPlan.lastAccessState, ResourceStates::DepthWrite); + EXPECT_EQ(transitionPlan.finalState, ResourceStates::DepthWrite); +} + TEST(RenderGraph_Test, ExecutesCompiledPassCallbacksInCompiledOrder) { RenderGraph graph; RenderGraphBuilder builder(graph);