blob: 3cbc6adf51cad04be907572edffb9cebf5daf50b [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
csmartdalton29df7602016-08-31 11:55:52 -070010#include "GrFixedClip.h"
egdaniel9cb63402016-06-23 08:37:05 -070011#include "GrMesh.h"
Brian Salomon742e31d2016-12-07 17:06:19 -050012#include "GrOpFlushState.h"
egdaniel9cb63402016-06-23 08:37:05 -070013#include "GrPipeline.h"
14#include "GrRenderTargetPriv.h"
egdaniel9cb63402016-06-23 08:37:05 -070015#include "GrTexturePriv.h"
egdaniel066df7c2016-06-08 14:02:27 -070016#include "GrVkCommandBuffer.h"
17#include "GrVkGpu.h"
egdaniel9cb63402016-06-23 08:37:05 -070018#include "GrVkPipeline.h"
egdaniel066df7c2016-06-08 14:02:27 -070019#include "GrVkRenderPass.h"
20#include "GrVkRenderTarget.h"
21#include "GrVkResourceProvider.h"
egdaniel9cb63402016-06-23 08:37:05 -070022#include "GrVkTexture.h"
Greg Daniel36a77ee2016-10-18 10:33:25 -040023#include "SkRect.h"
egdaniel066df7c2016-06-08 14:02:27 -070024
Robert Phillipsb0e93a22017-08-29 08:26:54 -040025void GrVkGpuTextureCommandBuffer::copy(GrSurface* src, GrSurfaceOrigin srcOrigin,
26 const SkIRect& srcRect, const SkIPoint& dstPoint) {
27 fCopies.emplace_back(src, srcOrigin, srcRect, dstPoint);
Greg Daniel500d58b2017-08-24 15:59:33 -040028}
29
30void GrVkGpuTextureCommandBuffer::insertEventMarker(const char* msg) {
31 // TODO: does Vulkan have a correlate?
32}
33
34void GrVkGpuTextureCommandBuffer::submit() {
35 for (int i = 0; i < fCopies.count(); ++i) {
36 CopyInfo& copyInfo = fCopies[i];
Robert Phillipsb0e93a22017-08-29 08:26:54 -040037 fGpu->copySurface(fTexture, fOrigin, copyInfo.fSrc, copyInfo.fSrcOrigin, copyInfo.fSrcRect,
38 copyInfo.fDstPoint);
Greg Daniel500d58b2017-08-24 15:59:33 -040039 }
40}
41
42GrVkGpuTextureCommandBuffer::~GrVkGpuTextureCommandBuffer() {}
43
44////////////////////////////////////////////////////////////////////////////////
45
Robert Phillips6b47c7d2017-08-29 07:24:09 -040046void get_vk_load_store_ops(GrLoadOp loadOpIn, GrStoreOp storeOpIn,
egdaniel066df7c2016-06-08 14:02:27 -070047 VkAttachmentLoadOp* loadOp, VkAttachmentStoreOp* storeOp) {
Robert Phillips95214472017-08-08 18:00:03 -040048 switch (loadOpIn) {
Robert Phillips6b47c7d2017-08-29 07:24:09 -040049 case GrLoadOp::kLoad:
egdaniel066df7c2016-06-08 14:02:27 -070050 *loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
egdaniel066df7c2016-06-08 14:02:27 -070051 break;
Robert Phillips6b47c7d2017-08-29 07:24:09 -040052 case GrLoadOp::kClear:
egdaniel9cb63402016-06-23 08:37:05 -070053 *loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
54 break;
Robert Phillips6b47c7d2017-08-29 07:24:09 -040055 case GrLoadOp::kDiscard:
egdaniel9cb63402016-06-23 08:37:05 -070056 *loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
57 break;
58 default:
59 SK_ABORT("Invalid LoadOp");
egdaniel066df7c2016-06-08 14:02:27 -070060 *loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
egdaniel9cb63402016-06-23 08:37:05 -070061 }
62
Robert Phillips95214472017-08-08 18:00:03 -040063 switch (storeOpIn) {
Robert Phillips6b47c7d2017-08-29 07:24:09 -040064 case GrStoreOp::kStore:
egdaniel066df7c2016-06-08 14:02:27 -070065 *storeOp = VK_ATTACHMENT_STORE_OP_STORE;
66 break;
Robert Phillips6b47c7d2017-08-29 07:24:09 -040067 case GrStoreOp::kDiscard:
egdaniel066df7c2016-06-08 14:02:27 -070068 *storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
69 break;
brianosman0bbc3712016-06-14 04:53:09 -070070 default:
egdaniel9cb63402016-06-23 08:37:05 -070071 SK_ABORT("Invalid StoreOp");
brianosman0bbc3712016-06-14 04:53:09 -070072 *storeOp = VK_ATTACHMENT_STORE_OP_STORE;
egdaniel066df7c2016-06-08 14:02:27 -070073 }
74}
75
Greg Daniel500d58b2017-08-24 15:59:33 -040076GrVkGpuRTCommandBuffer::GrVkGpuRTCommandBuffer(GrVkGpu* gpu,
77 GrRenderTarget* rt, GrSurfaceOrigin origin,
78 const LoadAndStoreInfo& colorInfo,
79 const StencilLoadAndStoreInfo& stencilInfo)
Robert Phillips19e51dc2017-08-09 09:30:51 -040080 : INHERITED(rt, origin)
81 , fGpu(gpu)
82 , fClearColor(GrColor4f::FromGrColor(colorInfo.fClearColor))
83 , fLastPipelineState(nullptr) {
Robert Phillips95214472017-08-08 18:00:03 -040084 get_vk_load_store_ops(colorInfo.fLoadOp, colorInfo.fStoreOp,
85 &fVkColorLoadOp, &fVkColorStoreOp);
egdaniel066df7c2016-06-08 14:02:27 -070086
Robert Phillips95214472017-08-08 18:00:03 -040087 get_vk_load_store_ops(stencilInfo.fLoadOp, stencilInfo.fStoreOp,
88 &fVkStencilLoadOp, &fVkStencilStoreOp);
Greg Daniel22bc8652017-03-22 15:45:43 -040089 fCurrentCmdInfo = -1;
Robert Phillips95214472017-08-08 18:00:03 -040090
Robert Phillips19e51dc2017-08-09 09:30:51 -040091 this->init();
Brian Salomonc293a292016-11-30 13:38:32 -050092}
93
Greg Daniel500d58b2017-08-24 15:59:33 -040094void GrVkGpuRTCommandBuffer::init() {
Brian Salomonc293a292016-11-30 13:38:32 -050095 GrVkRenderPass::LoadStoreOps vkColorOps(fVkColorLoadOp, fVkColorStoreOp);
96 GrVkRenderPass::LoadStoreOps vkStencilOps(fVkStencilLoadOp, fVkStencilStoreOp);
egdaniel9cb63402016-06-23 08:37:05 -070097
Greg Daniel36a77ee2016-10-18 10:33:25 -040098 CommandBufferInfo& cbInfo = fCommandBufferInfos.push_back();
Brian Salomonc293a292016-11-30 13:38:32 -050099 SkASSERT(fCommandBufferInfos.count() == 1);
Greg Daniel22bc8652017-03-22 15:45:43 -0400100 fCurrentCmdInfo = 0;
Greg Daniel36a77ee2016-10-18 10:33:25 -0400101
Robert Phillips19e51dc2017-08-09 09:30:51 -0400102 GrVkRenderTarget* vkRT = static_cast<GrVkRenderTarget*>(fRenderTarget);
103 const GrVkResourceProvider::CompatibleRPHandle& rpHandle = vkRT->compatibleRenderPassHandle();
egdaniel066df7c2016-06-08 14:02:27 -0700104 if (rpHandle.isValid()) {
Greg Daniel36a77ee2016-10-18 10:33:25 -0400105 cbInfo.fRenderPass = fGpu->resourceProvider().findRenderPass(rpHandle,
106 vkColorOps,
107 vkStencilOps);
egdaniel066df7c2016-06-08 14:02:27 -0700108 } else {
Robert Phillips19e51dc2017-08-09 09:30:51 -0400109 cbInfo.fRenderPass = fGpu->resourceProvider().findRenderPass(*vkRT,
Greg Daniel36a77ee2016-10-18 10:33:25 -0400110 vkColorOps,
111 vkStencilOps);
egdaniel066df7c2016-06-08 14:02:27 -0700112 }
113
Brian Salomonc293a292016-11-30 13:38:32 -0500114 cbInfo.fColorClearValue.color.float32[0] = fClearColor.fRGBA[0];
115 cbInfo.fColorClearValue.color.float32[1] = fClearColor.fRGBA[1];
116 cbInfo.fColorClearValue.color.float32[2] = fClearColor.fRGBA[2];
117 cbInfo.fColorClearValue.color.float32[3] = fClearColor.fRGBA[3];
egdaniel9cb63402016-06-23 08:37:05 -0700118
Robert Phillips380b90c2017-08-30 07:41:07 -0400119 if (VK_ATTACHMENT_LOAD_OP_CLEAR == fVkColorLoadOp) {
120 cbInfo.fBounds = SkRect::MakeWH(vkRT->width(), vkRT->height());
121 } else {
122 cbInfo.fBounds.setEmpty();
123 }
Greg Daniela3c68df2018-03-16 13:46:53 -0400124
125 if (VK_ATTACHMENT_LOAD_OP_CLEAR == fVkColorLoadOp) {
126 cbInfo.fLoadStoreState = LoadStoreState::kStartsWithClear;
127 } else if (VK_ATTACHMENT_LOAD_OP_LOAD == fVkColorLoadOp &&
128 VK_ATTACHMENT_STORE_OP_STORE == fVkColorStoreOp) {
129 cbInfo.fLoadStoreState = LoadStoreState::kLoadAndStore;
130 } else if (VK_ATTACHMENT_LOAD_OP_DONT_CARE == fVkColorLoadOp) {
131 cbInfo.fLoadStoreState = LoadStoreState::kStartsWithDiscard;
132 }
Greg Daniel36a77ee2016-10-18 10:33:25 -0400133
Greg Daniel22bc8652017-03-22 15:45:43 -0400134 cbInfo.fCommandBuffers.push_back(fGpu->resourceProvider().findOrCreateSecondaryCommandBuffer());
Robert Phillips19e51dc2017-08-09 09:30:51 -0400135 cbInfo.currentCmdBuf()->begin(fGpu, vkRT->framebuffer(), cbInfo.fRenderPass);
egdaniel066df7c2016-06-08 14:02:27 -0700136}
137
Brian Salomonc293a292016-11-30 13:38:32 -0500138
Greg Daniel500d58b2017-08-24 15:59:33 -0400139GrVkGpuRTCommandBuffer::~GrVkGpuRTCommandBuffer() {
Greg Daniel36a77ee2016-10-18 10:33:25 -0400140 for (int i = 0; i < fCommandBufferInfos.count(); ++i) {
141 CommandBufferInfo& cbInfo = fCommandBufferInfos[i];
Greg Daniel22bc8652017-03-22 15:45:43 -0400142 for (int j = 0; j < cbInfo.fCommandBuffers.count(); ++j) {
143 cbInfo.fCommandBuffers[j]->unref(fGpu);
144 }
Greg Daniel36a77ee2016-10-18 10:33:25 -0400145 cbInfo.fRenderPass->unref(fGpu);
146 }
egdaniel066df7c2016-06-08 14:02:27 -0700147}
148
Greg Daniel500d58b2017-08-24 15:59:33 -0400149GrGpu* GrVkGpuRTCommandBuffer::gpu() { return fGpu; }
egdaniel9cb63402016-06-23 08:37:05 -0700150
Greg Daniel500d58b2017-08-24 15:59:33 -0400151void GrVkGpuRTCommandBuffer::end() {
Greg Daniel22bc8652017-03-22 15:45:43 -0400152 if (fCurrentCmdInfo >= 0) {
153 fCommandBufferInfos[fCurrentCmdInfo].currentCmdBuf()->end(fGpu);
Brian Salomonc293a292016-11-30 13:38:32 -0500154 }
egdaniel066df7c2016-06-08 14:02:27 -0700155}
156
Greg Daniel500d58b2017-08-24 15:59:33 -0400157void GrVkGpuRTCommandBuffer::submit() {
Brian Salomonc293a292016-11-30 13:38:32 -0500158 if (!fRenderTarget) {
159 return;
160 }
Robert Phillips19e51dc2017-08-09 09:30:51 -0400161
162 GrVkRenderTarget* vkRT = static_cast<GrVkRenderTarget*>(fRenderTarget);
Robert Phillips19e51dc2017-08-09 09:30:51 -0400163 GrVkImage* targetImage = vkRT->msaaImage() ? vkRT->msaaImage() : vkRT;
Greg Daniel45a44de2018-02-27 10:07:29 -0500164 GrStencilAttachment* stencil = fRenderTarget->renderTargetPriv().getStencilAttachment();
egdaniel9cb63402016-06-23 08:37:05 -0700165
Greg Daniel36a77ee2016-10-18 10:33:25 -0400166 for (int i = 0; i < fCommandBufferInfos.count(); ++i) {
167 CommandBufferInfo& cbInfo = fCommandBufferInfos[i];
168
Greg Daniel77b53f62016-10-18 11:48:51 -0400169 for (int j = 0; j < cbInfo.fPreDrawUploads.count(); ++j) {
170 InlineUploadInfo& iuInfo = cbInfo.fPreDrawUploads[j];
171 iuInfo.fFlushState->doUpload(iuInfo.fUpload);
172 }
173
Greg Daniel500d58b2017-08-24 15:59:33 -0400174 for (int j = 0; j < cbInfo.fPreCopies.count(); ++j) {
175 CopyInfo& copyInfo = cbInfo.fPreCopies[j];
Robert Phillipsb0e93a22017-08-29 08:26:54 -0400176 fGpu->copySurface(fRenderTarget, fOrigin, copyInfo.fSrc, copyInfo.fSrcOrigin,
Greg Daniel55fa6472018-03-16 16:13:10 -0400177 copyInfo.fSrcRect, copyInfo.fDstPoint, copyInfo.fShouldDiscardDst);
Greg Daniel500d58b2017-08-24 15:59:33 -0400178 }
179
Greg Daniel45a44de2018-02-27 10:07:29 -0500180
Greg Daniel38c3d932018-03-16 14:22:30 -0400181 // TODO: Many things create a scratch texture which adds the discard immediately, but then
182 // don't draw to it right away. This causes the discard to be ignored and we get yelled at
183 // for loading uninitialized data. However, once MDB lands with reordering, the discard will
184 // get reordered with the rest of the draw commands and we can remove the discard check.
185 if (cbInfo.fIsEmpty &&
186 cbInfo.fLoadStoreState != LoadStoreState::kStartsWithClear &&
187 cbInfo.fLoadStoreState != LoadStoreState::kStartsWithDiscard) {
Greg Daniel77b53f62016-10-18 11:48:51 -0400188 // We have sumbitted no actual draw commands to the command buffer and we are not using
189 // the render pass to do a clear so there is no need to submit anything.
190 continue;
191 }
Greg Daniel38c3d932018-03-16 14:22:30 -0400192
Greg Danieldbdba602018-04-20 11:52:43 -0400193 // Make sure if we only have a discard load that we execute the discard on the whole image.
194 // TODO: Once we improve our tracking of discards so that we never end up flushing a discard
195 // call with no actually ops, remove this.
196 if (cbInfo.fIsEmpty && cbInfo.fLoadStoreState == LoadStoreState::kStartsWithDiscard) {
197 cbInfo.fBounds = SkRect::MakeWH(vkRT->width(), vkRT->height());
198 }
199
Greg Daniel36a77ee2016-10-18 10:33:25 -0400200 if (cbInfo.fBounds.intersect(0, 0,
201 SkIntToScalar(fRenderTarget->width()),
202 SkIntToScalar(fRenderTarget->height()))) {
Greg Daniel38c3d932018-03-16 14:22:30 -0400203 // Make sure we do the following layout changes after all copies, uploads, or any other
204 // pre-work is done since we may change the layouts in the pre-work. Also since the
205 // draws will be submitted in different render passes, we need to guard againts write
206 // and write issues.
207
208 // Change layout of our render target so it can be used as the color attachment.
209 targetImage->setImageLayout(fGpu,
210 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
211 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
212 VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT,
213 false);
214
215 // If we are using a stencil attachment we also need to update its layout
216 if (stencil) {
217 GrVkStencilAttachment* vkStencil = (GrVkStencilAttachment*)stencil;
218 vkStencil->setImageLayout(fGpu,
219 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
220 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT |
221 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT,
222 VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT,
223 false);
224 }
225
226 // If we have any sampled images set their layout now.
227 for (int j = 0; j < cbInfo.fSampledImages.count(); ++j) {
228 cbInfo.fSampledImages[j]->setImageLayout(fGpu,
229 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
230 VK_ACCESS_SHADER_READ_BIT,
231 VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT,
232 false);
233 }
234
Greg Daniel36a77ee2016-10-18 10:33:25 -0400235 SkIRect iBounds;
236 cbInfo.fBounds.roundOut(&iBounds);
237
Greg Daniel22bc8652017-03-22 15:45:43 -0400238 fGpu->submitSecondaryCommandBuffer(cbInfo.fCommandBuffers, cbInfo.fRenderPass,
Robert Phillipsb0e93a22017-08-29 08:26:54 -0400239 &cbInfo.fColorClearValue, vkRT, fOrigin, iBounds);
Greg Daniel36a77ee2016-10-18 10:33:25 -0400240 }
241 }
egdaniel9cb63402016-06-23 08:37:05 -0700242}
243
Greg Daniel500d58b2017-08-24 15:59:33 -0400244void GrVkGpuRTCommandBuffer::discard() {
Robert Phillips19e51dc2017-08-09 09:30:51 -0400245 GrVkRenderTarget* vkRT = static_cast<GrVkRenderTarget*>(fRenderTarget);
Brian Salomonc293a292016-11-30 13:38:32 -0500246
Greg Daniel22bc8652017-03-22 15:45:43 -0400247 CommandBufferInfo& cbInfo = fCommandBufferInfos[fCurrentCmdInfo];
Greg Daniel77b53f62016-10-18 11:48:51 -0400248 if (cbInfo.fIsEmpty) {
Robert Phillips74c627f2017-08-09 10:28:00 -0400249 // Change the render pass to do a don't-care load for both color & stencil
egdaniel37535c92016-06-30 08:23:30 -0700250 GrVkRenderPass::LoadStoreOps vkColorOps(VK_ATTACHMENT_LOAD_OP_DONT_CARE,
251 VK_ATTACHMENT_STORE_OP_STORE);
252 GrVkRenderPass::LoadStoreOps vkStencilOps(VK_ATTACHMENT_LOAD_OP_DONT_CARE,
253 VK_ATTACHMENT_STORE_OP_STORE);
egdaniel37535c92016-06-30 08:23:30 -0700254
Greg Daniel36a77ee2016-10-18 10:33:25 -0400255 const GrVkRenderPass* oldRP = cbInfo.fRenderPass;
egdaniel37535c92016-06-30 08:23:30 -0700256
egdaniel37535c92016-06-30 08:23:30 -0700257 const GrVkResourceProvider::CompatibleRPHandle& rpHandle =
Robert Phillips19e51dc2017-08-09 09:30:51 -0400258 vkRT->compatibleRenderPassHandle();
egdaniel37535c92016-06-30 08:23:30 -0700259 if (rpHandle.isValid()) {
Greg Daniel36a77ee2016-10-18 10:33:25 -0400260 cbInfo.fRenderPass = fGpu->resourceProvider().findRenderPass(rpHandle,
261 vkColorOps,
262 vkStencilOps);
egdaniel37535c92016-06-30 08:23:30 -0700263 } else {
Robert Phillips19e51dc2017-08-09 09:30:51 -0400264 cbInfo.fRenderPass = fGpu->resourceProvider().findRenderPass(*vkRT,
Greg Daniel36a77ee2016-10-18 10:33:25 -0400265 vkColorOps,
266 vkStencilOps);
egdaniel37535c92016-06-30 08:23:30 -0700267 }
268
Greg Daniel36a77ee2016-10-18 10:33:25 -0400269 SkASSERT(cbInfo.fRenderPass->isCompatible(*oldRP));
egdaniel37535c92016-06-30 08:23:30 -0700270 oldRP->unref(fGpu);
Greg Daniel5011f852016-10-28 15:07:16 -0400271 cbInfo.fBounds.join(fRenderTarget->getBoundsRect());
Greg Daniela3c68df2018-03-16 13:46:53 -0400272 cbInfo.fLoadStoreState = LoadStoreState::kStartsWithDiscard;
273 // If we are going to discard the whole render target then the results of any copies we did
274 // immediately before to the target won't matter, so just drop them.
275 cbInfo.fPreCopies.reset();
egdaniel37535c92016-06-30 08:23:30 -0700276 }
277}
278
Greg Daniel500d58b2017-08-24 15:59:33 -0400279void GrVkGpuRTCommandBuffer::insertEventMarker(const char* msg) {
Robert Phillips65a88fa2017-08-08 08:36:22 -0400280 // TODO: does Vulkan have a correlate?
281}
282
Greg Daniel500d58b2017-08-24 15:59:33 -0400283void GrVkGpuRTCommandBuffer::onClearStencilClip(const GrFixedClip& clip, bool insideStencilMask) {
Chris Dalton94c04682017-11-01 17:15:06 -0600284 SkASSERT(!clip.hasWindowRectangles());
285
Jim Van Verth6a40abc2017-11-02 16:56:09 +0000286 CommandBufferInfo& cbInfo = fCommandBufferInfos[fCurrentCmdInfo];
287
Greg Daniel65a09272016-10-12 09:47:22 -0400288 GrStencilAttachment* sb = fRenderTarget->renderTargetPriv().getStencilAttachment();
egdaniel9cb63402016-06-23 08:37:05 -0700289 // this should only be called internally when we know we have a
290 // stencil buffer.
291 SkASSERT(sb);
292 int stencilBitCount = sb->bits();
293
294 // The contract with the callers does not guarantee that we preserve all bits in the stencil
295 // during this clear. Thus we will clear the entire stencil to the desired value.
296
297 VkClearDepthStencilValue vkStencilColor;
298 memset(&vkStencilColor, 0, sizeof(VkClearDepthStencilValue));
csmartdalton29df7602016-08-31 11:55:52 -0700299 if (insideStencilMask) {
egdaniel9cb63402016-06-23 08:37:05 -0700300 vkStencilColor.stencil = (1 << (stencilBitCount - 1));
301 } else {
302 vkStencilColor.stencil = 0;
303 }
304
305 VkClearRect clearRect;
306 // Flip rect if necessary
csmartdalton29df7602016-08-31 11:55:52 -0700307 SkIRect vkRect;
Brian Salomond818ebf2018-07-02 14:08:49 +0000308 if (!clip.scissorEnabled()) {
Greg Daniel65a09272016-10-12 09:47:22 -0400309 vkRect.setXYWH(0, 0, fRenderTarget->width(), fRenderTarget->height());
Robert Phillips4f101a72017-07-28 08:42:04 -0400310 } else if (kBottomLeft_GrSurfaceOrigin != fOrigin) {
csmartdalton29df7602016-08-31 11:55:52 -0700311 vkRect = clip.scissorRect();
312 } else {
313 const SkIRect& scissor = clip.scissorRect();
Greg Daniel65a09272016-10-12 09:47:22 -0400314 vkRect.setLTRB(scissor.fLeft, fRenderTarget->height() - scissor.fBottom,
315 scissor.fRight, fRenderTarget->height() - scissor.fTop);
egdaniel9cb63402016-06-23 08:37:05 -0700316 }
317
318 clearRect.rect.offset = { vkRect.fLeft, vkRect.fTop };
319 clearRect.rect.extent = { (uint32_t)vkRect.width(), (uint32_t)vkRect.height() };
320
321 clearRect.baseArrayLayer = 0;
322 clearRect.layerCount = 1;
323
324 uint32_t stencilIndex;
Greg Daniel36a77ee2016-10-18 10:33:25 -0400325 SkAssertResult(cbInfo.fRenderPass->stencilAttachmentIndex(&stencilIndex));
egdaniel9cb63402016-06-23 08:37:05 -0700326
327 VkClearAttachment attachment;
328 attachment.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT;
329 attachment.colorAttachment = 0; // this value shouldn't matter
330 attachment.clearValue.depthStencil = vkStencilColor;
331
Greg Daniel22bc8652017-03-22 15:45:43 -0400332 cbInfo.currentCmdBuf()->clearAttachments(fGpu, 1, &attachment, 1, &clearRect);
Greg Daniel77b53f62016-10-18 11:48:51 -0400333 cbInfo.fIsEmpty = false;
Greg Daniel36a77ee2016-10-18 10:33:25 -0400334
335 // Update command buffer bounds
Brian Salomond818ebf2018-07-02 14:08:49 +0000336 if (!clip.scissorEnabled()) {
Greg Daniel36a77ee2016-10-18 10:33:25 -0400337 cbInfo.fBounds.join(fRenderTarget->getBoundsRect());
338 } else {
339 cbInfo.fBounds.join(SkRect::Make(clip.scissorRect()));
340 }
egdaniel9cb63402016-06-23 08:37:05 -0700341}
342
Greg Daniel500d58b2017-08-24 15:59:33 -0400343void GrVkGpuRTCommandBuffer::onClear(const GrFixedClip& clip, GrColor color) {
Robert Phillips19e51dc2017-08-09 09:30:51 -0400344 GrVkRenderTarget* vkRT = static_cast<GrVkRenderTarget*>(fRenderTarget);
345
Jim Van Verth6a40abc2017-11-02 16:56:09 +0000346 // parent class should never let us get here with no RT
csmartdaltonbf4a8f92016-09-06 10:01:06 -0700347 SkASSERT(!clip.hasWindowRectangles());
egdaniel9cb63402016-06-23 08:37:05 -0700348
Greg Daniel22bc8652017-03-22 15:45:43 -0400349 CommandBufferInfo& cbInfo = fCommandBufferInfos[fCurrentCmdInfo];
Greg Daniel36a77ee2016-10-18 10:33:25 -0400350
egdaniel9cb63402016-06-23 08:37:05 -0700351 VkClearColorValue vkColor;
352 GrColorToRGBAFloat(color, vkColor.float32);
353
Brian Salomond818ebf2018-07-02 14:08:49 +0000354 if (cbInfo.fIsEmpty && !clip.scissorEnabled()) {
Robert Phillips74c627f2017-08-09 10:28:00 -0400355 // Change the render pass to do a clear load
egdaniel9cb63402016-06-23 08:37:05 -0700356 GrVkRenderPass::LoadStoreOps vkColorOps(VK_ATTACHMENT_LOAD_OP_CLEAR,
357 VK_ATTACHMENT_STORE_OP_STORE);
Robert Phillips74c627f2017-08-09 10:28:00 -0400358 // Preserve the stencil buffer's load & store settings
359 GrVkRenderPass::LoadStoreOps vkStencilOps(fVkStencilLoadOp, fVkStencilStoreOp);
egdaniel9cb63402016-06-23 08:37:05 -0700360
Greg Daniel36a77ee2016-10-18 10:33:25 -0400361 const GrVkRenderPass* oldRP = cbInfo.fRenderPass;
egdaniel9cb63402016-06-23 08:37:05 -0700362
363 const GrVkResourceProvider::CompatibleRPHandle& rpHandle =
Robert Phillips19e51dc2017-08-09 09:30:51 -0400364 vkRT->compatibleRenderPassHandle();
egdaniel9cb63402016-06-23 08:37:05 -0700365 if (rpHandle.isValid()) {
Greg Daniel36a77ee2016-10-18 10:33:25 -0400366 cbInfo.fRenderPass = fGpu->resourceProvider().findRenderPass(rpHandle,
367 vkColorOps,
368 vkStencilOps);
egdaniel9cb63402016-06-23 08:37:05 -0700369 } else {
Robert Phillips19e51dc2017-08-09 09:30:51 -0400370 cbInfo.fRenderPass = fGpu->resourceProvider().findRenderPass(*vkRT,
Greg Daniel36a77ee2016-10-18 10:33:25 -0400371 vkColorOps,
372 vkStencilOps);
egdaniel9cb63402016-06-23 08:37:05 -0700373 }
374
Greg Daniel36a77ee2016-10-18 10:33:25 -0400375 SkASSERT(cbInfo.fRenderPass->isCompatible(*oldRP));
egdaniel9cb63402016-06-23 08:37:05 -0700376 oldRP->unref(fGpu);
377
Greg Daniel36a77ee2016-10-18 10:33:25 -0400378 GrColorToRGBAFloat(color, cbInfo.fColorClearValue.color.float32);
Greg Daniela3c68df2018-03-16 13:46:53 -0400379 cbInfo.fLoadStoreState = LoadStoreState::kStartsWithClear;
380 // If we are going to clear the whole render target then the results of any copies we did
381 // immediately before to the target won't matter, so just drop them.
382 cbInfo.fPreCopies.reset();
Greg Daniel36a77ee2016-10-18 10:33:25 -0400383
384 // Update command buffer bounds
385 cbInfo.fBounds.join(fRenderTarget->getBoundsRect());
egdaniel9cb63402016-06-23 08:37:05 -0700386 return;
387 }
388
389 // We always do a sub rect clear with clearAttachments since we are inside a render pass
390 VkClearRect clearRect;
391 // Flip rect if necessary
csmartdalton29df7602016-08-31 11:55:52 -0700392 SkIRect vkRect;
Brian Salomond818ebf2018-07-02 14:08:49 +0000393 if (!clip.scissorEnabled()) {
Greg Daniel65a09272016-10-12 09:47:22 -0400394 vkRect.setXYWH(0, 0, fRenderTarget->width(), fRenderTarget->height());
Robert Phillips4f101a72017-07-28 08:42:04 -0400395 } else if (kBottomLeft_GrSurfaceOrigin != fOrigin) {
csmartdalton29df7602016-08-31 11:55:52 -0700396 vkRect = clip.scissorRect();
397 } else {
398 const SkIRect& scissor = clip.scissorRect();
Greg Daniel65a09272016-10-12 09:47:22 -0400399 vkRect.setLTRB(scissor.fLeft, fRenderTarget->height() - scissor.fBottom,
400 scissor.fRight, fRenderTarget->height() - scissor.fTop);
egdaniel9cb63402016-06-23 08:37:05 -0700401 }
402 clearRect.rect.offset = { vkRect.fLeft, vkRect.fTop };
403 clearRect.rect.extent = { (uint32_t)vkRect.width(), (uint32_t)vkRect.height() };
404 clearRect.baseArrayLayer = 0;
405 clearRect.layerCount = 1;
406
407 uint32_t colorIndex;
Greg Daniel36a77ee2016-10-18 10:33:25 -0400408 SkAssertResult(cbInfo.fRenderPass->colorAttachmentIndex(&colorIndex));
egdaniel9cb63402016-06-23 08:37:05 -0700409
410 VkClearAttachment attachment;
411 attachment.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
412 attachment.colorAttachment = colorIndex;
413 attachment.clearValue.color = vkColor;
414
Greg Daniel22bc8652017-03-22 15:45:43 -0400415 cbInfo.currentCmdBuf()->clearAttachments(fGpu, 1, &attachment, 1, &clearRect);
Greg Daniel77b53f62016-10-18 11:48:51 -0400416 cbInfo.fIsEmpty = false;
Greg Daniel36a77ee2016-10-18 10:33:25 -0400417
418 // Update command buffer bounds
Brian Salomond818ebf2018-07-02 14:08:49 +0000419 if (!clip.scissorEnabled()) {
Greg Daniel36a77ee2016-10-18 10:33:25 -0400420 cbInfo.fBounds.join(fRenderTarget->getBoundsRect());
421 } else {
422 cbInfo.fBounds.join(SkRect::Make(clip.scissorRect()));
423 }
egdaniel9cb63402016-06-23 08:37:05 -0700424 return;
425}
426
Greg Daniel500d58b2017-08-24 15:59:33 -0400427////////////////////////////////////////////////////////////////////////////////
428
429void GrVkGpuRTCommandBuffer::addAdditionalCommandBuffer() {
Robert Phillips19e51dc2017-08-09 09:30:51 -0400430 GrVkRenderTarget* vkRT = static_cast<GrVkRenderTarget*>(fRenderTarget);
431
Greg Daniel22bc8652017-03-22 15:45:43 -0400432 CommandBufferInfo& cbInfo = fCommandBufferInfos[fCurrentCmdInfo];
433 cbInfo.currentCmdBuf()->end(fGpu);
434 cbInfo.fCommandBuffers.push_back(fGpu->resourceProvider().findOrCreateSecondaryCommandBuffer());
Robert Phillips19e51dc2017-08-09 09:30:51 -0400435 cbInfo.currentCmdBuf()->begin(fGpu, vkRT->framebuffer(), cbInfo.fRenderPass);
Greg Daniel22bc8652017-03-22 15:45:43 -0400436}
437
Greg Daniel500d58b2017-08-24 15:59:33 -0400438void GrVkGpuRTCommandBuffer::addAdditionalRenderPass() {
Robert Phillips19e51dc2017-08-09 09:30:51 -0400439 GrVkRenderTarget* vkRT = static_cast<GrVkRenderTarget*>(fRenderTarget);
440
Greg Daniel22bc8652017-03-22 15:45:43 -0400441 fCommandBufferInfos[fCurrentCmdInfo].currentCmdBuf()->end(fGpu);
Greg Daniel77b53f62016-10-18 11:48:51 -0400442
443 CommandBufferInfo& cbInfo = fCommandBufferInfos.push_back();
Greg Daniel22bc8652017-03-22 15:45:43 -0400444 fCurrentCmdInfo++;
Greg Daniel77b53f62016-10-18 11:48:51 -0400445
446 GrVkRenderPass::LoadStoreOps vkColorOps(VK_ATTACHMENT_LOAD_OP_LOAD,
447 VK_ATTACHMENT_STORE_OP_STORE);
448 GrVkRenderPass::LoadStoreOps vkStencilOps(VK_ATTACHMENT_LOAD_OP_LOAD,
449 VK_ATTACHMENT_STORE_OP_STORE);
450
451 const GrVkResourceProvider::CompatibleRPHandle& rpHandle =
Robert Phillips19e51dc2017-08-09 09:30:51 -0400452 vkRT->compatibleRenderPassHandle();
Greg Daniel77b53f62016-10-18 11:48:51 -0400453 if (rpHandle.isValid()) {
454 cbInfo.fRenderPass = fGpu->resourceProvider().findRenderPass(rpHandle,
455 vkColorOps,
456 vkStencilOps);
457 } else {
Robert Phillips19e51dc2017-08-09 09:30:51 -0400458 cbInfo.fRenderPass = fGpu->resourceProvider().findRenderPass(*vkRT,
Greg Daniel77b53f62016-10-18 11:48:51 -0400459 vkColorOps,
460 vkStencilOps);
461 }
Greg Daniela3c68df2018-03-16 13:46:53 -0400462 cbInfo.fLoadStoreState = LoadStoreState::kLoadAndStore;
Greg Daniel77b53f62016-10-18 11:48:51 -0400463
Greg Daniel22bc8652017-03-22 15:45:43 -0400464 cbInfo.fCommandBuffers.push_back(fGpu->resourceProvider().findOrCreateSecondaryCommandBuffer());
Greg Daniel77b53f62016-10-18 11:48:51 -0400465 // It shouldn't matter what we set the clear color to here since we will assume loading of the
466 // attachment.
467 memset(&cbInfo.fColorClearValue, 0, sizeof(VkClearValue));
468 cbInfo.fBounds.setEmpty();
Greg Daniel77b53f62016-10-18 11:48:51 -0400469
Robert Phillips19e51dc2017-08-09 09:30:51 -0400470 cbInfo.currentCmdBuf()->begin(fGpu, vkRT->framebuffer(), cbInfo.fRenderPass);
Greg Daniel77b53f62016-10-18 11:48:51 -0400471}
472
Brian Salomon943ed792017-10-30 09:37:55 -0400473void GrVkGpuRTCommandBuffer::inlineUpload(GrOpFlushState* state,
474 GrDeferredTextureUploadFn& upload) {
Greg Daniel22bc8652017-03-22 15:45:43 -0400475 if (!fCommandBufferInfos[fCurrentCmdInfo].fIsEmpty) {
476 this->addAdditionalRenderPass();
Greg Daniel77b53f62016-10-18 11:48:51 -0400477 }
Greg Daniel22bc8652017-03-22 15:45:43 -0400478 fCommandBufferInfos[fCurrentCmdInfo].fPreDrawUploads.emplace_back(state, upload);
Greg Daniel77b53f62016-10-18 11:48:51 -0400479}
480
Robert Phillipsb0e93a22017-08-29 08:26:54 -0400481void GrVkGpuRTCommandBuffer::copy(GrSurface* src, GrSurfaceOrigin srcOrigin, const SkIRect& srcRect,
Greg Daniel500d58b2017-08-24 15:59:33 -0400482 const SkIPoint& dstPoint) {
Greg Daniela3c68df2018-03-16 13:46:53 -0400483 CommandBufferInfo& cbInfo = fCommandBufferInfos[fCurrentCmdInfo];
484 if (!cbInfo.fIsEmpty || LoadStoreState::kStartsWithClear == cbInfo.fLoadStoreState) {
Greg Daniel500d58b2017-08-24 15:59:33 -0400485 this->addAdditionalRenderPass();
486 }
Greg Daniela3c68df2018-03-16 13:46:53 -0400487
Greg Daniel55fa6472018-03-16 16:13:10 -0400488 fCommandBufferInfos[fCurrentCmdInfo].fPreCopies.emplace_back(
489 src, srcOrigin, srcRect, dstPoint,
490 LoadStoreState::kStartsWithDiscard == cbInfo.fLoadStoreState);
491
Greg Daniela3c68df2018-03-16 13:46:53 -0400492 if (LoadStoreState::kLoadAndStore != cbInfo.fLoadStoreState) {
493 // Change the render pass to do a load and store so we don't lose the results of our copy
494 GrVkRenderPass::LoadStoreOps vkColorOps(VK_ATTACHMENT_LOAD_OP_LOAD,
495 VK_ATTACHMENT_STORE_OP_STORE);
496 GrVkRenderPass::LoadStoreOps vkStencilOps(VK_ATTACHMENT_LOAD_OP_LOAD,
497 VK_ATTACHMENT_STORE_OP_STORE);
498
499 const GrVkRenderPass* oldRP = cbInfo.fRenderPass;
500
501 GrVkRenderTarget* vkRT = static_cast<GrVkRenderTarget*>(fRenderTarget);
502 const GrVkResourceProvider::CompatibleRPHandle& rpHandle =
503 vkRT->compatibleRenderPassHandle();
504 if (rpHandle.isValid()) {
505 cbInfo.fRenderPass = fGpu->resourceProvider().findRenderPass(rpHandle,
506 vkColorOps,
507 vkStencilOps);
508 } else {
509 cbInfo.fRenderPass = fGpu->resourceProvider().findRenderPass(*vkRT,
510 vkColorOps,
511 vkStencilOps);
512 }
513 SkASSERT(cbInfo.fRenderPass->isCompatible(*oldRP));
514 oldRP->unref(fGpu);
515
516 cbInfo.fLoadStoreState = LoadStoreState::kLoadAndStore;
517
518 }
Greg Daniel500d58b2017-08-24 15:59:33 -0400519}
520
egdaniel9cb63402016-06-23 08:37:05 -0700521////////////////////////////////////////////////////////////////////////////////
522
Brian Salomon802cb312018-06-08 18:05:20 -0400523void GrVkGpuRTCommandBuffer::bindGeometry(const GrBuffer* indexBuffer,
Greg Daniel500d58b2017-08-24 15:59:33 -0400524 const GrBuffer* vertexBuffer,
525 const GrBuffer* instanceBuffer) {
Chris Daltonff926502017-05-03 14:36:54 -0400526 GrVkSecondaryCommandBuffer* currCmdBuf = fCommandBufferInfos[fCurrentCmdInfo].currentCmdBuf();
egdaniel9cb63402016-06-23 08:37:05 -0700527 // There is no need to put any memory barriers to make sure host writes have finished here.
528 // When a command buffer is submitted to a queue, there is an implicit memory barrier that
529 // occurs for all host writes. Additionally, BufferMemoryBarriers are not allowed inside of
530 // an active RenderPass.
egdaniel9cb63402016-06-23 08:37:05 -0700531
Chris Dalton1d616352017-05-31 12:51:23 -0600532 // Here our vertex and instance inputs need to match the same 0-based bindings they were
533 // assigned in GrVkPipeline. That is, vertex first (if any) followed by instance.
534 uint32_t binding = 0;
535
Brian Salomon802cb312018-06-08 18:05:20 -0400536 if (vertexBuffer) {
Chris Dalton1d616352017-05-31 12:51:23 -0600537 SkASSERT(vertexBuffer);
538 SkASSERT(!vertexBuffer->isCPUBacked());
539 SkASSERT(!vertexBuffer->isMapped());
540
541 currCmdBuf->bindInputBuffer(fGpu, binding++,
542 static_cast<const GrVkVertexBuffer*>(vertexBuffer));
543 }
544
Brian Salomon802cb312018-06-08 18:05:20 -0400545 if (instanceBuffer) {
Chris Dalton1d616352017-05-31 12:51:23 -0600546 SkASSERT(instanceBuffer);
547 SkASSERT(!instanceBuffer->isCPUBacked());
548 SkASSERT(!instanceBuffer->isMapped());
549
550 currCmdBuf->bindInputBuffer(fGpu, binding++,
551 static_cast<const GrVkVertexBuffer*>(instanceBuffer));
552 }
egdaniel9cb63402016-06-23 08:37:05 -0700553
Chris Daltonff926502017-05-03 14:36:54 -0400554 if (indexBuffer) {
555 SkASSERT(indexBuffer);
556 SkASSERT(!indexBuffer->isMapped());
557 SkASSERT(!indexBuffer->isCPUBacked());
egdaniel9cb63402016-06-23 08:37:05 -0700558
Chris Daltonff926502017-05-03 14:36:54 -0400559 currCmdBuf->bindIndexBuffer(fGpu, static_cast<const GrVkIndexBuffer*>(indexBuffer));
egdaniel9cb63402016-06-23 08:37:05 -0700560 }
561}
562
Brian Salomon49348902018-06-26 09:12:38 -0400563GrVkPipelineState* GrVkGpuRTCommandBuffer::prepareDrawState(
564 const GrPrimitiveProcessor& primProc,
565 const GrPipeline& pipeline,
566 const GrPipeline::FixedDynamicState* fixedDynamicState,
567 const GrPipeline::DynamicStateArrays* dynamicStateArrays,
568 GrPrimitiveType primitiveType) {
Greg Daniel22bc8652017-03-22 15:45:43 -0400569 CommandBufferInfo& cbInfo = fCommandBufferInfos[fCurrentCmdInfo];
570 SkASSERT(cbInfo.fRenderPass);
Greg Daniel36a77ee2016-10-18 10:33:25 -0400571
Greg Daniel09eeefb2017-10-16 15:15:02 -0400572 GrVkPipelineState* pipelineState =
egdaniel9cb63402016-06-23 08:37:05 -0700573 fGpu->resourceProvider().findOrCreateCompatiblePipelineState(pipeline,
574 primProc,
575 primitiveType,
Greg Daniel36a77ee2016-10-18 10:33:25 -0400576 *cbInfo.fRenderPass);
egdaniel9cb63402016-06-23 08:37:05 -0700577 if (!pipelineState) {
578 return pipelineState;
579 }
580
Greg Daniel22bc8652017-03-22 15:45:43 -0400581 if (!cbInfo.fIsEmpty &&
Greg Daniel09eeefb2017-10-16 15:15:02 -0400582 fLastPipelineState && fLastPipelineState != pipelineState &&
Greg Daniele3cd6912017-05-17 11:15:55 -0400583 fGpu->vkCaps().newCBOnPipelineChange()) {
Greg Daniel22bc8652017-03-22 15:45:43 -0400584 this->addAdditionalCommandBuffer();
585 }
Greg Daniel09eeefb2017-10-16 15:15:02 -0400586 fLastPipelineState = pipelineState;
Greg Daniel22bc8652017-03-22 15:45:43 -0400587
Brian Salomonaf874832018-08-03 11:53:40 -0400588 const GrTextureProxy* const* primProcProxies = nullptr;
589 if (fixedDynamicState) {
590 primProcProxies = fixedDynamicState->fPrimitiveProcessorTextures;
591 }
592 pipelineState->setData(fGpu, primProc, pipeline, primProcProxies);
egdaniel9cb63402016-06-23 08:37:05 -0700593
Greg Daniel22bc8652017-03-22 15:45:43 -0400594 pipelineState->bind(fGpu, cbInfo.currentCmdBuf());
egdaniel9cb63402016-06-23 08:37:05 -0700595
Robert Phillips2890fbf2017-07-26 15:48:41 -0400596 GrRenderTarget* rt = pipeline.renderTarget();
Chris Dalton46983b72017-06-06 12:27:16 -0600597
Brian Salomond818ebf2018-07-02 14:08:49 +0000598 if (!pipeline.isScissorEnabled()) {
Robert Phillipsb0e93a22017-08-29 08:26:54 -0400599 GrVkPipeline::SetDynamicScissorRectState(fGpu, cbInfo.currentCmdBuf(),
600 rt, pipeline.proxy()->origin(),
Chris Dalton46983b72017-06-06 12:27:16 -0600601 SkIRect::MakeWH(rt->width(), rt->height()));
Brian Salomon49348902018-06-26 09:12:38 -0400602 } else if (!dynamicStateArrays || !dynamicStateArrays->fScissorRects) {
603 SkASSERT(fixedDynamicState);
604 GrVkPipeline::SetDynamicScissorRectState(fGpu, cbInfo.currentCmdBuf(), rt,
605 pipeline.proxy()->origin(),
606 fixedDynamicState->fScissorRect);
Chris Dalton46983b72017-06-06 12:27:16 -0600607 }
Jim Van Verth6a40abc2017-11-02 16:56:09 +0000608 GrVkPipeline::SetDynamicViewportState(fGpu, cbInfo.currentCmdBuf(), rt);
Chris Dalton46983b72017-06-06 12:27:16 -0600609 GrVkPipeline::SetDynamicBlendConstantState(fGpu, cbInfo.currentCmdBuf(), rt->config(),
610 pipeline.getXferProcessor());
egdaniel9cb63402016-06-23 08:37:05 -0700611
612 return pipelineState;
613}
614
Brian Salomonff168d92018-06-23 15:17:27 -0400615void GrVkGpuRTCommandBuffer::onDraw(const GrPrimitiveProcessor& primProc,
616 const GrPipeline& pipeline,
Brian Salomon49348902018-06-26 09:12:38 -0400617 const GrPipeline::FixedDynamicState* fixedDynamicState,
618 const GrPipeline::DynamicStateArrays* dynamicStateArrays,
Greg Daniel500d58b2017-08-24 15:59:33 -0400619 const GrMesh meshes[],
Greg Daniel500d58b2017-08-24 15:59:33 -0400620 int meshCount,
621 const SkRect& bounds) {
Robert Phillips19e51dc2017-08-09 09:30:51 -0400622 SkASSERT(pipeline.renderTarget() == fRenderTarget);
Brian Salomonc293a292016-11-30 13:38:32 -0500623
egdaniel9cb63402016-06-23 08:37:05 -0700624 if (!meshCount) {
625 return;
626 }
Greg Danielea022cd2018-03-16 11:10:03 -0400627
628 CommandBufferInfo& cbInfo = fCommandBufferInfos[fCurrentCmdInfo];
629
Brian Salomone782f842018-07-31 13:53:11 -0400630 auto prepareSampledImage = [&](GrTexture* texture, GrSamplerState::Filter filter) {
631 GrVkTexture* vkTexture = static_cast<GrVkTexture*>(texture);
632 // We may need to resolve the texture first if it is also a render target
633 GrVkRenderTarget* texRT = static_cast<GrVkRenderTarget*>(vkTexture->asRenderTarget());
634 if (texRT) {
635 fGpu->onResolveRenderTarget(texRT);
636 }
637
638 // Check if we need to regenerate any mip maps
639 if (GrSamplerState::Filter::kMipMap == filter &&
640 (vkTexture->width() != 1 || vkTexture->height() != 1)) {
641 SkASSERT(vkTexture->texturePriv().mipMapped() == GrMipMapped::kYes);
642 if (vkTexture->texturePriv().mipMapsAreDirty()) {
643 fGpu->regenerateMipMapLevels(vkTexture);
644 }
645 }
646 cbInfo.fSampledImages.push_back(vkTexture);
647 };
648
649 for (int i = 0; i < primProc.numTextureSamplers(); ++i) {
Brian Salomonaf874832018-08-03 11:53:40 -0400650 auto texture = fixedDynamicState->fPrimitiveProcessorTextures[i]->peekTexture();
651 prepareSampledImage(texture, primProc.textureSampler(i).samplerState().filter());
Brian Salomone782f842018-07-31 13:53:11 -0400652 }
bsalomonb58a2b42016-09-26 06:55:02 -0700653 GrFragmentProcessor::Iter iter(pipeline);
654 while (const GrFragmentProcessor* fp = iter.next()) {
Brian Salomone782f842018-07-31 13:53:11 -0400655 for (int i = 0; i < fp->numTextureSamplers(); ++i) {
656 const GrFragmentProcessor::TextureSampler& sampler = fp->textureSampler(i);
657 prepareSampledImage(sampler.peekTexture(), sampler.samplerState().filter());
658 }
egdaniel2f5792a2016-07-06 08:51:23 -0700659 }
Robert Phillipsbb581ce2017-05-29 15:05:15 -0400660 if (GrTexture* dstTexture = pipeline.peekDstTexture()) {
Greg Danielea022cd2018-03-16 11:10:03 -0400661 cbInfo.fSampledImages.push_back(static_cast<GrVkTexture*>(dstTexture));
Brian Salomon18dfa982017-04-03 16:57:43 -0400662 }
egdaniel2f5792a2016-07-06 08:51:23 -0700663
Chris Daltonbca46e22017-05-15 11:03:26 -0600664 GrPrimitiveType primitiveType = meshes[0].primitiveType();
Brian Salomon49348902018-06-26 09:12:38 -0400665 GrVkPipelineState* pipelineState = this->prepareDrawState(primProc, pipeline, fixedDynamicState,
666 dynamicStateArrays, primitiveType);
egdaniel9cb63402016-06-23 08:37:05 -0700667 if (!pipelineState) {
668 return;
669 }
670
Brian Salomond818ebf2018-07-02 14:08:49 +0000671 bool dynamicScissor =
672 pipeline.isScissorEnabled() && dynamicStateArrays && dynamicStateArrays->fScissorRects;
Brian Salomon49348902018-06-26 09:12:38 -0400673
egdaniel9cb63402016-06-23 08:37:05 -0700674 for (int i = 0; i < meshCount; ++i) {
675 const GrMesh& mesh = meshes[i];
Chris Daltonbca46e22017-05-15 11:03:26 -0600676 if (mesh.primitiveType() != primitiveType) {
Chris Dalton6f241802017-05-08 13:58:38 -0400677 // Technically we don't have to call this here (since there is a safety check in
678 // pipelineState:setData but this will allow for quicker freeing of resources if the
679 // pipelineState sits in a cache for a while.
680 pipelineState->freeTempResources(fGpu);
681 SkDEBUGCODE(pipelineState = nullptr);
Chris Daltonbca46e22017-05-15 11:03:26 -0600682 primitiveType = mesh.primitiveType();
Brian Salomon49348902018-06-26 09:12:38 -0400683 pipelineState = this->prepareDrawState(primProc, pipeline, fixedDynamicState,
684 dynamicStateArrays, primitiveType);
Chris Dalton6f241802017-05-08 13:58:38 -0400685 if (!pipelineState) {
686 return;
egdaniel9cb63402016-06-23 08:37:05 -0700687 }
Chris Dalton6f241802017-05-08 13:58:38 -0400688 }
egdaniel9cb63402016-06-23 08:37:05 -0700689
Brian Salomon49348902018-06-26 09:12:38 -0400690 if (dynamicScissor) {
691 GrVkPipeline::SetDynamicScissorRectState(fGpu, cbInfo.currentCmdBuf(), fRenderTarget,
692 pipeline.proxy()->origin(),
693 dynamicStateArrays->fScissorRects[i]);
Chris Dalton46983b72017-06-06 12:27:16 -0600694 }
695
Chris Daltonbca46e22017-05-15 11:03:26 -0600696 SkASSERT(pipelineState);
Brian Salomon802cb312018-06-08 18:05:20 -0400697 mesh.sendToGpu(this);
egdaniel9cb63402016-06-23 08:37:05 -0700698 }
699
Greg Daniel36a77ee2016-10-18 10:33:25 -0400700 cbInfo.fBounds.join(bounds);
Chris Dalton114a3c02017-05-26 15:17:19 -0600701 cbInfo.fIsEmpty = false;
Greg Daniel36a77ee2016-10-18 10:33:25 -0400702
egdaniel9cb63402016-06-23 08:37:05 -0700703 // Technically we don't have to call this here (since there is a safety check in
704 // pipelineState:setData but this will allow for quicker freeing of resources if the
705 // pipelineState sits in a cache for a while.
706 pipelineState->freeTempResources(fGpu);
egdaniel066df7c2016-06-08 14:02:27 -0700707}
708
Brian Salomon802cb312018-06-08 18:05:20 -0400709void GrVkGpuRTCommandBuffer::sendInstancedMeshToGpu(GrPrimitiveType,
Greg Daniel500d58b2017-08-24 15:59:33 -0400710 const GrBuffer* vertexBuffer,
711 int vertexCount,
712 int baseVertex,
713 const GrBuffer* instanceBuffer,
714 int instanceCount,
715 int baseInstance) {
Chris Dalton114a3c02017-05-26 15:17:19 -0600716 CommandBufferInfo& cbInfo = fCommandBufferInfos[fCurrentCmdInfo];
Brian Salomon802cb312018-06-08 18:05:20 -0400717 this->bindGeometry(nullptr, vertexBuffer, instanceBuffer);
Chris Dalton1d616352017-05-31 12:51:23 -0600718 cbInfo.currentCmdBuf()->draw(fGpu, vertexCount, instanceCount, baseVertex, baseInstance);
Chris Dalton114a3c02017-05-26 15:17:19 -0600719 fGpu->stats()->incNumDraws();
720}
721
Brian Salomon802cb312018-06-08 18:05:20 -0400722void GrVkGpuRTCommandBuffer::sendIndexedInstancedMeshToGpu(GrPrimitiveType,
Greg Daniel500d58b2017-08-24 15:59:33 -0400723 const GrBuffer* indexBuffer,
724 int indexCount,
725 int baseIndex,
726 const GrBuffer* vertexBuffer,
727 int baseVertex,
728 const GrBuffer* instanceBuffer,
729 int instanceCount,
Brian Salomon802cb312018-06-08 18:05:20 -0400730 int baseInstance,
731 GrPrimitiveRestart restart) {
732 SkASSERT(restart == GrPrimitiveRestart::kNo);
Chris Dalton114a3c02017-05-26 15:17:19 -0600733 CommandBufferInfo& cbInfo = fCommandBufferInfos[fCurrentCmdInfo];
Brian Salomon802cb312018-06-08 18:05:20 -0400734 this->bindGeometry(indexBuffer, vertexBuffer, instanceBuffer);
Chris Dalton1d616352017-05-31 12:51:23 -0600735 cbInfo.currentCmdBuf()->drawIndexed(fGpu, indexCount, instanceCount,
736 baseIndex, baseVertex, baseInstance);
Chris Dalton114a3c02017-05-26 15:17:19 -0600737 fGpu->stats()->incNumDraws();
738}