RebarTransientMemoryPool.h 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  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/Util/CVarSet.h>
  7. #include <AnKi/Core/StatsSet.h>
  8. #include <AnKi/Gr/Buffer.h>
  9. #include <AnKi/Gr/GrManager.h>
  10. namespace anki {
  11. /// @addtogroup gpu_memory
  12. /// @{
  13. ANKI_CVAR(NumericCVar<PtrSize>, Core, RebarGpuMemorySize, 24_MB, 1_MB, 1_GB, "ReBAR: always mapped GPU memory")
  14. /// Manages staging GPU memory.
  15. class RebarTransientMemoryPool : public MakeSingleton<RebarTransientMemoryPool>
  16. {
  17. template<typename>
  18. friend class MakeSingleton;
  19. public:
  20. RebarTransientMemoryPool(const RebarTransientMemoryPool&) = delete; // Non-copyable
  21. RebarTransientMemoryPool& operator=(const RebarTransientMemoryPool&) = delete; // Non-copyable
  22. void init();
  23. void endFrame();
  24. /// Allocate staging memory for various operations. The memory will be reclaimed at the begining of the N-(kMaxFramesInFlight-1) frame.
  25. template<typename T>
  26. BufferView allocate(PtrSize size, U32 alignment, T*& mappedMem)
  27. {
  28. void* mem;
  29. const BufferView out = allocateInternal(size, alignment, mem);
  30. mappedMem = static_cast<T*>(mem);
  31. return out;
  32. }
  33. /// @copydoc allocate
  34. template<typename T>
  35. BufferView allocateConstantBuffer(T*& mappedMem)
  36. {
  37. return allocate(sizeof(T), GrManager::getSingleton().getDeviceCapabilities().m_constantBufferBindOffsetAlignment, mappedMem);
  38. }
  39. /// @copydoc allocate
  40. template<typename T>
  41. BufferView allocateStructuredBuffer(U32 count, WeakArray<T>& arr)
  42. {
  43. T* mem;
  44. const U32 alignment = (m_structuredBufferAlignment == kMaxU32) ? sizeof(T) : m_structuredBufferAlignment;
  45. const BufferView out = allocate(count * sizeof(T), alignment, mem);
  46. arr = {mem, count};
  47. return out;
  48. }
  49. /// @copydoc allocate
  50. template<typename T>
  51. BufferView allocateCopyBuffer(U32 count, WeakArray<T>& arr)
  52. {
  53. T* mem;
  54. const U32 alignment = sizeof(U32);
  55. const BufferView out = allocate(sizeof(T) * count, alignment, mem);
  56. arr = {mem, count};
  57. return out;
  58. }
  59. ANKI_PURE Buffer& getBuffer() const
  60. {
  61. return *m_buffer;
  62. }
  63. U8* getBufferMappedAddress()
  64. {
  65. return m_mappedMem;
  66. }
  67. private:
  68. BufferPtr m_buffer;
  69. U8* m_mappedMem = nullptr; ///< Cache it.
  70. PtrSize m_bufferSize = 0; ///< Cache it.
  71. Atomic<PtrSize> m_offset = {0};
  72. PtrSize m_previousFrameEndOffset = 0;
  73. U32 m_structuredBufferAlignment = kMaxU32;
  74. RebarTransientMemoryPool() = default;
  75. ~RebarTransientMemoryPool();
  76. BufferView allocateInternal(PtrSize size, U32 alignment, void*& mappedMem);
  77. };
  78. /// @}
  79. } // end namespace anki