From 57331c1c2535ffa3e95a13ba59f82beade49586f Mon Sep 17 00:00:00 2001 From: ssdfasd <2156608475@qq.com> Date: Fri, 10 Apr 2026 02:56:36 +0800 Subject: [PATCH] refactor: unify builtin forward scene execution --- .../Pipelines/BuiltinForwardPipeline.h | 79 ++++++-- .../Pipelines/BuiltinForwardPipeline.cpp | 173 ++++++------------ 2 files changed, 126 insertions(+), 126 deletions(-) diff --git a/engine/include/XCEngine/Rendering/Pipelines/BuiltinForwardPipeline.h b/engine/include/XCEngine/Rendering/Pipelines/BuiltinForwardPipeline.h index b7c066e5..a71d83a1 100644 --- a/engine/include/XCEngine/Rendering/Pipelines/BuiltinForwardPipeline.h +++ b/engine/include/XCEngine/Rendering/Pipelines/BuiltinForwardPipeline.h @@ -36,11 +36,13 @@ namespace Rendering { class RenderSurface; namespace Pipelines { -namespace Detail { -class BuiltinForwardOpaquePass; -class BuiltinForwardSkyboxPass; -class BuiltinForwardTransparentPass; -} // namespace Detail +} // namespace Pipelines + +namespace Passes { +class BuiltinVolumetricPass; +} // namespace Passes + +namespace Pipelines { class BuiltinForwardPipeline : public RenderPipeline { public: @@ -57,10 +59,6 @@ public: const RenderSceneData& sceneData) override; private: - friend class Detail::BuiltinForwardOpaquePass; - friend class Detail::BuiltinForwardSkyboxPass; - friend class Detail::BuiltinForwardTransparentPass; - struct OwnedDescriptorSet { RHI::RHIDescriptorPool* pool = nullptr; RHI::RHIDescriptorSet* set = nullptr; @@ -189,12 +187,22 @@ private: const Resources::Shader* shader = nullptr; Containers::String passName; Containers::String keywordSignature; + Core::uint32 renderTargetCount = 0; + std::array renderTargetFormats = {}; + Core::uint32 depthStencilFormat = 0; + Core::uint32 sampleCount = 1; + Core::uint32 sampleQuality = 0; bool operator==(const PipelineStateKey& other) const { return renderState == other.renderState && shader == other.shader && passName == other.passName && - keywordSignature == other.keywordSignature; + keywordSignature == other.keywordSignature && + renderTargetCount == other.renderTargetCount && + renderTargetFormats == other.renderTargetFormats && + depthStencilFormat == other.depthStencilFormat && + sampleCount == other.sampleCount && + sampleQuality == other.sampleQuality; } }; @@ -208,6 +216,46 @@ private: combine(reinterpret_cast(key.shader)); combine(std::hash{}(key.passName)); combine(std::hash{}(key.keywordSignature)); + combine(std::hash{}(key.renderTargetCount)); + for (Core::uint32 format : key.renderTargetFormats) { + combine(std::hash{}(format)); + } + combine(std::hash{}(key.depthStencilFormat)); + combine(std::hash{}(key.sampleCount)); + combine(std::hash{}(key.sampleQuality)); + return hash; + } + }; + + struct SkyboxPipelineStateKey { + Core::uint32 renderTargetCount = 0; + std::array renderTargetFormats = {}; + Core::uint32 depthStencilFormat = 0; + Core::uint32 sampleCount = 1; + Core::uint32 sampleQuality = 0; + + bool operator==(const SkyboxPipelineStateKey& other) const { + return renderTargetCount == other.renderTargetCount && + renderTargetFormats == other.renderTargetFormats && + depthStencilFormat == other.depthStencilFormat && + sampleCount == other.sampleCount && + sampleQuality == other.sampleQuality; + } + }; + + struct SkyboxPipelineStateKeyHash { + size_t operator()(const SkyboxPipelineStateKey& key) const noexcept { + size_t hash = std::hash{}(key.renderTargetCount); + auto combine = [&hash](size_t value) { + hash ^= value + 0x9e3779b9u + (hash << 6) + (hash >> 2); + }; + + for (Core::uint32 format : key.renderTargetFormats) { + combine(std::hash{}(format)); + } + combine(std::hash{}(key.depthStencilFormat)); + combine(std::hash{}(key.sampleCount)); + combine(std::hash{}(key.sampleQuality)); return hash; } }; @@ -226,8 +274,12 @@ private: const ResolvedShaderPass& resolvedShaderPass); RHI::RHIPipelineState* GetOrCreatePipelineState( const RenderContext& context, + const RenderSurface& surface, const RenderSceneData& sceneData, const Resources::Material* material); + RHI::RHIPipelineState* GetOrCreateSkyboxPipelineState( + const RenderContext& context, + const RenderSurface& surface); bool CreateOwnedDescriptorSet( const BuiltinPassSetLayoutMetadata& setLayout, OwnedDescriptorSet& descriptorSet); @@ -263,10 +315,12 @@ private: bool ExecuteForwardTransparentPass(const RenderPassContext& context); bool DrawVisibleItems( const RenderContext& context, + const RenderSurface& surface, const RenderSceneData& sceneData, bool drawTransparentItems); bool DrawVisibleItem( const RenderContext& context, + const RenderSurface& surface, const RenderSceneData& sceneData, const VisibleRenderItem& visibleItem); bool EnsureSkyboxResources(const RenderContext& context); @@ -292,7 +346,8 @@ private: RHI::RHITexture* m_fallbackTextureCube = nullptr; RHI::RHIResourceView* m_fallbackTextureCubeView = nullptr; RHI::RHIPipelineLayout* m_skyboxPipelineLayout = nullptr; - RHI::RHIPipelineState* m_skyboxPipelineState = nullptr; + Containers::String m_skyboxPassName; + std::unordered_map m_skyboxPipelineStates; OwnedDescriptorSet m_skyboxEnvironmentSet = {}; OwnedDescriptorSet m_skyboxMaterialSet = {}; OwnedDescriptorSet m_skyboxPanoramicTextureSet = {}; @@ -300,7 +355,7 @@ private: OwnedDescriptorSet m_skyboxSamplerSet = {}; RHI::RHIResourceView* m_skyboxBoundPanoramicTextureView = nullptr; RHI::RHIResourceView* m_skyboxBoundCubemapTextureView = nullptr; - RenderPassSequence m_passSequence; + std::unique_ptr m_volumetricPass; }; class BuiltinForwardPipelineAsset final : public RenderPipelineAsset { diff --git a/engine/src/Rendering/Pipelines/BuiltinForwardPipeline.cpp b/engine/src/Rendering/Pipelines/BuiltinForwardPipeline.cpp index 2642baff..41b4d032 100644 --- a/engine/src/Rendering/Pipelines/BuiltinForwardPipeline.cpp +++ b/engine/src/Rendering/Pipelines/BuiltinForwardPipeline.cpp @@ -15,88 +15,6 @@ namespace XCEngine { namespace Rendering { namespace Pipelines { -namespace Internal { - -class BuiltinForwardOpaquePass final : public RenderPass { -public: - explicit BuiltinForwardOpaquePass(BuiltinForwardPipeline& pipeline) - : m_pipeline(pipeline) { - } - - const char* GetName() const override { - return "BuiltinForwardOpaquePass"; - } - - bool Initialize(const RenderContext& context) override { - return m_pipeline.EnsureInitialized(context); - } - - void Shutdown() override { - m_pipeline.DestroyPipelineResources(); - } - - bool Execute(const RenderPassContext& context) override { - return m_pipeline.ExecuteForwardOpaquePass(context); - } - -private: - BuiltinForwardPipeline& m_pipeline; -}; - -class BuiltinForwardSkyboxPass final : public RenderPass { -public: - explicit BuiltinForwardSkyboxPass(BuiltinForwardPipeline& pipeline) - : m_pipeline(pipeline) { - } - - const char* GetName() const override { - return "BuiltinForwardSkyboxPass"; - } - - bool Initialize(const RenderContext& context) override { - return m_pipeline.EnsureInitialized(context); - } - - void Shutdown() override { - m_pipeline.DestroyPipelineResources(); - } - - bool Execute(const RenderPassContext& context) override { - return m_pipeline.ExecuteForwardSkyboxPass(context); - } - -private: - BuiltinForwardPipeline& m_pipeline; -}; - -class BuiltinForwardTransparentPass final : public RenderPass { -public: - explicit BuiltinForwardTransparentPass(BuiltinForwardPipeline& pipeline) - : m_pipeline(pipeline) { - } - - const char* GetName() const override { - return "BuiltinForwardTransparentPass"; - } - - bool Initialize(const RenderContext& context) override { - return m_pipeline.EnsureInitialized(context); - } - - void Shutdown() override { - m_pipeline.DestroyPipelineResources(); - } - - bool Execute(const RenderPassContext& context) override { - return m_pipeline.ExecuteForwardTransparentPass(context); - } - -private: - BuiltinForwardPipeline& m_pipeline; -}; - -} // namespace Internal - namespace { bool IsDepthFormat(RHI::Format format) { @@ -104,6 +22,30 @@ bool IsDepthFormat(RHI::Format format) { format == RHI::Format::D32_Float; } +bool ShouldSampleMainDirectionalShadowMap(const RenderSceneData& sceneData) { + return sceneData.lighting.HasMainDirectionalShadow() && + sceneData.lighting.mainDirectionalShadow.shadowMap != nullptr && + IsDepthFormat(sceneData.lighting.mainDirectionalShadow.shadowMap->GetFormat()); +} + +void TransitionMainDirectionalShadowForSampling( + const RenderContext& context, + const RenderSceneData& sceneData) { + context.commandList->TransitionBarrier( + sceneData.lighting.mainDirectionalShadow.shadowMap, + RHI::ResourceStates::DepthWrite, + RHI::ResourceStates::PixelShaderResource); +} + +void RestoreMainDirectionalShadowAfterSampling( + const RenderContext& context, + const RenderSceneData& sceneData) { + context.commandList->TransitionBarrier( + sceneData.lighting.mainDirectionalShadow.shadowMap, + RHI::ResourceStates::PixelShaderResource, + RHI::ResourceStates::DepthWrite); +} + std::vector CollectSurfaceColorAttachments(const RenderSurface& surface) { std::vector renderTargets; const Core::uint32 colorAttachmentCount = @@ -124,10 +66,7 @@ std::vector CollectSurfaceColorAttachments(const RenderSu } // namespace BuiltinForwardPipeline::BuiltinForwardPipeline() { - m_passSequence.AddPass(std::make_unique(*this)); - m_passSequence.AddPass(std::make_unique(*this)); - m_passSequence.AddPass(std::make_unique()); - m_passSequence.AddPass(std::make_unique(*this)); + m_volumetricPass = std::make_unique(); } BuiltinForwardPipeline::~BuiltinForwardPipeline() { @@ -169,11 +108,16 @@ RHI::InputLayoutDesc BuiltinForwardPipeline::BuildInputLayout() { } bool BuiltinForwardPipeline::Initialize(const RenderContext& context) { - return m_passSequence.Initialize(context); + return EnsureInitialized(context) && + m_volumetricPass != nullptr && + m_volumetricPass->Initialize(context); } void BuiltinForwardPipeline::Shutdown() { - m_passSequence.Shutdown(); + if (m_volumetricPass != nullptr) { + m_volumetricPass->Shutdown(); + } + DestroyPipelineResources(); } bool BuiltinForwardPipeline::Render( @@ -193,7 +137,32 @@ bool BuiltinForwardPipeline::Render( RHI::ResourceStates::Common }; - return m_passSequence.Execute(passContext); + if (!BeginForwardScenePass(passContext)) { + return false; + } + + const bool sampledDirectionalShadow = ShouldSampleMainDirectionalShadowMap(sceneData); + if (sampledDirectionalShadow) { + TransitionMainDirectionalShadowForSampling(context, sceneData); + } + + bool renderResult = ExecuteForwardOpaquePass(passContext); + if (renderResult) { + renderResult = ExecuteForwardSkyboxPass(passContext); + } + if (renderResult && m_volumetricPass != nullptr) { + renderResult = m_volumetricPass->Execute(passContext); + } + if (renderResult) { + renderResult = ExecuteForwardTransparentPass(passContext); + } + + if (sampledDirectionalShadow) { + RestoreMainDirectionalShadowAfterSampling(context, sceneData); + } + EndForwardScenePass(passContext); + + return renderResult; } bool BuiltinForwardPipeline::BeginForwardScenePass(const RenderPassContext& passContext) { @@ -309,18 +278,6 @@ bool BuiltinForwardPipeline::ExecuteForwardOpaquePass(const RenderPassContext& p const RenderSurface& surface = passContext.surface; const RenderSceneData& sceneData = passContext.sceneData; - if (!BeginForwardScenePass(passContext)) { - return false; - } - - if (sceneData.lighting.HasMainDirectionalShadow() && - IsDepthFormat(sceneData.lighting.mainDirectionalShadow.shadowMap->GetFormat())) { - context.commandList->TransitionBarrier( - sceneData.lighting.mainDirectionalShadow.shadowMap, - RHI::ResourceStates::DepthWrite, - RHI::ResourceStates::PixelShaderResource); - } - return DrawVisibleItems(context, surface, sceneData, false); } @@ -329,19 +286,7 @@ bool BuiltinForwardPipeline::ExecuteForwardTransparentPass(const RenderPassConte const RenderSurface& surface = passContext.surface; const RenderSceneData& sceneData = passContext.sceneData; - const bool drawResult = DrawVisibleItems(context, surface, sceneData, true); - - if (sceneData.lighting.HasMainDirectionalShadow() && - IsDepthFormat(sceneData.lighting.mainDirectionalShadow.shadowMap->GetFormat())) { - context.commandList->TransitionBarrier( - sceneData.lighting.mainDirectionalShadow.shadowMap, - RHI::ResourceStates::PixelShaderResource, - RHI::ResourceStates::DepthWrite); - } - - EndForwardScenePass(passContext); - - return drawResult; + return DrawVisibleItems(context, surface, sceneData, true); } bool BuiltinForwardPipeline::DrawVisibleItems(