AzslShaderBuilderSystemComponent.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  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 <AzslShaderBuilderSystemComponent.h>
  9. #include <AssetBuilderSDK/AssetBuilderSDK.h>
  10. #include <AssetBuilderSDK/AssetBuilderBusses.h>
  11. #include <Atom/RHI.Edit/ShaderPlatformInterface.h>
  12. #include <Atom/RHI.Edit/Utils.h>
  13. #include <Atom/RHI.Edit/ShaderBuildOptions.h>
  14. #include <Atom/RPI.Reflect/Asset/AssetHandler.h>
  15. #include <Atom/RPI.Reflect/Shader/ShaderAsset.h>
  16. #include <Atom/RPI.Edit/Shader/ShaderSourceData.h>
  17. #include <Atom/RPI.Edit/Shader/ShaderVariantListSourceData.h>
  18. #include <AzToolsFramework/ToolsComponents/ToolsAssetCatalogBus.h>
  19. #include <AzCore/Serialization/EditContext.h>
  20. #include <AzCore/Serialization/SerializeContext.h>
  21. #include <AzCore/Settings/SettingsRegistry.h>
  22. #include <CommonFiles/Preprocessor.h>
  23. #include "HashedVariantListSourceData.h"
  24. namespace AZ
  25. {
  26. namespace ShaderBuilder
  27. {
  28. void AzslShaderBuilderSystemComponent::Reflect(ReflectContext* context)
  29. {
  30. if (SerializeContext* serialize = azrtti_cast<SerializeContext*>(context))
  31. {
  32. serialize->Class<AzslShaderBuilderSystemComponent, Component>()
  33. ->Version(0)
  34. ->Attribute(Edit::Attributes::SystemComponentTags, AZStd::vector<Crc32>({ AssetBuilderSDK::ComponentTags::AssetBuilder }))
  35. ;
  36. }
  37. PreprocessorOptions::Reflect(context);
  38. RHI::ShaderCompilerProfiling::Reflect(context);
  39. RHI::ShaderBuildArguments::Reflect(context);
  40. RHI::ShaderBuildOptions::Reflect(context);
  41. HashedVariantListSourceData::Reflect(context);
  42. }
  43. void AzslShaderBuilderSystemComponent::GetProvidedServices(ComponentDescriptor::DependencyArrayType& provided)
  44. {
  45. provided.push_back(AZ_CRC("AzslShaderBuilderService", 0x09315a40));
  46. }
  47. void AzslShaderBuilderSystemComponent::GetIncompatibleServices(ComponentDescriptor::DependencyArrayType& incompatible)
  48. {
  49. incompatible.push_back(AZ_CRC("AzslShaderBuilderService", 0x09315a40));
  50. }
  51. void AzslShaderBuilderSystemComponent::GetRequiredServices(ComponentDescriptor::DependencyArrayType& required)
  52. {
  53. (void)required;
  54. }
  55. void AzslShaderBuilderSystemComponent::GetDependentServices(ComponentDescriptor::DependencyArrayType& dependent)
  56. {
  57. dependent.push_back(AZ_CRC("AssetCatalogService", 0xc68ffc57));
  58. }
  59. void AzslShaderBuilderSystemComponent::Init()
  60. {
  61. }
  62. void AzslShaderBuilderSystemComponent::Activate()
  63. {
  64. RHI::ShaderPlatformInterfaceRegisterBus::Handler::BusConnect();
  65. ShaderPlatformInterfaceRequestBus::Handler::BusConnect();
  66. // Register Shader Asset Builder
  67. AssetBuilderSDK::AssetBuilderDesc shaderAssetBuilderDescriptor;
  68. shaderAssetBuilderDescriptor.m_name = "Shader Asset Builder";
  69. shaderAssetBuilderDescriptor.m_version = 124; // Add specialization constants for shader options
  70. shaderAssetBuilderDescriptor.m_patterns.push_back(AssetBuilderSDK::AssetBuilderPattern( AZStd::string::format("*.%s", RPI::ShaderSourceData::Extension), AssetBuilderSDK::AssetBuilderPattern::PatternType::Wildcard));
  71. shaderAssetBuilderDescriptor.m_busId = azrtti_typeid<ShaderAssetBuilder>();
  72. shaderAssetBuilderDescriptor.m_createJobFunction = AZStd::bind(&ShaderAssetBuilder::CreateJobs, &m_shaderAssetBuilder, AZStd::placeholders::_1, AZStd::placeholders::_2);
  73. shaderAssetBuilderDescriptor.m_processJobFunction = AZStd::bind(&ShaderAssetBuilder::ProcessJob, &m_shaderAssetBuilder, AZStd::placeholders::_1, AZStd::placeholders::_2);
  74. m_shaderAssetBuilder.BusConnect(shaderAssetBuilderDescriptor.m_busId);
  75. AssetBuilderSDK::AssetBuilderBus::Broadcast(&AssetBuilderSDK::AssetBuilderBus::Handler::RegisterBuilderInformation, shaderAssetBuilderDescriptor);
  76. // If, either the SettingsRegistry doesn't exist, or the property @EnableShaderVariantAssetBuilderRegistryKey is not found,
  77. // the default is to enable the ShaderVariantAssetBuilder.
  78. m_enableShaderVariantAssetBuilder = true;
  79. auto settingsRegistry = AZ::SettingsRegistry::Get();
  80. if (settingsRegistry)
  81. {
  82. settingsRegistry->Get(m_enableShaderVariantAssetBuilder, EnableShaderVariantAssetBuilderRegistryKey);
  83. }
  84. if (m_enableShaderVariantAssetBuilder)
  85. {
  86. // Register Shader Variant Asset Builder
  87. AssetBuilderSDK::AssetBuilderDesc shaderVariantAssetBuilderDescriptor;
  88. shaderVariantAssetBuilderDescriptor.m_name = "Shader Variant Asset Builder";
  89. // Both "Shader Variant Asset Builder" and "Shader Asset Builder" produce ShaderVariantAsset products. If you update
  90. // ShaderVariantAsset you will need to update BOTH version numbers, not just "Shader Variant Asset Builder".
  91. shaderVariantAssetBuilderDescriptor.m_version = 41; // Add specialization constants for shader options
  92. shaderVariantAssetBuilderDescriptor.m_patterns.push_back(AssetBuilderSDK::AssetBuilderPattern(AZStd::string::format("*.%s", HashedVariantListSourceData::Extension), AssetBuilderSDK::AssetBuilderPattern::PatternType::Wildcard));
  93. shaderVariantAssetBuilderDescriptor.m_patterns.push_back(AssetBuilderSDK::AssetBuilderPattern(AZStd::string::format("*.%s", HashedVariantInfoSourceData::Extension), AssetBuilderSDK::AssetBuilderPattern::PatternType::Wildcard));
  94. shaderVariantAssetBuilderDescriptor.m_busId = azrtti_typeid<ShaderVariantAssetBuilder>();
  95. shaderVariantAssetBuilderDescriptor.m_createJobFunction = AZStd::bind(&ShaderVariantAssetBuilder::CreateJobs, &m_shaderVariantAssetBuilder, AZStd::placeholders::_1, AZStd::placeholders::_2);
  96. shaderVariantAssetBuilderDescriptor.m_processJobFunction = AZStd::bind(&ShaderVariantAssetBuilder::ProcessJob, &m_shaderVariantAssetBuilder, AZStd::placeholders::_1, AZStd::placeholders::_2);
  97. m_shaderVariantAssetBuilder.BusConnect(shaderVariantAssetBuilderDescriptor.m_busId);
  98. AssetBuilderSDK::AssetBuilderBus::Broadcast(&AssetBuilderSDK::AssetBuilderBus::Handler::RegisterBuilderInformation, shaderVariantAssetBuilderDescriptor);
  99. // Register Shader Variant List Builder
  100. AssetBuilderSDK::AssetBuilderDesc shaderVariantListBuilderDescriptor;
  101. shaderVariantListBuilderDescriptor.m_name = "Shader Variant List Builder";
  102. shaderVariantListBuilderDescriptor.m_version = 2; // Add specialization constants for shader options
  103. shaderVariantListBuilderDescriptor.m_patterns.push_back(AssetBuilderSDK::AssetBuilderPattern(AZStd::string::format("*.%s", RPI::ShaderVariantListSourceData::Extension), AssetBuilderSDK::AssetBuilderPattern::PatternType::Wildcard));
  104. shaderVariantListBuilderDescriptor.m_busId = azrtti_typeid<ShaderVariantListBuilder>();
  105. shaderVariantListBuilderDescriptor.m_createJobFunction = AZStd::bind(&ShaderVariantListBuilder::CreateJobs, &m_shaderVariantListBuilder, AZStd::placeholders::_1, AZStd::placeholders::_2);
  106. shaderVariantListBuilderDescriptor.m_processJobFunction = AZStd::bind(&ShaderVariantListBuilder::ProcessJob, &m_shaderVariantListBuilder, AZStd::placeholders::_1, AZStd::placeholders::_2);
  107. m_shaderVariantListBuilder.BusConnect(shaderVariantListBuilderDescriptor.m_busId);
  108. AssetBuilderSDK::AssetBuilderBus::Broadcast(&AssetBuilderSDK::AssetBuilderBus::Handler::RegisterBuilderInformation, shaderVariantListBuilderDescriptor);
  109. }
  110. // Register Precompiled Shader Builder
  111. AssetBuilderSDK::AssetBuilderDesc precompiledShaderBuilderDescriptor;
  112. precompiledShaderBuilderDescriptor.m_name = "Precompiled Shader Builder";
  113. precompiledShaderBuilderDescriptor.m_version = 14; // Fixing warnings from having both source and job dependencies
  114. precompiledShaderBuilderDescriptor.m_patterns.push_back(AssetBuilderSDK::AssetBuilderPattern(AZStd::string::format("*.%s", AZ::PrecompiledShaderBuilder::Extension), AssetBuilderSDK::AssetBuilderPattern::PatternType::Wildcard));
  115. precompiledShaderBuilderDescriptor.m_busId = azrtti_typeid<PrecompiledShaderBuilder>();
  116. precompiledShaderBuilderDescriptor.m_createJobFunction = AZStd::bind(&PrecompiledShaderBuilder::CreateJobs, &m_precompiledShaderBuilder, AZStd::placeholders::_1, AZStd::placeholders::_2);
  117. precompiledShaderBuilderDescriptor.m_processJobFunction = AZStd::bind(&PrecompiledShaderBuilder::ProcessJob, &m_precompiledShaderBuilder, AZStd::placeholders::_1, AZStd::placeholders::_2);
  118. m_precompiledShaderBuilder.BusConnect(precompiledShaderBuilderDescriptor.m_busId);
  119. AssetBuilderSDK::AssetBuilderBus::Broadcast(&AssetBuilderSDK::AssetBuilderBus::Handler::RegisterBuilderInformation, precompiledShaderBuilderDescriptor);
  120. }
  121. void AzslShaderBuilderSystemComponent::Deactivate()
  122. {
  123. m_shaderAssetBuilder.BusDisconnect();
  124. if (m_enableShaderVariantAssetBuilder)
  125. {
  126. m_shaderVariantAssetBuilder.BusDisconnect();
  127. m_shaderVariantListBuilder.BusDisconnect();
  128. }
  129. m_precompiledShaderBuilder.BusDisconnect();
  130. RHI::ShaderPlatformInterfaceRegisterBus::Handler::BusDisconnect();
  131. ShaderPlatformInterfaceRequestBus::Handler::BusDisconnect();
  132. }
  133. void AzslShaderBuilderSystemComponent::RegisterShaderPlatformHandler(RHI::ShaderPlatformInterface* shaderPlatformInterface)
  134. {
  135. m_shaderPlatformInterfaces[shaderPlatformInterface->GetAPIType()] = shaderPlatformInterface;
  136. }
  137. void AzslShaderBuilderSystemComponent::UnregisterShaderPlatformHandler(RHI::ShaderPlatformInterface* shaderPlatformInterface)
  138. {
  139. m_shaderPlatformInterfaces.erase(shaderPlatformInterface->GetAPIType());
  140. }
  141. AZStd::vector<RHI::ShaderPlatformInterface*> AzslShaderBuilderSystemComponent::GetShaderPlatformInterface(const AssetBuilderSDK::PlatformInfo& platformInfo)
  142. {
  143. //Used to validate that each ShaderPlatformInterface returns a unique index.
  144. AZStd::unordered_map<uint32_t, Name> apiUniqueIndexToName;
  145. AZStd::vector<RHI::ShaderPlatformInterface*> results;
  146. results.reserve(platformInfo.m_tags.size());
  147. for (const AZStd::string& tag : platformInfo.m_tags)
  148. {
  149. // Use the platform tags to find the proper ShaderPlatformInterface
  150. auto findIt = m_shaderPlatformInterfaces.find(RHI::APIType(tag.c_str()));
  151. if (findIt != m_shaderPlatformInterfaces.end())
  152. {
  153. RHI::ShaderPlatformInterface* rhiApi = findIt->second;
  154. const uint32_t uniqueIndex = rhiApi->GetAPIUniqueIndex();
  155. auto uniqueIt = apiUniqueIndexToName.find(uniqueIndex);
  156. if (uniqueIt != apiUniqueIndexToName.end())
  157. {
  158. AZ_Assert(false, "The ShaderPlatformInterface with name [%s] is providing a unique api index [%u] which was already provided by the ShaderPlatformInterface [%s]",
  159. rhiApi->GetAPIName().GetCStr(), uniqueIndex, uniqueIt->second.GetCStr());
  160. continue;
  161. }
  162. AZ_Assert(uniqueIndex <= RHI::Limits::APIType::PerPlatformApiUniqueIndexMax, "The api index [%u] from ShaderPlatformInterface [%s] is invalid", uniqueIndex, rhiApi->GetAPIName().GetCStr());
  163. apiUniqueIndexToName[uniqueIndex] = rhiApi->GetAPIName();
  164. results.push_back(rhiApi);
  165. }
  166. }
  167. return results;
  168. }
  169. } // namespace ShaderBuilder
  170. } // namespace AZ