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