ConstantsLayout.cpp 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  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/ConstantsLayout.h>
  9. #include <AzCore/Serialization/SerializeContext.h>
  10. #include <AzCore/Utils/TypeHash.h>
  11. namespace AZ::RHI
  12. {
  13. void ConstantsLayout::Reflect(AZ::ReflectContext* context)
  14. {
  15. if (SerializeContext* serializeContext = azrtti_cast<SerializeContext*>(context))
  16. {
  17. serializeContext->Class<ConstantsLayout>()
  18. ->Version(1) // Version 1: Adding debug helper functions to Shader Resource Groups
  19. ->Field("m_inputs", &ConstantsLayout::m_inputs)
  20. ->Field("m_idReflection", &ConstantsLayout::m_idReflection)
  21. ->Field("m_sizeInBytes", &ConstantsLayout::m_sizeInBytes)
  22. ->Field("m_hash", &ConstantsLayout::m_hash);
  23. }
  24. IdReflectionMapForConstants::Reflect(context);
  25. }
  26. RHI::Ptr<ConstantsLayout> ConstantsLayout::Create()
  27. {
  28. return aznew ConstantsLayout;
  29. }
  30. void ConstantsLayout::AddShaderInput(const ShaderInputConstantDescriptor& descriptor)
  31. {
  32. m_inputs.push_back(descriptor);
  33. }
  34. void ConstantsLayout::Clear()
  35. {
  36. m_inputs.clear();
  37. m_idReflection.Clear();
  38. m_sizeInBytes = 0;
  39. m_hash = InvalidHash;
  40. }
  41. bool ConstantsLayout::IsFinalized() const
  42. {
  43. return m_hash != InvalidHash;
  44. }
  45. bool ConstantsLayout::Finalize()
  46. {
  47. m_hash = HashValue64{ 0 };
  48. uint32_t constantInputIndex = 0;
  49. uint32_t constantDataSize = 0;
  50. for (const auto& constantDescriptor : m_inputs)
  51. {
  52. const ShaderInputConstantIndex inputIndex(constantInputIndex);
  53. if (!m_idReflection.Insert(constantDescriptor.m_name, inputIndex))
  54. {
  55. Clear();
  56. return false;
  57. }
  58. uint32_t end = constantDescriptor.m_constantByteOffset + constantDescriptor.m_constantByteCount;
  59. constantDataSize = AZStd::max(constantDataSize, end);
  60. ++constantInputIndex;
  61. m_hash = TypeHash64(constantDescriptor.GetHash(), m_hash);
  62. }
  63. m_sizeInBytes = constantDataSize;
  64. if (!ValidateConstantInputs())
  65. {
  66. Clear();
  67. return false;
  68. }
  69. return true;
  70. }
  71. HashValue64 ConstantsLayout::GetHash() const
  72. {
  73. return m_hash;
  74. }
  75. ShaderInputConstantIndex ConstantsLayout::FindShaderInputIndex(const Name& name) const
  76. {
  77. return m_idReflection.Find(name);
  78. }
  79. Interval ConstantsLayout::GetInterval(ShaderInputConstantIndex inputIndex) const
  80. {
  81. const ShaderInputConstantDescriptor& desc = GetShaderInput(inputIndex);
  82. uint32_t start = desc.m_constantByteOffset;
  83. uint32_t end = start + desc.m_constantByteCount;
  84. return Interval(start, end);
  85. }
  86. const ShaderInputConstantDescriptor& ConstantsLayout::GetShaderInput(ShaderInputConstantIndex inputIndex) const
  87. {
  88. const auto index = inputIndex.GetIndex();
  89. static const ShaderInputConstantDescriptor invalidDescriptor;
  90. return index < m_inputs.size() ? m_inputs[index] : invalidDescriptor;
  91. }
  92. AZStd::span<const ShaderInputConstantDescriptor> ConstantsLayout::GetShaderInputList() const
  93. {
  94. return m_inputs;
  95. }
  96. uint32_t ConstantsLayout::GetDataSize() const
  97. {
  98. return m_sizeInBytes;
  99. }
  100. bool ConstantsLayout::ValidateAccess(ShaderInputConstantIndex inputIndex) const
  101. {
  102. if (Validation::IsEnabled())
  103. {
  104. uint32_t count = static_cast<uint32_t>(m_inputs.size());
  105. if (inputIndex.GetIndex() >= count)
  106. {
  107. AZ_Assert(false, "Inline Constant Input index '%d' out of range [0,%d).", inputIndex.GetIndex(), count);
  108. return false;
  109. }
  110. }
  111. return true;
  112. }
  113. bool ConstantsLayout::ValidateConstantInputs() const
  114. {
  115. if (Validation::IsEnabled())
  116. {
  117. if (!m_sizeInBytes)
  118. {
  119. AZ_Assert(m_idReflection.IsEmpty(), "Constants size is not valid.");
  120. return m_idReflection.IsEmpty();
  121. }
  122. }
  123. return true;
  124. }
  125. void ConstantsLayout::DebugPrintNames(AZStd::span<const ShaderInputConstantIndex> constantList) const
  126. {
  127. AZStd::string output;
  128. for (const ShaderInputConstantIndex& constantIdx : constantList)
  129. {
  130. if (constantIdx.GetIndex() < m_inputs.size())
  131. {
  132. output += m_inputs[constantIdx.GetIndex()].m_name.GetCStr();
  133. output += " - ";
  134. }
  135. }
  136. AZ_Printf("RHI", output.c_str());
  137. }
  138. }