diff --git a/Gems/Atom/Feature/Common/Code/Source/DisplayMapper/DisplayMapperPass.cpp b/Gems/Atom/Feature/Common/Code/Source/DisplayMapper/DisplayMapperPass.cpp index be3e05163a..b6fa0b5c41 100644 --- a/Gems/Atom/Feature/Common/Code/Source/DisplayMapper/DisplayMapperPass.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/DisplayMapper/DisplayMapperPass.cpp @@ -46,6 +46,8 @@ namespace AZ DisplayMapperPass::DisplayMapperPass(const RPI::PassDescriptor& descriptor) : RPI::ParentPass(descriptor) { + m_flags.m_alreadyCreated = false; + AzFramework::NativeWindowHandle windowHandle = nullptr; AzFramework::WindowSystemRequestBus::BroadcastResult( windowHandle, diff --git a/Gems/Atom/Feature/Common/Code/Source/LuxCore/LuxCoreTexturePass.cpp b/Gems/Atom/Feature/Common/Code/Source/LuxCore/LuxCoreTexturePass.cpp index 3c7233e747..7708605e29 100644 --- a/Gems/Atom/Feature/Common/Code/Source/LuxCore/LuxCoreTexturePass.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/LuxCore/LuxCoreTexturePass.cpp @@ -28,6 +28,8 @@ 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 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 ee7f850d27..b71016f30a 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 @@ -393,6 +393,7 @@ namespace AZ uint64_t m_parentEnabled : 1; uint64_t m_initialized : 1; + uint64_t m_alreadyCreated : 1; uint64_t m_partOfHierarchy : 1; uint64_t m_hasDrawListTag : 1; 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 7244510fbd..ebdfa7cf55 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/ParentPass.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/ParentPass.cpp @@ -248,6 +248,12 @@ namespace AZ void ParentPass::CreateChildPasses() { + if (m_flags.m_alreadyCreated) + { + return; + } + m_flags.m_alreadyCreated = true; + RemoveChildren(); CreatePassesFromTemplate(); CreateChildPassesInternal(); 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 da9022b655..726d702a72 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/Pass.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/Pass.cpp @@ -151,6 +151,7 @@ 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; } void Pass::OnOrphan() @@ -358,7 +359,7 @@ namespace AZ void Pass::QueueForBuild() { // Don't queue if we're in building phase - if (PassSystemInterface::Get()->GetState() != PassSystemState::Building && + if (m_state != PassState::Building && (m_queueState == PassQueueState::NoQueue || m_queueState == PassQueueState::QueuedForInitialization)) { PassSystemInterface::Get()->QueueForBuild(this); @@ -374,7 +375,7 @@ namespace AZ void Pass::QueueForInitialization() { // Don't queue if we're in initialization phase - if (PassSystemInterface::Get()->GetState() != PassSystemState::Initializing && m_queueState == PassQueueState::NoQueue) + if (m_queueState == PassQueueState::NoQueue) { PassSystemInterface::Get()->QueueForInitialization(this); m_queueState = PassQueueState::QueuedForInitialization; @@ -1086,11 +1087,12 @@ namespace AZ void Pass::Build() { - if (m_queueState != PassQueueState::QueuedForBuild || m_state != PassState::Resetting) + if (m_queueState != PassQueueState::QueuedForBuild || (m_state != PassState::Queued && m_state != PassState::Resetting)) { return; } m_state = PassState::Building; + m_queueState = PassQueueState::NoQueue; AZ_RPI_BREAK_ON_TARGET_PASS; @@ -1115,7 +1117,6 @@ namespace AZ UpdateAttachmentUsageIndices(); // Queue for Initialization - m_queueState = PassQueueState::NoQueue; QueueForInitialization(); } @@ -1123,6 +1124,7 @@ namespace AZ { AZ_RPI_BREAK_ON_TARGET_PASS; + m_flags.m_alreadyCreated = false; m_importedAttachmentStore.clear(); OnBuildFinishedInternal(); } @@ -1133,6 +1135,7 @@ namespace AZ { return; } + m_queueState = PassQueueState::NoQueue; m_state = PassState::Initializing; InitializeInternal(); 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 3dabd88fff..0c38b228f5 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/PassSystem.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/PassSystem.cpp @@ -242,19 +242,22 @@ namespace AZ AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzRender); AZ_ATOM_PROFILE_FUNCTION("RPI", "PassSystem: BuildPassAttachments"); - if(!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(m_initializePassList.begin(), m_initializePassList.end(), + auto unused = AZStd::remove_if(initListCopy.begin(), initListCopy.end(), [](const RHI::Ptr& currentPass) { return !currentPass->m_flags.m_partOfHierarchy; }); - m_initializePassList.erase(unused, m_initializePassList.end()); + initListCopy.erase(unused, initListCopy.end()); - SortPassListAscending(m_initializePassList); + SortPassListAscending(initListCopy); - for (const Ptr& pass : m_initializePassList) + for (const Ptr& pass : initListCopy) { pass->Initialize(); } 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 672e5509ee..be06343ab9 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,6 +37,8 @@ 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) 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 e6f65e997c..45fb890e91 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,6 +26,8 @@ namespace AZ , m_windowContext(windowContext) , m_childTemplateName(childTemplateName) { + m_flags.m_alreadyCreated = false; + PassSystemInterface* passSystem = PassSystemInterface::Get(); // Create child pass