FrameGpuAllocator.cpp 2.5 KB

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