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