blob: 35b2f13cb2c2fd7299ce9d7cecd641c23bce86ca [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
Greg Daniel426274b2020-07-20 11:37:38 -040049 void bindInputBuffer(GrVkGpu* gpu, uint32_t binding, sk_sp<const GrBuffer> buffer);
Chris Dalton1d616352017-05-31 12:51:23 -060050
Greg Daniel426274b2020-07-20 11:37:38 -040051 void bindIndexBuffer(GrVkGpu* gpu, sk_sp<const GrBuffer> buffer);
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
Greg Daniel426274b2020-07-20 11:37:38 -0400125 void addGrBuffer(sk_sp<const GrBuffer> buffer) {
Greg Daniela58db7f2020-07-15 09:17:59 -0400126 fTrackedGpuBuffers.push_back(std::move(buffer));
127 }
128
Jim Van Verth5082df12020-03-11 16:14:51 -0400129 void releaseResources();
jvanverth7ec92412016-07-06 09:24:57 -0700130
Jim Van Verth5082df12020-03-11 16:14:51 -0400131 void freeGPUData(const GrGpu* gpu, VkCommandPool pool) const;
Greg Daniel8daf3b72019-07-30 09:57:26 -0400132
Robert Phillipsce0a2bf2019-04-02 13:37:34 -0400133 bool hasWork() const { return fHasWork; }
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 Daniel9a18b082020-08-14 14:03:50 -0400148 void submitPipelineBarriers(const GrVkGpu* gpu, bool forSelfDependency = false);
Robert Phillipsce0a2bf2019-04-02 13:37:34 -0400149
Greg Daniela58db7f2020-07-15 09:17:59 -0400150 SkTDArray<const GrManagedResource*> fTrackedResources;
151 SkTDArray<const GrRecycledResource*> fTrackedRecycledResources;
Greg Daniel426274b2020-07-20 11:37:38 -0400152 SkSTArray<16, sk_sp<const GrBuffer>> fTrackedGpuBuffers;
egdaniel9a6cf802016-06-08 08:22:05 -0700153
Greg Daniel8daf3b72019-07-30 09:57:26 -0400154 // Tracks whether we are in the middle of a command buffer begin/end calls and thus can add
155 // new commands to the buffer;
Greg Daniel0addbdf2019-11-25 15:03:58 -0500156 bool fIsActive = false;
Greg Daniel8daf3b72019-07-30 09:57:26 -0400157 bool fHasWork = false;
egdaniel9a6cf802016-06-08 08:22:05 -0700158
Greg Daniel8daf3b72019-07-30 09:57:26 -0400159 // Stores a pointer to the current active render pass (i.e. begin has been called but not
160 // end). A nullptr means there is no active render pass. The GrVKCommandBuffer does not own
161 // the render pass.
Greg Daniel0addbdf2019-11-25 15:03:58 -0500162 const GrVkRenderPass* fActiveRenderPass = nullptr;
egdaniel9a6cf802016-06-08 08:22:05 -0700163
Greg Daniel8daf3b72019-07-30 09:57:26 -0400164 VkCommandBuffer fCmdBuffer;
egdaniel9a6cf802016-06-08 08:22:05 -0700165
166private:
167 static const int kInitialTrackedResourcesCount = 32;
168
Jim Van Verth5082df12020-03-11 16:14:51 -0400169 virtual void onReleaseResources() {}
170 virtual void onFreeGPUData(const GrVkGpu* gpu) const = 0;
jvanverth7ec92412016-07-06 09:24:57 -0700171
Greg Daniel6ecc9112017-06-16 16:17:03 +0000172 static constexpr uint32_t kMaxInputBuffers = 2;
173
Chris Dalton1d616352017-05-31 12:51:23 -0600174 VkBuffer fBoundInputBuffers[kMaxInputBuffers];
175 VkBuffer fBoundIndexBuffer;
egdaniel9a6cf802016-06-08 08:22:05 -0700176
egdaniel594739c2016-09-20 12:39:25 -0700177 // When resetting the command buffer, we remove the tracked resources from their arrays, and
178 // we prefer to not free all the memory every time so usually we just rewind. However, to avoid
179 // all arrays growing to the max size, after so many resets we'll do a full reset of the tracked
180 // resource arrays.
181 static const int kNumRewindResetsBeforeFullReset = 8;
Greg Daniel0addbdf2019-11-25 15:03:58 -0500182 int fNumResets = 0;
egdaniel594739c2016-09-20 12:39:25 -0700183
egdaniel9a6cf802016-06-08 08:22:05 -0700184 // Cached values used for dynamic state updates
185 VkViewport fCachedViewport;
186 VkRect2D fCachedScissor;
187 float fCachedBlendConstant[4];
Ethan Nicholas8e265a72018-12-12 16:22:40 -0500188
Greg Danielee54f232019-04-03 14:58:40 -0400189 // Tracking of memory barriers so that we can submit them all in a batch together.
190 SkSTArray<4, VkBufferMemoryBarrier> fBufferBarriers;
191 SkSTArray<1, VkImageMemoryBarrier> fImageBarriers;
192 bool fBarriersByRegion = false;
193 VkPipelineStageFlags fSrcStageMask = 0;
194 VkPipelineStageFlags fDstStageMask = 0;
Greg Daniel0addbdf2019-11-25 15:03:58 -0500195
196 bool fIsWrapped;
egdaniel9a6cf802016-06-08 08:22:05 -0700197};
198
199class GrVkSecondaryCommandBuffer;
200
201class GrVkPrimaryCommandBuffer : public GrVkCommandBuffer {
202public:
egdaniel9cb63402016-06-23 08:37:05 -0700203 ~GrVkPrimaryCommandBuffer() override;
204
Greg Daniel315c8dc2019-11-26 15:41:27 -0500205 static GrVkPrimaryCommandBuffer* Create(GrVkGpu* gpu, VkCommandPool cmdPool);
egdaniel9a6cf802016-06-08 08:22:05 -0700206
Greg Daniele643da62019-11-05 12:36:42 -0500207 void begin(GrVkGpu* gpu);
Ethan Nicholas8e265a72018-12-12 16:22:40 -0500208 void end(GrVkGpu* gpu);
egdaniel9a6cf802016-06-08 08:22:05 -0700209
210 // Begins render pass on this command buffer. The framebuffer from GrVkRenderTarget will be used
211 // in the render pass.
Greg Danielfa3adf72019-11-07 09:53:41 -0500212 bool beginRenderPass(GrVkGpu* gpu,
egdaniel9a6cf802016-06-08 08:22:05 -0700213 const GrVkRenderPass* renderPass,
Robert Phillips95214472017-08-08 18:00:03 -0400214 const VkClearValue clearValues[],
Greg Danielfa3adf72019-11-07 09:53:41 -0500215 GrVkRenderTarget* target,
egdaniel9cb63402016-06-23 08:37:05 -0700216 const SkIRect& bounds,
217 bool forSecondaryCB);
egdaniel9a6cf802016-06-08 08:22:05 -0700218 void endRenderPass(const GrVkGpu* gpu);
219
220 // Submits the SecondaryCommandBuffer into this command buffer. It is required that we are
221 // currently inside a render pass that is compatible with the one used to create the
222 // SecondaryCommandBuffer.
223 void executeCommands(const GrVkGpu* gpu,
Greg Daniel8daf3b72019-07-30 09:57:26 -0400224 std::unique_ptr<GrVkSecondaryCommandBuffer> secondaryBuffer);
egdaniel9a6cf802016-06-08 08:22:05 -0700225
Greg Daniel164a9f02016-02-22 09:56:40 -0500226 // Commands that only work outside of a render pass
227 void clearColorImage(const GrVkGpu* gpu,
228 GrVkImage* image,
229 const VkClearColorValue* color,
230 uint32_t subRangeCount,
231 const VkImageSubresourceRange* subRanges);
232
egdaniel3d5d9ac2016-03-01 12:56:15 -0800233 void clearDepthStencilImage(const GrVkGpu* gpu,
234 GrVkImage* image,
235 const VkClearDepthStencilValue* color,
236 uint32_t subRangeCount,
237 const VkImageSubresourceRange* subRanges);
238
Greg Daniel164a9f02016-02-22 09:56:40 -0500239 void copyImage(const GrVkGpu* gpu,
240 GrVkImage* srcImage,
241 VkImageLayout srcLayout,
242 GrVkImage* dstImage,
243 VkImageLayout dstLayout,
244 uint32_t copyRegionCount,
245 const VkImageCopy* copyRegions);
246
egdaniel17b89252016-04-05 07:23:38 -0700247 void blitImage(const GrVkGpu* gpu,
Jim Van Verth3e192162020-03-10 16:23:16 -0400248 const GrManagedResource* srcResource,
egdanielb2df0c22016-05-13 11:30:37 -0700249 VkImage srcImage,
egdaniel17b89252016-04-05 07:23:38 -0700250 VkImageLayout srcLayout,
Jim Van Verth3e192162020-03-10 16:23:16 -0400251 const GrManagedResource* dstResource,
egdanielb2df0c22016-05-13 11:30:37 -0700252 VkImage dstImage,
egdaniel17b89252016-04-05 07:23:38 -0700253 VkImageLayout dstLayout,
254 uint32_t blitRegionCount,
255 const VkImageBlit* blitRegions,
256 VkFilter filter);
257
egdanielb2df0c22016-05-13 11:30:37 -0700258 void blitImage(const GrVkGpu* gpu,
259 const GrVkImage& srcImage,
260 const GrVkImage& dstImage,
261 uint32_t blitRegionCount,
262 const VkImageBlit* blitRegions,
Greg Daniel6ecc9112017-06-16 16:17:03 +0000263 VkFilter filter);
egdanielb2df0c22016-05-13 11:30:37 -0700264
Greg Daniel164a9f02016-02-22 09:56:40 -0500265 void copyImageToBuffer(const GrVkGpu* gpu,
266 GrVkImage* srcImage,
267 VkImageLayout srcLayout,
268 GrVkTransferBuffer* dstBuffer,
269 uint32_t copyRegionCount,
270 const VkBufferImageCopy* copyRegions);
271
272 void copyBufferToImage(const GrVkGpu* gpu,
273 GrVkTransferBuffer* srcBuffer,
274 GrVkImage* dstImage,
275 VkImageLayout dstLayout,
276 uint32_t copyRegionCount,
277 const VkBufferImageCopy* copyRegions);
278
Greg Daniel6888c0d2017-08-25 11:55:50 -0400279 void copyBuffer(GrVkGpu* gpu,
280 GrVkBuffer* srcBuffer,
281 GrVkBuffer* dstBuffer,
282 uint32_t regionCount,
283 const VkBufferCopy* regions);
284
jvanvertha584de92016-06-30 09:10:52 -0700285 void updateBuffer(GrVkGpu* gpu,
286 GrVkBuffer* dstBuffer,
287 VkDeviceSize dstOffset,
288 VkDeviceSize dataSize,
289 const void* data);
290
egdaniel52ad2512016-08-04 12:50:01 -0700291 void resolveImage(GrVkGpu* gpu,
292 const GrVkImage& srcImage,
293 const GrVkImage& dstImage,
294 uint32_t regionCount,
295 const VkImageResolve* regions);
296
Greg Daniele1185582019-12-04 11:29:44 -0500297 bool submitToQueue(GrVkGpu* gpu, VkQueue queue,
Greg Daniel48661b82018-01-22 16:11:35 -0500298 SkTArray<GrVkSemaphore::Resource*>& signalSemaphores,
299 SkTArray<GrVkSemaphore::Resource*>& waitSemaphores);
Greg Daniele1185582019-12-04 11:29:44 -0500300
301 void forceSync(GrVkGpu* gpu);
302
303 bool finished(GrVkGpu* gpu);
Greg Daniela3aa75a2019-04-12 14:24:55 -0400304
305 void addFinishedProc(sk_sp<GrRefCntedCallback> finishedProc);
Greg Daniel164a9f02016-02-22 09:56:40 -0500306
Greg Danielfe159622020-04-10 17:43:51 +0000307 void callFinishedProcs() {
308 fFinishedProcs.reset();
309 }
310
Greg Daniel0addbdf2019-11-25 15:03:58 -0500311 void recycleSecondaryCommandBuffers(GrVkCommandPool* cmdPool);
jvanverth7ec92412016-07-06 09:24:57 -0700312
Greg Daniel164a9f02016-02-22 09:56:40 -0500313private:
Greg Daniel0addbdf2019-11-25 15:03:58 -0500314 explicit GrVkPrimaryCommandBuffer(VkCommandBuffer cmdBuffer)
315 : INHERITED(cmdBuffer)
egdaniel9cb63402016-06-23 08:37:05 -0700316 , fSubmitFence(VK_NULL_HANDLE) {}
317
Jim Van Verth5082df12020-03-11 16:14:51 -0400318 void onFreeGPUData(const GrVkGpu* gpu) const override;
egdaniel9cb63402016-06-23 08:37:05 -0700319
Jim Van Verth5082df12020-03-11 16:14:51 -0400320 void onReleaseResources() override;
jvanverth7ec92412016-07-06 09:24:57 -0700321
Greg Daniel8daf3b72019-07-30 09:57:26 -0400322 SkTArray<std::unique_ptr<GrVkSecondaryCommandBuffer>, true> fSecondaryCommandBuffers;
323 VkFence fSubmitFence;
324 SkTArray<sk_sp<GrRefCntedCallback>> fFinishedProcs;
Greg Daniel164a9f02016-02-22 09:56:40 -0500325
John Stiles7571f9e2020-09-02 22:42:33 -0400326 using INHERITED = GrVkCommandBuffer;
Greg Daniel164a9f02016-02-22 09:56:40 -0500327};
328
egdaniel9a6cf802016-06-08 08:22:05 -0700329class GrVkSecondaryCommandBuffer : public GrVkCommandBuffer {
330public:
Greg Daniel315c8dc2019-11-26 15:41:27 -0500331 static GrVkSecondaryCommandBuffer* Create(GrVkGpu* gpu, GrVkCommandPool* cmdPool);
Greg Daniel070cbaf2019-01-03 17:35:54 -0500332 // Used for wrapping an external secondary command buffer.
333 static GrVkSecondaryCommandBuffer* Create(VkCommandBuffer externalSecondaryCB);
egdaniel9a6cf802016-06-08 08:22:05 -0700334
Greg Daniele643da62019-11-05 12:36:42 -0500335 void begin(GrVkGpu* gpu, const GrVkFramebuffer* framebuffer,
jvanverth7ec92412016-07-06 09:24:57 -0700336 const GrVkRenderPass* compatibleRenderPass);
Ethan Nicholas8e265a72018-12-12 16:22:40 -0500337 void end(GrVkGpu* gpu);
egdaniel9a6cf802016-06-08 08:22:05 -0700338
Greg Daniel0addbdf2019-11-25 15:03:58 -0500339 void recycle(GrVkCommandPool* cmdPool);
Greg Daniel64cc9aa2018-10-19 13:54:56 -0400340
Greg Daniel8daf3b72019-07-30 09:57:26 -0400341 VkCommandBuffer vkCommandBuffer() { return fCmdBuffer; }
jvanverth7ec92412016-07-06 09:24:57 -0700342
egdaniel9a6cf802016-06-08 08:22:05 -0700343private:
Greg Daniel0addbdf2019-11-25 15:03:58 -0500344 explicit GrVkSecondaryCommandBuffer(VkCommandBuffer cmdBuffer, bool isWrapped)
345 : INHERITED(cmdBuffer, isWrapped) {}
egdaniel9a6cf802016-06-08 08:22:05 -0700346
Jim Van Verth5082df12020-03-11 16:14:51 -0400347 void onFreeGPUData(const GrVkGpu* gpu) const override {}
Ethan Nicholas8e265a72018-12-12 16:22:40 -0500348
Greg Daniel315c8dc2019-11-26 15:41:27 -0500349 // Used for accessing fIsActive (on GrVkCommandBuffer)
egdaniel9a6cf802016-06-08 08:22:05 -0700350 friend class GrVkPrimaryCommandBuffer;
351
John Stiles7571f9e2020-09-02 22:42:33 -0400352 using INHERITED = GrVkCommandBuffer;
egdaniel9a6cf802016-06-08 08:22:05 -0700353};
Greg Daniel164a9f02016-02-22 09:56:40 -0500354
355#endif