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 bindVertexBuffer(GrVkGpu * gpu,GrVkVertexBuffer * vbuffer)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 bindIndexBuffer(GrVkGpu * gpu,GrVkIndexBuffer * ibuffer)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 bindPipeline(const GrVkGpu * gpu,const GrVkPipeline * pipeline)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 addResource(const GrVkResource * resource)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 GrVkCommandBuffer(VkCommandBuffer cmdBuffer)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