From 2b16f6860f588888039884cfba74167a34ed2340 Mon Sep 17 00:00:00 2001 From: Guthrie Adams Date: Sun, 13 Feb 2022 02:04:14 -0600 Subject: [PATCH 1/3] Atom Tools: Moving shader management console file operations into document class Standardizing how document classes are implemented between atom tools. Moved several functions that were added to allow shader variant lists to be built from a Python script into the tools document class. Reimplemented the portion of the script that generated a shader variant list from a shader asset into the document class. Opening a shader management console document from a shader asset will automatically generate this shader variant list data inside the document. Description now just opens and saves the documents to a new location. Signed-off-by: Guthrie Adams --- .../ShaderManagementConsoleDocument.cpp | 200 ++++++++++++++++-- .../ShaderManagementConsoleDocument.h | 8 +- .../ShaderManagementConsoleApplication.cpp | 124 +---------- .../ShaderManagementConsoleApplication.h | 7 - .../ShaderManagementConsoleRequestBus.h | 38 ---- .../Window/ShaderManagementConsoleWindow.cpp | 29 +-- .../Code/shadermanagementconsole_files.cmake | 1 - .../GenerateShaderVariantListForMaterials.py | 130 ++++-------- 8 files changed, 249 insertions(+), 288 deletions(-) delete mode 100644 Gems/Atom/Tools/ShaderManagementConsole/Code/Source/ShaderManagementConsoleRequestBus.h diff --git a/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/Document/ShaderManagementConsoleDocument.cpp b/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/Document/ShaderManagementConsoleDocument.cpp index e7bd6033de..78a6f78d49 100644 --- a/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/Document/ShaderManagementConsoleDocument.cpp +++ b/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/Document/ShaderManagementConsoleDocument.cpp @@ -6,10 +6,16 @@ * */ +#include +#include #include +#include #include #include +#include #include +#include +#include #include namespace ShaderManagementConsole @@ -32,10 +38,7 @@ namespace ShaderManagementConsole AzFramework::StringFunc::Path::ReplaceExtension(shaderPath, AZ::RPI::ShaderAsset::Extension); m_shaderAsset = AZ::RPI::AssetUtils::LoadAssetByProductPath(shaderPath.c_str()); - if (!m_shaderAsset) - { - AZ_Error("ShaderManagementConsoleDocument", false, "Could not load shader asset: %s.", shaderPath.c_str()); - } + AZ_Error("ShaderManagementConsoleDocument", m_shaderAsset.IsReady(), "Could not load shader asset: %s.", shaderPath.c_str()); AtomToolsFramework::AtomToolsDocumentNotificationBus::Event( m_toolId, &AtomToolsFramework::AtomToolsDocumentNotificationBus::Events::OnDocumentModified, m_id); @@ -107,22 +110,98 @@ namespace ShaderManagementConsole return false; } - if (!AzFramework::StringFunc::Path::IsExtension(m_absolutePath.c_str(), AZ::RPI::ShaderVariantListSourceData::Extension)) + if (AzFramework::StringFunc::Path::IsExtension(m_absolutePath.c_str(), AZ::RPI::ShaderVariantListSourceData::Extension)) { - AZ_Error("ShaderManagementConsoleDocument", false, "Document extension is not supported: '%s.'", m_absolutePath.c_str()); - return OpenFailed(); + // Load the shader config data and create a shader config asset from it + AZ::RPI::ShaderVariantListSourceData sourceData; + if (!AZ::RPI::JsonUtils::LoadObjectFromFile(m_absolutePath, sourceData)) + { + AZ_Error( + "ShaderManagementConsoleDocument", false, "Failed loading shader variant list data: '%s.'", m_absolutePath.c_str()); + return OpenFailed(); + } + + SetShaderVariantListSourceData(sourceData); + return IsOpen() ? OpenSucceeded() : OpenFailed(); } - // Load the shader config data and create a shader config asset from it - AZ::RPI::ShaderVariantListSourceData sourceData; - if (!AZ::RPI::JsonUtils::LoadObjectFromFile(m_absolutePath, sourceData)) + if (AzFramework::StringFunc::Path::IsExtension(m_absolutePath.c_str(), AZ::RPI::ShaderSourceData::Extension)) { - AZ_Error("ShaderManagementConsoleDocument", false, "Failed loading shader variant list data: '%s.'", m_absolutePath.c_str()); - return OpenFailed(); + // Get info such as relative path of the file and asset id + bool result = false; + AZ::Data::AssetInfo shaderAssetInfo; + AZStd::string watchFolder; + AzToolsFramework::AssetSystemRequestBus::BroadcastResult( + result, &AzToolsFramework::AssetSystem::AssetSystemRequest::GetSourceInfoBySourcePath, m_absolutePath.c_str(), + shaderAssetInfo, watchFolder); + + if (!result) + { + AZ_Error( + "ShaderManagementConsoleDocument", false, "Failed to get the asset info for the file: %s.", m_absolutePath.c_str()); + return OpenFailed(); + } + + // retrieves a list of all material source files that use the shader. Note that materials inherit from materialtype files, which + // are actual files that refer to shader files. + const auto& materialAssetIds = FindMaterialAssetsUsingShader(shaderAssetInfo.m_relativePath); + + // This loop collects all uniquely-identified shader items used by the materials based on its shader variant id. + AZStd::set shaderVariantIds; + AZStd::vector shaderVariantListShaderOptionGroups; + for (const auto& materialAssetId : materialAssetIds) + { + const auto& materialInstanceShaderItems = GetMaterialInstanceShaderItems(materialAssetId); + for (const auto& shaderItem : materialInstanceShaderItems) + { + const auto& shaderAssetId = shaderItem.GetShaderAsset().GetId(); + if (shaderAssetInfo.m_assetId == shaderAssetId) + { + const auto& shaderVariantId = shaderItem.GetShaderVariantId(); + if (!shaderVariantId.IsEmpty() && shaderVariantIds.insert(shaderVariantId).second) + { + shaderVariantListShaderOptionGroups.push_back(shaderItem.GetShaderOptionGroup()); + } + } + } + } + + // Generate the shader variant list data by collecting shader option name-value pairs.s + AZ::RPI::ShaderVariantListSourceData shaderVariantList; + shaderVariantList.m_shaderFilePath = shaderAssetInfo.m_relativePath; + int stableId = 1; + for (const auto& shaderOptionGroup : shaderVariantListShaderOptionGroups) + { + AZ::RPI::ShaderVariantListSourceData::VariantInfo variantInfo; + variantInfo.m_stableId = stableId; + + const auto& shaderOptionDescriptors = shaderOptionGroup.GetShaderOptionDescriptors(); + for (const auto& shaderOptionDescriptor : shaderOptionDescriptors) + { + const auto& optionName = shaderOptionDescriptor.GetName(); + const auto& optionValue = shaderOptionGroup.GetValue(optionName); + if (!optionValue.IsValid()) + { + continue; + } + + const auto& valueName = shaderOptionDescriptor.GetValueName(optionValue); + variantInfo.m_options[optionName.GetStringView()] = valueName.GetStringView(); + } + + if (!variantInfo.m_options.empty()) + { + shaderVariantList.m_shaderVariants.push_back(variantInfo); + stableId++; + } + } + + SetShaderVariantListSourceData(shaderVariantList); + return IsOpen() ? OpenSucceeded() : OpenFailed(); } - SetShaderVariantListSourceData(sourceData); - return IsOpen() ? OpenSucceeded() : OpenFailed(); + AZ_Error("ShaderManagementConsoleDocument", false, "Document extension is not supported: '%s.'", m_absolutePath.c_str()); + return OpenFailed(); } bool ShaderManagementConsoleDocument::Save() @@ -173,7 +252,8 @@ namespace ShaderManagementConsole bool ShaderManagementConsoleDocument::IsSavable() const { - return true; + return IsOpen() && + AzFramework::StringFunc::Path::IsExtension(m_absolutePath.c_str(), AZ::RPI::ShaderVariantListSourceData::Extension); } void ShaderManagementConsoleDocument::Clear() @@ -195,4 +275,94 @@ namespace ShaderManagementConsole m_absolutePath = m_savePathNormalized; return SaveSucceeded(); } + + AZStd::vector ShaderManagementConsoleDocument::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 ShaderManagementConsoleDocument::GetMaterialInstanceShaderItems( + const AZ::Data::AssetId& assetId) + { + auto materialAsset = AZ::RPI::AssetUtils::LoadAssetById(assetId, AZ::RPI::AssetUtils::TraceLevel::Error); + if (!materialAsset.IsReady()) + { + AZ_Error( + "ShaderManagementConsoleDocument", false, "Failed to load material asset from asset id: %s", + assetId.ToString().c_str()); + return AZStd::vector(); + } + + auto materialInstance = AZ::RPI::Material::Create(materialAsset); + if (!materialInstance) + { + AZ_Error( + "ShaderManagementConsoleDocument", false, "Failed to create material instance from asset: %s", + materialAsset.ToString().c_str()); + return AZStd::vector(); + } + + return AZStd::vector( + materialInstance->GetShaderCollection().begin(), materialInstance->GetShaderCollection().end()); + } } // namespace ShaderManagementConsole diff --git a/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/Document/ShaderManagementConsoleDocument.h b/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/Document/ShaderManagementConsoleDocument.h index 46002ce1da..c470f5826a 100644 --- a/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/Document/ShaderManagementConsoleDocument.h +++ b/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/Document/ShaderManagementConsoleDocument.h @@ -8,17 +8,17 @@ #pragma once #include +#include #include #include #include #include +#include #include namespace ShaderManagementConsole { - /** - * ShaderManagementConsoleDocument provides an API for modifying and saving document properties. - */ + //! ShaderManagementConsoleDocument provides an API for modifying and saving document properties. class ShaderManagementConsoleDocument : public AtomToolsFramework::AtomToolsDocument , public ShaderManagementConsoleDocumentRequestBus::Handler @@ -54,6 +54,8 @@ namespace ShaderManagementConsole void Clear() override; bool SaveSourceData(); + AZStd::vector FindMaterialAssetsUsingShader(const AZStd::string& shaderFilePath); + AZStd::vector GetMaterialInstanceShaderItems(const AZ::Data::AssetId& assetId); // Source data for shader variant list AZ::RPI::ShaderVariantListSourceData m_shaderVariantListSourceData; diff --git a/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/ShaderManagementConsoleApplication.cpp b/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/ShaderManagementConsoleApplication.cpp index 43936c59da..dff162b0cb 100644 --- a/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/ShaderManagementConsoleApplication.cpp +++ b/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/ShaderManagementConsoleApplication.cpp @@ -6,27 +6,17 @@ * */ -#include -#include -#include -#include -#include #include -#include #include #include #include #include #include -#include #include -#include #include -#include #include #include #include -#include #include #include @@ -62,13 +52,11 @@ namespace ShaderManagementConsole QApplication::setApplicationName("O3DE Shader Management Console"); - ShaderManagementConsoleRequestBus::Handler::BusConnect(); AzToolsFramework::EditorWindowRequestBus::Handler::BusConnect(); } ShaderManagementConsoleApplication::~ShaderManagementConsoleApplication() { - ShaderManagementConsoleRequestBus::Handler::BusDisconnect(); AzToolsFramework::EditorWindowRequestBus::Handler::BusDisconnect(); m_window.reset(); } @@ -79,15 +67,6 @@ namespace ShaderManagementConsole 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") @@ -145,8 +124,11 @@ namespace ShaderManagementConsole pythonArgs); }); } - else if (AzFramework::StringFunc::Path::IsExtension( - entries.front()->GetFullPath().c_str(), AZ::RPI::ShaderVariantListSourceData::Extension)) + + if (AzFramework::StringFunc::Path::IsExtension( + entries.front()->GetFullPath().c_str(), AZ::RPI::ShaderSourceData::Extension) || + AzFramework::StringFunc::Path::IsExtension( + entries.front()->GetFullPath().c_str(), AZ::RPI::ShaderVariantListSourceData::Extension)) { menu->addAction(QObject::tr("Open"), [entries, this]() { @@ -180,100 +162,4 @@ namespace ShaderManagementConsole { return m_window.get(); } - - 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 diff --git a/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/ShaderManagementConsoleApplication.h b/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/ShaderManagementConsoleApplication.h index 75d1ab83c8..01d0b9e415 100644 --- a/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/ShaderManagementConsoleApplication.h +++ b/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/ShaderManagementConsoleApplication.h @@ -12,14 +12,12 @@ #include #include #include -#include #include namespace ShaderManagementConsole { class ShaderManagementConsoleApplication : public AtomToolsFramework::AtomToolsDocumentApplication - , private ShaderManagementConsoleRequestBus::Handler , private AzToolsFramework::EditorWindowRequestBus::Handler { public: @@ -42,11 +40,6 @@ namespace ShaderManagementConsole // AzToolsFramework::EditorWindowRequests::Bus::Handler QWidget* GetAppMainWindow() override; - // ShaderManagementConsoleRequestBus::Handler overrides... - AZ::Data::AssetInfo GetSourceAssetInfo(const AZStd::string& sourceAssetFileName) override; - AZStd::vector FindMaterialAssetsUsingShader(const AZStd::string& shaderFilePath) override; - AZStd::vector GetMaterialInstanceShaderItems(const AZ::Data::AssetId& assetId) override; - private: AZStd::unique_ptr m_window; AZStd::unique_ptr m_assetBrowserInteractions; diff --git a/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/ShaderManagementConsoleRequestBus.h b/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/ShaderManagementConsoleRequestBus.h deleted file mode 100644 index 355c51ed54..0000000000 --- a/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/ShaderManagementConsoleRequestBus.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * 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 - * - */ - -#pragma once - -#include -#include -#include -#include -#include - -namespace ShaderManagementConsole -{ - //! ShaderManagementConsoleRequestBus provides - class ShaderManagementConsoleRequests - : public AZ::EBusTraits - { - public: - static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single; - static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single; - - //! Returns a shader file's asset id and relative filepath - virtual AZ::Data::AssetInfo GetSourceAssetInfo(const AZStd::string& sourceAssetFileName) = 0; - - // [GFX TODO][ATOM-14857] Generalize this API - //! Returns a list of material AssetIds that use the shader file. - virtual AZStd::vector FindMaterialAssetsUsingShader (const AZStd::string& shaderFilePath) = 0; - - //! Returns a list of shader items contained within an instantiated material source's shader collection. - virtual AZStd::vector GetMaterialInstanceShaderItems(const AZ::Data::AssetId& assetId) = 0; - }; - using ShaderManagementConsoleRequestBus = AZ::EBus; -} // namespace ShaderManagementConsole diff --git a/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/Window/ShaderManagementConsoleWindow.cpp b/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/Window/ShaderManagementConsoleWindow.cpp index b1bd906f81..7c1ee29cb2 100644 --- a/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/Window/ShaderManagementConsoleWindow.cpp +++ b/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/Window/ShaderManagementConsoleWindow.cpp @@ -9,10 +9,10 @@ #include #include #include +#include #include #include #include -#include AZ_PUSH_DISABLE_WARNING(4251 4800, "-Wunknown-warning-option") // disable warnings spawned by QT #include @@ -41,15 +41,17 @@ namespace ShaderManagementConsole m_assetBrowser->SetFilterState("", AZ::RPI::ShaderAsset::Group, true); m_assetBrowser->SetOpenHandler([this](const AZStd::string& absolutePath) { - if (AzFramework::StringFunc::Path::IsExtension(absolutePath.c_str(), AZ::RPI::ShaderVariantListSourceData::Extension)) { - AtomToolsFramework::AtomToolsDocumentSystemRequestBus::Event( - m_toolId, &AtomToolsFramework::AtomToolsDocumentSystemRequestBus::Events::OpenDocument, absolutePath); - return; - } + if (AzFramework::StringFunc::Path::IsExtension(absolutePath.c_str(), AZ::RPI::ShaderSourceData::Extension) || + AzFramework::StringFunc::Path::IsExtension(absolutePath.c_str(), AZ::RPI::ShaderVariantListSourceData::Extension)) + { + AtomToolsFramework::AtomToolsDocumentSystemRequestBus::Event( + m_toolId, &AtomToolsFramework::AtomToolsDocumentSystemRequestBus::Events::OpenDocument, absolutePath); + return; + } - QDesktopServices::openUrl(QUrl::fromLocalFile(absolutePath.c_str())); - }); + QDesktopServices::openUrl(QUrl::fromLocalFile(absolutePath.c_str())); + }); // Restore geometry and show the window mainWindowWrapper->showFromSettings(); @@ -66,7 +68,12 @@ namespace ShaderManagementConsole bool ShaderManagementConsoleWindow::GetOpenDocumentParams(AZStd::string& openPath) { openPath = QFileDialog::getOpenFileName( - this, tr("Open Document"), AZ::Utils::GetProjectPath().c_str(), tr("Files (*.%1)").arg(AZ::RPI::ShaderVariantListSourceData::Extension)).toUtf8().constData(); + this, tr("Open Document"), AZ::Utils::GetProjectPath().c_str(), + tr("Shader Files (*.%1);;Shader Variant List Files (*.%2)") + .arg(AZ::RPI::ShaderSourceData::Extension) + .arg(AZ::RPI::ShaderVariantListSourceData::Extension)) + .toUtf8() + .constData(); return !openPath.empty(); } @@ -83,9 +90,7 @@ namespace ShaderManagementConsole AZ::RPI::ShaderOptionDescriptor shaderOptionDesc; ShaderManagementConsoleDocumentRequestBus::EventResult( shaderOptionDesc, documentId, &ShaderManagementConsoleDocumentRequestBus::Events::GetShaderOptionDescriptor, optionIndex); - - const char* optionName = shaderOptionDesc.GetName().GetCStr(); - optionNames.insert(optionName); + optionNames.insert(shaderOptionDesc.GetName().GetCStr()); } size_t shaderVariantCount = 0; diff --git a/Gems/Atom/Tools/ShaderManagementConsole/Code/shadermanagementconsole_files.cmake b/Gems/Atom/Tools/ShaderManagementConsole/Code/shadermanagementconsole_files.cmake index 332cd73b40..b7da8d449a 100644 --- a/Gems/Atom/Tools/ShaderManagementConsole/Code/shadermanagementconsole_files.cmake +++ b/Gems/Atom/Tools/ShaderManagementConsole/Code/shadermanagementconsole_files.cmake @@ -18,6 +18,5 @@ set(FILES Source/main.cpp Source/ShaderManagementConsoleApplication.cpp Source/ShaderManagementConsoleApplication.h - Source/ShaderManagementConsoleRequestBus.h ../Scripts/GenerateShaderVariantListForMaterials.py ) diff --git a/Gems/Atom/Tools/ShaderManagementConsole/Scripts/GenerateShaderVariantListForMaterials.py b/Gems/Atom/Tools/ShaderManagementConsole/Scripts/GenerateShaderVariantListForMaterials.py index c31047d347..79a0391bf7 100755 --- a/Gems/Atom/Tools/ShaderManagementConsole/Scripts/GenerateShaderVariantListForMaterials.py +++ b/Gems/Atom/Tools/ShaderManagementConsole/Scripts/GenerateShaderVariantListForMaterials.py @@ -38,28 +38,16 @@ def main(): if extension != "shader": print("The input argument for the script is not a valid .shader file") return - - # Get info such as relative path of the file and asset id - shaderAssetInfo = azlmbr.shadermanagementconsole.ShaderManagementConsoleRequestBus( - azlmbr.bus.Broadcast, - 'GetSourceAssetInfo', - filename - ) - - # retrieves a list of all material source files that use the shader. Note that materials inherit from materialtype files, which are actual files that refer to shader files. - materialAssetIds = azlmbr.shadermanagementconsole.ShaderManagementConsoleRequestBus( - azlmbr.bus.Broadcast, - 'FindMaterialAssetsUsingShader', - shaderAssetInfo.relativePath - ) - + + # prompt the user to save the file in the project folder or same folder as the shader msgBox = QtWidgets.QMessageBox( QtWidgets.QMessageBox.Question, "Choose Save Location for .shadervariantlist File", "Save .shadervariantlist file in Project folder or in the same folder as shader file?" ) + projectButton = msgBox.addButton("Project Folder", QtWidgets.QMessageBox.AcceptRole) - msgBox.addButton("Same Folder as Shader", QtWidgets.QMessageBox.AcceptRole) + shaderButton = msgBox.addButton("Same Folder as Shader", QtWidgets.QMessageBox.AcceptRole) cancelButton = msgBox.addButton("Cancel", QtWidgets.QMessageBox.RejectRole) msgBox.exec() @@ -68,98 +56,54 @@ def main(): is_save_in_project_folder = True elif msgBox.clickedButton() == cancelButton: return - - # This loop collects all uniquely-identified shader items used by the materials based on its shader variant id. - shader_file = os.path.basename(filename) - shaderVariantIds = [] - shaderVariantListShaderOptionGroups = [] - progressDialog = QtWidgets.QProgressDialog(f"Generating .shadervariantlist file for:\n{shader_file}", "Cancel", 0, len(materialAssetIds)) - progressDialog.setMaximumWidth(400) - progressDialog.setMaximumHeight(100) - progressDialog.setModal(True) - progressDialog.setWindowTitle("Generating Shader Variant List") - for i, materialAssetId in enumerate(materialAssetIds): - materialInstanceShaderItems = azlmbr.shadermanagementconsole.ShaderManagementConsoleRequestBus(azlmbr.bus.Broadcast, 'GetMaterialInstanceShaderItems', materialAssetId) - - for shaderItem in materialInstanceShaderItems: - shaderAssetId = shaderItem.GetShaderAsset().get_id() - if shaderAssetInfo.assetId == shaderAssetId: - shaderVariantId = shaderItem.GetShaderVariantId() - if not shaderVariantId.IsEmpty(): - # Check for repeat shader variant ids. We are using a list here - # instead of a set to check for duplicates on shaderVariantIds because - # shaderVariantId is not hashed by the ID like it is in the C++ side. - has_repeat = False - for variantId in shaderVariantIds: - if shaderVariantId == variantId: - has_repeat = True - break - if has_repeat: - continue - - shaderVariantIds.append(shaderVariantId) - shaderVariantListShaderOptionGroups.append(shaderItem.GetShaderOptionGroup()) - - progressDialog.setValue(i) - if progressDialog.wasCanceled(): - return - - progressDialog.close() - - # Generate the shader variant list data by collecting shader option name-value pairs.s - shaderVariantList = azlmbr.shader.ShaderVariantListSourceData() - shaderVariantList.shaderFilePath = shaderAssetInfo.relativePath - shaderVariants = [] - stableId = 1 - for shaderOptionGroup in shaderVariantListShaderOptionGroups: - variantInfo = azlmbr.shader.ShaderVariantInfo() - variantInfo.stableId = stableId - options = {} - - shaderOptionDescriptors = shaderOptionGroup.GetShaderOptionDescriptors() - for shaderOptionDescriptor in shaderOptionDescriptors: - optionName = shaderOptionDescriptor.GetName() - optionValue = shaderOptionGroup.GetValueByOptionName(optionName) - if not optionValue.IsValid(): - continue - - valueName = shaderOptionDescriptor.GetValueName(optionValue) - options[optionName.ToString()] = valueName.ToString() - - if len(options) != 0: - variantInfo.options = options - shaderVariants.append(variantInfo) - stableId += 1 - - shaderVariantList.shaderVariants = shaderVariants + + # open the shader file as a document which will generate all of the shader variant list data + documentId = azlmbr.atomtools.AtomToolsDocumentSystemRequestBus( + azlmbr.bus.Broadcast, + 'OpenDocument', + filename + ) + + if documentId.IsNull(): + print("The shader source data file could not be opened") + return + + # get the shader variant list data object which is only needed for the shader file path + shaderVariantList = azlmbr.shadermanagementconsole.ShaderManagementConsoleDocumentRequestBus( + azlmbr.bus.Event, + 'GetShaderVariantListSourceData', + documentId + ) + + # generate the default save file path by replacing the extension of the open shader file + pre, ext = os.path.splitext(filename) + defaultShaderVariantListFilePath = f'{pre}.shadervariantlist' # clean previously generated shader variant list file so they don't clash. - pre, ext = os.path.splitext(shaderAssetInfo.relativePath) + pre, ext = os.path.splitext(shaderVariantList.shaderFilePath) projectShaderVariantListFilePath = os.path.join(azlmbr.paths.projectroot, PROJECT_SHADER_VARIANTS_FOLDER, f'{pre}.shadervariantlist') - pre, ext = os.path.splitext(filename) - defaultShaderVariantListFilePath = f'{pre}.shadervariantlist' - clean_existing_shadervariantlist_files([ projectShaderVariantListFilePath ]) + # Save the shader variant list file if is_save_in_project_folder: shaderVariantListFilePath = projectShaderVariantListFilePath else: shaderVariantListFilePath = defaultShaderVariantListFilePath - + shaderVariantListFilePath = shaderVariantListFilePath.replace("\\", "/") - azlmbr.shader.SaveShaderVariantListSourceData(shaderVariantListFilePath, shaderVariantList) - - # Open the document in shader management console - result = azlmbr.atomtools.AtomToolsDocumentSystemRequestBus( + + # Save the document in shader management console + saveResult = azlmbr.atomtools.AtomToolsDocumentSystemRequestBus( azlmbr.bus.Broadcast, - 'OpenDocument', + 'SaveDocumentAsChild', + documentId, shaderVariantListFilePath ) - - if not result.IsNull(): + + if saveResult: msgBox = QtWidgets.QMessageBox( QtWidgets.QMessageBox.Information, "Shader Variant List File Successfully Generated", @@ -167,7 +111,7 @@ def main(): QtWidgets.QMessageBox.Ok ) msgBox.exec() - + print("==== End shader variant script ============================================================") if __name__ == "__main__": From 2b49b5eefef8409239e30edda3cccbddfbdd0a97 Mon Sep 17 00:00:00 2001 From: Guthrie Adams Date: Sun, 13 Feb 2022 17:01:31 -0600 Subject: [PATCH 2/3] Moved loading code into separate functions based on source file type Moved table view code into its own class that will handle modifications to the document Signed-off-by: Guthrie Adams --- .../ShaderManagementConsoleDocument.cpp | 215 +++++++++--------- .../ShaderManagementConsoleDocument.h | 16 +- ...haderManagementConsoleDocumentRequestBus.h | 7 +- .../ShaderManagementConsoleTableView.cpp | 104 +++++++++ .../Window/ShaderManagementConsoleTableView.h | 40 ++++ .../Window/ShaderManagementConsoleWindow.cpp | 67 +----- .../Window/ShaderManagementConsoleWindow.h | 8 - .../Code/shadermanagementconsole_files.cmake | 2 + 8 files changed, 279 insertions(+), 180 deletions(-) create mode 100644 Gems/Atom/Tools/ShaderManagementConsole/Code/Source/Window/ShaderManagementConsoleTableView.cpp create mode 100644 Gems/Atom/Tools/ShaderManagementConsole/Code/Source/Window/ShaderManagementConsoleTableView.h diff --git a/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/Document/ShaderManagementConsoleDocument.cpp b/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/Document/ShaderManagementConsoleDocument.cpp index 78a6f78d49..241ebb2433 100644 --- a/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/Document/ShaderManagementConsoleDocument.cpp +++ b/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/Document/ShaderManagementConsoleDocument.cpp @@ -9,8 +9,10 @@ #include #include #include +#include #include #include +#include #include #include #include @@ -31,9 +33,10 @@ namespace ShaderManagementConsole ShaderManagementConsoleDocumentRequestBus::Handler::BusDisconnect(); } - void ShaderManagementConsoleDocument::SetShaderVariantListSourceData(const AZ::RPI::ShaderVariantListSourceData& sourceData) + void ShaderManagementConsoleDocument::SetShaderVariantListSourceData( + const AZ::RPI::ShaderVariantListSourceData& shaderVariantListSourceData) { - m_shaderVariantListSourceData = sourceData; + m_shaderVariantListSourceData = shaderVariantListSourceData; AZStd::string shaderPath = m_shaderVariantListSourceData.m_shaderFilePath; AzFramework::StringFunc::Path::ReplaceExtension(shaderPath, AZ::RPI::ShaderAsset::Extension); @@ -110,94 +113,14 @@ namespace ShaderManagementConsole return false; } - if (AzFramework::StringFunc::Path::IsExtension(m_absolutePath.c_str(), AZ::RPI::ShaderVariantListSourceData::Extension)) + if (AzFramework::StringFunc::Path::IsExtension(m_absolutePath.c_str(), AZ::RPI::ShaderSourceData::Extension)) { - // Load the shader config data and create a shader config asset from it - AZ::RPI::ShaderVariantListSourceData sourceData; - if (!AZ::RPI::JsonUtils::LoadObjectFromFile(m_absolutePath, sourceData)) - { - AZ_Error( - "ShaderManagementConsoleDocument", false, "Failed loading shader variant list data: '%s.'", m_absolutePath.c_str()); - return OpenFailed(); - } - - SetShaderVariantListSourceData(sourceData); - return IsOpen() ? OpenSucceeded() : OpenFailed(); + return LoadShaderSourceData(); } - if (AzFramework::StringFunc::Path::IsExtension(m_absolutePath.c_str(), AZ::RPI::ShaderSourceData::Extension)) + if (AzFramework::StringFunc::Path::IsExtension(m_absolutePath.c_str(), AZ::RPI::ShaderVariantListSourceData::Extension)) { - // Get info such as relative path of the file and asset id - bool result = false; - AZ::Data::AssetInfo shaderAssetInfo; - AZStd::string watchFolder; - AzToolsFramework::AssetSystemRequestBus::BroadcastResult( - result, &AzToolsFramework::AssetSystem::AssetSystemRequest::GetSourceInfoBySourcePath, m_absolutePath.c_str(), - shaderAssetInfo, watchFolder); - - if (!result) - { - AZ_Error( - "ShaderManagementConsoleDocument", false, "Failed to get the asset info for the file: %s.", m_absolutePath.c_str()); - return OpenFailed(); - } - - // retrieves a list of all material source files that use the shader. Note that materials inherit from materialtype files, which - // are actual files that refer to shader files. - const auto& materialAssetIds = FindMaterialAssetsUsingShader(shaderAssetInfo.m_relativePath); - - // This loop collects all uniquely-identified shader items used by the materials based on its shader variant id. - AZStd::set shaderVariantIds; - AZStd::vector shaderVariantListShaderOptionGroups; - for (const auto& materialAssetId : materialAssetIds) - { - const auto& materialInstanceShaderItems = GetMaterialInstanceShaderItems(materialAssetId); - for (const auto& shaderItem : materialInstanceShaderItems) - { - const auto& shaderAssetId = shaderItem.GetShaderAsset().GetId(); - if (shaderAssetInfo.m_assetId == shaderAssetId) - { - const auto& shaderVariantId = shaderItem.GetShaderVariantId(); - if (!shaderVariantId.IsEmpty() && shaderVariantIds.insert(shaderVariantId).second) - { - shaderVariantListShaderOptionGroups.push_back(shaderItem.GetShaderOptionGroup()); - } - } - } - } - - // Generate the shader variant list data by collecting shader option name-value pairs.s - AZ::RPI::ShaderVariantListSourceData shaderVariantList; - shaderVariantList.m_shaderFilePath = shaderAssetInfo.m_relativePath; - int stableId = 1; - for (const auto& shaderOptionGroup : shaderVariantListShaderOptionGroups) - { - AZ::RPI::ShaderVariantListSourceData::VariantInfo variantInfo; - variantInfo.m_stableId = stableId; - - const auto& shaderOptionDescriptors = shaderOptionGroup.GetShaderOptionDescriptors(); - for (const auto& shaderOptionDescriptor : shaderOptionDescriptors) - { - const auto& optionName = shaderOptionDescriptor.GetName(); - const auto& optionValue = shaderOptionGroup.GetValue(optionName); - if (!optionValue.IsValid()) - { - continue; - } - - const auto& valueName = shaderOptionDescriptor.GetValueName(optionValue); - variantInfo.m_options[optionName.GetStringView()] = valueName.GetStringView(); - } - - if (!variantInfo.m_options.empty()) - { - shaderVariantList.m_shaderVariants.push_back(variantInfo); - stableId++; - } - } - - SetShaderVariantListSourceData(shaderVariantList); - return IsOpen() ? OpenSucceeded() : OpenFailed(); + return LoadShaderVariantListSourceData(); } AZ_Error("ShaderManagementConsoleDocument", false, "Document extension is not supported: '%s.'", m_absolutePath.c_str()); @@ -276,29 +199,115 @@ namespace ShaderManagementConsole return SaveSucceeded(); } - AZStd::vector ShaderManagementConsoleDocument::FindMaterialAssetsUsingShader(const AZStd::string& shaderFilePath) + bool ShaderManagementConsoleDocument::LoadShaderSourceData() { - // Collect the material types referencing the shader - AZStd::vector materialTypeSources; + // Get info such as relative path of the file and asset id + bool result = false; + AZ::Data::AssetInfo shaderAssetInfo; + AZStd::string watchFolder; + AzToolsFramework::AssetSystemRequestBus::BroadcastResult( + result, &AzToolsFramework::AssetSystem::AssetSystemRequest::GetSourceInfoBySourcePath, m_absolutePath.c_str(), shaderAssetInfo, + watchFolder); + + if (!result) + { + AZ_Error("ShaderManagementConsoleDocument", false, "Failed to get the asset info for the file: %s.", m_absolutePath.c_str()); + return OpenFailed(); + } + // retrieves a list of all material source files that use the shader. Note that materials inherit from materialtype files, which + // are actual files that refer to shader files. + const auto& materialAssetIds = FindMaterialAssetsUsingShader(shaderAssetInfo.m_relativePath); + + // This loop collects all uniquely-identified shader items used by the materials based on its shader variant id. + AZStd::set shaderVariantIds; + AZStd::vector shaderVariantListShaderOptionGroups; + for (const auto& materialAssetId : materialAssetIds) + { + const auto& materialInstanceShaderItems = GetMaterialInstanceShaderItems(materialAssetId); + for (const auto& shaderItem : materialInstanceShaderItems) + { + const auto& shaderAssetId = shaderItem.GetShaderAsset().GetId(); + if (shaderAssetInfo.m_assetId == shaderAssetId) + { + const auto& shaderVariantId = shaderItem.GetShaderVariantId(); + if (!shaderVariantId.IsEmpty() && shaderVariantIds.insert(shaderVariantId).second) + { + shaderVariantListShaderOptionGroups.push_back(shaderItem.GetShaderOptionGroup()); + } + } + } + } + + // Generate the shader variant list data by collecting shader option name-value pairs.s + AZ::RPI::ShaderVariantListSourceData shaderVariantListSourceData; + shaderVariantListSourceData.m_shaderFilePath = shaderAssetInfo.m_relativePath; + int stableId = 1; + for (const auto& shaderOptionGroup : shaderVariantListShaderOptionGroups) + { + AZ::RPI::ShaderVariantListSourceData::VariantInfo variantInfo; + variantInfo.m_stableId = stableId; + + const auto& shaderOptionDescriptors = shaderOptionGroup.GetShaderOptionDescriptors(); + for (const auto& shaderOptionDescriptor : shaderOptionDescriptors) + { + const auto& optionName = shaderOptionDescriptor.GetName(); + const auto& optionValue = shaderOptionGroup.GetValue(optionName); + if (!optionValue.IsValid()) + { + continue; + } + + const auto& valueName = shaderOptionDescriptor.GetValueName(optionValue); + variantInfo.m_options[optionName.GetStringView()] = valueName.GetStringView(); + } + + if (!variantInfo.m_options.empty()) + { + shaderVariantListSourceData.m_shaderVariants.push_back(variantInfo); + stableId++; + } + } + + SetShaderVariantListSourceData(shaderVariantListSourceData); + return IsOpen() ? OpenSucceeded() : OpenFailed(); + } + + bool ShaderManagementConsoleDocument::LoadShaderVariantListSourceData() + { + // Load previously generated shader variant list source data + AZ::RPI::ShaderVariantListSourceData shaderVariantListSourceData; + if (!AZ::RPI::JsonUtils::LoadObjectFromFile(m_absolutePath, shaderVariantListSourceData)) + { + AZ_Error("ShaderManagementConsoleDocument", false, "Failed loading shader variant list data: '%s.'", m_absolutePath.c_str()); + return OpenFailed(); + } + + SetShaderVariantListSourceData(shaderVariantListSourceData); + return IsOpen() ? OpenSucceeded() : OpenFailed(); + } + + AZStd::vector ShaderManagementConsoleDocument::FindMaterialAssetsUsingShader(const AZStd::string& shaderFilePath) + { AzToolsFramework::AssetDatabase::AssetDatabaseConnection assetDatabaseConnection; assetDatabaseConnection.OpenDatabase(); + // Find all material types that reference shaderFilePath + AZStd::vector materialTypeSources; + 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 (AzFramework::StringFunc::Path::IsExtension( + sourceFileDependencyEntry.m_source.c_str(), AZ::RPI::MaterialTypeSourceData::Extension)) { - if (assetExtension == "materialtype") - { - materialTypeSources.push_back(sourceFileDependencyEntry.m_source); - } + materialTypeSources.push_back(sourceFileDependencyEntry.m_source); } return true; }); + // Find all materials that reference any of the material types using this shader AzToolsFramework::AssetDatabase::ProductDatabaseEntryContainer productDependencies; for (const auto& materialTypeSource : materialTypeSources) { @@ -313,13 +322,9 @@ namespace ShaderManagementConsole 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 (AzFramework::StringFunc::Path::IsExtension(entry.m_productName.c_str(), AZ::RPI::MaterialAsset::Extension)) { - if (assetExtension == "azmaterial") - { - productDependencies.push_back(entry); - } + productDependencies.push_back(entry); } return true; }); @@ -338,18 +343,20 @@ namespace ShaderManagementConsole }, nullptr); } + return results; } AZStd::vector ShaderManagementConsoleDocument::GetMaterialInstanceShaderItems( - const AZ::Data::AssetId& assetId) + const AZ::Data::AssetId& materialAssetId) { - auto materialAsset = AZ::RPI::AssetUtils::LoadAssetById(assetId, AZ::RPI::AssetUtils::TraceLevel::Error); + auto materialAsset = + AZ::RPI::AssetUtils::LoadAssetById(materialAssetId, AZ::RPI::AssetUtils::TraceLevel::Error); if (!materialAsset.IsReady()) { AZ_Error( "ShaderManagementConsoleDocument", false, "Failed to load material asset from asset id: %s", - assetId.ToString().c_str()); + materialAssetId.ToString().c_str()); return AZStd::vector(); } diff --git a/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/Document/ShaderManagementConsoleDocument.h b/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/Document/ShaderManagementConsoleDocument.h index c470f5826a..232910d9d1 100644 --- a/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/Document/ShaderManagementConsoleDocument.h +++ b/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/Document/ShaderManagementConsoleDocument.h @@ -5,6 +5,7 @@ * SPDX-License-Identifier: Apache-2.0 OR MIT * */ + #pragma once #include @@ -42,7 +43,7 @@ namespace ShaderManagementConsole bool IsSavable() const override; // ShaderManagementConsoleDocumentRequestBus::Handler overridfes... - void SetShaderVariantListSourceData(const AZ::RPI::ShaderVariantListSourceData& sourceData) override; + void SetShaderVariantListSourceData(const AZ::RPI::ShaderVariantListSourceData& shaderVariantListSourceData) override; const AZ::RPI::ShaderVariantListSourceData& GetShaderVariantListSourceData() const override; size_t GetShaderVariantCount() const override; const AZ::RPI::ShaderVariantListSourceData::VariantInfo& GetShaderVariantInfo(size_t index) const override; @@ -53,9 +54,20 @@ namespace ShaderManagementConsole // AtomToolsFramework::AtomToolsDocument overrides... void Clear() override; + // Write shader variant list source data to JSON bool SaveSourceData(); + + // Read shader variant list source data from JSON and initialize the document + bool LoadShaderSourceData(); + + // Read shader source data from JSON then find all references to to populate the shader variant list and initialize the document + bool LoadShaderVariantListSourceData(); + + // Find all material assets that reference material types using shaderFilePath AZStd::vector FindMaterialAssetsUsingShader(const AZStd::string& shaderFilePath); - AZStd::vector GetMaterialInstanceShaderItems(const AZ::Data::AssetId& assetId); + + // Retrieve all of the shader collection items from a material instance created from materialAssetId + AZStd::vector GetMaterialInstanceShaderItems(const AZ::Data::AssetId& materialAssetId); // Source data for shader variant list AZ::RPI::ShaderVariantListSourceData m_shaderVariantListSourceData; diff --git a/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/Document/ShaderManagementConsoleDocumentRequestBus.h b/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/Document/ShaderManagementConsoleDocumentRequestBus.h index e58ee34ed1..e249146af6 100644 --- a/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/Document/ShaderManagementConsoleDocumentRequestBus.h +++ b/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/Document/ShaderManagementConsoleDocumentRequestBus.h @@ -5,6 +5,7 @@ * SPDX-License-Identifier: Apache-2.0 OR MIT * */ + #pragma once #include @@ -14,9 +15,7 @@ namespace ShaderManagementConsole { - - class ShaderManagementConsoleDocumentRequests - : public AZ::EBusTraits + class ShaderManagementConsoleDocumentRequests : public AZ::EBusTraits { public: static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Multiple; @@ -24,7 +23,7 @@ namespace ShaderManagementConsole typedef AZ::Uuid BusIdType; //! Set the shader variant list - virtual void SetShaderVariantListSourceData(const AZ::RPI::ShaderVariantListSourceData& sourceData) = 0; + virtual void SetShaderVariantListSourceData(const AZ::RPI::ShaderVariantListSourceData& shaderVariantListSourceData) = 0; //! Get the shader variant list virtual const AZ::RPI::ShaderVariantListSourceData& GetShaderVariantListSourceData() const = 0; diff --git a/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/Window/ShaderManagementConsoleTableView.cpp b/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/Window/ShaderManagementConsoleTableView.cpp new file mode 100644 index 0000000000..5cde09fe68 --- /dev/null +++ b/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/Window/ShaderManagementConsoleTableView.cpp @@ -0,0 +1,104 @@ +/* + * 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 + +namespace ShaderManagementConsole +{ + ShaderManagementConsoleTableView::ShaderManagementConsoleTableView(const AZ::Uuid& documentId, QWidget* parent) + : QTableView(parent) + , m_documentId(documentId) + , m_model(new QStandardItemModel(this)) + { + setSelectionBehavior(QAbstractItemView::SelectRows); + setModel(m_model); + + RebuildTable(); + AtomToolsFramework::AtomToolsDocumentNotificationBus::Handler::BusConnect(); + } + + ShaderManagementConsoleTableView::~ShaderManagementConsoleTableView() + { + AtomToolsFramework::AtomToolsDocumentNotificationBus::Handler::BusDisconnect(); + } + + void ShaderManagementConsoleTableView::OnDocumentOpened(const AZ::Uuid& documentId) + { + if (m_documentId == documentId) + { + RebuildTable(); + } + } + + void ShaderManagementConsoleTableView::OnDocumentModified(const AZ::Uuid& documentId) + { + if (m_documentId == documentId) + { + RebuildTable(); + } + } + + void ShaderManagementConsole::ShaderManagementConsoleTableView::RebuildTable() + { + AZStd::unordered_set optionNames; + + size_t shaderOptionCount = 0; + ShaderManagementConsoleDocumentRequestBus::EventResult( + shaderOptionCount, m_documentId, &ShaderManagementConsoleDocumentRequestBus::Events::GetShaderOptionCount); + + for (size_t optionIndex = 0; optionIndex < shaderOptionCount; ++optionIndex) + { + AZ::RPI::ShaderOptionDescriptor shaderOptionDesc; + ShaderManagementConsoleDocumentRequestBus::EventResult( + shaderOptionDesc, m_documentId, &ShaderManagementConsoleDocumentRequestBus::Events::GetShaderOptionDescriptor, optionIndex); + optionNames.insert(shaderOptionDesc.GetName().GetCStr()); + } + + size_t shaderVariantCount = 0; + ShaderManagementConsoleDocumentRequestBus::EventResult( + shaderVariantCount, m_documentId, &ShaderManagementConsoleDocumentRequestBus::Events::GetShaderVariantCount); + + m_model->clear(); + m_model->setRowCount(static_cast(shaderVariantCount)); + m_model->setColumnCount(static_cast(optionNames.size())); + + int nameIndex = 0; + for (const auto& optionName : optionNames) + { + m_model->setHeaderData(nameIndex++, Qt::Horizontal, optionName.c_str()); + } + + for (int variantIndex = 0; variantIndex < shaderVariantCount; ++variantIndex) + { + AZ::RPI::ShaderVariantListSourceData::VariantInfo shaderVariantInfo; + ShaderManagementConsoleDocumentRequestBus::EventResult( + shaderVariantInfo, m_documentId, &ShaderManagementConsoleDocumentRequestBus::Events::GetShaderVariantInfo, variantIndex); + + m_model->setHeaderData(variantIndex, Qt::Vertical, QString::number(variantIndex)); + + for (const auto& shaderOption : shaderVariantInfo.m_options) + { + AZ::Name optionName{ shaderOption.first }; + AZ::Name optionValue{ shaderOption.second }; + + auto optionIt = optionNames.find(optionName.GetCStr()); + int optionIndex = static_cast(AZStd::distance(optionNames.begin(), optionIt)); + + QStandardItem* item = new QStandardItem(optionValue.GetCStr()); + m_model->setItem(variantIndex, optionIndex, item); + } + } + } +} // namespace ShaderManagementConsole + +#include +#include "ShaderManagementConsoleTableView.h" diff --git a/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/Window/ShaderManagementConsoleTableView.h b/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/Window/ShaderManagementConsoleTableView.h new file mode 100644 index 0000000000..32148c92f6 --- /dev/null +++ b/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/Window/ShaderManagementConsoleTableView.h @@ -0,0 +1,40 @@ +/* + * 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 + * + */ + +#pragma once + +#if !defined(Q_MOC_RUN) +#include + +#include +#include +#endif + +namespace ShaderManagementConsole +{ + class ShaderManagementConsoleTableView + : public QTableView + , public AtomToolsFramework::AtomToolsDocumentNotificationBus::Handler + { + public: + AZ_CLASS_ALLOCATOR(ShaderManagementConsoleTableView, AZ::SystemAllocator, 0); + ShaderManagementConsoleTableView(const AZ::Uuid& documentId, QWidget* parent = 0); + ~ShaderManagementConsoleTableView(); + + protected: + // AtomToolsFramework::AtomToolsDocumentNotificationBus::Handler overrides... + void OnDocumentOpened(const AZ::Uuid& documentId) override; + void OnDocumentModified(const AZ::Uuid& documentId) override; + + void RebuildTable(); + + AZ::Uuid m_documentId = AZ::Uuid::CreateNull(); + QStandardItemModel* m_model = {}; + + }; +} // namespace ShaderManagementConsole diff --git a/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/Window/ShaderManagementConsoleWindow.cpp b/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/Window/ShaderManagementConsoleWindow.cpp index 7c1ee29cb2..d686207ed2 100644 --- a/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/Window/ShaderManagementConsoleWindow.cpp +++ b/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/Window/ShaderManagementConsoleWindow.cpp @@ -6,23 +6,19 @@ * */ +#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 -#include -#include #include #include -AZ_POP_DISABLE_WARNING namespace ShaderManagementConsole { @@ -79,60 +75,7 @@ namespace ShaderManagementConsole QWidget* ShaderManagementConsoleWindow::CreateDocumentTabView(const AZ::Uuid& documentId) { - AZStd::unordered_set optionNames; - - size_t shaderOptionCount = 0; - ShaderManagementConsoleDocumentRequestBus::EventResult( - shaderOptionCount, documentId, &ShaderManagementConsoleDocumentRequestBus::Events::GetShaderOptionCount); - - for (size_t optionIndex = 0; optionIndex < shaderOptionCount; ++optionIndex) - { - AZ::RPI::ShaderOptionDescriptor shaderOptionDesc; - ShaderManagementConsoleDocumentRequestBus::EventResult( - shaderOptionDesc, documentId, &ShaderManagementConsoleDocumentRequestBus::Events::GetShaderOptionDescriptor, optionIndex); - optionNames.insert(shaderOptionDesc.GetName().GetCStr()); - } - - size_t shaderVariantCount = 0; - ShaderManagementConsoleDocumentRequestBus::EventResult( - shaderVariantCount, documentId, &ShaderManagementConsoleDocumentRequestBus::Events::GetShaderVariantCount); - - auto model = new QStandardItemModel(); - model->setRowCount(static_cast(shaderVariantCount)); - model->setColumnCount(static_cast(optionNames.size())); - - int nameIndex = 0; - for (const auto& optionName : optionNames) - { - model->setHeaderData(nameIndex++, Qt::Horizontal, optionName.c_str()); - } - - for (int variantIndex = 0; variantIndex < shaderVariantCount; ++variantIndex) - { - AZ::RPI::ShaderVariantListSourceData::VariantInfo shaderVariantInfo; - ShaderManagementConsoleDocumentRequestBus::EventResult( - shaderVariantInfo, documentId, &ShaderManagementConsoleDocumentRequestBus::Events::GetShaderVariantInfo, variantIndex); - - model->setHeaderData(variantIndex, Qt::Vertical, QString::number(variantIndex)); - - for (const auto& shaderOption : shaderVariantInfo.m_options) - { - AZ::Name optionName{ shaderOption.first }; - AZ::Name optionValue{ shaderOption.second }; - - auto optionIt = optionNames.find(optionName.GetCStr()); - int optionIndex = static_cast(AZStd::distance(optionNames.begin(), optionIt)); - - QStandardItem* item = new QStandardItem(optionValue.GetCStr()); - model->setItem(variantIndex, optionIndex, item); - } - } - - // The document tab contains a table view. - auto contentWidget = new QTableView(centralWidget()); - contentWidget->setSelectionBehavior(QAbstractItemView::SelectRows); - contentWidget->setModel(model); - return contentWidget; + return new ShaderManagementConsoleTableView(documentId, centralWidget()); } } // namespace ShaderManagementConsole diff --git a/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/Window/ShaderManagementConsoleWindow.h b/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/Window/ShaderManagementConsoleWindow.h index 1a8ac53992..5ebb2005b9 100644 --- a/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/Window/ShaderManagementConsoleWindow.h +++ b/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/Window/ShaderManagementConsoleWindow.h @@ -8,16 +8,8 @@ #pragma once -#if !defined(Q_MOC_RUN) -#include -#include #include -AZ_PUSH_DISABLE_WARNING(4251 4800, "-Wunknown-warning-option") // disable warnings spawned by QT -#include -AZ_POP_DISABLE_WARNING -#endif - namespace ShaderManagementConsole { //! ShaderManagementConsoleWindow is the main class. Its responsibility is limited to initializing and connecting diff --git a/Gems/Atom/Tools/ShaderManagementConsole/Code/shadermanagementconsole_files.cmake b/Gems/Atom/Tools/ShaderManagementConsole/Code/shadermanagementconsole_files.cmake index b7da8d449a..c66405ac15 100644 --- a/Gems/Atom/Tools/ShaderManagementConsole/Code/shadermanagementconsole_files.cmake +++ b/Gems/Atom/Tools/ShaderManagementConsole/Code/shadermanagementconsole_files.cmake @@ -11,6 +11,8 @@ set(FILES Source/Document/ShaderManagementConsoleDocument.cpp Source/Document/ShaderManagementConsoleDocument.h + Source/Window/ShaderManagementConsoleTableView.h + Source/Window/ShaderManagementConsoleTableView.cpp Source/Window/ShaderManagementConsoleWindow.h Source/Window/ShaderManagementConsoleWindow.cpp Source/Window/ShaderManagementConsole.qrc From b0fd3d22f102fb10ec259c48a779cc3a05584d26 Mon Sep 17 00:00:00 2001 From: Guthrie Adams Date: Mon, 14 Feb 2022 06:19:19 -0600 Subject: [PATCH 3/3] resolving merge issues fixing crash on startup because allocator was not available when string was allocated Signed-off-by: Guthrie Adams --- .../AtomToolsFramework/Application/AtomToolsApplication.h | 2 +- .../Document/AtomToolsDocumentApplication.h | 2 +- .../Code/Source/Application/AtomToolsApplication.cpp | 2 +- .../Code/Source/Document/AtomToolsDocumentApplication.cpp | 2 +- .../Code/Source/Window/ShaderManagementConsoleTableView.cpp | 6 ++++-- .../Code/Source/Window/ShaderManagementConsoleTableView.h | 6 +++--- .../Code/Source/Window/ShaderManagementConsoleWindow.cpp | 4 ++-- 7 files changed, 13 insertions(+), 11 deletions(-) diff --git a/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Application/AtomToolsApplication.h b/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Application/AtomToolsApplication.h index 1c2a2edc53..5d2c1ce4e0 100644 --- a/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Application/AtomToolsApplication.h +++ b/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Application/AtomToolsApplication.h @@ -43,7 +43,7 @@ namespace AtomToolsFramework using Base = AzFramework::Application; - AtomToolsApplication(const AZStd::string& targetName, int* argc, char*** argv); + AtomToolsApplication(const char* targetName, int* argc, char*** argv); ~AtomToolsApplication(); virtual bool LaunchLocalServer(); diff --git a/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Document/AtomToolsDocumentApplication.h b/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Document/AtomToolsDocumentApplication.h index c94cf97508..095b62dfc9 100644 --- a/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Document/AtomToolsDocumentApplication.h +++ b/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Document/AtomToolsDocumentApplication.h @@ -22,7 +22,7 @@ namespace AtomToolsFramework using Base = AtomToolsApplication; - AtomToolsDocumentApplication(const AZStd::string& targetName, int* argc, char*** argv); + AtomToolsDocumentApplication(const char* targetName, int* argc, char*** argv); protected: // AtomToolsApplication overrides... diff --git a/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Application/AtomToolsApplication.cpp b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Application/AtomToolsApplication.cpp index bac26451fd..e35e120fbe 100644 --- a/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Application/AtomToolsApplication.cpp +++ b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Application/AtomToolsApplication.cpp @@ -45,7 +45,7 @@ AZ_POP_DISABLE_WARNING namespace AtomToolsFramework { - AtomToolsApplication::AtomToolsApplication(const AZStd::string& targetName, int* argc, char*** argv) + AtomToolsApplication::AtomToolsApplication(const char* targetName, int* argc, char*** argv) : Application(argc, argv) , AzQtApplication(*argc, *argv) , m_targetName(targetName) diff --git a/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Document/AtomToolsDocumentApplication.cpp b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Document/AtomToolsDocumentApplication.cpp index c4eb89e7d1..f0dea20402 100644 --- a/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Document/AtomToolsDocumentApplication.cpp +++ b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Document/AtomToolsDocumentApplication.cpp @@ -11,7 +11,7 @@ namespace AtomToolsFramework { - AtomToolsDocumentApplication::AtomToolsDocumentApplication(const AZStd::string& targetName, int* argc, char*** argv) + AtomToolsDocumentApplication::AtomToolsDocumentApplication(const char* targetName, int* argc, char*** argv) : Base(targetName, argc, argv) { } diff --git a/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/Window/ShaderManagementConsoleTableView.cpp b/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/Window/ShaderManagementConsoleTableView.cpp index 5cde09fe68..12445f7fa3 100644 --- a/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/Window/ShaderManagementConsoleTableView.cpp +++ b/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/Window/ShaderManagementConsoleTableView.cpp @@ -14,8 +14,10 @@ namespace ShaderManagementConsole { - ShaderManagementConsoleTableView::ShaderManagementConsoleTableView(const AZ::Uuid& documentId, QWidget* parent) + ShaderManagementConsoleTableView::ShaderManagementConsoleTableView( + const AZ::Crc32& toolId, const AZ::Uuid& documentId, QWidget* parent) : QTableView(parent) + , m_toolId(toolId) , m_documentId(documentId) , m_model(new QStandardItemModel(this)) { @@ -23,7 +25,7 @@ namespace ShaderManagementConsole setModel(m_model); RebuildTable(); - AtomToolsFramework::AtomToolsDocumentNotificationBus::Handler::BusConnect(); + AtomToolsFramework::AtomToolsDocumentNotificationBus::Handler::BusConnect(m_toolId); } ShaderManagementConsoleTableView::~ShaderManagementConsoleTableView() diff --git a/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/Window/ShaderManagementConsoleTableView.h b/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/Window/ShaderManagementConsoleTableView.h index 32148c92f6..1d62c97412 100644 --- a/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/Window/ShaderManagementConsoleTableView.h +++ b/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/Window/ShaderManagementConsoleTableView.h @@ -23,7 +23,7 @@ namespace ShaderManagementConsole { public: AZ_CLASS_ALLOCATOR(ShaderManagementConsoleTableView, AZ::SystemAllocator, 0); - ShaderManagementConsoleTableView(const AZ::Uuid& documentId, QWidget* parent = 0); + ShaderManagementConsoleTableView(const AZ::Crc32& toolId, const AZ::Uuid& documentId, QWidget* parent); ~ShaderManagementConsoleTableView(); protected: @@ -33,8 +33,8 @@ namespace ShaderManagementConsole void RebuildTable(); - AZ::Uuid m_documentId = AZ::Uuid::CreateNull(); + const AZ::Crc32 m_toolId = {}; + const AZ::Uuid m_documentId = AZ::Uuid::CreateNull(); QStandardItemModel* m_model = {}; - }; } // namespace ShaderManagementConsole diff --git a/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/Window/ShaderManagementConsoleWindow.cpp b/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/Window/ShaderManagementConsoleWindow.cpp index d686207ed2..79e9804f87 100644 --- a/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/Window/ShaderManagementConsoleWindow.cpp +++ b/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/Window/ShaderManagementConsoleWindow.cpp @@ -36,7 +36,7 @@ namespace ShaderManagementConsole setObjectName("ShaderManagementConsoleWindow"); m_assetBrowser->SetFilterState("", AZ::RPI::ShaderAsset::Group, true); - m_assetBrowser->SetOpenHandler([this](const AZStd::string& absolutePath) { + m_assetBrowser->SetOpenHandler([this](const AZStd::string& absolutePath) { if (AzFramework::StringFunc::Path::IsExtension(absolutePath.c_str(), AZ::RPI::ShaderSourceData::Extension) || AzFramework::StringFunc::Path::IsExtension(absolutePath.c_str(), AZ::RPI::ShaderVariantListSourceData::Extension)) @@ -75,7 +75,7 @@ namespace ShaderManagementConsole QWidget* ShaderManagementConsoleWindow::CreateDocumentTabView(const AZ::Uuid& documentId) { - return new ShaderManagementConsoleTableView(documentId, centralWidget()); + return new ShaderManagementConsoleTableView(m_toolId, documentId, centralWidget()); } } // namespace ShaderManagementConsole