diff --git a/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/DisplayMapper/AcesOutputTransformLutPass.h b/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/DisplayMapper/AcesOutputTransformLutPass.h index bc8673a64b..a6c7615574 100644 --- a/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/DisplayMapper/AcesOutputTransformLutPass.h +++ b/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/DisplayMapper/AcesOutputTransformLutPass.h @@ -48,7 +48,9 @@ namespace AZ void SetShaperParams(const ShaperParams& shaperParams); private: explicit AcesOutputTransformLutPass(const RPI::PassDescriptor& descriptor); - void Init() override; + + // Pass behavior overrides... + void InitializeInternal() override; // Scope producer functions... void SetupFrameGraphDependencies(RHI::FrameGraphInterface frameGraph) override; diff --git a/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/DisplayMapper/AcesOutputTransformPass.h b/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/DisplayMapper/AcesOutputTransformPass.h index 5a0ccdb32a..350b178cfa 100644 --- a/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/DisplayMapper/AcesOutputTransformPass.h +++ b/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/DisplayMapper/AcesOutputTransformPass.h @@ -50,7 +50,9 @@ namespace AZ private: explicit AcesOutputTransformPass(const RPI::PassDescriptor& descriptor); - void Init() override; + + // Pass behavior overrides + void InitializeInternal() override; // Scope producer functions... void CompileResources(const RHI::FrameGraphCompileContext& context) override; diff --git a/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/DisplayMapper/ApplyShaperLookupTablePass.h b/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/DisplayMapper/ApplyShaperLookupTablePass.h index 35d2fcf603..3b6d7f7c27 100644 --- a/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/DisplayMapper/ApplyShaperLookupTablePass.h +++ b/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/DisplayMapper/ApplyShaperLookupTablePass.h @@ -45,7 +45,9 @@ namespace AZ protected: explicit ApplyShaperLookupTablePass(const RPI::PassDescriptor& descriptor); - void Init() override; + + // Pass behavior overrides... + void InitializeInternal() override; RHI::ShaderInputImageIndex m_shaderInputLutImageIndex; diff --git a/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/DisplayMapper/BakeAcesOutputTransformLutPass.h b/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/DisplayMapper/BakeAcesOutputTransformLutPass.h index 60505653b7..0f6f1aa954 100644 --- a/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/DisplayMapper/BakeAcesOutputTransformLutPass.h +++ b/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/DisplayMapper/BakeAcesOutputTransformLutPass.h @@ -57,15 +57,13 @@ namespace AZ explicit BakeAcesOutputTransformLutPass(const RPI::PassDescriptor& descriptor); // Pass behavior overrides... - void FrameBeginInternal(FramePrepareParams params) override; + void InitializeInternal() override; // RHI::ScopeProducer overrides... void SetupFrameGraphDependencies(RHI::FrameGraphInterface frameGraph) override; void CompileResources(const RHI::FrameGraphCompileContext& context) override; void BuildCommandListInternal(const RHI::FrameGraphExecuteContext& context) override; - void Init(); - void AcquireLutImage(); void ReleaseLutImage(); diff --git a/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/DisplayMapper/DisplayMapperFullScreenPass.h b/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/DisplayMapper/DisplayMapperFullScreenPass.h index 94e52d41b0..59c02accdd 100644 --- a/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/DisplayMapper/DisplayMapperFullScreenPass.h +++ b/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/DisplayMapper/DisplayMapperFullScreenPass.h @@ -41,14 +41,11 @@ namespace AZ void SetInputReferencePassName(const Name& passName); void SetInputReferenceAttachmentName(const Name& attachmentName); - // Pass behavior overrides - virtual void BuildAttachmentsInternal() override; - protected: explicit DisplayMapperFullScreenPass(const RPI::PassDescriptor& descriptor); - // FullscreenTrianglePass behavior overrides - virtual void Init(); + // Pass behavior overrides... + virtual void BuildInternal() override; private: Name m_inputReferencePassName = Name{ "Parent" }; diff --git a/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/DisplayMapper/DisplayMapperPass.h b/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/DisplayMapper/DisplayMapperPass.h index 67d9eae9ae..b741a10953 100644 --- a/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/DisplayMapper/DisplayMapperPass.h +++ b/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/DisplayMapper/DisplayMapperPass.h @@ -76,7 +76,8 @@ namespace AZ DisplayMapperPass(const RPI::PassDescriptor& descriptor); // Pass behavior overrides - void BuildAttachmentsInternal() final; + void BuildInternal() final; + void InitializeInternal() final; void FrameBeginInternal(FramePrepareParams params) final; void FrameEndInternal() final; void CreateChildPassesInternal() final; diff --git a/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/DisplayMapper/OutputTransformPass.h b/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/DisplayMapper/OutputTransformPass.h index b266eab14b..caee7ae3dd 100644 --- a/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/DisplayMapper/OutputTransformPass.h +++ b/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/DisplayMapper/OutputTransformPass.h @@ -49,7 +49,9 @@ namespace AZ protected: explicit OutputTransformPass(const RPI::PassDescriptor& descriptor); - void Init() override; + + // Pass behavior overrides + void InitializeInternal() override; private: // Scope producer functions... diff --git a/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/LuxCore/LuxCoreTexturePass.h b/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/LuxCore/LuxCoreTexturePass.h index 23e9c220b2..2ad2af3efd 100644 --- a/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/LuxCore/LuxCoreTexturePass.h +++ b/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/LuxCore/LuxCoreTexturePass.h @@ -42,7 +42,7 @@ namespace AZ protected: // Pass behavior overrides void CreateChildPassesInternal() final; - void BuildAttachmentsInternal() final; + void BuildInternal() final; void FrameBeginInternal(FramePrepareParams params) final; private: diff --git a/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/LuxCore/RenderTexturePass.h b/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/LuxCore/RenderTexturePass.h index 5ae5008a92..cd148d3452 100644 --- a/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/LuxCore/RenderTexturePass.h +++ b/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/LuxCore/RenderTexturePass.h @@ -46,7 +46,7 @@ namespace AZ private: - void BuildAttachmentsInternal() override; + void BuildInternal() override; void FrameBeginInternal(FramePrepareParams params) override; void UpdataAttachment(); diff --git a/Gems/Atom/Feature/Common/Code/Source/Checkerboard/CheckerboardColorResolvePass.cpp b/Gems/Atom/Feature/Common/Code/Source/Checkerboard/CheckerboardColorResolvePass.cpp index 3ebb6b370c..a6c440cf39 100644 --- a/Gems/Atom/Feature/Common/Code/Source/Checkerboard/CheckerboardColorResolvePass.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/Checkerboard/CheckerboardColorResolvePass.cpp @@ -60,7 +60,7 @@ namespace AZ Base::FrameBeginInternal(params); } - void CheckerboardColorResolvePass::BuildAttachmentsInternal() + void CheckerboardColorResolvePass::BuildInternal() { // For each bound attachments they are the inputs from current frame. // We use them to get their owner CheckerboardPass then find the render targets from last frame @@ -99,7 +99,7 @@ namespace AZ // reset frame offset to 0 since attachments are rebuilt m_frameOffset = 0; - Base::BuildAttachmentsInternal(); + Base::BuildInternal(); } void CheckerboardColorResolvePass::CompileResources(const RHI::FrameGraphCompileContext& context) @@ -135,7 +135,7 @@ namespace AZ void CheckerboardColorResolvePass::FrameEndInternal() { // For the input slots for current frame, they always get updated when CheckerboardPass updates the render targets - // But for the input slots for previous frame, we need to manually update them since they were manually attached in BuildAttachmentsInternal() + // But for the input slots for previous frame, we need to manually update them since they were manually attached in BuildInternal() // // When pass attachment was built, CheckerboardPass creates two resources for each render target. // For example, diffuse_0 and diffuse_1 which diffuse_0 is for even frame and diffuse_1 is for odd frame. diff --git a/Gems/Atom/Feature/Common/Code/Source/Checkerboard/CheckerboardColorResolvePass.h b/Gems/Atom/Feature/Common/Code/Source/Checkerboard/CheckerboardColorResolvePass.h index 8cb15d5f49..93930e2bbc 100644 --- a/Gems/Atom/Feature/Common/Code/Source/Checkerboard/CheckerboardColorResolvePass.h +++ b/Gems/Atom/Feature/Common/Code/Source/Checkerboard/CheckerboardColorResolvePass.h @@ -52,7 +52,7 @@ namespace AZ protected: // Pass overrides... void FrameBeginInternal(FramePrepareParams params) override; - void BuildAttachmentsInternal() override; + void BuildInternal() override; void FrameEndInternal() override; // Scope producer functions... diff --git a/Gems/Atom/Feature/Common/Code/Source/Checkerboard/CheckerboardPass.cpp b/Gems/Atom/Feature/Common/Code/Source/Checkerboard/CheckerboardPass.cpp index 09c69dfe18..a781c460f5 100644 --- a/Gems/Atom/Feature/Common/Code/Source/Checkerboard/CheckerboardPass.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/Checkerboard/CheckerboardPass.cpp @@ -50,7 +50,7 @@ namespace AZ Base::FrameBeginInternal(params); } - void CheckerboardPass::BuildAttachmentsInternal() + void CheckerboardPass::BuildInternal() { Data::Instance pool = RPI::ImageSystemInterface::Get()->GetSystemAttachmentPool(); @@ -101,7 +101,7 @@ namespace AZ // reset frame offset to 0 since attachments are rebuilt m_frameOffset = 0; - Base::BuildAttachmentsInternal(); + Base::BuildInternal(); } diff --git a/Gems/Atom/Feature/Common/Code/Source/Checkerboard/CheckerboardPass.h b/Gems/Atom/Feature/Common/Code/Source/Checkerboard/CheckerboardPass.h index 3b905cc3db..02429bb837 100644 --- a/Gems/Atom/Feature/Common/Code/Source/Checkerboard/CheckerboardPass.h +++ b/Gems/Atom/Feature/Common/Code/Source/Checkerboard/CheckerboardPass.h @@ -40,7 +40,7 @@ namespace AZ protected: // Pass overrides... void FrameBeginInternal(FramePrepareParams params); - void BuildAttachmentsInternal() override; + void BuildInternal() override; void FrameEndInternal() override; private: diff --git a/Gems/Atom/Feature/Common/Code/Source/CoreLights/CascadedShadowmapsPass.cpp b/Gems/Atom/Feature/Common/Code/Source/CoreLights/CascadedShadowmapsPass.cpp index d83201533c..b9beac4285 100644 --- a/Gems/Atom/Feature/Common/Code/Source/CoreLights/CascadedShadowmapsPass.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/CoreLights/CascadedShadowmapsPass.cpp @@ -100,7 +100,7 @@ namespace AZ m_arraySize = arraySize; m_updateChildren = true; - QueueForBuildAttachments(); + QueueForBuildAndInitialization(); m_atlas.Initialize(); for (size_t cascadeIndex = 0; cascadeIndex < m_arraySize; ++cascadeIndex) @@ -149,7 +149,7 @@ namespace AZ return m_atlas; } - void CascadedShadowmapsPass::BuildAttachmentsInternal() + void CascadedShadowmapsPass::BuildInternal() { UpdateChildren(); @@ -159,7 +159,7 @@ namespace AZ } UpdateShadowmapImageSize(); - Base::BuildAttachmentsInternal(); + Base::BuildInternal(); } void CascadedShadowmapsPass::GetPipelineViewTags(RPI::SortedPipelineViewTags& outTags) const @@ -215,7 +215,7 @@ namespace AZ AZ_RPI_PASS_WARNING(child, "CascadedShadowmapsPass child Pass creation failed for %d", cascadeIndex); if (child) { - child->QueueForBuildAttachments(); + child->QueueForBuildAndInitialization(); AddChild(child); } } diff --git a/Gems/Atom/Feature/Common/Code/Source/CoreLights/CascadedShadowmapsPass.h b/Gems/Atom/Feature/Common/Code/Source/CoreLights/CascadedShadowmapsPass.h index aa95e0af44..772be9466d 100644 --- a/Gems/Atom/Feature/Common/Code/Source/CoreLights/CascadedShadowmapsPass.h +++ b/Gems/Atom/Feature/Common/Code/Source/CoreLights/CascadedShadowmapsPass.h @@ -53,7 +53,7 @@ namespace AZ explicit CascadedShadowmapsPass(const RPI::PassDescriptor& descriptor); // RPI::Pass overrides... - void BuildAttachmentsInternal() override; + void BuildInternal() override; void GetPipelineViewTags(RPI::SortedPipelineViewTags& outTags) const override; void GetViewDrawListInfo(RHI::DrawListMask& outDrawListMask, RPI::PassesByDrawList& outPassesByDrawList, const RPI::PipelineViewTag& viewTag) const override; diff --git a/Gems/Atom/Feature/Common/Code/Source/CoreLights/DirectionalLightFeatureProcessor.cpp b/Gems/Atom/Feature/Common/Code/Source/CoreLights/DirectionalLightFeatureProcessor.cpp index 9b40097716..c4f4bc54b3 100644 --- a/Gems/Atom/Feature/Common/Code/Source/CoreLights/DirectionalLightFeatureProcessor.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/CoreLights/DirectionalLightFeatureProcessor.cpp @@ -1106,7 +1106,7 @@ namespace AZ { for (EsmShadowmapsPass* pass : it.second) { - pass->QueueForBuildAttachments(); + pass->QueueForBuildAndInitialization(); } } } diff --git a/Gems/Atom/Feature/Common/Code/Source/CoreLights/LightCullingPass.cpp b/Gems/Atom/Feature/Common/Code/Source/CoreLights/LightCullingPass.cpp index a9b43ef1e7..fa293ac9fd 100644 --- a/Gems/Atom/Feature/Common/Code/Source/CoreLights/LightCullingPass.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/CoreLights/LightCullingPass.cpp @@ -163,7 +163,6 @@ namespace AZ void LightCullingPass::ResetInternal() { - m_initialized = false; m_tileDataIndex = -1; m_constantDataIndex.Reset(); @@ -260,7 +259,7 @@ namespace AZ return gridPixelSize; } - void LightCullingPass::BuildAttachmentsInternal() + void LightCullingPass::BuildInternal() { m_tileDataIndex = FindInputBinding(AZ::Name("TileLightData")); CreateLightList(); diff --git a/Gems/Atom/Feature/Common/Code/Source/CoreLights/LightCullingPass.h b/Gems/Atom/Feature/Common/Code/Source/CoreLights/LightCullingPass.h index d8699ea0c7..8080379716 100644 --- a/Gems/Atom/Feature/Common/Code/Source/CoreLights/LightCullingPass.h +++ b/Gems/Atom/Feature/Common/Code/Source/CoreLights/LightCullingPass.h @@ -50,7 +50,7 @@ namespace AZ // Pass behavior overrides... void ResetInternal()override; - void BuildAttachmentsInternal() override; + void BuildInternal() override; // Scope producer functions... void CompileResources(const RHI::FrameGraphCompileContext& context) override; @@ -96,7 +96,6 @@ namespace AZ AZ::RHI::ShaderInputNameIndex m_constantDataIndex = "m_constantData"; - bool m_initialized = false; Data::Instance m_lightList; uint32_t m_tileDataIndex = -1; diff --git a/Gems/Atom/Feature/Common/Code/Source/CoreLights/LightCullingRemap.cpp b/Gems/Atom/Feature/Common/Code/Source/CoreLights/LightCullingRemap.cpp index 26e4ed9f6e..d13e72815b 100644 --- a/Gems/Atom/Feature/Common/Code/Source/CoreLights/LightCullingRemap.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/CoreLights/LightCullingRemap.cpp @@ -108,7 +108,7 @@ namespace AZ return -1; } - void LightCullingRemap::BuildAttachmentsInternal() + void LightCullingRemap::BuildInternal() { m_tileDataIndex = FindInputOutputBinding(AZ::Name("TileLightData")); m_tileDim = GetTileDataBufferResolution(); diff --git a/Gems/Atom/Feature/Common/Code/Source/CoreLights/LightCullingRemap.h b/Gems/Atom/Feature/Common/Code/Source/CoreLights/LightCullingRemap.h index 0738acd459..6d60f93a64 100644 --- a/Gems/Atom/Feature/Common/Code/Source/CoreLights/LightCullingRemap.h +++ b/Gems/Atom/Feature/Common/Code/Source/CoreLights/LightCullingRemap.h @@ -55,7 +55,7 @@ namespace AZ // Pass behavior overrides... void ResetInternal()override; - void BuildAttachmentsInternal() override; + void BuildInternal() override; // RHI::ScopeProducer overrides... void SetupFrameGraphDependencies(RHI::FrameGraphInterface frameGraph) override; diff --git a/Gems/Atom/Feature/Common/Code/Source/CoreLights/LightCullingTilePreparePass.cpp b/Gems/Atom/Feature/Common/Code/Source/CoreLights/LightCullingTilePreparePass.cpp index 816ef25bc6..4f2a4f0346 100644 --- a/Gems/Atom/Feature/Common/Code/Source/CoreLights/LightCullingTilePreparePass.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/CoreLights/LightCullingTilePreparePass.cpp @@ -167,37 +167,36 @@ namespace AZ AZ_Assert(setOk, "LightCullingTilePreparePass::SetConstantData() - could not set constant data"); } - void LightCullingTilePreparePass::BuildAttachmentsInternal() + void LightCullingTilePreparePass::BuildInternal() { ChooseShaderVariant(); } - void LightCullingTilePreparePass::OnShaderReinitialized(const AZ::RPI::Shader&) + void LightCullingTilePreparePass::OnShaderReloaded() { LoadShader(); - if (!m_flags.m_queuedForBuildAttachment && !m_flags.m_isBuildingAttachments) + AZ_Assert(GetPassState() != RPI::PassState::Rendering, "LightCullingTilePreparePass: Trying to reload shader during rendering"); + if (GetPassState() == RPI::PassState::Idle) { ChooseShaderVariant(); } } + + void LightCullingTilePreparePass::OnShaderReinitialized(const AZ::RPI::Shader&) + { + OnShaderReloaded(); + } + void LightCullingTilePreparePass::OnShaderAssetReinitialized(const Data::Asset&) { - LoadShader(); - if (!m_flags.m_queuedForBuildAttachment && !m_flags.m_isBuildingAttachments) - { - ChooseShaderVariant(); - } + OnShaderReloaded(); } void LightCullingTilePreparePass::OnShaderVariantReinitialized( const AZ::RPI::Shader&, const AZ::RPI::ShaderVariantId&, AZ::RPI::ShaderVariantStableId) { - LoadShader(); - if (!m_flags.m_queuedForBuildAttachment && !m_flags.m_isBuildingAttachments) - { - ChooseShaderVariant(); - } + OnShaderReloaded(); } } // namespace Render diff --git a/Gems/Atom/Feature/Common/Code/Source/CoreLights/LightCullingTilePreparePass.h b/Gems/Atom/Feature/Common/Code/Source/CoreLights/LightCullingTilePreparePass.h index efba105912..0febb66e3d 100644 --- a/Gems/Atom/Feature/Common/Code/Source/CoreLights/LightCullingTilePreparePass.h +++ b/Gems/Atom/Feature/Common/Code/Source/CoreLights/LightCullingTilePreparePass.h @@ -50,7 +50,7 @@ namespace AZ LightCullingTilePreparePass(const RPI::PassDescriptor& descriptor); // Pass behavior overrides... - void BuildAttachmentsInternal() override; + void BuildInternal() override; /////////////////////////////////////////////////////////////////// // ShaderReloadNotificationBus overrides... @@ -73,6 +73,7 @@ namespace AZ const AZ::RPI::ShaderVariant& CreateShaderVariant(); void CreatePipelineStateFromShaderVariant(const RPI::ShaderVariant& shaderVariant); void SetConstantData(); + void OnShaderReloaded(); AZ::RHI::ShaderInputNameIndex m_constantDataIndex = "m_constantData"; diff --git a/Gems/Atom/Feature/Common/Code/Source/CoreLights/ProjectedShadowmapsPass.cpp b/Gems/Atom/Feature/Common/Code/Source/CoreLights/ProjectedShadowmapsPass.cpp index d77419fe8f..2f1badaae7 100644 --- a/Gems/Atom/Feature/Common/Code/Source/CoreLights/ProjectedShadowmapsPass.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/CoreLights/ProjectedShadowmapsPass.cpp @@ -73,7 +73,7 @@ namespace AZ { m_sizes = sizes; m_updateChildren = true; - QueueForBuildAttachments(); + QueueForBuildAndInitialization(); m_atlas.Initialize(); for (const auto& it : m_sizes) @@ -156,7 +156,7 @@ namespace AZ return m_atlas; } - void ProjectedShadowmapsPass::BuildAttachmentsInternal() + void ProjectedShadowmapsPass::BuildInternal() { UpdateChildren(); @@ -177,7 +177,7 @@ namespace AZ imageDescriptor.m_size = RHI::Size(shadowmapWidth, shadowmapWidth, 1); imageDescriptor.m_arraySize = m_atlas.GetArraySliceCount(); - Base::BuildAttachmentsInternal(); + Base::BuildInternal(); } void ProjectedShadowmapsPass::GetPipelineViewTags(RPI::SortedPipelineViewTags& outTags) const diff --git a/Gems/Atom/Feature/Common/Code/Source/CoreLights/ProjectedShadowmapsPass.h b/Gems/Atom/Feature/Common/Code/Source/CoreLights/ProjectedShadowmapsPass.h index 63640d22c6..f1963cc885 100644 --- a/Gems/Atom/Feature/Common/Code/Source/CoreLights/ProjectedShadowmapsPass.h +++ b/Gems/Atom/Feature/Common/Code/Source/CoreLights/ProjectedShadowmapsPass.h @@ -71,7 +71,7 @@ namespace AZ explicit ProjectedShadowmapsPass(const RPI::PassDescriptor& descriptor); // RPI::Pass overrides... - void BuildAttachmentsInternal() override; + void BuildInternal() override; void GetPipelineViewTags(RPI::SortedPipelineViewTags& outTags) const override; void GetViewDrawListInfo(RHI::DrawListMask& outDrawListMask, RPI::PassesByDrawList& outPassesByDrawList, const RPI::PipelineViewTag& viewTag) const override; diff --git a/Gems/Atom/Feature/Common/Code/Source/CoreLights/ShadowmapPass.cpp b/Gems/Atom/Feature/Common/Code/Source/CoreLights/ShadowmapPass.cpp index 087a73a94d..d31947da5a 100644 --- a/Gems/Atom/Feature/Common/Code/Source/CoreLights/ShadowmapPass.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/CoreLights/ShadowmapPass.cpp @@ -107,7 +107,7 @@ namespace AZ m_scissorState = scissor; } - void ShadowmapPass::BuildAttachmentsInternal() + void ShadowmapPass::BuildInternal() { RPI::Ptr parentPass = GetParent(); if (!parentPass) @@ -135,7 +135,7 @@ namespace AZ action.m_loadAction = m_clearEnabled ? RHI::AttachmentLoadAction::Clear : RHI::AttachmentLoadAction::DontCare; binding.m_unifiedScopeDesc = RHI::UnifiedScopeAttachmentDescriptor(attachmentId, imageViewDescriptor, action); - Base::BuildAttachmentsInternal(); + Base::BuildInternal(); } } // namespace Render diff --git a/Gems/Atom/Feature/Common/Code/Source/CoreLights/ShadowmapPass.h b/Gems/Atom/Feature/Common/Code/Source/CoreLights/ShadowmapPass.h index 9c308dc4df..2814761a69 100644 --- a/Gems/Atom/Feature/Common/Code/Source/CoreLights/ShadowmapPass.h +++ b/Gems/Atom/Feature/Common/Code/Source/CoreLights/ShadowmapPass.h @@ -58,7 +58,7 @@ namespace AZ explicit ShadowmapPass(const RPI::PassDescriptor& descriptor); // RHI::Pass overrides... - void BuildAttachmentsInternal() override; + void BuildInternal() override; uint16_t m_arraySlice = 0; bool m_clearEnabled = true; diff --git a/Gems/Atom/Feature/Common/Code/Source/DisplayMapper/AcesOutputTransformLutPass.cpp b/Gems/Atom/Feature/Common/Code/Source/DisplayMapper/AcesOutputTransformLutPass.cpp index 104a91174d..5e3bde94e9 100644 --- a/Gems/Atom/Feature/Common/Code/Source/DisplayMapper/AcesOutputTransformLutPass.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/DisplayMapper/AcesOutputTransformLutPass.cpp @@ -42,9 +42,9 @@ namespace AZ ReleaseLutImage(); } - void AcesOutputTransformLutPass::Init() + void AcesOutputTransformLutPass::InitializeInternal() { - DisplayMapperFullScreenPass::Init(); + DisplayMapperFullScreenPass::InitializeInternal(); AZ_Assert(m_shaderResourceGroup != nullptr, "AcesOutputTransformLutPass %s has a null shader resource group when calling Init.", GetPathName().GetCStr()); diff --git a/Gems/Atom/Feature/Common/Code/Source/DisplayMapper/AcesOutputTransformPass.cpp b/Gems/Atom/Feature/Common/Code/Source/DisplayMapper/AcesOutputTransformPass.cpp index 6fe38ff032..ec34d40ea6 100644 --- a/Gems/Atom/Feature/Common/Code/Source/DisplayMapper/AcesOutputTransformPass.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/DisplayMapper/AcesOutputTransformPass.cpp @@ -44,9 +44,9 @@ namespace AZ { } - void AcesOutputTransformPass::Init() + void AcesOutputTransformPass::InitializeInternal() { - DisplayMapperFullScreenPass::Init(); + DisplayMapperFullScreenPass::InitializeInternal(); AZ_Assert(m_shaderResourceGroup != nullptr, "AcesOutputTransformPass %s has a null shader resource group when calling Init.", GetPathName().GetCStr()); diff --git a/Gems/Atom/Feature/Common/Code/Source/DisplayMapper/ApplyShaperLookupTablePass.cpp b/Gems/Atom/Feature/Common/Code/Source/DisplayMapper/ApplyShaperLookupTablePass.cpp index 496b4dcc8f..ff910a4b81 100644 --- a/Gems/Atom/Feature/Common/Code/Source/DisplayMapper/ApplyShaperLookupTablePass.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/DisplayMapper/ApplyShaperLookupTablePass.cpp @@ -38,9 +38,9 @@ namespace AZ ReleaseLutImage(); } - void ApplyShaperLookupTablePass::Init() + void ApplyShaperLookupTablePass::InitializeInternal() { - DisplayMapperFullScreenPass::Init(); + DisplayMapperFullScreenPass::InitializeInternal(); AZ_Assert(m_shaderResourceGroup != nullptr, "ApplyShaperLookupTablePass %s has a null shader resource group when calling Init.", GetPathName().GetCStr()); diff --git a/Gems/Atom/Feature/Common/Code/Source/DisplayMapper/BakeAcesOutputTransformLutPass.cpp b/Gems/Atom/Feature/Common/Code/Source/DisplayMapper/BakeAcesOutputTransformLutPass.cpp index 3322b82ff7..7a32925e93 100644 --- a/Gems/Atom/Feature/Common/Code/Source/DisplayMapper/BakeAcesOutputTransformLutPass.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/DisplayMapper/BakeAcesOutputTransformLutPass.cpp @@ -38,17 +38,7 @@ namespace AZ ReleaseLutImage(); } - void BakeAcesOutputTransformLutPass::FrameBeginInternal(FramePrepareParams params) - { - if (!m_flags.m_initialized) - { - Init(); - } - - ComputePass::FrameBeginInternal(params); - } - - void BakeAcesOutputTransformLutPass::Init() + void BakeAcesOutputTransformLutPass::InitializeInternal() { AZ_Assert(m_shaderResourceGroup != nullptr, "BakeAcesOutputTransformLutPass %s has a null shader resource group when calling Init.", GetPathName().GetCStr()); @@ -67,7 +57,6 @@ namespace AZ m_shaderInputShaperBiasIndex = m_shaderResourceGroup->FindShaderInputConstantIndex(Name{ "m_shaperBias" }); m_shaderInputShaperScaleIndex = m_shaderResourceGroup->FindShaderInputConstantIndex(Name{ "m_shaperScale" }); } - m_flags.m_initialized = true; } void BakeAcesOutputTransformLutPass::SetupFrameGraphDependencies(RHI::FrameGraphInterface frameGraph) diff --git a/Gems/Atom/Feature/Common/Code/Source/DisplayMapper/DisplayMapperFullScreenPass.cpp b/Gems/Atom/Feature/Common/Code/Source/DisplayMapper/DisplayMapperFullScreenPass.cpp index ba83fabed3..03fcfbe71d 100644 --- a/Gems/Atom/Feature/Common/Code/Source/DisplayMapper/DisplayMapperFullScreenPass.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/DisplayMapper/DisplayMapperFullScreenPass.cpp @@ -34,7 +34,7 @@ namespace AZ { } - void DisplayMapperFullScreenPass::BuildAttachmentsInternal() + void DisplayMapperFullScreenPass::BuildInternal() { RPI::PassConnection inConnection; inConnection.m_localSlot = InputAttachmentName; @@ -53,9 +53,5 @@ namespace AZ m_inputReferenceAttachmentName = attachmentName; } - void DisplayMapperFullScreenPass::Init() - { - FullscreenTrianglePass::Init(); - } } // namespace Render } // namespace AZ diff --git a/Gems/Atom/Feature/Common/Code/Source/DisplayMapper/DisplayMapperPass.cpp b/Gems/Atom/Feature/Common/Code/Source/DisplayMapper/DisplayMapperPass.cpp index 8ae790e12c..b37c218c21 100644 --- a/Gems/Atom/Feature/Common/Code/Source/DisplayMapper/DisplayMapperPass.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/DisplayMapper/DisplayMapperPass.cpp @@ -46,8 +46,6 @@ namespace AZ DisplayMapperPass::DisplayMapperPass(const RPI::PassDescriptor& descriptor) : RPI::ParentPass(descriptor) { - m_flags.m_alreadyCreated = false; - AzFramework::NativeWindowHandle windowHandle = nullptr; AzFramework::WindowSystemRequestBus::BroadcastResult( windowHandle, @@ -61,8 +59,6 @@ namespace AZ { m_displayMapperConfigurationDescriptor = passData->m_config; } - - m_needToRebuildChildren = true; } DisplayMapperPass::~DisplayMapperPass() @@ -86,7 +82,7 @@ namespace AZ const Name& passName = fullscreenTrianglePass->GetName(); if (passName.GetStringView() == "CopyToSwapChain") { - fullscreenTrianglePass->Invalidate(); + fullscreenTrianglePass->QueueForInitialization(); } } } @@ -137,7 +133,7 @@ namespace AZ } } - void DisplayMapperPass::BuildAttachmentsInternal() + void DisplayMapperPass::BuildInternal() { const Name outputName = Name{ "Output" }; Name inputPass = Name{ "Parent" }; @@ -187,7 +183,21 @@ namespace AZ m_swapChainAttachmentBinding = FindAttachmentBinding(Name("SwapChainOutput")); - ParentPass::BuildAttachmentsInternal(); + ParentPass::BuildInternal(); + } + + void DisplayMapperPass::InitializeInternal() + { + // Force update on bindings because children of display mapper pass have their outputs connect to + // their parent's output, which is a non-conventional and non-standard workflow. Parent outputs are + // updated after child outputs, so post-build the child outputs do not yet point to the attachments on + // the parent bindings they are connected to. Forcing this refresh sets the attachment on the child output. + for (const RPI::Ptr& child : m_children) + { + child->UpdateConnectedBindings(); + } + + RPI::ParentPass::InitializeInternal(); } void DisplayMapperPass::FrameBeginInternal(FramePrepareParams params) @@ -199,24 +209,14 @@ namespace AZ void DisplayMapperPass::FrameEndInternal() { GetDisplayMapperConfiguration(); - if (m_needToRebuildChildren) - { - ClearChildren(); - BuildGradingLutTemplate(); - CreateGradingAndAcesPasses(); - } ParentPass::FrameEndInternal(); } void DisplayMapperPass::CreateChildPassesInternal() { - if (m_needToRebuildChildren) - { - ClearChildren(); - BuildGradingLutTemplate(); - CreateGradingAndAcesPasses(); - } - ParentPass::CreateChildPassesInternal(); + ClearChildren(); + BuildGradingLutTemplate(); + CreateGradingAndAcesPasses(); } AZStd::shared_ptr CreatePassTemplateHelper( @@ -485,7 +485,6 @@ namespace AZ { AddChild(m_ldrGradingLookupTablePass); } - m_needToRebuildChildren = false; } void DisplayMapperPass::GetDisplayMapperConfiguration() @@ -513,7 +512,8 @@ namespace AZ desc.m_ldrColorGradingLut != m_displayMapperConfigurationDescriptor.m_ldrColorGradingLut || desc.m_acesParameterOverrides.m_overrideDefaults != m_displayMapperConfigurationDescriptor.m_acesParameterOverrides.m_overrideDefaults) { - m_needToRebuildChildren = true; + m_flags.m_createChildren = true; + QueueForBuildAndInitialization(); } m_displayMapperConfigurationDescriptor = desc; } @@ -527,41 +527,15 @@ namespace AZ void DisplayMapperPass::ClearChildren() { - if (m_acesOutputTransformPass) - { - RemoveChild(m_acesOutputTransformPass); - m_acesOutputTransformPass = nullptr; - } - if (m_bakeAcesOutputTransformLutPass) - { - RemoveChild(m_bakeAcesOutputTransformLutPass); - m_bakeAcesOutputTransformLutPass = nullptr; - } - if (m_acesOutputTransformLutPass) - { - RemoveChild(m_acesOutputTransformLutPass); - m_acesOutputTransformLutPass = nullptr; - } - if (m_displayMapperPassthroughPass) - { - RemoveChild(m_displayMapperPassthroughPass); - m_displayMapperPassthroughPass = nullptr; - } - if (m_displayMapperOnlyGammaCorrectionPass) - { - RemoveChild(m_displayMapperOnlyGammaCorrectionPass); - m_displayMapperOnlyGammaCorrectionPass = nullptr; - } - if (m_ldrGradingLookupTablePass) - { - RemoveChild(m_ldrGradingLookupTablePass); - m_ldrGradingLookupTablePass = nullptr; - } - if (m_outputTransformPass) - { - RemoveChild(m_outputTransformPass); - m_outputTransformPass = nullptr; - } + RemoveChildren(); + + m_acesOutputTransformPass = nullptr; + m_bakeAcesOutputTransformLutPass = nullptr; + m_acesOutputTransformLutPass = nullptr; + m_displayMapperPassthroughPass = nullptr; + m_displayMapperOnlyGammaCorrectionPass = nullptr; + m_ldrGradingLookupTablePass = nullptr; + m_outputTransformPass = nullptr; } } // namespace Render } // namespace AZ diff --git a/Gems/Atom/Feature/Common/Code/Source/DisplayMapper/OutputTransformPass.cpp b/Gems/Atom/Feature/Common/Code/Source/DisplayMapper/OutputTransformPass.cpp index a6b23171a5..5937f9ee49 100644 --- a/Gems/Atom/Feature/Common/Code/Source/DisplayMapper/OutputTransformPass.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/DisplayMapper/OutputTransformPass.cpp @@ -39,9 +39,9 @@ namespace AZ { } - void OutputTransformPass::Init() + void OutputTransformPass::InitializeInternal() { - DisplayMapperFullScreenPass::Init(); + DisplayMapperFullScreenPass::InitializeInternal(); AZ_Assert(m_shaderResourceGroup != nullptr, "OutputTransformPass %s has a null shader resource group when calling Init.", GetPathName().GetCStr()); diff --git a/Gems/Atom/Feature/Common/Code/Source/ImGui/ImGuiPass.cpp b/Gems/Atom/Feature/Common/Code/Source/ImGui/ImGuiPass.cpp index a29354f723..750402ada8 100644 --- a/Gems/Atom/Feature/Common/Code/Source/ImGui/ImGuiPass.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/ImGui/ImGuiPass.cpp @@ -519,13 +519,13 @@ namespace AZ io.Fonts->TexID = reinterpret_cast(m_fontAtlas.get()); } - void ImGuiPass::OnBuildAttachmentsFinishedInternal() + void ImGuiPass::InitializeInternal() { // Set output format and finalize pipeline state m_pipelineState->SetOutputFromPass(this); m_pipelineState->Finalize(); - Base::OnBuildAttachmentsFinishedInternal(); + Base::InitializeInternal(); } void ImGuiPass::SetupFrameGraphDependencies(RHI::FrameGraphInterface frameGraph) diff --git a/Gems/Atom/Feature/Common/Code/Source/ImGui/ImGuiPass.h b/Gems/Atom/Feature/Common/Code/Source/ImGui/ImGuiPass.h index c8be0d7ee6..f63b515536 100644 --- a/Gems/Atom/Feature/Common/Code/Source/ImGui/ImGuiPass.h +++ b/Gems/Atom/Feature/Common/Code/Source/ImGui/ImGuiPass.h @@ -94,7 +94,7 @@ namespace AZ explicit ImGuiPass(const RPI::PassDescriptor& descriptor); // Pass Behaviour Overrides... - void OnBuildAttachmentsFinishedInternal() override; + void InitializeInternal() override; void FrameBeginInternal(FramePrepareParams params) override; // Scope producer functions diff --git a/Gems/Atom/Feature/Common/Code/Source/LuxCore/LuxCoreTexturePass.cpp b/Gems/Atom/Feature/Common/Code/Source/LuxCore/LuxCoreTexturePass.cpp index 9a921205ab..724511b355 100644 --- a/Gems/Atom/Feature/Common/Code/Source/LuxCore/LuxCoreTexturePass.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/LuxCore/LuxCoreTexturePass.cpp @@ -28,8 +28,6 @@ namespace AZ LuxCoreTexturePass::LuxCoreTexturePass(const RPI::PassDescriptor& descriptor) : ParentPass(descriptor) { - m_flags.m_alreadyCreated = false; - RPI::PassSystemInterface* passSystem = RPI::PassSystemInterface::Get(); // Create render target pass @@ -41,8 +39,6 @@ namespace AZ // Create readback m_readback = AZStd::make_shared(AZ::RHI::ScopeId{ Uuid::CreateRandom().ToString() }); - - CreateChildPasses(); } LuxCoreTexturePass::~LuxCoreTexturePass() @@ -61,9 +57,9 @@ namespace AZ AddChild(m_renderTargetPass); } - void LuxCoreTexturePass::BuildAttachmentsInternal() + void LuxCoreTexturePass::BuildInternal() { - ParentPass::BuildAttachmentsInternal(); + ParentPass::BuildInternal(); } void LuxCoreTexturePass::FrameBeginInternal(FramePrepareParams params) diff --git a/Gems/Atom/Feature/Common/Code/Source/LuxCore/RenderTexturePass.cpp b/Gems/Atom/Feature/Common/Code/Source/LuxCore/RenderTexturePass.cpp index 0782e12278..6e0444dca4 100644 --- a/Gems/Atom/Feature/Common/Code/Source/LuxCore/RenderTexturePass.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/LuxCore/RenderTexturePass.cpp @@ -38,13 +38,13 @@ namespace AZ m_attachmentSize = image->GetRHIImage()->GetDescriptor().m_size; m_attachmentFormat = format; m_shaderResourceGroup->SetImage(m_textureIndex, image); - QueueForBuildAttachments(); + QueueForBuildAndInitialization(); } - void RenderTexturePass::BuildAttachmentsInternal() + void RenderTexturePass::BuildInternal() { UpdataAttachment(); - FullscreenTrianglePass::BuildAttachmentsInternal(); + FullscreenTrianglePass::BuildInternal(); } void RenderTexturePass::FrameBeginInternal(FramePrepareParams params) diff --git a/Gems/Atom/Feature/Common/Code/Source/MorphTargets/MorphTargetComputePass.cpp b/Gems/Atom/Feature/Common/Code/Source/MorphTargets/MorphTargetComputePass.cpp index 1bb537ecef..42acd5c447 100644 --- a/Gems/Atom/Feature/Common/Code/Source/MorphTargets/MorphTargetComputePass.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/MorphTargets/MorphTargetComputePass.cpp @@ -44,7 +44,7 @@ namespace AZ m_skinnedMeshFeatureProcessor = skinnedMeshFeatureProcessor; } - void MorphTargetComputePass::BuildAttachmentsInternal() + void MorphTargetComputePass::BuildInternal() { // The same buffer that skinning writes to is used to manage the computed vertex deltas that are passed from the // morph target pass to the skinning pass. This simplifies things by only requiring one class to manage the memory diff --git a/Gems/Atom/Feature/Common/Code/Source/MorphTargets/MorphTargetComputePass.h b/Gems/Atom/Feature/Common/Code/Source/MorphTargets/MorphTargetComputePass.h index 61fa485fbc..d346edd908 100644 --- a/Gems/Atom/Feature/Common/Code/Source/MorphTargets/MorphTargetComputePass.h +++ b/Gems/Atom/Feature/Common/Code/Source/MorphTargets/MorphTargetComputePass.h @@ -37,7 +37,7 @@ namespace AZ void SetFeatureProcessor(SkinnedMeshFeatureProcessor* m_skinnedMeshFeatureProcessor); private: - void BuildAttachmentsInternal() override; + void BuildInternal() override; void BuildCommandListInternal(const RHI::FrameGraphExecuteContext& context) override; SkinnedMeshFeatureProcessor* m_skinnedMeshFeatureProcessor = nullptr; diff --git a/Gems/Atom/Feature/Common/Code/Source/PostProcessing/BlendColorGradingLutsPass.cpp b/Gems/Atom/Feature/Common/Code/Source/PostProcessing/BlendColorGradingLutsPass.cpp index e0ff253301..433f9c0276 100644 --- a/Gems/Atom/Feature/Common/Code/Source/PostProcessing/BlendColorGradingLutsPass.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/PostProcessing/BlendColorGradingLutsPass.cpp @@ -43,14 +43,9 @@ namespace AZ ReleaseLutImage(); } - void BlendColorGradingLutsPass::FrameBeginInternal(FramePrepareParams params) + void BlendColorGradingLutsPass::InitializeInternal() { - if (!m_flags.m_initialized) - { - Init(); - } - - ComputePass::FrameBeginInternal(params); + InitializeShaderVariant(); } void BlendColorGradingLutsPass::InitializeShaderVariant() @@ -106,12 +101,6 @@ namespace AZ m_needToUpdateShaderVariant = false; } - void BlendColorGradingLutsPass::Init() - { - InitializeShaderVariant(); - m_flags.m_initialized = true; - } - void BlendColorGradingLutsPass::SetupFrameGraphDependencies(RHI::FrameGraphInterface frameGraph) { ComputePass::SetupFrameGraphDependencies(frameGraph); diff --git a/Gems/Atom/Feature/Common/Code/Source/PostProcessing/BlendColorGradingLutsPass.h b/Gems/Atom/Feature/Common/Code/Source/PostProcessing/BlendColorGradingLutsPass.h index c131a3cb38..048d0069f4 100644 --- a/Gems/Atom/Feature/Common/Code/Source/PostProcessing/BlendColorGradingLutsPass.h +++ b/Gems/Atom/Feature/Common/Code/Source/PostProcessing/BlendColorGradingLutsPass.h @@ -56,7 +56,7 @@ namespace AZ explicit BlendColorGradingLutsPass(const RPI::PassDescriptor& descriptor); // Pass behavior overrides... - void FrameBeginInternal(FramePrepareParams params) override; + void InitializeInternal() override; // Scope producer functions... void SetupFrameGraphDependencies(RHI::FrameGraphInterface frameGraph) override; @@ -66,8 +66,6 @@ namespace AZ void InitializeShaderVariant(); void UpdateCurrentShaderVariant(); - void Init(); - void AcquireLutImage(); void ReleaseLutImage(); diff --git a/Gems/Atom/Feature/Common/Code/Source/PostProcessing/BloomBlurPass.cpp b/Gems/Atom/Feature/Common/Code/Source/PostProcessing/BloomBlurPass.cpp index 1427adeb08..af95a76718 100644 --- a/Gems/Atom/Feature/Common/Code/Source/PostProcessing/BloomBlurPass.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/PostProcessing/BloomBlurPass.cpp @@ -252,10 +252,10 @@ namespace AZ } } - void BloomBlurPass::BuildAttachmentsInternal() + void BloomBlurPass::BuildInternal() { BuildChildPasses(); - ParentPass::BuildAttachmentsInternal(); + ParentPass::BuildInternal(); } void BloomBlurPass::FrameBeginInternal(FramePrepareParams params) diff --git a/Gems/Atom/Feature/Common/Code/Source/PostProcessing/BloomBlurPass.h b/Gems/Atom/Feature/Common/Code/Source/PostProcessing/BloomBlurPass.h index e87d831382..4c65368506 100644 --- a/Gems/Atom/Feature/Common/Code/Source/PostProcessing/BloomBlurPass.h +++ b/Gems/Atom/Feature/Common/Code/Source/PostProcessing/BloomBlurPass.h @@ -47,7 +47,7 @@ namespace AZ BloomBlurPass(const RPI::PassDescriptor& descriptor); // Pass behaviour overrides... - void BuildAttachmentsInternal() override; + void BuildInternal() override; void FrameBeginInternal(FramePrepareParams params) override; void GetInputInfo(); diff --git a/Gems/Atom/Feature/Common/Code/Source/PostProcessing/BloomCompositePass.cpp b/Gems/Atom/Feature/Common/Code/Source/PostProcessing/BloomCompositePass.cpp index fbb020cbf3..810353aab1 100644 --- a/Gems/Atom/Feature/Common/Code/Source/PostProcessing/BloomCompositePass.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/PostProcessing/BloomCompositePass.cpp @@ -56,10 +56,10 @@ namespace AZ m_passData = *passData; } - void BloomCompositePass::BuildAttachmentsInternal() + void BloomCompositePass::BuildInternal() { BuildChildPasses(); - ParentPass::BuildAttachmentsInternal(); + ParentPass::BuildInternal(); } void BloomCompositePass::FrameBeginInternal(FramePrepareParams params) diff --git a/Gems/Atom/Feature/Common/Code/Source/PostProcessing/BloomCompositePass.h b/Gems/Atom/Feature/Common/Code/Source/PostProcessing/BloomCompositePass.h index 86d897ae7d..a19947e1d0 100644 --- a/Gems/Atom/Feature/Common/Code/Source/PostProcessing/BloomCompositePass.h +++ b/Gems/Atom/Feature/Common/Code/Source/PostProcessing/BloomCompositePass.h @@ -44,7 +44,7 @@ namespace AZ BloomCompositePass(const RPI::PassDescriptor& descriptor); // Pass behaviour overrides... - void BuildAttachmentsInternal() override; + void BuildInternal() override; void FrameBeginInternal(FramePrepareParams params) override; void GetAttachmentInfo(); diff --git a/Gems/Atom/Feature/Common/Code/Source/PostProcessing/BloomDownsamplePass.cpp b/Gems/Atom/Feature/Common/Code/Source/PostProcessing/BloomDownsamplePass.cpp index 647177a1ce..63779beb16 100644 --- a/Gems/Atom/Feature/Common/Code/Source/PostProcessing/BloomDownsamplePass.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/PostProcessing/BloomDownsamplePass.cpp @@ -74,10 +74,10 @@ namespace AZ AddAttachmentBinding(outBinding); } - ComputePass::BuildAttachmentsInternal(); + ComputePass::BuildInternal(); } - void BloomDownsamplePass::BuildAttachmentsInternal() + void BloomDownsamplePass::BuildInternal() { BuildOutAttachmentBinding(); } diff --git a/Gems/Atom/Feature/Common/Code/Source/PostProcessing/BloomDownsamplePass.h b/Gems/Atom/Feature/Common/Code/Source/PostProcessing/BloomDownsamplePass.h index 824f703417..3eb0ac8740 100644 --- a/Gems/Atom/Feature/Common/Code/Source/PostProcessing/BloomDownsamplePass.h +++ b/Gems/Atom/Feature/Common/Code/Source/PostProcessing/BloomDownsamplePass.h @@ -37,7 +37,7 @@ namespace AZ BloomDownsamplePass(const RPI::PassDescriptor& descriptor); // Pass Behaviour Overrides... - void BuildAttachmentsInternal() override; + void BuildInternal() override; void FrameBeginInternal(FramePrepareParams params) override; void BuildOutAttachmentBinding(); diff --git a/Gems/Atom/Feature/Common/Code/Source/PostProcessing/DepthOfFieldBokehBlurPass.cpp b/Gems/Atom/Feature/Common/Code/Source/PostProcessing/DepthOfFieldBokehBlurPass.cpp index 4a4a8a8b76..090d87e048 100644 --- a/Gems/Atom/Feature/Common/Code/Source/PostProcessing/DepthOfFieldBokehBlurPass.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/PostProcessing/DepthOfFieldBokehBlurPass.cpp @@ -43,9 +43,9 @@ namespace AZ { } - void DepthOfFieldBokehBlurPass::Init() + void DepthOfFieldBokehBlurPass::InitializeInternal() { - FullscreenTrianglePass::Init(); + FullscreenTrianglePass::InitializeInternal(); m_sampleNumberIndex.Reset(); m_radiusMinIndex.Reset(); diff --git a/Gems/Atom/Feature/Common/Code/Source/PostProcessing/DepthOfFieldBokehBlurPass.h b/Gems/Atom/Feature/Common/Code/Source/PostProcessing/DepthOfFieldBokehBlurPass.h index 688138fff0..c9b2dc6be2 100644 --- a/Gems/Atom/Feature/Common/Code/Source/PostProcessing/DepthOfFieldBokehBlurPass.h +++ b/Gems/Atom/Feature/Common/Code/Source/PostProcessing/DepthOfFieldBokehBlurPass.h @@ -39,11 +39,11 @@ namespace AZ protected: // Behaviour functions override... + void InitializeInternal() override; void FrameBeginInternal(FramePrepareParams params) override; private: DepthOfFieldBokehBlurPass(const RPI::PassDescriptor& descriptor); - void Init() override; void InitializeShaderVariant(); void UpdateCurrentShaderVariant(); diff --git a/Gems/Atom/Feature/Common/Code/Source/PostProcessing/DepthOfFieldCompositePass.cpp b/Gems/Atom/Feature/Common/Code/Source/PostProcessing/DepthOfFieldCompositePass.cpp index 30c92963d0..bf88f8f8fb 100644 --- a/Gems/Atom/Feature/Common/Code/Source/PostProcessing/DepthOfFieldCompositePass.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/PostProcessing/DepthOfFieldCompositePass.cpp @@ -40,9 +40,9 @@ namespace AZ { } - void DepthOfFieldCompositePass::Init() + void DepthOfFieldCompositePass::InitializeInternal() { - FullscreenTrianglePass::Init(); + FullscreenTrianglePass::InitializeInternal(); m_backBlendFactorDivision2Index.Reset(); m_backBlendFactorDivision4Index.Reset(); diff --git a/Gems/Atom/Feature/Common/Code/Source/PostProcessing/DepthOfFieldCompositePass.h b/Gems/Atom/Feature/Common/Code/Source/PostProcessing/DepthOfFieldCompositePass.h index fe4d60e679..00afdd0b0b 100644 --- a/Gems/Atom/Feature/Common/Code/Source/PostProcessing/DepthOfFieldCompositePass.h +++ b/Gems/Atom/Feature/Common/Code/Source/PostProcessing/DepthOfFieldCompositePass.h @@ -37,11 +37,11 @@ namespace AZ protected: // Pass behavior overrides... + void InitializeInternal() override; void FrameBeginInternal(FramePrepareParams params) override; private: DepthOfFieldCompositePass(const RPI::PassDescriptor& descriptor); - void Init() override; void InitializeShaderVariant(); void UpdateCurrentShaderVariant(); diff --git a/Gems/Atom/Feature/Common/Code/Source/PostProcessing/DepthOfFieldCopyFocusDepthToCpuPass.cpp b/Gems/Atom/Feature/Common/Code/Source/PostProcessing/DepthOfFieldCopyFocusDepthToCpuPass.cpp index d64bba1957..00d5ad93c3 100644 --- a/Gems/Atom/Feature/Common/Code/Source/PostProcessing/DepthOfFieldCopyFocusDepthToCpuPass.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/PostProcessing/DepthOfFieldCopyFocusDepthToCpuPass.cpp @@ -52,7 +52,7 @@ namespace AZ return depth; } - void DepthOfFieldCopyFocusDepthToCpuPass::BuildAttachmentsInternal() + void DepthOfFieldCopyFocusDepthToCpuPass::BuildInternal() { SetScopeId(RHI::ScopeId(GetPathName())); } diff --git a/Gems/Atom/Feature/Common/Code/Source/PostProcessing/DepthOfFieldCopyFocusDepthToCpuPass.h b/Gems/Atom/Feature/Common/Code/Source/PostProcessing/DepthOfFieldCopyFocusDepthToCpuPass.h index 64301b6e0c..7e8d041e96 100644 --- a/Gems/Atom/Feature/Common/Code/Source/PostProcessing/DepthOfFieldCopyFocusDepthToCpuPass.h +++ b/Gems/Atom/Feature/Common/Code/Source/PostProcessing/DepthOfFieldCopyFocusDepthToCpuPass.h @@ -48,7 +48,7 @@ namespace AZ void BuildCommandList(const RHI::FrameGraphExecuteContext& context) override; // Pass overrides - void BuildAttachmentsInternal() override; + void BuildInternal() override; void FrameBeginInternal(FramePrepareParams params) override; RPI::Ptr m_bufferRef; diff --git a/Gems/Atom/Feature/Common/Code/Source/PostProcessing/DepthOfFieldMaskPass.cpp b/Gems/Atom/Feature/Common/Code/Source/PostProcessing/DepthOfFieldMaskPass.cpp index 3f9c09c88c..93c19e5484 100644 --- a/Gems/Atom/Feature/Common/Code/Source/PostProcessing/DepthOfFieldMaskPass.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/PostProcessing/DepthOfFieldMaskPass.cpp @@ -33,9 +33,9 @@ namespace AZ { } - void DepthOfFieldMaskPass::Init() + void DepthOfFieldMaskPass::InitializeInternal() { - FullscreenTrianglePass::Init(); + FullscreenTrianglePass::InitializeInternal(); m_blendFactorIndex.Reset(); m_inputResolutionInverseIndex.Reset(); diff --git a/Gems/Atom/Feature/Common/Code/Source/PostProcessing/DepthOfFieldMaskPass.h b/Gems/Atom/Feature/Common/Code/Source/PostProcessing/DepthOfFieldMaskPass.h index 09bb08a22c..7e21f87af7 100644 --- a/Gems/Atom/Feature/Common/Code/Source/PostProcessing/DepthOfFieldMaskPass.h +++ b/Gems/Atom/Feature/Common/Code/Source/PostProcessing/DepthOfFieldMaskPass.h @@ -37,11 +37,11 @@ namespace AZ protected: // Pass behavior overrides... + void InitializeInternal() override; void FrameBeginInternal(FramePrepareParams params) override; private: DepthOfFieldMaskPass(const RPI::PassDescriptor& descriptor); - virtual void Init() override; // SRG binding indices... RHI::ShaderInputNameIndex m_blendFactorIndex = "m_blendFactor"; diff --git a/Gems/Atom/Feature/Common/Code/Source/PostProcessing/DepthOfFieldReadBackFocusDepthPass.cpp b/Gems/Atom/Feature/Common/Code/Source/PostProcessing/DepthOfFieldReadBackFocusDepthPass.cpp index c355b7c8a7..6050ac2b2e 100644 --- a/Gems/Atom/Feature/Common/Code/Source/PostProcessing/DepthOfFieldReadBackFocusDepthPass.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/PostProcessing/DepthOfFieldReadBackFocusDepthPass.cpp @@ -34,18 +34,6 @@ namespace AZ DepthOfFieldReadBackFocusDepthPass::DepthOfFieldReadBackFocusDepthPass(const RPI::PassDescriptor& descriptor) : ParentPass(descriptor) { - RPI::PassSystemInterface* passSystem = RPI::PassSystemInterface::Get(); - - // Create read back pass - m_readbackPass = passSystem->CreatePass(AZ::Name("DepthOfFieldReadBackPass")); - AZ_Assert(m_readbackPass, "DepthOfFieldReadBackFocusDepthPass : read back pass is invalid"); - - AddChild(m_readbackPass); - - // Find GetDepth pass on template - auto pass = FindChildPass(Name("DepthOfFieldWriteFocusDepthFromGpu")); - m_getDepthPass = static_cast(pass.get()); - // Create buffer for read back focus depth. We append static counter to avoid name conflicts. RPI::CommonBufferDescriptor desc; desc.m_bufferName = "DepthOfFieldReadBackAutoFocusDepthBuffer"; @@ -55,9 +43,6 @@ namespace AZ desc.m_bufferData = nullptr; desc.m_elementFormat = RHI::Format::R32_FLOAT; m_buffer = RPI::BufferSystemInterface::Get()->CreateBufferFromCommonPool(desc); - - m_getDepthPass->SetBufferRef(m_buffer); - m_readbackPass->SetBufferRef(m_buffer); } DepthOfFieldReadBackFocusDepthPass::~DepthOfFieldReadBackFocusDepthPass() @@ -85,6 +70,24 @@ namespace AZ } } + void DepthOfFieldReadBackFocusDepthPass::CreateChildPassesInternal() + { + RPI::PassSystemInterface* passSystem = RPI::PassSystemInterface::Get(); + + // Create read back pass + m_readbackPass = passSystem->CreatePass(AZ::Name("DepthOfFieldReadBackPass")); + AZ_Assert(m_readbackPass, "DepthOfFieldReadBackFocusDepthPass : read back pass is invalid"); + + AddChild(m_readbackPass); + + // Find GetDepth pass on template + auto pass = FindChildPass(Name("DepthOfFieldWriteFocusDepthFromGpu")); + m_getDepthPass = static_cast(pass.get()); + + m_getDepthPass->SetBufferRef(m_buffer); + m_readbackPass->SetBufferRef(m_buffer); + } + void DepthOfFieldReadBackFocusDepthPass::FrameBeginInternal(FramePrepareParams params) { RPI::Scene* scene = GetScene(); diff --git a/Gems/Atom/Feature/Common/Code/Source/PostProcessing/DepthOfFieldReadBackFocusDepthPass.h b/Gems/Atom/Feature/Common/Code/Source/PostProcessing/DepthOfFieldReadBackFocusDepthPass.h index 75842fb67a..db29576d22 100644 --- a/Gems/Atom/Feature/Common/Code/Source/PostProcessing/DepthOfFieldReadBackFocusDepthPass.h +++ b/Gems/Atom/Feature/Common/Code/Source/PostProcessing/DepthOfFieldReadBackFocusDepthPass.h @@ -43,6 +43,7 @@ namespace AZ protected: // Pass behavior overrides... + void CreateChildPassesInternal() override; void FrameBeginInternal(FramePrepareParams params) override; private: diff --git a/Gems/Atom/Feature/Common/Code/Source/PostProcessing/DepthOfFieldWriteFocusDepthFromGpuPass.cpp b/Gems/Atom/Feature/Common/Code/Source/PostProcessing/DepthOfFieldWriteFocusDepthFromGpuPass.cpp index e7ac891198..4aaf936426 100644 --- a/Gems/Atom/Feature/Common/Code/Source/PostProcessing/DepthOfFieldWriteFocusDepthFromGpuPass.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/PostProcessing/DepthOfFieldWriteFocusDepthFromGpuPass.cpp @@ -62,9 +62,9 @@ namespace AZ m_bufferRef = bufferRef; } - void DepthOfFieldWriteFocusDepthFromGpuPass::BuildAttachmentsInternal() + void DepthOfFieldWriteFocusDepthFromGpuPass::BuildInternal() { - AZ_Assert(m_bufferRef != nullptr, "%s has a null buffer when calling BuildAttachmentsInternal.", GetPathName().GetCStr()); + AZ_Assert(m_bufferRef != nullptr, "%s has a null buffer when calling BuildInternal.", GetPathName().GetCStr()); AttachBufferToSlot(Name("DofDepthInputOutput"), m_bufferRef); } diff --git a/Gems/Atom/Feature/Common/Code/Source/PostProcessing/DepthOfFieldWriteFocusDepthFromGpuPass.h b/Gems/Atom/Feature/Common/Code/Source/PostProcessing/DepthOfFieldWriteFocusDepthFromGpuPass.h index 592ab64c01..881ef9df94 100644 --- a/Gems/Atom/Feature/Common/Code/Source/PostProcessing/DepthOfFieldWriteFocusDepthFromGpuPass.h +++ b/Gems/Atom/Feature/Common/Code/Source/PostProcessing/DepthOfFieldWriteFocusDepthFromGpuPass.h @@ -51,7 +51,7 @@ namespace AZ void CompileResources(const RHI::FrameGraphCompileContext& context) override; // Pass overrides - void BuildAttachmentsInternal() override; + void BuildInternal() override; }; } // namespace Render } // namespace AZ diff --git a/Gems/Atom/Feature/Common/Code/Source/PostProcessing/EyeAdaptationPass.cpp b/Gems/Atom/Feature/Common/Code/Source/PostProcessing/EyeAdaptationPass.cpp index bf293fd3d2..e131f7ad22 100644 --- a/Gems/Atom/Feature/Common/Code/Source/PostProcessing/EyeAdaptationPass.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/PostProcessing/EyeAdaptationPass.cpp @@ -60,7 +60,7 @@ namespace AZ m_buffer = RPI::BufferSystemInterface::Get()->CreateBufferFromCommonPool(desc); } - void EyeAdaptationPass::BuildAttachmentsInternal() + void EyeAdaptationPass::BuildInternal() { if (!m_buffer) { diff --git a/Gems/Atom/Feature/Common/Code/Source/PostProcessing/EyeAdaptationPass.h b/Gems/Atom/Feature/Common/Code/Source/PostProcessing/EyeAdaptationPass.h index cef168a122..d53569a9f9 100644 --- a/Gems/Atom/Feature/Common/Code/Source/PostProcessing/EyeAdaptationPass.h +++ b/Gems/Atom/Feature/Common/Code/Source/PostProcessing/EyeAdaptationPass.h @@ -58,7 +58,7 @@ namespace AZ float m_exposureValue = 1.0f; }; - void BuildAttachmentsInternal() override; + void BuildInternal() override; void FrameBeginInternal(FramePrepareParams params) override; diff --git a/Gems/Atom/Feature/Common/Code/Source/PostProcessing/LookModificationCompositePass.cpp b/Gems/Atom/Feature/Common/Code/Source/PostProcessing/LookModificationCompositePass.cpp index aff01d5bf1..45d3e0c39a 100644 --- a/Gems/Atom/Feature/Common/Code/Source/PostProcessing/LookModificationCompositePass.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/PostProcessing/LookModificationCompositePass.cpp @@ -48,9 +48,9 @@ namespace AZ } } - void LookModificationCompositePass::Init() + void LookModificationCompositePass::InitializeInternal() { - FullscreenTrianglePass::Init(); + FullscreenTrianglePass::InitializeInternal(); m_shaderColorGradingLutImageIndex.Reset(); m_shaderColorGradingShaperTypeIndex.Reset(); diff --git a/Gems/Atom/Feature/Common/Code/Source/PostProcessing/LookModificationCompositePass.h b/Gems/Atom/Feature/Common/Code/Source/PostProcessing/LookModificationCompositePass.h index fb6c968436..8292330a2d 100644 --- a/Gems/Atom/Feature/Common/Code/Source/PostProcessing/LookModificationCompositePass.h +++ b/Gems/Atom/Feature/Common/Code/Source/PostProcessing/LookModificationCompositePass.h @@ -60,9 +60,9 @@ namespace AZ protected: LookModificationCompositePass(const RPI::PassDescriptor& descriptor); - void Init() override; //! Pass behavior overrides + void InitializeInternal() override; void FrameBeginInternal(FramePrepareParams params) final; private: diff --git a/Gems/Atom/Feature/Common/Code/Source/PostProcessing/LookModificationTransformPass.cpp b/Gems/Atom/Feature/Common/Code/Source/PostProcessing/LookModificationTransformPass.cpp index 98c842042b..9f792370fc 100644 --- a/Gems/Atom/Feature/Common/Code/Source/PostProcessing/LookModificationTransformPass.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/PostProcessing/LookModificationTransformPass.cpp @@ -36,10 +36,10 @@ namespace AZ &AzFramework::WindowSystemRequestBus::Events::GetDefaultWindowHandle); } - void LookModificationPass::BuildAttachmentsInternal() + void LookModificationPass::BuildInternal() { m_swapChainAttachmentBinding = FindAttachmentBinding(Name("SwapChainOutput")); - ParentPass::BuildAttachmentsInternal(); + ParentPass::BuildInternal(); } void LookModificationPass::FrameBeginInternal([[maybe_unused]] FramePrepareParams params) diff --git a/Gems/Atom/Feature/Common/Code/Source/PostProcessing/LookModificationTransformPass.h b/Gems/Atom/Feature/Common/Code/Source/PostProcessing/LookModificationTransformPass.h index 5102015e82..8203530918 100644 --- a/Gems/Atom/Feature/Common/Code/Source/PostProcessing/LookModificationTransformPass.h +++ b/Gems/Atom/Feature/Common/Code/Source/PostProcessing/LookModificationTransformPass.h @@ -52,7 +52,7 @@ namespace AZ //! Pass overrides ... void FrameBeginInternal(FramePrepareParams params) override; - void BuildAttachmentsInternal() override; + void BuildInternal() override; private: const RPI::PassAttachmentBinding* m_swapChainAttachmentBinding = nullptr; diff --git a/Gems/Atom/Feature/Common/Code/Source/PostProcessing/LuminanceHistogramGeneratorPass.cpp b/Gems/Atom/Feature/Common/Code/Source/PostProcessing/LuminanceHistogramGeneratorPass.cpp index 715ebf2945..55c64c1f33 100644 --- a/Gems/Atom/Feature/Common/Code/Source/PostProcessing/LuminanceHistogramGeneratorPass.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/PostProcessing/LuminanceHistogramGeneratorPass.cpp @@ -81,7 +81,7 @@ namespace AZ return colorBuffer->m_descriptor.m_image.m_size; } - void LuminanceHistogramGeneratorPass::BuildAttachmentsInternal() + void LuminanceHistogramGeneratorPass::BuildInternal() { CreateHistogramBuffer(); AttachHistogramBuffer(); diff --git a/Gems/Atom/Feature/Common/Code/Source/PostProcessing/LuminanceHistogramGeneratorPass.h b/Gems/Atom/Feature/Common/Code/Source/PostProcessing/LuminanceHistogramGeneratorPass.h index ee8a10fe16..9691daab6f 100644 --- a/Gems/Atom/Feature/Common/Code/Source/PostProcessing/LuminanceHistogramGeneratorPass.h +++ b/Gems/Atom/Feature/Common/Code/Source/PostProcessing/LuminanceHistogramGeneratorPass.h @@ -42,7 +42,7 @@ namespace AZ protected: LuminanceHistogramGeneratorPass(const RPI::PassDescriptor& descriptor); - virtual void BuildAttachmentsInternal() override; + virtual void BuildInternal() override; void CreateHistogramBuffer(); void AttachHistogramBuffer(); AZ::RHI::Size GetColorBufferResolution(); diff --git a/Gems/Atom/Feature/Common/Code/Source/PostProcessing/SMAABasePass.cpp b/Gems/Atom/Feature/Common/Code/Source/PostProcessing/SMAABasePass.cpp index d2424e24fd..f95637e824 100644 --- a/Gems/Atom/Feature/Common/Code/Source/PostProcessing/SMAABasePass.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/PostProcessing/SMAABasePass.cpp @@ -43,9 +43,9 @@ namespace AZ { } - void SMAABasePass::Init() + void SMAABasePass::InitializeInternal() { - FullscreenTrianglePass::Init(); + FullscreenTrianglePass::InitializeInternal(); AZ_Assert(m_shaderResourceGroup != nullptr, "SMAABasePass %s has a null shader resource group when calling Init.", GetPathName().GetCStr()); diff --git a/Gems/Atom/Feature/Common/Code/Source/PostProcessing/SMAABasePass.h b/Gems/Atom/Feature/Common/Code/Source/PostProcessing/SMAABasePass.h index 0484b7d430..3a18d587b5 100644 --- a/Gems/Atom/Feature/Common/Code/Source/PostProcessing/SMAABasePass.h +++ b/Gems/Atom/Feature/Common/Code/Source/PostProcessing/SMAABasePass.h @@ -41,9 +41,12 @@ namespace AZ protected: SMAABasePass(const RPI::PassDescriptor& descriptor); - void Init() override; + // Pass behavior overrides... + void InitializeInternal() override; + // An interface to update pass srg. virtual void UpdateSRG() = 0; + // An interface to get current shader variation option. virtual void GetCurrentShaderOption(AZ::RPI::ShaderOptionGroup& shaderOption) const = 0; diff --git a/Gems/Atom/Feature/Common/Code/Source/PostProcessing/SMAABlendingWeightCalculationPass.cpp b/Gems/Atom/Feature/Common/Code/Source/PostProcessing/SMAABlendingWeightCalculationPass.cpp index 39d9e51c86..7776bc3904 100644 --- a/Gems/Atom/Feature/Common/Code/Source/PostProcessing/SMAABlendingWeightCalculationPass.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/PostProcessing/SMAABlendingWeightCalculationPass.cpp @@ -94,9 +94,9 @@ namespace AZ } } - void SMAABlendingWeightCalculationPass::Init() + void SMAABlendingWeightCalculationPass::InitializeInternal() { - SMAABasePass::Init(); + SMAABasePass::InitializeInternal(); AZ_Assert(m_shaderResourceGroup != nullptr, "SMAABlendingWeightCalculationPass %s has a null shader resource group when calling Init.", GetPathName().GetCStr()); diff --git a/Gems/Atom/Feature/Common/Code/Source/PostProcessing/SMAABlendingWeightCalculationPass.h b/Gems/Atom/Feature/Common/Code/Source/PostProcessing/SMAABlendingWeightCalculationPass.h index b968a9c2d9..2f589a7ae6 100644 --- a/Gems/Atom/Feature/Common/Code/Source/PostProcessing/SMAABlendingWeightCalculationPass.h +++ b/Gems/Atom/Feature/Common/Code/Source/PostProcessing/SMAABlendingWeightCalculationPass.h @@ -43,7 +43,9 @@ namespace AZ private: SMAABlendingWeightCalculationPass(const RPI::PassDescriptor& descriptor); - void Init() override; + + // Pass behavior overrides... + void InitializeInternal() override; // SMAABasePass functions... void UpdateSRG() override; diff --git a/Gems/Atom/Feature/Common/Code/Source/PostProcessing/SMAAEdgeDetectionPass.cpp b/Gems/Atom/Feature/Common/Code/Source/PostProcessing/SMAAEdgeDetectionPass.cpp index 68485f3280..bb8069d0de 100644 --- a/Gems/Atom/Feature/Common/Code/Source/PostProcessing/SMAAEdgeDetectionPass.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/PostProcessing/SMAAEdgeDetectionPass.cpp @@ -48,9 +48,9 @@ namespace AZ { } - void SMAAEdgeDetectionPass::Init() + void SMAAEdgeDetectionPass::InitializeInternal() { - SMAABasePass::Init(); + SMAABasePass::InitializeInternal(); m_renderTargetMetricsShaderInputIndex.Reset(); m_chromaThresholdShaderInputIndex.Reset(); diff --git a/Gems/Atom/Feature/Common/Code/Source/PostProcessing/SMAAEdgeDetectionPass.h b/Gems/Atom/Feature/Common/Code/Source/PostProcessing/SMAAEdgeDetectionPass.h index f8302c55ca..f2c85297b6 100644 --- a/Gems/Atom/Feature/Common/Code/Source/PostProcessing/SMAAEdgeDetectionPass.h +++ b/Gems/Atom/Feature/Common/Code/Source/PostProcessing/SMAAEdgeDetectionPass.h @@ -45,7 +45,9 @@ namespace AZ private: SMAAEdgeDetectionPass(const RPI::PassDescriptor& descriptor); - void Init() override; + + // Pass behavior overrides + void InitializeInternal() override; // SMAABasePass functions... void UpdateSRG() override; diff --git a/Gems/Atom/Feature/Common/Code/Source/PostProcessing/SMAANeighborhoodBlendingPass.cpp b/Gems/Atom/Feature/Common/Code/Source/PostProcessing/SMAANeighborhoodBlendingPass.cpp index 777e4d7d95..b2307de714 100644 --- a/Gems/Atom/Feature/Common/Code/Source/PostProcessing/SMAANeighborhoodBlendingPass.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/PostProcessing/SMAANeighborhoodBlendingPass.cpp @@ -47,9 +47,9 @@ namespace AZ { } - void SMAANeighborhoodBlendingPass::Init() + void SMAANeighborhoodBlendingPass::InitializeInternal() { - SMAABasePass::Init(); + SMAABasePass::InitializeInternal(); m_renderTargetMetricsShaderInputIndex.Reset(); } diff --git a/Gems/Atom/Feature/Common/Code/Source/PostProcessing/SMAANeighborhoodBlendingPass.h b/Gems/Atom/Feature/Common/Code/Source/PostProcessing/SMAANeighborhoodBlendingPass.h index 86386a0545..f54ff30575 100644 --- a/Gems/Atom/Feature/Common/Code/Source/PostProcessing/SMAANeighborhoodBlendingPass.h +++ b/Gems/Atom/Feature/Common/Code/Source/PostProcessing/SMAANeighborhoodBlendingPass.h @@ -37,7 +37,9 @@ namespace AZ private: SMAANeighborhoodBlendingPass(const RPI::PassDescriptor& descriptor); - void Init() override; + + // Pass behavior overrides + void InitializeInternal() override; // SMAABasePass functions... void UpdateSRG() override; diff --git a/Gems/Atom/Feature/Common/Code/Source/PostProcessing/SsaoPasses.cpp b/Gems/Atom/Feature/Common/Code/Source/PostProcessing/SsaoPasses.cpp index 68472115ce..8954584886 100644 --- a/Gems/Atom/Feature/Common/Code/Source/PostProcessing/SsaoPasses.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/PostProcessing/SsaoPasses.cpp @@ -41,9 +41,9 @@ namespace AZ return ParentPass::IsEnabled(); } - void SsaoParentPass::OnBuildAttachmentsFinishedInternal() + void SsaoParentPass::InitializeInternal() { - ParentPass::OnBuildAttachmentsFinishedInternal(); + ParentPass::InitializeInternal(); m_blurParentPass = FindChildPass(Name("SsaoBlur"))->AsParent(); AZ_Assert(m_blurParentPass, "[SsaoParentPass] Could not retrieve parent blur pass."); diff --git a/Gems/Atom/Feature/Common/Code/Source/PostProcessing/SsaoPasses.h b/Gems/Atom/Feature/Common/Code/Source/PostProcessing/SsaoPasses.h index 9abd04e306..9fc5448f65 100644 --- a/Gems/Atom/Feature/Common/Code/Source/PostProcessing/SsaoPasses.h +++ b/Gems/Atom/Feature/Common/Code/Source/PostProcessing/SsaoPasses.h @@ -36,7 +36,7 @@ namespace AZ protected: // Behavior functions override... - void OnBuildAttachmentsFinishedInternal() override; + void InitializeInternal() override; void FrameBeginInternal(FramePrepareParams params) override; private: diff --git a/Gems/Atom/Feature/Common/Code/Source/PostProcessing/TaaPass.cpp b/Gems/Atom/Feature/Common/Code/Source/PostProcessing/TaaPass.cpp index 9f885ede70..38e03ab156 100644 --- a/Gems/Atom/Feature/Common/Code/Source/PostProcessing/TaaPass.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/PostProcessing/TaaPass.cpp @@ -108,7 +108,7 @@ namespace AZ::Render Base::ResetInternal(); } - void TaaPass::BuildAttachmentsInternal() + void TaaPass::BuildInternal() { m_accumulationAttachments[0] = FindAttachment(Name("Accumulation1")); m_accumulationAttachments[1] = FindAttachment(Name("Accumulation2")); @@ -143,7 +143,7 @@ namespace AZ::Render m_outputColorBinding->SetAttachment(m_accumulationAttachments[1]); } - Base::BuildAttachmentsInternal(); + Base::BuildInternal(); } void TaaPass::UpdateAttachmentImage(RPI::Ptr& attachment) diff --git a/Gems/Atom/Feature/Common/Code/Source/PostProcessing/TaaPass.h b/Gems/Atom/Feature/Common/Code/Source/PostProcessing/TaaPass.h index 6133720691..e8f4796e7b 100644 --- a/Gems/Atom/Feature/Common/Code/Source/PostProcessing/TaaPass.h +++ b/Gems/Atom/Feature/Common/Code/Source/PostProcessing/TaaPass.h @@ -63,7 +63,7 @@ namespace AZ::Render // Pass behavior overrides... void FrameBeginInternal(FramePrepareParams params) override; void ResetInternal() override; - void BuildAttachmentsInternal() override; + void BuildInternal() override; void UpdateAttachmentImage(RPI::Ptr& attachment); diff --git a/Gems/Atom/Feature/Common/Code/Source/RayTracing/RayTracingAccelerationStructurePass.cpp b/Gems/Atom/Feature/Common/Code/Source/RayTracing/RayTracingAccelerationStructurePass.cpp index 92cd41b4e8..f1fcd2de35 100644 --- a/Gems/Atom/Feature/Common/Code/Source/RayTracing/RayTracingAccelerationStructurePass.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/RayTracing/RayTracingAccelerationStructurePass.cpp @@ -42,7 +42,7 @@ namespace AZ } } - void RayTracingAccelerationStructurePass::BuildAttachmentsInternal() + void RayTracingAccelerationStructurePass::BuildInternal() { SetScopeId(RHI::ScopeId(GetPathName())); } diff --git a/Gems/Atom/Feature/Common/Code/Source/RayTracing/RayTracingAccelerationStructurePass.h b/Gems/Atom/Feature/Common/Code/Source/RayTracing/RayTracingAccelerationStructurePass.h index 6d90d752e3..127669301e 100644 --- a/Gems/Atom/Feature/Common/Code/Source/RayTracing/RayTracingAccelerationStructurePass.h +++ b/Gems/Atom/Feature/Common/Code/Source/RayTracing/RayTracingAccelerationStructurePass.h @@ -44,7 +44,7 @@ namespace AZ void BuildCommandList(const RHI::FrameGraphExecuteContext& context) override; // Pass overrides - void BuildAttachmentsInternal() override; + void BuildInternal() override; void FrameBeginInternal(FramePrepareParams params) override; // buffer view descriptor for the TLAS diff --git a/Gems/Atom/Feature/Common/Code/Source/ReflectionScreenSpace/ReflectionCopyFrameBufferPass.cpp b/Gems/Atom/Feature/Common/Code/Source/ReflectionScreenSpace/ReflectionCopyFrameBufferPass.cpp index 5137b66bf9..9a9064bdf7 100644 --- a/Gems/Atom/Feature/Common/Code/Source/ReflectionScreenSpace/ReflectionCopyFrameBufferPass.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/ReflectionScreenSpace/ReflectionCopyFrameBufferPass.cpp @@ -30,7 +30,7 @@ namespace AZ { } - void ReflectionCopyFrameBufferPass::BuildAttachmentsInternal() + void ReflectionCopyFrameBufferPass::BuildInternal() { RPI::PassHierarchyFilter passFilter(AZ::Name("ReflectionScreenSpaceBlurPass")); const AZStd::vector& passes = RPI::PassSystemInterface::Get()->FindPasses(passFilter); @@ -43,7 +43,7 @@ namespace AZ AttachImageToSlot(outputBinding.m_name, frameBufferAttachment); } - FullscreenTrianglePass::BuildAttachmentsInternal(); + FullscreenTrianglePass::BuildInternal(); } } // namespace RPI } // namespace AZ diff --git a/Gems/Atom/Feature/Common/Code/Source/ReflectionScreenSpace/ReflectionCopyFrameBufferPass.h b/Gems/Atom/Feature/Common/Code/Source/ReflectionScreenSpace/ReflectionCopyFrameBufferPass.h index 2a2fecea40..f0b8c80d72 100644 --- a/Gems/Atom/Feature/Common/Code/Source/ReflectionScreenSpace/ReflectionCopyFrameBufferPass.h +++ b/Gems/Atom/Feature/Common/Code/Source/ReflectionScreenSpace/ReflectionCopyFrameBufferPass.h @@ -37,7 +37,7 @@ namespace AZ explicit ReflectionCopyFrameBufferPass(const RPI::PassDescriptor& descriptor); // Pass Overrides... - void BuildAttachmentsInternal() override; + void BuildInternal() override; }; } // namespace RPI } // namespace AZ diff --git a/Gems/Atom/Feature/Common/Code/Source/ReflectionScreenSpace/ReflectionScreenSpaceBlurPass.cpp b/Gems/Atom/Feature/Common/Code/Source/ReflectionScreenSpace/ReflectionScreenSpaceBlurPass.cpp index 883686ac5b..631ff803dd 100644 --- a/Gems/Atom/Feature/Common/Code/Source/ReflectionScreenSpace/ReflectionScreenSpaceBlurPass.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/ReflectionScreenSpace/ReflectionScreenSpaceBlurPass.cpp @@ -47,7 +47,7 @@ namespace AZ RemoveChildren(); } - void ReflectionScreenSpaceBlurPass::CreateChildPasses(uint32_t numBlurMips) + void ReflectionScreenSpaceBlurPass::CreateChildPassesInternal() { RPI::PassSystemInterface* passSystem = RPI::PassSystemInterface::Get(); @@ -83,7 +83,7 @@ namespace AZ horizontalBlurChildDesc.m_passTemplate = blurHorizontalPassTemplate; // add child passes to perform the vertical and horizontal Gaussian blur for each roughness mip level - for (uint32_t mip = 0; mip < numBlurMips; ++mip) + for (uint32_t mip = 0; mip < m_numBlurMips; ++mip) { // create Vertical blur child passes { @@ -113,9 +113,10 @@ namespace AZ } } - void ReflectionScreenSpaceBlurPass::BuildAttachmentsInternal() + void ReflectionScreenSpaceBlurPass::BuildInternal() { RemoveChildren(); + m_flags.m_createChildren = true; Data::Instance pool = RPI::ImageSystemInterface::Get()->GetSystemAttachmentPool(); @@ -163,12 +164,11 @@ namespace AZ m_ownedAttachments.push_back(transientPassAttachment); } - // create child passes, one vertical and one horizontal blur per mip level - CreateChildPasses(mipLevels - 1); + m_numBlurMips = mipLevels - 1; - // call ParentPass::BuildAttachmentsInternal() first to configure the slots and auto-add the empty bindings, + // call ParentPass::BuildInternal() first to configure the slots and auto-add the empty bindings, // then we will assign attachments to the bindings - ParentPass::BuildAttachmentsInternal(); + ParentPass::BuildInternal(); // setup attachment bindings on vertical blur child passes uint32_t attachmentIndex = 0; diff --git a/Gems/Atom/Feature/Common/Code/Source/ReflectionScreenSpace/ReflectionScreenSpaceBlurPass.h b/Gems/Atom/Feature/Common/Code/Source/ReflectionScreenSpace/ReflectionScreenSpaceBlurPass.h index 53f4026aef..4a2ccce1d4 100644 --- a/Gems/Atom/Feature/Common/Code/Source/ReflectionScreenSpace/ReflectionScreenSpaceBlurPass.h +++ b/Gems/Atom/Feature/Common/Code/Source/ReflectionScreenSpace/ReflectionScreenSpaceBlurPass.h @@ -40,16 +40,17 @@ namespace AZ private: explicit ReflectionScreenSpaceBlurPass(const RPI::PassDescriptor& descriptor); - void CreateChildPasses(uint32_t numBlurMips); + void CreateChildPassesInternal() override; // Pass Overrides... void ResetInternal() override; - void BuildAttachmentsInternal() override; + void BuildInternal() override; AZStd::vector> m_verticalBlurChildPasses; AZStd::vector> m_horizontalBlurChildPasses; Data::Instance m_frameBufferImageAttachment; + uint32_t m_numBlurMips = 0; }; } // namespace RPI } // namespace AZ diff --git a/Gems/Atom/Feature/Common/Code/Source/ScreenSpace/DeferredFogPass.cpp b/Gems/Atom/Feature/Common/Code/Source/ScreenSpace/DeferredFogPass.cpp index 477040b74a..70e17a28d3 100644 --- a/Gems/Atom/Feature/Common/Code/Source/ScreenSpace/DeferredFogPass.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/ScreenSpace/DeferredFogPass.cpp @@ -46,9 +46,9 @@ namespace AZ } - void DeferredFogPass::Init() + void DeferredFogPass::InitializeInternal() { - FullscreenTrianglePass::Init(); + FullscreenTrianglePass::InitializeInternal(); // The following will ensure that in the case of data driven pass, the settings will get // updated by the pass enable state. diff --git a/Gems/Atom/Feature/Common/Code/Source/ScreenSpace/DeferredFogPass.h b/Gems/Atom/Feature/Common/Code/Source/ScreenSpace/DeferredFogPass.h index e2740850de..78b7d25bff 100644 --- a/Gems/Atom/Feature/Common/Code/Source/ScreenSpace/DeferredFogPass.h +++ b/Gems/Atom/Feature/Common/Code/Source/ScreenSpace/DeferredFogPass.h @@ -43,13 +43,11 @@ namespace AZ { AZ_RPI_PASS(DeferredFogPass); - public: AZ_RTTI(DeferredFogPass, "{0406C8AB-E95D-43A7-AF53-BDEE22D36746}", RPI::FullscreenTrianglePass); AZ_CLASS_ALLOCATOR(DeferredFogPass, SystemAllocator, 0); ~DeferredFogPass() = default; - void Init() override; static RPI::Ptr Create(const RPI::PassDescriptor& descriptor); @@ -57,12 +55,16 @@ namespace AZ virtual bool IsEnabled() const override; - void SetupFrameGraphDependencies(RHI::FrameGraphInterface frameGraph) override; - void CompileResources(const RHI::FrameGraphCompileContext& context) override; - protected: DeferredFogPass(const RPI::PassDescriptor& descriptor); + // Pass behavior overrides... + void InitializeInternal() override; + + // Scope producer functions... + void SetupFrameGraphDependencies(RHI::FrameGraphInterface frameGraph) override; + void CompileResources(const RHI::FrameGraphCompileContext& context) override; + //! Set the binding indices of all members of the SRG void SetSrgBindIndices(); diff --git a/Gems/Atom/Feature/Common/Code/Source/Shadows/ProjectedShadowFeatureProcessor.cpp b/Gems/Atom/Feature/Common/Code/Source/Shadows/ProjectedShadowFeatureProcessor.cpp index 216a126953..da174ab0d5 100644 --- a/Gems/Atom/Feature/Common/Code/Source/Shadows/ProjectedShadowFeatureProcessor.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/Shadows/ProjectedShadowFeatureProcessor.cpp @@ -526,7 +526,7 @@ namespace AZ::Render for (EsmShadowmapsPass* esmPass : m_esmShadowmapsPasses) { - esmPass->QueueForBuildAttachments(); + esmPass->QueueForBuildAndInitialization(); } for (ProjectedShadowmapsPass* shadowPass : m_projectedShadowmapsPasses) diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/AttachmentReadback.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/AttachmentReadback.h index 539e1a5398..3c00ce4e4c 100644 --- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/AttachmentReadback.h +++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/AttachmentReadback.h @@ -99,7 +99,7 @@ namespace AZ void DecomposeExecute(const RHI::FrameGraphExecuteContext& context); // copy data from the read back buffer (m_readbackBuffer) to the data buffer (m_dataBuffer) - void CopyBufferData(uint32_t readbackBufferIndex); + bool CopyBufferData(uint32_t readbackBufferIndex); // Get read back data in a structure ReadbackResult GetReadbackResult() const; diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/CopyPass.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/CopyPass.h index ede14564cd..fd5cdabc83 100644 --- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/CopyPass.h +++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/CopyPass.h @@ -49,7 +49,7 @@ namespace AZ void CopyImageToBuffer(const RHI::FrameGraphCompileContext& context); // Pass behavior overrides - void BuildAttachmentsInternal() override; + void BuildInternal() override; // Scope producer functions... void SetupFrameGraphDependencies(RHI::FrameGraphInterface frameGraph) override; diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/FullscreenTrianglePass.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/FullscreenTrianglePass.h index fdb3241b44..616fc4639a 100644 --- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/FullscreenTrianglePass.h +++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/FullscreenTrianglePass.h @@ -44,14 +44,11 @@ namespace AZ //! Creates a FullscreenTrianglePass static Ptr Create(const PassDescriptor& descriptor); - // Clears the initialized flag so that the next time PrepareFrameInternal is called, it will update the pipeline state - void Invalidate(); - protected: FullscreenTrianglePass(const PassDescriptor& descriptor); - virtual void Init(); // Pass behavior overrides... + void InitializeInternal() override; void FrameBeginInternal(FramePrepareParams params) override; RHI::Viewport m_viewportState; diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/MSAAResolvePass.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/MSAAResolvePass.h index 91ae1536c3..71776982b3 100644 --- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/MSAAResolvePass.h +++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/MSAAResolvePass.h @@ -40,7 +40,7 @@ namespace AZ MSAAResolvePass(const PassDescriptor& descriptor); // Pass behavior overrides... - void BuildAttachmentsInternal() override; + void BuildInternal() override; void FrameBeginInternal(FramePrepareParams params) override; private: diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/ParentPass.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/ParentPass.h index b4f63a7099..727398040d 100644 --- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/ParentPass.h +++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/ParentPass.h @@ -109,15 +109,16 @@ namespace AZ // --- Pass Behaviour Overrides --- void ResetInternal() override; - void BuildAttachmentsInternal() override; - void OnBuildAttachmentsFinishedInternal() override; + void BuildInternal() override; + void OnInitializationFinishedInternal() override; + void InitializeInternal() override; void FrameBeginInternal(FramePrepareParams params) override; void FrameEndInternal() override; // Finds the pass in m_children and removes it void RemoveChild(Ptr pass); - // Orphans all children from clearing m_children. + // Orphans all children by clearing m_children. void RemoveChildren(); private: diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/Pass.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/Pass.h index 3d0a8cd3a8..9d0b36d126 100644 --- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/Pass.h +++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/Pass.h @@ -40,6 +40,7 @@ friend class PassSystem; \ friend class PassFactory; \ friend class ParentPass; \ + friend class RenderPipeline; \ friend class UnitTest::PassTests; \ namespace UnitTest @@ -78,9 +79,9 @@ namespace AZ //! //! When authoring a new pass class, inherit from Pass and override any of the virtual functions //! ending with 'Internal' to define the behavior of your passes. These virtual are recursively - //! called in Preorder order throughout the pass tree. Only FramePrepare and FrameEnd are + //! called in preorder traversal throughout the pass tree. Only FrameBegin and FrameEnd are //! guaranteed to be called per frame. The other override-able functions are called as needed - //! when scheduled with the PassSystem. See QueueForBuildAttachments and QueueForRemoval. + //! when scheduled with the PassSystem. See QueueForBuildAndInitialization, QueueForRemoval and QueueForInitialization. //! //! Passes are created by the PassFactory. They can be created using either Pass Name, //! a PassTemplate, or a PassRequest. To register your pass class with the PassFactory, @@ -153,11 +154,14 @@ namespace AZ // --- Utility functions --- - //! Queues the pass to have BuildAttachments() called by the PassSystem on frame update - void QueueForBuildAttachments(); + //! Queues the pass to have Build() and Initilize() called by the PassSystem on frame update + void QueueForBuildAndInitialization(); //! Queues the pass to have RemoveFromParent() called by the PassSystem on frame update - void QueueForRemoval(bool needsDeletion = false); + void QueueForRemoval(); + + //! Queues the pass to have Initialize() called by the PassSystem on frame update + void QueueForInitialization(); //! Adds an attachment binding to the list of this Pass' attachment bindings void AddAttachmentBinding(PassAttachmentBinding attachmentBinding); @@ -173,8 +177,8 @@ namespace AZ //! Attach an external buffer resource as attachment to specified slot //! The buffer will be added as a pass attachment then attach to the pass slot - //! Note: the pass attachment and binding will be removed after the general BuildAttachments call. - //! you can add this call in pass' BuildAttachmentsInternal so it will be added whenever attachments get rebuilt + //! Note: the pass attachment and binding will be removed after the general Build call. + //! you can add this call in pass' BuildInternal so it will be added whenever attachments get rebuilt void AttachBufferToSlot(AZStd::string_view slot, Data::Instance buffer); void AttachBufferToSlot(const Name& slot, Data::Instance buffer); void AttachImageToSlot(const Name& slot, Data::Instance image); @@ -256,6 +260,12 @@ namespace AZ //! Returns pointer to the parent pass ParentPass* GetParent() const; + PassState GetPassState() const; + + // Update all bindings on this pass that are connected to bindings on other passes + void UpdateConnectedBindings(); + + protected: explicit Pass(const PassDescriptor& descriptor); @@ -309,18 +319,23 @@ namespace AZ // customize it's behavior, hence why these functions are called the pass behavior functions. // Resets everything in the pass (like Attachments). - // Called from PassSystem when pass is QueueForBuildAttachments. + // Called from PassSystem when pass is QueueForBuildAndInitialization. void Reset(); virtual void ResetInternal() { } // Builds and sets up any attachments and input/output connections the pass needs. - // Called from PassSystem when pass is QueueForBuildAttachments. - void BuildAttachments(); - virtual void BuildAttachmentsInternal() { } + // Called from PassSystem when pass is QueueForBuildAndInitialization. + void Build(bool calledFromPassSystem = false); + virtual void BuildInternal() { } - // Called after the pass build phase has finished. Allows passes to reset build flags. - void OnBuildAttachmentsFinished(); - virtual void OnBuildAttachmentsFinishedInternal() { }; + // Allows for additional pass initialization between building and rendering + // Can be queued independently of Build so as to only invoke Initialize() without Build() + void Initialize(); + virtual void InitializeInternal() { }; + + // Called after the pass initialization phase has finished. Allows passes to reset various states and flags. + void OnInitializationFinished(); + virtual void OnInitializationFinishedInternal() { }; // The Pass's 'Render' function. Called every frame, here the pass sets up it's rendering logic with // the FrameGraphBuilder. This is where your derived pass needs to call ImportScopeProducer on @@ -378,21 +393,36 @@ namespace AZ { struct { + // Whether this pass was created with a PassRequest (in which case m_request holds valid data) uint64_t m_createdByPassRequest : 1; - uint64_t m_initialized : 1; + + // Whether the pass is enabled (behavior can be customized by overriding IsEnabled() ) uint64_t m_enabled : 1; + + // False if parent or one of it's ancestors is disabled uint64_t m_parentEnabled : 1; - uint64_t m_alreadyCreated : 1; - uint64_t m_alreadyReset : 1; - uint64_t m_alreadyPrepared : 1; + + // If this is a parent pass, indicates if the pass has already created children this frame + // Prevents ParentPass::CreateChildPasses from executing multiple times in the same pass + uint64_t m_alreadyCreatedChildren : 1; + + // If this is a parent pass, indicates whether the pass needs to create child passes + uint64_t m_createChildren : 1; + + // Whether this pass belongs to the pass hierarchy, i.e. if you can trace it's parents up to the Root pass uint64_t m_partOfHierarchy : 1; + + // Whether this pass has a DrawListTag uint64_t m_hasDrawListTag : 1; + + // Whether this pass has a PipelineViewTag uint64_t m_hasPipelineViewTag : 1; - uint64_t m_queuedForBuildAttachment : 1; + + // Whether the pass should gather timestamp query metrics uint64_t m_timestampQueryEnabled : 1; + + // Whether the pass should gather pipeline statics uint64_t m_pipelineStatisticsQueryEnabled : 1; - uint64_t m_isBuildingAttachments : 1; - uint64_t m_isRendering : 1; }; uint64_t m_allFlags = 0; }; @@ -412,6 +442,7 @@ namespace AZ // fully custom sort implementations by overriding the SortDrawList() function. RHI::DrawListSortType m_drawListSortType = RHI::DrawListSortType::KeyThenDepth; + private: // Return the Timestamp result of this pass virtual TimestampResult GetTimestampResultInternal() const; @@ -423,6 +454,10 @@ namespace AZ // buffers and images don't get deleted during attachment build phase void StoreImportedAttachmentReferences(); + // Used by the RenderPipeline to create it's passes immediately instead of waiting on + // the next Pass System update. The function internally build and initializes the pass. + void ManualPipelineBuildAndInitialize(); + // --- Hierarchy related functions --- // Called when the pass gets a new spot in the pass hierarchy @@ -460,9 +495,6 @@ namespace AZ // This sets the binding's attachment pointer to the connected binding's attachment void UpdateConnectedBinding(PassAttachmentBinding& binding); - // Update all bindings on this pass that are connected to bindings on other passes - void UpdateConnectedBindings(); - // Process a PassFallbackConnection to connect an output to an input to act as a short-circuit for when Pass is disabled void ProcessFallbackConnection(const PassFallbackConnection& connection); @@ -502,6 +534,7 @@ namespace AZ // buffers and images don't get deleted during attachment build phase AZStd::vector> m_importedAttachmentStore; + // Name of the pass. Will be concatenated with parent names to form a unique path Name m_name; // Path of the pass in the hierarchy. Example: Root.Ssao.Downsample @@ -510,6 +543,12 @@ namespace AZ // Depth of the tree hierarchy this pass is at. // Example: Root would be depth 0, Root.Ssao.Downsample depth 2 uint32_t m_treeDepth = 0; + + // Used to track what phase of build/execution the pass is in + PassState m_state = PassState::Uninitialized; + + // Used to track what phases of build/initialization the pass is queued for + PassQueueState m_queueState = PassQueueState::NoQueue; }; //! Struct used to return results from Pass hierarchy validation diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/PassDefines.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/PassDefines.h index d536104768..a7513cc53c 100644 --- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/PassDefines.h +++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/PassDefines.h @@ -21,3 +21,100 @@ // Set this to 1 locally on your machine to facilitate pass debugging and get extra information // about passes in the output window. DO NOT SUBMIT with value set to 1 #define AZ_RPI_ENABLE_PASS_DEBUGGING 0 + +namespace AZ +{ + namespace RPI + { + // This enum tracks the state of passes across build, initialization and rendering + // + // Standard order of state progression: + // + // Uninitialized -> Queued -> Resetting -> Reset -> Building -> Built -> Initializing -> Initialized -> Idle -> Rendering -> Idle ... + // + // Addition state transitions: + // + // Queued -> Resetting + // -> Building + // -> Initializing + // + // Idle -> Queued + // -> Resetting + // -> Building + // -> Initializing + // -> Rendering + // + // Rendering -> Idle + // -> Queued (Rendering will transition to Queued if a pass was queued with the PassSystem during Rendering) + // + enum class PassState : u8 + { + // Default value, you should only ever see this in the Pass constructor + // Once the constructor is done, the Pass will set it's state to Reset + Uninitialized, + // | + // | + // V + // Pass is queued with the Pass System for an update (see PassQueueState below) + Queued, + // | + // | + // V + // Pass is currently in the process of resetting + Resetting, + // | + // | + // V + // Pass has been reset and is awaiting build + Reset, + // | + // | + // V + // Pass is currently building + Building, + // | + // | + // V + // Pass has been built and is awaiting initialization + Built, + // | + // | + // V + // Pass is currently being initialized + Initializing, + // | + // | + // V + // Pass has been initialized + Initialized, + // | + // | + // V + // Idle state, pass is awaiting rendering + Idle, + // | + // | + // V + // Pass is currently rendering. Pass must be in Idle state before entering this state + Rendering + }; + + // This enum keeps track of what actions the pass is queued for with the pass system + enum class PassQueueState : u8 + { + // The pass is currently not in any queued state and may therefore transition to any queued state + NoQueue, + + // The pass is queued for Removal at the start of the next frame. Has the highest priority and cannot be overridden by any other queue state + QueuedForRemoval, + + // The pass is queued for Build at the start of the frame. Note that any pass built at the start of the frame will also be Initialized. + // This state can be overridden by QueuedForRemoval, as we don't want to build a pass that has been removed. + QueuedForBuildAndInitialization, + + // The pass is queued for Initialization at the start of the frame. + // This state has the lowest priority and can therefore be overridden by QueueForBuildAndInitialization or QueueForRemoval. + QueuedForInitialization, + }; + } +} diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/PassSystem.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/PassSystem.h index fd30f4f406..534bf211dd 100644 --- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/PassSystem.h +++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/PassSystem.h @@ -73,12 +73,12 @@ namespace AZ bool LoadPassTemplateMappings(const AZStd::string& templateMappingPath) override; void WriteTemplateToFile(const PassTemplate& passTemplate, AZStd::string_view assetFilePath) override; void DebugPrintPassHierarchy() override; - bool IsBuilding() const override; bool IsHotReloading() const override; void SetHotReloading(bool hotReloading) override; void SetTargetedPassDebuggingName(const AZ::Name& targetPassName) override; const AZ::Name& GetTargetedPassDebuggingName() const override; void ConnectEvent(OnReadyLoadTemplatesEvent::Handler& handler) override; + PassSystemState GetState() const override; // PassSystemInterface factory related functions... void AddPassCreator(Name className, PassCreator createFunction) override; @@ -103,8 +103,11 @@ namespace AZ // Returns the root of the pass tree hierarchy const Ptr& GetRootPass() override; - // Calls BuildAttachments() on passes queued in m_buildAttachmentsList - void BuildPassAttachments(); + // Calls Build() on passes queued in m_buildPassList + void BuildPasses(); + + // Calls Initialize() on passes queued in m_initializePassList + void InitializePasses(); // Validates Pass Hierarchy after building void Validate(); @@ -113,13 +116,15 @@ namespace AZ void RemovePasses(); // Functions for queuing passes in the lists below - void QueueForBuildAttachments(Pass* pass) override; + void QueueForBuild(Pass* pass) override; void QueueForRemoval(Pass* pass) override; + void QueueForInitialization(Pass* pass) override; // Lists for queuing passes for various function calls // Name of the list reflects the pass function it will call - AZStd::vector< Ptr > m_buildAttachmentsList; + AZStd::vector< Ptr > m_buildPassList; AZStd::vector< Ptr > m_removePassList; + AZStd::vector< Ptr > m_initializePassList; // Library of pass descriptors that can be instantiated through data driven pass requests PassLibrary m_passLibrary; @@ -133,9 +138,6 @@ namespace AZ // Whether the Pass Hierarchy changed bool m_passHierarchyChanged = true; - // Whether the Pass System is currently in it's building phase - bool m_isBuilding = false; - // Whether the Pass System is currently hot reloading passes bool m_isHotReloading = false; @@ -147,6 +149,9 @@ namespace AZ // Events OnReadyLoadTemplatesEvent m_loadTemplatesEvent; + + // Used to track what phase of execution the pass system is in + PassSystemState m_state = PassSystemState::Unitialized; }; } // namespace RPI } // namespace AZ diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/PassSystemInterface.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/PassSystemInterface.h index 1224bf9545..72501fc61c 100644 --- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/PassSystemInterface.h +++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/PassSystemInterface.h @@ -40,6 +40,37 @@ namespace AZ using PassCreator = AZStd::function(const PassDescriptor& descriptor)>; + // Enum to track the different execution phases of the Pass System + enum class PassSystemState : u32 + { + // Default state, + Unitialized, + + // Initial Pass System setup. Transitions to Idle + InitializingPassSystem, + + // Pass System is processing passes queued for Removal. Transitions to Idle + RemovingPasses, + + // Pass System is processing passes queued for Build (and their child passes). Transitions to Idle + BuildingPasses, + + // Pass System is processing passes queued for Initialization (and their child passes). Transitions to Idle + InitializingPasses, + + // Pass System is validating that the Pass hierarchy is in a valid state after Build and Initialization. Transitions to Idle + ValidatingPasses, + + // Pass System is idle and can transition to any other state (except FrameEnd) + Idle, + + // Pass System is currently rendering a frame. Transitions to FrameEnd + Rendering, + + // Pass System is finishing rendering a frame. Transitions to Idle + FrameEnd, + }; + class PassSystemInterface { friend class Pass; @@ -77,9 +108,6 @@ namespace AZ //! Prints the entire pass hierarchy from the root virtual void DebugPrintPassHierarchy() = 0; - //! Returns whether the Pass System is currently in it's build phase - virtual bool IsBuilding() const = 0; - //! Returns whether the Pass System is currently hot reloading virtual bool IsHotReloading() const = 0; @@ -157,15 +185,20 @@ namespace AZ //! The handler can add new pass templates or load pass template mappings from assets virtual void ConnectEvent(OnReadyLoadTemplatesEvent::Handler& handler) = 0; + virtual PassSystemState GetState() const = 0; + private: // These functions are only meant to be used by the Pass class - // Schedules a pass to have it's BuildAttachments() function called during frame update - virtual void QueueForBuildAttachments(Pass* pass) = 0; + // Schedules a pass to have it's Build() function called during frame update + virtual void QueueForBuild(Pass* pass) = 0; // Schedules a pass to be deleted during frame update virtual void QueueForRemoval(Pass* pass) = 0; + // Schedules a pass to be initialized during frame update + virtual void QueueForInitialization(Pass* pass) = 0; + //! Registers the pass with the pass library. Called in the Pass constructor. virtual void RegisterPass(Pass* pass) = 0; diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/RenderPass.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/RenderPass.h index 5cd917e841..8f8267393e 100644 --- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/RenderPass.h +++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/RenderPass.h @@ -96,7 +96,7 @@ namespace AZ void BindPassSrg(const RHI::FrameGraphCompileContext& context, Data::Instance& shaderResourceGroup); // Pass behavior overrides... - void OnBuildAttachmentsFinishedInternal() override; + void InitializeInternal() override; void FrameBeginInternal(FramePrepareParams params) override; void FrameEndInternal() override; diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/Specific/DownsampleMipChainPass.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/Specific/DownsampleMipChainPass.h index 71c1fe4c49..eb4c4ed0aa 100644 --- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/Specific/DownsampleMipChainPass.h +++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/Specific/DownsampleMipChainPass.h @@ -46,7 +46,7 @@ namespace AZ // Pass Behaviour Overrides... void ResetInternal() override; - void BuildAttachmentsInternal() override; + void BuildInternal() override; void FrameBeginInternal(FramePrepareParams params) override; private: diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/Specific/EnvironmentCubeMapPass.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/Specific/EnvironmentCubeMapPass.h index 293a750f38..235871df83 100644 --- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/Specific/EnvironmentCubeMapPass.h +++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/Specific/EnvironmentCubeMapPass.h @@ -61,7 +61,7 @@ namespace AZ // Pass overrides void CreateChildPassesInternal() override; - void BuildAttachmentsInternal() override; + void BuildInternal() override; void FrameBeginInternal(FramePrepareParams params) override; void FrameEndInternal() override; diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/Specific/RenderToTexturePass.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/Specific/RenderToTexturePass.h index c8daab8ef8..c86203b79b 100644 --- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/Specific/RenderToTexturePass.h +++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/Specific/RenderToTexturePass.h @@ -47,7 +47,7 @@ namespace AZ protected: // Pass behavior overrides - void BuildAttachmentsInternal() override; + void BuildInternal() override; void FrameBeginInternal(FramePrepareParams params) override; // Function to be called when output size changed diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/Specific/SelectorPass.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/Specific/SelectorPass.h index fe0ce231eb..2d876c6040 100644 --- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/Specific/SelectorPass.h +++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/Specific/SelectorPass.h @@ -49,7 +49,7 @@ namespace AZ SelectorPass(const PassDescriptor& descriptor); // Pass behavior overrides - void BuildAttachmentsInternal() final; + void BuildInternal() final; // the input slot index each output slot connect to AZStd::vector m_connections; diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/Specific/SwapChainPass.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/Specific/SwapChainPass.h index 9aa00c99c2..7eac0d366d 100644 --- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/Specific/SwapChainPass.h +++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/Specific/SwapChainPass.h @@ -64,7 +64,7 @@ namespace AZ protected: // Pass behavior overrides void CreateChildPassesInternal() override final; - void BuildAttachmentsInternal() override final; + void BuildInternal() override final; void FrameBeginInternal(FramePrepareParams params) override final; // WindowNotificationBus::Handler overrides ... diff --git a/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/AttachmentReadback.cpp b/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/AttachmentReadback.cpp index 6435ae9570..88d3eb27fd 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/AttachmentReadback.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/AttachmentReadback.cpp @@ -320,8 +320,14 @@ namespace AZ { if (m_state == ReadbackState::Reading) { - CopyBufferData(readbackBufferCurrentIndex); - m_state = ReadbackState::Success; + if (CopyBufferData(readbackBufferCurrentIndex)) + { + m_state = ReadbackState::Success; + } + else + { + m_state = ReadbackState::Failed; + } } if (m_callback) { @@ -498,13 +504,13 @@ namespace AZ return result; } - void AttachmentReadback::CopyBufferData(uint32_t readbackBufferIndex) + bool AttachmentReadback::CopyBufferData(uint32_t readbackBufferIndex) { Data::Instance readbackBufferCurrent = m_readbackBufferArray[readbackBufferIndex]; if (!readbackBufferCurrent) { - return; + return false; } auto bufferSize = readbackBufferCurrent->GetBufferSize(); @@ -537,6 +543,7 @@ namespace AZ } m_isReadbackComplete[readbackBufferIndex] = true; + return true; } } // namespace RPI } // namespace AZ diff --git a/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/CopyPass.cpp b/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/CopyPass.cpp index 4a6c883584..9648a47fd6 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/CopyPass.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/CopyPass.cpp @@ -74,7 +74,7 @@ namespace AZ // --- Pass behavior overrides --- - void CopyPass::BuildAttachmentsInternal() + void CopyPass::BuildInternal() { AZ_Assert(GetInputCount() == 1 && GetOutputCount() == 1, "CopyPass has %d inputs and %d outputs. It should have exactly one of each.", diff --git a/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/FullscreenTrianglePass.cpp b/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/FullscreenTrianglePass.cpp index 1f8f361b8b..a854867998 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/FullscreenTrianglePass.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/FullscreenTrianglePass.cpp @@ -64,6 +64,8 @@ namespace AZ void FullscreenTrianglePass::LoadShader() { + AZ_Assert(GetPassState() != PassState::Rendering, "FullscreenTrianglePass - Reloading shader during Rendering phase!"); + // Load FullscreenTrianglePassData const FullscreenTrianglePassData* passData = PassUtils::GetPassData(m_passDescriptor); if (passData == nullptr) @@ -121,14 +123,16 @@ namespace AZ // Store stencil reference value for the draw call m_stencilRef = passData->m_stencilRef; - m_flags.m_initialized = false; + QueueForInitialization(); ShaderReloadNotificationBus::Handler::BusDisconnect(); ShaderReloadNotificationBus::Handler::BusConnect(shaderAsset.GetId()); } - void FullscreenTrianglePass::Init() + void FullscreenTrianglePass::InitializeInternal() { + RenderPass::InitializeInternal(); + // This draw item purposefully does not reference any geometry buffers. // Instead it's expected that the extended class uses a vertex shader // that generates a full-screen triangle completely from vertex ids. @@ -155,17 +159,10 @@ namespace AZ m_item.m_arguments = RHI::DrawArguments(draw); m_item.m_pipelineState = m_shader->AcquirePipelineState(pipelineStateDescriptor); m_item.m_stencilRef = m_stencilRef; - - m_flags.m_initialized = true; } void FullscreenTrianglePass::FrameBeginInternal(FramePrepareParams params) { - if (!m_flags.m_initialized) - { - Init(); - } - const PassAttachment* outputAttachment = nullptr; if (GetOutputCount() > 0) @@ -225,11 +222,6 @@ namespace AZ commandList->Submit(m_item); } - - void FullscreenTrianglePass::Invalidate() - { - m_flags.m_initialized = false; - } } // namespace RPI } // namespace AZ diff --git a/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/MSAAResolvePass.cpp b/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/MSAAResolvePass.cpp index c889f367b7..e457cb4992 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/MSAAResolvePass.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/MSAAResolvePass.cpp @@ -38,7 +38,7 @@ namespace AZ { } - void MSAAResolvePass::BuildAttachmentsInternal() + void MSAAResolvePass::BuildInternal() { AZ_Assert(GetOutputCount() != 0, "MSAAResolvePass %s has no outputs to render to.", GetPathName().GetCStr()); } diff --git a/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/ParentPass.cpp b/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/ParentPass.cpp index 106ef82bf1..cbae56e809 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/ParentPass.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/ParentPass.cpp @@ -40,7 +40,7 @@ namespace AZ ParentPass::ParentPass(const PassDescriptor& descriptor) : Pass(descriptor) { - CreateChildPasses(); + m_flags.m_createChildren = true; } ParentPass::~ParentPass() @@ -59,7 +59,7 @@ namespace AZ child->m_parent = this; child->OnHierarchyChange(); - QueueForBuildAttachments(); + QueueForBuildAndInitialization(); // Notify pipeline if (m_pipeline) @@ -248,25 +248,18 @@ namespace AZ void ParentPass::CreateChildPasses() { - // Flag prevents the function from executing multiple times a frame. Can happen - // as pass system has a list of passes for which it needs to call this function. - if (m_flags.m_alreadyCreated) + // The already created flag prevents this function from executing multiple times a frame + if (!m_flags.m_createChildren || m_flags.m_alreadyCreatedChildren) { return; } - m_flags.m_alreadyCreated = true; + m_flags.m_alreadyCreatedChildren = true; + RemoveChildren(); CreatePassesFromTemplate(); CreateChildPassesInternal(); - for (Ptr& child : m_children) - { - ParentPass* asParent = child->AsParent(); - if (asParent != nullptr) - { - asParent->CreateChildPasses(); - } - } + m_flags.m_createChildren = false; } void ParentPass::ResetInternal() @@ -277,19 +270,29 @@ namespace AZ } } - void ParentPass::BuildAttachmentsInternal() + void ParentPass::BuildInternal() { + CreateChildPasses(); + for (const Ptr& child : m_children) { - child->BuildAttachments(); + child->Build(); } } - void ParentPass::OnBuildAttachmentsFinishedInternal() + void ParentPass::OnInitializationFinishedInternal() { for (const Ptr& child : m_children) { - child->OnBuildAttachmentsFinished(); + child->OnInitializationFinished(); + } + } + + void ParentPass::InitializeInternal() + { + for (const Ptr& child : m_children) + { + child->Initialize(); } } diff --git a/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/Pass.cpp b/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/Pass.cpp index 1e230a7fc0..99a6e23914 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/Pass.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/Pass.cpp @@ -37,10 +37,12 @@ #include #include + namespace AZ { namespace RPI { + // --- Constructors --- Pass::Pass(const PassDescriptor& descriptor) @@ -71,7 +73,10 @@ namespace AZ } PassSystemInterface::Get()->RegisterPass(this); - QueueForBuildAttachments(); + QueueForBuildAndInitialization(); + + // Skip reset since the pass just got created + m_state = PassState::Reset; } Pass::~Pass() @@ -151,6 +156,8 @@ namespace AZ { AZ_RPI_PASS_ASSERT(m_parent != nullptr, "Trying to remove pass from parent but pointer to the parent pass is null."); m_parent->RemoveChild(Ptr(this)); + m_queueState = PassQueueState::NoQueue; + m_state = PassState::Idle; } void Pass::OnOrphan() @@ -162,6 +169,11 @@ namespace AZ // --- Getters & Setters --- + PassState Pass::GetPassState() const + { + return m_state; + } + ParentPass* Pass::GetParent() const { return m_parent; @@ -348,32 +360,6 @@ namespace AZ return nullptr; } - // --- Queuing functions with PassSystem --- - - void Pass::QueueForBuildAttachments() - { - // Don't queue if we're in building phase - if (!PassSystemInterface::Get()->IsBuilding()) - { - // m_queuedForBuildAttachment makes sure the pass only be queue for once - if (!m_flags.m_queuedForBuildAttachment) - { - PassSystemInterface::Get()->QueueForBuildAttachments(this); - m_flags.m_queuedForBuildAttachment = true; - - // Set these two flags to false since when queue build attachments request, they should all be already be false except one use - // case that the pass system processed all queued requests when active a scene. - m_flags.m_alreadyPrepared = false; - m_flags.m_alreadyReset = false; - } - } - } - - void Pass::QueueForRemoval([[maybe_unused]] bool needsDeletion) - { - PassSystemInterface::Get()->QueueForRemoval(this); - } - // --- PassTemplate related functions --- void Pass::CreateBindingsFromTemplate() @@ -403,7 +389,7 @@ namespace AZ PassAttachmentBinding* localBinding = FindAttachmentBinding(slot); if (!localBinding) { - AZ_RPI_PASS_ERROR(false, "Pass::AttachBufferToSlot - Pass %s failed to find slot %s.", + AZ_RPI_PASS_ERROR(false, "Pass::AttachBufferToSlot - Pass [%s] failed to find slot [%s].", m_path.GetCStr(), slot.GetCStr()); return; } @@ -413,7 +399,7 @@ namespace AZ // handle the connected bindings if (localBinding->m_attachment) { - AZ_RPI_PASS_ERROR(false, "Pass::AttachBufferToSlot - Slot %s already has attachment %s.", + AZ_RPI_PASS_ERROR(false, "Pass::AttachBufferToSlot - Slot [%s] already has attachment [%s].", slot.GetCStr(), localBinding->m_attachment->m_name.GetCStr()); return; } @@ -435,7 +421,7 @@ namespace AZ PassAttachmentBinding* localBinding = FindAttachmentBinding(slot); if (!localBinding) { - AZ_RPI_PASS_ERROR(false, "Pass::AttachImageToSlot - Pass %s failed to find slot %s.", + AZ_RPI_PASS_ERROR(false, "Pass::AttachImageToSlot - Pass [%s] failed to find slot [%s].", m_path.GetCStr(), slot.GetCStr()); return; } @@ -445,7 +431,7 @@ namespace AZ // handle the connected bindings if (localBinding->m_attachment) { - AZ_RPI_PASS_ERROR(false, "Pass::AttachImageToSlot - Slot %s already has attachment %s.", + AZ_RPI_PASS_ERROR(false, "Pass::AttachImageToSlot - Slot [%s] already has attachment [%s].", slot.GetCStr(), localBinding->m_attachment->m_name.GetCStr()); return; } @@ -468,7 +454,7 @@ namespace AZ PassAttachmentBinding* localBinding = FindAttachmentBinding(connection.m_localSlot); if (!localBinding) { - AZ_RPI_PASS_ERROR(false, "Pass::ProcessConnection - Pass %s failed to find slot %s.", + AZ_RPI_PASS_ERROR(false, "Pass::ProcessConnection - Pass [%s] failed to find slot [%s].", m_path.GetCStr(), connection.m_localSlot.GetCStr()); return; @@ -490,7 +476,7 @@ namespace AZ { foundPass = true; const Ptr attachment = FindOwnedAttachment(connectedSlotName); - AZ_RPI_PASS_ERROR(attachment, "Pass::ProcessConnection - Pass %s doesn't own an attachment named %s.", + AZ_RPI_PASS_ERROR(attachment, "Pass::ProcessConnection - Pass [%s] doesn't own an attachment named [%s].", m_path.GetCStr(), connectedSlotName.GetCStr()); localBinding->SetAttachment(attachment); @@ -601,10 +587,10 @@ namespace AZ if (!outputBinding || !inputBinding) { - AZ_RPI_PASS_ERROR(inputBinding, "Pass::ProcessFallbackConnection - Pass %s failed to find input slot %s.", + AZ_RPI_PASS_ERROR(inputBinding, "Pass::ProcessFallbackConnection - Pass [%s] failed to find input slot [%s].", m_path.GetCStr(), connection.m_inputSlotName.GetCStr()); - AZ_RPI_PASS_ERROR(outputBinding, "Pass::ProcessFallbackConnection - Pass %s failed to find output slot %s.", + AZ_RPI_PASS_ERROR(outputBinding, "Pass::ProcessFallbackConnection - Pass [%s] failed to find output slot [%s].", m_path.GetCStr(), connection.m_outputSlotName.GetCStr()); return; @@ -614,10 +600,10 @@ namespace AZ if (!typesAreValid) { - AZ_RPI_PASS_ERROR(inputBinding->m_slotType == PassSlotType::Input, "Pass::ProcessFallbackConnection - Pass %s specifies fallback connection input %s, which is not an input.", + AZ_RPI_PASS_ERROR(inputBinding->m_slotType == PassSlotType::Input, "Pass::ProcessFallbackConnection - Pass [%s] specifies fallback connection input [%s], which is not an input.", m_path.GetCStr(), connection.m_inputSlotName.GetCStr()); - AZ_RPI_PASS_ERROR(outputBinding->m_slotType == PassSlotType::Output, "Pass::ProcessFallbackConnection - Pass %s specifies fallback connection output %s, which is not an output.", + AZ_RPI_PASS_ERROR(outputBinding->m_slotType == PassSlotType::Output, "Pass::ProcessFallbackConnection - Pass [%s] specifies fallback connection output [%s], which is not an output.", m_path.GetCStr(), connection.m_inputSlotName.GetCStr()); return; @@ -1007,7 +993,7 @@ namespace AZ { Ptr targetAttachment = nullptr; - if (!m_flags.m_isBuildingAttachments && !IsEnabled() && binding.m_slotType == PassSlotType::Output && binding.m_fallbackBinding) + if (m_state != PassState::Building && !IsEnabled() && binding.m_slotType == PassSlotType::Output && binding.m_fallbackBinding) { targetAttachment = binding.m_fallbackBinding->m_attachment; } @@ -1028,7 +1014,7 @@ namespace AZ // Check whether the template's slot allows this attachment if (m_template && !m_template->AttachmentFitsSlot(targetAttachment->m_descriptor, binding.m_name)) { - AZ_RPI_PASS_ERROR(false, "Pass::UpdateConnectedBinding - Attachment %s did not match the filters of input slot %s on pass %s.", + AZ_RPI_PASS_ERROR(false, "Pass::UpdateConnectedBinding - Attachment [%s] did not match the filters of input slot [%s] on pass [%s].", targetAttachment->m_name.GetCStr(), binding.m_name.GetCStr(), m_path.GetCStr()); @@ -1050,17 +1036,83 @@ namespace AZ } } + // --- Queuing functions with PassSystem --- + + void Pass::QueueForBuildAndInitialization() + { + // Don't queue if we're currently building. Don't queue if we're already queued for Build or Removal + if (m_state != PassState::Building && + m_queueState != PassQueueState::QueuedForBuildAndInitialization && + m_queueState != PassQueueState::QueuedForRemoval) + { + // NOTE: We only queue for Build here, the queue for Initialization happens at the end of Pass::Build + // (doing it this way is an optimization to minimize the number of passes queued for initialization, + // as many passes will be initialized by their parent passes and thus don't need to be queued) + PassSystemInterface::Get()->QueueForBuild(this); + + m_queueState = PassQueueState::QueuedForBuildAndInitialization; + + // Transition state + // If we are Rendering, the state will transition [Rendering -> Queued] in Pass::FrameEnd + if (m_state != PassState::Rendering) + { + m_state = PassState::Queued; + } + } + } + + void Pass::QueueForInitialization() + { + // Only queue if the pass is not in any queue. Don't queue if we're currently initializing. + if (m_queueState == PassQueueState::NoQueue && m_state != PassState::Initializing) + { + PassSystemInterface::Get()->QueueForInitialization(this); + m_queueState = PassQueueState::QueuedForInitialization; + + // Transition state + // If we are Rendering, the state will transition [Rendering -> Queued] in Pass::FrameEnd + // If the state is Built, preserve the state since [Built -> Initializing] is a valid transition + // Preserving PassState::Built lets the pass ignore subsequent build calls in the same frame + if (m_state != PassState::Rendering && m_state != PassState::Built) + { + m_state = PassState::Queued; + } + } + } + + void Pass::QueueForRemoval() + { + // Skip only if we're already queued for removal, otherwise proceed. + // QueuedForRemoval overrides QueuedForBuildAndInitialization and QueuedForInitialization. + if (m_queueState != PassQueueState::QueuedForRemoval) + { + PassSystemInterface::Get()->QueueForRemoval(this); + m_queueState = PassQueueState::QueuedForRemoval; + + // Transition state + // If we are Rendering, the state will transition [Rendering -> Queued] in Pass::FrameEnd + if (m_state != PassState::Rendering) + { + m_state = PassState::Queued; + } + } + } + // --- Pass behavior functions --- void Pass::Reset() { - // Flag prevents the function from executing multiple times a frame. Can happen - // as pass system has a list of passes for which it needs to call this function. - if (m_flags.m_alreadyReset) + // Ensure we're in a valid state to reset. This ensures the pass won't be reset multiple times in the same frame. + bool execute = (m_state == PassState::Idle); + execute = execute || (m_state == PassState::Queued && m_queueState == PassQueueState::QueuedForBuildAndInitialization); + execute = execute || (m_state == PassState::Queued && m_queueState == PassQueueState::QueuedForInitialization); + + if (!execute) { return; } - m_flags.m_alreadyReset = true; + + m_state = PassState::Resetting; // Store references to imported attachments to underlying images and buffers aren't deleted during attachment building StoreImportedAttachmentReferences(); @@ -1075,22 +1127,23 @@ namespace AZ m_executeBeforePasses.clear(); ResetInternal(); + + m_state = PassState::Reset; } - void Pass::BuildAttachments() + void Pass::Build(bool calledFromPassSystem) { - m_flags.m_queuedForBuildAttachment = false; + AZ_RPI_BREAK_ON_TARGET_PASS; - // Flag prevents the function from executing multiple times a frame. Can happen - // as pass system has a list of passes for which it needs to call this function. - if (m_flags.m_alreadyPrepared) + // Ensure we're in a valid state to build. This ensures the pass won't be built multiple times in the same frame. + bool execute = (m_state == PassState::Reset); + + if (!execute) { return; } - m_flags.m_alreadyPrepared = true; - m_flags.m_isBuildingAttachments = true; - AZ_RPI_BREAK_ON_TARGET_PASS; + m_state = PassState::Building; // Bindings, inputs and attachments CreateBindingsFromTemplate(); @@ -1101,7 +1154,7 @@ namespace AZ SetupInputsFromTemplate(); // Custom pass behavior - BuildAttachmentsInternal(); + BuildInternal(); // Outputs SetupOutputsFromTemplate(); @@ -1112,21 +1165,46 @@ namespace AZ UpdateOwnedAttachments(); UpdateAttachmentUsageIndices(); - m_flags.m_isBuildingAttachments = false; + m_state = PassState::Built; + m_queueState = PassQueueState::NoQueue; + + // If this pass's Build() wasn't called from the Pass System, then it was called by it's parent pass + // In which case we don't need to queue for initialization because the parent will already be queued + if (calledFromPassSystem) + { + // Queue for Initialization + QueueForInitialization(); + } } - void Pass::OnBuildAttachmentsFinished() + void Pass::Initialize() { AZ_RPI_BREAK_ON_TARGET_PASS; - // These flags are to prevent a pass from being built multiple times. - // We reset them after each build phase. - m_flags.m_alreadyCreated = false; - m_flags.m_alreadyPrepared = false; - m_flags.m_alreadyReset = false; - m_flags.m_queuedForBuildAttachment = false; + // Ensure we're in a valid state to initialize. This ensures the pass won't be initialized multiple times in the same frame. + bool execute = (m_state == PassState::Idle || m_state == PassState::Built); + execute = execute || (m_state == PassState::Queued && m_queueState == PassQueueState::QueuedForInitialization); + + if (!execute) + { + return; + } + + m_state = PassState::Initializing; + m_queueState = PassQueueState::NoQueue; + + InitializeInternal(); + + m_state = PassState::Initialized; + } + + void Pass::OnInitializationFinished() + { + m_flags.m_alreadyCreatedChildren = false; m_importedAttachmentStore.clear(); - OnBuildAttachmentsFinishedInternal(); + OnInitializationFinishedInternal(); + + m_state = PassState::Idle; } void Pass::Validate(PassValidationResults& validationResults) @@ -1182,7 +1260,9 @@ namespace AZ UpdateConnectedBindings(); return; } - m_flags.m_isRendering = true; + + AZ_Assert(m_state == PassState::Idle, "Pass::FrameBegin - Pass [%s] is attempting to render, but is not in the Idle state.", m_path.GetCStr()); + m_state = PassState::Rendering; UpdateConnectedBindings(); UpdateOwnedAttachments(); @@ -1197,10 +1277,10 @@ namespace AZ void Pass::FrameEnd() { - if (m_flags.m_isRendering) + if (m_state == PassState::Rendering) { FrameEndInternal(); - m_flags.m_isRendering = false; + m_state = (m_queueState == PassQueueState::NoQueue) ? PassState::Idle : PassState::Queued; } } @@ -1238,6 +1318,13 @@ namespace AZ return m_pipeline; } + void Pass::ManualPipelineBuildAndInitialize() + { + Build(); + Initialize(); + OnInitializationFinished(); + } + Scene* Pass::GetScene() const { if (m_pipeline) diff --git a/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/PassSystem.cpp b/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/PassSystem.cpp index 448c28f202..cc51c8760a 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/PassSystem.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/PassSystem.cpp @@ -50,6 +50,7 @@ namespace AZ { namespace RPI { + PassSystemInterface* PassSystemInterface::Get() { return Interface::Get(); @@ -93,11 +94,21 @@ namespace AZ void PassSystem::Init() { + m_state = PassSystemState::InitializingPassSystem; + Interface::Register(this); m_passLibrary.Init(); m_passFactory.Init(&m_passLibrary); m_rootPass = CreatePass(Name{"Root"}); m_rootPass->m_flags.m_partOfHierarchy = true; + m_rootPass->m_flags.m_createChildren = false; + + // Here you can specify the name of a pass you would like to break into during execution + // If you enable AZ_RPI_ENABLE_PASS_DEBUGGING, then any pass matching the specified name will debug + // break on any instance of the AZ_RPI_BREAK_ON_TARGET_PASS macro. See Pass::Build for an example + // m_targetedPassDebugName = "MyPassName"; + + m_state = PassSystemState::Idle; } void PassSystem::InitPassTemplates() @@ -118,10 +129,10 @@ namespace AZ JsonSerializationUtils::SaveObjectToFile(&passAsset, assetFilePath); } - void PassSystem::QueueForBuildAttachments(Pass* pass) + void PassSystem::QueueForBuild(Pass* pass) { - AZ_Assert(pass != nullptr, "Queuing nullptr pass in PassSystem::QueueForBuildAttachments"); - m_buildAttachmentsList.push_back(pass); + AZ_Assert(pass != nullptr, "Queuing nullptr pass in PassSystem::QueueForBuild"); + m_buildPassList.push_back(pass); } void PassSystem::QueueForRemoval(Pass* pass) @@ -130,6 +141,12 @@ namespace AZ m_removePassList.push_back(pass); } + void PassSystem::QueueForInitialization(Pass* pass) + { + AZ_Assert(pass != nullptr, "Queuing nullptr pass in PassSystem::QueueForInitialization"); + m_initializePassList.push_back(pass); + } + // Sort so passes with less depth (closer to the root) are first. Used when changes // in the parent passes can affect the child passes, like with attachment building. void SortPassListAscending(AZStd::vector< Ptr >& passList) @@ -155,6 +172,7 @@ namespace AZ void PassSystem::RemovePasses() { + m_state = PassSystemState::RemovingPasses; AZ_ATOM_PROFILE_FUNCTION("RPI", "PassSystem: RemovePasses"); if (!m_removePassList.empty()) @@ -168,24 +186,25 @@ namespace AZ m_removePassList.clear(); } + + m_state = PassSystemState::Idle; } - void PassSystem::BuildPassAttachments() + void PassSystem::BuildPasses() { + m_state = PassSystemState::BuildingPasses; AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzRender); AZ_ATOM_PROFILE_FUNCTION("RPI", "PassSystem: BuildPassAttachments"); - m_isBuilding = true; + m_passHierarchyChanged = m_passHierarchyChanged || !m_buildPassList.empty(); - m_passHierarchyChanged = !m_buildAttachmentsList.empty(); - - // While loop is for the event in which passes being built add more pass to m_buildAttachmentsList - while(!m_buildAttachmentsList.empty()) + // While loop is for the event in which passes being built add more pass to m_buildPassList + while(!m_buildPassList.empty()) { AZ_Assert(m_removePassList.empty(), "Passes shouldn't be queued removal during build attachment process"); - AZStd::vector< Ptr > buildListCopy = m_buildAttachmentsList; - m_buildAttachmentsList.clear(); + AZStd::vector< Ptr > buildListCopy = m_buildPassList; + m_buildPassList.clear(); // Erase passes which were removed from pass tree already (which parent is empty) auto unused = AZStd::remove_if(buildListCopy.begin(), buildListCopy.end(), @@ -203,11 +222,8 @@ namespace AZ } for (const Ptr& pass : buildListCopy) { - pass->BuildAttachments(); + pass->Build(true); } - - // Signal all passes that we have finished building - m_rootPass->OnBuildAttachmentsFinished(); } if (m_passHierarchyChanged) @@ -221,11 +237,50 @@ namespace AZ #endif } - m_isBuilding = false; + m_state = PassSystemState::Idle; + } + + void PassSystem::InitializePasses() + { + m_state = PassSystemState::InitializingPasses; + AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzRender); + AZ_ATOM_PROFILE_FUNCTION("RPI", "PassSystem: BuildPassAttachments"); + + m_passHierarchyChanged = m_passHierarchyChanged || !m_initializePassList.empty(); + + while (!m_initializePassList.empty()) + { + AZStd::vector< Ptr > initListCopy = m_initializePassList; + m_initializePassList.clear(); + + // Erase passes which were removed from pass tree already (which parent is empty) + auto unused = AZStd::remove_if(initListCopy.begin(), initListCopy.end(), + [](const RHI::Ptr& currentPass) + { + return !currentPass->m_flags.m_partOfHierarchy; + }); + initListCopy.erase(unused, initListCopy.end()); + + SortPassListAscending(initListCopy); + + for (const Ptr& pass : initListCopy) + { + pass->Initialize(); + } + } + + if (m_passHierarchyChanged) + { + // Signal all passes that we have finished initialization + m_rootPass->OnInitializationFinished(); + } + + m_state = PassSystemState::Idle; } void PassSystem::Validate() { + m_state = PassSystemState::ValidatingPasses; AZ_ATOM_PROFILE_FUNCTION("RPI", "PassSystem: Validate"); if (PassValidation::IsEnabled()) @@ -241,12 +296,15 @@ namespace AZ m_rootPass->Validate(validationResults); validationResults.PrintValidationIfError(); } + + m_state = PassSystemState::Idle; } void PassSystem::ProcessQueuedChanges() { RemovePasses(); - BuildPassAttachments(); + BuildPasses(); + InitializePasses(); Validate(); } @@ -256,6 +314,8 @@ namespace AZ AZ_ATOM_PROFILE_FUNCTION("RPI", "PassSystem: FrameUpdate"); ProcessQueuedChanges(); + + m_state = PassSystemState::Rendering; Pass::FramePrepareParams params{ &frameGraphBuilder }; m_rootPass->FrameBegin(params); } @@ -264,6 +324,8 @@ namespace AZ { AZ_ATOM_PROFILE_FUNCTION("RHI", "PassSystem: FrameEnd"); + m_state = PassSystemState::FrameEnd; + m_rootPass->FrameEnd(); // remove any pipelines that are marked as ExecuteOnce @@ -278,12 +340,14 @@ namespace AZ } m_passHierarchyChanged = false; + + m_state = PassSystemState::Idle; } void PassSystem::Shutdown() { RemovePasses(); - m_buildAttachmentsList.clear(); + m_buildPassList.clear(); m_rootPass = nullptr; m_passFactory.Shutdown(); m_passLibrary.Shutdown(); @@ -296,9 +360,9 @@ namespace AZ return m_rootPass; } - bool PassSystem::IsBuilding() const + PassSystemState PassSystem::GetState() const { - return m_isBuilding; + return m_state; } bool PassSystem::IsHotReloading() const diff --git a/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/RenderPass.cpp b/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/RenderPass.cpp index 3a2a556429..3e52130f6f 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/RenderPass.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/RenderPass.cpp @@ -128,7 +128,7 @@ namespace AZ } - void RenderPass::OnBuildAttachmentsFinishedInternal() + void RenderPass::InitializeInternal() { if (m_shaderResourceGroup != nullptr) { diff --git a/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/Specific/DownsampleMipChainPass.cpp b/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/Specific/DownsampleMipChainPass.cpp index 0e0ebf445e..329247d4eb 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/Specific/DownsampleMipChainPass.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/Specific/DownsampleMipChainPass.cpp @@ -181,12 +181,12 @@ namespace AZ // Pass behavior functions... - void DownsampleMipChainPass::BuildAttachmentsInternal() + void DownsampleMipChainPass::BuildInternal() { GetInputInfo(); BuildChildPasses(); UpdateChildren(); - ParentPass::BuildAttachmentsInternal(); + ParentPass::BuildInternal(); } void DownsampleMipChainPass::FrameBeginInternal(FramePrepareParams params) diff --git a/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/Specific/EnvironmentCubeMapPass.cpp b/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/Specific/EnvironmentCubeMapPass.cpp index c72712bce5..28a03de297 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/Specific/EnvironmentCubeMapPass.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/Specific/EnvironmentCubeMapPass.cpp @@ -37,8 +37,6 @@ namespace AZ EnvironmentCubeMapPass::EnvironmentCubeMapPass(const PassDescriptor& passDescriptor) : ParentPass(passDescriptor) { - m_flags.m_alreadyCreated = false; - // load pass data const EnvironmentCubeMapPassData* passData = PassUtils::GetPassData(passDescriptor); if (passData == nullptr) @@ -88,8 +86,6 @@ namespace AZ AZ::Matrix4x4 viewToClipMatrix; MakePerspectiveFovMatrixRH(viewToClipMatrix, AZ::Constants::HalfPi, 1.0f, 0.1f, 100.0f, true); m_view->SetViewToClipMatrix(viewToClipMatrix); - - CreateChildPasses(); } EnvironmentCubeMapPass::~EnvironmentCubeMapPass() @@ -113,7 +109,7 @@ namespace AZ AddChild(m_childPass); } - void EnvironmentCubeMapPass::BuildAttachmentsInternal() + void EnvironmentCubeMapPass::BuildInternal() { // create output image descriptor m_outputImageDesc = RHI::ImageDescriptor::Create2D(RHI::ImageBindFlags::Color | RHI::ImageBindFlags::CopyRead, CubeMapFaceSize, CubeMapFaceSize, RHI::Format::R16G16B16A16_FLOAT); @@ -135,7 +131,7 @@ namespace AZ m_attachmentBindings.push_back(outputAttachment); - ParentPass::BuildAttachmentsInternal(); + ParentPass::BuildInternal(); } void EnvironmentCubeMapPass::FrameBeginInternal(FramePrepareParams params) diff --git a/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/Specific/RenderToTexturePass.cpp b/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/Specific/RenderToTexturePass.cpp index 4356a56622..7306bf5b6a 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/Specific/RenderToTexturePass.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/Specific/RenderToTexturePass.cpp @@ -50,7 +50,7 @@ namespace AZ { } - void RenderToTexturePass::BuildAttachmentsInternal() + void RenderToTexturePass::BuildInternal() { m_outputAttachment = aznew PassAttachment(); m_outputAttachment->m_name = "RenderTarget"; @@ -73,7 +73,7 @@ namespace AZ m_attachmentBindings.push_back(outputBinding); - Base::BuildAttachmentsInternal(); + Base::BuildInternal(); } void RenderToTexturePass::FrameBeginInternal(FramePrepareParams params) @@ -100,7 +100,7 @@ namespace AZ m_passData.m_width = width; m_passData.m_height = height; OnUpdateOutputSize(); - QueueForBuildAttachments(); + QueueForBuildAndInitialization(); } void RenderToTexturePass::OnUpdateOutputSize() diff --git a/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/Specific/SelectorPass.cpp b/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/Specific/SelectorPass.cpp index 8e8c67393d..82cea31ca1 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/Specific/SelectorPass.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/Specific/SelectorPass.cpp @@ -44,7 +44,7 @@ namespace AZ } } - void SelectorPass::BuildAttachmentsInternal() + void SelectorPass::BuildInternal() { // Update output connections based on m_connections // This need to be done after BuildAttachment is finished @@ -72,7 +72,7 @@ namespace AZ m_connections[outputSlotIndex] = inputSlotIndex; // Queue to rebuild attachment connections - QueueForBuildAttachments(); + QueueForBuildAndInitialization(); } void SelectorPass::Connect(const AZ::Name& inputSlot, const AZ::Name& outputSlot) @@ -113,7 +113,7 @@ namespace AZ m_connections[outputIdx] = inputIdx; // Queue to rebuild attachment connections - QueueForBuildAttachments(); + QueueForBuildAndInitialization(); } } // namespace RPI diff --git a/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/Specific/SwapChainPass.cpp b/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/Specific/SwapChainPass.cpp index 5bcec87df0..7b79efbaec 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/Specific/SwapChainPass.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/Specific/SwapChainPass.cpp @@ -26,8 +26,6 @@ namespace AZ , m_windowContext(windowContext) , m_childTemplateName(childTemplateName) { - m_flags.m_alreadyCreated = false; - PassSystemInterface* passSystem = PassSystemInterface::Get(); // Create child pass @@ -44,8 +42,6 @@ namespace AZ m_childPass = passSystem->CreatePassFromRequest(&childRequest); AZ_Assert(m_childPass, "SwapChain child pass is invalid: check your passs pipeline, run configuration and your AssetProcessor set project (project_path)"); - - CreateChildPasses(); AzFramework::WindowNotificationBus::Handler::BusConnect(m_windowContext->GetWindowHandle()); } @@ -112,7 +108,7 @@ namespace AZ AddChild(m_childPass); } - void SwapChainPass::BuildAttachmentsInternal() + void SwapChainPass::BuildInternal() { if (m_windowContext->GetSwapChain() == nullptr) { @@ -124,7 +120,7 @@ namespace AZ SetupSwapChainAttachment(); - ParentPass::BuildAttachmentsInternal(); + ParentPass::BuildInternal(); } void SwapChainPass::FrameBeginInternal(FramePrepareParams params) @@ -154,7 +150,7 @@ namespace AZ void SwapChainPass::OnWindowResized([[maybe_unused]] uint32_t width, [[maybe_unused]] uint32_t height) { - QueueForBuildAttachments(); + QueueForBuildAndInitialization(); } void SwapChainPass::ReadbackSwapChain(AZStd::shared_ptr readback) diff --git a/Gems/Atom/RPI/Code/Source/RPI.Public/RenderPipeline.cpp b/Gems/Atom/RPI/Code/Source/RPI.Public/RenderPipeline.cpp index cc0cefd082..ad2fc4b19e 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Public/RenderPipeline.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Public/RenderPipeline.cpp @@ -107,7 +107,7 @@ namespace AZ pipeline->m_originalRenderSettings = desc.m_renderSettings; pipeline->m_activeRenderSettings = desc.m_renderSettings; pipeline->m_rootPass->SetRenderPipeline(pipeline); - pipeline->BuildPipelineViews(); + pipeline->m_rootPass->ManualPipelineBuildAndInitialize(); } RenderPipeline::~RenderPipeline() @@ -320,8 +320,8 @@ namespace AZ Ptr newRoot = m_rootPass->Recreate(); newRoot->SetRenderPipeline(this); - // Force processing of queued changes so we can validate the new pipeline - passSystem->ProcessQueuedChanges(); + // Manually build the pipeline + newRoot->ManualPipelineBuildAndInitialize(); // Validate the new root PassValidationResults validation; @@ -329,9 +329,8 @@ namespace AZ if (validation.IsValid()) { // Remove old pass - bool deletePass = true; m_rootPass->SetRenderPipeline(nullptr); - m_rootPass->QueueForRemoval(deletePass); + m_rootPass->QueueForRemoval(); // Set new root m_rootPass = newRoot; diff --git a/Gems/Atom/RPI/Code/Source/RPI.Public/Scene.cpp b/Gems/Atom/RPI/Code/Source/RPI.Public/Scene.cpp index 7e33750eb5..62efc3dccb 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Public/Scene.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Public/Scene.cpp @@ -289,9 +289,10 @@ namespace AZ } pipeline->OnAddedToScene(this); + PassSystemInterface::Get()->ProcessQueuedChanges(); + pipeline->BuildPipelineViews(); // Force to update the lookup table since adding render pipeline would effect any pipeline states created before pass system tick - AZ::RPI::PassSystemInterface::Get()->ProcessQueuedChanges(); RebuildPipelineStatesLookup(); AZ_Assert(!m_id.IsNull(), "RPI::Scene needs to have a valid uuid."); diff --git a/Gems/Atom/RPI/Code/Tests/Pass/PassTests.cpp b/Gems/Atom/RPI/Code/Tests/Pass/PassTests.cpp index 96a21f8c9b..f9a2bc4493 100644 --- a/Gems/Atom/RPI/Code/Tests/Pass/PassTests.cpp +++ b/Gems/Atom/RPI/Code/Tests/Pass/PassTests.cpp @@ -329,7 +329,7 @@ namespace UnitTest Ptr parentPass = m_passSystem->CreatePassFromTemplate(Name("ParentPass"), Name("ParentPass")); parentPass->Reset(); - parentPass->BuildAttachments(); + parentPass->Build(); PassValidationResults validationResults; parentPass->Validate(validationResults); @@ -351,7 +351,7 @@ namespace UnitTest Ptr parentPass = m_passSystem->CreatePassFromTemplate(Name("ParentPass"), Name("ParentPass")); parentPass->Reset(); - parentPass->BuildAttachments(); + parentPass->Build(); PassValidationResults validationResults; parentPass->Validate(validationResults); @@ -373,7 +373,7 @@ namespace UnitTest Ptr parentPass = m_passSystem->CreatePassFromTemplate(Name("ParentPass"), Name("ParentPass")); parentPass->Reset(); - parentPass->BuildAttachments(); + parentPass->Build(); PassValidationResults validationResults; parentPass->Validate(validationResults); @@ -397,7 +397,7 @@ namespace UnitTest parentPass->m_flags.m_partOfHierarchy = true; parentPass->OnHierarchyChange(); parentPass->Reset(); - parentPass->BuildAttachments(); + parentPass->Build(); PassValidationResults validationResults; parentPass->Validate(validationResults); @@ -421,7 +421,7 @@ namespace UnitTest parentPass->m_flags.m_partOfHierarchy = true; parentPass->OnHierarchyChange(); parentPass->Reset(); - parentPass->BuildAttachments(); + parentPass->Build(); PassValidationResults validationResults; parentPass->Validate(validationResults); @@ -445,7 +445,7 @@ namespace UnitTest parentPass->m_flags.m_partOfHierarchy = true; parentPass->OnHierarchyChange(); parentPass->Reset(); - parentPass->BuildAttachments(); + parentPass->Build(); PassValidationResults validationResults; parentPass->Validate(validationResults); @@ -469,7 +469,7 @@ namespace UnitTest parentPass->m_flags.m_partOfHierarchy = true; parentPass->OnHierarchyChange(); parentPass->Reset(); - parentPass->BuildAttachments(); + parentPass->Build(); PassValidationResults validationResults; parentPass->Validate(validationResults);