FrameGpuAllocator.cpp 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  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. #include <AnKi/Gr/Utils/FrameGpuAllocator.h>
  6. namespace anki
  7. {
  8. void FrameGpuAllocator::init(PtrSize size, U32 alignment, PtrSize maxAllocationSize)
  9. {
  10. ANKI_ASSERT(!isCreated());
  11. ANKI_ASSERT(size > 0 && alignment > 0 && maxAllocationSize > 0);
  12. PtrSize perFrameSize = size / MAX_FRAMES_IN_FLIGHT;
  13. alignRoundDown(alignment, perFrameSize);
  14. m_size = perFrameSize * MAX_FRAMES_IN_FLIGHT;
  15. m_alignment = alignment;
  16. m_maxAllocationSize = maxAllocationSize;
  17. }
  18. PtrSize FrameGpuAllocator::endFrame()
  19. {
  20. ANKI_ASSERT(isCreated());
  21. PtrSize perFrameSize = m_size / MAX_FRAMES_IN_FLIGHT;
  22. PtrSize crntFrameStartOffset = perFrameSize * (m_frame % MAX_FRAMES_IN_FLIGHT);
  23. PtrSize nextFrameStartOffset = perFrameSize * ((m_frame + 1) % MAX_FRAMES_IN_FLIGHT);
  24. PtrSize crntOffset = m_offset.exchange(nextFrameStartOffset);
  25. ANKI_ASSERT(crntOffset >= crntFrameStartOffset);
  26. PtrSize bytesUsed = crntOffset - crntFrameStartOffset;
  27. PtrSize bytesNotUsed = (bytesUsed > perFrameSize) ? 0 : perFrameSize - bytesUsed;
  28. ++m_frame;
  29. return bytesNotUsed;
  30. }
  31. Error FrameGpuAllocator::allocate(PtrSize originalSize, PtrSize& outOffset)
  32. {
  33. ANKI_ASSERT(isCreated());
  34. ANKI_ASSERT(originalSize > 0);
  35. Error err = Error::NONE;
  36. // Align size
  37. PtrSize size = getAlignedRoundUp(m_alignment, originalSize);
  38. ANKI_ASSERT(size <= m_maxAllocationSize && "Too high!");
  39. PtrSize offset = m_offset.fetchAdd(size);
  40. PtrSize perFrameSize = m_size / MAX_FRAMES_IN_FLIGHT;
  41. PtrSize crntFrameStartOffset = perFrameSize * (m_frame % MAX_FRAMES_IN_FLIGHT);
  42. if(offset - crntFrameStartOffset + size <= perFrameSize)
  43. {
  44. ANKI_ASSERT(isAligned(m_alignment, offset));
  45. ANKI_ASSERT((offset + size) <= m_size);
  46. #if ANKI_ENABLE_TRACE
  47. m_lastAllocatedSize.store(size);
  48. #endif
  49. // Encode token
  50. outOffset = offset;
  51. ANKI_ASSERT(outOffset + originalSize <= m_size);
  52. }
  53. else
  54. {
  55. outOffset = MAX_PTR_SIZE;
  56. err = Error::OUT_OF_MEMORY;
  57. }
  58. return err;
  59. }
  60. #if ANKI_ENABLE_TRACE
  61. PtrSize FrameGpuAllocator::getUnallocatedMemorySize() const
  62. {
  63. PtrSize perFrameSize = m_size / MAX_FRAMES_IN_FLIGHT;
  64. PtrSize crntFrameStartOffset = perFrameSize * (m_frame % MAX_FRAMES_IN_FLIGHT);
  65. PtrSize usedSize = m_offset.getNonAtomically() - crntFrameStartOffset + m_lastAllocatedSize.getNonAtomically();
  66. PtrSize remaining = (perFrameSize >= usedSize) ? (perFrameSize - usedSize) : 0;
  67. return remaining;
  68. }
  69. #endif
  70. } // end namespace anki