TileAllocator.h 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  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. #pragma once
  6. #include <AnKi/Renderer/Common.h>
  7. namespace anki {
  8. /// @addtogroup renderer
  9. /// @{
  10. /// The result of a tile allocation.
  11. enum class TileAllocatorResult2 : U8
  12. {
  13. kAllocationFailed = 0,
  14. kAllocationSucceded = 1 << 0, ///< Allocation succedded.
  15. kTileCached = 1 << 1, ///< The tile was in the cache already. Goes only with kAllocationSucceded.
  16. };
  17. ANKI_ENUM_ALLOW_NUMERIC_OPERATIONS(TileAllocatorResult2)
  18. /// Allocates tiles out of a tilemap suitable for shadow mapping.
  19. class TileAllocator
  20. {
  21. public:
  22. using ArrayOfLightUuids = DynamicArray<U64, MemoryPoolPtrWrapper<StackMemoryPool>>;
  23. TileAllocator();
  24. TileAllocator(const TileAllocator&) = delete; // Non-copyable
  25. ~TileAllocator();
  26. TileAllocator& operator=(const TileAllocator&) = delete; // Non-copyable
  27. /// Initialize the allocator.
  28. /// @param tileCountX The size of the smallest tile (0 hierarchy level).
  29. void init(U32 tileCountX, U32 tileCountY, U32 hierarchyCount, Bool enableCaching);
  30. /// Allocate some tiles.
  31. /// @param hierarchy If it's 0 it chooses the smallest tile.
  32. [[nodiscard]] TileAllocatorResult2 allocate(Timestamp crntTimestamp, U64 lightUuid, U32 hierarchy, Array<U32, 4>& tileViewport,
  33. ArrayOfLightUuids& kickedOutLightUuids);
  34. /// Remove an light from the cache.
  35. void invalidateCache(U64 lightUuid);
  36. private:
  37. class Tile;
  38. RendererDynamicArray<Tile> m_allTiles;
  39. RendererDynamicArray<U32> m_firstTileIdxOfHierarchy;
  40. RendererHashMap<U64, U32> m_lightUuidToTileIdx;
  41. U16 m_tileCountX = 0; ///< Tile count for hierarchy 0
  42. U16 m_tileCountY = 0; ///< Tile count for hierarchy 0
  43. U8 m_hierarchyCount = 0;
  44. Bool m_cachingEnabled = false;
  45. U32 translateTileIdx(U32 x, U32 y, U32 hierarchy) const
  46. {
  47. const U32 hierarchyWidth = m_tileCountX >> hierarchy;
  48. const U32 idx = y * hierarchyWidth + x + m_firstTileIdxOfHierarchy[hierarchy];
  49. ANKI_ASSERT(idx < m_allTiles.getSize());
  50. return idx;
  51. }
  52. void updateSubTiles(const Tile& updateFrom, U64 crntLightUuid, ArrayOfLightUuids& kickedOutLights);
  53. void updateSuperTiles(const Tile& updateFrom, U64 crntLightUuid, ArrayOfLightUuids& kickedOutLights);
  54. /// Given a tile move the hierarchy up and down to update the hierarchy this tile belongs to.
  55. void updateTileHierarchy(const Tile& updateFrom, U64 crntLightUuid, ArrayOfLightUuids& kickedOutLights)
  56. {
  57. updateSubTiles(updateFrom, crntLightUuid, kickedOutLights);
  58. updateSuperTiles(updateFrom, crntLightUuid, kickedOutLights);
  59. }
  60. /// Search for a tile recursively.
  61. Bool searchTileRecursively(U32 crntTileIdx, U32 crntTileHierarchy, U32 allocationHierarchy, Timestamp crntTimestamp, U32& emptyTileIdx,
  62. U32& toKickTileIdx, Timestamp& tileToKickMinTimestamp) const;
  63. Bool evaluateCandidate(U32 tileIdx, Timestamp crntTimestamp, U32& emptyTileIdx, U32& toKickTileIdx, Timestamp& tileToKickMinTimestamp) const;
  64. };
  65. /// @}
  66. } // end namespace anki