/* * Copyright (c) Contributors to the Open 3D Engine Project. * For complete copyright and license terms please see the LICENSE at the root of this distribution. * * SPDX-License-Identifier: Apache-2.0 OR MIT * */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include AZ_PUSH_DISABLE_WARNING(4251 4800, "-Wunknown-warning-option") // disable warnings spawned by QT #include #include #include AZ_POP_DISABLE_WARNING void InitShaderManagementConsoleResources() { // Must register qt resources from other modules Q_INIT_RESOURCE(ShaderManagementConsole); Q_INIT_RESOURCE(InspectorWidget); Q_INIT_RESOURCE(AtomToolsAssetBrowser); } namespace ShaderManagementConsole { ShaderManagementConsoleApplication::ShaderManagementConsoleApplication(int* argc, char*** argv) : Base(argc, argv) { InitShaderManagementConsoleResources(); QApplication::setApplicationName("O3DE Shader Management Console"); // The settings registry has been created at this point, so add the CMake target AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_AddBuildSystemTargetSpecialization( *AZ::SettingsRegistry::Get(), GetBuildTargetName()); ShaderManagementConsoleRequestBus::Handler::BusConnect(); AzToolsFramework::EditorWindowRequestBus::Handler::BusConnect(); AtomToolsFramework::AtomToolsMainWindowFactoryRequestBus::Handler::BusConnect(); } ShaderManagementConsoleApplication::~ShaderManagementConsoleApplication() { ShaderManagementConsoleRequestBus::Handler::BusDisconnect(); AzToolsFramework::EditorWindowRequestBus::Handler::BusDisconnect(); AtomToolsFramework::AtomToolsMainWindowFactoryRequestBus::Handler::BusDisconnect(); m_window.reset(); } void ShaderManagementConsoleApplication::Reflect(AZ::ReflectContext* context) { Base::Reflect(context); if (AZ::BehaviorContext* behaviorContext = azrtti_cast(context)) { behaviorContext->EBus("ShaderManagementConsoleRequestBus") ->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Automation) ->Attribute(AZ::Script::Attributes::Category, "Editor") ->Attribute(AZ::Script::Attributes::Module, "shadermanagementconsole") ->Event("GetSourceAssetInfo", &ShaderManagementConsoleRequestBus::Events::GetSourceAssetInfo) ->Event("FindMaterialAssetsUsingShader", &ShaderManagementConsoleRequestBus::Events::FindMaterialAssetsUsingShader ) ->Event("GetMaterialInstanceShaderItems", &ShaderManagementConsoleRequestBus::Events::GetMaterialInstanceShaderItems) ; behaviorContext->EBus("ShaderManagementConsoleDocumentRequestBus") ->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common) ->Attribute(AZ::Script::Attributes::Category, "Editor") ->Attribute(AZ::Script::Attributes::Module, "shadermanagementconsole") ->Event("SetShaderVariantListSourceData", &ShaderManagementConsoleDocumentRequestBus::Events::SetShaderVariantListSourceData) ->Event("GetShaderVariantListSourceData", &ShaderManagementConsoleDocumentRequestBus::Events::GetShaderVariantListSourceData) ->Event("GetShaderOptionCount", &ShaderManagementConsoleDocumentRequestBus::Events::GetShaderOptionCount) ->Event("GetShaderOptionDescriptor", &ShaderManagementConsoleDocumentRequestBus::Events::GetShaderOptionDescriptor) ->Event("GetShaderVariantCount", &ShaderManagementConsoleDocumentRequestBus::Events::GetShaderVariantCount) ->Event("GetShaderVariantInfo", &ShaderManagementConsoleDocumentRequestBus::Events::GetShaderVariantInfo) ; } } const char* ShaderManagementConsoleApplication::GetCurrentConfigurationName() const { #if defined(_RELEASE) return "ReleaseShaderManagementConsole"; #elif defined(_DEBUG) return "DebugShaderManagementConsole"; #else return "ProfileShaderManagementConsole"; #endif } void ShaderManagementConsoleApplication::StartCommon(AZ::Entity* systemEntity) { Base::StartCommon(systemEntity); AtomToolsFramework::AtomToolsDocumentSystemRequestBus::Broadcast( &AtomToolsFramework::AtomToolsDocumentSystemRequestBus::Handler::RegisterDocumentType, []() { return aznew ShaderManagementConsoleDocument(); }); } AZStd::string ShaderManagementConsoleApplication::GetBuildTargetName() const { #if !defined(LY_CMAKE_TARGET) #error "LY_CMAKE_TARGET must be defined in order to add this source file to a CMake executable target" #endif //! Returns the build system target name of "ShaderManagementConsole" return AZStd::string_view{ LY_CMAKE_TARGET }; } AZStd::vector ShaderManagementConsoleApplication::GetCriticalAssetFilters() const { return AZStd::vector({ "passes/", "config/" }); } QWidget* ShaderManagementConsoleApplication::GetAppMainWindow() { return m_window.get(); } void ShaderManagementConsoleApplication::CreateMainWindow() { m_assetBrowserInteractions.reset(aznew ShaderManagementConsoleBrowserInteractions); m_window.reset(aznew ShaderManagementConsoleWindow); m_window->show(); } void ShaderManagementConsoleApplication::DestroyMainWindow() { m_window.reset(); } AZ::Data::AssetInfo ShaderManagementConsoleApplication::GetSourceAssetInfo(const AZStd::string& sourceAssetFileName) { bool result = false; AZ::Data::AssetInfo assetInfo; AZStd::string watchFolder; AzToolsFramework::AssetSystemRequestBus::BroadcastResult( result, &AzToolsFramework::AssetSystem::AssetSystemRequest::GetSourceInfoBySourcePath, sourceAssetFileName.c_str(), assetInfo, watchFolder); AZ_Error(nullptr, result, "Failed to get the asset info for the file: %s.", sourceAssetFileName.c_str()); return assetInfo; } AZStd::vector ShaderManagementConsoleApplication::FindMaterialAssetsUsingShader(const AZStd::string& shaderFilePath) { // Collect the material types referencing the shader AZStd::vector materialTypeSources; AzToolsFramework::AssetDatabase::AssetDatabaseConnection assetDatabaseConnection; assetDatabaseConnection.OpenDatabase(); assetDatabaseConnection.QuerySourceDependencyByDependsOnSource( shaderFilePath.c_str(), nullptr, AzToolsFramework::AssetDatabase::SourceFileDependencyEntry::DEP_Any, [&](AzToolsFramework::AssetDatabase::SourceFileDependencyEntry& sourceFileDependencyEntry) { AZStd::string assetExtension; if (AzFramework::StringFunc::Path::GetExtension(sourceFileDependencyEntry.m_source.c_str(), assetExtension, false)) { if (assetExtension == "materialtype") { materialTypeSources.push_back(sourceFileDependencyEntry.m_source); } } return true; }); AzToolsFramework::AssetDatabase::ProductDatabaseEntryContainer productDependencies; for (const auto& materialTypeSource : materialTypeSources) { bool result = false; AZ::Data::AssetInfo materialTypeSourceAssetInfo; AZStd::string watchFolder; AzToolsFramework::AssetSystemRequestBus::BroadcastResult( result, &AzToolsFramework::AssetSystem::AssetSystemRequest::GetSourceInfoBySourcePath, materialTypeSource.c_str(), materialTypeSourceAssetInfo, watchFolder); assetDatabaseConnection.QueryDirectReverseProductDependenciesBySourceGuidSubId( materialTypeSourceAssetInfo.m_assetId.m_guid, materialTypeSourceAssetInfo.m_assetId.m_subId, [&](AzToolsFramework::AssetDatabase::ProductDatabaseEntry& entry) { AZStd::string assetExtension; if (AzFramework::StringFunc::Path::GetExtension(entry.m_productName.c_str(), assetExtension, false)) { if (assetExtension == "azmaterial") { productDependencies.push_back(entry); } } return true; }); } AZStd::vector results; results.reserve(productDependencies.size()); for (auto product : productDependencies) { assetDatabaseConnection.QueryCombinedByProductID( product.m_productID, [&](AzToolsFramework::AssetDatabase::CombinedDatabaseEntry& combined) { results.push_back({ combined.m_sourceGuid, combined.m_subID }); return false; }, nullptr); } return results; } AZStd::vector ShaderManagementConsoleApplication::GetMaterialInstanceShaderItems( const AZ::Data::AssetId& assetId) { auto materialAsset = AZ::RPI::AssetUtils::LoadAssetById(assetId, AZ::RPI::AssetUtils::TraceLevel::Error); auto materialInstance = AZ::RPI::Material::Create(materialAsset); AZ_Error( nullptr, materialAsset, "Failed to get a material instance from product asset id: %s", assetId.ToString().c_str()); if (materialInstance != nullptr) { return AZStd::vector( materialInstance->GetShaderCollection().begin(), materialInstance->GetShaderCollection().end()); } return AZStd::vector(); } } // namespace ShaderManagementConsole