MeshInstanceManagerTests.cpp 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  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 <Mesh/MeshInstanceManager.h>
  9. #include <AzCore/UnitTest/TestTypes.h>
  10. namespace
  11. {
  12. }
  13. namespace UnitTest
  14. {
  15. using namespace AZ;
  16. using namespace AZ::Render;
  17. constexpr size_t keyCount = 4;
  18. AZ::Data::InstanceId modelIdA = AZ::Data::InstanceId::CreateFromAssetId({ AZ::Uuid::CreateRandom(), 0 });
  19. AZ::Data::InstanceId modelIdB = AZ::Data::InstanceId::CreateFromAssetId({ AZ::Uuid::CreateRandom(), 0 });
  20. uint32_t testLodIndex = 0;
  21. uint32_t testMeshIndex = 0;
  22. RHI::DrawItemSortKey testSortKey = 0;
  23. AZ::Data::InstanceId materialIdA = AZ::Data::InstanceId::CreateFromAssetId({ AZ::Uuid::CreateRandom(), 0 });
  24. AZ::Data::InstanceId materialIdB = AZ::Data::InstanceId::CreateFromAssetId({ AZ::Uuid::CreateRandom(), 0 });
  25. class MeshInstanceManagerTestFixture
  26. : public LeakDetectionFixture
  27. {
  28. void SetUp() override
  29. {
  30. // Add the initial instances
  31. for (size_t i = 0; i < m_uniqueKeys.size(); ++i)
  32. {
  33. m_indices[i] = m_meshInstanceManager.AddInstance(m_uniqueKeys[i]);
  34. }
  35. }
  36. public:
  37. MeshInstanceManager m_meshInstanceManager;
  38. AZStd::array<MeshInstanceGroupKey, keyCount> m_uniqueKeys{
  39. MeshInstanceGroupKey{ modelIdA, testLodIndex, testMeshIndex, materialIdA, Uuid::CreateNull(), testSortKey },
  40. MeshInstanceGroupKey{ modelIdA, testLodIndex, testMeshIndex, materialIdB, Uuid::CreateNull(), testSortKey },
  41. MeshInstanceGroupKey{ modelIdB, testLodIndex, testMeshIndex, materialIdA, Uuid::CreateNull(), testSortKey },
  42. MeshInstanceGroupKey{ modelIdB, testLodIndex, testMeshIndex, materialIdB, Uuid::CreateNull(), testSortKey }
  43. };
  44. AZStd::array<MeshInstanceManager::InsertResult, keyCount> m_indices{};
  45. };
  46. TEST_F(MeshInstanceManagerTestFixture, AddInstance)
  47. {
  48. // Each key was unique, so each index should also be unique
  49. for (size_t i = 0; i < m_indices.size(); ++i)
  50. {
  51. for (size_t j = i + 1; j < m_indices.size(); ++j)
  52. {
  53. EXPECT_NE(m_indices[i].m_handle, m_indices[j].m_handle);
  54. }
  55. // None of these have been intiailized before, so they should not all have an instance count of 1 after adding
  56. EXPECT_EQ(m_indices[i].m_instanceCount, 1);
  57. }
  58. }
  59. TEST_F(MeshInstanceManagerTestFixture, RemoveInstanceByKey)
  60. {
  61. // Remove all of the entries
  62. for (size_t i = 0; i < m_uniqueKeys.size(); ++i)
  63. {
  64. m_meshInstanceManager.RemoveInstance(m_uniqueKeys[i]);
  65. }
  66. // All objects were removed, the size of the data vector should be 0
  67. EXPECT_EQ(m_meshInstanceManager.GetInstanceGroupCount(), 0);
  68. }
  69. TEST_F(MeshInstanceManagerTestFixture, RemoveInstanceByIndex)
  70. {
  71. // Remove all of the entries
  72. for (size_t i = 0; i < m_indices.size(); ++i)
  73. {
  74. m_meshInstanceManager.RemoveInstance(m_indices[i].m_handle);
  75. }
  76. // All objects were removed, the size of the data vector should be 0
  77. EXPECT_EQ(m_meshInstanceManager.GetInstanceGroupCount(), 0);
  78. }
  79. TEST_F(MeshInstanceManagerTestFixture, IncreaseRefCount)
  80. {
  81. // Increase the refcount of one of the keys
  82. size_t refCountIncreaseIndex = 2;
  83. MeshInstanceManager::InsertResult instanceIndex = m_meshInstanceManager.AddInstance(m_uniqueKeys[refCountIncreaseIndex]);
  84. // We should get back the same instace index that was given originally
  85. EXPECT_EQ(instanceIndex.m_handle, m_indices[refCountIncreaseIndex].m_handle);
  86. // It was not inserted, since it already existed
  87. EXPECT_GT(instanceIndex.m_instanceCount, 1);
  88. // Remove all of the entries
  89. for (size_t i = 0; i < m_uniqueKeys.size(); ++i)
  90. {
  91. m_meshInstanceManager.RemoveInstance(m_uniqueKeys[i]);
  92. }
  93. // The entry at refCountIncreaseIndex should still exist. The rest should not.
  94. // Try adding them again to see if they still exist
  95. for (size_t i = 0; i < m_indices.size(); ++i)
  96. {
  97. MeshInstanceManager::InsertResult existenceCheck = m_meshInstanceManager.AddInstance(m_uniqueKeys[i]);
  98. m_meshInstanceManager.RemoveInstance(m_uniqueKeys[i]);
  99. if (i == refCountIncreaseIndex)
  100. {
  101. // Expect that it already existed
  102. EXPECT_GT(existenceCheck.m_instanceCount, 1);
  103. }
  104. else
  105. {
  106. // Expect that it was inserted
  107. EXPECT_EQ(existenceCheck.m_instanceCount, 1);
  108. }
  109. }
  110. // If we remove the entry one more time, it should no longer exist
  111. m_meshInstanceManager.RemoveInstance(m_uniqueKeys[refCountIncreaseIndex]);
  112. // Check that it was previously removed by adding it again and verifying the instance count
  113. MeshInstanceManager::InsertResult existenceCheck = m_meshInstanceManager.AddInstance(m_uniqueKeys[refCountIncreaseIndex]);
  114. EXPECT_EQ(existenceCheck.m_instanceCount, 1);
  115. // You should be able to remove it again
  116. m_meshInstanceManager.RemoveInstance(m_uniqueKeys[refCountIncreaseIndex]);
  117. // It should error if you try to remove it again, since it no longer exits
  118. AZ_TEST_START_TRACE_SUPPRESSION;
  119. m_meshInstanceManager.RemoveInstance(m_uniqueKeys[refCountIncreaseIndex]);
  120. AZ_TEST_STOP_TRACE_SUPPRESSION(1);
  121. }
  122. } // namespace UnitTest