GpuSceneBuffer.h 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  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/Core/Common.h>
  7. #include <AnKi/Gr/Utils/SegregatedListsGpuMemoryPool.h>
  8. #include <AnKi/Resource/ShaderProgramResource.h>
  9. namespace anki {
  10. /// @addtogroup core
  11. /// @{
  12. /// @memberof GpuSceneBuffer
  13. class GpuSceneBufferAllocation
  14. {
  15. friend class GpuSceneBuffer;
  16. public:
  17. GpuSceneBufferAllocation() = default;
  18. GpuSceneBufferAllocation(const GpuSceneBufferAllocation&) = delete;
  19. GpuSceneBufferAllocation(GpuSceneBufferAllocation&& b)
  20. {
  21. *this = std::move(b);
  22. }
  23. ~GpuSceneBufferAllocation();
  24. GpuSceneBufferAllocation& operator=(const GpuSceneBufferAllocation&) = delete;
  25. GpuSceneBufferAllocation& operator=(GpuSceneBufferAllocation&& b)
  26. {
  27. ANKI_ASSERT(!isValid() && "Forgot to delete");
  28. m_token = b.m_token;
  29. b.m_token = {};
  30. return *this;
  31. }
  32. Bool isValid() const
  33. {
  34. return m_token.m_offset != kMaxPtrSize;
  35. }
  36. /// Get offset in the Unified Geometry Buffer buffer.
  37. U32 getOffset() const
  38. {
  39. ANKI_ASSERT(isValid());
  40. return U32(m_token.m_offset);
  41. }
  42. U32 getAllocatedSize() const
  43. {
  44. ANKI_ASSERT(isValid());
  45. return U32(m_token.m_size);
  46. }
  47. private:
  48. SegregatedListsGpuMemoryPoolToken m_token;
  49. };
  50. /// Memory pool for the GPU scene.
  51. class GpuSceneBuffer : public MakeSingleton<GpuSceneBuffer>
  52. {
  53. template<typename>
  54. friend class MakeSingleton;
  55. public:
  56. GpuSceneBuffer(const GpuSceneBuffer&) = delete; // Non-copyable
  57. GpuSceneBuffer& operator=(const GpuSceneBuffer&) = delete; // Non-copyable
  58. void init();
  59. GpuSceneBufferAllocation allocate(PtrSize size, U32 alignment)
  60. {
  61. GpuSceneBufferAllocation alloc;
  62. m_pool.allocate(size, alignment, alloc.m_token);
  63. return alloc;
  64. }
  65. template<typename T>
  66. GpuSceneBufferAllocation allocateStructuredBuffer(U32 count)
  67. {
  68. const U32 alignment = (GrManager::getSingleton().getDeviceCapabilities().m_structuredBufferNaturalAlignment)
  69. ? sizeof(T)
  70. : GrManager::getSingleton().getDeviceCapabilities().m_structuredBufferBindOffsetAlignment;
  71. GpuSceneBufferAllocation alloc;
  72. m_pool.allocate(count * sizeof(T), alignment, alloc.m_token);
  73. return alloc;
  74. }
  75. void deferredFree(GpuSceneBufferAllocation& alloc)
  76. {
  77. m_pool.deferredFree(alloc.m_token);
  78. }
  79. void endFrame()
  80. {
  81. m_pool.endFrame();
  82. #if ANKI_STATS_ENABLED
  83. updateStats();
  84. #endif
  85. }
  86. Buffer& getBuffer() const
  87. {
  88. return m_pool.getGpuBuffer();
  89. }
  90. BufferView getBufferView() const
  91. {
  92. return BufferView(&m_pool.getGpuBuffer());
  93. }
  94. private:
  95. SegregatedListsGpuMemoryPool m_pool;
  96. GpuSceneBuffer() = default;
  97. ~GpuSceneBuffer() = default;
  98. void updateStats() const;
  99. };
  100. inline GpuSceneBufferAllocation::~GpuSceneBufferAllocation()
  101. {
  102. GpuSceneBuffer::getSingleton().deferredFree(*this);
  103. }
  104. /// Creates the copy jobs that will patch the GPU Scene.
  105. class GpuSceneMicroPatcher : public MakeSingleton<GpuSceneMicroPatcher>
  106. {
  107. template<typename>
  108. friend class MakeSingleton;
  109. public:
  110. GpuSceneMicroPatcher(const GpuSceneMicroPatcher&) = delete;
  111. GpuSceneMicroPatcher& operator=(const GpuSceneMicroPatcher&) = delete;
  112. Error init();
  113. /// Copy data for the GPU scene to a staging buffer.
  114. /// @note It's thread-safe.
  115. void newCopy(StackMemoryPool& frameCpuPool, PtrSize gpuSceneDestOffset, PtrSize dataSize, const void* data);
  116. template<typename T>
  117. void newCopy(StackMemoryPool& frameCpuPool, PtrSize gpuSceneDestOffset, const T& value)
  118. {
  119. newCopy(frameCpuPool, gpuSceneDestOffset, sizeof(value), &value);
  120. }
  121. /// @see newCopy
  122. void newCopy(StackMemoryPool& frameCpuPool, const GpuSceneBufferAllocation& dest, PtrSize dataSize, const void* data)
  123. {
  124. ANKI_ASSERT(dataSize <= dest.getAllocatedSize());
  125. newCopy(frameCpuPool, dest.getOffset(), dataSize, data);
  126. }
  127. /// @see newCopy
  128. template<typename T>
  129. void newCopy(StackMemoryPool& frameCpuPool, const GpuSceneBufferAllocation& dest, const T& value)
  130. {
  131. ANKI_ASSERT(sizeof(value) <= dest.getAllocatedSize());
  132. newCopy(frameCpuPool, dest.getOffset(), sizeof(value), &value);
  133. }
  134. /// Check if there is a need to call patchGpuScene or if no copies are needed.
  135. /// @note Not thread-safe. Nothing else should be happening before calling it.
  136. Bool patchingIsNeeded() const
  137. {
  138. return m_crntFramePatchHeaders.getSize() > 0;
  139. }
  140. /// Copy the data to the GPU scene buffer.
  141. /// @note Not thread-safe. Nothing else should be happening before calling it.
  142. void patchGpuScene(CommandBuffer& cmdb);
  143. private:
  144. static constexpr U32 kDwordsPerPatch = 64;
  145. class PatchHeader;
  146. DynamicArray<PatchHeader, MemoryPoolPtrWrapper<StackMemoryPool>> m_crntFramePatchHeaders;
  147. DynamicArray<U32, MemoryPoolPtrWrapper<StackMemoryPool>> m_crntFramePatchData;
  148. Mutex m_mtx;
  149. ShaderProgramResourcePtr m_copyProgram;
  150. ShaderProgramPtr m_grProgram;
  151. GpuSceneMicroPatcher();
  152. ~GpuSceneMicroPatcher();
  153. };
  154. /// @}
  155. } // end namespace anki