Home | History | Annotate | Download | only in vk
      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
    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.
    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)
    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 
    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 updateBuffer(GrVkGpu* gpu,
    254                       GrVkBuffer* dstBuffer,
    255                       VkDeviceSize dstOffset,
    256                       VkDeviceSize dataSize,
    257                       const void* data);
    258 
    259     void resolveImage(GrVkGpu* gpu,
    260                       const GrVkImage& srcImage,
    261                       const GrVkImage& dstImage,
    262                       uint32_t regionCount,
    263                       const VkImageResolve* regions);
    264 
    265     void submitToQueue(const GrVkGpu* gpu, VkQueue queue, GrVkGpu::SyncQueue sync,
    266                        SkTArray<const GrVkSemaphore::Resource*>& signalSemaphores,
    267                        SkTArray<const GrVkSemaphore::Resource*>& waitSemaphores);
    268     bool finished(const GrVkGpu* gpu) const;
    269 
    270 #ifdef SK_TRACE_VK_RESOURCES
    271     void dumpInfo() const override {
    272         SkDebugf("GrVkPrimaryCommandBuffer: %d (%d refs)\n", fCmdBuffer, this->getRefCnt());
    273     }
    274 #endif
    275 
    276 private:
    277     explicit GrVkPrimaryCommandBuffer(VkCommandBuffer cmdBuffer)
    278         : INHERITED(cmdBuffer)
    279         , fSubmitFence(VK_NULL_HANDLE) {}
    280 
    281     void onFreeGPUData(const GrVkGpu* gpu) const override;
    282 
    283     void onReset(GrVkGpu* gpu) override;
    284 
    285     SkTArray<GrVkSecondaryCommandBuffer*, true> fSecondaryCommandBuffers;
    286     VkFence                                     fSubmitFence;
    287 
    288     typedef GrVkCommandBuffer INHERITED;
    289 };
    290 
    291 class GrVkSecondaryCommandBuffer : public GrVkCommandBuffer {
    292 public:
    293     static GrVkSecondaryCommandBuffer* Create(const GrVkGpu* gpu, VkCommandPool cmdPool);
    294 
    295     void begin(const GrVkGpu* gpu, const GrVkFramebuffer* framebuffer,
    296                const GrVkRenderPass* compatibleRenderPass);
    297     void end(const GrVkGpu* gpu);
    298 
    299 #ifdef SK_TRACE_VK_RESOURCES
    300     void dumpInfo() const override {
    301         SkDebugf("GrVkSecondaryCommandBuffer: %d (%d refs)\n", fCmdBuffer, this->getRefCnt());
    302     }
    303 #endif
    304 
    305 private:
    306     explicit GrVkSecondaryCommandBuffer(VkCommandBuffer cmdBuffer)
    307         : INHERITED(cmdBuffer) {
    308     }
    309 
    310     void onFreeGPUData(const GrVkGpu* gpu) const override {}
    311 
    312     friend class GrVkPrimaryCommandBuffer;
    313 
    314     typedef GrVkCommandBuffer INHERITED;
    315 };
    316 
    317 #endif
    318