3
0

ShaderManagementConsoleWindow.cpp 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. #include <Atom/RPI.Edit/Shader/ShaderSourceData.h>
  9. #include <Atom/RPI.Edit/Shader/ShaderVariantListSourceData.h>
  10. #include <Atom/RPI.Edit/Common/AssetUtils.h>
  11. #include <Atom/RPI.Reflect/Shader/ShaderAsset.h>
  12. #include <AtomToolsFramework/Document/AtomToolsDocumentSystemRequestBus.h>
  13. #include <AzToolsFramework/API/EditorAssetSystemAPI.h>
  14. #include <AzToolsFramework/UI/UICore/WidgetHelpers.h>
  15. #include <AzCore/Utils/Utils.h>
  16. #include <Data/ShaderVariantStatisticData.h>
  17. #include <Document/ShaderManagementConsoleDocumentRequestBus.h>
  18. #include <Window/ShaderManagementConsoleWindow.h>
  19. #include <Window/ShaderManagementConsoleStatisticView.h>
  20. #include <ShaderManagementConsoleRequestBus.h>
  21. #include <QFileDialog>
  22. #include <QMenu>
  23. #include <QProgressDialog>
  24. #include <QUrl>
  25. #include <QWindow>
  26. #include <QMessageBox>
  27. namespace ShaderManagementConsole
  28. {
  29. ShaderManagementConsoleWindow::ShaderManagementConsoleWindow(const AZ::Crc32& toolId, QWidget* parent)
  30. : Base(toolId, "ShaderManagementConsoleWindow", parent)
  31. {
  32. m_assetBrowser->GetSearchWidget()->ClearTypeFilter();
  33. m_assetBrowser->GetSearchWidget()->SetTypeFilterVisible(false);
  34. m_assetBrowser->SetFileTypeFilters({
  35. { "Material", { "material" }, true },
  36. { "Material Type", { "materialtype" }, true },
  37. { "Shader", { "shader" }, true },
  38. { "Shader Template", { "shader.template" }, true },
  39. { "Shader Variant List", { "shadervariantlist" }, true },
  40. { "AZSL", { "azsl", "azsli", "srgi" }, true },
  41. });
  42. m_documentInspector = new AtomToolsFramework::AtomToolsDocumentInspector(m_toolId, this);
  43. m_documentInspector->SetDocumentSettingsPrefix("/O3DE/Atom/ShaderManagementConsole/DocumentInspector");
  44. AddDockWidget("Inspector", m_documentInspector, Qt::RightDockWidgetArea);
  45. SetDockWidgetVisible("Inspector", false);
  46. OnDocumentOpened(AZ::Uuid::CreateNull());
  47. }
  48. void ShaderManagementConsoleWindow::OnDocumentOpened(const AZ::Uuid& documentId)
  49. {
  50. Base::OnDocumentOpened(documentId);
  51. m_documentInspector->SetDocumentId(documentId);
  52. }
  53. AZStd::string ShaderManagementConsoleWindow::GetSaveDocumentParams(const AZStd::string& initialPath, const AZ::Uuid& documentId) const
  54. {
  55. // Get shader file path
  56. AZ::IO::Path shaderFullPath;
  57. AZ::RPI::ShaderVariantListSourceData shaderVariantList = {};
  58. ShaderManagementConsoleDocumentRequestBus::EventResult(
  59. shaderVariantList,
  60. documentId,
  61. &ShaderManagementConsoleDocumentRequestBus::Events::GetShaderVariantListSourceData);
  62. shaderFullPath = AZ::RPI::AssetUtils::ResolvePathReference(initialPath, shaderVariantList.m_shaderFilePath);
  63. QMessageBox msgBox;
  64. msgBox.setText("Where do you want to save the list?");
  65. QPushButton* projectBtn = msgBox.addButton(QObject::tr("Save to project"), QMessageBox::ActionRole);
  66. QPushButton* engineBtn = msgBox.addButton(QObject::tr("Save to engine"), QMessageBox::ActionRole);
  67. msgBox.addButton(QObject::tr("Cancel"), QMessageBox::RejectRole);
  68. msgBox.exec();
  69. AZ::IO::Path result;
  70. if (msgBox.clickedButton() == projectBtn)
  71. {
  72. AZ::IO::FixedMaxPath projectPath = AZ::Utils::GetProjectPath();
  73. AZ::IO::Path relativePath, rootFolder;
  74. bool pathFound = false;
  75. AzToolsFramework::AssetSystemRequestBus::BroadcastResult(
  76. pathFound,
  77. &AzToolsFramework::AssetSystemRequestBus::Events::GenerateRelativeSourcePath,
  78. shaderFullPath.Native(),
  79. relativePath.Native(),
  80. rootFolder.Native());
  81. if (pathFound)
  82. {
  83. relativePath.ReplaceExtension("shadervariantlist");
  84. projectPath /= AZ::IO::Path ("ShaderVariants") / relativePath;
  85. result = projectPath.LexicallyNormal();
  86. }
  87. else
  88. {
  89. AZ_Error("ShaderManagementConsoleWindow", false, "Can not find a relative path from the shader: '%s'.", shaderFullPath.c_str());
  90. }
  91. }
  92. else if(msgBox.clickedButton() == engineBtn)
  93. {
  94. shaderFullPath.ReplaceExtension("shadervariantlist");
  95. result = shaderFullPath;
  96. }
  97. return result.Native();
  98. }
  99. void ShaderManagementConsoleWindow::CreateMenus(QMenuBar* menuBar)
  100. {
  101. Base::CreateMenus(menuBar);
  102. // Add statistic button
  103. QAction* action = new QAction(tr("Generate Shader Variant Statistic..."), m_menuFile);
  104. QObject::connect(action, &QAction::triggered, this, &ShaderManagementConsoleWindow::GenerateStatisticView);
  105. m_menuFile->insertAction(m_menuFile->actions().back(), action);
  106. }
  107. void ShaderManagementConsoleWindow::GenerateStatisticView()
  108. {
  109. AZStd::vector<AZ::Data::AssetId> materialAssetIdList;
  110. ShaderManagementConsoleRequestBus::BroadcastResult(
  111. materialAssetIdList, &ShaderManagementConsoleRequestBus::Events::GetAllMaterialAssetIds);
  112. QProgressDialog progressDialog(AzToolsFramework::GetActiveWindow());
  113. progressDialog.setWindowModality(Qt::WindowModal);
  114. progressDialog.setMaximum(static_cast<int>(materialAssetIdList.size()));
  115. progressDialog.setMaximumWidth(400);
  116. progressDialog.setMaximumHeight(100);
  117. progressDialog.setWindowTitle(tr("Gather information from material assets"));
  118. progressDialog.setLabelText(tr("Gather shader variant information..."));
  119. ShaderVariantStatisticData statisticData;
  120. for (int i = 0; i < materialAssetIdList.size(); ++i)
  121. {
  122. AZStd::vector<AZ::RPI::ShaderCollection::Item> shaderItemList;
  123. ShaderManagementConsoleRequestBus::BroadcastResult(
  124. shaderItemList, &ShaderManagementConsoleRequestBus::Events::GetMaterialInstanceShaderItems, materialAssetIdList[i]);
  125. for (auto& shaderItem : shaderItemList)
  126. {
  127. AZ::RPI::ShaderVariantId shaderVariantId = shaderItem.GetShaderVariantId();
  128. if (!shaderVariantId.IsEmpty())
  129. {
  130. if (statisticData.m_shaderVariantUsage.find(shaderVariantId) == statisticData.m_shaderVariantUsage.end())
  131. {
  132. // Varient not found
  133. statisticData.m_shaderVariantUsage[shaderVariantId].m_count = 1;
  134. }
  135. else
  136. {
  137. statisticData.m_shaderVariantUsage[shaderVariantId].m_count += 1;
  138. }
  139. AZ::RPI::ShaderOptionGroup shaderOptionGroup = shaderItem.GetShaderOptionGroup();
  140. statisticData.m_shaderVariantUsage[shaderVariantId].m_shaderOptionGroup = shaderOptionGroup;
  141. for (auto& shaderOptionDescriptor : shaderOptionGroup.GetShaderOptionDescriptors())
  142. {
  143. AZ::Name optionName = shaderOptionDescriptor.GetName();
  144. AZ::RPI::ShaderOptionValue optionValue = shaderOptionGroup.GetValue(optionName);
  145. if (!optionValue.IsValid())
  146. {
  147. continue;
  148. }
  149. AZ::Name valueName = shaderOptionDescriptor.GetValueName(optionValue);
  150. if (statisticData.m_shaderOptionUsage.find(optionName) == statisticData.m_shaderOptionUsage.end())
  151. {
  152. // Option Not found
  153. statisticData.m_shaderOptionUsage[optionName][valueName] = 1;
  154. }
  155. else
  156. {
  157. if (statisticData.m_shaderOptionUsage[optionName].find(valueName) ==
  158. statisticData.m_shaderOptionUsage[optionName].end())
  159. {
  160. // Value not found
  161. statisticData.m_shaderOptionUsage[optionName][valueName] = 1;
  162. }
  163. else
  164. {
  165. statisticData.m_shaderOptionUsage[optionName][valueName] += 1;
  166. }
  167. }
  168. }
  169. }
  170. }
  171. progressDialog.setValue(i);
  172. if (progressDialog.wasCanceled())
  173. {
  174. return;
  175. }
  176. }
  177. progressDialog.close();
  178. if (m_statisticView)
  179. {
  180. delete m_statisticView;
  181. m_statisticView = nullptr;
  182. }
  183. m_statisticView = new ShaderManagementConsoleStatisticView(statisticData, nullptr);
  184. m_statisticView->setWindowTitle(tr("Shader Variant Statistic View"));
  185. m_statisticView->show();
  186. }
  187. void ShaderManagementConsoleWindow::closeEvent(QCloseEvent* closeEvent)
  188. {
  189. if (m_statisticView)
  190. {
  191. m_statisticView->close();
  192. delete m_statisticView;
  193. m_statisticView = nullptr;
  194. }
  195. Base::closeEvent(closeEvent);
  196. }
  197. } // namespace ShaderManagementConsole
  198. #include <Window/moc_ShaderManagementConsoleWindow.cpp>