BsVulkanCommandBuffer.h 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. #pragma once
  4. #include "BsVulkanPrerequisites.h"
  5. #include "BsCommandBuffer.h"
  6. #include "BsVulkanRenderAPI.h"
  7. #include "BsVulkanResource.h"
  8. namespace BansheeEngine
  9. {
  10. /** @addtogroup Vulkan
  11. * @{
  12. */
  13. class VulkanCmdBuffer;
  14. #define BS_MAX_VULKAN_CB_PER_QUEUE_FAMILY BS_MAX_QUEUES_PER_TYPE * 32
  15. /** Pool that allocates and distributes Vulkan command buffers. */
  16. class VulkanCmdBufferPool
  17. {
  18. public:
  19. VulkanCmdBufferPool(VulkanDevice& device);
  20. ~VulkanCmdBufferPool();
  21. /**
  22. * Attempts to find a free command buffer, or creates a new one if not found. Caller must guarantee the provided
  23. * queue family is valid.
  24. */
  25. VulkanCmdBuffer* getBuffer(UINT32 queueFamily, bool secondary);
  26. private:
  27. /** Command buffer pool and related information. */
  28. struct PoolInfo
  29. {
  30. VkCommandPool pool = VK_NULL_HANDLE;
  31. VulkanCmdBuffer* buffers[BS_MAX_VULKAN_CB_PER_QUEUE_FAMILY];
  32. UINT32 queueFamily = -1;
  33. };
  34. /** Creates a new command buffer. */
  35. VulkanCmdBuffer* createBuffer(UINT32 queueFamily, bool secondary);
  36. VulkanDevice& mDevice;
  37. UnorderedMap<UINT32, PoolInfo> mPools;
  38. UINT32 mNextId;
  39. };
  40. /**
  41. * Represents a direct wrapper over an internal Vulkan command buffer. This is unlike VulkanCommandBuffer which is a
  42. * higher level class, and it allows for re-use by internally using multiple low-level command buffers.
  43. */
  44. class VulkanCmdBuffer
  45. {
  46. /** Possible states a command buffer can be in. */
  47. enum class State
  48. {
  49. /** Buffer is ready to be re-used. */
  50. Ready,
  51. /** Buffer is currently recording commands, but isn't recording a render pass. */
  52. Recording,
  53. /** Buffer is currently recording render pass commands. */
  54. RecordingRenderPass,
  55. /** Buffer is done recording but hasn't been submitted. */
  56. RecordingDone,
  57. /** Buffer is done recording and is currently submitted on a queue. */
  58. Submitted
  59. };
  60. public:
  61. VulkanCmdBuffer(VulkanDevice& device, UINT32 id, VkCommandPool pool, UINT32 queueFamily, bool secondary);
  62. ~VulkanCmdBuffer();
  63. /** Returns an unique identifier of this command buffer. */
  64. UINT32 getId() const { return mId; }
  65. /** Returns the index of the queue family this command buffer is executing on. */
  66. UINT32 getQueueFamily() const { return mQueueFamily; }
  67. /** Returns the index of the device this command buffer will execute on. */
  68. UINT32 getDeviceIdx() const;
  69. /** Makes the command buffer ready to start recording commands. */
  70. void begin();
  71. /** Ends command buffer command recording (as started with begin()). */
  72. void end();
  73. /** Begins render pass recording. Must be called within begin()/end() calls. */
  74. void beginRenderPass();
  75. /** Ends render pass recording (as started with beginRenderPass(). */
  76. void endRenderPass();
  77. /**
  78. * Submits the command buffer for execution.
  79. *
  80. * @param[in] queue Queue to submit the command buffer on.
  81. * @param[in] queueIdx Index of the queue the command buffer was submitted on. Note that this may be different
  82. * from the actual VulkanQueue index since multiple command buffer queue indices can map
  83. * to the same queue.
  84. * @param[in] syncMask Mask that controls which other command buffers does this command buffer depend upon
  85. * (if any). See description of @p syncMask parameter in RenderAPICore::executeCommands().
  86. */
  87. void submit(VulkanQueue* queue, UINT32 queueIdx, UINT32 syncMask);
  88. /** Returns the handle to the internal Vulkan command buffer wrapped by this object. */
  89. VkCommandBuffer getHandle() const { return mCmdBuffer; }
  90. /** Returns a fence that can be used for tracking when the command buffer is done executing. */
  91. VkFence getFence() const { return mFence; }
  92. /**
  93. * Returns a semaphore that may be used for synchronizing execution between command buffers executing on different
  94. * queues.
  95. */
  96. VkSemaphore getSemaphore() const { return mSemaphore; }
  97. /** Returns true if the command buffer is currently being processed by the device. */
  98. bool isSubmitted() const { return mState == State::Submitted; }
  99. /** Returns true if the command buffer is ready to be submitted to a queue. */
  100. bool isReadyForSubmit() const { return mState == State::RecordingDone; }
  101. /** Returns a counter that gets incremented whenever the command buffer is done executing. */
  102. UINT32 getFenceCounter() const { return mFenceCounter; }
  103. /** Checks the internal fence and changes command buffer state if done executing. */
  104. void refreshFenceStatus();
  105. /**
  106. * Lets the command buffer know that the provided resource has been queued on it, and will be used by the
  107. * device when the command buffer is submitted.
  108. */
  109. void registerResource(VulkanResource* res, VulkanUseFlags flags);
  110. /**
  111. * Lets the command buffer know that the provided GPU params object has been bound to it, and its resources
  112. * and descriptors will be used by the device when the command buffer is submitted.
  113. */
  114. void registerGpuParams(const SPtr<VulkanGpuParams>& params);
  115. private:
  116. friend class VulkanCmdBufferPool;
  117. friend class VulkanCommandBuffer;
  118. /** Contains information about a single Vulkan resource bound/used on this command buffer. */
  119. struct ResourceUseHandle
  120. {
  121. bool used;
  122. VulkanUseFlags flags;
  123. };
  124. UINT32 mId;
  125. UINT32 mQueueFamily;
  126. State mState;
  127. VulkanDevice& mDevice;
  128. VkCommandPool mPool;
  129. VkCommandBuffer mCmdBuffer;
  130. VkFence mFence;
  131. VkSemaphore mSemaphore;
  132. UINT32 mFenceCounter;
  133. UnorderedMap<VulkanResource*, ResourceUseHandle> mResources;
  134. UnorderedSet<SPtr<VulkanGpuParams>> mBoundParams;
  135. VkSemaphore mSemaphoresTemp[BS_MAX_COMMAND_BUFFERS];
  136. UnorderedMap<UINT32, TransitionInfo> mTransitionInfoTemp;
  137. };
  138. /** CommandBuffer implementation for Vulkan. */
  139. class VulkanCommandBuffer : public CommandBuffer
  140. {
  141. public:
  142. /**
  143. * Submits the command buffer for execution.
  144. *
  145. * @param[in] syncMask Mask that controls which other command buffers does this command buffer depend upon
  146. * (if any). See description of @p syncMask parameter in RenderAPICore::executeCommands().
  147. */
  148. void submit(UINT32 syncMask);
  149. /**
  150. * Returns the internal command buffer.
  151. *
  152. * @note This buffer will change after a submit() call.
  153. */
  154. VulkanCmdBuffer* getInternal() const { return mBuffer; }
  155. private:
  156. friend class VulkanCommandBufferManager;
  157. VulkanCommandBuffer(VulkanDevice& device, GpuQueueType type, UINT32 deviceIdx, UINT32 queueIdx,
  158. bool secondary);
  159. /**
  160. * Tasks the command buffer to find a new internal command buffer. Call this after the command buffer has been
  161. * submitted to a queue (it's not allowed to be used until the queue is done with it).
  162. */
  163. void acquireNewBuffer();
  164. VulkanCmdBuffer* mBuffer;
  165. VulkanDevice& mDevice;
  166. VulkanQueue* mQueue;
  167. UINT32 mIdMask;
  168. VkSemaphore mSemaphoresTemp[BS_MAX_COMMAND_BUFFERS];
  169. UnorderedMap<UINT32, TransitionInfo> mTransitionInfoTemp;
  170. };
  171. /** @} */
  172. }