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