diff --git a/Gems/Atom/Feature/Common/Code/Source/CommonSystemComponent.cpp b/Gems/Atom/Feature/Common/Code/Source/CommonSystemComponent.cpp index be6d438a62..089a6168b1 100644 --- a/Gems/Atom/Feature/Common/Code/Source/CommonSystemComponent.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/CommonSystemComponent.cpp @@ -274,6 +274,10 @@ namespace AZ passSystem->AddPassCreator(Name("ReflectionScreenSpaceBlurPass"), &Render::ReflectionScreenSpaceBlurPass::Create); passSystem->AddPassCreator(Name("ReflectionScreenSpaceBlurChildPass"), &Render::ReflectionScreenSpaceBlurChildPass::Create); passSystem->AddPassCreator(Name("ReflectionCopyFrameBufferPass"), &Render::ReflectionCopyFrameBufferPass::Create); + + // setup handler for load pass template mappings + m_loadTemplatesHandler = RPI::PassSystemInterface::OnReadyLoadTemplatesEvent::Handler([this]() { this->LoadPassTemplateMappings(); }); + RPI::PassSystemInterface::Get()->ConnectEvent(m_loadTemplatesHandler); } void CommonSystemComponent::Deactivate() @@ -292,5 +296,12 @@ namespace AZ AZ::RPI::FeatureProcessorFactory::Get()->UnregisterFeatureProcessor(); AZ::RPI::FeatureProcessorFactory::Get()->UnregisterFeatureProcessor(); } + + void CommonSystemComponent::LoadPassTemplateMappings() + { + const char* passTemplatesFile = "Passes/PassTemplates.azasset"; + RPI::PassSystemInterface::Get()->LoadPassTemplateMappings(passTemplatesFile); + } + } // namespace Render } // namespace AZ diff --git a/Gems/Atom/Feature/Common/Code/Source/CommonSystemComponent.h b/Gems/Atom/Feature/Common/Code/Source/CommonSystemComponent.h index 595faba523..92705f0fa6 100644 --- a/Gems/Atom/Feature/Common/Code/Source/CommonSystemComponent.h +++ b/Gems/Atom/Feature/Common/Code/Source/CommonSystemComponent.h @@ -14,6 +14,8 @@ #include #include +#include + #if AZ_TRAIT_LUXCORE_SUPPORTED #include "LuxCore/LuxCoreRenderer.h" #endif @@ -41,6 +43,11 @@ namespace AZ void Activate() override; void Deactivate() override; + // Load pass template mappings for this gem + void LoadPassTemplateMappings(); + + RPI::PassSystemInterface::OnReadyLoadTemplatesEvent::Handler m_loadTemplatesHandler; + #if AZ_TRAIT_LUXCORE_SUPPORTED // LuxCore LuxCoreRenderer m_luxCore; diff --git a/Gems/Atom/RPI/Assets/ShaderLib/Atom/RPI/ShaderResourceGroups/BindlessPrototypeSrg.azsli b/Gems/Atom/RPI/Assets/ShaderLib/Atom/RPI/ShaderResourceGroups/BindlessPrototypeSrg.azsli deleted file mode 100644 index 7304af9e1e..0000000000 --- a/Gems/Atom/RPI/Assets/ShaderLib/Atom/RPI/ShaderResourceGroups/BindlessPrototypeSrg.azsli +++ /dev/null @@ -1,136 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#pragma once - -// NOTE: Nest this array, so Azslc will output a size of the bindingslot to 1 -struct FloatBuffer -{ - float buffer; -}; - -// Listed on update frequency -ShaderResourceGroupSemantic FrequencyPerScene -{ - FrequencyId = 6; -}; - -ShaderResourceGroupSemantic FloatBufferSemanticId -{ - FrequencyId = 7; -}; - -ShaderResourceGroup ImageSrg : FrequencyPerScene -{ - Sampler m_sampler - { - MaxAnisotropy = 16; - AddressU = Wrap; - AddressV = Wrap; - AddressW = Wrap; - }; - - // Array of textures - Texture2D m_textureArray[]; -} - -ShaderResourceGroup FloatBufferSrg : FloatBufferSemanticId -{ - StructuredBuffer m_floatBuffer; -}; - -// Helper functions to read data from the FloatBuffer. The FloatBuffer is accessed with a descriptor and a index. -// The descriptor holds the initial offset within the FloatBuffer, and the index is a sub-index, which increments with each property that is being read. -// The data needs to be read in the same order as it is allocated on the host. - -// All float setters -void SetFloat(out float outFloat, in uint desc, inout uint index) -{ - outFloat = FloatBufferSrg::m_floatBuffer[desc + index + 0].buffer; - index += 1; -} - -void SetFloat2(out float2 outFloat, in uint desc, inout uint index) -{ - outFloat.x = FloatBufferSrg::m_floatBuffer[desc + index + 0].buffer; - outFloat.y = FloatBufferSrg::m_floatBuffer[desc + index + 1].buffer; - index += 2; -} - -void SetFloat3(out float3 outFloat, in uint desc, inout uint index) -{ - outFloat.x = FloatBufferSrg::m_floatBuffer[desc + index + 0].buffer; - outFloat.y = FloatBufferSrg::m_floatBuffer[desc + index + 1].buffer; - outFloat.z = FloatBufferSrg::m_floatBuffer[desc + index + 2].buffer; - index += 3; -} - -void SetFloat4(out float4 outFloat, in uint desc, inout uint index) -{ - outFloat.x = FloatBufferSrg::m_floatBuffer[desc + index + 0].buffer; - outFloat.y = FloatBufferSrg::m_floatBuffer[desc + index + 1].buffer; - outFloat.z = FloatBufferSrg::m_floatBuffer[desc + index + 2].buffer; - outFloat.w = FloatBufferSrg::m_floatBuffer[desc + index + 3].buffer; - index += 4; -} - -// All matrix setters -void SetFloat4x4(out float4x4 outFloat, in uint desc, inout uint index) -{ - [unroll(4)] - for(uint i = 0; i < 4; i++) - { - SetFloat4(outFloat[i], desc, index); - } -} - -// All uint setters -void SetUint(out uint outUInt, in uint desc, inout uint index) -{ - outUInt = asuint(FloatBufferSrg::m_floatBuffer[desc + index + 0].buffer); - index += 1; -} - -void SetUint2(out uint2 outUInt, in uint desc, inout uint index) -{ - outUInt.x = asuint(FloatBufferSrg::m_floatBuffer[desc + index + 0].buffer); - outUInt.y = asuint(FloatBufferSrg::m_floatBuffer[desc + index + 1].buffer); - index += 2; -} - -void SetUint3(out uint3 outUInt, in uint desc, inout uint index) -{ - outUInt.x = asuint(FloatBufferSrg::m_floatBuffer[desc + index + 0].buffer); - outUInt.y = asuint(FloatBufferSrg::m_floatBuffer[desc + index + 1].buffer); - outUInt.z = asuint(FloatBufferSrg::m_floatBuffer[desc + index + 2].buffer); - index += 3; -} - -void SetUint4(out uint4 outUInt, in uint desc, inout uint index) -{ - outUInt.x = asuint(FloatBufferSrg::m_floatBuffer[desc + index + 0].buffer); - outUInt.y = asuint(FloatBufferSrg::m_floatBuffer[desc + index + 1].buffer); - outUInt.z = asuint(FloatBufferSrg::m_floatBuffer[desc + index + 2].buffer); - outUInt.w = asuint(FloatBufferSrg::m_floatBuffer[desc + index + 3].buffer); - index += 4; -} - -// All double setters -void SetDouble(out double outDouble, in uint desc, inout uint index) -{ - uint lowBits; - uint highBits; - SetUint(highBits, desc, index); - SetUint(lowBits, desc, index); - - outDouble = asdouble(lowBits, highBits); -} diff --git a/Gems/Atom/RPI/Assets/atom_rpi_asset_files.cmake b/Gems/Atom/RPI/Assets/atom_rpi_asset_files.cmake index 47bece22c9..b7dd571002 100644 --- a/Gems/Atom/RPI/Assets/atom_rpi_asset_files.cmake +++ b/Gems/Atom/RPI/Assets/atom_rpi_asset_files.cmake @@ -21,7 +21,6 @@ set(FILES Shader/ImagePreview.shader ShaderLib/Atom/RPI/Math.azsli ShaderLib/Atom/RPI/TangentSpace.azsli - ShaderLib/Atom/RPI/ShaderResourceGroups/BindlessPrototypeSrg.azsli ShaderLib/Atom/RPI/ShaderResourceGroups/DefaultDrawSrg.azsli ShaderLib/Atom/RPI/ShaderResourceGroups/DefaultObjectSrg.azsli ) diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/PassFactory.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/PassFactory.h index dc39687a97..2252838541 100644 --- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/PassFactory.h +++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/PassFactory.h @@ -89,7 +89,7 @@ namespace AZ // --- Members --- // Cached pointer to the pass library to simplify code - PassLibrary* m_passLibary = nullptr; + PassLibrary* m_passLibrary = nullptr; // ClassNames are used to look up PassCreators. This list is 1-to-1 with the PassCreator list AZStd::vector m_passClassNames; diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/PassLibrary.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/PassLibrary.h index 283cea7c0a..d26f15096b 100644 --- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/PassLibrary.h +++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/PassLibrary.h @@ -56,6 +56,9 @@ namespace AZ // The list of passes created from this template AZStd::vector m_passes; + + // The pass templates mapping asset id which this template is coming from. + Data::AssetId m_mappingAssetId; }; typedef AZStd::unordered_map TemplateEntriesByName; @@ -105,7 +108,7 @@ namespace AZ bool LoadPassAsset(const Name& name, const Data::Asset& passAsset, bool hotReloading = false); // Find asset with specified pass template asset id and load pass template from the asset. - void LoadPassAsset(const Name& name, const Data::AssetId& passAssetId); + bool LoadPassAsset(const Name& name, const Data::AssetId& passAssetId); // Data::AssetBus::Handler overrides... void OnAssetReloaded(Data::Asset asset) override; 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 d37868025c..fd30f4f406 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 @@ -55,6 +55,10 @@ namespace AZ //! Initializes the PassSystem and the Root Pass and creates the Pass InstanceDatabase void Init(); + //! Initialize and load pass templates + //! This function need to be called after Init() + void InitPassTemplates(); + //! Deletes the Root Pass and shuts down the PassSystem void Shutdown(); @@ -74,6 +78,7 @@ namespace AZ void SetHotReloading(bool hotReloading) override; void SetTargetedPassDebuggingName(const AZ::Name& targetPassName) override; const AZ::Name& GetTargetedPassDebuggingName() const override; + void ConnectEvent(OnReadyLoadTemplatesEvent::Handler& handler) override; // PassSystemInterface factory related functions... void AddPassCreator(Name className, PassCreator createFunction) override; @@ -139,6 +144,9 @@ namespace AZ // Counts the number of passes int32_t m_passCounter = 0; + + // Events + OnReadyLoadTemplatesEvent m_loadTemplatesEvent; }; } // 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 82d52ab5a2..1224bf9545 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 @@ -64,7 +64,10 @@ namespace AZ //! initializing a scene; virtual void ProcessQueuedChanges() = 0; - //! Load pass templates listed in a name-assetid mapping asset + //! Load pass templates listed in a name-assetid mapping asset + //! This function should be called before the render pipelines which use templates from this mappings are created. + //! To load pass template mapping before any render pipelines are created, use OnReadyLoadTemplatesEvent::Handler to + //! load desired pass template mappings virtual bool LoadPassTemplateMappings(const AZStd::string& templateMappingPath) = 0; //! Writes a pass template to a .pass file which can then be used as a pass asset. Useful for @@ -148,6 +151,12 @@ namespace AZ //! Find the SwapChainPass associated with window Handle virtual SwapChainPass* FindSwapChainPass(AzFramework::NativeWindowHandle windowHandle) const = 0; + using OnReadyLoadTemplatesEvent = AZ::Event<>; + //! Connect a handler to listen to the event that the pass system is ready to load pass templates + //! The event is triggered when pass system is initialized and asset system is ready. + //! The handler can add new pass templates or load pass template mappings from assets + virtual void ConnectEvent(OnReadyLoadTemplatesEvent::Handler& handler) = 0; + private: // These functions are only meant to be used by the Pass class @@ -164,17 +173,10 @@ namespace AZ virtual void UnregisterPass(Pass* pass) = 0; }; - - //! Notifications of the pass system such attachments were rebuilt, pass tree changes - class PassSystemNotificiations - : public AZ::EBusTraits + + namespace PassSystemEvents { - public: - - //! Notify when any pass's attachment was rebuilt - virtual void OnPassAttachmentsBuilt() = 0; - }; + } - using PassSystemNotificiationBus = AZ::EBus; } // namespace RPI } // namespace AZ diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Reflect/Asset/AssetUtils.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Reflect/Asset/AssetUtils.h index 5a169a9e61..1a8ddb5d97 100644 --- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Reflect/Asset/AssetUtils.h +++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Reflect/Asset/AssetUtils.h @@ -137,13 +137,19 @@ namespace AZ template Data::Asset LoadCriticalAsset(const AZStd::string& assetFilePath, TraceLevel reporting) { - AzFramework::AssetSystem::AssetStatus status = AzFramework::AssetSystem::AssetStatus_Unknown; - AzFramework::AssetSystemRequestBus::BroadcastResult(status, &AzFramework::AssetSystemRequestBus::Events::CompileAssetSync, assetFilePath); - - if (status != AzFramework::AssetSystem::AssetStatus_Compiled) + bool apConnected = false; + AzFramework::AssetSystemRequestBus::BroadcastResult( + apConnected, &AzFramework::AssetSystemRequestBus::Events::ConnectedWithAssetProcessor); + if (apConnected) { - AssetUtilsInternal::ReportIssue(reporting, AZStd::string::format("Could not compile asset '%s'", assetFilePath.c_str()).c_str()); - return {}; + AzFramework::AssetSystem::AssetStatus status = AzFramework::AssetSystem::AssetStatus_Unknown; + AzFramework::AssetSystemRequestBus::BroadcastResult( + status, &AzFramework::AssetSystemRequestBus::Events::CompileAssetSync, assetFilePath); + if (status != AzFramework::AssetSystem::AssetStatus_Compiled) + { + AssetUtilsInternal::ReportIssue(reporting, AZStd::string::format("Could not compile asset '%s'", assetFilePath.c_str()).c_str()); + return {}; + } } return LoadAssetByProductPath(assetFilePath.c_str(), reporting); diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Reflect/RPISystemDescriptor.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Reflect/RPISystemDescriptor.h index 1223f984fd..3d0b9f4f63 100644 --- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Reflect/RPISystemDescriptor.h +++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Reflect/RPISystemDescriptor.h @@ -44,9 +44,6 @@ namespace AZ //! The path of the only one view srg asset for the RPI system. This is used to create any RPI::View. AZStd::string m_viewSrgAssetPath = "shaderlib/viewsrg_viewsrg.azsrg"; - //! Path of pass templates' name-assetid mapping file. - AZStd::string m_passTemplatesMappingPath = "Passes/PassTemplates.azasset"; - ImageSystemDescriptor m_imageSystemDescriptor; GpuQuerySystemDescriptor m_gpuQuerySystemDescriptor; DynamicDrawSystemDescriptor m_dynamicDrawSystemDescriptor; diff --git a/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/PassFactory.cpp b/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/PassFactory.cpp index 6a2e756403..90df206a3d 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/PassFactory.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/PassFactory.cpp @@ -36,7 +36,7 @@ namespace AZ { void PassFactory::Init(PassLibrary* passLibrary) { - m_passLibary = passLibrary; + m_passLibrary = passLibrary; AddCorePasses(); } @@ -125,7 +125,7 @@ namespace AZ Ptr PassFactory::CreatePassFromTemplate(Name templateName, Name passName) { - const AZStd::shared_ptr& passTemplate = m_passLibary->GetPassTemplate(templateName); + const AZStd::shared_ptr& passTemplate = m_passLibrary->GetPassTemplate(templateName); if (passTemplate == nullptr) { AZ_Error("PassFactory", false, "FAILED TO CREATE PASS [%s]. Could not find pass template [%s]", passName.GetCStr(), templateName.GetCStr()); @@ -143,7 +143,7 @@ namespace AZ return nullptr; } - const AZStd::shared_ptr& passTemplate = m_passLibary->GetPassTemplate(passRequest->m_templateName); + const AZStd::shared_ptr& passTemplate = m_passLibrary->GetPassTemplate(passRequest->m_templateName); if (passTemplate == nullptr) { AZ_Error("PassFactory", false, "FAILED TO CREATE PASS [%s]. Could not find pass template [%s]", passRequest->m_passName.GetCStr(), passRequest->m_templateName.GetCStr()); diff --git a/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/PassLibrary.cpp b/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/PassLibrary.cpp index 6c1f96e414..346ccc7d76 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/PassLibrary.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/PassLibrary.cpp @@ -262,6 +262,7 @@ namespace AZ } // Handle template mapping reload + // Note: it's a known issue that when mapping asset got reloaded, we only handle the new entries Data::Asset templateMappings = { asset.GetAs(), AZ::Data::AssetLoadBehavior::PreLoad }; if (templateMappings) { @@ -310,7 +311,7 @@ namespace AZ return success; } - void PassLibrary::LoadPassAsset(const Name& name, const Data::AssetId& passAssetId) + bool PassLibrary::LoadPassAsset(const Name& name, const Data::AssetId& passAssetId) { Data::Asset passAsset; if (passAssetId.IsValid()) @@ -325,11 +326,20 @@ namespace AZ { Data::AssetBus::MultiHandler::BusConnect(passAssetId); } + + return loadSuccess; } bool PassLibrary::LoadPassTemplateMappings(const AZStd::string& templateMappingPath) { Data::Asset mappingAsset = AssetUtils::LoadCriticalAsset(templateMappingPath.c_str(), AssetUtils::TraceLevel::Error); + + if (m_templateMappingAssets.find(mappingAsset.GetId()) != m_templateMappingAssets.end()) + { + AZ_Warning("PassLibrary", false, "Pass template mapping [%s] was already loaded", mappingAsset.GetHint().c_str()); + return true; + } + bool success = LoadPassTemplateMappings(mappingAsset); if (success) { @@ -350,13 +360,29 @@ namespace AZ } const AZStd::unordered_map& assetMapping = mappings->GetAssetMapping(); + Data::AssetId mappingAssetId = mappingAsset.GetId(); m_templateEntries.reserve(m_templateEntries.size() + assetMapping.size()); for (const auto& assetInfo : assetMapping) { Name templateName = AZ::Name(assetInfo.first); if (!HasTemplate(templateName)) { - LoadPassAsset(templateName, assetInfo.second); + bool loaded = LoadPassAsset(templateName, assetInfo.second); + if (loaded) + { + auto& entry = m_templateEntries[templateName]; + entry.m_mappingAssetId = mappingAssetId; + } + } + else + { + // Report a warning if the template was setup in another mappping asset. + // We won't report a warning if the template was loaded from same asset. This only happens when the asset got reloaded. + if (m_templateEntries[templateName].m_mappingAssetId != mappingAssetId) + { + AZ_Warning("PassLibrary", false, "Template [%s] was aleady added to the library. Duplicated template from [%s]", + templateName.GetCStr(), mappingAsset.ToString().c_str()); + } } } 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 706d759231..448c28f202 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/PassSystem.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/PassSystem.cpp @@ -100,6 +100,12 @@ namespace AZ m_rootPass->m_flags.m_partOfHierarchy = true; } + void PassSystem::InitPassTemplates() + { + AZ_Assert(m_rootPass, "PassSystem::Init() need to be called"); + m_loadTemplatesEvent.Signal(); + } + bool PassSystem::LoadPassTemplateMappings(const AZStd::string& templateMappingPath) { return m_passLibrary.LoadPassTemplateMappings(templateMappingPath); @@ -213,7 +219,6 @@ namespace AZ DebugPrintPassHierarchy(); } #endif - PassSystemNotificiationBus::Broadcast(&PassSystemNotificiationBus::Events::OnPassAttachmentsBuilt); } m_isBuilding = false; @@ -323,6 +328,11 @@ namespace AZ return m_targetedPassDebugName; } + void PassSystem::ConnectEvent(OnReadyLoadTemplatesEvent::Handler& handler) + { + handler.Connect(m_loadTemplatesEvent); + } + // --- Pass Factory Functions --- void PassSystem::AddPassCreator(Name className, PassCreator createFunction) diff --git a/Gems/Atom/RPI/Code/Source/RPI.Public/RPISystem.cpp b/Gems/Atom/RPI/Code/Source/RPI.Public/RPISystem.cpp index 5cd6f93715..44be2dabeb 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Public/RPISystem.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Public/RPISystem.cpp @@ -369,12 +369,7 @@ namespace AZ m_bufferSystem.Init(); m_dynamicDraw.Init(m_descriptor.m_dynamicDrawSystemDescriptor); - // Have pass system load default pass template mapping - bool passSystemReady = m_passSystem.LoadPassTemplateMappings(m_descriptor.m_passTemplatesMappingPath); - if (!passSystemReady) - { - return; - } + m_passSystem.InitPassTemplates(); m_systemAssetsInitialized = true; } diff --git a/Gems/Atom/RPI/Code/Source/RPI.Public/Scene.cpp b/Gems/Atom/RPI/Code/Source/RPI.Public/Scene.cpp index a66471e038..7e33750eb5 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Public/Scene.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Public/Scene.cpp @@ -99,7 +99,6 @@ namespace AZ { WaitAndCleanCompletionJob(m_simulationCompletion); SceneRequestBus::Handler::BusDisconnect(); - DisableAllFeatureProcessors(); // Remove all the render pipelines. Need to process queued changes with pass system before and after remove render pipelines AZ::RPI::PassSystemInterface::Get()->ProcessQueuedChanges(); @@ -111,6 +110,8 @@ namespace AZ m_pipelines.clear(); AZ::RPI::PassSystemInterface::Get()->ProcessQueuedChanges(); + Deactivate(); + delete m_cullingScene; } @@ -138,8 +139,11 @@ namespace AZ void Scene::Deactivate() { - AZ_Assert(m_activated, "Not activated"); - + if (!m_activated) + { + return; + } + for (auto& fp : m_featureProcessors) { fp->Deactivate(); @@ -240,7 +244,6 @@ namespace AZ fp->Deactivate(); } m_featureProcessors.clear(); - m_pipelineStatesLookup.clear(); } FeatureProcessor* Scene::GetFeatureProcessor(const FeatureProcessorId& featureProcessorId) const