PipelineLayoutDescriptor.cpp 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  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/RHI.Reflect/PipelineLayoutDescriptor.h>
  9. #include <AzCore/Serialization/SerializeContext.h>
  10. #include <AzCore/Utils/TypeHash.h>
  11. namespace AZ::RHI
  12. {
  13. void ResourceBindingInfo::Reflect(AZ::ReflectContext* context)
  14. {
  15. if (SerializeContext* serializeContext = azrtti_cast<SerializeContext*>(context))
  16. {
  17. serializeContext->Class<ResourceBindingInfo>()
  18. ->Version(1)
  19. ->Field("m_shaderStageMask", &ResourceBindingInfo::m_shaderStageMask)
  20. ->Field("m_registerId", &ResourceBindingInfo::m_registerId)
  21. ->Field("m_spaceId", &ResourceBindingInfo::m_spaceId);
  22. }
  23. }
  24. HashValue64 ResourceBindingInfo::GetHash() const
  25. {
  26. HashValue64 hash = TypeHash64(static_cast<uint32_t>(m_shaderStageMask));
  27. hash = TypeHash64(m_registerId, hash);
  28. return hash;
  29. }
  30. void ShaderResourceGroupBindingInfo::Reflect(AZ::ReflectContext* context)
  31. {
  32. ResourceBindingInfo::Reflect(context);
  33. if (SerializeContext* serializeContext = azrtti_cast<SerializeContext*>(context))
  34. {
  35. serializeContext->Class<ShaderResourceGroupBindingInfo>()
  36. ->Version(1)
  37. ->Field("m_constantDataBindingInfo", &ShaderResourceGroupBindingInfo::m_constantDataBindingInfo)
  38. ->Field("m_resourcesRegisterMap", &ShaderResourceGroupBindingInfo::m_resourcesRegisterMap);
  39. }
  40. }
  41. HashValue64 ShaderResourceGroupBindingInfo::GetHash() const
  42. {
  43. HashValue64 seed = TypeHash64(m_constantDataBindingInfo);
  44. for (const auto& resourceInfo : m_resourcesRegisterMap)
  45. {
  46. seed = TypeHash64(resourceInfo.first.GetHash(), seed);
  47. seed = TypeHash64(resourceInfo.second, seed);
  48. }
  49. return seed;
  50. }
  51. void PipelineLayoutDescriptor::Reflect(AZ::ReflectContext* context)
  52. {
  53. ShaderResourceGroupBindingInfo::Reflect(context);
  54. ConstantsLayout::Reflect(context);
  55. if (SerializeContext* serializeContext = azrtti_cast<SerializeContext*>(context))
  56. {
  57. serializeContext->Class<PipelineLayoutDescriptor>()
  58. ->Version(4)
  59. ->Field("m_shaderResourceGroupLayoutsInfo", &PipelineLayoutDescriptor::m_shaderResourceGroupLayoutsInfo)
  60. ->Field("m_rootConstantLayout", &PipelineLayoutDescriptor::m_rootConstantsLayout)
  61. ->Field("m_bindingSlotToIndex", &PipelineLayoutDescriptor::m_bindingSlotToIndex)
  62. ->Field("m_hash", &PipelineLayoutDescriptor::m_hash);
  63. }
  64. }
  65. RHI::Ptr<PipelineLayoutDescriptor> PipelineLayoutDescriptor::Create()
  66. {
  67. return aznew PipelineLayoutDescriptor;
  68. }
  69. bool PipelineLayoutDescriptor::IsFinalized() const
  70. {
  71. return m_hash != InvalidHash;
  72. }
  73. void PipelineLayoutDescriptor::Reset()
  74. {
  75. m_hash = InvalidHash;
  76. m_shaderResourceGroupLayoutsInfo.clear();
  77. m_bindingSlotToIndex.fill(RHI::Limits::Pipeline::ShaderResourceGroupCountMax);
  78. ResetInternal();
  79. }
  80. ResultCode PipelineLayoutDescriptor::Finalize()
  81. {
  82. ResultCode resultCode = FinalizeInternal();
  83. if (resultCode == ResultCode::Success)
  84. {
  85. HashValue64 seed = HashValue64{ 0 };
  86. for (const ShaderResourceGroupLayoutInfo& layoutInfo : m_shaderResourceGroupLayoutsInfo)
  87. {
  88. seed = TypeHash64(layoutInfo.first->GetHash(), seed);
  89. seed = TypeHash64(layoutInfo.second.GetHash(), seed);
  90. }
  91. if (m_rootConstantsLayout)
  92. {
  93. seed = TypeHash64(m_rootConstantsLayout->GetHash(), seed);
  94. }
  95. for (const auto& index : m_bindingSlotToIndex)
  96. {
  97. seed = TypeHash64(index, seed);
  98. }
  99. m_hash = GetHashInternal(seed);
  100. }
  101. return resultCode;
  102. }
  103. void PipelineLayoutDescriptor::ResetInternal() {}
  104. ResultCode PipelineLayoutDescriptor::FinalizeInternal()
  105. {
  106. return ResultCode::Success;
  107. }
  108. HashValue64 PipelineLayoutDescriptor::GetHashInternal(HashValue64 seed) const
  109. {
  110. return seed;
  111. }
  112. void PipelineLayoutDescriptor::AddShaderResourceGroupLayoutInfo(const ShaderResourceGroupLayout& layout, const ShaderResourceGroupBindingInfo& shaderResourceGroupInfo)
  113. {
  114. m_bindingSlotToIndex[layout.GetBindingSlot()] = aznumeric_caster(m_shaderResourceGroupLayoutsInfo.size());
  115. // NOTE: The const_cast is required because serialization does not allow for ConstPtr. However,
  116. // the layout is always treated as immutable internally, and is only exposed as such externally.
  117. m_shaderResourceGroupLayoutsInfo.push_back({ const_cast<ShaderResourceGroupLayout*>(&layout), shaderResourceGroupInfo });
  118. }
  119. void PipelineLayoutDescriptor::SetRootConstantsLayout(const ConstantsLayout& rootConstantsLayout)
  120. {
  121. // NOTE: The const_cast is required because serialization does not allow for ConstPtr.However,
  122. // the layout is always treated as immutable internally, and is only exposed as such externally.
  123. m_rootConstantsLayout = const_cast<ConstantsLayout*>(&rootConstantsLayout);
  124. }
  125. size_t PipelineLayoutDescriptor::GetShaderResourceGroupLayoutCount() const
  126. {
  127. AZ_Assert(IsFinalized(), "Accessor called on a non-finalized pipeline layout. This is not permitted.");
  128. return m_shaderResourceGroupLayoutsInfo.size();
  129. }
  130. const ShaderResourceGroupLayout* PipelineLayoutDescriptor::GetShaderResourceGroupLayout(size_t index) const
  131. {
  132. AZ_Assert(IsFinalized(), "Accessor called on a non-finalized pipeline layout. This is not permitted.");
  133. return m_shaderResourceGroupLayoutsInfo[index].first.get();
  134. }
  135. const ShaderResourceGroupBindingInfo& PipelineLayoutDescriptor::GetShaderResourceGroupBindingInfo(size_t index) const
  136. {
  137. AZ_Assert(IsFinalized(), "Accessor called on a non-finalized pipeline layout. This is not permitted.");
  138. return m_shaderResourceGroupLayoutsInfo[index].second;
  139. }
  140. const ConstantsLayout* PipelineLayoutDescriptor::GetRootConstantsLayout() const
  141. {
  142. AZ_Assert(IsFinalized(), "Accessor called on a non-finalized pipeline layout. This is not permitted.");
  143. return m_rootConstantsLayout.get();
  144. }
  145. HashValue64 PipelineLayoutDescriptor::GetHash() const
  146. {
  147. AZ_Assert(IsFinalized(), "Accessor called on a non-finalized pipeline layout. This is not permitted.");
  148. return m_hash;
  149. }
  150. uint32_t PipelineLayoutDescriptor::GetShaderResourceGroupIndexFromBindingSlot(uint32_t bindingSlot) const
  151. {
  152. AZ_Assert(IsFinalized(), "Accessor called on a non-finalized pipeline layout. This is not permitted.");
  153. return m_bindingSlotToIndex[bindingSlot];
  154. }
  155. }