blob: 4a59bcfb96e09e8cea2672edc4e494f37a8b1668 [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
Robert Phillipsb0e93a22017-08-29 08:26:54 -040030void GrVkGpuTextureCommandBuffer::copy(GrSurface* src, GrSurfaceOrigin srcOrigin,
31 const SkIRect& srcRect, const SkIPoint& dstPoint) {
32 fCopies.emplace_back(src, srcOrigin, srcRect, dstPoint);
Greg Daniel500d58b2017-08-24 15:59:33 -040033}
34
35void GrVkGpuTextureCommandBuffer::insertEventMarker(const char* msg) {
36 // TODO: does Vulkan have a correlate?
37}
38
39void GrVkGpuTextureCommandBuffer::submit() {
40 for (int i = 0; i < fCopies.count(); ++i) {
41 CopyInfo& copyInfo = fCopies[i];
Chris Dalton298238a2019-02-21 16:28:44 -050042 fGpu->copySurface(fTexture, fOrigin, copyInfo.fSrc.get(), copyInfo.fSrcOrigin,
43 copyInfo.fSrcRect, copyInfo.fDstPoint);
Greg Daniel500d58b2017-08-24 15:59:33 -040044 }
45}
46
47GrVkGpuTextureCommandBuffer::~GrVkGpuTextureCommandBuffer() {}
48
49////////////////////////////////////////////////////////////////////////////////
50
Robert Phillips6b47c7d2017-08-29 07:24:09 -040051void get_vk_load_store_ops(GrLoadOp loadOpIn, GrStoreOp storeOpIn,
egdaniel066df7c2016-06-08 14:02:27 -070052 VkAttachmentLoadOp* loadOp, VkAttachmentStoreOp* storeOp) {
Robert Phillips95214472017-08-08 18:00:03 -040053 switch (loadOpIn) {
Robert Phillips6b47c7d2017-08-29 07:24:09 -040054 case GrLoadOp::kLoad:
egdaniel066df7c2016-06-08 14:02:27 -070055 *loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
egdaniel066df7c2016-06-08 14:02:27 -070056 break;
Robert Phillips6b47c7d2017-08-29 07:24:09 -040057 case GrLoadOp::kClear:
egdaniel9cb63402016-06-23 08:37:05 -070058 *loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
59 break;
Robert Phillips6b47c7d2017-08-29 07:24:09 -040060 case GrLoadOp::kDiscard:
egdaniel9cb63402016-06-23 08:37:05 -070061 *loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
62 break;
63 default:
64 SK_ABORT("Invalid LoadOp");
egdaniel066df7c2016-06-08 14:02:27 -070065 *loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
egdaniel9cb63402016-06-23 08:37:05 -070066 }
67
Robert Phillips95214472017-08-08 18:00:03 -040068 switch (storeOpIn) {
Robert Phillips6b47c7d2017-08-29 07:24:09 -040069 case GrStoreOp::kStore:
egdaniel066df7c2016-06-08 14:02:27 -070070 *storeOp = VK_ATTACHMENT_STORE_OP_STORE;
71 break;
Robert Phillips6b47c7d2017-08-29 07:24:09 -040072 case GrStoreOp::kDiscard:
egdaniel066df7c2016-06-08 14:02:27 -070073 *storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
74 break;
brianosman0bbc3712016-06-14 04:53:09 -070075 default:
egdaniel9cb63402016-06-23 08:37:05 -070076 SK_ABORT("Invalid StoreOp");
brianosman0bbc3712016-06-14 04:53:09 -070077 *storeOp = VK_ATTACHMENT_STORE_OP_STORE;
egdaniel066df7c2016-06-08 14:02:27 -070078 }
79}
80
Robert Phillips5b5d84c2018-08-09 15:12:18 -040081GrVkGpuRTCommandBuffer::GrVkGpuRTCommandBuffer(GrVkGpu* gpu)
82 : fCurrentCmdInfo(-1)
Robert Phillips19e51dc2017-08-09 09:30:51 -040083 , fGpu(gpu)
Robert Phillips19e51dc2017-08-09 09:30:51 -040084 , fLastPipelineState(nullptr) {
Brian Salomonc293a292016-11-30 13:38:32 -050085}
86
Greg Daniel500d58b2017-08-24 15:59:33 -040087void GrVkGpuRTCommandBuffer::init() {
Brian Salomonc293a292016-11-30 13:38:32 -050088 GrVkRenderPass::LoadStoreOps vkColorOps(fVkColorLoadOp, fVkColorStoreOp);
89 GrVkRenderPass::LoadStoreOps vkStencilOps(fVkStencilLoadOp, fVkStencilStoreOp);
egdaniel9cb63402016-06-23 08:37:05 -070090
Greg Daniel36a77ee2016-10-18 10:33:25 -040091 CommandBufferInfo& cbInfo = fCommandBufferInfos.push_back();
Brian Salomonc293a292016-11-30 13:38:32 -050092 SkASSERT(fCommandBufferInfos.count() == 1);
Greg Daniel22bc8652017-03-22 15:45:43 -040093 fCurrentCmdInfo = 0;
Greg Daniel36a77ee2016-10-18 10:33:25 -040094
Robert Phillips19e51dc2017-08-09 09:30:51 -040095 GrVkRenderTarget* vkRT = static_cast<GrVkRenderTarget*>(fRenderTarget);
96 const GrVkResourceProvider::CompatibleRPHandle& rpHandle = vkRT->compatibleRenderPassHandle();
egdaniel066df7c2016-06-08 14:02:27 -070097 if (rpHandle.isValid()) {
Greg Daniel36a77ee2016-10-18 10:33:25 -040098 cbInfo.fRenderPass = fGpu->resourceProvider().findRenderPass(rpHandle,
99 vkColorOps,
100 vkStencilOps);
egdaniel066df7c2016-06-08 14:02:27 -0700101 } else {
Robert Phillips19e51dc2017-08-09 09:30:51 -0400102 cbInfo.fRenderPass = fGpu->resourceProvider().findRenderPass(*vkRT,
Greg Daniel36a77ee2016-10-18 10:33:25 -0400103 vkColorOps,
104 vkStencilOps);
egdaniel066df7c2016-06-08 14:02:27 -0700105 }
106
Brian Osmancb3d0872018-10-16 15:19:28 -0400107 cbInfo.fColorClearValue.color.float32[0] = fClearColor[0];
108 cbInfo.fColorClearValue.color.float32[1] = fClearColor[1];
109 cbInfo.fColorClearValue.color.float32[2] = fClearColor[2];
110 cbInfo.fColorClearValue.color.float32[3] = fClearColor[3];
egdaniel9cb63402016-06-23 08:37:05 -0700111
Robert Phillips380b90c2017-08-30 07:41:07 -0400112 if (VK_ATTACHMENT_LOAD_OP_CLEAR == fVkColorLoadOp) {
Greg Daniela41a74a2018-10-09 12:59:23 +0000113 cbInfo.fBounds = SkRect::MakeWH(vkRT->width(), vkRT->height());
Robert Phillips380b90c2017-08-30 07:41:07 -0400114 } else {
115 cbInfo.fBounds.setEmpty();
116 }
Greg Daniela3c68df2018-03-16 13:46:53 -0400117
118 if (VK_ATTACHMENT_LOAD_OP_CLEAR == fVkColorLoadOp) {
119 cbInfo.fLoadStoreState = LoadStoreState::kStartsWithClear;
120 } else if (VK_ATTACHMENT_LOAD_OP_LOAD == fVkColorLoadOp &&
121 VK_ATTACHMENT_STORE_OP_STORE == fVkColorStoreOp) {
122 cbInfo.fLoadStoreState = LoadStoreState::kLoadAndStore;
123 } else if (VK_ATTACHMENT_LOAD_OP_DONT_CARE == fVkColorLoadOp) {
124 cbInfo.fLoadStoreState = LoadStoreState::kStartsWithDiscard;
125 }
Greg Daniel36a77ee2016-10-18 10:33:25 -0400126
Ethan Nicholas8e265a72018-12-12 16:22:40 -0500127 cbInfo.fCommandBuffers.push_back(fGpu->cmdPool()->findOrCreateSecondaryCommandBuffer(fGpu));
Robert Phillips19e51dc2017-08-09 09:30:51 -0400128 cbInfo.currentCmdBuf()->begin(fGpu, vkRT->framebuffer(), cbInfo.fRenderPass);
egdaniel066df7c2016-06-08 14:02:27 -0700129}
130
Greg Daniel070cbaf2019-01-03 17:35:54 -0500131void GrVkGpuRTCommandBuffer::initWrapped() {
132 CommandBufferInfo& cbInfo = fCommandBufferInfos.push_back();
133 SkASSERT(fCommandBufferInfos.count() == 1);
134 fCurrentCmdInfo = 0;
135
136 GrVkRenderTarget* vkRT = static_cast<GrVkRenderTarget*>(fRenderTarget);
137 SkASSERT(vkRT->wrapsSecondaryCommandBuffer());
138 cbInfo.fRenderPass = vkRT->externalRenderPass();
139 cbInfo.fRenderPass->ref();
140
141 cbInfo.fBounds.setEmpty();
142 cbInfo.fCommandBuffers.push_back(vkRT->getExternalSecondaryCommandBuffer());
143 cbInfo.fCommandBuffers[0]->ref();
144 cbInfo.currentCmdBuf()->begin(fGpu, nullptr, cbInfo.fRenderPass);
145}
Brian Salomonc293a292016-11-30 13:38:32 -0500146
Greg Daniel500d58b2017-08-24 15:59:33 -0400147GrVkGpuRTCommandBuffer::~GrVkGpuRTCommandBuffer() {
Robert Phillips5b5d84c2018-08-09 15:12:18 -0400148 this->reset();
egdaniel066df7c2016-06-08 14:02:27 -0700149}
150
Greg Daniel500d58b2017-08-24 15:59:33 -0400151GrGpu* GrVkGpuRTCommandBuffer::gpu() { return fGpu; }
egdaniel9cb63402016-06-23 08:37:05 -0700152
Greg Daniel500d58b2017-08-24 15:59:33 -0400153void GrVkGpuRTCommandBuffer::end() {
Greg Daniel22bc8652017-03-22 15:45:43 -0400154 if (fCurrentCmdInfo >= 0) {
155 fCommandBufferInfos[fCurrentCmdInfo].currentCmdBuf()->end(fGpu);
Brian Salomonc293a292016-11-30 13:38:32 -0500156 }
egdaniel066df7c2016-06-08 14:02:27 -0700157}
158
Greg Daniel500d58b2017-08-24 15:59:33 -0400159void GrVkGpuRTCommandBuffer::submit() {
Brian Salomonc293a292016-11-30 13:38:32 -0500160 if (!fRenderTarget) {
161 return;
162 }
Robert Phillips19e51dc2017-08-09 09:30:51 -0400163
164 GrVkRenderTarget* vkRT = static_cast<GrVkRenderTarget*>(fRenderTarget);
Robert Phillips19e51dc2017-08-09 09:30:51 -0400165 GrVkImage* targetImage = vkRT->msaaImage() ? vkRT->msaaImage() : vkRT;
Greg Daniel45a44de2018-02-27 10:07:29 -0500166 GrStencilAttachment* stencil = fRenderTarget->renderTargetPriv().getStencilAttachment();
egdaniel9cb63402016-06-23 08:37:05 -0700167
Greg Daniel36a77ee2016-10-18 10:33:25 -0400168 for (int i = 0; i < fCommandBufferInfos.count(); ++i) {
169 CommandBufferInfo& cbInfo = fCommandBufferInfos[i];
170
Greg Daniel77b53f62016-10-18 11:48:51 -0400171 for (int j = 0; j < cbInfo.fPreDrawUploads.count(); ++j) {
172 InlineUploadInfo& iuInfo = cbInfo.fPreDrawUploads[j];
173 iuInfo.fFlushState->doUpload(iuInfo.fUpload);
174 }
175
Greg Daniel500d58b2017-08-24 15:59:33 -0400176 for (int j = 0; j < cbInfo.fPreCopies.count(); ++j) {
177 CopyInfo& copyInfo = cbInfo.fPreCopies[j];
Chris Dalton298238a2019-02-21 16:28:44 -0500178 fGpu->copySurface(fRenderTarget, fOrigin, copyInfo.fSrc.get(), copyInfo.fSrcOrigin,
Greg Daniel55fa6472018-03-16 16:13:10 -0400179 copyInfo.fSrcRect, copyInfo.fDstPoint, copyInfo.fShouldDiscardDst);
Greg Daniel500d58b2017-08-24 15:59:33 -0400180 }
181
Greg Daniel45a44de2018-02-27 10:07:29 -0500182
Greg Daniel38c3d932018-03-16 14:22:30 -0400183 // TODO: Many things create a scratch texture which adds the discard immediately, but then
184 // don't draw to it right away. This causes the discard to be ignored and we get yelled at
185 // for loading uninitialized data. However, once MDB lands with reordering, the discard will
186 // get reordered with the rest of the draw commands and we can remove the discard check.
187 if (cbInfo.fIsEmpty &&
188 cbInfo.fLoadStoreState != LoadStoreState::kStartsWithClear &&
189 cbInfo.fLoadStoreState != LoadStoreState::kStartsWithDiscard) {
Greg Daniel77b53f62016-10-18 11:48:51 -0400190 // We have sumbitted no actual draw commands to the command buffer and we are not using
191 // the render pass to do a clear so there is no need to submit anything.
192 continue;
193 }
Greg Daniel38c3d932018-03-16 14:22:30 -0400194
Greg Daniel070cbaf2019-01-03 17:35:54 -0500195 // We don't want to actually submit the secondary command buffer if it is wrapped.
196 if (this->wrapsSecondaryCommandBuffer()) {
197 // If we have any sampled images set their layout now.
Chris Dalton298238a2019-02-21 16:28:44 -0500198 for (int j = 0; j < cbInfo.fSampledTextures.count(); ++j) {
199 cbInfo.fSampledTextures[j]->setImageLayout(
200 fGpu, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_ACCESS_SHADER_READ_BIT,
201 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, false);
Greg Daniel070cbaf2019-01-03 17:35:54 -0500202 }
203
204 // There should have only been one secondary command buffer in the wrapped case so it is
205 // safe to just return here.
206 SkASSERT(fCommandBufferInfos.count() == 1);
207 return;
208 }
209
Greg Danieldbdba602018-04-20 11:52:43 -0400210 // Make sure if we only have a discard load that we execute the discard on the whole image.
211 // TODO: Once we improve our tracking of discards so that we never end up flushing a discard
212 // call with no actually ops, remove this.
213 if (cbInfo.fIsEmpty && cbInfo.fLoadStoreState == LoadStoreState::kStartsWithDiscard) {
Greg Daniela41a74a2018-10-09 12:59:23 +0000214 cbInfo.fBounds = SkRect::MakeWH(vkRT->width(), vkRT->height());
Greg Danieldbdba602018-04-20 11:52:43 -0400215 }
216
Greg Daniela41a74a2018-10-09 12:59:23 +0000217 if (cbInfo.fBounds.intersect(0, 0,
218 SkIntToScalar(fRenderTarget->width()),
219 SkIntToScalar(fRenderTarget->height()))) {
Greg Daniel38c3d932018-03-16 14:22:30 -0400220 // Make sure we do the following layout changes after all copies, uploads, or any other
221 // pre-work is done since we may change the layouts in the pre-work. Also since the
222 // draws will be submitted in different render passes, we need to guard againts write
223 // and write issues.
224
225 // Change layout of our render target so it can be used as the color attachment.
Greg Danielf7828d02018-10-09 12:01:32 -0400226 // TODO: If we know that we will never be blending or loading the attachment we could
227 // drop the VK_ACCESS_COLOR_ATTACHMENT_READ_BIT.
Greg Daniel38c3d932018-03-16 14:22:30 -0400228 targetImage->setImageLayout(fGpu,
229 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
Greg Danielf7828d02018-10-09 12:01:32 -0400230 VK_ACCESS_COLOR_ATTACHMENT_READ_BIT |
Greg Daniel38c3d932018-03-16 14:22:30 -0400231 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
Greg Danielf7828d02018-10-09 12:01:32 -0400232 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
Greg Daniel38c3d932018-03-16 14:22:30 -0400233 false);
234
235 // If we are using a stencil attachment we also need to update its layout
236 if (stencil) {
237 GrVkStencilAttachment* vkStencil = (GrVkStencilAttachment*)stencil;
Greg Danielf7828d02018-10-09 12:01:32 -0400238 // We need the write and read access bits since we may load and store the stencil.
239 // The initial load happens in the VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT so we
240 // wait there.
Greg Daniel38c3d932018-03-16 14:22:30 -0400241 vkStencil->setImageLayout(fGpu,
242 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
243 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT |
244 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT,
Greg Danielf7828d02018-10-09 12:01:32 -0400245 VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT,
Greg Daniel38c3d932018-03-16 14:22:30 -0400246 false);
247 }
248
249 // If we have any sampled images set their layout now.
Chris Dalton298238a2019-02-21 16:28:44 -0500250 for (int j = 0; j < cbInfo.fSampledTextures.count(); ++j) {
251 cbInfo.fSampledTextures[j]->setImageLayout(
252 fGpu, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_ACCESS_SHADER_READ_BIT,
253 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, false);
Greg Daniel38c3d932018-03-16 14:22:30 -0400254 }
255
Greg Daniel36a77ee2016-10-18 10:33:25 -0400256 SkIRect iBounds;
257 cbInfo.fBounds.roundOut(&iBounds);
258
Greg Daniel22bc8652017-03-22 15:45:43 -0400259 fGpu->submitSecondaryCommandBuffer(cbInfo.fCommandBuffers, cbInfo.fRenderPass,
Robert Phillipsb0e93a22017-08-29 08:26:54 -0400260 &cbInfo.fColorClearValue, vkRT, fOrigin, iBounds);
Greg Daniel36a77ee2016-10-18 10:33:25 -0400261 }
262 }
egdaniel9cb63402016-06-23 08:37:05 -0700263}
264
Robert Phillips5b5d84c2018-08-09 15:12:18 -0400265void GrVkGpuRTCommandBuffer::set(GrRenderTarget* rt, GrSurfaceOrigin origin,
266 const GrGpuRTCommandBuffer::LoadAndStoreInfo& colorInfo,
267 const GrGpuRTCommandBuffer::StencilLoadAndStoreInfo& stencilInfo) {
268 SkASSERT(!fRenderTarget);
269 SkASSERT(fCommandBufferInfos.empty());
270 SkASSERT(-1 == fCurrentCmdInfo);
Robert Phillips9da87e02019-02-04 13:26:26 -0500271 SkASSERT(fGpu == rt->getContext()->priv().getGpu());
Robert Phillips5b5d84c2018-08-09 15:12:18 -0400272 SkASSERT(!fLastPipelineState);
273
274 this->INHERITED::set(rt, origin);
275
Greg Daniel070cbaf2019-01-03 17:35:54 -0500276 if (this->wrapsSecondaryCommandBuffer()) {
277 this->initWrapped();
278 return;
279 }
280
Brian Osman9a9baae2018-11-05 15:06:26 -0500281 fClearColor = colorInfo.fClearColor;
Robert Phillips5b5d84c2018-08-09 15:12:18 -0400282
283 get_vk_load_store_ops(colorInfo.fLoadOp, colorInfo.fStoreOp,
284 &fVkColorLoadOp, &fVkColorStoreOp);
285
286 get_vk_load_store_ops(stencilInfo.fLoadOp, stencilInfo.fStoreOp,
287 &fVkStencilLoadOp, &fVkStencilStoreOp);
288
289 this->init();
290}
291
292void GrVkGpuRTCommandBuffer::reset() {
293 for (int i = 0; i < fCommandBufferInfos.count(); ++i) {
294 CommandBufferInfo& cbInfo = fCommandBufferInfos[i];
295 for (int j = 0; j < cbInfo.fCommandBuffers.count(); ++j) {
296 cbInfo.fCommandBuffers[j]->unref(fGpu);
297 }
298 cbInfo.fRenderPass->unref(fGpu);
299 }
300 fCommandBufferInfos.reset();
301
302 fCurrentCmdInfo = -1;
303
304 fLastPipelineState = nullptr;
305 fRenderTarget = nullptr;
306}
307
Greg Daniel070cbaf2019-01-03 17:35:54 -0500308bool GrVkGpuRTCommandBuffer::wrapsSecondaryCommandBuffer() const {
309 GrVkRenderTarget* vkRT = static_cast<GrVkRenderTarget*>(fRenderTarget);
310 return vkRT->wrapsSecondaryCommandBuffer();
311}
312
Greg Daniel64cc9aa2018-10-19 13:54:56 -0400313////////////////////////////////////////////////////////////////////////////////
314
Greg Daniel500d58b2017-08-24 15:59:33 -0400315void GrVkGpuRTCommandBuffer::discard() {
Robert Phillips19e51dc2017-08-09 09:30:51 -0400316 GrVkRenderTarget* vkRT = static_cast<GrVkRenderTarget*>(fRenderTarget);
Brian Salomonc293a292016-11-30 13:38:32 -0500317
Greg Daniel22bc8652017-03-22 15:45:43 -0400318 CommandBufferInfo& cbInfo = fCommandBufferInfos[fCurrentCmdInfo];
Greg Daniel77b53f62016-10-18 11:48:51 -0400319 if (cbInfo.fIsEmpty) {
Robert Phillips74c627f2017-08-09 10:28:00 -0400320 // Change the render pass to do a don't-care load for both color & stencil
egdaniel37535c92016-06-30 08:23:30 -0700321 GrVkRenderPass::LoadStoreOps vkColorOps(VK_ATTACHMENT_LOAD_OP_DONT_CARE,
322 VK_ATTACHMENT_STORE_OP_STORE);
323 GrVkRenderPass::LoadStoreOps vkStencilOps(VK_ATTACHMENT_LOAD_OP_DONT_CARE,
324 VK_ATTACHMENT_STORE_OP_STORE);
egdaniel37535c92016-06-30 08:23:30 -0700325
Greg Daniel36a77ee2016-10-18 10:33:25 -0400326 const GrVkRenderPass* oldRP = cbInfo.fRenderPass;
egdaniel37535c92016-06-30 08:23:30 -0700327
egdaniel37535c92016-06-30 08:23:30 -0700328 const GrVkResourceProvider::CompatibleRPHandle& rpHandle =
Robert Phillips19e51dc2017-08-09 09:30:51 -0400329 vkRT->compatibleRenderPassHandle();
egdaniel37535c92016-06-30 08:23:30 -0700330 if (rpHandle.isValid()) {
Greg Daniel36a77ee2016-10-18 10:33:25 -0400331 cbInfo.fRenderPass = fGpu->resourceProvider().findRenderPass(rpHandle,
332 vkColorOps,
333 vkStencilOps);
egdaniel37535c92016-06-30 08:23:30 -0700334 } else {
Robert Phillips19e51dc2017-08-09 09:30:51 -0400335 cbInfo.fRenderPass = fGpu->resourceProvider().findRenderPass(*vkRT,
Greg Daniel36a77ee2016-10-18 10:33:25 -0400336 vkColorOps,
337 vkStencilOps);
egdaniel37535c92016-06-30 08:23:30 -0700338 }
339
Greg Daniel36a77ee2016-10-18 10:33:25 -0400340 SkASSERT(cbInfo.fRenderPass->isCompatible(*oldRP));
egdaniel37535c92016-06-30 08:23:30 -0700341 oldRP->unref(fGpu);
Greg Daniel5011f852016-10-28 15:07:16 -0400342 cbInfo.fBounds.join(fRenderTarget->getBoundsRect());
Greg Daniela3c68df2018-03-16 13:46:53 -0400343 cbInfo.fLoadStoreState = LoadStoreState::kStartsWithDiscard;
344 // If we are going to discard the whole render target then the results of any copies we did
345 // immediately before to the target won't matter, so just drop them.
346 cbInfo.fPreCopies.reset();
egdaniel37535c92016-06-30 08:23:30 -0700347 }
348}
349
Greg Daniel500d58b2017-08-24 15:59:33 -0400350void GrVkGpuRTCommandBuffer::insertEventMarker(const char* msg) {
Robert Phillips65a88fa2017-08-08 08:36:22 -0400351 // TODO: does Vulkan have a correlate?
352}
353
Greg Daniel500d58b2017-08-24 15:59:33 -0400354void GrVkGpuRTCommandBuffer::onClearStencilClip(const GrFixedClip& clip, bool insideStencilMask) {
Chris Dalton94c04682017-11-01 17:15:06 -0600355 SkASSERT(!clip.hasWindowRectangles());
356
Jim Van Verth6a40abc2017-11-02 16:56:09 +0000357 CommandBufferInfo& cbInfo = fCommandBufferInfos[fCurrentCmdInfo];
358
Greg Daniel65a09272016-10-12 09:47:22 -0400359 GrStencilAttachment* sb = fRenderTarget->renderTargetPriv().getStencilAttachment();
egdaniel9cb63402016-06-23 08:37:05 -0700360 // this should only be called internally when we know we have a
361 // stencil buffer.
362 SkASSERT(sb);
363 int stencilBitCount = sb->bits();
364
365 // The contract with the callers does not guarantee that we preserve all bits in the stencil
366 // during this clear. Thus we will clear the entire stencil to the desired value.
367
368 VkClearDepthStencilValue vkStencilColor;
369 memset(&vkStencilColor, 0, sizeof(VkClearDepthStencilValue));
csmartdalton29df7602016-08-31 11:55:52 -0700370 if (insideStencilMask) {
egdaniel9cb63402016-06-23 08:37:05 -0700371 vkStencilColor.stencil = (1 << (stencilBitCount - 1));
372 } else {
373 vkStencilColor.stencil = 0;
374 }
375
376 VkClearRect clearRect;
377 // Flip rect if necessary
csmartdalton29df7602016-08-31 11:55:52 -0700378 SkIRect vkRect;
Brian Salomond818ebf2018-07-02 14:08:49 +0000379 if (!clip.scissorEnabled()) {
Greg Daniela41a74a2018-10-09 12:59:23 +0000380 vkRect.setXYWH(0, 0, fRenderTarget->width(), fRenderTarget->height());
Robert Phillips4f101a72017-07-28 08:42:04 -0400381 } else if (kBottomLeft_GrSurfaceOrigin != fOrigin) {
csmartdalton29df7602016-08-31 11:55:52 -0700382 vkRect = clip.scissorRect();
383 } else {
384 const SkIRect& scissor = clip.scissorRect();
Greg Daniel65a09272016-10-12 09:47:22 -0400385 vkRect.setLTRB(scissor.fLeft, fRenderTarget->height() - scissor.fBottom,
386 scissor.fRight, fRenderTarget->height() - scissor.fTop);
egdaniel9cb63402016-06-23 08:37:05 -0700387 }
388
389 clearRect.rect.offset = { vkRect.fLeft, vkRect.fTop };
390 clearRect.rect.extent = { (uint32_t)vkRect.width(), (uint32_t)vkRect.height() };
391
392 clearRect.baseArrayLayer = 0;
393 clearRect.layerCount = 1;
394
395 uint32_t stencilIndex;
Greg Daniel36a77ee2016-10-18 10:33:25 -0400396 SkAssertResult(cbInfo.fRenderPass->stencilAttachmentIndex(&stencilIndex));
egdaniel9cb63402016-06-23 08:37:05 -0700397
398 VkClearAttachment attachment;
399 attachment.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT;
400 attachment.colorAttachment = 0; // this value shouldn't matter
401 attachment.clearValue.depthStencil = vkStencilColor;
402
Greg Daniel22bc8652017-03-22 15:45:43 -0400403 cbInfo.currentCmdBuf()->clearAttachments(fGpu, 1, &attachment, 1, &clearRect);
Greg Daniel77b53f62016-10-18 11:48:51 -0400404 cbInfo.fIsEmpty = false;
Greg Daniel36a77ee2016-10-18 10:33:25 -0400405
406 // Update command buffer bounds
Brian Salomond818ebf2018-07-02 14:08:49 +0000407 if (!clip.scissorEnabled()) {
Greg Daniel36a77ee2016-10-18 10:33:25 -0400408 cbInfo.fBounds.join(fRenderTarget->getBoundsRect());
409 } else {
410 cbInfo.fBounds.join(SkRect::Make(clip.scissorRect()));
411 }
egdaniel9cb63402016-06-23 08:37:05 -0700412}
413
Brian Osman9a9baae2018-11-05 15:06:26 -0500414void GrVkGpuRTCommandBuffer::onClear(const GrFixedClip& clip, const SkPMColor4f& color) {
Robert Phillips19e51dc2017-08-09 09:30:51 -0400415 GrVkRenderTarget* vkRT = static_cast<GrVkRenderTarget*>(fRenderTarget);
416
Jim Van Verth6a40abc2017-11-02 16:56:09 +0000417 // parent class should never let us get here with no RT
csmartdaltonbf4a8f92016-09-06 10:01:06 -0700418 SkASSERT(!clip.hasWindowRectangles());
egdaniel9cb63402016-06-23 08:37:05 -0700419
Greg Daniel22bc8652017-03-22 15:45:43 -0400420 CommandBufferInfo& cbInfo = fCommandBufferInfos[fCurrentCmdInfo];
Greg Daniel36a77ee2016-10-18 10:33:25 -0400421
Brian Osman9a9baae2018-11-05 15:06:26 -0500422 VkClearColorValue vkColor = {{color.fR, color.fG, color.fB, color.fA}};
egdaniel9cb63402016-06-23 08:37:05 -0700423
Brian Salomond818ebf2018-07-02 14:08:49 +0000424 if (cbInfo.fIsEmpty && !clip.scissorEnabled()) {
Robert Phillips74c627f2017-08-09 10:28:00 -0400425 // Change the render pass to do a clear load
egdaniel9cb63402016-06-23 08:37:05 -0700426 GrVkRenderPass::LoadStoreOps vkColorOps(VK_ATTACHMENT_LOAD_OP_CLEAR,
427 VK_ATTACHMENT_STORE_OP_STORE);
Robert Phillips74c627f2017-08-09 10:28:00 -0400428 // Preserve the stencil buffer's load & store settings
429 GrVkRenderPass::LoadStoreOps vkStencilOps(fVkStencilLoadOp, fVkStencilStoreOp);
egdaniel9cb63402016-06-23 08:37:05 -0700430
Greg Daniel36a77ee2016-10-18 10:33:25 -0400431 const GrVkRenderPass* oldRP = cbInfo.fRenderPass;
egdaniel9cb63402016-06-23 08:37:05 -0700432
433 const GrVkResourceProvider::CompatibleRPHandle& rpHandle =
Robert Phillips19e51dc2017-08-09 09:30:51 -0400434 vkRT->compatibleRenderPassHandle();
egdaniel9cb63402016-06-23 08:37:05 -0700435 if (rpHandle.isValid()) {
Greg Daniel36a77ee2016-10-18 10:33:25 -0400436 cbInfo.fRenderPass = fGpu->resourceProvider().findRenderPass(rpHandle,
437 vkColorOps,
438 vkStencilOps);
egdaniel9cb63402016-06-23 08:37:05 -0700439 } else {
Robert Phillips19e51dc2017-08-09 09:30:51 -0400440 cbInfo.fRenderPass = fGpu->resourceProvider().findRenderPass(*vkRT,
Greg Daniel36a77ee2016-10-18 10:33:25 -0400441 vkColorOps,
442 vkStencilOps);
egdaniel9cb63402016-06-23 08:37:05 -0700443 }
444
Greg Daniel36a77ee2016-10-18 10:33:25 -0400445 SkASSERT(cbInfo.fRenderPass->isCompatible(*oldRP));
egdaniel9cb63402016-06-23 08:37:05 -0700446 oldRP->unref(fGpu);
447
Brian Osman9a9baae2018-11-05 15:06:26 -0500448 cbInfo.fColorClearValue.color = {{color.fR, color.fG, color.fB, color.fA}};
Greg Daniela3c68df2018-03-16 13:46:53 -0400449 cbInfo.fLoadStoreState = LoadStoreState::kStartsWithClear;
450 // If we are going to clear the whole render target then the results of any copies we did
451 // immediately before to the target won't matter, so just drop them.
452 cbInfo.fPreCopies.reset();
Greg Daniel36a77ee2016-10-18 10:33:25 -0400453
454 // Update command buffer bounds
455 cbInfo.fBounds.join(fRenderTarget->getBoundsRect());
egdaniel9cb63402016-06-23 08:37:05 -0700456 return;
457 }
458
459 // We always do a sub rect clear with clearAttachments since we are inside a render pass
460 VkClearRect clearRect;
461 // Flip rect if necessary
csmartdalton29df7602016-08-31 11:55:52 -0700462 SkIRect vkRect;
Brian Salomond818ebf2018-07-02 14:08:49 +0000463 if (!clip.scissorEnabled()) {
Greg Daniela41a74a2018-10-09 12:59:23 +0000464 vkRect.setXYWH(0, 0, fRenderTarget->width(), fRenderTarget->height());
Robert Phillips4f101a72017-07-28 08:42:04 -0400465 } else if (kBottomLeft_GrSurfaceOrigin != fOrigin) {
csmartdalton29df7602016-08-31 11:55:52 -0700466 vkRect = clip.scissorRect();
467 } else {
468 const SkIRect& scissor = clip.scissorRect();
Greg Daniel65a09272016-10-12 09:47:22 -0400469 vkRect.setLTRB(scissor.fLeft, fRenderTarget->height() - scissor.fBottom,
470 scissor.fRight, fRenderTarget->height() - scissor.fTop);
egdaniel9cb63402016-06-23 08:37:05 -0700471 }
472 clearRect.rect.offset = { vkRect.fLeft, vkRect.fTop };
473 clearRect.rect.extent = { (uint32_t)vkRect.width(), (uint32_t)vkRect.height() };
474 clearRect.baseArrayLayer = 0;
475 clearRect.layerCount = 1;
476
477 uint32_t colorIndex;
Greg Daniel36a77ee2016-10-18 10:33:25 -0400478 SkAssertResult(cbInfo.fRenderPass->colorAttachmentIndex(&colorIndex));
egdaniel9cb63402016-06-23 08:37:05 -0700479
480 VkClearAttachment attachment;
481 attachment.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
482 attachment.colorAttachment = colorIndex;
483 attachment.clearValue.color = vkColor;
484
Greg Daniel22bc8652017-03-22 15:45:43 -0400485 cbInfo.currentCmdBuf()->clearAttachments(fGpu, 1, &attachment, 1, &clearRect);
Greg Daniel77b53f62016-10-18 11:48:51 -0400486 cbInfo.fIsEmpty = false;
Greg Daniel36a77ee2016-10-18 10:33:25 -0400487
488 // Update command buffer bounds
Brian Salomond818ebf2018-07-02 14:08:49 +0000489 if (!clip.scissorEnabled()) {
Greg Daniel36a77ee2016-10-18 10:33:25 -0400490 cbInfo.fBounds.join(fRenderTarget->getBoundsRect());
491 } else {
492 cbInfo.fBounds.join(SkRect::Make(clip.scissorRect()));
493 }
egdaniel9cb63402016-06-23 08:37:05 -0700494 return;
495}
496
Greg Daniel500d58b2017-08-24 15:59:33 -0400497////////////////////////////////////////////////////////////////////////////////
498
499void GrVkGpuRTCommandBuffer::addAdditionalCommandBuffer() {
Robert Phillips19e51dc2017-08-09 09:30:51 -0400500 GrVkRenderTarget* vkRT = static_cast<GrVkRenderTarget*>(fRenderTarget);
501
Greg Daniel22bc8652017-03-22 15:45:43 -0400502 CommandBufferInfo& cbInfo = fCommandBufferInfos[fCurrentCmdInfo];
503 cbInfo.currentCmdBuf()->end(fGpu);
Ethan Nicholas8e265a72018-12-12 16:22:40 -0500504 cbInfo.fCommandBuffers.push_back(fGpu->cmdPool()->findOrCreateSecondaryCommandBuffer(fGpu));
Robert Phillips19e51dc2017-08-09 09:30:51 -0400505 cbInfo.currentCmdBuf()->begin(fGpu, vkRT->framebuffer(), cbInfo.fRenderPass);
Greg Daniel22bc8652017-03-22 15:45:43 -0400506}
507
Greg Daniel500d58b2017-08-24 15:59:33 -0400508void GrVkGpuRTCommandBuffer::addAdditionalRenderPass() {
Robert Phillips19e51dc2017-08-09 09:30:51 -0400509 GrVkRenderTarget* vkRT = static_cast<GrVkRenderTarget*>(fRenderTarget);
510
Greg Daniel22bc8652017-03-22 15:45:43 -0400511 fCommandBufferInfos[fCurrentCmdInfo].currentCmdBuf()->end(fGpu);
Greg Daniel77b53f62016-10-18 11:48:51 -0400512
513 CommandBufferInfo& cbInfo = fCommandBufferInfos.push_back();
Greg Daniel22bc8652017-03-22 15:45:43 -0400514 fCurrentCmdInfo++;
Greg Daniel77b53f62016-10-18 11:48:51 -0400515
516 GrVkRenderPass::LoadStoreOps vkColorOps(VK_ATTACHMENT_LOAD_OP_LOAD,
517 VK_ATTACHMENT_STORE_OP_STORE);
518 GrVkRenderPass::LoadStoreOps vkStencilOps(VK_ATTACHMENT_LOAD_OP_LOAD,
519 VK_ATTACHMENT_STORE_OP_STORE);
520
521 const GrVkResourceProvider::CompatibleRPHandle& rpHandle =
Robert Phillips19e51dc2017-08-09 09:30:51 -0400522 vkRT->compatibleRenderPassHandle();
Greg Daniel77b53f62016-10-18 11:48:51 -0400523 if (rpHandle.isValid()) {
524 cbInfo.fRenderPass = fGpu->resourceProvider().findRenderPass(rpHandle,
525 vkColorOps,
526 vkStencilOps);
527 } else {
Robert Phillips19e51dc2017-08-09 09:30:51 -0400528 cbInfo.fRenderPass = fGpu->resourceProvider().findRenderPass(*vkRT,
Greg Daniel77b53f62016-10-18 11:48:51 -0400529 vkColorOps,
530 vkStencilOps);
531 }
Greg Daniela3c68df2018-03-16 13:46:53 -0400532 cbInfo.fLoadStoreState = LoadStoreState::kLoadAndStore;
Greg Daniel77b53f62016-10-18 11:48:51 -0400533
Ethan Nicholas8e265a72018-12-12 16:22:40 -0500534 cbInfo.fCommandBuffers.push_back(fGpu->cmdPool()->findOrCreateSecondaryCommandBuffer(fGpu));
Greg Daniel77b53f62016-10-18 11:48:51 -0400535 // It shouldn't matter what we set the clear color to here since we will assume loading of the
536 // attachment.
537 memset(&cbInfo.fColorClearValue, 0, sizeof(VkClearValue));
538 cbInfo.fBounds.setEmpty();
Greg Daniel77b53f62016-10-18 11:48:51 -0400539
Robert Phillips19e51dc2017-08-09 09:30:51 -0400540 cbInfo.currentCmdBuf()->begin(fGpu, vkRT->framebuffer(), cbInfo.fRenderPass);
Greg Daniel77b53f62016-10-18 11:48:51 -0400541}
542
Brian Salomon943ed792017-10-30 09:37:55 -0400543void GrVkGpuRTCommandBuffer::inlineUpload(GrOpFlushState* state,
544 GrDeferredTextureUploadFn& upload) {
Greg Daniel22bc8652017-03-22 15:45:43 -0400545 if (!fCommandBufferInfos[fCurrentCmdInfo].fIsEmpty) {
546 this->addAdditionalRenderPass();
Greg Daniel77b53f62016-10-18 11:48:51 -0400547 }
Greg Daniel22bc8652017-03-22 15:45:43 -0400548 fCommandBufferInfos[fCurrentCmdInfo].fPreDrawUploads.emplace_back(state, upload);
Greg Daniel77b53f62016-10-18 11:48:51 -0400549}
550
Robert Phillipsb0e93a22017-08-29 08:26:54 -0400551void GrVkGpuRTCommandBuffer::copy(GrSurface* src, GrSurfaceOrigin srcOrigin, const SkIRect& srcRect,
Greg Daniel500d58b2017-08-24 15:59:33 -0400552 const SkIPoint& dstPoint) {
Greg Daniela3c68df2018-03-16 13:46:53 -0400553 CommandBufferInfo& cbInfo = fCommandBufferInfos[fCurrentCmdInfo];
554 if (!cbInfo.fIsEmpty || LoadStoreState::kStartsWithClear == cbInfo.fLoadStoreState) {
Greg Daniel500d58b2017-08-24 15:59:33 -0400555 this->addAdditionalRenderPass();
556 }
Greg Daniela3c68df2018-03-16 13:46:53 -0400557
Greg Daniel55fa6472018-03-16 16:13:10 -0400558 fCommandBufferInfos[fCurrentCmdInfo].fPreCopies.emplace_back(
559 src, srcOrigin, srcRect, dstPoint,
560 LoadStoreState::kStartsWithDiscard == cbInfo.fLoadStoreState);
561
Greg Daniela3c68df2018-03-16 13:46:53 -0400562 if (LoadStoreState::kLoadAndStore != cbInfo.fLoadStoreState) {
563 // Change the render pass to do a load and store so we don't lose the results of our copy
564 GrVkRenderPass::LoadStoreOps vkColorOps(VK_ATTACHMENT_LOAD_OP_LOAD,
565 VK_ATTACHMENT_STORE_OP_STORE);
566 GrVkRenderPass::LoadStoreOps vkStencilOps(VK_ATTACHMENT_LOAD_OP_LOAD,
567 VK_ATTACHMENT_STORE_OP_STORE);
568
569 const GrVkRenderPass* oldRP = cbInfo.fRenderPass;
570
571 GrVkRenderTarget* vkRT = static_cast<GrVkRenderTarget*>(fRenderTarget);
572 const GrVkResourceProvider::CompatibleRPHandle& rpHandle =
573 vkRT->compatibleRenderPassHandle();
574 if (rpHandle.isValid()) {
575 cbInfo.fRenderPass = fGpu->resourceProvider().findRenderPass(rpHandle,
576 vkColorOps,
577 vkStencilOps);
578 } else {
579 cbInfo.fRenderPass = fGpu->resourceProvider().findRenderPass(*vkRT,
580 vkColorOps,
581 vkStencilOps);
582 }
583 SkASSERT(cbInfo.fRenderPass->isCompatible(*oldRP));
584 oldRP->unref(fGpu);
585
586 cbInfo.fLoadStoreState = LoadStoreState::kLoadAndStore;
587
588 }
Greg Daniel500d58b2017-08-24 15:59:33 -0400589}
590
egdaniel9cb63402016-06-23 08:37:05 -0700591////////////////////////////////////////////////////////////////////////////////
592
Brian Salomondbf70722019-02-07 11:31:24 -0500593void GrVkGpuRTCommandBuffer::bindGeometry(const GrGpuBuffer* indexBuffer,
594 const GrGpuBuffer* vertexBuffer,
595 const GrGpuBuffer* instanceBuffer) {
Chris Daltonff926502017-05-03 14:36:54 -0400596 GrVkSecondaryCommandBuffer* currCmdBuf = fCommandBufferInfos[fCurrentCmdInfo].currentCmdBuf();
egdaniel9cb63402016-06-23 08:37:05 -0700597 // There is no need to put any memory barriers to make sure host writes have finished here.
598 // When a command buffer is submitted to a queue, there is an implicit memory barrier that
599 // occurs for all host writes. Additionally, BufferMemoryBarriers are not allowed inside of
600 // an active RenderPass.
egdaniel9cb63402016-06-23 08:37:05 -0700601
Chris Dalton1d616352017-05-31 12:51:23 -0600602 // Here our vertex and instance inputs need to match the same 0-based bindings they were
603 // assigned in GrVkPipeline. That is, vertex first (if any) followed by instance.
604 uint32_t binding = 0;
605
Brian Salomon802cb312018-06-08 18:05:20 -0400606 if (vertexBuffer) {
Chris Dalton1d616352017-05-31 12:51:23 -0600607 SkASSERT(vertexBuffer);
Chris Dalton1d616352017-05-31 12:51:23 -0600608 SkASSERT(!vertexBuffer->isMapped());
609
610 currCmdBuf->bindInputBuffer(fGpu, binding++,
611 static_cast<const GrVkVertexBuffer*>(vertexBuffer));
612 }
613
Brian Salomon802cb312018-06-08 18:05:20 -0400614 if (instanceBuffer) {
Chris Dalton1d616352017-05-31 12:51:23 -0600615 SkASSERT(instanceBuffer);
Chris Dalton1d616352017-05-31 12:51:23 -0600616 SkASSERT(!instanceBuffer->isMapped());
617
618 currCmdBuf->bindInputBuffer(fGpu, binding++,
619 static_cast<const GrVkVertexBuffer*>(instanceBuffer));
620 }
Chris Daltonff926502017-05-03 14:36:54 -0400621 if (indexBuffer) {
622 SkASSERT(indexBuffer);
623 SkASSERT(!indexBuffer->isMapped());
egdaniel9cb63402016-06-23 08:37:05 -0700624
Chris Daltonff926502017-05-03 14:36:54 -0400625 currCmdBuf->bindIndexBuffer(fGpu, static_cast<const GrVkIndexBuffer*>(indexBuffer));
egdaniel9cb63402016-06-23 08:37:05 -0700626 }
627}
628
Brian Salomon49348902018-06-26 09:12:38 -0400629GrVkPipelineState* GrVkGpuRTCommandBuffer::prepareDrawState(
630 const GrPrimitiveProcessor& primProc,
631 const GrPipeline& pipeline,
632 const GrPipeline::FixedDynamicState* fixedDynamicState,
633 const GrPipeline::DynamicStateArrays* dynamicStateArrays,
634 GrPrimitiveType primitiveType) {
Greg Daniel22bc8652017-03-22 15:45:43 -0400635 CommandBufferInfo& cbInfo = fCommandBufferInfos[fCurrentCmdInfo];
636 SkASSERT(cbInfo.fRenderPass);
Greg Daniel36a77ee2016-10-18 10:33:25 -0400637
Greg Daniel99b88e02018-10-03 15:31:20 -0400638 VkRenderPass compatibleRenderPass = cbInfo.fRenderPass->vkRenderPass();
639
Greg Daniel9a51a862018-11-30 10:18:14 -0500640 const GrTextureProxy* const* primProcProxies = nullptr;
641 if (dynamicStateArrays && dynamicStateArrays->fPrimitiveProcessorTextures) {
642 primProcProxies = dynamicStateArrays->fPrimitiveProcessorTextures;
643 } else if (fixedDynamicState) {
644 primProcProxies = fixedDynamicState->fPrimitiveProcessorTextures;
645 }
646
647 SkASSERT(SkToBool(primProcProxies) == SkToBool(primProc.numTextureSamplers()));
648
Greg Daniel09eeefb2017-10-16 15:15:02 -0400649 GrVkPipelineState* pipelineState =
Robert Phillipsd0fe8752019-01-31 14:13:59 -0500650 fGpu->resourceProvider().findOrCreateCompatiblePipelineState(fRenderTarget, fOrigin,
651 pipeline,
egdaniel9cb63402016-06-23 08:37:05 -0700652 primProc,
Greg Daniel9a51a862018-11-30 10:18:14 -0500653 primProcProxies,
egdaniel9cb63402016-06-23 08:37:05 -0700654 primitiveType,
Greg Daniel99b88e02018-10-03 15:31:20 -0400655 compatibleRenderPass);
egdaniel9cb63402016-06-23 08:37:05 -0700656 if (!pipelineState) {
657 return pipelineState;
658 }
659
Greg Daniel22bc8652017-03-22 15:45:43 -0400660 if (!cbInfo.fIsEmpty &&
Greg Daniel09eeefb2017-10-16 15:15:02 -0400661 fLastPipelineState && fLastPipelineState != pipelineState &&
Greg Daniele3cd6912017-05-17 11:15:55 -0400662 fGpu->vkCaps().newCBOnPipelineChange()) {
Greg Daniel22bc8652017-03-22 15:45:43 -0400663 this->addAdditionalCommandBuffer();
664 }
Greg Daniel09eeefb2017-10-16 15:15:02 -0400665 fLastPipelineState = pipelineState;
Greg Daniel22bc8652017-03-22 15:45:43 -0400666
Brian Salomonf7232642018-09-19 08:58:08 -0400667 pipelineState->bindPipeline(fGpu, cbInfo.currentCmdBuf());
Brian Salomoncd7907b2018-08-30 08:36:18 -0400668
Robert Phillipsd0fe8752019-01-31 14:13:59 -0500669 pipelineState->setAndBindUniforms(fGpu, fRenderTarget, fOrigin,
670 primProc, pipeline, cbInfo.currentCmdBuf());
Brian Salomonf7232642018-09-19 08:58:08 -0400671
672 // Check whether we need to bind textures between each GrMesh. If not we can bind them all now.
673 bool setTextures = !(dynamicStateArrays && dynamicStateArrays->fPrimitiveProcessorTextures);
674 if (setTextures) {
Brian Salomonf7232642018-09-19 08:58:08 -0400675 pipelineState->setAndBindTextures(fGpu, primProc, pipeline, primProcProxies,
676 cbInfo.currentCmdBuf());
677 }
egdaniel9cb63402016-06-23 08:37:05 -0700678
Brian Salomond818ebf2018-07-02 14:08:49 +0000679 if (!pipeline.isScissorEnabled()) {
Robert Phillipsb0e93a22017-08-29 08:26:54 -0400680 GrVkPipeline::SetDynamicScissorRectState(fGpu, cbInfo.currentCmdBuf(),
Robert Phillipsd0fe8752019-01-31 14:13:59 -0500681 fRenderTarget, fOrigin,
682 SkIRect::MakeWH(fRenderTarget->width(),
683 fRenderTarget->height()));
Brian Salomon49348902018-06-26 09:12:38 -0400684 } else if (!dynamicStateArrays || !dynamicStateArrays->fScissorRects) {
685 SkASSERT(fixedDynamicState);
Robert Phillipsd0fe8752019-01-31 14:13:59 -0500686 GrVkPipeline::SetDynamicScissorRectState(fGpu, cbInfo.currentCmdBuf(), fRenderTarget,
687 fOrigin,
Brian Salomon49348902018-06-26 09:12:38 -0400688 fixedDynamicState->fScissorRect);
Chris Dalton46983b72017-06-06 12:27:16 -0600689 }
Robert Phillipsd0fe8752019-01-31 14:13:59 -0500690 GrVkPipeline::SetDynamicViewportState(fGpu, cbInfo.currentCmdBuf(), fRenderTarget);
691 GrVkPipeline::SetDynamicBlendConstantState(fGpu, cbInfo.currentCmdBuf(),
692 fRenderTarget->config(),
Chris Dalton46983b72017-06-06 12:27:16 -0600693 pipeline.getXferProcessor());
egdaniel9cb63402016-06-23 08:37:05 -0700694
695 return pipelineState;
696}
697
Brian Salomonff168d92018-06-23 15:17:27 -0400698void GrVkGpuRTCommandBuffer::onDraw(const GrPrimitiveProcessor& primProc,
699 const GrPipeline& pipeline,
Brian Salomon49348902018-06-26 09:12:38 -0400700 const GrPipeline::FixedDynamicState* fixedDynamicState,
701 const GrPipeline::DynamicStateArrays* dynamicStateArrays,
Greg Daniel500d58b2017-08-24 15:59:33 -0400702 const GrMesh meshes[],
Greg Daniel500d58b2017-08-24 15:59:33 -0400703 int meshCount,
704 const SkRect& bounds) {
egdaniel9cb63402016-06-23 08:37:05 -0700705 if (!meshCount) {
706 return;
707 }
Greg Danielea022cd2018-03-16 11:10:03 -0400708
709 CommandBufferInfo& cbInfo = fCommandBufferInfos[fCurrentCmdInfo];
710
Brian Salomone782f842018-07-31 13:53:11 -0400711 auto prepareSampledImage = [&](GrTexture* texture, GrSamplerState::Filter filter) {
712 GrVkTexture* vkTexture = static_cast<GrVkTexture*>(texture);
713 // We may need to resolve the texture first if it is also a render target
714 GrVkRenderTarget* texRT = static_cast<GrVkRenderTarget*>(vkTexture->asRenderTarget());
715 if (texRT) {
Greg Daniel0a77f432018-12-06 11:23:32 -0500716 fGpu->resolveRenderTargetNoFlush(texRT);
Brian Salomone782f842018-07-31 13:53:11 -0400717 }
718
719 // Check if we need to regenerate any mip maps
720 if (GrSamplerState::Filter::kMipMap == filter &&
721 (vkTexture->width() != 1 || vkTexture->height() != 1)) {
722 SkASSERT(vkTexture->texturePriv().mipMapped() == GrMipMapped::kYes);
723 if (vkTexture->texturePriv().mipMapsAreDirty()) {
724 fGpu->regenerateMipMapLevels(vkTexture);
725 }
726 }
Chris Dalton298238a2019-02-21 16:28:44 -0500727 cbInfo.fSampledTextures.push_back(sk_ref_sp(vkTexture));
Brian Salomone782f842018-07-31 13:53:11 -0400728 };
729
Brian Salomonf7232642018-09-19 08:58:08 -0400730 if (dynamicStateArrays && dynamicStateArrays->fPrimitiveProcessorTextures) {
731 for (int m = 0, i = 0; m < meshCount; ++m) {
732 for (int s = 0; s < primProc.numTextureSamplers(); ++s, ++i) {
733 auto texture = dynamicStateArrays->fPrimitiveProcessorTextures[i]->peekTexture();
734 prepareSampledImage(texture, primProc.textureSampler(s).samplerState().filter());
735 }
736 }
737 } else {
738 for (int i = 0; i < primProc.numTextureSamplers(); ++i) {
739 auto texture = fixedDynamicState->fPrimitiveProcessorTextures[i]->peekTexture();
740 prepareSampledImage(texture, primProc.textureSampler(i).samplerState().filter());
741 }
Brian Salomone782f842018-07-31 13:53:11 -0400742 }
bsalomonb58a2b42016-09-26 06:55:02 -0700743 GrFragmentProcessor::Iter iter(pipeline);
744 while (const GrFragmentProcessor* fp = iter.next()) {
Brian Salomone782f842018-07-31 13:53:11 -0400745 for (int i = 0; i < fp->numTextureSamplers(); ++i) {
746 const GrFragmentProcessor::TextureSampler& sampler = fp->textureSampler(i);
747 prepareSampledImage(sampler.peekTexture(), sampler.samplerState().filter());
748 }
egdaniel2f5792a2016-07-06 08:51:23 -0700749 }
Robert Phillipsbb581ce2017-05-29 15:05:15 -0400750 if (GrTexture* dstTexture = pipeline.peekDstTexture()) {
Chris Dalton298238a2019-02-21 16:28:44 -0500751 cbInfo.fSampledTextures.push_back(sk_ref_sp(static_cast<GrVkTexture*>(dstTexture)));
Brian Salomon18dfa982017-04-03 16:57:43 -0400752 }
egdaniel2f5792a2016-07-06 08:51:23 -0700753
Chris Daltonbca46e22017-05-15 11:03:26 -0600754 GrPrimitiveType primitiveType = meshes[0].primitiveType();
Brian Salomon49348902018-06-26 09:12:38 -0400755 GrVkPipelineState* pipelineState = this->prepareDrawState(primProc, pipeline, fixedDynamicState,
756 dynamicStateArrays, primitiveType);
egdaniel9cb63402016-06-23 08:37:05 -0700757 if (!pipelineState) {
758 return;
759 }
760
Brian Salomond818ebf2018-07-02 14:08:49 +0000761 bool dynamicScissor =
762 pipeline.isScissorEnabled() && dynamicStateArrays && dynamicStateArrays->fScissorRects;
Brian Salomonf7232642018-09-19 08:58:08 -0400763 bool dynamicTextures = dynamicStateArrays && dynamicStateArrays->fPrimitiveProcessorTextures;
Brian Salomon49348902018-06-26 09:12:38 -0400764
egdaniel9cb63402016-06-23 08:37:05 -0700765 for (int i = 0; i < meshCount; ++i) {
766 const GrMesh& mesh = meshes[i];
Chris Daltonbca46e22017-05-15 11:03:26 -0600767 if (mesh.primitiveType() != primitiveType) {
Chris Dalton6f241802017-05-08 13:58:38 -0400768 SkDEBUGCODE(pipelineState = nullptr);
Chris Daltonbca46e22017-05-15 11:03:26 -0600769 primitiveType = mesh.primitiveType();
Brian Salomon49348902018-06-26 09:12:38 -0400770 pipelineState = this->prepareDrawState(primProc, pipeline, fixedDynamicState,
771 dynamicStateArrays, primitiveType);
Chris Dalton6f241802017-05-08 13:58:38 -0400772 if (!pipelineState) {
773 return;
egdaniel9cb63402016-06-23 08:37:05 -0700774 }
Chris Dalton6f241802017-05-08 13:58:38 -0400775 }
egdaniel9cb63402016-06-23 08:37:05 -0700776
Brian Salomon49348902018-06-26 09:12:38 -0400777 if (dynamicScissor) {
778 GrVkPipeline::SetDynamicScissorRectState(fGpu, cbInfo.currentCmdBuf(), fRenderTarget,
Robert Phillipsd0fe8752019-01-31 14:13:59 -0500779 fOrigin,
Brian Salomon49348902018-06-26 09:12:38 -0400780 dynamicStateArrays->fScissorRects[i]);
Chris Dalton46983b72017-06-06 12:27:16 -0600781 }
Brian Salomonf7232642018-09-19 08:58:08 -0400782 if (dynamicTextures) {
783 GrTextureProxy* const* meshProxies = dynamicStateArrays->fPrimitiveProcessorTextures +
784 primProc.numTextureSamplers() * i;
785 pipelineState->setAndBindTextures(fGpu, primProc, pipeline, meshProxies,
786 cbInfo.currentCmdBuf());
787 }
Chris Daltonbca46e22017-05-15 11:03:26 -0600788 SkASSERT(pipelineState);
Brian Salomon802cb312018-06-08 18:05:20 -0400789 mesh.sendToGpu(this);
egdaniel9cb63402016-06-23 08:37:05 -0700790 }
791
Greg Daniel36a77ee2016-10-18 10:33:25 -0400792 cbInfo.fBounds.join(bounds);
Chris Dalton114a3c02017-05-26 15:17:19 -0600793 cbInfo.fIsEmpty = false;
egdaniel066df7c2016-06-08 14:02:27 -0700794}
795
Brian Salomon802cb312018-06-08 18:05:20 -0400796void GrVkGpuRTCommandBuffer::sendInstancedMeshToGpu(GrPrimitiveType,
Greg Daniel500d58b2017-08-24 15:59:33 -0400797 const GrBuffer* vertexBuffer,
798 int vertexCount,
799 int baseVertex,
800 const GrBuffer* instanceBuffer,
801 int instanceCount,
802 int baseInstance) {
Chris Dalton114a3c02017-05-26 15:17:19 -0600803 CommandBufferInfo& cbInfo = fCommandBufferInfos[fCurrentCmdInfo];
Brian Salomondbf70722019-02-07 11:31:24 -0500804 SkASSERT(!vertexBuffer || !vertexBuffer->isCpuBuffer());
805 SkASSERT(!instanceBuffer || !instanceBuffer->isCpuBuffer());
806 auto gpuVertexBuffer = static_cast<const GrGpuBuffer*>(vertexBuffer);
807 auto gpuInstanceBuffer = static_cast<const GrGpuBuffer*>(instanceBuffer);
808 this->bindGeometry(nullptr, gpuVertexBuffer, gpuInstanceBuffer);
Chris Dalton1d616352017-05-31 12:51:23 -0600809 cbInfo.currentCmdBuf()->draw(fGpu, vertexCount, instanceCount, baseVertex, baseInstance);
Chris Dalton114a3c02017-05-26 15:17:19 -0600810 fGpu->stats()->incNumDraws();
811}
812
Brian Salomon802cb312018-06-08 18:05:20 -0400813void GrVkGpuRTCommandBuffer::sendIndexedInstancedMeshToGpu(GrPrimitiveType,
Greg Daniel500d58b2017-08-24 15:59:33 -0400814 const GrBuffer* indexBuffer,
815 int indexCount,
816 int baseIndex,
817 const GrBuffer* vertexBuffer,
818 int baseVertex,
819 const GrBuffer* instanceBuffer,
820 int instanceCount,
Brian Salomon802cb312018-06-08 18:05:20 -0400821 int baseInstance,
822 GrPrimitiveRestart restart) {
823 SkASSERT(restart == GrPrimitiveRestart::kNo);
Chris Dalton114a3c02017-05-26 15:17:19 -0600824 CommandBufferInfo& cbInfo = fCommandBufferInfos[fCurrentCmdInfo];
Brian Salomondbf70722019-02-07 11:31:24 -0500825 SkASSERT(!vertexBuffer || !vertexBuffer->isCpuBuffer());
826 SkASSERT(!instanceBuffer || !instanceBuffer->isCpuBuffer());
827 SkASSERT(!indexBuffer->isCpuBuffer());
828 auto gpuIndexxBuffer = static_cast<const GrGpuBuffer*>(indexBuffer);
829 auto gpuVertexBuffer = static_cast<const GrGpuBuffer*>(vertexBuffer);
830 auto gpuInstanceBuffer = static_cast<const GrGpuBuffer*>(instanceBuffer);
831 this->bindGeometry(gpuIndexxBuffer, gpuVertexBuffer, gpuInstanceBuffer);
Chris Dalton1d616352017-05-31 12:51:23 -0600832 cbInfo.currentCmdBuf()->drawIndexed(fGpu, indexCount, instanceCount,
833 baseIndex, baseVertex, baseInstance);
Chris Dalton114a3c02017-05-26 15:17:19 -0600834 fGpu->stats()->incNumDraws();
835}
Greg Daniel64cc9aa2018-10-19 13:54:56 -0400836
837////////////////////////////////////////////////////////////////////////////////
838
839void GrVkGpuRTCommandBuffer::executeDrawable(std::unique_ptr<SkDrawable::GpuDrawHandler> drawable) {
840 GrVkRenderTarget* target = static_cast<GrVkRenderTarget*>(fRenderTarget);
841
842 GrVkImage* targetImage = target->msaaImage() ? target->msaaImage() : target;
843
844 CommandBufferInfo& cbInfo = fCommandBufferInfos[fCurrentCmdInfo];
845 VkRect2D bounds;
846 bounds.offset = { 0, 0 };
847 bounds.extent = { 0, 0 };
848
849 GrVkDrawableInfo vkInfo;
850 vkInfo.fSecondaryCommandBuffer = cbInfo.currentCmdBuf()->vkCommandBuffer();
851 vkInfo.fCompatibleRenderPass = cbInfo.fRenderPass->vkRenderPass();
Greg Danielb353eeb2018-12-05 11:01:58 -0500852 SkAssertResult(cbInfo.fRenderPass->colorAttachmentIndex(&vkInfo.fColorAttachmentIndex));
Greg Daniel64cc9aa2018-10-19 13:54:56 -0400853 vkInfo.fFormat = targetImage->imageFormat();
854 vkInfo.fDrawBounds = &bounds;
Stan Ilievcb580602019-02-26 11:36:07 -0500855#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
856 vkInfo.fImage = targetImage->image();
857#else
858 vkInfo.fImage = VK_NULL_HANDLE;
859#endif //SK_BUILD_FOR_ANDROID_FRAMEWORK
Greg Daniel64cc9aa2018-10-19 13:54:56 -0400860
861 GrBackendDrawableInfo info(vkInfo);
862
Eric Karlc0b2ba22019-01-22 19:40:35 -0800863 // After we draw into the command buffer via the drawable, cached state we have may be invalid.
864 cbInfo.currentCmdBuf()->invalidateState();
Eric Karla8878a12019-02-07 18:17:43 -0800865 // Also assume that the drawable produced output.
866 cbInfo.fIsEmpty = false;
Eric Karlc0b2ba22019-01-22 19:40:35 -0800867
Greg Daniel64cc9aa2018-10-19 13:54:56 -0400868 drawable->draw(info);
869 fGpu->addDrawable(std::move(drawable));
870
871 if (bounds.extent.width == 0 || bounds.extent.height == 0) {
872 cbInfo.fBounds.join(target->getBoundsRect());
873 } else {
874 cbInfo.fBounds.join(SkRect::MakeXYWH(bounds.offset.x, bounds.offset.y,
875 bounds.extent.width, bounds.extent.height));
876 }
877}
878