SkinnedMeshDispatchItemTests.cpp 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  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 <SkinnedMesh/SkinnedMeshDispatchItem.h>
  9. #include <AzTest/AzTest.h>
  10. #include <AzCore/UnitTest/UnitTest.h>
  11. namespace UnitTest
  12. {
  13. using namespace AZ;
  14. using namespace AZ::Render;
  15. TEST(SkinnedMeshDispatchItemTest, CalculateSkinnedMeshTotalThreadsPerDimension_TotalThreadsLessThanPerDimensionMax_AllThreadsInXDimension)
  16. {
  17. uint32_t maxThreadsPerDimension = static_cast<uint32_t>(std::numeric_limits<uint16_t>::max());
  18. uint32_t xThreads = 0;
  19. uint32_t yThreads = 0;
  20. // Test minimum threads for one dimension
  21. uint32_t vertexCount = 1;
  22. CalculateSkinnedMeshTotalThreadsPerDimension(vertexCount, xThreads, yThreads);
  23. EXPECT_EQ(xThreads, vertexCount);
  24. EXPECT_EQ(yThreads, 1);
  25. // Test maximum threads for one dimension
  26. vertexCount = maxThreadsPerDimension;
  27. CalculateSkinnedMeshTotalThreadsPerDimension(vertexCount, xThreads, yThreads);
  28. EXPECT_EQ(xThreads, vertexCount);
  29. EXPECT_EQ(yThreads, 1);
  30. }
  31. TEST(SkinnedMeshDispatchItemTest, CalculateSkinnedMeshTotalThreadsPerDimension_TotalThreadsEvenlyDivisibleByYThreads_XYProductEqualsTotalVertexCount)
  32. {
  33. uint32_t maxThreadsPerDimension = static_cast<uint32_t>(std::numeric_limits<uint16_t>::max());
  34. uint32_t xThreads = 0;
  35. uint32_t yThreads = 0;
  36. // Test for one vertex more than the max that can fit in the x dimension
  37. uint32_t vertexCount = maxThreadsPerDimension + 1;
  38. CalculateSkinnedMeshTotalThreadsPerDimension(vertexCount, xThreads, yThreads);
  39. EXPECT_EQ(xThreads, vertexCount / 2);
  40. EXPECT_EQ(yThreads, 2);
  41. EXPECT_EQ(xThreads * yThreads, vertexCount);
  42. // Test for two vertices less than the max that can fit with two y threads
  43. vertexCount = maxThreadsPerDimension * 2 - 2;
  44. CalculateSkinnedMeshTotalThreadsPerDimension(vertexCount, xThreads, yThreads);
  45. EXPECT_EQ(xThreads, vertexCount / 2);
  46. EXPECT_EQ(yThreads, 2);
  47. EXPECT_EQ(xThreads * yThreads, vertexCount);
  48. // Test for the max number of vertices that can fit with two y threads
  49. vertexCount = maxThreadsPerDimension * 2;
  50. CalculateSkinnedMeshTotalThreadsPerDimension(vertexCount, xThreads, yThreads);
  51. EXPECT_EQ(xThreads, vertexCount / 2);
  52. EXPECT_EQ(yThreads, 2);
  53. EXPECT_EQ(xThreads * yThreads, vertexCount);
  54. // Test for three vertices more than the max that can fit with two y threads
  55. vertexCount = maxThreadsPerDimension * 2 + 3;
  56. CalculateSkinnedMeshTotalThreadsPerDimension(vertexCount, xThreads, yThreads);
  57. EXPECT_EQ(xThreads, vertexCount / 3);
  58. EXPECT_EQ(yThreads, 3);
  59. EXPECT_EQ(xThreads * yThreads, vertexCount);
  60. // Test for three vertices less than the max that can fit with two y threads
  61. vertexCount = maxThreadsPerDimension * 3 - 3;
  62. CalculateSkinnedMeshTotalThreadsPerDimension(vertexCount, xThreads, yThreads);
  63. EXPECT_EQ(xThreads, vertexCount / 3);
  64. EXPECT_EQ(yThreads, 3);
  65. EXPECT_EQ(xThreads * yThreads, vertexCount);
  66. // Test for one fewer dimension than the max
  67. vertexCount = maxThreadsPerDimension * (maxThreadsPerDimension - 1);
  68. CalculateSkinnedMeshTotalThreadsPerDimension(vertexCount, xThreads, yThreads);
  69. EXPECT_EQ(xThreads, maxThreadsPerDimension);
  70. EXPECT_EQ(yThreads, maxThreadsPerDimension - 1);
  71. EXPECT_EQ(static_cast<uint32_t>(xThreads) * static_cast<uint32_t>(yThreads), vertexCount);
  72. // Test for maximum supported vertex count in each dimension
  73. vertexCount = maxThreadsPerDimension * maxThreadsPerDimension;
  74. CalculateSkinnedMeshTotalThreadsPerDimension(vertexCount, xThreads, yThreads);
  75. EXPECT_EQ(xThreads, maxThreadsPerDimension);
  76. EXPECT_EQ(yThreads, maxThreadsPerDimension);
  77. EXPECT_EQ(static_cast<uint32_t>(xThreads) * static_cast<uint32_t>(yThreads), vertexCount);
  78. }
  79. TEST(SkinnedMeshDispatchItemTest, CalculateSkinnedMeshTotalThreadsPerDimension_TotalThreadsNotEvenlyDivisibleByYThreads_ExtraXThreadAndTotalThreadsExceedsVertexCount)
  80. {
  81. uint32_t maxThreadsPerDimension = static_cast<uint32_t>(std::numeric_limits<uint16_t>::max());
  82. uint32_t xThreads = 0;
  83. uint32_t yThreads = 0;
  84. // Test for two vertices more than the max that can fit in the x dimension
  85. uint32_t vertexCount = maxThreadsPerDimension + 2;
  86. CalculateSkinnedMeshTotalThreadsPerDimension(vertexCount, xThreads, yThreads);
  87. EXPECT_EQ(xThreads, vertexCount / 2 + 1);
  88. EXPECT_EQ(yThreads, 2);
  89. EXPECT_EQ(xThreads * yThreads, vertexCount + 1);
  90. // Test for one vertex less than the max that can fit with two y threads
  91. vertexCount = maxThreadsPerDimension * 2 - 1;
  92. CalculateSkinnedMeshTotalThreadsPerDimension(vertexCount, xThreads, yThreads);
  93. EXPECT_EQ(xThreads, vertexCount / 2 + 1);
  94. EXPECT_EQ(yThreads, 2);
  95. EXPECT_EQ(xThreads * yThreads, vertexCount + 1);
  96. // Test for one vertex more than the max that can fit with two y threads
  97. vertexCount = maxThreadsPerDimension * 2 + 1;
  98. CalculateSkinnedMeshTotalThreadsPerDimension(vertexCount, xThreads, yThreads);
  99. EXPECT_EQ(xThreads, vertexCount / 3 + 1);
  100. EXPECT_EQ(yThreads, 3);
  101. EXPECT_EQ(xThreads * yThreads, vertexCount + 2);
  102. // Test for two vertices more than the max that can fit with two y threads
  103. vertexCount = maxThreadsPerDimension * 2 + 2;
  104. CalculateSkinnedMeshTotalThreadsPerDimension(vertexCount, xThreads, yThreads);
  105. EXPECT_EQ(xThreads, vertexCount / 3 + 1);
  106. EXPECT_EQ(yThreads, 3);
  107. EXPECT_EQ(xThreads * yThreads, vertexCount + 1);
  108. // Test for two vertices less than the max that can fit with three y threads
  109. vertexCount = maxThreadsPerDimension * 3 - 2;
  110. CalculateSkinnedMeshTotalThreadsPerDimension(vertexCount, xThreads, yThreads);
  111. EXPECT_EQ(xThreads, vertexCount / 3 + 1);
  112. EXPECT_EQ(yThreads, 3);
  113. EXPECT_EQ(xThreads * yThreads, vertexCount + 2);
  114. // Test for one vertex less than the max that can fit with three y threads
  115. vertexCount = maxThreadsPerDimension * 3 - 1;
  116. CalculateSkinnedMeshTotalThreadsPerDimension(vertexCount, xThreads, yThreads);
  117. EXPECT_EQ(xThreads, vertexCount / 3 + 1);
  118. EXPECT_EQ(yThreads, 3);
  119. EXPECT_EQ(xThreads * yThreads, vertexCount + 1);
  120. // Test for the fewest number of vertices that would still max out each dimension
  121. vertexCount = maxThreadsPerDimension * (maxThreadsPerDimension - 1) + 1;
  122. CalculateSkinnedMeshTotalThreadsPerDimension(vertexCount, xThreads, yThreads);
  123. EXPECT_EQ(xThreads, maxThreadsPerDimension);
  124. EXPECT_EQ(yThreads, maxThreadsPerDimension);
  125. EXPECT_EQ(static_cast<uint32_t>(xThreads) * static_cast<uint32_t>(yThreads), vertexCount + (maxThreadsPerDimension - 1));
  126. // Test for one vertex less than the maximum supported vertex count
  127. vertexCount = maxThreadsPerDimension * maxThreadsPerDimension - 1;
  128. CalculateSkinnedMeshTotalThreadsPerDimension(vertexCount, xThreads, yThreads);
  129. EXPECT_EQ(xThreads, maxThreadsPerDimension);
  130. EXPECT_EQ(yThreads, maxThreadsPerDimension);
  131. EXPECT_EQ(static_cast<uint32_t>(xThreads) * static_cast<uint32_t>(yThreads), vertexCount + 1);
  132. }
  133. TEST(SkinnedMeshDispatchItemTest, CalculateSkinnedMeshTotalThreadsPerDimension_VertexCountExceedsMaxSupported_Error)
  134. {
  135. uint32_t maxThreadsPerDimension = static_cast<uint32_t>(std::numeric_limits<uint16_t>::max());
  136. uint32_t xThreads = 0;
  137. uint32_t yThreads = 0;
  138. // Test beyond maximum supported vertex count
  139. uint32_t vertexCount = static_cast<uint32_t>(std::numeric_limits<uint32_t>::max());
  140. AZ_TEST_START_ASSERTTEST;
  141. CalculateSkinnedMeshTotalThreadsPerDimension(vertexCount, xThreads, yThreads);
  142. AZ_TEST_STOP_ASSERTTEST(1);
  143. EXPECT_EQ(xThreads, maxThreadsPerDimension);
  144. EXPECT_EQ(yThreads, maxThreadsPerDimension);
  145. EXPECT_NE(static_cast<uint32_t>(xThreads) * static_cast<uint32_t>(yThreads), vertexCount);
  146. }
  147. TEST(SkinnedMeshDispatchItemTest, CalculateSkinnedMeshTotalThreadsPerDimension_VertexCountIsZero_Error)
  148. {
  149. uint32_t xThreads = 0;
  150. uint32_t yThreads = 0;
  151. // Test zero vertex count
  152. uint32_t vertexCount = 0;
  153. AZ_TEST_START_ASSERTTEST;
  154. CalculateSkinnedMeshTotalThreadsPerDimension(vertexCount, xThreads, yThreads);
  155. AZ_TEST_STOP_ASSERTTEST(1);
  156. EXPECT_EQ(xThreads, 0);
  157. EXPECT_EQ(yThreads, 0);
  158. }
  159. } // namespace UnitTest