VkCommandBufferFactory.h 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  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/Gr/Vulkan/VkFenceFactory.h>
  7. #include <AnKi/Gr/CommandBuffer.h>
  8. #include <AnKi/Gr/BackendCommon/MicroObjectRecycler.h>
  9. #include <AnKi/Gr/Vulkan/VkDescriptor.h>
  10. #include <AnKi/Util/List.h>
  11. namespace anki {
  12. // Forward
  13. class CommandBufferThreadAllocator;
  14. /// @addtogroup vulkan
  15. /// @{
  16. class MicroCommandBuffer
  17. {
  18. friend class CommandBufferThreadAllocator;
  19. public:
  20. MicroCommandBuffer(CommandBufferThreadAllocator* allocator)
  21. : m_threadAlloc(allocator)
  22. {
  23. ANKI_ASSERT(allocator);
  24. }
  25. ~MicroCommandBuffer();
  26. void retain() const
  27. {
  28. m_refcount.fetchAdd(1);
  29. }
  30. void release()
  31. {
  32. if(m_refcount.fetchSub(1) == 1)
  33. {
  34. releaseInternal();
  35. }
  36. }
  37. I32 getRefcount() const
  38. {
  39. return m_refcount.load();
  40. }
  41. VkCommandBuffer getHandle() const
  42. {
  43. ANKI_ASSERT(m_handle);
  44. return m_handle;
  45. }
  46. CommandBufferFlag getFlags() const
  47. {
  48. return m_flags;
  49. }
  50. GpuQueueType getVulkanQueueType() const
  51. {
  52. ANKI_ASSERT(m_queue != GpuQueueType::kCount);
  53. return m_queue;
  54. }
  55. DescriptorAllocator& getDSAllocator()
  56. {
  57. return m_dsAllocator;
  58. }
  59. private:
  60. VkCommandBuffer m_handle = {};
  61. DescriptorAllocator m_dsAllocator;
  62. CommandBufferThreadAllocator* m_threadAlloc;
  63. mutable Atomic<I32> m_refcount = {0};
  64. CommandBufferFlag m_flags = CommandBufferFlag::kNone;
  65. GpuQueueType m_queue = GpuQueueType::kCount;
  66. void releaseInternal();
  67. };
  68. /// Micro command buffer pointer.
  69. using MicroCommandBufferPtr = IntrusiveNoDelPtr<MicroCommandBuffer>;
  70. /// Per-thread command buffer allocator.
  71. class alignas(ANKI_CACHE_LINE_SIZE) CommandBufferThreadAllocator
  72. {
  73. friend class CommandBufferFactory;
  74. friend class MicroCommandBuffer;
  75. public:
  76. CommandBufferThreadAllocator(ThreadId tid)
  77. : m_tid(tid)
  78. {
  79. }
  80. ~CommandBufferThreadAllocator()
  81. {
  82. }
  83. Error init();
  84. void destroy();
  85. /// Request a new command buffer.
  86. Error newCommandBuffer(CommandBufferFlag cmdbFlags, MicroCommandBufferPtr& ptr);
  87. /// It will recycle it.
  88. void recycleCommandBuffer(MicroCommandBuffer* ptr);
  89. private:
  90. ThreadId m_tid;
  91. Array<VkCommandPool, U(GpuQueueType::kCount)> m_pools = {};
  92. #if ANKI_EXTRA_CHECKS
  93. Atomic<U32> m_createdCmdbs = {0};
  94. #endif
  95. Array2d<MicroObjectRecycler<MicroCommandBuffer>, 2, U(GpuQueueType::kCount)> m_recyclers;
  96. };
  97. /// Command bufffer object recycler.
  98. class CommandBufferFactory : public MakeSingleton<CommandBufferFactory>
  99. {
  100. friend class CommandBufferThreadAllocator;
  101. friend class MicroCommandBuffer;
  102. public:
  103. CommandBufferFactory() = default;
  104. CommandBufferFactory(const CommandBufferFactory&) = delete; // Non-copyable
  105. ~CommandBufferFactory()
  106. {
  107. destroy();
  108. }
  109. CommandBufferFactory& operator=(const CommandBufferFactory&) = delete; // Non-copyable
  110. /// Request a new command buffer.
  111. Error newCommandBuffer(ThreadId tid, CommandBufferFlag cmdbFlags, MicroCommandBufferPtr& ptr);
  112. private:
  113. GrDynamicArray<CommandBufferThreadAllocator*> m_threadAllocs;
  114. RWMutex m_threadAllocMtx;
  115. void destroy();
  116. };
  117. /// @}
  118. } // end namespace anki