GrVkCommandBuffer.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377
  1. /*
  2. * Copyright 2015 Google Inc.
  3. *
  4. * Use of this source code is governed by a BSD-style license that can be
  5. * found in the LICENSE file.
  6. */
  7. #ifndef GrVkCommandBuffer_DEFINED
  8. #define GrVkCommandBuffer_DEFINED
  9. #include "include/gpu/vk/GrVkTypes.h"
  10. #include "src/gpu/vk/GrVkGpu.h"
  11. #include "src/gpu/vk/GrVkResource.h"
  12. #include "src/gpu/vk/GrVkSemaphore.h"
  13. #include "src/gpu/vk/GrVkUtil.h"
  14. class GrVkBuffer;
  15. class GrVkFramebuffer;
  16. class GrVkIndexBuffer;
  17. class GrVkImage;
  18. class GrVkPipeline;
  19. class GrVkPipelineState;
  20. class GrVkRenderPass;
  21. class GrVkRenderTarget;
  22. class GrVkTransferBuffer;
  23. class GrVkVertexBuffer;
  24. class GrVkCommandBuffer : public GrVkResource {
  25. public:
  26. void invalidateState();
  27. ////////////////////////////////////////////////////////////////////////////
  28. // CommandBuffer commands
  29. ////////////////////////////////////////////////////////////////////////////
  30. enum BarrierType {
  31. kBufferMemory_BarrierType,
  32. kImageMemory_BarrierType
  33. };
  34. void pipelineBarrier(const GrVkGpu* gpu,
  35. const GrVkResource* resource,
  36. VkPipelineStageFlags srcStageMask,
  37. VkPipelineStageFlags dstStageMask,
  38. bool byRegion,
  39. BarrierType barrierType,
  40. void* barrier);
  41. void bindInputBuffer(GrVkGpu* gpu, uint32_t binding, const GrVkVertexBuffer* vbuffer);
  42. void bindIndexBuffer(GrVkGpu* gpu, const GrVkIndexBuffer* ibuffer);
  43. void bindPipeline(const GrVkGpu* gpu, const GrVkPipeline* pipeline);
  44. void bindDescriptorSets(const GrVkGpu* gpu,
  45. GrVkPipelineState*,
  46. GrVkPipelineLayout* layout,
  47. uint32_t firstSet,
  48. uint32_t setCount,
  49. const VkDescriptorSet* descriptorSets,
  50. uint32_t dynamicOffsetCount,
  51. const uint32_t* dynamicOffsets);
  52. void bindDescriptorSets(const GrVkGpu* gpu,
  53. const SkTArray<const GrVkRecycledResource*>&,
  54. const SkTArray<const GrVkResource*>&,
  55. GrVkPipelineLayout* layout,
  56. uint32_t firstSet,
  57. uint32_t setCount,
  58. const VkDescriptorSet* descriptorSets,
  59. uint32_t dynamicOffsetCount,
  60. const uint32_t* dynamicOffsets);
  61. GrVkCommandPool* commandPool() { return fCmdPool; }
  62. void setViewport(const GrVkGpu* gpu,
  63. uint32_t firstViewport,
  64. uint32_t viewportCount,
  65. const VkViewport* viewports);
  66. void setScissor(const GrVkGpu* gpu,
  67. uint32_t firstScissor,
  68. uint32_t scissorCount,
  69. const VkRect2D* scissors);
  70. void setBlendConstants(const GrVkGpu* gpu, const float blendConstants[4]);
  71. // Commands that only work inside of a render pass
  72. void clearAttachments(const GrVkGpu* gpu,
  73. int numAttachments,
  74. const VkClearAttachment* attachments,
  75. int numRects,
  76. const VkClearRect* clearRects);
  77. void drawIndexed(const GrVkGpu* gpu,
  78. uint32_t indexCount,
  79. uint32_t instanceCount,
  80. uint32_t firstIndex,
  81. int32_t vertexOffset,
  82. uint32_t firstInstance);
  83. void draw(const GrVkGpu* gpu,
  84. uint32_t vertexCount,
  85. uint32_t instanceCount,
  86. uint32_t firstVertex,
  87. uint32_t firstInstance);
  88. // Add ref-counted resource that will be tracked and released when this command buffer finishes
  89. // execution
  90. void addResource(const GrVkResource* resource) {
  91. resource->ref();
  92. resource->notifyAddedToCommandBuffer();
  93. fTrackedResources.append(1, &resource);
  94. }
  95. // Add ref-counted resource that will be tracked and released when this command buffer finishes
  96. // execution. When it is released, it will signal that the resource can be recycled for reuse.
  97. void addRecycledResource(const GrVkRecycledResource* resource) {
  98. resource->ref();
  99. resource->notifyAddedToCommandBuffer();
  100. fTrackedRecycledResources.append(1, &resource);
  101. }
  102. // Add ref-counted resource that will be tracked and released when this command buffer finishes
  103. // recording.
  104. void addRecordingResource(const GrVkResource* resource) {
  105. resource->ref();
  106. resource->notifyAddedToCommandBuffer();
  107. fTrackedRecordingResources.append(1, &resource);
  108. }
  109. void releaseResources(GrVkGpu* gpu);
  110. bool hasWork() const { return fHasWork; }
  111. protected:
  112. GrVkCommandBuffer(VkCommandBuffer cmdBuffer, GrVkCommandPool* cmdPool,
  113. const GrVkRenderPass* rp = nullptr)
  114. : fIsActive(false)
  115. , fActiveRenderPass(rp)
  116. , fCmdBuffer(cmdBuffer)
  117. , fCmdPool(cmdPool)
  118. , fNumResets(0) {
  119. fTrackedResources.setReserve(kInitialTrackedResourcesCount);
  120. fTrackedRecycledResources.setReserve(kInitialTrackedResourcesCount);
  121. fTrackedRecordingResources.setReserve(kInitialTrackedResourcesCount);
  122. this->invalidateState();
  123. }
  124. bool isWrapped() const {
  125. return fCmdPool == nullptr;
  126. }
  127. void addingWork(const GrVkGpu* gpu);
  128. void submitPipelineBarriers(const GrVkGpu* gpu);
  129. SkTDArray<const GrVkResource*> fTrackedResources;
  130. SkTDArray<const GrVkRecycledResource*> fTrackedRecycledResources;
  131. SkTDArray<const GrVkResource*> fTrackedRecordingResources;
  132. // Tracks whether we are in the middle of a command buffer begin/end calls and thus can add
  133. // new commands to the buffer;
  134. bool fIsActive;
  135. bool fHasWork = false;
  136. // Stores a pointer to the current active render pass (i.e. begin has been called but not
  137. // end). A nullptr means there is no active render pass. The GrVKCommandBuffer does not own
  138. // the render pass.
  139. const GrVkRenderPass* fActiveRenderPass;
  140. VkCommandBuffer fCmdBuffer;
  141. // Raw pointer, not refcounted. The command pool controls the command buffer's lifespan, so
  142. // it's guaranteed to outlive us.
  143. GrVkCommandPool* fCmdPool;
  144. private:
  145. static const int kInitialTrackedResourcesCount = 32;
  146. void freeGPUData(GrVkGpu* gpu) const final override;
  147. virtual void onFreeGPUData(GrVkGpu* gpu) const = 0;
  148. void abandonGPUData() const final override;
  149. virtual void onAbandonGPUData() const = 0;
  150. virtual void onReleaseResources(GrVkGpu* gpu) {}
  151. static constexpr uint32_t kMaxInputBuffers = 2;
  152. VkBuffer fBoundInputBuffers[kMaxInputBuffers];
  153. VkBuffer fBoundIndexBuffer;
  154. // When resetting the command buffer, we remove the tracked resources from their arrays, and
  155. // we prefer to not free all the memory every time so usually we just rewind. However, to avoid
  156. // all arrays growing to the max size, after so many resets we'll do a full reset of the tracked
  157. // resource arrays.
  158. static const int kNumRewindResetsBeforeFullReset = 8;
  159. int fNumResets;
  160. // Cached values used for dynamic state updates
  161. VkViewport fCachedViewport;
  162. VkRect2D fCachedScissor;
  163. float fCachedBlendConstant[4];
  164. #ifdef SK_DEBUG
  165. mutable bool fResourcesReleased = false;
  166. #endif
  167. // Tracking of memory barriers so that we can submit them all in a batch together.
  168. SkSTArray<4, VkBufferMemoryBarrier> fBufferBarriers;
  169. SkSTArray<1, VkImageMemoryBarrier> fImageBarriers;
  170. bool fBarriersByRegion = false;
  171. VkPipelineStageFlags fSrcStageMask = 0;
  172. VkPipelineStageFlags fDstStageMask = 0;
  173. };
  174. class GrVkSecondaryCommandBuffer;
  175. class GrVkPrimaryCommandBuffer : public GrVkCommandBuffer {
  176. public:
  177. ~GrVkPrimaryCommandBuffer() override;
  178. static GrVkPrimaryCommandBuffer* Create(const GrVkGpu* gpu, GrVkCommandPool* cmdPool);
  179. void begin(const GrVkGpu* gpu);
  180. void end(GrVkGpu* gpu);
  181. // Begins render pass on this command buffer. The framebuffer from GrVkRenderTarget will be used
  182. // in the render pass.
  183. void beginRenderPass(const GrVkGpu* gpu,
  184. const GrVkRenderPass* renderPass,
  185. const VkClearValue clearValues[],
  186. const GrVkRenderTarget& target,
  187. const SkIRect& bounds,
  188. bool forSecondaryCB);
  189. void endRenderPass(const GrVkGpu* gpu);
  190. // Submits the SecondaryCommandBuffer into this command buffer. It is required that we are
  191. // currently inside a render pass that is compatible with the one used to create the
  192. // SecondaryCommandBuffer.
  193. void executeCommands(const GrVkGpu* gpu,
  194. GrVkSecondaryCommandBuffer* secondaryBuffer);
  195. // Commands that only work outside of a render pass
  196. void clearColorImage(const GrVkGpu* gpu,
  197. GrVkImage* image,
  198. const VkClearColorValue* color,
  199. uint32_t subRangeCount,
  200. const VkImageSubresourceRange* subRanges);
  201. void clearDepthStencilImage(const GrVkGpu* gpu,
  202. GrVkImage* image,
  203. const VkClearDepthStencilValue* color,
  204. uint32_t subRangeCount,
  205. const VkImageSubresourceRange* subRanges);
  206. void copyImage(const GrVkGpu* gpu,
  207. GrVkImage* srcImage,
  208. VkImageLayout srcLayout,
  209. GrVkImage* dstImage,
  210. VkImageLayout dstLayout,
  211. uint32_t copyRegionCount,
  212. const VkImageCopy* copyRegions);
  213. void blitImage(const GrVkGpu* gpu,
  214. const GrVkResource* srcResource,
  215. VkImage srcImage,
  216. VkImageLayout srcLayout,
  217. const GrVkResource* dstResource,
  218. VkImage dstImage,
  219. VkImageLayout dstLayout,
  220. uint32_t blitRegionCount,
  221. const VkImageBlit* blitRegions,
  222. VkFilter filter);
  223. void blitImage(const GrVkGpu* gpu,
  224. const GrVkImage& srcImage,
  225. const GrVkImage& dstImage,
  226. uint32_t blitRegionCount,
  227. const VkImageBlit* blitRegions,
  228. VkFilter filter);
  229. void copyImageToBuffer(const GrVkGpu* gpu,
  230. GrVkImage* srcImage,
  231. VkImageLayout srcLayout,
  232. GrVkTransferBuffer* dstBuffer,
  233. uint32_t copyRegionCount,
  234. const VkBufferImageCopy* copyRegions);
  235. void copyBufferToImage(const GrVkGpu* gpu,
  236. GrVkTransferBuffer* srcBuffer,
  237. GrVkImage* dstImage,
  238. VkImageLayout dstLayout,
  239. uint32_t copyRegionCount,
  240. const VkBufferImageCopy* copyRegions);
  241. void copyBuffer(GrVkGpu* gpu,
  242. GrVkBuffer* srcBuffer,
  243. GrVkBuffer* dstBuffer,
  244. uint32_t regionCount,
  245. const VkBufferCopy* regions);
  246. void updateBuffer(GrVkGpu* gpu,
  247. GrVkBuffer* dstBuffer,
  248. VkDeviceSize dstOffset,
  249. VkDeviceSize dataSize,
  250. const void* data);
  251. void resolveImage(GrVkGpu* gpu,
  252. const GrVkImage& srcImage,
  253. const GrVkImage& dstImage,
  254. uint32_t regionCount,
  255. const VkImageResolve* regions);
  256. void submitToQueue(const GrVkGpu* gpu, VkQueue queue, GrVkGpu::SyncQueue sync,
  257. SkTArray<GrVkSemaphore::Resource*>& signalSemaphores,
  258. SkTArray<GrVkSemaphore::Resource*>& waitSemaphores);
  259. bool finished(const GrVkGpu* gpu);
  260. void addFinishedProc(sk_sp<GrRefCntedCallback> finishedProc);
  261. void recycleSecondaryCommandBuffers();
  262. #ifdef SK_TRACE_VK_RESOURCES
  263. void dumpInfo() const override {
  264. SkDebugf("GrVkPrimaryCommandBuffer: %d (%d refs)\n", fCmdBuffer, this->getRefCnt());
  265. }
  266. #endif
  267. private:
  268. explicit GrVkPrimaryCommandBuffer(VkCommandBuffer cmdBuffer, GrVkCommandPool* cmdPool)
  269. : INHERITED(cmdBuffer, cmdPool)
  270. , fSubmitFence(VK_NULL_HANDLE) {}
  271. void onFreeGPUData(GrVkGpu* gpu) const override;
  272. void onAbandonGPUData() const override;
  273. void onReleaseResources(GrVkGpu* gpu) override;
  274. SkTArray<GrVkSecondaryCommandBuffer*, true> fSecondaryCommandBuffers;
  275. VkFence fSubmitFence;
  276. SkTArray<sk_sp<GrRefCntedCallback>> fFinishedProcs;
  277. typedef GrVkCommandBuffer INHERITED;
  278. };
  279. class GrVkSecondaryCommandBuffer : public GrVkCommandBuffer {
  280. public:
  281. static GrVkSecondaryCommandBuffer* Create(const GrVkGpu* gpu, GrVkCommandPool* cmdPool);
  282. // Used for wrapping an external secondary command buffer.
  283. static GrVkSecondaryCommandBuffer* Create(VkCommandBuffer externalSecondaryCB);
  284. void begin(const GrVkGpu* gpu, const GrVkFramebuffer* framebuffer,
  285. const GrVkRenderPass* compatibleRenderPass);
  286. void end(GrVkGpu* gpu);
  287. VkCommandBuffer vkCommandBuffer() { return fCmdBuffer; }
  288. #ifdef SK_TRACE_VK_RESOURCES
  289. void dumpInfo() const override {
  290. SkDebugf("GrVkSecondaryCommandBuffer: %d (%d refs)\n", fCmdBuffer, this->getRefCnt());
  291. }
  292. #endif
  293. private:
  294. explicit GrVkSecondaryCommandBuffer(VkCommandBuffer cmdBuffer, GrVkCommandPool* cmdPool)
  295. : INHERITED(cmdBuffer, cmdPool) {}
  296. void onFreeGPUData(GrVkGpu* gpu) const override {}
  297. void onAbandonGPUData() const override {}
  298. friend class GrVkPrimaryCommandBuffer;
  299. typedef GrVkCommandBuffer INHERITED;
  300. };
  301. #endif