TileAllocator.cpp 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. // Copyright (C) 2009-present, Panagiotis Christopoulos Charitos and contributors.
  2. // All rights reserved.
  3. // Code licensed under the BSD License.
  4. // http://www.anki3d.org/LICENSE
  5. #include <Tests/Framework/Framework.h>
  6. #include <AnKi/Renderer/Utils/TileAllocator.h>
  7. ANKI_TEST(Renderer, TileAllocator)
  8. {
  9. RendererMemoryPool::allocateSingleton(allocAligned, nullptr);
  10. {
  11. StackMemoryPool pool;
  12. pool.init(allocAligned, nullptr, 1024);
  13. TileAllocator::ArrayOfLightUuids kickedOutUuids(&pool);
  14. TileAllocator talloc;
  15. talloc.init(8, 8, 3, true);
  16. Array<U32, 4> viewport;
  17. TileAllocatorResult2 res;
  18. const U64 lightUuid = 1000;
  19. Timestamp crntTimestamp = 1;
  20. constexpr U kSmallTile = 0;
  21. constexpr U kMedTile = 1;
  22. constexpr U kBigTile = 2;
  23. // Allocate 1 med
  24. res = talloc.allocate(crntTimestamp, lightUuid + 1, kMedTile, viewport, kickedOutUuids);
  25. ANKI_TEST_EXPECT_EQ(res, TileAllocatorResult2::kAllocationSucceded);
  26. // Allocate 3 big
  27. res = talloc.allocate(crntTimestamp, lightUuid + 2, kBigTile, viewport, kickedOutUuids);
  28. ANKI_TEST_EXPECT_EQ(res, TileAllocatorResult2::kAllocationSucceded);
  29. ANKI_TEST_EXPECT_EQ(kickedOutUuids.getSize(), 0);
  30. res = talloc.allocate(crntTimestamp, lightUuid + 3, kBigTile, viewport, kickedOutUuids);
  31. ANKI_TEST_EXPECT_EQ(res, TileAllocatorResult2::kAllocationSucceded);
  32. ANKI_TEST_EXPECT_EQ(kickedOutUuids.getSize(), 0);
  33. res = talloc.allocate(crntTimestamp, lightUuid + 4, kBigTile, viewport, kickedOutUuids);
  34. ANKI_TEST_EXPECT_EQ(res, TileAllocatorResult2::kAllocationSucceded);
  35. ANKI_TEST_EXPECT_EQ(kickedOutUuids.getSize(), 0);
  36. // Fail to allocate 1 big
  37. res = talloc.allocate(crntTimestamp, lightUuid + 5, kBigTile, viewport, kickedOutUuids);
  38. ANKI_TEST_EXPECT_EQ(res, TileAllocatorResult2::kAllocationFailed);
  39. // Allocate 3 med
  40. res = talloc.allocate(crntTimestamp, lightUuid + 6, kMedTile, viewport, kickedOutUuids);
  41. ANKI_TEST_EXPECT_EQ(res, TileAllocatorResult2::kAllocationSucceded);
  42. ANKI_TEST_EXPECT_EQ(kickedOutUuids.getSize(), 0);
  43. res = talloc.allocate(crntTimestamp, lightUuid + 7, kMedTile, viewport, kickedOutUuids);
  44. ANKI_TEST_EXPECT_EQ(res, TileAllocatorResult2::kAllocationSucceded);
  45. ANKI_TEST_EXPECT_EQ(kickedOutUuids.getSize(), 0);
  46. res = talloc.allocate(crntTimestamp, lightUuid + 8, kMedTile, viewport, kickedOutUuids);
  47. ANKI_TEST_EXPECT_EQ(res, TileAllocatorResult2::kAllocationSucceded);
  48. ANKI_TEST_EXPECT_EQ(kickedOutUuids.getSize(), 0);
  49. // Fail to allocate a small
  50. res = talloc.allocate(crntTimestamp, lightUuid + 9, kSmallTile, viewport, kickedOutUuids);
  51. ANKI_TEST_EXPECT_EQ(res, TileAllocatorResult2::kAllocationFailed);
  52. ANKI_TEST_EXPECT_EQ(kickedOutUuids.getSize(), 0);
  53. // New frame
  54. ++crntTimestamp;
  55. // Allocate the same 3 big again
  56. res = talloc.allocate(crntTimestamp, lightUuid + 2, kBigTile, viewport, kickedOutUuids);
  57. ANKI_TEST_EXPECT_EQ(res, TileAllocatorResult2::kAllocationSucceded | TileAllocatorResult2::kTileCached);
  58. ANKI_TEST_EXPECT_EQ(kickedOutUuids.getSize(), 0);
  59. res = talloc.allocate(crntTimestamp, lightUuid + 3, kBigTile, viewport, kickedOutUuids);
  60. ANKI_TEST_EXPECT_EQ(res, TileAllocatorResult2::kAllocationSucceded | TileAllocatorResult2::kTileCached);
  61. ANKI_TEST_EXPECT_EQ(kickedOutUuids.getSize(), 0);
  62. res = talloc.allocate(crntTimestamp, lightUuid + 4, kBigTile, viewport, kickedOutUuids);
  63. ANKI_TEST_EXPECT_EQ(res, TileAllocatorResult2::kAllocationSucceded | TileAllocatorResult2::kTileCached);
  64. ANKI_TEST_EXPECT_EQ(kickedOutUuids.getSize(), 0);
  65. // New frame
  66. ++crntTimestamp;
  67. // Allocate 16 small
  68. TileAllocator::ArrayOfLightUuids allKicked(&pool);
  69. for(U i = 0; i < 16; ++i)
  70. {
  71. res = talloc.allocate(crntTimestamp, lightUuid + 10 + i, kSmallTile, viewport, kickedOutUuids);
  72. ANKI_TEST_EXPECT_EQ(res, TileAllocatorResult2::kAllocationSucceded);
  73. for(U64 uuid : kickedOutUuids)
  74. {
  75. allKicked.emplaceBack(uuid);
  76. }
  77. }
  78. // Check those that are kicked
  79. ANKI_TEST_EXPECT_EQ(allKicked.getSize(), 4);
  80. for(U64 uuid = lightUuid + 1; uuid <= lightUuid + 9; ++uuid)
  81. {
  82. auto it = std::find(allKicked.getBegin(), allKicked.getEnd(), uuid);
  83. if(uuid == lightUuid + 5 || uuid == lightUuid + 9)
  84. {
  85. // Allocation failures, skip
  86. }
  87. else if(uuid >= lightUuid + 2 && uuid <= lightUuid + 4)
  88. {
  89. // It's the big tiles, shouldn't have been kicked
  90. ANKI_TEST_EXPECT_EQ(it, allKicked.getEnd());
  91. }
  92. else
  93. {
  94. // Tiles from the 1st frame, should have been kicked all
  95. ANKI_TEST_EXPECT_NEQ(it, allKicked.getEnd());
  96. }
  97. }
  98. }
  99. RendererMemoryPool::freeSingleton();
  100. }