blob: 309980c498840d1b8839fd39c66ce1cbae677c22 [file] [log] [blame]
Greg Daniel164a9f02016-02-22 09:56:40 -05001/*
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
8#ifndef GrVkCommandBuffer_DEFINED
9#define GrVkCommandBuffer_DEFINED
10
Mike Kleinc0bd9f92019-04-23 12:05:21 -050011#include "include/gpu/vk/GrVkTypes.h"
Jim Van Verth3e192162020-03-10 16:23:16 -040012#include "src/gpu/GrManagedResource.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050013#include "src/gpu/vk/GrVkGpu.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050014#include "src/gpu/vk/GrVkSemaphore.h"
15#include "src/gpu/vk/GrVkUtil.h"
Greg Daniel164a9f02016-02-22 09:56:40 -050016
Greg Daniel6ecc9112017-06-16 16:17:03 +000017class GrVkBuffer;
egdaniel9a6cf802016-06-08 08:22:05 -070018class GrVkFramebuffer;
Greg Daniel6ecc9112017-06-16 16:17:03 +000019class GrVkImage;
Chris Dalton10ee0b22020-04-02 16:28:52 -060020class GrVkMeshBuffer;
egdaniel470d77a2016-03-18 12:50:27 -070021class GrVkPipeline;
Greg Daniel6ecc9112017-06-16 16:17:03 +000022class GrVkPipelineState;
Greg Daniel164a9f02016-02-22 09:56:40 -050023class GrVkRenderPass;
24class GrVkRenderTarget;
25class GrVkTransferBuffer;
26
Greg Daniel8daf3b72019-07-30 09:57:26 -040027class GrVkCommandBuffer {
Greg Daniel164a9f02016-02-22 09:56:40 -050028public:
Greg Daniel8daf3b72019-07-30 09:57:26 -040029 virtual ~GrVkCommandBuffer() {}
30
Greg Daniel164a9f02016-02-22 09:56:40 -050031 void invalidateState();
32
Greg Daniel164a9f02016-02-22 09:56:40 -050033 ////////////////////////////////////////////////////////////////////////////
Greg Daniel164a9f02016-02-22 09:56:40 -050034 // CommandBuffer commands
35 ////////////////////////////////////////////////////////////////////////////
36 enum BarrierType {
Greg Daniel164a9f02016-02-22 09:56:40 -050037 kBufferMemory_BarrierType,
38 kImageMemory_BarrierType
39 };
40
41 void pipelineBarrier(const GrVkGpu* gpu,
Jim Van Verth3e192162020-03-10 16:23:16 -040042 const GrManagedResource* resource,
Greg Daniel164a9f02016-02-22 09:56:40 -050043 VkPipelineStageFlags srcStageMask,
44 VkPipelineStageFlags dstStageMask,
45 bool byRegion,
46 BarrierType barrierType,
Greg Daniel59dc1482019-02-22 10:46:38 -050047 void* barrier);
Greg Daniel164a9f02016-02-22 09:56:40 -050048
Chris Dalton10ee0b22020-04-02 16:28:52 -060049 void bindInputBuffer(GrVkGpu* gpu, uint32_t binding, const GrVkMeshBuffer* vbuffer);
Chris Dalton1d616352017-05-31 12:51:23 -060050
Chris Dalton10ee0b22020-04-02 16:28:52 -060051 void bindIndexBuffer(GrVkGpu* gpu, const GrVkMeshBuffer* ibuffer);
Greg Daniel164a9f02016-02-22 09:56:40 -050052
egdaniel58a8d922016-04-21 08:03:10 -070053 void bindPipeline(const GrVkGpu* gpu, const GrVkPipeline* pipeline);
54
Greg Daniel164a9f02016-02-22 09:56:40 -050055 void bindDescriptorSets(const GrVkGpu* gpu,
egdaniel22281c12016-03-23 13:49:40 -070056 GrVkPipelineState*,
Greg Danieleecc6872019-07-29 13:21:37 -040057 VkPipelineLayout layout,
egdanielbc9b2962016-09-27 08:00:53 -070058 uint32_t firstSet,
59 uint32_t setCount,
60 const VkDescriptorSet* descriptorSets,
61 uint32_t dynamicOffsetCount,
62 const uint32_t* dynamicOffsets);
63
egdaniel470d77a2016-03-18 12:50:27 -070064 void setViewport(const GrVkGpu* gpu,
65 uint32_t firstViewport,
66 uint32_t viewportCount,
67 const VkViewport* viewports);
68
69 void setScissor(const GrVkGpu* gpu,
70 uint32_t firstScissor,
71 uint32_t scissorCount,
72 const VkRect2D* scissors);
73
74 void setBlendConstants(const GrVkGpu* gpu, const float blendConstants[4]);
75
egdaniel9a6cf802016-06-08 08:22:05 -070076 // Commands that only work inside of a render pass
77 void clearAttachments(const GrVkGpu* gpu,
78 int numAttachments,
79 const VkClearAttachment* attachments,
80 int numRects,
Greg Danielf346df32019-04-03 14:52:13 -040081 const VkClearRect* clearRects);
egdaniel9a6cf802016-06-08 08:22:05 -070082
83 void drawIndexed(const GrVkGpu* gpu,
84 uint32_t indexCount,
85 uint32_t instanceCount,
86 uint32_t firstIndex,
87 int32_t vertexOffset,
Greg Danielf346df32019-04-03 14:52:13 -040088 uint32_t firstInstance);
egdaniel9a6cf802016-06-08 08:22:05 -070089
90 void draw(const GrVkGpu* gpu,
91 uint32_t vertexCount,
92 uint32_t instanceCount,
93 uint32_t firstVertex,
Greg Danielf346df32019-04-03 14:52:13 -040094 uint32_t firstInstance);
egdaniel9a6cf802016-06-08 08:22:05 -070095
Chris Dalton03fdf6a2020-04-07 12:31:59 -060096 void drawIndirect(const GrVkGpu* gpu,
97 const GrVkMeshBuffer* indirectBuffer,
98 VkDeviceSize offset,
99 uint32_t drawCount,
100 uint32_t stride);
101
102 void drawIndexedIndirect(const GrVkGpu* gpu,
103 const GrVkMeshBuffer* indirectBuffer,
104 VkDeviceSize offset,
105 uint32_t drawCount,
106 uint32_t stride);
107
Greg Daniel7d918fd2018-06-19 15:22:01 -0400108 // Add ref-counted resource that will be tracked and released when this command buffer finishes
109 // execution
Jim Van Verth3e192162020-03-10 16:23:16 -0400110 void addResource(const GrManagedResource* resource) {
Greg Danielfa3adf72019-11-07 09:53:41 -0500111 SkASSERT(resource);
egdaniel9a6cf802016-06-08 08:22:05 -0700112 resource->ref();
Jim Van Verth3e192162020-03-10 16:23:16 -0400113 resource->notifyQueuedForWorkOnGpu();
egdaniel594739c2016-09-20 12:39:25 -0700114 fTrackedResources.append(1, &resource);
egdaniel9a6cf802016-06-08 08:22:05 -0700115 }
116
egdanielc1be9bc2016-07-20 08:33:00 -0700117 // Add ref-counted resource that will be tracked and released when this command buffer finishes
118 // execution. When it is released, it will signal that the resource can be recycled for reuse.
Jim Van Verth3e192162020-03-10 16:23:16 -0400119 void addRecycledResource(const GrRecycledResource* resource) {
egdanielc1be9bc2016-07-20 08:33:00 -0700120 resource->ref();
Jim Van Verth3e192162020-03-10 16:23:16 -0400121 resource->notifyQueuedForWorkOnGpu();
egdaniel594739c2016-09-20 12:39:25 -0700122 fTrackedRecycledResources.append(1, &resource);
egdanielc1be9bc2016-07-20 08:33:00 -0700123 }
124
Jim Van Verth5082df12020-03-11 16:14:51 -0400125 void releaseResources();
jvanverth7ec92412016-07-06 09:24:57 -0700126
Jim Van Verth5082df12020-03-11 16:14:51 -0400127 void freeGPUData(const GrGpu* gpu, VkCommandPool pool) const;
Greg Daniel8daf3b72019-07-30 09:57:26 -0400128
Robert Phillipsce0a2bf2019-04-02 13:37:34 -0400129 bool hasWork() const { return fHasWork; }
130
Greg Danield922f332020-04-27 11:21:36 -0400131#ifdef SK_DEBUG
132 bool validateNoSharedImageResources(const GrVkCommandBuffer* other);
133#endif
134
egdaniel9a6cf802016-06-08 08:22:05 -0700135protected:
Greg Daniel0addbdf2019-11-25 15:03:58 -0500136 GrVkCommandBuffer(VkCommandBuffer cmdBuffer, bool isWrapped = false)
137 : fCmdBuffer(cmdBuffer)
138 , fIsWrapped(isWrapped) {
Greg Daniel8daf3b72019-07-30 09:57:26 -0400139 fTrackedResources.setReserve(kInitialTrackedResourcesCount);
140 fTrackedRecycledResources.setReserve(kInitialTrackedResourcesCount);
141 this->invalidateState();
142 }
egdaniel594739c2016-09-20 12:39:25 -0700143
Greg Daniel0addbdf2019-11-25 15:03:58 -0500144 bool isWrapped() const { return fIsWrapped; }
Greg Daniel070cbaf2019-01-03 17:35:54 -0500145
Greg Daniel8daf3b72019-07-30 09:57:26 -0400146 void addingWork(const GrVkGpu* gpu);
Greg Danielee54f232019-04-03 14:58:40 -0400147
Greg Daniel8daf3b72019-07-30 09:57:26 -0400148 void submitPipelineBarriers(const GrVkGpu* gpu);
Robert Phillipsce0a2bf2019-04-02 13:37:34 -0400149
Jim Van Verth3e192162020-03-10 16:23:16 -0400150 SkTDArray<const GrManagedResource*> fTrackedResources;
151 SkTDArray<const GrRecycledResource*> fTrackedRecycledResources;
egdaniel9a6cf802016-06-08 08:22:05 -0700152
Greg Daniel8daf3b72019-07-30 09:57:26 -0400153 // Tracks whether we are in the middle of a command buffer begin/end calls and thus can add
154 // new commands to the buffer;
Greg Daniel0addbdf2019-11-25 15:03:58 -0500155 bool fIsActive = false;
Greg Daniel8daf3b72019-07-30 09:57:26 -0400156 bool fHasWork = false;
egdaniel9a6cf802016-06-08 08:22:05 -0700157
Greg Daniel8daf3b72019-07-30 09:57:26 -0400158 // Stores a pointer to the current active render pass (i.e. begin has been called but not
159 // end). A nullptr means there is no active render pass. The GrVKCommandBuffer does not own
160 // the render pass.
Greg Daniel0addbdf2019-11-25 15:03:58 -0500161 const GrVkRenderPass* fActiveRenderPass = nullptr;
egdaniel9a6cf802016-06-08 08:22:05 -0700162
Greg Daniel8daf3b72019-07-30 09:57:26 -0400163 VkCommandBuffer fCmdBuffer;
egdaniel9a6cf802016-06-08 08:22:05 -0700164
165private:
166 static const int kInitialTrackedResourcesCount = 32;
167
Jim Van Verth5082df12020-03-11 16:14:51 -0400168 virtual void onReleaseResources() {}
169 virtual void onFreeGPUData(const GrVkGpu* gpu) const = 0;
jvanverth7ec92412016-07-06 09:24:57 -0700170
Greg Daniel6ecc9112017-06-16 16:17:03 +0000171 static constexpr uint32_t kMaxInputBuffers = 2;
172
Chris Dalton1d616352017-05-31 12:51:23 -0600173 VkBuffer fBoundInputBuffers[kMaxInputBuffers];
174 VkBuffer fBoundIndexBuffer;
egdaniel9a6cf802016-06-08 08:22:05 -0700175
egdaniel594739c2016-09-20 12:39:25 -0700176 // When resetting the command buffer, we remove the tracked resources from their arrays, and
177 // we prefer to not free all the memory every time so usually we just rewind. However, to avoid
178 // all arrays growing to the max size, after so many resets we'll do a full reset of the tracked
179 // resource arrays.
180 static const int kNumRewindResetsBeforeFullReset = 8;
Greg Daniel0addbdf2019-11-25 15:03:58 -0500181 int fNumResets = 0;
egdaniel594739c2016-09-20 12:39:25 -0700182
egdaniel9a6cf802016-06-08 08:22:05 -0700183 // Cached values used for dynamic state updates
184 VkViewport fCachedViewport;
185 VkRect2D fCachedScissor;
186 float fCachedBlendConstant[4];
Ethan Nicholas8e265a72018-12-12 16:22:40 -0500187
Greg Danielee54f232019-04-03 14:58:40 -0400188 // Tracking of memory barriers so that we can submit them all in a batch together.
189 SkSTArray<4, VkBufferMemoryBarrier> fBufferBarriers;
190 SkSTArray<1, VkImageMemoryBarrier> fImageBarriers;
191 bool fBarriersByRegion = false;
192 VkPipelineStageFlags fSrcStageMask = 0;
193 VkPipelineStageFlags fDstStageMask = 0;
Greg Daniel0addbdf2019-11-25 15:03:58 -0500194
195 bool fIsWrapped;
egdaniel9a6cf802016-06-08 08:22:05 -0700196};
197
198class GrVkSecondaryCommandBuffer;
199
200class GrVkPrimaryCommandBuffer : public GrVkCommandBuffer {
201public:
egdaniel9cb63402016-06-23 08:37:05 -0700202 ~GrVkPrimaryCommandBuffer() override;
203
Greg Daniel315c8dc2019-11-26 15:41:27 -0500204 static GrVkPrimaryCommandBuffer* Create(GrVkGpu* gpu, VkCommandPool cmdPool);
egdaniel9a6cf802016-06-08 08:22:05 -0700205
Greg Daniele643da62019-11-05 12:36:42 -0500206 void begin(GrVkGpu* gpu);
Ethan Nicholas8e265a72018-12-12 16:22:40 -0500207 void end(GrVkGpu* gpu);
egdaniel9a6cf802016-06-08 08:22:05 -0700208
209 // Begins render pass on this command buffer. The framebuffer from GrVkRenderTarget will be used
210 // in the render pass.
Greg Danielfa3adf72019-11-07 09:53:41 -0500211 bool beginRenderPass(GrVkGpu* gpu,
egdaniel9a6cf802016-06-08 08:22:05 -0700212 const GrVkRenderPass* renderPass,
Robert Phillips95214472017-08-08 18:00:03 -0400213 const VkClearValue clearValues[],
Greg Danielfa3adf72019-11-07 09:53:41 -0500214 GrVkRenderTarget* target,
egdaniel9cb63402016-06-23 08:37:05 -0700215 const SkIRect& bounds,
216 bool forSecondaryCB);
egdaniel9a6cf802016-06-08 08:22:05 -0700217 void endRenderPass(const GrVkGpu* gpu);
218
219 // Submits the SecondaryCommandBuffer into this command buffer. It is required that we are
220 // currently inside a render pass that is compatible with the one used to create the
221 // SecondaryCommandBuffer.
222 void executeCommands(const GrVkGpu* gpu,
Greg Daniel8daf3b72019-07-30 09:57:26 -0400223 std::unique_ptr<GrVkSecondaryCommandBuffer> secondaryBuffer);
egdaniel9a6cf802016-06-08 08:22:05 -0700224
Greg Daniel164a9f02016-02-22 09:56:40 -0500225 // Commands that only work outside of a render pass
226 void clearColorImage(const GrVkGpu* gpu,
227 GrVkImage* image,
228 const VkClearColorValue* color,
229 uint32_t subRangeCount,
230 const VkImageSubresourceRange* subRanges);
231
egdaniel3d5d9ac2016-03-01 12:56:15 -0800232 void clearDepthStencilImage(const GrVkGpu* gpu,
233 GrVkImage* image,
234 const VkClearDepthStencilValue* color,
235 uint32_t subRangeCount,
236 const VkImageSubresourceRange* subRanges);
237
Greg Daniel164a9f02016-02-22 09:56:40 -0500238 void copyImage(const GrVkGpu* gpu,
239 GrVkImage* srcImage,
240 VkImageLayout srcLayout,
241 GrVkImage* dstImage,
242 VkImageLayout dstLayout,
243 uint32_t copyRegionCount,
244 const VkImageCopy* copyRegions);
245
egdaniel17b89252016-04-05 07:23:38 -0700246 void blitImage(const GrVkGpu* gpu,
Jim Van Verth3e192162020-03-10 16:23:16 -0400247 const GrManagedResource* srcResource,
egdanielb2df0c22016-05-13 11:30:37 -0700248 VkImage srcImage,
egdaniel17b89252016-04-05 07:23:38 -0700249 VkImageLayout srcLayout,
Jim Van Verth3e192162020-03-10 16:23:16 -0400250 const GrManagedResource* dstResource,
egdanielb2df0c22016-05-13 11:30:37 -0700251 VkImage dstImage,
egdaniel17b89252016-04-05 07:23:38 -0700252 VkImageLayout dstLayout,
253 uint32_t blitRegionCount,
254 const VkImageBlit* blitRegions,
255 VkFilter filter);
256
egdanielb2df0c22016-05-13 11:30:37 -0700257 void blitImage(const GrVkGpu* gpu,
258 const GrVkImage& srcImage,
259 const GrVkImage& dstImage,
260 uint32_t blitRegionCount,
261 const VkImageBlit* blitRegions,
Greg Daniel6ecc9112017-06-16 16:17:03 +0000262 VkFilter filter);
egdanielb2df0c22016-05-13 11:30:37 -0700263
Greg Daniel164a9f02016-02-22 09:56:40 -0500264 void copyImageToBuffer(const GrVkGpu* gpu,
265 GrVkImage* srcImage,
266 VkImageLayout srcLayout,
267 GrVkTransferBuffer* dstBuffer,
268 uint32_t copyRegionCount,
269 const VkBufferImageCopy* copyRegions);
270
271 void copyBufferToImage(const GrVkGpu* gpu,
272 GrVkTransferBuffer* srcBuffer,
273 GrVkImage* dstImage,
274 VkImageLayout dstLayout,
275 uint32_t copyRegionCount,
276 const VkBufferImageCopy* copyRegions);
277
Greg Daniel6888c0d2017-08-25 11:55:50 -0400278 void copyBuffer(GrVkGpu* gpu,
279 GrVkBuffer* srcBuffer,
280 GrVkBuffer* dstBuffer,
281 uint32_t regionCount,
282 const VkBufferCopy* regions);
283
jvanvertha584de92016-06-30 09:10:52 -0700284 void updateBuffer(GrVkGpu* gpu,
285 GrVkBuffer* dstBuffer,
286 VkDeviceSize dstOffset,
287 VkDeviceSize dataSize,
288 const void* data);
289
egdaniel52ad2512016-08-04 12:50:01 -0700290 void resolveImage(GrVkGpu* gpu,
291 const GrVkImage& srcImage,
292 const GrVkImage& dstImage,
293 uint32_t regionCount,
294 const VkImageResolve* regions);
295
Greg Daniele1185582019-12-04 11:29:44 -0500296 bool submitToQueue(GrVkGpu* gpu, VkQueue queue,
Greg Daniel48661b82018-01-22 16:11:35 -0500297 SkTArray<GrVkSemaphore::Resource*>& signalSemaphores,
298 SkTArray<GrVkSemaphore::Resource*>& waitSemaphores);
Greg Daniele1185582019-12-04 11:29:44 -0500299
300 void forceSync(GrVkGpu* gpu);
301
302 bool finished(GrVkGpu* gpu);
Greg Daniela3aa75a2019-04-12 14:24:55 -0400303
304 void addFinishedProc(sk_sp<GrRefCntedCallback> finishedProc);
Greg Daniel164a9f02016-02-22 09:56:40 -0500305
Greg Danielfe159622020-04-10 17:43:51 +0000306 void callFinishedProcs() {
307 fFinishedProcs.reset();
308 }
309
Greg Daniel0addbdf2019-11-25 15:03:58 -0500310 void recycleSecondaryCommandBuffers(GrVkCommandPool* cmdPool);
jvanverth7ec92412016-07-06 09:24:57 -0700311
Greg Daniel164a9f02016-02-22 09:56:40 -0500312private:
Greg Daniel0addbdf2019-11-25 15:03:58 -0500313 explicit GrVkPrimaryCommandBuffer(VkCommandBuffer cmdBuffer)
314 : INHERITED(cmdBuffer)
egdaniel9cb63402016-06-23 08:37:05 -0700315 , fSubmitFence(VK_NULL_HANDLE) {}
316
Jim Van Verth5082df12020-03-11 16:14:51 -0400317 void onFreeGPUData(const GrVkGpu* gpu) const override;
egdaniel9cb63402016-06-23 08:37:05 -0700318
Jim Van Verth5082df12020-03-11 16:14:51 -0400319 void onReleaseResources() override;
jvanverth7ec92412016-07-06 09:24:57 -0700320
Greg Daniel8daf3b72019-07-30 09:57:26 -0400321 SkTArray<std::unique_ptr<GrVkSecondaryCommandBuffer>, true> fSecondaryCommandBuffers;
322 VkFence fSubmitFence;
323 SkTArray<sk_sp<GrRefCntedCallback>> fFinishedProcs;
Greg Daniel164a9f02016-02-22 09:56:40 -0500324
egdaniel9a6cf802016-06-08 08:22:05 -0700325 typedef GrVkCommandBuffer INHERITED;
Greg Daniel164a9f02016-02-22 09:56:40 -0500326};
327
egdaniel9a6cf802016-06-08 08:22:05 -0700328class GrVkSecondaryCommandBuffer : public GrVkCommandBuffer {
329public:
Greg Daniel315c8dc2019-11-26 15:41:27 -0500330 static GrVkSecondaryCommandBuffer* Create(GrVkGpu* gpu, GrVkCommandPool* cmdPool);
Greg Daniel070cbaf2019-01-03 17:35:54 -0500331 // Used for wrapping an external secondary command buffer.
332 static GrVkSecondaryCommandBuffer* Create(VkCommandBuffer externalSecondaryCB);
egdaniel9a6cf802016-06-08 08:22:05 -0700333
Greg Daniele643da62019-11-05 12:36:42 -0500334 void begin(GrVkGpu* gpu, const GrVkFramebuffer* framebuffer,
jvanverth7ec92412016-07-06 09:24:57 -0700335 const GrVkRenderPass* compatibleRenderPass);
Ethan Nicholas8e265a72018-12-12 16:22:40 -0500336 void end(GrVkGpu* gpu);
egdaniel9a6cf802016-06-08 08:22:05 -0700337
Greg Daniel0addbdf2019-11-25 15:03:58 -0500338 void recycle(GrVkCommandPool* cmdPool);
Greg Daniel64cc9aa2018-10-19 13:54:56 -0400339
Greg Daniel8daf3b72019-07-30 09:57:26 -0400340 VkCommandBuffer vkCommandBuffer() { return fCmdBuffer; }
jvanverth7ec92412016-07-06 09:24:57 -0700341
egdaniel9a6cf802016-06-08 08:22:05 -0700342private:
Greg Daniel0addbdf2019-11-25 15:03:58 -0500343 explicit GrVkSecondaryCommandBuffer(VkCommandBuffer cmdBuffer, bool isWrapped)
344 : INHERITED(cmdBuffer, isWrapped) {}
egdaniel9a6cf802016-06-08 08:22:05 -0700345
Jim Van Verth5082df12020-03-11 16:14:51 -0400346 void onFreeGPUData(const GrVkGpu* gpu) const override {}
Ethan Nicholas8e265a72018-12-12 16:22:40 -0500347
Greg Daniel315c8dc2019-11-26 15:41:27 -0500348 // Used for accessing fIsActive (on GrVkCommandBuffer)
egdaniel9a6cf802016-06-08 08:22:05 -0700349 friend class GrVkPrimaryCommandBuffer;
350
351 typedef GrVkCommandBuffer INHERITED;
352};
Greg Daniel164a9f02016-02-22 09:56:40 -0500353
354#endif