GrVkGpuCommandBuffer.h 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. /*
  2. * Copyright 2016 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. #ifndef GrVkGpuCommandBuffer_DEFINED
  8. #define GrVkGpuCommandBuffer_DEFINED
  9. #include "src/gpu/GrGpuCommandBuffer.h"
  10. #include "include/gpu/GrTypes.h"
  11. #include "include/gpu/vk/GrVkTypes.h"
  12. #include "src/gpu/GrColor.h"
  13. #include "src/gpu/GrMesh.h"
  14. #include "src/gpu/GrTRecorder.h"
  15. #include "src/gpu/vk/GrVkPipelineState.h"
  16. class GrVkGpu;
  17. class GrVkImage;
  18. class GrVkRenderPass;
  19. class GrVkRenderTarget;
  20. class GrVkSecondaryCommandBuffer;
  21. /** Base class for tasks executed on primary command buffer, between secondary command buffers. */
  22. class GrVkPrimaryCommandBufferTask {
  23. public:
  24. virtual ~GrVkPrimaryCommandBufferTask();
  25. struct Args {
  26. GrGpu* fGpu;
  27. GrSurface* fSurface;
  28. };
  29. virtual void execute(const Args& args) = 0;
  30. protected:
  31. GrVkPrimaryCommandBufferTask();
  32. GrVkPrimaryCommandBufferTask(const GrVkPrimaryCommandBufferTask&) = delete;
  33. GrVkPrimaryCommandBufferTask& operator=(const GrVkPrimaryCommandBufferTask&) = delete;
  34. };
  35. class GrVkGpuTextureCommandBuffer : public GrGpuTextureCommandBuffer {
  36. public:
  37. GrVkGpuTextureCommandBuffer(GrVkGpu* gpu) : fGpu(gpu) {}
  38. void copy(GrSurface* src, const SkIRect& srcRect, const SkIPoint& dstPoint) override;
  39. void transferFrom(const SkIRect& srcRect, GrColorType bufferColorType,
  40. GrGpuBuffer* transferBuffer, size_t offset) override;
  41. void insertEventMarker(const char*) override;
  42. void reset() {
  43. fTasks.reset();
  44. fTexture = nullptr;
  45. #ifdef SK_DEBUG
  46. fIsActive = false;
  47. #endif
  48. }
  49. void setVk(GrTexture* tex, GrSurfaceOrigin origin) {
  50. #ifdef SK_DEBUG
  51. fIsActive = true;
  52. #endif
  53. this->INHERITED::set(tex, origin);
  54. }
  55. #ifdef SK_DEBUG
  56. bool isActive() const { return fIsActive; }
  57. #endif
  58. void submit();
  59. private:
  60. GrVkGpu* fGpu;
  61. GrTRecorder<GrVkPrimaryCommandBufferTask> fTasks{1024};
  62. #ifdef SK_DEBUG
  63. // When we are actively recording into the GrVkGpuCommandBuffer we set this flag to true. This
  64. // then allows us to assert that we never submit a primary command buffer to the queue while in
  65. // a recording state. This is needed since when we submit to the queue we change command pools
  66. // and may trigger the old one to be reset, but a recording GrVkGpuCommandBuffer may still have
  67. // a outstanding secondary command buffer allocated from that pool that we'll try to access
  68. // after the pool as been reset.
  69. bool fIsActive = false;
  70. #endif
  71. typedef GrGpuTextureCommandBuffer INHERITED;
  72. };
  73. class GrVkGpuRTCommandBuffer : public GrGpuRTCommandBuffer, private GrMesh::SendToGpuImpl {
  74. public:
  75. GrVkGpuRTCommandBuffer(GrVkGpu*);
  76. ~GrVkGpuRTCommandBuffer() override;
  77. void begin() override { }
  78. void end() override;
  79. void insertEventMarker(const char*) override;
  80. void inlineUpload(GrOpFlushState* state, GrDeferredTextureUploadFn& upload) override;
  81. void copy(GrSurface* src, const SkIRect& srcRect, const SkIPoint& dstPoint) override;
  82. void transferFrom(const SkIRect& srcRect, GrColorType bufferColorType,
  83. GrGpuBuffer* transferBuffer, size_t offset) override;
  84. void executeDrawable(std::unique_ptr<SkDrawable::GpuDrawHandler>) override;
  85. void set(GrRenderTarget*, GrSurfaceOrigin,
  86. const GrGpuRTCommandBuffer::LoadAndStoreInfo&,
  87. const GrGpuRTCommandBuffer::StencilLoadAndStoreInfo&);
  88. void reset();
  89. void submit();
  90. #ifdef SK_DEBUG
  91. bool isActive() const { return fIsActive; }
  92. #endif
  93. private:
  94. void init();
  95. // Called instead of init when we are drawing to a render target that already wraps a secondary
  96. // command buffer.
  97. void initWrapped();
  98. bool wrapsSecondaryCommandBuffer() const;
  99. GrGpu* gpu() override;
  100. // Bind vertex and index buffers
  101. void bindGeometry(const GrGpuBuffer* indexBuffer,
  102. const GrGpuBuffer* vertexBuffer,
  103. const GrGpuBuffer* instanceBuffer);
  104. GrVkPipelineState* prepareDrawState(const GrPrimitiveProcessor&,
  105. const GrPipeline&,
  106. const GrPipeline::FixedDynamicState*,
  107. const GrPipeline::DynamicStateArrays*,
  108. GrPrimitiveType);
  109. void onDraw(const GrPrimitiveProcessor&,
  110. const GrPipeline&,
  111. const GrPipeline::FixedDynamicState*,
  112. const GrPipeline::DynamicStateArrays*,
  113. const GrMesh[],
  114. int meshCount,
  115. const SkRect& bounds) override;
  116. // GrMesh::SendToGpuImpl methods. These issue the actual Vulkan draw commands.
  117. // Marked final as a hint to the compiler to not use virtual dispatch.
  118. void sendMeshToGpu(GrPrimitiveType primType, const GrBuffer* vertexBuffer, int vertexCount,
  119. int baseVertex) final {
  120. this->sendInstancedMeshToGpu(primType, vertexBuffer, vertexCount, baseVertex, nullptr, 1,
  121. 0);
  122. }
  123. void sendIndexedMeshToGpu(GrPrimitiveType primType, const GrBuffer* indexBuffer, int indexCount,
  124. int baseIndex, uint16_t /*minIndexValue*/, uint16_t /*maxIndexValue*/,
  125. const GrBuffer* vertexBuffer, int baseVertex,
  126. GrPrimitiveRestart restart) final {
  127. SkASSERT(restart == GrPrimitiveRestart::kNo);
  128. this->sendIndexedInstancedMeshToGpu(primType, indexBuffer, indexCount, baseIndex,
  129. vertexBuffer, baseVertex, nullptr, 1, 0,
  130. GrPrimitiveRestart::kNo);
  131. }
  132. void sendInstancedMeshToGpu(GrPrimitiveType, const GrBuffer* vertexBuffer, int vertexCount,
  133. int baseVertex, const GrBuffer* instanceBuffer, int instanceCount,
  134. int baseInstance) final;
  135. void sendIndexedInstancedMeshToGpu(GrPrimitiveType, const GrBuffer* indexBuffer, int indexCount,
  136. int baseIndex, const GrBuffer* vertexBuffer, int baseVertex,
  137. const GrBuffer* instanceBuffer, int instanceCount,
  138. int baseInstance, GrPrimitiveRestart) final;
  139. void onClear(const GrFixedClip&, const SkPMColor4f& color) override;
  140. void onClearStencilClip(const GrFixedClip&, bool insideStencilMask) override;
  141. void addAdditionalCommandBuffer();
  142. void addAdditionalRenderPass();
  143. enum class LoadStoreState {
  144. kUnknown,
  145. kStartsWithClear,
  146. kStartsWithDiscard,
  147. kLoadAndStore,
  148. };
  149. struct CommandBufferInfo {
  150. using SampledTexture = GrPendingIOResource<GrVkTexture, kRead_GrIOType>;
  151. const GrVkRenderPass* fRenderPass;
  152. SkTArray<GrVkSecondaryCommandBuffer*> fCommandBuffers;
  153. int fNumPreCmds = 0;
  154. VkClearValue fColorClearValue;
  155. SkRect fBounds;
  156. bool fIsEmpty = true;
  157. LoadStoreState fLoadStoreState = LoadStoreState::kUnknown;
  158. // Array of images that will be sampled and thus need to be transferred to sampled layout
  159. // before submitting the secondary command buffers. This must happen after we do any predraw
  160. // uploads or copies.
  161. SkTArray<SampledTexture> fSampledTextures;
  162. GrVkSecondaryCommandBuffer* currentCmdBuf() {
  163. return fCommandBuffers.back();
  164. }
  165. };
  166. SkTArray<CommandBufferInfo> fCommandBufferInfos;
  167. GrTRecorder<GrVkPrimaryCommandBufferTask> fPreCommandBufferTasks{1024};
  168. GrVkGpu* fGpu;
  169. GrVkPipelineState* fLastPipelineState = nullptr;
  170. SkPMColor4f fClearColor;
  171. VkAttachmentLoadOp fVkColorLoadOp;
  172. VkAttachmentStoreOp fVkColorStoreOp;
  173. VkAttachmentLoadOp fVkStencilLoadOp;
  174. VkAttachmentStoreOp fVkStencilStoreOp;
  175. int fCurrentCmdInfo = -1;
  176. #ifdef SK_DEBUG
  177. // When we are actively recording into the GrVkGpuCommandBuffer we set this flag to true. This
  178. // then allows us to assert that we never submit a primary command buffer to the queue while in
  179. // a recording state. This is needed since when we submit to the queue we change command pools
  180. // and may trigger the old one to be reset, but a recording GrVkGpuCommandBuffer may still have
  181. // a outstanding secondary command buffer allocated from that pool that we'll try to access
  182. // after the pool as been reset.
  183. bool fIsActive = false;
  184. #endif
  185. typedef GrGpuRTCommandBuffer INHERITED;
  186. };
  187. #endif