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 "GrVkPipeline.h"
     13 #include "GrVkResource.h"
     14 #include "GrVkUtil.h"
     15 #include "vulkan/vulkan.h"
     16 
     17 class GrVkRenderPass;
     18 class GrVkRenderTarget;
     19 class GrVkTransferBuffer;
     20 
     21 class GrVkCommandBuffer : public GrVkResource {
     22 public:
     23     static GrVkCommandBuffer* Create(const GrVkGpu* gpu, VkCommandPool cmdPool);
     24     ~GrVkCommandBuffer() override;
     25 
     26     void begin(const GrVkGpu* gpu);
     27     void end(const GrVkGpu* gpu);
     28 
     29     void invalidateState();
     30 
     31     // Begins render pass on this command buffer. The framebuffer from GrVkRenderTarget will be used
     32     // in the render pass.
     33     void beginRenderPass(const GrVkGpu* gpu,
     34                          const GrVkRenderPass* renderPass,
     35                          const GrVkRenderTarget& target);
     36     void endRenderPass(const GrVkGpu* gpu);
     37 
     38     void submitToQueue(const GrVkGpu* gpu, VkQueue queue, GrVkGpu::SyncQueue sync);
     39     bool finished(const GrVkGpu* gpu) const;
     40 
     41     ////////////////////////////////////////////////////////////////////////////
     42     // CommandBuffer State/Object bindings
     43     ////////////////////////////////////////////////////////////////////////////
     44 #if 0
     45     void bindPipeline(const GrVkGpu* gpu) const;
     46     void bindDynamicState(const GrVkGpu* gpu) const;
     47     void bindDescriptorSet(const GrVkGpu* gpu) const;
     48 #endif
     49 
     50     ////////////////////////////////////////////////////////////////////////////
     51     // CommandBuffer commands
     52     ////////////////////////////////////////////////////////////////////////////
     53     enum BarrierType {
     54         kMemory_BarrierType,
     55         kBufferMemory_BarrierType,
     56         kImageMemory_BarrierType
     57     };
     58 
     59     void pipelineBarrier(const GrVkGpu* gpu,
     60                          VkPipelineStageFlags srcStageMask,
     61                          VkPipelineStageFlags dstStageMask,
     62                          bool byRegion,
     63                          BarrierType barrierType,
     64                          void* barrier) const;
     65 
     66     void bindVertexBuffer(GrVkGpu* gpu, GrVkVertexBuffer* vbuffer) {
     67         VkBuffer vkBuffer = vbuffer->buffer();
     68         if (!fBoundVertexBufferIsValid || vkBuffer != fBoundVertexBuffer) {
     69             VkDeviceSize offset = 0;
     70             GR_VK_CALL(gpu->vkInterface(), CmdBindVertexBuffers(fCmdBuffer,
     71                                                                 0,
     72                                                                 1,
     73                                                                 &vkBuffer,
     74                                                                 &offset));
     75             fBoundVertexBufferIsValid = true;
     76             fBoundVertexBuffer = vkBuffer;
     77             addResource(vbuffer->resource());
     78         }
     79     }
     80 
     81     void bindIndexBuffer(GrVkGpu* gpu, GrVkIndexBuffer* ibuffer) {
     82         VkBuffer vkBuffer = ibuffer->buffer();
     83         if (!fBoundIndexBufferIsValid || vkBuffer != fBoundIndexBuffer) {
     84             GR_VK_CALL(gpu->vkInterface(), CmdBindIndexBuffer(fCmdBuffer,
     85                                                               vkBuffer,
     86                                                               0,
     87                                                               VK_INDEX_TYPE_UINT16));
     88             fBoundIndexBufferIsValid = true;
     89             fBoundIndexBuffer = vkBuffer;
     90             addResource(ibuffer->resource());
     91         }
     92     }
     93 
     94     void bindPipeline(const GrVkGpu* gpu, const GrVkPipeline* pipeline) {
     95         GR_VK_CALL(gpu->vkInterface(), CmdBindPipeline(fCmdBuffer,
     96                                                        VK_PIPELINE_BIND_POINT_GRAPHICS,
     97                                                        pipeline->pipeline()));
     98         addResource(pipeline);
     99     }
    100 
    101     void bindDescriptorSets(const GrVkGpu* gpu,
    102                             GrVkProgram*,
    103                             VkPipelineLayout layout,
    104                             uint32_t firstSet,
    105                             uint32_t setCount,
    106                             const VkDescriptorSet* descriptorSets,
    107                             uint32_t dynamicOffsetCount,
    108                             const uint32_t* dynamicOffsets);
    109 
    110     // Commands that only work outside of a render pass
    111     void clearColorImage(const GrVkGpu* gpu,
    112                          GrVkImage* image,
    113                          const VkClearColorValue* color,
    114                          uint32_t subRangeCount,
    115                          const VkImageSubresourceRange* subRanges);
    116 
    117     void copyImage(const GrVkGpu* gpu,
    118                    GrVkImage* srcImage,
    119                    VkImageLayout srcLayout,
    120                    GrVkImage* dstImage,
    121                    VkImageLayout dstLayout,
    122                    uint32_t copyRegionCount,
    123                    const VkImageCopy* copyRegions);
    124 
    125     void copyImageToBuffer(const GrVkGpu* gpu,
    126                            GrVkImage* srcImage,
    127                            VkImageLayout srcLayout,
    128                            GrVkTransferBuffer* dstBuffer,
    129                            uint32_t copyRegionCount,
    130                            const VkBufferImageCopy* copyRegions);
    131 
    132     void copyBufferToImage(const GrVkGpu* gpu,
    133                            GrVkTransferBuffer* srcBuffer,
    134                            GrVkImage* dstImage,
    135                            VkImageLayout dstLayout,
    136                            uint32_t copyRegionCount,
    137                            const VkBufferImageCopy* copyRegions);
    138 
    139     // Commands that only work inside of a render pass
    140     void clearAttachments(const GrVkGpu* gpu,
    141                           int numAttachments,
    142                           const VkClearAttachment* attachments,
    143                           int numRects,
    144                           const VkClearRect* clearRects) const;
    145 
    146     void drawIndexed(const GrVkGpu* gpu,
    147                      uint32_t indexCount,
    148                      uint32_t instanceCount,
    149                      uint32_t firstIndex,
    150                      int32_t vertexOffset,
    151                      uint32_t firstInstance) const;
    152 
    153     void draw(const GrVkGpu* gpu,
    154               uint32_t vertexCount,
    155               uint32_t instanceCount,
    156               uint32_t firstVertex,
    157               uint32_t firstInstance) const;
    158 
    159     // Add ref-counted resource that will be tracked and released when this
    160     // command buffer finishes execution
    161     void addResource(const GrVkResource* resource) {
    162         resource->ref();
    163         fTrackedResources.push_back(resource);
    164     }
    165 
    166 private:
    167     static const int kInitialTrackedResourcesCount = 32;
    168 
    169     explicit GrVkCommandBuffer(VkCommandBuffer cmdBuffer)
    170         : fTrackedResources(kInitialTrackedResourcesCount)
    171         , fCmdBuffer(cmdBuffer)
    172         , fSubmitFence(VK_NULL_HANDLE)
    173         , fBoundVertexBufferIsValid(false)
    174         , fBoundIndexBufferIsValid(false)
    175         , fIsActive(false)
    176         , fActiveRenderPass(nullptr) {
    177         this->invalidateState();
    178     }
    179 
    180     void freeGPUData(const GrVkGpu* gpu) const override;
    181     void abandonSubResources() const override;
    182 
    183     SkTArray<const GrVkResource*, true>     fTrackedResources;
    184 
    185     VkCommandBuffer                         fCmdBuffer;
    186     VkFence                                 fSubmitFence;
    187 
    188     VkBuffer                                fBoundVertexBuffer;
    189     bool                                    fBoundVertexBufferIsValid;
    190 
    191     VkBuffer                                fBoundIndexBuffer;
    192     bool                                    fBoundIndexBufferIsValid;
    193 
    194     // Tracks whether we are in the middle of a command buffer begin/end calls and thus can add new
    195     // commands to the buffer;
    196     bool fIsActive;
    197 
    198     // Stores a pointer to the current active render pass (i.e. begin has been called but not end).
    199     // A nullptr means there is no active render pass. The GrVKCommandBuffer does not own the render
    200     // pass.
    201     const GrVkRenderPass*     fActiveRenderPass;
    202 };
    203 
    204 
    205 #endif
    206 
    207