blob: d78676d8455b4859bdc1b23dc4a62143d7703fea [file] [log] [blame]
egdaniel066df7c2016-06-08 14:02:27 -07001/*
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#include "GrVkGpuCommandBuffer.h"
9
Greg Daniel64cc9aa2018-10-19 13:54:56 -040010#include "GrBackendDrawableInfo.h"
Robert Phillipsbe9aff22019-02-15 11:33:22 -050011#include "GrContextPriv.h"
csmartdalton29df7602016-08-31 11:55:52 -070012#include "GrFixedClip.h"
egdaniel9cb63402016-06-23 08:37:05 -070013#include "GrMesh.h"
Brian Salomon742e31d2016-12-07 17:06:19 -050014#include "GrOpFlushState.h"
egdaniel9cb63402016-06-23 08:37:05 -070015#include "GrPipeline.h"
16#include "GrRenderTargetPriv.h"
egdaniel9cb63402016-06-23 08:37:05 -070017#include "GrTexturePriv.h"
egdaniel066df7c2016-06-08 14:02:27 -070018#include "GrVkCommandBuffer.h"
Ethan Nicholas8e265a72018-12-12 16:22:40 -050019#include "GrVkCommandPool.h"
egdaniel066df7c2016-06-08 14:02:27 -070020#include "GrVkGpu.h"
egdaniel9cb63402016-06-23 08:37:05 -070021#include "GrVkPipeline.h"
egdaniel066df7c2016-06-08 14:02:27 -070022#include "GrVkRenderPass.h"
23#include "GrVkRenderTarget.h"
24#include "GrVkResourceProvider.h"
Greg Daniel64cc9aa2018-10-19 13:54:56 -040025#include "GrVkSemaphore.h"
egdaniel9cb63402016-06-23 08:37:05 -070026#include "GrVkTexture.h"
Greg Daniel64cc9aa2018-10-19 13:54:56 -040027#include "SkDrawable.h"
Greg Daniel36a77ee2016-10-18 10:33:25 -040028#include "SkRect.h"
egdaniel066df7c2016-06-08 14:02:27 -070029
Brian Salomon5d8f1cc2019-04-24 09:03:53 -040030GrVkPrimaryCommandBufferTask::~GrVkPrimaryCommandBufferTask() = default;
31GrVkPrimaryCommandBufferTask::GrVkPrimaryCommandBufferTask() = default;
32
33namespace {
34
35class InlineUpload : public GrVkPrimaryCommandBufferTask {
36public:
37 InlineUpload(GrOpFlushState* state, const GrDeferredTextureUploadFn& upload)
38 : fFlushState(state), fUpload(upload) {}
39 ~InlineUpload() override = default;
40
41 void execute(const Args& args) override { fFlushState->doUpload(fUpload); }
42
43private:
44 GrOpFlushState* fFlushState;
45 GrDeferredTextureUploadFn fUpload;
46};
47
48class Copy : public GrVkPrimaryCommandBufferTask {
49public:
50 Copy(GrSurface* src, GrSurfaceOrigin srcOrigin, const SkIRect& srcRect,
51 const SkIPoint& dstPoint, bool shouldDiscardDst)
52 : fSrc(src)
53 , fSrcOrigin(srcOrigin)
54 , fSrcRect(srcRect)
55 , fDstPoint(dstPoint)
56 , fShouldDiscardDst(shouldDiscardDst) {}
57 ~Copy() override = default;
58
59 void execute(const Args& args) override {
60 args.fGpu->copySurface(args.fSurface, args.fOrigin, fSrc.get(), fSrcOrigin, fSrcRect,
61 fDstPoint, fShouldDiscardDst);
62 }
63
64private:
65 using Src = GrPendingIOResource<GrSurface, kRead_GrIOType>;
66 Src fSrc;
67 GrSurfaceOrigin fSrcOrigin;
68 SkIRect fSrcRect;
69 SkIPoint fDstPoint;
70 bool fShouldDiscardDst;
71};
72
73} // anonymous namespace
74
75/////////////////////////////////////////////////////////////////////////////
76
Robert Phillipsb0e93a22017-08-29 08:26:54 -040077void GrVkGpuTextureCommandBuffer::copy(GrSurface* src, GrSurfaceOrigin srcOrigin,
78 const SkIRect& srcRect, const SkIPoint& dstPoint) {
Brian Salomon5d8f1cc2019-04-24 09:03:53 -040079 fTasks.emplace<Copy>(src, srcOrigin, srcRect, dstPoint, false);
Greg Daniel500d58b2017-08-24 15:59:33 -040080}
81
82void GrVkGpuTextureCommandBuffer::insertEventMarker(const char* msg) {
83 // TODO: does Vulkan have a correlate?
84}
85
86void GrVkGpuTextureCommandBuffer::submit() {
Brian Salomon5d8f1cc2019-04-24 09:03:53 -040087 GrVkPrimaryCommandBufferTask::Args taskArgs{fGpu, fTexture, fOrigin};
88 for (auto& task : fTasks) {
89 task.execute(taskArgs);
Greg Daniel500d58b2017-08-24 15:59:33 -040090 }
91}
92
Greg Daniel500d58b2017-08-24 15:59:33 -040093////////////////////////////////////////////////////////////////////////////////
94
Robert Phillips6b47c7d2017-08-29 07:24:09 -040095void get_vk_load_store_ops(GrLoadOp loadOpIn, GrStoreOp storeOpIn,
egdaniel066df7c2016-06-08 14:02:27 -070096 VkAttachmentLoadOp* loadOp, VkAttachmentStoreOp* storeOp) {
Robert Phillips95214472017-08-08 18:00:03 -040097 switch (loadOpIn) {
Robert Phillips6b47c7d2017-08-29 07:24:09 -040098 case GrLoadOp::kLoad:
egdaniel066df7c2016-06-08 14:02:27 -070099 *loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
egdaniel066df7c2016-06-08 14:02:27 -0700100 break;
Robert Phillips6b47c7d2017-08-29 07:24:09 -0400101 case GrLoadOp::kClear:
egdaniel9cb63402016-06-23 08:37:05 -0700102 *loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
103 break;
Robert Phillips6b47c7d2017-08-29 07:24:09 -0400104 case GrLoadOp::kDiscard:
egdaniel9cb63402016-06-23 08:37:05 -0700105 *loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
106 break;
107 default:
108 SK_ABORT("Invalid LoadOp");
egdaniel066df7c2016-06-08 14:02:27 -0700109 *loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
egdaniel9cb63402016-06-23 08:37:05 -0700110 }
111
Robert Phillips95214472017-08-08 18:00:03 -0400112 switch (storeOpIn) {
Robert Phillips6b47c7d2017-08-29 07:24:09 -0400113 case GrStoreOp::kStore:
egdaniel066df7c2016-06-08 14:02:27 -0700114 *storeOp = VK_ATTACHMENT_STORE_OP_STORE;
115 break;
Robert Phillips6b47c7d2017-08-29 07:24:09 -0400116 case GrStoreOp::kDiscard:
egdaniel066df7c2016-06-08 14:02:27 -0700117 *storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
118 break;
brianosman0bbc3712016-06-14 04:53:09 -0700119 default:
egdaniel9cb63402016-06-23 08:37:05 -0700120 SK_ABORT("Invalid StoreOp");
brianosman0bbc3712016-06-14 04:53:09 -0700121 *storeOp = VK_ATTACHMENT_STORE_OP_STORE;
egdaniel066df7c2016-06-08 14:02:27 -0700122 }
123}
124
Brian Salomon24d377e2019-04-23 15:24:31 -0400125GrVkGpuRTCommandBuffer::GrVkGpuRTCommandBuffer(GrVkGpu* gpu) : fGpu(gpu) {}
Brian Salomonc293a292016-11-30 13:38:32 -0500126
Greg Daniel500d58b2017-08-24 15:59:33 -0400127void GrVkGpuRTCommandBuffer::init() {
Brian Salomonc293a292016-11-30 13:38:32 -0500128 GrVkRenderPass::LoadStoreOps vkColorOps(fVkColorLoadOp, fVkColorStoreOp);
129 GrVkRenderPass::LoadStoreOps vkStencilOps(fVkStencilLoadOp, fVkStencilStoreOp);
egdaniel9cb63402016-06-23 08:37:05 -0700130
Greg Daniel36a77ee2016-10-18 10:33:25 -0400131 CommandBufferInfo& cbInfo = fCommandBufferInfos.push_back();
Brian Salomonc293a292016-11-30 13:38:32 -0500132 SkASSERT(fCommandBufferInfos.count() == 1);
Greg Daniel22bc8652017-03-22 15:45:43 -0400133 fCurrentCmdInfo = 0;
Greg Daniel36a77ee2016-10-18 10:33:25 -0400134
Robert Phillips19e51dc2017-08-09 09:30:51 -0400135 GrVkRenderTarget* vkRT = static_cast<GrVkRenderTarget*>(fRenderTarget);
136 const GrVkResourceProvider::CompatibleRPHandle& rpHandle = vkRT->compatibleRenderPassHandle();
egdaniel066df7c2016-06-08 14:02:27 -0700137 if (rpHandle.isValid()) {
Greg Daniel36a77ee2016-10-18 10:33:25 -0400138 cbInfo.fRenderPass = fGpu->resourceProvider().findRenderPass(rpHandle,
139 vkColorOps,
140 vkStencilOps);
egdaniel066df7c2016-06-08 14:02:27 -0700141 } else {
Robert Phillips19e51dc2017-08-09 09:30:51 -0400142 cbInfo.fRenderPass = fGpu->resourceProvider().findRenderPass(*vkRT,
Greg Daniel36a77ee2016-10-18 10:33:25 -0400143 vkColorOps,
144 vkStencilOps);
egdaniel066df7c2016-06-08 14:02:27 -0700145 }
146
Brian Osmancb3d0872018-10-16 15:19:28 -0400147 cbInfo.fColorClearValue.color.float32[0] = fClearColor[0];
148 cbInfo.fColorClearValue.color.float32[1] = fClearColor[1];
149 cbInfo.fColorClearValue.color.float32[2] = fClearColor[2];
150 cbInfo.fColorClearValue.color.float32[3] = fClearColor[3];
egdaniel9cb63402016-06-23 08:37:05 -0700151
Robert Phillips380b90c2017-08-30 07:41:07 -0400152 if (VK_ATTACHMENT_LOAD_OP_CLEAR == fVkColorLoadOp) {
Greg Daniela41a74a2018-10-09 12:59:23 +0000153 cbInfo.fBounds = SkRect::MakeWH(vkRT->width(), vkRT->height());
Robert Phillips380b90c2017-08-30 07:41:07 -0400154 } else {
155 cbInfo.fBounds.setEmpty();
156 }
Greg Daniela3c68df2018-03-16 13:46:53 -0400157
158 if (VK_ATTACHMENT_LOAD_OP_CLEAR == fVkColorLoadOp) {
159 cbInfo.fLoadStoreState = LoadStoreState::kStartsWithClear;
160 } else if (VK_ATTACHMENT_LOAD_OP_LOAD == fVkColorLoadOp &&
161 VK_ATTACHMENT_STORE_OP_STORE == fVkColorStoreOp) {
162 cbInfo.fLoadStoreState = LoadStoreState::kLoadAndStore;
163 } else if (VK_ATTACHMENT_LOAD_OP_DONT_CARE == fVkColorLoadOp) {
164 cbInfo.fLoadStoreState = LoadStoreState::kStartsWithDiscard;
165 }
Greg Daniel36a77ee2016-10-18 10:33:25 -0400166
Ethan Nicholas8e265a72018-12-12 16:22:40 -0500167 cbInfo.fCommandBuffers.push_back(fGpu->cmdPool()->findOrCreateSecondaryCommandBuffer(fGpu));
Robert Phillips19e51dc2017-08-09 09:30:51 -0400168 cbInfo.currentCmdBuf()->begin(fGpu, vkRT->framebuffer(), cbInfo.fRenderPass);
egdaniel066df7c2016-06-08 14:02:27 -0700169}
170
Greg Daniel070cbaf2019-01-03 17:35:54 -0500171void GrVkGpuRTCommandBuffer::initWrapped() {
172 CommandBufferInfo& cbInfo = fCommandBufferInfos.push_back();
173 SkASSERT(fCommandBufferInfos.count() == 1);
174 fCurrentCmdInfo = 0;
175
176 GrVkRenderTarget* vkRT = static_cast<GrVkRenderTarget*>(fRenderTarget);
177 SkASSERT(vkRT->wrapsSecondaryCommandBuffer());
178 cbInfo.fRenderPass = vkRT->externalRenderPass();
179 cbInfo.fRenderPass->ref();
180
181 cbInfo.fBounds.setEmpty();
182 cbInfo.fCommandBuffers.push_back(vkRT->getExternalSecondaryCommandBuffer());
183 cbInfo.fCommandBuffers[0]->ref();
184 cbInfo.currentCmdBuf()->begin(fGpu, nullptr, cbInfo.fRenderPass);
185}
Brian Salomonc293a292016-11-30 13:38:32 -0500186
Greg Daniel500d58b2017-08-24 15:59:33 -0400187GrVkGpuRTCommandBuffer::~GrVkGpuRTCommandBuffer() {
Robert Phillips5b5d84c2018-08-09 15:12:18 -0400188 this->reset();
egdaniel066df7c2016-06-08 14:02:27 -0700189}
190
Greg Daniel500d58b2017-08-24 15:59:33 -0400191GrGpu* GrVkGpuRTCommandBuffer::gpu() { return fGpu; }
egdaniel9cb63402016-06-23 08:37:05 -0700192
Greg Daniel500d58b2017-08-24 15:59:33 -0400193void GrVkGpuRTCommandBuffer::end() {
Greg Daniel22bc8652017-03-22 15:45:43 -0400194 if (fCurrentCmdInfo >= 0) {
195 fCommandBufferInfos[fCurrentCmdInfo].currentCmdBuf()->end(fGpu);
Brian Salomonc293a292016-11-30 13:38:32 -0500196 }
egdaniel066df7c2016-06-08 14:02:27 -0700197}
198
Greg Daniel500d58b2017-08-24 15:59:33 -0400199void GrVkGpuRTCommandBuffer::submit() {
Brian Salomonc293a292016-11-30 13:38:32 -0500200 if (!fRenderTarget) {
201 return;
202 }
Robert Phillips19e51dc2017-08-09 09:30:51 -0400203
204 GrVkRenderTarget* vkRT = static_cast<GrVkRenderTarget*>(fRenderTarget);
Robert Phillips19e51dc2017-08-09 09:30:51 -0400205 GrVkImage* targetImage = vkRT->msaaImage() ? vkRT->msaaImage() : vkRT;
Greg Daniel45a44de2018-02-27 10:07:29 -0500206 GrStencilAttachment* stencil = fRenderTarget->renderTargetPriv().getStencilAttachment();
Brian Salomon24d377e2019-04-23 15:24:31 -0400207 auto currPreCmd = fPreCommandBufferTasks.begin();
egdaniel9cb63402016-06-23 08:37:05 -0700208
Brian Salomon5d8f1cc2019-04-24 09:03:53 -0400209 GrVkPrimaryCommandBufferTask::Args taskArgs{fGpu, fRenderTarget, fOrigin};
Greg Daniel36a77ee2016-10-18 10:33:25 -0400210 for (int i = 0; i < fCommandBufferInfos.count(); ++i) {
211 CommandBufferInfo& cbInfo = fCommandBufferInfos[i];
212
Brian Salomon24d377e2019-04-23 15:24:31 -0400213 for (int c = 0; c < cbInfo.fNumPreCmds; ++c, ++currPreCmd) {
Brian Salomon5d8f1cc2019-04-24 09:03:53 -0400214 currPreCmd->execute(taskArgs);
Greg Daniel77b53f62016-10-18 11:48:51 -0400215 }
216
Greg Daniel38c3d932018-03-16 14:22:30 -0400217 // TODO: Many things create a scratch texture which adds the discard immediately, but then
218 // don't draw to it right away. This causes the discard to be ignored and we get yelled at
219 // for loading uninitialized data. However, once MDB lands with reordering, the discard will
220 // get reordered with the rest of the draw commands and we can remove the discard check.
221 if (cbInfo.fIsEmpty &&
222 cbInfo.fLoadStoreState != LoadStoreState::kStartsWithClear &&
223 cbInfo.fLoadStoreState != LoadStoreState::kStartsWithDiscard) {
Greg Daniel77b53f62016-10-18 11:48:51 -0400224 // We have sumbitted no actual draw commands to the command buffer and we are not using
225 // the render pass to do a clear so there is no need to submit anything.
226 continue;
227 }
Greg Daniel38c3d932018-03-16 14:22:30 -0400228
Greg Daniel070cbaf2019-01-03 17:35:54 -0500229 // We don't want to actually submit the secondary command buffer if it is wrapped.
230 if (this->wrapsSecondaryCommandBuffer()) {
231 // If we have any sampled images set their layout now.
Chris Dalton298238a2019-02-21 16:28:44 -0500232 for (int j = 0; j < cbInfo.fSampledTextures.count(); ++j) {
233 cbInfo.fSampledTextures[j]->setImageLayout(
234 fGpu, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_ACCESS_SHADER_READ_BIT,
235 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, false);
Greg Daniel070cbaf2019-01-03 17:35:54 -0500236 }
237
238 // There should have only been one secondary command buffer in the wrapped case so it is
239 // safe to just return here.
240 SkASSERT(fCommandBufferInfos.count() == 1);
241 return;
242 }
243
Greg Danieldbdba602018-04-20 11:52:43 -0400244 // Make sure if we only have a discard load that we execute the discard on the whole image.
245 // TODO: Once we improve our tracking of discards so that we never end up flushing a discard
246 // call with no actually ops, remove this.
247 if (cbInfo.fIsEmpty && cbInfo.fLoadStoreState == LoadStoreState::kStartsWithDiscard) {
Greg Daniela41a74a2018-10-09 12:59:23 +0000248 cbInfo.fBounds = SkRect::MakeWH(vkRT->width(), vkRT->height());
Greg Danieldbdba602018-04-20 11:52:43 -0400249 }
250
Greg Daniela41a74a2018-10-09 12:59:23 +0000251 if (cbInfo.fBounds.intersect(0, 0,
252 SkIntToScalar(fRenderTarget->width()),
253 SkIntToScalar(fRenderTarget->height()))) {
Greg Daniel38c3d932018-03-16 14:22:30 -0400254 // Make sure we do the following layout changes after all copies, uploads, or any other
255 // pre-work is done since we may change the layouts in the pre-work. Also since the
256 // draws will be submitted in different render passes, we need to guard againts write
257 // and write issues.
258
259 // Change layout of our render target so it can be used as the color attachment.
Greg Danielf7828d02018-10-09 12:01:32 -0400260 // TODO: If we know that we will never be blending or loading the attachment we could
261 // drop the VK_ACCESS_COLOR_ATTACHMENT_READ_BIT.
Greg Daniel38c3d932018-03-16 14:22:30 -0400262 targetImage->setImageLayout(fGpu,
263 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
Greg Danielf7828d02018-10-09 12:01:32 -0400264 VK_ACCESS_COLOR_ATTACHMENT_READ_BIT |
Greg Daniel38c3d932018-03-16 14:22:30 -0400265 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
Greg Danielf7828d02018-10-09 12:01:32 -0400266 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
Greg Daniel38c3d932018-03-16 14:22:30 -0400267 false);
268
269 // If we are using a stencil attachment we also need to update its layout
270 if (stencil) {
271 GrVkStencilAttachment* vkStencil = (GrVkStencilAttachment*)stencil;
Greg Danielf7828d02018-10-09 12:01:32 -0400272 // We need the write and read access bits since we may load and store the stencil.
273 // The initial load happens in the VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT so we
274 // wait there.
Greg Daniel38c3d932018-03-16 14:22:30 -0400275 vkStencil->setImageLayout(fGpu,
276 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
277 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT |
278 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT,
Greg Danielf7828d02018-10-09 12:01:32 -0400279 VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT,
Greg Daniel38c3d932018-03-16 14:22:30 -0400280 false);
281 }
282
283 // If we have any sampled images set their layout now.
Chris Dalton298238a2019-02-21 16:28:44 -0500284 for (int j = 0; j < cbInfo.fSampledTextures.count(); ++j) {
285 cbInfo.fSampledTextures[j]->setImageLayout(
286 fGpu, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_ACCESS_SHADER_READ_BIT,
287 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, false);
Greg Daniel38c3d932018-03-16 14:22:30 -0400288 }
289
Greg Daniel36a77ee2016-10-18 10:33:25 -0400290 SkIRect iBounds;
291 cbInfo.fBounds.roundOut(&iBounds);
292
Greg Daniel22bc8652017-03-22 15:45:43 -0400293 fGpu->submitSecondaryCommandBuffer(cbInfo.fCommandBuffers, cbInfo.fRenderPass,
Robert Phillipsb0e93a22017-08-29 08:26:54 -0400294 &cbInfo.fColorClearValue, vkRT, fOrigin, iBounds);
Greg Daniel36a77ee2016-10-18 10:33:25 -0400295 }
296 }
Brian Salomon24d377e2019-04-23 15:24:31 -0400297 SkASSERT(currPreCmd == fPreCommandBufferTasks.end());
egdaniel9cb63402016-06-23 08:37:05 -0700298}
299
Robert Phillips5b5d84c2018-08-09 15:12:18 -0400300void GrVkGpuRTCommandBuffer::set(GrRenderTarget* rt, GrSurfaceOrigin origin,
301 const GrGpuRTCommandBuffer::LoadAndStoreInfo& colorInfo,
302 const GrGpuRTCommandBuffer::StencilLoadAndStoreInfo& stencilInfo) {
303 SkASSERT(!fRenderTarget);
304 SkASSERT(fCommandBufferInfos.empty());
305 SkASSERT(-1 == fCurrentCmdInfo);
Robert Phillips9da87e02019-02-04 13:26:26 -0500306 SkASSERT(fGpu == rt->getContext()->priv().getGpu());
Robert Phillips5b5d84c2018-08-09 15:12:18 -0400307 SkASSERT(!fLastPipelineState);
308
309 this->INHERITED::set(rt, origin);
310
Greg Daniel070cbaf2019-01-03 17:35:54 -0500311 if (this->wrapsSecondaryCommandBuffer()) {
312 this->initWrapped();
313 return;
314 }
315
Brian Osman9a9baae2018-11-05 15:06:26 -0500316 fClearColor = colorInfo.fClearColor;
Robert Phillips5b5d84c2018-08-09 15:12:18 -0400317
318 get_vk_load_store_ops(colorInfo.fLoadOp, colorInfo.fStoreOp,
319 &fVkColorLoadOp, &fVkColorStoreOp);
320
321 get_vk_load_store_ops(stencilInfo.fLoadOp, stencilInfo.fStoreOp,
322 &fVkStencilLoadOp, &fVkStencilStoreOp);
323
324 this->init();
325}
326
327void GrVkGpuRTCommandBuffer::reset() {
328 for (int i = 0; i < fCommandBufferInfos.count(); ++i) {
329 CommandBufferInfo& cbInfo = fCommandBufferInfos[i];
330 for (int j = 0; j < cbInfo.fCommandBuffers.count(); ++j) {
331 cbInfo.fCommandBuffers[j]->unref(fGpu);
332 }
333 cbInfo.fRenderPass->unref(fGpu);
334 }
335 fCommandBufferInfos.reset();
Brian Salomon24d377e2019-04-23 15:24:31 -0400336 fPreCommandBufferTasks.reset();
Robert Phillips5b5d84c2018-08-09 15:12:18 -0400337
338 fCurrentCmdInfo = -1;
339
340 fLastPipelineState = nullptr;
341 fRenderTarget = nullptr;
342}
343
Greg Daniel070cbaf2019-01-03 17:35:54 -0500344bool GrVkGpuRTCommandBuffer::wrapsSecondaryCommandBuffer() const {
345 GrVkRenderTarget* vkRT = static_cast<GrVkRenderTarget*>(fRenderTarget);
346 return vkRT->wrapsSecondaryCommandBuffer();
347}
348
Greg Daniel64cc9aa2018-10-19 13:54:56 -0400349////////////////////////////////////////////////////////////////////////////////
350
Greg Daniel500d58b2017-08-24 15:59:33 -0400351void GrVkGpuRTCommandBuffer::discard() {
Robert Phillips19e51dc2017-08-09 09:30:51 -0400352 GrVkRenderTarget* vkRT = static_cast<GrVkRenderTarget*>(fRenderTarget);
Brian Salomonc293a292016-11-30 13:38:32 -0500353
Greg Daniel22bc8652017-03-22 15:45:43 -0400354 CommandBufferInfo& cbInfo = fCommandBufferInfos[fCurrentCmdInfo];
Greg Daniel77b53f62016-10-18 11:48:51 -0400355 if (cbInfo.fIsEmpty) {
Robert Phillips74c627f2017-08-09 10:28:00 -0400356 // Change the render pass to do a don't-care load for both color & stencil
egdaniel37535c92016-06-30 08:23:30 -0700357 GrVkRenderPass::LoadStoreOps vkColorOps(VK_ATTACHMENT_LOAD_OP_DONT_CARE,
358 VK_ATTACHMENT_STORE_OP_STORE);
359 GrVkRenderPass::LoadStoreOps vkStencilOps(VK_ATTACHMENT_LOAD_OP_DONT_CARE,
360 VK_ATTACHMENT_STORE_OP_STORE);
egdaniel37535c92016-06-30 08:23:30 -0700361
Greg Daniel36a77ee2016-10-18 10:33:25 -0400362 const GrVkRenderPass* oldRP = cbInfo.fRenderPass;
egdaniel37535c92016-06-30 08:23:30 -0700363
egdaniel37535c92016-06-30 08:23:30 -0700364 const GrVkResourceProvider::CompatibleRPHandle& rpHandle =
Robert Phillips19e51dc2017-08-09 09:30:51 -0400365 vkRT->compatibleRenderPassHandle();
egdaniel37535c92016-06-30 08:23:30 -0700366 if (rpHandle.isValid()) {
Greg Daniel36a77ee2016-10-18 10:33:25 -0400367 cbInfo.fRenderPass = fGpu->resourceProvider().findRenderPass(rpHandle,
368 vkColorOps,
369 vkStencilOps);
egdaniel37535c92016-06-30 08:23:30 -0700370 } else {
Robert Phillips19e51dc2017-08-09 09:30:51 -0400371 cbInfo.fRenderPass = fGpu->resourceProvider().findRenderPass(*vkRT,
Greg Daniel36a77ee2016-10-18 10:33:25 -0400372 vkColorOps,
373 vkStencilOps);
egdaniel37535c92016-06-30 08:23:30 -0700374 }
375
Greg Daniel36a77ee2016-10-18 10:33:25 -0400376 SkASSERT(cbInfo.fRenderPass->isCompatible(*oldRP));
egdaniel37535c92016-06-30 08:23:30 -0700377 oldRP->unref(fGpu);
Greg Daniel5011f852016-10-28 15:07:16 -0400378 cbInfo.fBounds.join(fRenderTarget->getBoundsRect());
Greg Daniela3c68df2018-03-16 13:46:53 -0400379 cbInfo.fLoadStoreState = LoadStoreState::kStartsWithDiscard;
egdaniel37535c92016-06-30 08:23:30 -0700380 }
381}
382
Greg Daniel500d58b2017-08-24 15:59:33 -0400383void GrVkGpuRTCommandBuffer::insertEventMarker(const char* msg) {
Robert Phillips65a88fa2017-08-08 08:36:22 -0400384 // TODO: does Vulkan have a correlate?
385}
386
Greg Daniel500d58b2017-08-24 15:59:33 -0400387void GrVkGpuRTCommandBuffer::onClearStencilClip(const GrFixedClip& clip, bool insideStencilMask) {
Chris Dalton94c04682017-11-01 17:15:06 -0600388 SkASSERT(!clip.hasWindowRectangles());
389
Jim Van Verth6a40abc2017-11-02 16:56:09 +0000390 CommandBufferInfo& cbInfo = fCommandBufferInfos[fCurrentCmdInfo];
391
Greg Daniel65a09272016-10-12 09:47:22 -0400392 GrStencilAttachment* sb = fRenderTarget->renderTargetPriv().getStencilAttachment();
egdaniel9cb63402016-06-23 08:37:05 -0700393 // this should only be called internally when we know we have a
394 // stencil buffer.
395 SkASSERT(sb);
396 int stencilBitCount = sb->bits();
397
398 // The contract with the callers does not guarantee that we preserve all bits in the stencil
399 // during this clear. Thus we will clear the entire stencil to the desired value.
400
401 VkClearDepthStencilValue vkStencilColor;
402 memset(&vkStencilColor, 0, sizeof(VkClearDepthStencilValue));
csmartdalton29df7602016-08-31 11:55:52 -0700403 if (insideStencilMask) {
egdaniel9cb63402016-06-23 08:37:05 -0700404 vkStencilColor.stencil = (1 << (stencilBitCount - 1));
405 } else {
406 vkStencilColor.stencil = 0;
407 }
408
409 VkClearRect clearRect;
410 // Flip rect if necessary
csmartdalton29df7602016-08-31 11:55:52 -0700411 SkIRect vkRect;
Brian Salomond818ebf2018-07-02 14:08:49 +0000412 if (!clip.scissorEnabled()) {
Greg Daniela41a74a2018-10-09 12:59:23 +0000413 vkRect.setXYWH(0, 0, fRenderTarget->width(), fRenderTarget->height());
Robert Phillips4f101a72017-07-28 08:42:04 -0400414 } else if (kBottomLeft_GrSurfaceOrigin != fOrigin) {
csmartdalton29df7602016-08-31 11:55:52 -0700415 vkRect = clip.scissorRect();
416 } else {
417 const SkIRect& scissor = clip.scissorRect();
Greg Daniel65a09272016-10-12 09:47:22 -0400418 vkRect.setLTRB(scissor.fLeft, fRenderTarget->height() - scissor.fBottom,
419 scissor.fRight, fRenderTarget->height() - scissor.fTop);
egdaniel9cb63402016-06-23 08:37:05 -0700420 }
421
422 clearRect.rect.offset = { vkRect.fLeft, vkRect.fTop };
423 clearRect.rect.extent = { (uint32_t)vkRect.width(), (uint32_t)vkRect.height() };
424
425 clearRect.baseArrayLayer = 0;
426 clearRect.layerCount = 1;
427
428 uint32_t stencilIndex;
Greg Daniel36a77ee2016-10-18 10:33:25 -0400429 SkAssertResult(cbInfo.fRenderPass->stencilAttachmentIndex(&stencilIndex));
egdaniel9cb63402016-06-23 08:37:05 -0700430
431 VkClearAttachment attachment;
432 attachment.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT;
433 attachment.colorAttachment = 0; // this value shouldn't matter
434 attachment.clearValue.depthStencil = vkStencilColor;
435
Greg Daniel22bc8652017-03-22 15:45:43 -0400436 cbInfo.currentCmdBuf()->clearAttachments(fGpu, 1, &attachment, 1, &clearRect);
Greg Daniel77b53f62016-10-18 11:48:51 -0400437 cbInfo.fIsEmpty = false;
Greg Daniel36a77ee2016-10-18 10:33:25 -0400438
439 // Update command buffer bounds
Brian Salomond818ebf2018-07-02 14:08:49 +0000440 if (!clip.scissorEnabled()) {
Greg Daniel36a77ee2016-10-18 10:33:25 -0400441 cbInfo.fBounds.join(fRenderTarget->getBoundsRect());
442 } else {
443 cbInfo.fBounds.join(SkRect::Make(clip.scissorRect()));
444 }
egdaniel9cb63402016-06-23 08:37:05 -0700445}
446
Brian Osman9a9baae2018-11-05 15:06:26 -0500447void GrVkGpuRTCommandBuffer::onClear(const GrFixedClip& clip, const SkPMColor4f& color) {
Robert Phillips19e51dc2017-08-09 09:30:51 -0400448 GrVkRenderTarget* vkRT = static_cast<GrVkRenderTarget*>(fRenderTarget);
449
Jim Van Verth6a40abc2017-11-02 16:56:09 +0000450 // parent class should never let us get here with no RT
csmartdaltonbf4a8f92016-09-06 10:01:06 -0700451 SkASSERT(!clip.hasWindowRectangles());
egdaniel9cb63402016-06-23 08:37:05 -0700452
Greg Daniel22bc8652017-03-22 15:45:43 -0400453 CommandBufferInfo& cbInfo = fCommandBufferInfos[fCurrentCmdInfo];
Greg Daniel36a77ee2016-10-18 10:33:25 -0400454
Brian Osman9a9baae2018-11-05 15:06:26 -0500455 VkClearColorValue vkColor = {{color.fR, color.fG, color.fB, color.fA}};
egdaniel9cb63402016-06-23 08:37:05 -0700456
Brian Salomond818ebf2018-07-02 14:08:49 +0000457 if (cbInfo.fIsEmpty && !clip.scissorEnabled()) {
Robert Phillips74c627f2017-08-09 10:28:00 -0400458 // Change the render pass to do a clear load
egdaniel9cb63402016-06-23 08:37:05 -0700459 GrVkRenderPass::LoadStoreOps vkColorOps(VK_ATTACHMENT_LOAD_OP_CLEAR,
460 VK_ATTACHMENT_STORE_OP_STORE);
Robert Phillips74c627f2017-08-09 10:28:00 -0400461 // Preserve the stencil buffer's load & store settings
462 GrVkRenderPass::LoadStoreOps vkStencilOps(fVkStencilLoadOp, fVkStencilStoreOp);
egdaniel9cb63402016-06-23 08:37:05 -0700463
Greg Daniel36a77ee2016-10-18 10:33:25 -0400464 const GrVkRenderPass* oldRP = cbInfo.fRenderPass;
egdaniel9cb63402016-06-23 08:37:05 -0700465
466 const GrVkResourceProvider::CompatibleRPHandle& rpHandle =
Robert Phillips19e51dc2017-08-09 09:30:51 -0400467 vkRT->compatibleRenderPassHandle();
egdaniel9cb63402016-06-23 08:37:05 -0700468 if (rpHandle.isValid()) {
Greg Daniel36a77ee2016-10-18 10:33:25 -0400469 cbInfo.fRenderPass = fGpu->resourceProvider().findRenderPass(rpHandle,
470 vkColorOps,
471 vkStencilOps);
egdaniel9cb63402016-06-23 08:37:05 -0700472 } else {
Robert Phillips19e51dc2017-08-09 09:30:51 -0400473 cbInfo.fRenderPass = fGpu->resourceProvider().findRenderPass(*vkRT,
Greg Daniel36a77ee2016-10-18 10:33:25 -0400474 vkColorOps,
475 vkStencilOps);
egdaniel9cb63402016-06-23 08:37:05 -0700476 }
477
Greg Daniel36a77ee2016-10-18 10:33:25 -0400478 SkASSERT(cbInfo.fRenderPass->isCompatible(*oldRP));
egdaniel9cb63402016-06-23 08:37:05 -0700479 oldRP->unref(fGpu);
480
Brian Osman9a9baae2018-11-05 15:06:26 -0500481 cbInfo.fColorClearValue.color = {{color.fR, color.fG, color.fB, color.fA}};
Greg Daniela3c68df2018-03-16 13:46:53 -0400482 cbInfo.fLoadStoreState = LoadStoreState::kStartsWithClear;
Greg Daniel36a77ee2016-10-18 10:33:25 -0400483 // Update command buffer bounds
484 cbInfo.fBounds.join(fRenderTarget->getBoundsRect());
egdaniel9cb63402016-06-23 08:37:05 -0700485 return;
486 }
487
488 // We always do a sub rect clear with clearAttachments since we are inside a render pass
489 VkClearRect clearRect;
490 // Flip rect if necessary
csmartdalton29df7602016-08-31 11:55:52 -0700491 SkIRect vkRect;
Brian Salomond818ebf2018-07-02 14:08:49 +0000492 if (!clip.scissorEnabled()) {
Greg Daniela41a74a2018-10-09 12:59:23 +0000493 vkRect.setXYWH(0, 0, fRenderTarget->width(), fRenderTarget->height());
Robert Phillips4f101a72017-07-28 08:42:04 -0400494 } else if (kBottomLeft_GrSurfaceOrigin != fOrigin) {
csmartdalton29df7602016-08-31 11:55:52 -0700495 vkRect = clip.scissorRect();
496 } else {
497 const SkIRect& scissor = clip.scissorRect();
Greg Daniel65a09272016-10-12 09:47:22 -0400498 vkRect.setLTRB(scissor.fLeft, fRenderTarget->height() - scissor.fBottom,
499 scissor.fRight, fRenderTarget->height() - scissor.fTop);
egdaniel9cb63402016-06-23 08:37:05 -0700500 }
501 clearRect.rect.offset = { vkRect.fLeft, vkRect.fTop };
502 clearRect.rect.extent = { (uint32_t)vkRect.width(), (uint32_t)vkRect.height() };
503 clearRect.baseArrayLayer = 0;
504 clearRect.layerCount = 1;
505
506 uint32_t colorIndex;
Greg Daniel36a77ee2016-10-18 10:33:25 -0400507 SkAssertResult(cbInfo.fRenderPass->colorAttachmentIndex(&colorIndex));
egdaniel9cb63402016-06-23 08:37:05 -0700508
509 VkClearAttachment attachment;
510 attachment.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
511 attachment.colorAttachment = colorIndex;
512 attachment.clearValue.color = vkColor;
513
Greg Daniel22bc8652017-03-22 15:45:43 -0400514 cbInfo.currentCmdBuf()->clearAttachments(fGpu, 1, &attachment, 1, &clearRect);
Greg Daniel77b53f62016-10-18 11:48:51 -0400515 cbInfo.fIsEmpty = false;
Greg Daniel36a77ee2016-10-18 10:33:25 -0400516
517 // Update command buffer bounds
Brian Salomond818ebf2018-07-02 14:08:49 +0000518 if (!clip.scissorEnabled()) {
Greg Daniel36a77ee2016-10-18 10:33:25 -0400519 cbInfo.fBounds.join(fRenderTarget->getBoundsRect());
520 } else {
521 cbInfo.fBounds.join(SkRect::Make(clip.scissorRect()));
522 }
egdaniel9cb63402016-06-23 08:37:05 -0700523 return;
524}
525
Greg Daniel500d58b2017-08-24 15:59:33 -0400526////////////////////////////////////////////////////////////////////////////////
527
528void GrVkGpuRTCommandBuffer::addAdditionalCommandBuffer() {
Robert Phillips19e51dc2017-08-09 09:30:51 -0400529 GrVkRenderTarget* vkRT = static_cast<GrVkRenderTarget*>(fRenderTarget);
530
Greg Daniel22bc8652017-03-22 15:45:43 -0400531 CommandBufferInfo& cbInfo = fCommandBufferInfos[fCurrentCmdInfo];
532 cbInfo.currentCmdBuf()->end(fGpu);
Ethan Nicholas8e265a72018-12-12 16:22:40 -0500533 cbInfo.fCommandBuffers.push_back(fGpu->cmdPool()->findOrCreateSecondaryCommandBuffer(fGpu));
Robert Phillips19e51dc2017-08-09 09:30:51 -0400534 cbInfo.currentCmdBuf()->begin(fGpu, vkRT->framebuffer(), cbInfo.fRenderPass);
Greg Daniel22bc8652017-03-22 15:45:43 -0400535}
536
Greg Daniel500d58b2017-08-24 15:59:33 -0400537void GrVkGpuRTCommandBuffer::addAdditionalRenderPass() {
Robert Phillips19e51dc2017-08-09 09:30:51 -0400538 GrVkRenderTarget* vkRT = static_cast<GrVkRenderTarget*>(fRenderTarget);
539
Greg Daniel22bc8652017-03-22 15:45:43 -0400540 fCommandBufferInfos[fCurrentCmdInfo].currentCmdBuf()->end(fGpu);
Greg Daniel77b53f62016-10-18 11:48:51 -0400541
542 CommandBufferInfo& cbInfo = fCommandBufferInfos.push_back();
Greg Daniel22bc8652017-03-22 15:45:43 -0400543 fCurrentCmdInfo++;
Greg Daniel77b53f62016-10-18 11:48:51 -0400544
545 GrVkRenderPass::LoadStoreOps vkColorOps(VK_ATTACHMENT_LOAD_OP_LOAD,
546 VK_ATTACHMENT_STORE_OP_STORE);
547 GrVkRenderPass::LoadStoreOps vkStencilOps(VK_ATTACHMENT_LOAD_OP_LOAD,
548 VK_ATTACHMENT_STORE_OP_STORE);
549
550 const GrVkResourceProvider::CompatibleRPHandle& rpHandle =
Robert Phillips19e51dc2017-08-09 09:30:51 -0400551 vkRT->compatibleRenderPassHandle();
Greg Daniel77b53f62016-10-18 11:48:51 -0400552 if (rpHandle.isValid()) {
553 cbInfo.fRenderPass = fGpu->resourceProvider().findRenderPass(rpHandle,
554 vkColorOps,
555 vkStencilOps);
556 } else {
Robert Phillips19e51dc2017-08-09 09:30:51 -0400557 cbInfo.fRenderPass = fGpu->resourceProvider().findRenderPass(*vkRT,
Greg Daniel77b53f62016-10-18 11:48:51 -0400558 vkColorOps,
559 vkStencilOps);
560 }
Greg Daniela3c68df2018-03-16 13:46:53 -0400561 cbInfo.fLoadStoreState = LoadStoreState::kLoadAndStore;
Greg Daniel77b53f62016-10-18 11:48:51 -0400562
Ethan Nicholas8e265a72018-12-12 16:22:40 -0500563 cbInfo.fCommandBuffers.push_back(fGpu->cmdPool()->findOrCreateSecondaryCommandBuffer(fGpu));
Greg Daniel77b53f62016-10-18 11:48:51 -0400564 // It shouldn't matter what we set the clear color to here since we will assume loading of the
565 // attachment.
566 memset(&cbInfo.fColorClearValue, 0, sizeof(VkClearValue));
567 cbInfo.fBounds.setEmpty();
Greg Daniel77b53f62016-10-18 11:48:51 -0400568
Robert Phillips19e51dc2017-08-09 09:30:51 -0400569 cbInfo.currentCmdBuf()->begin(fGpu, vkRT->framebuffer(), cbInfo.fRenderPass);
Greg Daniel77b53f62016-10-18 11:48:51 -0400570}
571
Brian Salomon943ed792017-10-30 09:37:55 -0400572void GrVkGpuRTCommandBuffer::inlineUpload(GrOpFlushState* state,
573 GrDeferredTextureUploadFn& upload) {
Greg Daniel22bc8652017-03-22 15:45:43 -0400574 if (!fCommandBufferInfos[fCurrentCmdInfo].fIsEmpty) {
575 this->addAdditionalRenderPass();
Greg Daniel77b53f62016-10-18 11:48:51 -0400576 }
Brian Salomon24d377e2019-04-23 15:24:31 -0400577
Brian Salomon24d377e2019-04-23 15:24:31 -0400578 fPreCommandBufferTasks.emplace<InlineUpload>(state, upload);
579 ++fCommandBufferInfos[fCurrentCmdInfo].fNumPreCmds;
Greg Daniel77b53f62016-10-18 11:48:51 -0400580}
581
Robert Phillipsb0e93a22017-08-29 08:26:54 -0400582void GrVkGpuRTCommandBuffer::copy(GrSurface* src, GrSurfaceOrigin srcOrigin, const SkIRect& srcRect,
Greg Daniel500d58b2017-08-24 15:59:33 -0400583 const SkIPoint& dstPoint) {
Greg Daniela3c68df2018-03-16 13:46:53 -0400584 CommandBufferInfo& cbInfo = fCommandBufferInfos[fCurrentCmdInfo];
585 if (!cbInfo.fIsEmpty || LoadStoreState::kStartsWithClear == cbInfo.fLoadStoreState) {
Greg Daniel500d58b2017-08-24 15:59:33 -0400586 this->addAdditionalRenderPass();
587 }
Greg Daniela3c68df2018-03-16 13:46:53 -0400588
Brian Salomon24d377e2019-04-23 15:24:31 -0400589 fPreCommandBufferTasks.emplace<Copy>(
Greg Daniel55fa6472018-03-16 16:13:10 -0400590 src, srcOrigin, srcRect, dstPoint,
591 LoadStoreState::kStartsWithDiscard == cbInfo.fLoadStoreState);
Brian Salomon24d377e2019-04-23 15:24:31 -0400592 ++fCommandBufferInfos[fCurrentCmdInfo].fNumPreCmds;
Greg Daniel55fa6472018-03-16 16:13:10 -0400593
Greg Daniela3c68df2018-03-16 13:46:53 -0400594 if (LoadStoreState::kLoadAndStore != cbInfo.fLoadStoreState) {
595 // Change the render pass to do a load and store so we don't lose the results of our copy
596 GrVkRenderPass::LoadStoreOps vkColorOps(VK_ATTACHMENT_LOAD_OP_LOAD,
597 VK_ATTACHMENT_STORE_OP_STORE);
598 GrVkRenderPass::LoadStoreOps vkStencilOps(VK_ATTACHMENT_LOAD_OP_LOAD,
599 VK_ATTACHMENT_STORE_OP_STORE);
600
601 const GrVkRenderPass* oldRP = cbInfo.fRenderPass;
602
603 GrVkRenderTarget* vkRT = static_cast<GrVkRenderTarget*>(fRenderTarget);
604 const GrVkResourceProvider::CompatibleRPHandle& rpHandle =
605 vkRT->compatibleRenderPassHandle();
606 if (rpHandle.isValid()) {
607 cbInfo.fRenderPass = fGpu->resourceProvider().findRenderPass(rpHandle,
608 vkColorOps,
609 vkStencilOps);
610 } else {
611 cbInfo.fRenderPass = fGpu->resourceProvider().findRenderPass(*vkRT,
612 vkColorOps,
613 vkStencilOps);
614 }
615 SkASSERT(cbInfo.fRenderPass->isCompatible(*oldRP));
616 oldRP->unref(fGpu);
617
618 cbInfo.fLoadStoreState = LoadStoreState::kLoadAndStore;
619
620 }
Greg Daniel500d58b2017-08-24 15:59:33 -0400621}
622
egdaniel9cb63402016-06-23 08:37:05 -0700623////////////////////////////////////////////////////////////////////////////////
624
Brian Salomondbf70722019-02-07 11:31:24 -0500625void GrVkGpuRTCommandBuffer::bindGeometry(const GrGpuBuffer* indexBuffer,
626 const GrGpuBuffer* vertexBuffer,
627 const GrGpuBuffer* instanceBuffer) {
Chris Daltonff926502017-05-03 14:36:54 -0400628 GrVkSecondaryCommandBuffer* currCmdBuf = fCommandBufferInfos[fCurrentCmdInfo].currentCmdBuf();
egdaniel9cb63402016-06-23 08:37:05 -0700629 // There is no need to put any memory barriers to make sure host writes have finished here.
630 // When a command buffer is submitted to a queue, there is an implicit memory barrier that
631 // occurs for all host writes. Additionally, BufferMemoryBarriers are not allowed inside of
632 // an active RenderPass.
egdaniel9cb63402016-06-23 08:37:05 -0700633
Chris Dalton1d616352017-05-31 12:51:23 -0600634 // Here our vertex and instance inputs need to match the same 0-based bindings they were
635 // assigned in GrVkPipeline. That is, vertex first (if any) followed by instance.
636 uint32_t binding = 0;
637
Brian Salomon802cb312018-06-08 18:05:20 -0400638 if (vertexBuffer) {
Chris Dalton1d616352017-05-31 12:51:23 -0600639 SkASSERT(vertexBuffer);
Chris Dalton1d616352017-05-31 12:51:23 -0600640 SkASSERT(!vertexBuffer->isMapped());
641
642 currCmdBuf->bindInputBuffer(fGpu, binding++,
643 static_cast<const GrVkVertexBuffer*>(vertexBuffer));
644 }
645
Brian Salomon802cb312018-06-08 18:05:20 -0400646 if (instanceBuffer) {
Chris Dalton1d616352017-05-31 12:51:23 -0600647 SkASSERT(instanceBuffer);
Chris Dalton1d616352017-05-31 12:51:23 -0600648 SkASSERT(!instanceBuffer->isMapped());
649
650 currCmdBuf->bindInputBuffer(fGpu, binding++,
651 static_cast<const GrVkVertexBuffer*>(instanceBuffer));
652 }
Chris Daltonff926502017-05-03 14:36:54 -0400653 if (indexBuffer) {
654 SkASSERT(indexBuffer);
655 SkASSERT(!indexBuffer->isMapped());
egdaniel9cb63402016-06-23 08:37:05 -0700656
Chris Daltonff926502017-05-03 14:36:54 -0400657 currCmdBuf->bindIndexBuffer(fGpu, static_cast<const GrVkIndexBuffer*>(indexBuffer));
egdaniel9cb63402016-06-23 08:37:05 -0700658 }
659}
660
Brian Salomon49348902018-06-26 09:12:38 -0400661GrVkPipelineState* GrVkGpuRTCommandBuffer::prepareDrawState(
662 const GrPrimitiveProcessor& primProc,
663 const GrPipeline& pipeline,
664 const GrPipeline::FixedDynamicState* fixedDynamicState,
665 const GrPipeline::DynamicStateArrays* dynamicStateArrays,
666 GrPrimitiveType primitiveType) {
Greg Daniel22bc8652017-03-22 15:45:43 -0400667 CommandBufferInfo& cbInfo = fCommandBufferInfos[fCurrentCmdInfo];
668 SkASSERT(cbInfo.fRenderPass);
Greg Daniel36a77ee2016-10-18 10:33:25 -0400669
Greg Daniel99b88e02018-10-03 15:31:20 -0400670 VkRenderPass compatibleRenderPass = cbInfo.fRenderPass->vkRenderPass();
671
Greg Daniel9a51a862018-11-30 10:18:14 -0500672 const GrTextureProxy* const* primProcProxies = nullptr;
673 if (dynamicStateArrays && dynamicStateArrays->fPrimitiveProcessorTextures) {
674 primProcProxies = dynamicStateArrays->fPrimitiveProcessorTextures;
675 } else if (fixedDynamicState) {
676 primProcProxies = fixedDynamicState->fPrimitiveProcessorTextures;
677 }
678
679 SkASSERT(SkToBool(primProcProxies) == SkToBool(primProc.numTextureSamplers()));
680
Greg Daniel09eeefb2017-10-16 15:15:02 -0400681 GrVkPipelineState* pipelineState =
Robert Phillipsd0fe8752019-01-31 14:13:59 -0500682 fGpu->resourceProvider().findOrCreateCompatiblePipelineState(fRenderTarget, fOrigin,
683 pipeline,
egdaniel9cb63402016-06-23 08:37:05 -0700684 primProc,
Greg Daniel9a51a862018-11-30 10:18:14 -0500685 primProcProxies,
egdaniel9cb63402016-06-23 08:37:05 -0700686 primitiveType,
Greg Daniel99b88e02018-10-03 15:31:20 -0400687 compatibleRenderPass);
egdaniel9cb63402016-06-23 08:37:05 -0700688 if (!pipelineState) {
689 return pipelineState;
690 }
691
Greg Daniel22bc8652017-03-22 15:45:43 -0400692 if (!cbInfo.fIsEmpty &&
Greg Daniel09eeefb2017-10-16 15:15:02 -0400693 fLastPipelineState && fLastPipelineState != pipelineState &&
Greg Daniele3cd6912017-05-17 11:15:55 -0400694 fGpu->vkCaps().newCBOnPipelineChange()) {
Greg Daniel22bc8652017-03-22 15:45:43 -0400695 this->addAdditionalCommandBuffer();
696 }
Greg Daniel09eeefb2017-10-16 15:15:02 -0400697 fLastPipelineState = pipelineState;
Greg Daniel22bc8652017-03-22 15:45:43 -0400698
Brian Salomonf7232642018-09-19 08:58:08 -0400699 pipelineState->bindPipeline(fGpu, cbInfo.currentCmdBuf());
Brian Salomoncd7907b2018-08-30 08:36:18 -0400700
Robert Phillipsd0fe8752019-01-31 14:13:59 -0500701 pipelineState->setAndBindUniforms(fGpu, fRenderTarget, fOrigin,
702 primProc, pipeline, cbInfo.currentCmdBuf());
Brian Salomonf7232642018-09-19 08:58:08 -0400703
704 // Check whether we need to bind textures between each GrMesh. If not we can bind them all now.
705 bool setTextures = !(dynamicStateArrays && dynamicStateArrays->fPrimitiveProcessorTextures);
706 if (setTextures) {
Brian Salomonf7232642018-09-19 08:58:08 -0400707 pipelineState->setAndBindTextures(fGpu, primProc, pipeline, primProcProxies,
708 cbInfo.currentCmdBuf());
709 }
egdaniel9cb63402016-06-23 08:37:05 -0700710
Brian Salomond818ebf2018-07-02 14:08:49 +0000711 if (!pipeline.isScissorEnabled()) {
Robert Phillipsb0e93a22017-08-29 08:26:54 -0400712 GrVkPipeline::SetDynamicScissorRectState(fGpu, cbInfo.currentCmdBuf(),
Robert Phillipsd0fe8752019-01-31 14:13:59 -0500713 fRenderTarget, fOrigin,
714 SkIRect::MakeWH(fRenderTarget->width(),
715 fRenderTarget->height()));
Brian Salomon49348902018-06-26 09:12:38 -0400716 } else if (!dynamicStateArrays || !dynamicStateArrays->fScissorRects) {
717 SkASSERT(fixedDynamicState);
Robert Phillipsd0fe8752019-01-31 14:13:59 -0500718 GrVkPipeline::SetDynamicScissorRectState(fGpu, cbInfo.currentCmdBuf(), fRenderTarget,
719 fOrigin,
Brian Salomon49348902018-06-26 09:12:38 -0400720 fixedDynamicState->fScissorRect);
Chris Dalton46983b72017-06-06 12:27:16 -0600721 }
Robert Phillipsd0fe8752019-01-31 14:13:59 -0500722 GrVkPipeline::SetDynamicViewportState(fGpu, cbInfo.currentCmdBuf(), fRenderTarget);
723 GrVkPipeline::SetDynamicBlendConstantState(fGpu, cbInfo.currentCmdBuf(),
724 fRenderTarget->config(),
Chris Dalton46983b72017-06-06 12:27:16 -0600725 pipeline.getXferProcessor());
egdaniel9cb63402016-06-23 08:37:05 -0700726
727 return pipelineState;
728}
729
Brian Salomonff168d92018-06-23 15:17:27 -0400730void GrVkGpuRTCommandBuffer::onDraw(const GrPrimitiveProcessor& primProc,
731 const GrPipeline& pipeline,
Brian Salomon49348902018-06-26 09:12:38 -0400732 const GrPipeline::FixedDynamicState* fixedDynamicState,
733 const GrPipeline::DynamicStateArrays* dynamicStateArrays,
Greg Daniel500d58b2017-08-24 15:59:33 -0400734 const GrMesh meshes[],
Greg Daniel500d58b2017-08-24 15:59:33 -0400735 int meshCount,
736 const SkRect& bounds) {
egdaniel9cb63402016-06-23 08:37:05 -0700737 if (!meshCount) {
738 return;
739 }
Greg Danielea022cd2018-03-16 11:10:03 -0400740
741 CommandBufferInfo& cbInfo = fCommandBufferInfos[fCurrentCmdInfo];
742
Brian Salomone782f842018-07-31 13:53:11 -0400743 auto prepareSampledImage = [&](GrTexture* texture, GrSamplerState::Filter filter) {
744 GrVkTexture* vkTexture = static_cast<GrVkTexture*>(texture);
745 // We may need to resolve the texture first if it is also a render target
746 GrVkRenderTarget* texRT = static_cast<GrVkRenderTarget*>(vkTexture->asRenderTarget());
747 if (texRT) {
Greg Daniel0a77f432018-12-06 11:23:32 -0500748 fGpu->resolveRenderTargetNoFlush(texRT);
Brian Salomone782f842018-07-31 13:53:11 -0400749 }
750
751 // Check if we need to regenerate any mip maps
752 if (GrSamplerState::Filter::kMipMap == filter &&
753 (vkTexture->width() != 1 || vkTexture->height() != 1)) {
754 SkASSERT(vkTexture->texturePriv().mipMapped() == GrMipMapped::kYes);
755 if (vkTexture->texturePriv().mipMapsAreDirty()) {
756 fGpu->regenerateMipMapLevels(vkTexture);
757 }
758 }
Brian Salomon5fd10572019-04-01 12:07:05 -0400759 cbInfo.fSampledTextures.push_back(vkTexture);
Brian Salomone782f842018-07-31 13:53:11 -0400760 };
761
Brian Salomonf7232642018-09-19 08:58:08 -0400762 if (dynamicStateArrays && dynamicStateArrays->fPrimitiveProcessorTextures) {
763 for (int m = 0, i = 0; m < meshCount; ++m) {
764 for (int s = 0; s < primProc.numTextureSamplers(); ++s, ++i) {
765 auto texture = dynamicStateArrays->fPrimitiveProcessorTextures[i]->peekTexture();
766 prepareSampledImage(texture, primProc.textureSampler(s).samplerState().filter());
767 }
768 }
769 } else {
770 for (int i = 0; i < primProc.numTextureSamplers(); ++i) {
771 auto texture = fixedDynamicState->fPrimitiveProcessorTextures[i]->peekTexture();
772 prepareSampledImage(texture, primProc.textureSampler(i).samplerState().filter());
773 }
Brian Salomone782f842018-07-31 13:53:11 -0400774 }
bsalomonb58a2b42016-09-26 06:55:02 -0700775 GrFragmentProcessor::Iter iter(pipeline);
776 while (const GrFragmentProcessor* fp = iter.next()) {
Brian Salomone782f842018-07-31 13:53:11 -0400777 for (int i = 0; i < fp->numTextureSamplers(); ++i) {
778 const GrFragmentProcessor::TextureSampler& sampler = fp->textureSampler(i);
779 prepareSampledImage(sampler.peekTexture(), sampler.samplerState().filter());
780 }
egdaniel2f5792a2016-07-06 08:51:23 -0700781 }
Robert Phillipsbb581ce2017-05-29 15:05:15 -0400782 if (GrTexture* dstTexture = pipeline.peekDstTexture()) {
Chris Dalton298238a2019-02-21 16:28:44 -0500783 cbInfo.fSampledTextures.push_back(sk_ref_sp(static_cast<GrVkTexture*>(dstTexture)));
Brian Salomon18dfa982017-04-03 16:57:43 -0400784 }
egdaniel2f5792a2016-07-06 08:51:23 -0700785
Chris Daltonbca46e22017-05-15 11:03:26 -0600786 GrPrimitiveType primitiveType = meshes[0].primitiveType();
Brian Salomon49348902018-06-26 09:12:38 -0400787 GrVkPipelineState* pipelineState = this->prepareDrawState(primProc, pipeline, fixedDynamicState,
788 dynamicStateArrays, primitiveType);
egdaniel9cb63402016-06-23 08:37:05 -0700789 if (!pipelineState) {
790 return;
791 }
792
Brian Salomond818ebf2018-07-02 14:08:49 +0000793 bool dynamicScissor =
794 pipeline.isScissorEnabled() && dynamicStateArrays && dynamicStateArrays->fScissorRects;
Brian Salomonf7232642018-09-19 08:58:08 -0400795 bool dynamicTextures = dynamicStateArrays && dynamicStateArrays->fPrimitiveProcessorTextures;
Brian Salomon49348902018-06-26 09:12:38 -0400796
egdaniel9cb63402016-06-23 08:37:05 -0700797 for (int i = 0; i < meshCount; ++i) {
798 const GrMesh& mesh = meshes[i];
Chris Daltonbca46e22017-05-15 11:03:26 -0600799 if (mesh.primitiveType() != primitiveType) {
Chris Dalton6f241802017-05-08 13:58:38 -0400800 SkDEBUGCODE(pipelineState = nullptr);
Chris Daltonbca46e22017-05-15 11:03:26 -0600801 primitiveType = mesh.primitiveType();
Brian Salomon49348902018-06-26 09:12:38 -0400802 pipelineState = this->prepareDrawState(primProc, pipeline, fixedDynamicState,
803 dynamicStateArrays, primitiveType);
Chris Dalton6f241802017-05-08 13:58:38 -0400804 if (!pipelineState) {
805 return;
egdaniel9cb63402016-06-23 08:37:05 -0700806 }
Chris Dalton6f241802017-05-08 13:58:38 -0400807 }
egdaniel9cb63402016-06-23 08:37:05 -0700808
Brian Salomon49348902018-06-26 09:12:38 -0400809 if (dynamicScissor) {
810 GrVkPipeline::SetDynamicScissorRectState(fGpu, cbInfo.currentCmdBuf(), fRenderTarget,
Robert Phillipsd0fe8752019-01-31 14:13:59 -0500811 fOrigin,
Brian Salomon49348902018-06-26 09:12:38 -0400812 dynamicStateArrays->fScissorRects[i]);
Chris Dalton46983b72017-06-06 12:27:16 -0600813 }
Brian Salomonf7232642018-09-19 08:58:08 -0400814 if (dynamicTextures) {
815 GrTextureProxy* const* meshProxies = dynamicStateArrays->fPrimitiveProcessorTextures +
816 primProc.numTextureSamplers() * i;
817 pipelineState->setAndBindTextures(fGpu, primProc, pipeline, meshProxies,
818 cbInfo.currentCmdBuf());
819 }
Chris Daltonbca46e22017-05-15 11:03:26 -0600820 SkASSERT(pipelineState);
Brian Salomon802cb312018-06-08 18:05:20 -0400821 mesh.sendToGpu(this);
egdaniel9cb63402016-06-23 08:37:05 -0700822 }
823
Greg Daniel36a77ee2016-10-18 10:33:25 -0400824 cbInfo.fBounds.join(bounds);
Chris Dalton114a3c02017-05-26 15:17:19 -0600825 cbInfo.fIsEmpty = false;
egdaniel066df7c2016-06-08 14:02:27 -0700826}
827
Brian Salomon802cb312018-06-08 18:05:20 -0400828void GrVkGpuRTCommandBuffer::sendInstancedMeshToGpu(GrPrimitiveType,
Greg Daniel500d58b2017-08-24 15:59:33 -0400829 const GrBuffer* vertexBuffer,
830 int vertexCount,
831 int baseVertex,
832 const GrBuffer* instanceBuffer,
833 int instanceCount,
834 int baseInstance) {
Chris Dalton114a3c02017-05-26 15:17:19 -0600835 CommandBufferInfo& cbInfo = fCommandBufferInfos[fCurrentCmdInfo];
Brian Salomondbf70722019-02-07 11:31:24 -0500836 SkASSERT(!vertexBuffer || !vertexBuffer->isCpuBuffer());
837 SkASSERT(!instanceBuffer || !instanceBuffer->isCpuBuffer());
838 auto gpuVertexBuffer = static_cast<const GrGpuBuffer*>(vertexBuffer);
839 auto gpuInstanceBuffer = static_cast<const GrGpuBuffer*>(instanceBuffer);
840 this->bindGeometry(nullptr, gpuVertexBuffer, gpuInstanceBuffer);
Chris Dalton1d616352017-05-31 12:51:23 -0600841 cbInfo.currentCmdBuf()->draw(fGpu, vertexCount, instanceCount, baseVertex, baseInstance);
Chris Dalton114a3c02017-05-26 15:17:19 -0600842 fGpu->stats()->incNumDraws();
843}
844
Brian Salomon802cb312018-06-08 18:05:20 -0400845void GrVkGpuRTCommandBuffer::sendIndexedInstancedMeshToGpu(GrPrimitiveType,
Greg Daniel500d58b2017-08-24 15:59:33 -0400846 const GrBuffer* indexBuffer,
847 int indexCount,
848 int baseIndex,
849 const GrBuffer* vertexBuffer,
850 int baseVertex,
851 const GrBuffer* instanceBuffer,
852 int instanceCount,
Brian Salomon802cb312018-06-08 18:05:20 -0400853 int baseInstance,
854 GrPrimitiveRestart restart) {
855 SkASSERT(restart == GrPrimitiveRestart::kNo);
Chris Dalton114a3c02017-05-26 15:17:19 -0600856 CommandBufferInfo& cbInfo = fCommandBufferInfos[fCurrentCmdInfo];
Brian Salomondbf70722019-02-07 11:31:24 -0500857 SkASSERT(!vertexBuffer || !vertexBuffer->isCpuBuffer());
858 SkASSERT(!instanceBuffer || !instanceBuffer->isCpuBuffer());
859 SkASSERT(!indexBuffer->isCpuBuffer());
860 auto gpuIndexxBuffer = static_cast<const GrGpuBuffer*>(indexBuffer);
861 auto gpuVertexBuffer = static_cast<const GrGpuBuffer*>(vertexBuffer);
862 auto gpuInstanceBuffer = static_cast<const GrGpuBuffer*>(instanceBuffer);
863 this->bindGeometry(gpuIndexxBuffer, gpuVertexBuffer, gpuInstanceBuffer);
Chris Dalton1d616352017-05-31 12:51:23 -0600864 cbInfo.currentCmdBuf()->drawIndexed(fGpu, indexCount, instanceCount,
865 baseIndex, baseVertex, baseInstance);
Chris Dalton114a3c02017-05-26 15:17:19 -0600866 fGpu->stats()->incNumDraws();
867}
Greg Daniel64cc9aa2018-10-19 13:54:56 -0400868
869////////////////////////////////////////////////////////////////////////////////
870
871void GrVkGpuRTCommandBuffer::executeDrawable(std::unique_ptr<SkDrawable::GpuDrawHandler> drawable) {
872 GrVkRenderTarget* target = static_cast<GrVkRenderTarget*>(fRenderTarget);
873
874 GrVkImage* targetImage = target->msaaImage() ? target->msaaImage() : target;
875
876 CommandBufferInfo& cbInfo = fCommandBufferInfos[fCurrentCmdInfo];
877 VkRect2D bounds;
878 bounds.offset = { 0, 0 };
879 bounds.extent = { 0, 0 };
880
881 GrVkDrawableInfo vkInfo;
882 vkInfo.fSecondaryCommandBuffer = cbInfo.currentCmdBuf()->vkCommandBuffer();
883 vkInfo.fCompatibleRenderPass = cbInfo.fRenderPass->vkRenderPass();
Greg Danielb353eeb2018-12-05 11:01:58 -0500884 SkAssertResult(cbInfo.fRenderPass->colorAttachmentIndex(&vkInfo.fColorAttachmentIndex));
Greg Daniel64cc9aa2018-10-19 13:54:56 -0400885 vkInfo.fFormat = targetImage->imageFormat();
886 vkInfo.fDrawBounds = &bounds;
Stan Ilievcb580602019-02-26 11:36:07 -0500887#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
888 vkInfo.fImage = targetImage->image();
889#else
890 vkInfo.fImage = VK_NULL_HANDLE;
891#endif //SK_BUILD_FOR_ANDROID_FRAMEWORK
Greg Daniel64cc9aa2018-10-19 13:54:56 -0400892
893 GrBackendDrawableInfo info(vkInfo);
894
Eric Karlc0b2ba22019-01-22 19:40:35 -0800895 // After we draw into the command buffer via the drawable, cached state we have may be invalid.
896 cbInfo.currentCmdBuf()->invalidateState();
Eric Karla8878a12019-02-07 18:17:43 -0800897 // Also assume that the drawable produced output.
898 cbInfo.fIsEmpty = false;
Eric Karlc0b2ba22019-01-22 19:40:35 -0800899
Greg Daniel64cc9aa2018-10-19 13:54:56 -0400900 drawable->draw(info);
901 fGpu->addDrawable(std::move(drawable));
902
903 if (bounds.extent.width == 0 || bounds.extent.height == 0) {
904 cbInfo.fBounds.join(target->getBoundsRect());
905 } else {
906 cbInfo.fBounds.join(SkRect::MakeXYWH(bounds.offset.x, bounds.offset.y,
907 bounds.extent.width, bounds.extent.height));
908 }
909}
910