Merge pull request #7613 from aws-lumberyard-dev/Atom/guthadam/centralize_shader_management_console_operations_in_document_class
Atom Tools: Moving shader management console file operations into document class
This commit is contained in:
+1
-1
@@ -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();
|
||||
|
||||
+1
-1
@@ -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...
|
||||
|
||||
@@ -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)
|
||||
|
||||
+1
-1
@@ -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)
|
||||
{
|
||||
}
|
||||
|
||||
+194
-17
@@ -6,10 +6,18 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <AssetDatabase/AssetDatabaseConnection.h>
|
||||
#include <Atom/RPI.Edit/Common/AssetUtils.h>
|
||||
#include <Atom/RPI.Edit/Common/JsonUtils.h>
|
||||
#include <Atom/RPI.Edit/Material/MaterialTypeSourceData.h>
|
||||
#include <Atom/RPI.Public/Material/Material.h>
|
||||
#include <Atom/RPI.Reflect/Asset/AssetUtils.h>
|
||||
#include <Atom/RPI.Reflect/Material/MaterialAsset.h>
|
||||
#include <AtomToolsFramework/Document/AtomToolsDocumentNotificationBus.h>
|
||||
#include <AzCore/Utils/Utils.h>
|
||||
#include <AzFramework/StringFunc/StringFunc.h>
|
||||
#include <AzToolsFramework/API/EditorAssetSystemAPI.h>
|
||||
#include <AzToolsFramework/API/ToolsApplicationAPI.h>
|
||||
#include <Document/ShaderManagementConsoleDocument.h>
|
||||
|
||||
namespace ShaderManagementConsole
|
||||
@@ -25,17 +33,15 @@ 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);
|
||||
|
||||
m_shaderAsset = AZ::RPI::AssetUtils::LoadAssetByProductPath<AZ::RPI::ShaderAsset>(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 +113,18 @@ 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))
|
||||
{
|
||||
AZ_Error("ShaderManagementConsoleDocument", false, "Document extension is not supported: '%s.'", m_absolutePath.c_str());
|
||||
return OpenFailed();
|
||||
return LoadShaderSourceData();
|
||||
}
|
||||
|
||||
// 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::ShaderVariantListSourceData::Extension))
|
||||
{
|
||||
AZ_Error("ShaderManagementConsoleDocument", false, "Failed loading shader variant list data: '%s.'", m_absolutePath.c_str());
|
||||
return OpenFailed();
|
||||
return LoadShaderVariantListSourceData();
|
||||
}
|
||||
|
||||
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 +175,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 +198,178 @@ namespace ShaderManagementConsole
|
||||
m_absolutePath = m_savePathNormalized;
|
||||
return SaveSucceeded();
|
||||
}
|
||||
|
||||
bool ShaderManagementConsoleDocument::LoadShaderSourceData()
|
||||
{
|
||||
// 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<AZ::RPI::ShaderVariantId> shaderVariantIds;
|
||||
AZStd::vector<AZ::RPI::ShaderOptionGroup> 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<AZ::Data::AssetId> ShaderManagementConsoleDocument::FindMaterialAssetsUsingShader(const AZStd::string& shaderFilePath)
|
||||
{
|
||||
AzToolsFramework::AssetDatabase::AssetDatabaseConnection assetDatabaseConnection;
|
||||
assetDatabaseConnection.OpenDatabase();
|
||||
|
||||
// Find all material types that reference shaderFilePath
|
||||
AZStd::vector<AZStd::string> materialTypeSources;
|
||||
|
||||
assetDatabaseConnection.QuerySourceDependencyByDependsOnSource(
|
||||
shaderFilePath.c_str(), nullptr, AzToolsFramework::AssetDatabase::SourceFileDependencyEntry::DEP_Any,
|
||||
[&](AzToolsFramework::AssetDatabase::SourceFileDependencyEntry& sourceFileDependencyEntry)
|
||||
{
|
||||
if (AzFramework::StringFunc::Path::IsExtension(
|
||||
sourceFileDependencyEntry.m_source.c_str(), AZ::RPI::MaterialTypeSourceData::Extension))
|
||||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
if (AzFramework::StringFunc::Path::IsExtension(entry.m_productName.c_str(), AZ::RPI::MaterialAsset::Extension))
|
||||
{
|
||||
productDependencies.push_back(entry);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
AZStd::vector<AZ::Data::AssetId> 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<AZ::RPI::ShaderCollection::Item> ShaderManagementConsoleDocument::GetMaterialInstanceShaderItems(
|
||||
const AZ::Data::AssetId& materialAssetId)
|
||||
{
|
||||
auto materialAsset =
|
||||
AZ::RPI::AssetUtils::LoadAssetById<AZ::RPI::MaterialAsset>(materialAssetId, AZ::RPI::AssetUtils::TraceLevel::Error);
|
||||
if (!materialAsset.IsReady())
|
||||
{
|
||||
AZ_Error(
|
||||
"ShaderManagementConsoleDocument", false, "Failed to load material asset from asset id: %s",
|
||||
materialAssetId.ToString<AZStd::string>().c_str());
|
||||
return AZStd::vector<AZ::RPI::ShaderCollection::Item>();
|
||||
}
|
||||
|
||||
auto materialInstance = AZ::RPI::Material::Create(materialAsset);
|
||||
if (!materialInstance)
|
||||
{
|
||||
AZ_Error(
|
||||
"ShaderManagementConsoleDocument", false, "Failed to create material instance from asset: %s",
|
||||
materialAsset.ToString<AZStd::string>().c_str());
|
||||
return AZStd::vector<AZ::RPI::ShaderCollection::Item>();
|
||||
}
|
||||
|
||||
return AZStd::vector<AZ::RPI::ShaderCollection::Item>(
|
||||
materialInstance->GetShaderCollection().begin(), materialInstance->GetShaderCollection().end());
|
||||
}
|
||||
} // namespace ShaderManagementConsole
|
||||
|
||||
+18
-4
@@ -5,20 +5,21 @@
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Atom/RPI.Edit/Shader/ShaderVariantListSourceData.h>
|
||||
#include <Atom/RPI.Reflect/Material/ShaderCollection.h>
|
||||
#include <Atom/RPI.Reflect/Shader/ShaderAsset.h>
|
||||
#include <AtomToolsFramework/Document/AtomToolsDocument.h>
|
||||
#include <AzCore/Asset/AssetCommon.h>
|
||||
#include <AzCore/RTTI/RTTI.h>
|
||||
#include <AzCore/std/containers/vector.h>
|
||||
#include <Document/ShaderManagementConsoleDocumentRequestBus.h>
|
||||
|
||||
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
|
||||
@@ -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,8 +54,21 @@ 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<AZ::Data::AssetId> FindMaterialAssetsUsingShader(const AZStd::string& shaderFilePath);
|
||||
|
||||
// Retrieve all of the shader collection items from a material instance created from materialAssetId
|
||||
AZStd::vector<AZ::RPI::ShaderCollection::Item> GetMaterialInstanceShaderItems(const AZ::Data::AssetId& materialAssetId);
|
||||
|
||||
// Source data for shader variant list
|
||||
AZ::RPI::ShaderVariantListSourceData m_shaderVariantListSourceData;
|
||||
|
||||
|
||||
+3
-4
@@ -5,6 +5,7 @@
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Atom/RPI.Edit/Shader/ShaderSourceData.h>
|
||||
@@ -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;
|
||||
|
||||
+5
-119
@@ -6,27 +6,17 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <AssetDatabase/AssetDatabaseConnection.h>
|
||||
#include <Atom/RPI.Edit/Common/AssetUtils.h>
|
||||
#include <Atom/RPI.Edit/Common/JsonUtils.h>
|
||||
#include <Atom/RPI.Public/Material/Material.h>
|
||||
#include <Atom/RPI.Reflect/Asset/AssetUtils.h>
|
||||
#include <AtomToolsFramework/Document/AtomToolsDocumentSystemRequestBus.h>
|
||||
#include <AtomToolsFramework/Util/Util.h>
|
||||
#include <AzCore/RTTI/BehaviorContext.h>
|
||||
#include <AzCore/Serialization/EditContext.h>
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
#include <AzCore/Settings/SettingsRegistryMergeUtils.h>
|
||||
#include <AzCore/Utils/Utils.h>
|
||||
#include <AzToolsFramework/API/EditorAssetSystemAPI.h>
|
||||
#include <AzToolsFramework/API/EditorPythonRunnerRequestsBus.h>
|
||||
#include <AzToolsFramework/API/ToolsApplicationAPI.h>
|
||||
#include <AzToolsFramework/AssetBrowser/AssetBrowserEntry.h>
|
||||
#include <AzToolsFramework/UI/UICore/QWidgetSavedState.h>
|
||||
#include <Document/ShaderManagementConsoleDocument.h>
|
||||
#include <Document/ShaderManagementConsoleDocumentRequestBus.h>
|
||||
#include <ShaderManagementConsoleApplication.h>
|
||||
#include <ShaderManagementConsoleRequestBus.h>
|
||||
#include <ShaderManagementConsole_Traits_Platform.h>
|
||||
|
||||
#include <QDesktopServices>
|
||||
@@ -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<AZ::BehaviorContext*>(context))
|
||||
{
|
||||
behaviorContext->EBus<ShaderManagementConsoleRequestBus>("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>("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<AZ::Data::AssetId> ShaderManagementConsoleApplication::FindMaterialAssetsUsingShader(const AZStd::string& shaderFilePath)
|
||||
{
|
||||
// Collect the material types referencing the shader
|
||||
AZStd::vector<AZStd::string> 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<AZ::Data::AssetId> 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<AZ::RPI::ShaderCollection::Item> ShaderManagementConsoleApplication::GetMaterialInstanceShaderItems(
|
||||
const AZ::Data::AssetId& assetId)
|
||||
{
|
||||
auto materialAsset = AZ::RPI::AssetUtils::LoadAssetById<AZ::RPI::MaterialAsset>(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<AZStd::string>().c_str());
|
||||
|
||||
if (materialInstance != nullptr)
|
||||
{
|
||||
return AZStd::vector<AZ::RPI::ShaderCollection::Item>(
|
||||
materialInstance->GetShaderCollection().begin(), materialInstance->GetShaderCollection().end());
|
||||
}
|
||||
return AZStd::vector<AZ::RPI::ShaderCollection::Item>();
|
||||
}
|
||||
} // namespace ShaderManagementConsole
|
||||
|
||||
-7
@@ -12,14 +12,12 @@
|
||||
#include <AtomToolsFramework/AssetBrowser/AtomToolsAssetBrowserInteractions.h>
|
||||
#include <AtomToolsFramework/Document/AtomToolsDocumentApplication.h>
|
||||
#include <AzToolsFramework/API/EditorWindowRequestBus.h>
|
||||
#include <ShaderManagementConsoleRequestBus.h>
|
||||
#include <Window/ShaderManagementConsoleWindow.h>
|
||||
|
||||
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<AZ::Data::AssetId> FindMaterialAssetsUsingShader(const AZStd::string& shaderFilePath) override;
|
||||
AZStd::vector<AZ::RPI::ShaderCollection::Item> GetMaterialInstanceShaderItems(const AZ::Data::AssetId& assetId) override;
|
||||
|
||||
private:
|
||||
AZStd::unique_ptr<ShaderManagementConsoleWindow> m_window;
|
||||
AZStd::unique_ptr<AtomToolsFramework::AtomToolsAssetBrowserInteractions> m_assetBrowserInteractions;
|
||||
|
||||
-38
@@ -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 <AzCore/std/containers/vector.h>
|
||||
#include <AzCore/EBus/EBus.h>
|
||||
#include <AzCore/Asset/AssetCommon.h>
|
||||
#include <Atom/RPI.Edit/Shader/ShaderVariantListSourceData.h>
|
||||
#include <Atom/RPI.Reflect/Material/ShaderCollection.h>
|
||||
|
||||
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<AZ::Data::AssetId> FindMaterialAssetsUsingShader (const AZStd::string& shaderFilePath) = 0;
|
||||
|
||||
//! Returns a list of shader items contained within an instantiated material source's shader collection.
|
||||
virtual AZStd::vector<AZ::RPI::ShaderCollection::Item> GetMaterialInstanceShaderItems(const AZ::Data::AssetId& assetId) = 0;
|
||||
};
|
||||
using ShaderManagementConsoleRequestBus = AZ::EBus<ShaderManagementConsoleRequests>;
|
||||
} // namespace ShaderManagementConsole
|
||||
+106
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
* 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 <AzCore/Name/Name.h>
|
||||
#include <Document/ShaderManagementConsoleDocumentRequestBus.h>
|
||||
#include <Window/ShaderManagementConsoleTableView.h>
|
||||
|
||||
#include <QHeaderView>
|
||||
|
||||
namespace ShaderManagementConsole
|
||||
{
|
||||
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))
|
||||
{
|
||||
setSelectionBehavior(QAbstractItemView::SelectRows);
|
||||
setModel(m_model);
|
||||
|
||||
RebuildTable();
|
||||
AtomToolsFramework::AtomToolsDocumentNotificationBus::Handler::BusConnect(m_toolId);
|
||||
}
|
||||
|
||||
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<AZStd::string> 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<int>(shaderVariantCount));
|
||||
m_model->setColumnCount(static_cast<int>(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<int>(AZStd::distance(optionNames.begin(), optionIt));
|
||||
|
||||
QStandardItem* item = new QStandardItem(optionValue.GetCStr());
|
||||
m_model->setItem(variantIndex, optionIndex, item);
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace ShaderManagementConsole
|
||||
|
||||
#include <Window/moc_ShaderManagementConsoleTableView.cpp>
|
||||
#include "ShaderManagementConsoleTableView.h"
|
||||
+40
@@ -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 <AtomToolsFramework/Document/AtomToolsDocumentNotificationBus.h>
|
||||
|
||||
#include <QStandardItemModel>
|
||||
#include <QTableView>
|
||||
#endif
|
||||
|
||||
namespace ShaderManagementConsole
|
||||
{
|
||||
class ShaderManagementConsoleTableView
|
||||
: public QTableView
|
||||
, public AtomToolsFramework::AtomToolsDocumentNotificationBus::Handler
|
||||
{
|
||||
public:
|
||||
AZ_CLASS_ALLOCATOR(ShaderManagementConsoleTableView, AZ::SystemAllocator, 0);
|
||||
ShaderManagementConsoleTableView(const AZ::Crc32& toolId, const AZ::Uuid& documentId, QWidget* parent);
|
||||
~ShaderManagementConsoleTableView();
|
||||
|
||||
protected:
|
||||
// AtomToolsFramework::AtomToolsDocumentNotificationBus::Handler overrides...
|
||||
void OnDocumentOpened(const AZ::Uuid& documentId) override;
|
||||
void OnDocumentModified(const AZ::Uuid& documentId) override;
|
||||
|
||||
void RebuildTable();
|
||||
|
||||
const AZ::Crc32 m_toolId = {};
|
||||
const AZ::Uuid m_documentId = AZ::Uuid::CreateNull();
|
||||
QStandardItemModel* m_model = {};
|
||||
};
|
||||
} // namespace ShaderManagementConsole
|
||||
+23
-75
@@ -6,23 +6,19 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <Atom/RPI.Edit/Shader/ShaderSourceData.h>
|
||||
#include <Atom/RPI.Edit/Shader/ShaderVariantListSourceData.h>
|
||||
#include <Atom/RPI.Reflect/Shader/ShaderAsset.h>
|
||||
#include <AtomToolsFramework/Document/AtomToolsDocumentSystemRequestBus.h>
|
||||
#include <AtomToolsFramework/Util/Util.h>
|
||||
#include <AzCore/Name/Name.h>
|
||||
#include <AzQtComponents/Components/WindowDecorationWrapper.h>
|
||||
#include <Document/ShaderManagementConsoleDocumentRequestBus.h>
|
||||
#include <Window/ShaderManagementConsoleWindow.h>
|
||||
#include <AzCore/Utils/Utils.h>
|
||||
#include <AzQtComponents/Components/WindowDecorationWrapper.h>
|
||||
#include <Window/ShaderManagementConsoleTableView.h>
|
||||
#include <Window/ShaderManagementConsoleWindow.h>
|
||||
|
||||
AZ_PUSH_DISABLE_WARNING(4251 4800, "-Wunknown-warning-option") // disable warnings spawned by QT
|
||||
#include <QDesktopServices>
|
||||
#include <QFileDialog>
|
||||
#include <QHeaderView>
|
||||
#include <QStandardItemModel>
|
||||
#include <QTableView>
|
||||
#include <QUrl>
|
||||
#include <QWindow>
|
||||
AZ_POP_DISABLE_WARNING
|
||||
|
||||
namespace ShaderManagementConsole
|
||||
{
|
||||
@@ -40,16 +36,18 @@ namespace ShaderManagementConsole
|
||||
setObjectName("ShaderManagementConsoleWindow");
|
||||
|
||||
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))
|
||||
m_assetBrowser->SetOpenHandler([this](const AZStd::string& absolutePath)
|
||||
{
|
||||
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,68 +64,18 @@ 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();
|
||||
}
|
||||
|
||||
QWidget* ShaderManagementConsoleWindow::CreateDocumentTabView(const AZ::Uuid& documentId)
|
||||
{
|
||||
AZStd::unordered_set<AZStd::string> 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);
|
||||
|
||||
const char* optionName = shaderOptionDesc.GetName().GetCStr();
|
||||
optionNames.insert(optionName);
|
||||
}
|
||||
|
||||
size_t shaderVariantCount = 0;
|
||||
ShaderManagementConsoleDocumentRequestBus::EventResult(
|
||||
shaderVariantCount, documentId, &ShaderManagementConsoleDocumentRequestBus::Events::GetShaderVariantCount);
|
||||
|
||||
auto model = new QStandardItemModel();
|
||||
model->setRowCount(static_cast<int>(shaderVariantCount));
|
||||
model->setColumnCount(static_cast<int>(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<int>(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(m_toolId, documentId, centralWidget());
|
||||
}
|
||||
} // namespace ShaderManagementConsole
|
||||
|
||||
|
||||
-8
@@ -8,16 +8,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#if !defined(Q_MOC_RUN)
|
||||
#include <Atom/RPI.Edit/Shader/ShaderVariantListSourceData.h>
|
||||
#include <Atom/RPI.Public/Shader/Shader.h>
|
||||
#include <AtomToolsFramework/Document/AtomToolsDocumentMainWindow.h>
|
||||
|
||||
AZ_PUSH_DISABLE_WARNING(4251 4800, "-Wunknown-warning-option") // disable warnings spawned by QT
|
||||
#include <QStandardItemModel>
|
||||
AZ_POP_DISABLE_WARNING
|
||||
#endif
|
||||
|
||||
namespace ShaderManagementConsole
|
||||
{
|
||||
//! ShaderManagementConsoleWindow is the main class. Its responsibility is limited to initializing and connecting
|
||||
|
||||
@@ -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
|
||||
@@ -18,6 +20,5 @@ set(FILES
|
||||
Source/main.cpp
|
||||
Source/ShaderManagementConsoleApplication.cpp
|
||||
Source/ShaderManagementConsoleApplication.h
|
||||
Source/ShaderManagementConsoleRequestBus.h
|
||||
../Scripts/GenerateShaderVariantListForMaterials.py
|
||||
)
|
||||
|
||||
+38
-94
@@ -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
|
||||
|
||||
# clean previously generated shader variant list file so they don't clash.
|
||||
pre, ext = os.path.splitext(shaderAssetInfo.relativePath)
|
||||
projectShaderVariantListFilePath = os.path.join(azlmbr.paths.projectroot, PROJECT_SHADER_VARIANTS_FOLDER, f'{pre}.shadervariantlist')
|
||||
|
||||
|
||||
# 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(shaderVariantList.shaderFilePath)
|
||||
projectShaderVariantListFilePath = os.path.join(azlmbr.paths.projectroot, PROJECT_SHADER_VARIANTS_FOLDER, 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__":
|
||||
|
||||
Reference in New Issue
Block a user