TileAllocator.h 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. // Copyright (C) 2009-2021, 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 TileAllocatorResult : U32
  12. {
  13. CACHED, ///< The tile is cached. No need to re-render it.
  14. ALLOCATION_FAILED, ///< No more available tiles.
  15. ALLOCATION_SUCCEEDED ///< Allocation succeded but the tile needs update.
  16. };
  17. /// Allocates tiles out of a tilemap suitable for shadow mapping.
  18. class TileAllocator
  19. {
  20. public:
  21. TileAllocator() = default;
  22. TileAllocator(const TileAllocator&) = delete; // Non-copyable
  23. ~TileAllocator();
  24. TileAllocator& operator=(const TileAllocator&) = delete; // Non-copyable
  25. /// Initialize the allocator.
  26. void init(HeapAllocator<U8> alloc, U32 tileCountX, U32 tileCountY, U32 lodCount, Bool enableCaching);
  27. /// Allocate some tiles.
  28. ANKI_USE_RESULT TileAllocatorResult allocate(Timestamp crntTimestamp, Timestamp lightTimestamp, U64 lightUuid,
  29. U32 lightFace, U32 drawcallCount, U32 lod,
  30. Array<U32, 4>& tileViewport);
  31. /// Remove an light from the cache.
  32. void invalidateCache(U64 lightUuid, U32 lightFace);
  33. private:
  34. class Tile;
  35. /// A HashMap key.
  36. class HashMapKey;
  37. HeapAllocator<U8> m_alloc;
  38. DynamicArray<Tile> m_allTiles;
  39. DynamicArray<U32> m_lodFirstTileIndex;
  40. HashMap<HashMapKey, U32> m_lightInfoToTileIdx;
  41. U16 m_tileCountX = 0; ///< Tile count for LOD 0
  42. U16 m_tileCountY = 0; ///< Tile count for LOD 0
  43. U8 m_lodCount = 0;
  44. Bool m_cachingEnabled = false;
  45. U32 translateTileIdx(U32 x, U32 y, U32 lod) const
  46. {
  47. const U32 lodWidth = m_tileCountX >> lod;
  48. const U32 idx = y * lodWidth + x + m_lodFirstTileIndex[lod];
  49. ANKI_ASSERT(idx < m_allTiles.getSize());
  50. return idx;
  51. }
  52. void updateSubTiles(const Tile& updateFrom);
  53. void updateSuperTiles(const Tile& updateFrom);
  54. /// Given a tile move the hierarchy up and down to update the hierarchy this tile belongs to.
  55. void updateTileHierarchy(const Tile& updateFrom)
  56. {
  57. updateSubTiles(updateFrom);
  58. updateSuperTiles(updateFrom);
  59. }
  60. /// Search for a tile recursively.
  61. Bool searchTileRecursively(U32 crntTileIdx, U32 crntTileLod, U32 allocationLod, Timestamp crntTimestamp,
  62. U32& emptyTileIdx, U32& toKickTileIdx, Timestamp& tileToKickMinTimestamp) const;
  63. Bool evaluateCandidate(U32 tileIdx, Timestamp crntTimestamp, U32& emptyTileIdx, U32& toKickTileIdx,
  64. Timestamp& tileToKickMinTimestamp) const;
  65. };
  66. /// @}
  67. } // end namespace anki