ShaderVariantKey.cpp 5.7 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/RPI.Reflect/Shader/ShaderVariantKey.h>
  9. namespace AZ
  10. {
  11. namespace RPI
  12. {
  13. const ShaderVariantStableId RootShaderVariantStableId{0};
  14. void ShaderVariantId::Reflect(ReflectContext* context)
  15. {
  16. if (auto* serializeContext = azrtti_cast<SerializeContext*>(context))
  17. {
  18. serializeContext->Class<ShaderVariantId>()
  19. ->Version(0)
  20. ->Field("Key", &ShaderVariantId::m_key)
  21. ->Field("Mask", &ShaderVariantId::m_mask)
  22. ;
  23. }
  24. if (BehaviorContext* behaviorContext = azrtti_cast<BehaviorContext*>(context))
  25. {
  26. behaviorContext->Class<ShaderVariantId>()
  27. ->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Automation)
  28. ->Attribute(AZ::Script::Attributes::Category, "Shader")
  29. ->Attribute(AZ::Script::Attributes::Module, "shader")
  30. ->Method("Equal", &ShaderVariantId::operator==)
  31. ->Attribute(AZ::Script::Attributes::Operator, AZ::Script::Attributes::OperatorType::Equal)
  32. ->Method("IsEmpty", &ShaderVariantId::IsEmpty)
  33. ;
  34. }
  35. }
  36. ShaderVariantId& ShaderVariantId::Reset()
  37. {
  38. m_key.reset();
  39. m_mask.reset();
  40. return *this;
  41. }
  42. bool ShaderVariantId::operator==(const ShaderVariantId& other) const
  43. {
  44. return ShaderVariantIdComparator::Compare(*this, other) == 0;
  45. }
  46. bool ShaderVariantId::operator!=(const ShaderVariantId& other) const
  47. {
  48. return ShaderVariantIdComparator::Compare(*this, other) != 0;
  49. }
  50. bool ShaderVariantId::operator<(const ShaderVariantId& other) const
  51. {
  52. return ShaderVariantIdComparator::Compare(*this, other) == -1;
  53. }
  54. bool ShaderVariantId::operator>(const ShaderVariantId& other) const
  55. {
  56. return ShaderVariantIdComparator::Compare(*this, other) == 1;
  57. }
  58. bool ShaderVariantId::operator<=(const ShaderVariantId& other) const
  59. {
  60. return ShaderVariantIdComparator::Compare(*this, other) != 1;
  61. }
  62. bool ShaderVariantId::operator>=(const ShaderVariantId& other) const
  63. {
  64. return ShaderVariantIdComparator::Compare(*this, other) != -1;
  65. }
  66. bool ShaderVariantId::IsEmpty() const
  67. {
  68. return m_mask.none();
  69. }
  70. ShaderVariantSearchResult::ShaderVariantSearchResult(ShaderVariantStableId stableId, uint32_t dynamicOptionCount)
  71. : m_shaderVariantStableId (stableId)
  72. , m_dynamicOptionCount(dynamicOptionCount)
  73. {
  74. }
  75. ShaderVariantStableId ShaderVariantSearchResult::GetStableId() const
  76. {
  77. return m_shaderVariantStableId;
  78. }
  79. bool ShaderVariantSearchResult::IsRoot() const
  80. {
  81. return m_shaderVariantStableId == RootShaderVariantStableId;
  82. }
  83. bool ShaderVariantSearchResult::IsFullyBaked() const
  84. {
  85. return (m_dynamicOptionCount == 0);
  86. }
  87. uint32_t ShaderVariantSearchResult::GetDynamicOptionCount() const
  88. {
  89. return m_dynamicOptionCount;
  90. }
  91. int ShaderVariantKeyComparator::Compare(const ShaderVariantKey& lhs, const ShaderVariantKey& rhs)
  92. {
  93. if constexpr (ShaderVariantKeyBitCount <= 64)
  94. {
  95. return CompareSmallKey(lhs, rhs);
  96. }
  97. else
  98. {
  99. return CompareLargeKey(lhs, rhs);
  100. }
  101. }
  102. int ShaderVariantKeyComparator::CompareSmallKey(const ShaderVariantKey& lhs, const ShaderVariantKey& rhs)
  103. {
  104. // Works for keys smaller than 64-bits. Asserts that bits higher than 64 aren't set.
  105. return lhs.to_ullong() < rhs.to_ullong() ?
  106. -1 : lhs.to_ullong() == rhs.to_ullong() ? 0 : 1;
  107. }
  108. int ShaderVariantKeyComparator::CompareLargeKey(const ShaderVariantKey& lhs, const ShaderVariantKey& rhs)
  109. {
  110. // Walks the from most to least significant and compares words. Matching upper words
  111. // requires searching the next lower word.
  112. for (size_t i = lhs.num_words() - 1; i != static_cast<size_t>(-1); --i)
  113. {
  114. const uint32_t lhsWord = lhs.data()[i];
  115. const uint32_t rhsWord = rhs.data()[i];
  116. if (lhsWord != rhsWord)
  117. {
  118. return lhsWord < rhsWord ? -1 : 1;
  119. }
  120. }
  121. return 0;
  122. }
  123. bool ShaderVariantKeyComparator::operator () (const ShaderVariantKey& lhs, const ShaderVariantKey& rhs) const
  124. {
  125. return ShaderVariantKeyComparator::Compare(lhs, rhs) < 0;
  126. }
  127. int ShaderVariantIdComparator::Compare(const ShaderVariantId& lhs, const ShaderVariantId& rhs)
  128. {
  129. auto compareMask = ShaderVariantKeyComparator::Compare(lhs.m_mask, rhs.m_mask);
  130. if (compareMask != 0)
  131. {
  132. return compareMask;
  133. }
  134. return ShaderVariantKeyComparator::Compare(lhs.m_key & lhs.m_mask, rhs.m_key & rhs.m_mask);
  135. }
  136. bool ShaderVariantIdComparator::operator () (const ShaderVariantId& lhs, const ShaderVariantId& rhs) const
  137. {
  138. return ShaderVariantIdComparator::Compare(lhs, rhs) < 0;
  139. }
  140. } // namespace RPI
  141. } // namespace AZ