From 01b2798fe17a6307131a3c1b6ba74f78b826865b Mon Sep 17 00:00:00 2001 From: Vicky <55564570+VickyAtAZ@users.noreply.github.com> Date: Mon, 10 May 2021 16:46:25 -0700 Subject: [PATCH] Integrate from 1.0 to main: LYN-3436 AutomatedTesting.GameLauncher crashes at launch if assets are not all processed (#612) * Atom/qingtao/lyn 3436 (#558) * LYN-3436 AutomatedTesting.GameLauncher crashes at launch if assets are not all processed Change RPISystem so that the application would exit if the RPI system couldn't load critical assets. Added code to avoid the GetLayout crash when layout for each platforms were not ready. Added LoadCriticalAsset function to force compile and load critical assets. Added default value to viewport size for ViewportContext. * Change RPISystem asset initialization order so it returns earlier when those critical assets are not ready --- .../Code/Source/BootstrapSystemComponent.cpp | 13 +++++ .../Code/Include/Atom/RHI/CpuProfilerImpl.h | 2 + .../RHI/Code/Source/RHI/CpuProfilerImpl.cpp | 6 +++ Gems/Atom/RHI/Code/Source/RHI/RHISystem.cpp | 9 ++-- .../DX12/Code/Source/RHI/AsyncUploadQueue.cpp | 10 ++-- .../Code/Source/RHI/CommandQueueContext.cpp | 5 +- .../Atom/RPI.Public/Buffer/BufferSystem.h | 2 + .../Atom/RPI.Public/Image/ImageSystem.h | 2 + .../Atom/RPI.Public/Pass/PassLibrary.h | 2 +- .../Include/Atom/RPI.Public/Pass/PassSystem.h | 2 +- .../RPI.Public/Pass/PassSystemInterface.h | 2 +- .../Code/Include/Atom/RPI.Public/RPISystem.h | 1 + .../Atom/RPI.Public/RPISystemInterface.h | 3 ++ .../Atom/RPI.Reflect/Asset/AssetUtils.h | 27 +++++++++- .../Source/RPI.Public/Buffer/BufferSystem.cpp | 11 ++++ .../Source/RPI.Public/Image/ImageSystem.cpp | 7 +++ .../Source/RPI.Public/Pass/PassLibrary.cpp | 5 +- .../Source/RPI.Public/Pass/PassSystem.cpp | 4 +- .../RPI/Code/Source/RPI.Public/RPISystem.cpp | 52 +++++++++++-------- .../Source/RPI.Public/ViewportContext.cpp | 1 + .../Shader/ShaderResourceGroupAsset.cpp | 6 ++- 21 files changed, 134 insertions(+), 38 deletions(-) diff --git a/Gems/Atom/Bootstrap/Code/Source/BootstrapSystemComponent.cpp b/Gems/Atom/Bootstrap/Code/Source/BootstrapSystemComponent.cpp index ddf0ae9274..e3bdb28046 100644 --- a/Gems/Atom/Bootstrap/Code/Source/BootstrapSystemComponent.cpp +++ b/Gems/Atom/Bootstrap/Code/Source/BootstrapSystemComponent.cpp @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -166,6 +167,18 @@ namespace AZ RPI::RPISystemInterface::Get()->InitializeSystemAssets(); + if (!RPI::RPISystemInterface::Get()->IsInitialized()) + { + AZ::OSString msgBoxMessage; + msgBoxMessage.append("RPI System could not initialize correctly. Check log for detail."); + + AZ::NativeUI::NativeUIRequestBus::Broadcast( + &AZ::NativeUI::NativeUIRequestBus::Events::DisplayOkDialog, "O3DE Fatal Error", msgBoxMessage.c_str(), false); + AzFramework::ApplicationRequests::Bus::Broadcast(&AzFramework::ApplicationRequests::ExitMainLoop); + + return; + } + // In the case of the game we want to call create and register the scene as a soon as we can // because a level could be loaded in autoexec.cfg and that will assert if there is no scene registered // to get the feature processors for the components. So we can't wait until the tick (whereas the Editor wants to wait) diff --git a/Gems/Atom/RHI/Code/Include/Atom/RHI/CpuProfilerImpl.h b/Gems/Atom/RHI/Code/Include/Atom/RHI/CpuProfilerImpl.h index 777a20ada9..30523194b6 100644 --- a/Gems/Atom/RHI/Code/Include/Atom/RHI/CpuProfilerImpl.h +++ b/Gems/Atom/RHI/Code/Include/Atom/RHI/CpuProfilerImpl.h @@ -124,6 +124,8 @@ namespace AZ // This lock will only be contested when the CpuProfiler's Shutdown() method has been called AZStd::shared_mutex m_shutdownMutex; + + bool m_initialized = false; }; }; // namespace RPI diff --git a/Gems/Atom/RHI/Code/Source/RHI/CpuProfilerImpl.cpp b/Gems/Atom/RHI/Code/Source/RHI/CpuProfilerImpl.cpp index 28c3ef6a7b..8242c89886 100644 --- a/Gems/Atom/RHI/Code/Source/RHI/CpuProfilerImpl.cpp +++ b/Gems/Atom/RHI/Code/Source/RHI/CpuProfilerImpl.cpp @@ -82,10 +82,15 @@ namespace AZ void CpuProfilerImpl::Init() { Interface::Register(this); + m_initialized = true; } void CpuProfilerImpl::Shutdown() { + if (!m_initialized) + { + return; + } // When this call is made, no more thread profiling calls can be performed anymore Interface::Unregister(this); @@ -97,6 +102,7 @@ namespace AZ // Cleanup all TLS m_registeredThreads.clear(); m_timeRegionMap.clear(); + m_initialized = false; } void CpuProfilerImpl::BeginTimeRegion(TimeRegion& timeRegion) diff --git a/Gems/Atom/RHI/Code/Source/RHI/RHISystem.cpp b/Gems/Atom/RHI/Code/Source/RHI/RHISystem.cpp index f92d2621b1..95e0a33981 100644 --- a/Gems/Atom/RHI/Code/Source/RHI/RHISystem.cpp +++ b/Gems/Atom/RHI/Code/Source/RHI/RHISystem.cpp @@ -200,9 +200,12 @@ namespace AZ m_platformLimitsDescriptor = nullptr; m_pipelineStateCache = nullptr; - m_device->PreShutdown(); - AZ_Assert(m_device->use_count()==1, "The ref count for Device is %i but it should be 1 here to ensure all the resources are released", m_device->use_count()); - m_device = nullptr; + if (m_device) + { + m_device->PreShutdown(); + AZ_Assert(m_device->use_count()==1, "The ref count for Device is %i but it should be 1 here to ensure all the resources are released", m_device->use_count()); + m_device = nullptr; + } m_cpuProfiler.Shutdown(); } diff --git a/Gems/Atom/RHI/DX12/Code/Source/RHI/AsyncUploadQueue.cpp b/Gems/Atom/RHI/DX12/Code/Source/RHI/AsyncUploadQueue.cpp index f816a7ae04..22849f7236 100644 --- a/Gems/Atom/RHI/DX12/Code/Source/RHI/AsyncUploadQueue.cpp +++ b/Gems/Atom/RHI/DX12/Code/Source/RHI/AsyncUploadQueue.cpp @@ -90,12 +90,16 @@ namespace AZ void AsyncUploadQueue::Shutdown() { - m_copyQueue->Shutdown(); + if (m_copyQueue) + { + m_copyQueue->Shutdown(); + m_copyQueue = nullptr; + } m_commandList = nullptr; - for (size_t i = 0; i < m_descriptor.m_frameCount; ++i) + for (auto& framePacket : m_framePackets) { - m_framePackets[i].m_fence.Shutdown(); + framePacket.m_fence.Shutdown(); } m_framePackets.clear(); m_uploadFence.Shutdown(); diff --git a/Gems/Atom/RHI/DX12/Code/Source/RHI/CommandQueueContext.cpp b/Gems/Atom/RHI/DX12/Code/Source/RHI/CommandQueueContext.cpp index 4c133084ac..a31e105b19 100644 --- a/Gems/Atom/RHI/DX12/Code/Source/RHI/CommandQueueContext.cpp +++ b/Gems/Atom/RHI/DX12/Code/Source/RHI/CommandQueueContext.cpp @@ -109,7 +109,10 @@ namespace AZ AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzRender); for (uint32_t hardwareQueueIdx = 0; hardwareQueueIdx < RHI::HardwareQueueClassCount; ++hardwareQueueIdx) { - m_commandQueues[hardwareQueueIdx]->WaitForIdle(); + if (m_commandQueues[hardwareQueueIdx]) + { + m_commandQueues[hardwareQueueIdx]->WaitForIdle(); + } } } diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Buffer/BufferSystem.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Buffer/BufferSystem.h index 91d60bcb36..c4b6aa74b4 100644 --- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Buffer/BufferSystem.h +++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Buffer/BufferSystem.h @@ -45,6 +45,8 @@ namespace AZ private: RHI::Ptr m_commonPools[static_cast(CommonBufferPoolType::Count)]; + + bool m_initialized = false; }; } // namespace RPI } // namespace AZ diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Image/ImageSystem.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Image/ImageSystem.h index 67f33758dc..b8f52a532e 100644 --- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Image/ImageSystem.h +++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Image/ImageSystem.h @@ -80,6 +80,8 @@ namespace AZ Data::Asset m_defaultStreamingImageControllerAsset; AZStd::fixed_vector, static_cast(SystemImage::Count)> m_systemImages; + + bool m_initialized = false; }; } } 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 e61b90d55a..283cea7c0a 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 @@ -82,7 +82,7 @@ namespace AZ void RemovePassFromLibrary(Pass* pass); //! Load pass templates which are list in an AssetAliases - void LoadPassTemplateMappings(const AZStd::string& templateMappingPath); + bool LoadPassTemplateMappings(const AZStd::string& templateMappingPath); bool LoadPassTemplateMappings(Data::Asset mappingAsset); //! Returns a list of passes found in the pass name mapping using the provided pass filter 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 acbb914dfa..d37868025c 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 @@ -66,7 +66,7 @@ namespace AZ // PassSystemInterface functions... void ProcessQueuedChanges() override; - void LoadPassTemplateMappings(const AZStd::string& templateMappingPath) override; + bool LoadPassTemplateMappings(const AZStd::string& templateMappingPath) override; void WriteTemplateToFile(const PassTemplate& passTemplate, AZStd::string_view assetFilePath) override; void DebugPrintPassHierarchy() override; bool IsBuilding() const override; 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 93754c2229..82d52ab5a2 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 @@ -65,7 +65,7 @@ namespace AZ virtual void ProcessQueuedChanges() = 0; //! Load pass templates listed in a name-assetid mapping asset - virtual void LoadPassTemplateMappings(const AZStd::string& templateMappingPath) = 0; + 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 //! quickly authoring a pass template in code and then outputting it as a pass asset using JSON diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/RPISystem.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/RPISystem.h index 80b9022f0d..ff3c784a51 100644 --- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/RPISystem.h +++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/RPISystem.h @@ -70,6 +70,7 @@ namespace AZ void Shutdown(); // RPISystemInterface overrides... + bool IsInitialized() const override; void InitializeSystemAssets() override; void RegisterScene(ScenePtr scene) override; void UnregisterScene(ScenePtr scene) override; diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/RPISystemInterface.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/RPISystemInterface.h index 27b381257d..c2ceca73a9 100644 --- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/RPISystemInterface.h +++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/RPISystemInterface.h @@ -40,6 +40,9 @@ namespace AZ //! Note: can't rely on the AzFramework::AssetCatalogEventBus's OnCatalogLoaded since the order of calling handlers is undefined. virtual void InitializeSystemAssets() = 0; + //! Was the RPI system initialized properly + virtual bool IsInitialized() const = 0; + //! Register a created scene to RPISystem. Registered scene will be simulated and rendered in RPISystem ticks virtual void RegisterScene(ScenePtr scene) = 0; 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 527bae7e1f..5a169a9e61 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 @@ -15,6 +15,8 @@ #include #include +#include + namespace AZ { namespace RPI @@ -48,6 +50,12 @@ namespace AZ //! @return a null asset if the asset could not be found or loaded. template Data::Asset LoadAssetById(Data::AssetId assetId, TraceLevel reporting = TraceLevel::Warning); + + //! Loads a critial asset using a file path (both source and product path should be same), on the current thread. + //! If the asset wasn't compiled, wait until the asset is compiled. + //! @return a null asset if the asset could not be compiled or loaded. + template + Data::Asset LoadCriticalAsset(const AZStd::string& assetFilePath, TraceLevel reporting = TraceLevel::Error); template bool LoadBlocking(AZ::Data::Asset& asset, TraceLevel reporting = TraceLevel::Warning); @@ -89,7 +97,7 @@ namespace AZ assetId, AZ::Data::AssetLoadBehavior::PreLoad); asset.BlockUntilLoadComplete(); - if (!asset.Get()) + if (!asset.IsReady()) { AssetUtilsInternal::ReportIssue(reporting, AZStd::string::format("Could not load '%s'", productPath).c_str()); return {}; @@ -117,7 +125,7 @@ namespace AZ ); asset.BlockUntilLoadComplete(); - if (!asset.Get()) + if (!asset.IsReady()) { AssetUtilsInternal::ReportIssue(reporting, AZStd::string::format("Could not load '%s'", assetId.ToString().c_str()).c_str()); return {}; @@ -126,6 +134,21 @@ namespace AZ return asset; } + 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) + { + AssetUtilsInternal::ReportIssue(reporting, AZStd::string::format("Could not compile asset '%s'", assetFilePath.c_str()).c_str()); + return {}; + } + + return LoadAssetByProductPath(assetFilePath.c_str(), reporting); + } + template bool LoadBlocking(AZ::Data::Asset& asset, TraceLevel reporting) { diff --git a/Gems/Atom/RPI/Code/Source/RPI.Public/Buffer/BufferSystem.cpp b/Gems/Atom/RPI/Code/Source/RPI.Public/Buffer/BufferSystem.cpp index 491f57deec..9a9254b0d6 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Public/Buffer/BufferSystem.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Public/Buffer/BufferSystem.cpp @@ -61,10 +61,16 @@ namespace AZ Data::InstanceDatabase::Create(azrtti_typeid(), handler); } Interface::Register(this); + + m_initialized = true; } void BufferSystem::Shutdown() { + if (!m_initialized) + { + return; + } for (uint8_t index = 0; index < static_cast(CommonBufferPoolType::Count); index++) { m_commonPools[index] = nullptr; @@ -72,6 +78,7 @@ namespace AZ Interface::Unregister(this); Data::InstanceDatabase::Destroy(); Data::InstanceDatabase::Destroy(); + m_initialized = false; } RHI::Ptr BufferSystem::GetCommonBufferPool(CommonBufferPoolType poolType) @@ -87,6 +94,10 @@ namespace AZ bool BufferSystem::CreateCommonBufferPool(CommonBufferPoolType poolType) { + if (!m_initialized) + { + return false; + } auto* device = RHI::RHISystemInterface::Get()->GetDevice(); RHI::Ptr bufferPool = RHI::Factory::Get().CreateBufferPool(); diff --git a/Gems/Atom/RPI/Code/Source/RPI.Public/Image/ImageSystem.cpp b/Gems/Atom/RPI/Code/Source/RPI.Public/Image/ImageSystem.cpp index ac7ba1e3cc..f7cdc2ff71 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Public/Image/ImageSystem.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Public/Image/ImageSystem.cpp @@ -148,10 +148,16 @@ namespace AZ CreateDefaultResources(desc); Interface::Register(this); + + m_initialized = true; } void ImageSystem::Shutdown() { + if (!m_initialized) + { + return; + } Interface::Unregister(this); m_defaultStreamingImageControllerAsset.Release(); @@ -167,6 +173,7 @@ namespace AZ Data::InstanceDatabase::Destroy(); m_activeStreamingPools.clear(); + m_initialized = false; } void ImageSystem::Update() 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 d8f6416abc..6c1f96e414 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/PassLibrary.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/PassLibrary.cpp @@ -327,14 +327,15 @@ namespace AZ } } - void PassLibrary::LoadPassTemplateMappings(const AZStd::string& templateMappingPath) + bool PassLibrary::LoadPassTemplateMappings(const AZStd::string& templateMappingPath) { - Data::Asset mappingAsset = AssetUtils::LoadAssetByProductPath(templateMappingPath.c_str(), AssetUtils::TraceLevel::Error); + Data::Asset mappingAsset = AssetUtils::LoadCriticalAsset(templateMappingPath.c_str(), AssetUtils::TraceLevel::Error); bool success = LoadPassTemplateMappings(mappingAsset); if (success) { Data::AssetBus::MultiHandler::BusConnect(mappingAsset->GetId()); } + return success; } bool PassLibrary::LoadPassTemplateMappings(Data::Asset mappingAsset) 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 55b71c6962..706d759231 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/PassSystem.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/PassSystem.cpp @@ -100,9 +100,9 @@ namespace AZ m_rootPass->m_flags.m_partOfHierarchy = true; } - void PassSystem::LoadPassTemplateMappings(const AZStd::string& templateMappingPath) + bool PassSystem::LoadPassTemplateMappings(const AZStd::string& templateMappingPath) { - m_passLibrary.LoadPassTemplateMappings(templateMappingPath); + return m_passLibrary.LoadPassTemplateMappings(templateMappingPath); } void PassSystem::WriteTemplateToFile(const PassTemplate& passTemplate, AZStd::string_view assetFilePath) diff --git a/Gems/Atom/RPI/Code/Source/RPI.Public/RPISystem.cpp b/Gems/Atom/RPI/Code/Source/RPI.Public/RPISystem.cpp index 52c39d2204..5cd6f93715 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Public/RPISystem.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Public/RPISystem.cpp @@ -334,7 +334,6 @@ namespace AZ void RPISystem::InitializeSystemAssets() { - AzFramework::AssetSystem::AssetStatus status = AzFramework::AssetSystem::AssetStatus_Unknown; if (m_systemAssetsInitialized) { AZ_Warning("RPISystem", false , "InitializeSystemAssets should only be called once'"); @@ -344,36 +343,47 @@ namespace AZ //[GFX TODO][ATOM-5867] - Move file loading code within RHI to reduce coupling with RPI AZStd::string platformLimitsFilePath = AZStd::string::format("config/platform/%s/%s/platformlimits.azasset", AZ_TRAIT_OS_PLATFORM_NAME, GetRenderApiName().GetCStr()); AZStd::to_lower(platformLimitsFilePath.begin(), platformLimitsFilePath.end()); - // Wait for the platformlimits asset to be compiled (if it exists) - AzFramework::AssetSystemRequestBus::BroadcastResult( - status, &AzFramework::AssetSystemRequestBus::Events::CompileAssetSync, platformLimitsFilePath); - Data::Asset platformLimitsAsset = RPI::AssetUtils::LoadAssetByProductPath(platformLimitsFilePath.c_str(), RPI::AssetUtils::TraceLevel::Error); - m_descriptor.m_rhiSystemDescriptor.m_platformLimits = RPI::GetDataFromAnyAsset(platformLimitsAsset); + + Data::Asset platformLimitsAsset; + platformLimitsAsset = RPI::AssetUtils::LoadCriticalAsset(platformLimitsFilePath.c_str(), RPI::AssetUtils::TraceLevel::None); + // Only read the m_platformLimits if the platformLimitsAsset is ready. + // The platformLimitsAsset may not exist for null renderer which is allowed + if (platformLimitsAsset.IsReady()) + { + m_descriptor.m_rhiSystemDescriptor.m_platformLimits = RPI::GetDataFromAnyAsset(platformLimitsAsset); + } + + m_viewSrgAsset = AssetUtils::LoadCriticalAsset( m_descriptor.m_viewSrgAssetPath.c_str()); + if (!m_viewSrgAsset.IsReady()) + { + return; + } + m_sceneSrgAsset = AssetUtils::LoadCriticalAsset(m_descriptor.m_sceneSrgAssetPath.c_str()); + if (!m_sceneSrgAsset.IsReady()) + { + return; + } m_rhiSystem.Init(m_descriptor.m_rhiSystemDescriptor); m_imageSystem.Init(m_descriptor.m_imageSystemDescriptor); m_bufferSystem.Init(); m_dynamicDraw.Init(m_descriptor.m_dynamicDrawSystemDescriptor); - // Wait for the assets be compiled - AzFramework::AssetSystemRequestBus::BroadcastResult( - status, &AzFramework::AssetSystemRequestBus::Events::CompileAssetSync, m_descriptor.m_viewSrgAssetPath); - AZ_Error("RPISystem", status == AzFramework::AssetSystem::AssetStatus_Compiled, "Could not compile view SRG at '%s'", m_descriptor.m_viewSrgAssetPath.c_str()); - AzFramework::AssetSystemRequestBus::BroadcastResult( - status, &AzFramework::AssetSystemRequestBus::Events::CompileAssetSync, m_descriptor.m_sceneSrgAssetPath); - AZ_Error("RPISystem", status == AzFramework::AssetSystem::AssetStatus_Compiled, "Could not compile scene SRG at '%s'", m_descriptor.m_sceneSrgAssetPath.c_str()); - AzFramework::AssetSystemRequestBus::BroadcastResult( - status, &AzFramework::AssetSystemRequestBus::Events::CompileAssetSync, m_descriptor.m_passTemplatesMappingPath); - AZ_Error("RPISystem", status == AzFramework::AssetSystem::AssetStatus_Compiled, "Could not compile pass template mapping at '%s'", m_descriptor.m_passTemplatesMappingPath.c_str()); - - m_viewSrgAsset = AssetUtils::LoadAssetByProductPath(m_descriptor.m_viewSrgAssetPath.c_str(), AssetUtils::TraceLevel::Error); - m_sceneSrgAsset = AssetUtils::LoadAssetByProductPath(m_descriptor.m_sceneSrgAssetPath.c_str(), AssetUtils::TraceLevel::Error); - // Have pass system load default pass template mapping - m_passSystem.LoadPassTemplateMappings(m_descriptor.m_passTemplatesMappingPath); + bool passSystemReady = m_passSystem.LoadPassTemplateMappings(m_descriptor.m_passTemplatesMappingPath); + if (!passSystemReady) + { + return; + } + m_systemAssetsInitialized = true; } + bool RPISystem::IsInitialized() const + { + return m_systemAssetsInitialized; + } + void RPISystem::InitializeSystemAssetsForTests() { if (m_systemAssetsInitialized) diff --git a/Gems/Atom/RPI/Code/Source/RPI.Public/ViewportContext.cpp b/Gems/Atom/RPI/Code/Source/RPI.Public/ViewportContext.cpp index b5d3f815fe..4bccd48b66 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Public/ViewportContext.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Public/ViewportContext.cpp @@ -26,6 +26,7 @@ namespace AZ , m_windowContext(AZStd::make_shared()) , m_manager(manager) , m_name(name) + , m_viewportSize(1, 1) { m_windowContext->Initialize(device, nativeWindow); AzFramework::WindowRequestBus::EventResult( diff --git a/Gems/Atom/RPI/Code/Source/RPI.Reflect/Shader/ShaderResourceGroupAsset.cpp b/Gems/Atom/RPI/Code/Source/RPI.Reflect/Shader/ShaderResourceGroupAsset.cpp index d372e1442d..d8f8c7d1ce 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Reflect/Shader/ShaderResourceGroupAsset.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Reflect/Shader/ShaderResourceGroupAsset.cpp @@ -41,7 +41,11 @@ namespace AZ const RHI::ShaderResourceGroupLayout* ShaderResourceGroupAsset::GetLayout() const { - AZ_Assert(m_currentAPITypeIndex < m_perAPILayout.size(), "Invalid API Type index"); + AZ_Error("RHI::ShaderResourceGroupLayout", m_currentAPITypeIndex < m_perAPILayout.size(), "Invalid API Type index"); + if (m_currentAPITypeIndex >= m_perAPILayout.size()) + { + return nullptr; + } return m_perAPILayout[m_currentAPITypeIndex].second.get(); }