blob: 15fdf4aa780e6e8f00791ab7292ed4931865c29c [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 Daniel77b53f62016-10-18 11:48:51 -0400124 cbInfo.fIsEmpty = true;
125 cbInfo.fStartsWithClear = false;
Greg Daniel36a77ee2016-10-18 10:33:25 -0400126
Greg Daniel22bc8652017-03-22 15:45:43 -0400127 cbInfo.fCommandBuffers.push_back(fGpu->resourceProvider().findOrCreateSecondaryCommandBuffer());
Robert Phillips19e51dc2017-08-09 09:30:51 -0400128 cbInfo.currentCmdBuf()->begin(fGpu, vkRT->framebuffer(), cbInfo.fRenderPass);
egdaniel066df7c2016-06-08 14:02:27 -0700129}
130
Brian Salomonc293a292016-11-30 13:38:32 -0500131
Greg Daniel500d58b2017-08-24 15:59:33 -0400132GrVkGpuRTCommandBuffer::~GrVkGpuRTCommandBuffer() {
Greg Daniel36a77ee2016-10-18 10:33:25 -0400133 for (int i = 0; i < fCommandBufferInfos.count(); ++i) {
134 CommandBufferInfo& cbInfo = fCommandBufferInfos[i];
Greg Daniel22bc8652017-03-22 15:45:43 -0400135 for (int j = 0; j < cbInfo.fCommandBuffers.count(); ++j) {
136 cbInfo.fCommandBuffers[j]->unref(fGpu);
137 }
Greg Daniel36a77ee2016-10-18 10:33:25 -0400138 cbInfo.fRenderPass->unref(fGpu);
139 }
egdaniel066df7c2016-06-08 14:02:27 -0700140}
141
Greg Daniel500d58b2017-08-24 15:59:33 -0400142GrGpu* GrVkGpuRTCommandBuffer::gpu() { return fGpu; }
egdaniel9cb63402016-06-23 08:37:05 -0700143
Greg Daniel500d58b2017-08-24 15:59:33 -0400144void GrVkGpuRTCommandBuffer::end() {
Greg Daniel22bc8652017-03-22 15:45:43 -0400145 if (fCurrentCmdInfo >= 0) {
146 fCommandBufferInfos[fCurrentCmdInfo].currentCmdBuf()->end(fGpu);
Brian Salomonc293a292016-11-30 13:38:32 -0500147 }
egdaniel066df7c2016-06-08 14:02:27 -0700148}
149
Greg Daniel500d58b2017-08-24 15:59:33 -0400150void GrVkGpuRTCommandBuffer::submit() {
Brian Salomonc293a292016-11-30 13:38:32 -0500151 if (!fRenderTarget) {
152 return;
153 }
Robert Phillips19e51dc2017-08-09 09:30:51 -0400154
155 GrVkRenderTarget* vkRT = static_cast<GrVkRenderTarget*>(fRenderTarget);
156
egdanielce3bfb12016-08-26 11:05:13 -0700157 // Change layout of our render target so it can be used as the color attachment. Currently
158 // we don't attach the resolve to the framebuffer so no need to change its layout.
Robert Phillips19e51dc2017-08-09 09:30:51 -0400159 GrVkImage* targetImage = vkRT->msaaImage() ? vkRT->msaaImage() : vkRT;
egdanielbc9b2962016-09-27 08:00:53 -0700160
161 // Change layout of our render target so it can be used as the color attachment
egdanielce3bfb12016-08-26 11:05:13 -0700162 targetImage->setImageLayout(fGpu,
163 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
164 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
egdanielbc9b2962016-09-27 08:00:53 -0700165 VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT,
egdanielce3bfb12016-08-26 11:05:13 -0700166 false);
egdaniel9cb63402016-06-23 08:37:05 -0700167
168 // If we are using a stencil attachment we also need to update its layout
169 if (GrStencilAttachment* stencil = fRenderTarget->renderTargetPriv().getStencilAttachment()) {
170 GrVkStencilAttachment* vkStencil = (GrVkStencilAttachment*)stencil;
171 vkStencil->setImageLayout(fGpu,
172 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
173 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT |
174 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT,
egdanielbc9b2962016-09-27 08:00:53 -0700175 VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT,
egdaniel9cb63402016-06-23 08:37:05 -0700176 false);
177 }
178
Greg Daniel36a77ee2016-10-18 10:33:25 -0400179 for (int i = 0; i < fCommandBufferInfos.count(); ++i) {
180 CommandBufferInfo& cbInfo = fCommandBufferInfos[i];
181
Greg Daniel77b53f62016-10-18 11:48:51 -0400182 for (int j = 0; j < cbInfo.fPreDrawUploads.count(); ++j) {
183 InlineUploadInfo& iuInfo = cbInfo.fPreDrawUploads[j];
184 iuInfo.fFlushState->doUpload(iuInfo.fUpload);
185 }
186
Greg Daniel500d58b2017-08-24 15:59:33 -0400187 for (int j = 0; j < cbInfo.fPreCopies.count(); ++j) {
188 CopyInfo& copyInfo = cbInfo.fPreCopies[j];
Robert Phillipsb0e93a22017-08-29 08:26:54 -0400189 fGpu->copySurface(fRenderTarget, fOrigin, copyInfo.fSrc, copyInfo.fSrcOrigin,
190 copyInfo.fSrcRect, copyInfo.fDstPoint);
Greg Daniel500d58b2017-08-24 15:59:33 -0400191 }
192
Greg Daniel77b53f62016-10-18 11:48:51 -0400193 // TODO: We can't add this optimization yet since many things create a scratch texture which
194 // adds the discard immediately, but then don't draw to it right away. This causes the
195 // discard to be ignored and we get yelled at for loading uninitialized data. However, once
Robert Phillips74c627f2017-08-09 10:28:00 -0400196 // MDB lands, the discard will get reordered with the rest of the draw commands and we can
Greg Daniel77b53f62016-10-18 11:48:51 -0400197 // re-enable this.
198#if 0
199 if (cbInfo.fIsEmpty && !cbInfo.fStartsWithClear) {
200 // We have sumbitted no actual draw commands to the command buffer and we are not using
201 // the render pass to do a clear so there is no need to submit anything.
202 continue;
203 }
204#endif
Greg Daniel36a77ee2016-10-18 10:33:25 -0400205 if (cbInfo.fBounds.intersect(0, 0,
206 SkIntToScalar(fRenderTarget->width()),
207 SkIntToScalar(fRenderTarget->height()))) {
208 SkIRect iBounds;
209 cbInfo.fBounds.roundOut(&iBounds);
210
Greg Daniel22bc8652017-03-22 15:45:43 -0400211 fGpu->submitSecondaryCommandBuffer(cbInfo.fCommandBuffers, cbInfo.fRenderPass,
Robert Phillipsb0e93a22017-08-29 08:26:54 -0400212 &cbInfo.fColorClearValue, vkRT, fOrigin, iBounds);
Greg Daniel36a77ee2016-10-18 10:33:25 -0400213 }
214 }
egdaniel9cb63402016-06-23 08:37:05 -0700215}
216
Greg Daniel500d58b2017-08-24 15:59:33 -0400217void GrVkGpuRTCommandBuffer::discard() {
Robert Phillips19e51dc2017-08-09 09:30:51 -0400218 GrVkRenderTarget* vkRT = static_cast<GrVkRenderTarget*>(fRenderTarget);
Brian Salomonc293a292016-11-30 13:38:32 -0500219
Greg Daniel22bc8652017-03-22 15:45:43 -0400220 CommandBufferInfo& cbInfo = fCommandBufferInfos[fCurrentCmdInfo];
Greg Daniel77b53f62016-10-18 11:48:51 -0400221 if (cbInfo.fIsEmpty) {
Robert Phillips74c627f2017-08-09 10:28:00 -0400222 // Change the render pass to do a don't-care load for both color & stencil
egdaniel37535c92016-06-30 08:23:30 -0700223 GrVkRenderPass::LoadStoreOps vkColorOps(VK_ATTACHMENT_LOAD_OP_DONT_CARE,
224 VK_ATTACHMENT_STORE_OP_STORE);
225 GrVkRenderPass::LoadStoreOps vkStencilOps(VK_ATTACHMENT_LOAD_OP_DONT_CARE,
226 VK_ATTACHMENT_STORE_OP_STORE);
egdaniel37535c92016-06-30 08:23:30 -0700227
Greg Daniel36a77ee2016-10-18 10:33:25 -0400228 const GrVkRenderPass* oldRP = cbInfo.fRenderPass;
egdaniel37535c92016-06-30 08:23:30 -0700229
egdaniel37535c92016-06-30 08:23:30 -0700230 const GrVkResourceProvider::CompatibleRPHandle& rpHandle =
Robert Phillips19e51dc2017-08-09 09:30:51 -0400231 vkRT->compatibleRenderPassHandle();
egdaniel37535c92016-06-30 08:23:30 -0700232 if (rpHandle.isValid()) {
Greg Daniel36a77ee2016-10-18 10:33:25 -0400233 cbInfo.fRenderPass = fGpu->resourceProvider().findRenderPass(rpHandle,
234 vkColorOps,
235 vkStencilOps);
egdaniel37535c92016-06-30 08:23:30 -0700236 } else {
Robert Phillips19e51dc2017-08-09 09:30:51 -0400237 cbInfo.fRenderPass = fGpu->resourceProvider().findRenderPass(*vkRT,
Greg Daniel36a77ee2016-10-18 10:33:25 -0400238 vkColorOps,
239 vkStencilOps);
egdaniel37535c92016-06-30 08:23:30 -0700240 }
241
Greg Daniel36a77ee2016-10-18 10:33:25 -0400242 SkASSERT(cbInfo.fRenderPass->isCompatible(*oldRP));
egdaniel37535c92016-06-30 08:23:30 -0700243 oldRP->unref(fGpu);
Greg Daniel5011f852016-10-28 15:07:16 -0400244 cbInfo.fBounds.join(fRenderTarget->getBoundsRect());
Greg Daniel77b53f62016-10-18 11:48:51 -0400245 cbInfo.fStartsWithClear = false;
egdaniel37535c92016-06-30 08:23:30 -0700246 }
247}
248
Greg Daniel500d58b2017-08-24 15:59:33 -0400249void GrVkGpuRTCommandBuffer::insertEventMarker(const char* msg) {
Robert Phillips65a88fa2017-08-08 08:36:22 -0400250 // TODO: does Vulkan have a correlate?
251}
252
Greg Daniel500d58b2017-08-24 15:59:33 -0400253void GrVkGpuRTCommandBuffer::onClearStencilClip(const GrFixedClip& clip, bool insideStencilMask) {
csmartdaltonbf4a8f92016-09-06 10:01:06 -0700254 SkASSERT(!clip.hasWindowRectangles());
egdaniel9cb63402016-06-23 08:37:05 -0700255
Greg Daniel22bc8652017-03-22 15:45:43 -0400256 CommandBufferInfo& cbInfo = fCommandBufferInfos[fCurrentCmdInfo];
Greg Daniel36a77ee2016-10-18 10:33:25 -0400257
Greg Daniel65a09272016-10-12 09:47:22 -0400258 GrStencilAttachment* sb = fRenderTarget->renderTargetPriv().getStencilAttachment();
egdaniel9cb63402016-06-23 08:37:05 -0700259 // this should only be called internally when we know we have a
260 // stencil buffer.
261 SkASSERT(sb);
262 int stencilBitCount = sb->bits();
263
264 // The contract with the callers does not guarantee that we preserve all bits in the stencil
265 // during this clear. Thus we will clear the entire stencil to the desired value.
266
267 VkClearDepthStencilValue vkStencilColor;
268 memset(&vkStencilColor, 0, sizeof(VkClearDepthStencilValue));
csmartdalton29df7602016-08-31 11:55:52 -0700269 if (insideStencilMask) {
egdaniel9cb63402016-06-23 08:37:05 -0700270 vkStencilColor.stencil = (1 << (stencilBitCount - 1));
271 } else {
272 vkStencilColor.stencil = 0;
273 }
274
275 VkClearRect clearRect;
276 // Flip rect if necessary
csmartdalton29df7602016-08-31 11:55:52 -0700277 SkIRect vkRect;
278 if (!clip.scissorEnabled()) {
Greg Daniel65a09272016-10-12 09:47:22 -0400279 vkRect.setXYWH(0, 0, fRenderTarget->width(), fRenderTarget->height());
Robert Phillips4f101a72017-07-28 08:42:04 -0400280 } else if (kBottomLeft_GrSurfaceOrigin != fOrigin) {
csmartdalton29df7602016-08-31 11:55:52 -0700281 vkRect = clip.scissorRect();
282 } else {
283 const SkIRect& scissor = clip.scissorRect();
Greg Daniel65a09272016-10-12 09:47:22 -0400284 vkRect.setLTRB(scissor.fLeft, fRenderTarget->height() - scissor.fBottom,
285 scissor.fRight, fRenderTarget->height() - scissor.fTop);
egdaniel9cb63402016-06-23 08:37:05 -0700286 }
287
288 clearRect.rect.offset = { vkRect.fLeft, vkRect.fTop };
289 clearRect.rect.extent = { (uint32_t)vkRect.width(), (uint32_t)vkRect.height() };
290
291 clearRect.baseArrayLayer = 0;
292 clearRect.layerCount = 1;
293
294 uint32_t stencilIndex;
Greg Daniel36a77ee2016-10-18 10:33:25 -0400295 SkAssertResult(cbInfo.fRenderPass->stencilAttachmentIndex(&stencilIndex));
egdaniel9cb63402016-06-23 08:37:05 -0700296
297 VkClearAttachment attachment;
298 attachment.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT;
299 attachment.colorAttachment = 0; // this value shouldn't matter
300 attachment.clearValue.depthStencil = vkStencilColor;
301
Greg Daniel22bc8652017-03-22 15:45:43 -0400302 cbInfo.currentCmdBuf()->clearAttachments(fGpu, 1, &attachment, 1, &clearRect);
Greg Daniel77b53f62016-10-18 11:48:51 -0400303 cbInfo.fIsEmpty = false;
Greg Daniel36a77ee2016-10-18 10:33:25 -0400304
305 // Update command buffer bounds
306 if (!clip.scissorEnabled()) {
307 cbInfo.fBounds.join(fRenderTarget->getBoundsRect());
308 } else {
309 cbInfo.fBounds.join(SkRect::Make(clip.scissorRect()));
310 }
egdaniel9cb63402016-06-23 08:37:05 -0700311}
312
Greg Daniel500d58b2017-08-24 15:59:33 -0400313void GrVkGpuRTCommandBuffer::onClear(const GrFixedClip& clip, GrColor color) {
Robert Phillips19e51dc2017-08-09 09:30:51 -0400314 GrVkRenderTarget* vkRT = static_cast<GrVkRenderTarget*>(fRenderTarget);
315
egdaniel9cb63402016-06-23 08:37:05 -0700316 // parent class should never let us get here with no RT
csmartdaltonbf4a8f92016-09-06 10:01:06 -0700317 SkASSERT(!clip.hasWindowRectangles());
egdaniel9cb63402016-06-23 08:37:05 -0700318
Greg Daniel22bc8652017-03-22 15:45:43 -0400319 CommandBufferInfo& cbInfo = fCommandBufferInfos[fCurrentCmdInfo];
Greg Daniel36a77ee2016-10-18 10:33:25 -0400320
egdaniel9cb63402016-06-23 08:37:05 -0700321 VkClearColorValue vkColor;
322 GrColorToRGBAFloat(color, vkColor.float32);
323
Greg Daniel77b53f62016-10-18 11:48:51 -0400324 if (cbInfo.fIsEmpty && !clip.scissorEnabled()) {
Robert Phillips74c627f2017-08-09 10:28:00 -0400325 // Change the render pass to do a clear load
egdaniel9cb63402016-06-23 08:37:05 -0700326 GrVkRenderPass::LoadStoreOps vkColorOps(VK_ATTACHMENT_LOAD_OP_CLEAR,
327 VK_ATTACHMENT_STORE_OP_STORE);
Robert Phillips74c627f2017-08-09 10:28:00 -0400328 // Preserve the stencil buffer's load & store settings
329 GrVkRenderPass::LoadStoreOps vkStencilOps(fVkStencilLoadOp, fVkStencilStoreOp);
egdaniel9cb63402016-06-23 08:37:05 -0700330
Greg Daniel36a77ee2016-10-18 10:33:25 -0400331 const GrVkRenderPass* oldRP = cbInfo.fRenderPass;
egdaniel9cb63402016-06-23 08:37:05 -0700332
333 const GrVkResourceProvider::CompatibleRPHandle& rpHandle =
Robert Phillips19e51dc2017-08-09 09:30:51 -0400334 vkRT->compatibleRenderPassHandle();
egdaniel9cb63402016-06-23 08:37:05 -0700335 if (rpHandle.isValid()) {
Greg Daniel36a77ee2016-10-18 10:33:25 -0400336 cbInfo.fRenderPass = fGpu->resourceProvider().findRenderPass(rpHandle,
337 vkColorOps,
338 vkStencilOps);
egdaniel9cb63402016-06-23 08:37:05 -0700339 } else {
Robert Phillips19e51dc2017-08-09 09:30:51 -0400340 cbInfo.fRenderPass = fGpu->resourceProvider().findRenderPass(*vkRT,
Greg Daniel36a77ee2016-10-18 10:33:25 -0400341 vkColorOps,
342 vkStencilOps);
egdaniel9cb63402016-06-23 08:37:05 -0700343 }
344
Greg Daniel36a77ee2016-10-18 10:33:25 -0400345 SkASSERT(cbInfo.fRenderPass->isCompatible(*oldRP));
egdaniel9cb63402016-06-23 08:37:05 -0700346 oldRP->unref(fGpu);
347
Greg Daniel36a77ee2016-10-18 10:33:25 -0400348 GrColorToRGBAFloat(color, cbInfo.fColorClearValue.color.float32);
Greg Daniel77b53f62016-10-18 11:48:51 -0400349 cbInfo.fStartsWithClear = true;
Greg Daniel36a77ee2016-10-18 10:33:25 -0400350
351 // Update command buffer bounds
352 cbInfo.fBounds.join(fRenderTarget->getBoundsRect());
egdaniel9cb63402016-06-23 08:37:05 -0700353 return;
354 }
355
356 // We always do a sub rect clear with clearAttachments since we are inside a render pass
357 VkClearRect clearRect;
358 // Flip rect if necessary
csmartdalton29df7602016-08-31 11:55:52 -0700359 SkIRect vkRect;
360 if (!clip.scissorEnabled()) {
Greg Daniel65a09272016-10-12 09:47:22 -0400361 vkRect.setXYWH(0, 0, fRenderTarget->width(), fRenderTarget->height());
Robert Phillips4f101a72017-07-28 08:42:04 -0400362 } else if (kBottomLeft_GrSurfaceOrigin != fOrigin) {
csmartdalton29df7602016-08-31 11:55:52 -0700363 vkRect = clip.scissorRect();
364 } else {
365 const SkIRect& scissor = clip.scissorRect();
Greg Daniel65a09272016-10-12 09:47:22 -0400366 vkRect.setLTRB(scissor.fLeft, fRenderTarget->height() - scissor.fBottom,
367 scissor.fRight, fRenderTarget->height() - scissor.fTop);
egdaniel9cb63402016-06-23 08:37:05 -0700368 }
369 clearRect.rect.offset = { vkRect.fLeft, vkRect.fTop };
370 clearRect.rect.extent = { (uint32_t)vkRect.width(), (uint32_t)vkRect.height() };
371 clearRect.baseArrayLayer = 0;
372 clearRect.layerCount = 1;
373
374 uint32_t colorIndex;
Greg Daniel36a77ee2016-10-18 10:33:25 -0400375 SkAssertResult(cbInfo.fRenderPass->colorAttachmentIndex(&colorIndex));
egdaniel9cb63402016-06-23 08:37:05 -0700376
377 VkClearAttachment attachment;
378 attachment.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
379 attachment.colorAttachment = colorIndex;
380 attachment.clearValue.color = vkColor;
381
Greg Daniel22bc8652017-03-22 15:45:43 -0400382 cbInfo.currentCmdBuf()->clearAttachments(fGpu, 1, &attachment, 1, &clearRect);
Greg Daniel77b53f62016-10-18 11:48:51 -0400383 cbInfo.fIsEmpty = false;
Greg Daniel36a77ee2016-10-18 10:33:25 -0400384
385 // Update command buffer bounds
386 if (!clip.scissorEnabled()) {
387 cbInfo.fBounds.join(fRenderTarget->getBoundsRect());
388 } else {
389 cbInfo.fBounds.join(SkRect::Make(clip.scissorRect()));
390 }
egdaniel9cb63402016-06-23 08:37:05 -0700391 return;
392}
393
Greg Daniel500d58b2017-08-24 15:59:33 -0400394////////////////////////////////////////////////////////////////////////////////
395
396void GrVkGpuRTCommandBuffer::addAdditionalCommandBuffer() {
Robert Phillips19e51dc2017-08-09 09:30:51 -0400397 GrVkRenderTarget* vkRT = static_cast<GrVkRenderTarget*>(fRenderTarget);
398
Greg Daniel22bc8652017-03-22 15:45:43 -0400399 CommandBufferInfo& cbInfo = fCommandBufferInfos[fCurrentCmdInfo];
400 cbInfo.currentCmdBuf()->end(fGpu);
401 cbInfo.fCommandBuffers.push_back(fGpu->resourceProvider().findOrCreateSecondaryCommandBuffer());
Robert Phillips19e51dc2017-08-09 09:30:51 -0400402 cbInfo.currentCmdBuf()->begin(fGpu, vkRT->framebuffer(), cbInfo.fRenderPass);
Greg Daniel22bc8652017-03-22 15:45:43 -0400403}
404
Greg Daniel500d58b2017-08-24 15:59:33 -0400405void GrVkGpuRTCommandBuffer::addAdditionalRenderPass() {
Robert Phillips19e51dc2017-08-09 09:30:51 -0400406 GrVkRenderTarget* vkRT = static_cast<GrVkRenderTarget*>(fRenderTarget);
407
Greg Daniel22bc8652017-03-22 15:45:43 -0400408 fCommandBufferInfos[fCurrentCmdInfo].currentCmdBuf()->end(fGpu);
Greg Daniel77b53f62016-10-18 11:48:51 -0400409
410 CommandBufferInfo& cbInfo = fCommandBufferInfos.push_back();
Greg Daniel22bc8652017-03-22 15:45:43 -0400411 fCurrentCmdInfo++;
Greg Daniel77b53f62016-10-18 11:48:51 -0400412
413 GrVkRenderPass::LoadStoreOps vkColorOps(VK_ATTACHMENT_LOAD_OP_LOAD,
414 VK_ATTACHMENT_STORE_OP_STORE);
415 GrVkRenderPass::LoadStoreOps vkStencilOps(VK_ATTACHMENT_LOAD_OP_LOAD,
416 VK_ATTACHMENT_STORE_OP_STORE);
417
418 const GrVkResourceProvider::CompatibleRPHandle& rpHandle =
Robert Phillips19e51dc2017-08-09 09:30:51 -0400419 vkRT->compatibleRenderPassHandle();
Greg Daniel77b53f62016-10-18 11:48:51 -0400420 if (rpHandle.isValid()) {
421 cbInfo.fRenderPass = fGpu->resourceProvider().findRenderPass(rpHandle,
422 vkColorOps,
423 vkStencilOps);
424 } else {
Robert Phillips19e51dc2017-08-09 09:30:51 -0400425 cbInfo.fRenderPass = fGpu->resourceProvider().findRenderPass(*vkRT,
Greg Daniel77b53f62016-10-18 11:48:51 -0400426 vkColorOps,
427 vkStencilOps);
428 }
429
Greg Daniel22bc8652017-03-22 15:45:43 -0400430 cbInfo.fCommandBuffers.push_back(fGpu->resourceProvider().findOrCreateSecondaryCommandBuffer());
Greg Daniel77b53f62016-10-18 11:48:51 -0400431 // It shouldn't matter what we set the clear color to here since we will assume loading of the
432 // attachment.
433 memset(&cbInfo.fColorClearValue, 0, sizeof(VkClearValue));
434 cbInfo.fBounds.setEmpty();
435 cbInfo.fIsEmpty = true;
436 cbInfo.fStartsWithClear = false;
437
Robert Phillips19e51dc2017-08-09 09:30:51 -0400438 cbInfo.currentCmdBuf()->begin(fGpu, vkRT->framebuffer(), cbInfo.fRenderPass);
Greg Daniel77b53f62016-10-18 11:48:51 -0400439}
440
Greg Daniel500d58b2017-08-24 15:59:33 -0400441void GrVkGpuRTCommandBuffer::inlineUpload(GrOpFlushState* state, GrDrawOp::DeferredUploadFn& upload) {
Robert Phillips19e51dc2017-08-09 09:30:51 -0400442
Greg Daniel22bc8652017-03-22 15:45:43 -0400443 if (!fCommandBufferInfos[fCurrentCmdInfo].fIsEmpty) {
444 this->addAdditionalRenderPass();
Greg Daniel77b53f62016-10-18 11:48:51 -0400445 }
Greg Daniel22bc8652017-03-22 15:45:43 -0400446 fCommandBufferInfos[fCurrentCmdInfo].fPreDrawUploads.emplace_back(state, upload);
Greg Daniel77b53f62016-10-18 11:48:51 -0400447}
448
Robert Phillipsb0e93a22017-08-29 08:26:54 -0400449void GrVkGpuRTCommandBuffer::copy(GrSurface* src, GrSurfaceOrigin srcOrigin, const SkIRect& srcRect,
Greg Daniel500d58b2017-08-24 15:59:33 -0400450 const SkIPoint& dstPoint) {
451 if (!fCommandBufferInfos[fCurrentCmdInfo].fIsEmpty ||
452 fCommandBufferInfos[fCurrentCmdInfo].fStartsWithClear) {
453 this->addAdditionalRenderPass();
454 }
Robert Phillipsb0e93a22017-08-29 08:26:54 -0400455 fCommandBufferInfos[fCurrentCmdInfo].fPreCopies.emplace_back(src, srcOrigin, srcRect, dstPoint);
Greg Daniel500d58b2017-08-24 15:59:33 -0400456}
457
egdaniel9cb63402016-06-23 08:37:05 -0700458////////////////////////////////////////////////////////////////////////////////
459
Greg Daniel500d58b2017-08-24 15:59:33 -0400460void GrVkGpuRTCommandBuffer::bindGeometry(const GrPrimitiveProcessor& primProc,
461 const GrBuffer* indexBuffer,
462 const GrBuffer* vertexBuffer,
463 const GrBuffer* instanceBuffer) {
Chris Daltonff926502017-05-03 14:36:54 -0400464 GrVkSecondaryCommandBuffer* currCmdBuf = fCommandBufferInfos[fCurrentCmdInfo].currentCmdBuf();
egdaniel9cb63402016-06-23 08:37:05 -0700465 // There is no need to put any memory barriers to make sure host writes have finished here.
466 // When a command buffer is submitted to a queue, there is an implicit memory barrier that
467 // occurs for all host writes. Additionally, BufferMemoryBarriers are not allowed inside of
468 // an active RenderPass.
egdaniel9cb63402016-06-23 08:37:05 -0700469
Chris Dalton1d616352017-05-31 12:51:23 -0600470 // Here our vertex and instance inputs need to match the same 0-based bindings they were
471 // assigned in GrVkPipeline. That is, vertex first (if any) followed by instance.
472 uint32_t binding = 0;
473
474 if (primProc.hasVertexAttribs()) {
475 SkASSERT(vertexBuffer);
476 SkASSERT(!vertexBuffer->isCPUBacked());
477 SkASSERT(!vertexBuffer->isMapped());
478
479 currCmdBuf->bindInputBuffer(fGpu, binding++,
480 static_cast<const GrVkVertexBuffer*>(vertexBuffer));
481 }
482
483 if (primProc.hasInstanceAttribs()) {
484 SkASSERT(instanceBuffer);
485 SkASSERT(!instanceBuffer->isCPUBacked());
486 SkASSERT(!instanceBuffer->isMapped());
487
488 currCmdBuf->bindInputBuffer(fGpu, binding++,
489 static_cast<const GrVkVertexBuffer*>(instanceBuffer));
490 }
egdaniel9cb63402016-06-23 08:37:05 -0700491
Chris Daltonff926502017-05-03 14:36:54 -0400492 if (indexBuffer) {
493 SkASSERT(indexBuffer);
494 SkASSERT(!indexBuffer->isMapped());
495 SkASSERT(!indexBuffer->isCPUBacked());
egdaniel9cb63402016-06-23 08:37:05 -0700496
Chris Daltonff926502017-05-03 14:36:54 -0400497 currCmdBuf->bindIndexBuffer(fGpu, static_cast<const GrVkIndexBuffer*>(indexBuffer));
egdaniel9cb63402016-06-23 08:37:05 -0700498 }
499}
500
Greg Daniel500d58b2017-08-24 15:59:33 -0400501sk_sp<GrVkPipelineState> GrVkGpuRTCommandBuffer::prepareDrawState(
egdaniel9cb63402016-06-23 08:37:05 -0700502 const GrPipeline& pipeline,
503 const GrPrimitiveProcessor& primProc,
Chris Dalton46983b72017-06-06 12:27:16 -0600504 GrPrimitiveType primitiveType,
505 bool hasDynamicState) {
Greg Daniel22bc8652017-03-22 15:45:43 -0400506 CommandBufferInfo& cbInfo = fCommandBufferInfos[fCurrentCmdInfo];
507 SkASSERT(cbInfo.fRenderPass);
Greg Daniel36a77ee2016-10-18 10:33:25 -0400508
egdaniel9cb63402016-06-23 08:37:05 -0700509 sk_sp<GrVkPipelineState> pipelineState =
510 fGpu->resourceProvider().findOrCreateCompatiblePipelineState(pipeline,
511 primProc,
512 primitiveType,
Greg Daniel36a77ee2016-10-18 10:33:25 -0400513 *cbInfo.fRenderPass);
egdaniel9cb63402016-06-23 08:37:05 -0700514 if (!pipelineState) {
515 return pipelineState;
516 }
517
Greg Daniel22bc8652017-03-22 15:45:43 -0400518 if (!cbInfo.fIsEmpty &&
519 fLastPipelineState && fLastPipelineState != pipelineState.get() &&
Greg Daniele3cd6912017-05-17 11:15:55 -0400520 fGpu->vkCaps().newCBOnPipelineChange()) {
Greg Daniel22bc8652017-03-22 15:45:43 -0400521 this->addAdditionalCommandBuffer();
522 }
523 fLastPipelineState = pipelineState.get();
524
egdaniel9cb63402016-06-23 08:37:05 -0700525 pipelineState->setData(fGpu, primProc, pipeline);
526
Greg Daniel22bc8652017-03-22 15:45:43 -0400527 pipelineState->bind(fGpu, cbInfo.currentCmdBuf());
egdaniel9cb63402016-06-23 08:37:05 -0700528
Robert Phillips2890fbf2017-07-26 15:48:41 -0400529 GrRenderTarget* rt = pipeline.renderTarget();
Chris Dalton46983b72017-06-06 12:27:16 -0600530
531 if (!pipeline.getScissorState().enabled()) {
Robert Phillipsb0e93a22017-08-29 08:26:54 -0400532 GrVkPipeline::SetDynamicScissorRectState(fGpu, cbInfo.currentCmdBuf(),
533 rt, pipeline.proxy()->origin(),
Chris Dalton46983b72017-06-06 12:27:16 -0600534 SkIRect::MakeWH(rt->width(), rt->height()));
535 } else if (!hasDynamicState) {
Robert Phillipsb0e93a22017-08-29 08:26:54 -0400536 GrVkPipeline::SetDynamicScissorRectState(fGpu, cbInfo.currentCmdBuf(),
537 rt, pipeline.proxy()->origin(),
Chris Dalton46983b72017-06-06 12:27:16 -0600538 pipeline.getScissorState().rect());
539 }
540 GrVkPipeline::SetDynamicViewportState(fGpu, cbInfo.currentCmdBuf(), rt);
541 GrVkPipeline::SetDynamicBlendConstantState(fGpu, cbInfo.currentCmdBuf(), rt->config(),
542 pipeline.getXferProcessor());
egdaniel9cb63402016-06-23 08:37:05 -0700543
544 return pipelineState;
545}
546
Brian Salomon18dfa982017-04-03 16:57:43 -0400547static void set_texture_layout(GrVkTexture* vkTexture, GrVkGpu* gpu) {
548 // TODO: If we ever decide to create the secondary command buffers ahead of time before we
549 // are actually going to submit them, we will need to track the sampled images and delay
550 // adding the layout change/barrier until we are ready to submit.
551 vkTexture->setImageLayout(gpu,
552 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
553 VK_ACCESS_SHADER_READ_BIT,
554 VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT,
555 false);
556}
557
Brian Salomonab015ef2017-04-04 10:15:51 -0400558static void prepare_sampled_images(const GrResourceIOProcessor& processor, GrVkGpu* gpu) {
Brian Salomon0bbecb22016-11-17 11:38:22 -0500559 for (int i = 0; i < processor.numTextureSamplers(); ++i) {
Brian Salomonab015ef2017-04-04 10:15:51 -0400560 const GrResourceIOProcessor::TextureSampler& sampler = processor.textureSampler(i);
Robert Phillips9bee2e52017-05-29 12:37:20 -0400561 GrVkTexture* vkTexture = static_cast<GrVkTexture*>(sampler.peekTexture());
egdaniel66933552016-08-24 07:22:19 -0700562
egdaniel8d2141f2016-09-02 11:19:13 -0700563 // We may need to resolve the texture first if it is also a render target
564 GrVkRenderTarget* texRT = static_cast<GrVkRenderTarget*>(vkTexture->asRenderTarget());
565 if (texRT) {
Robert Phillipsb0e93a22017-08-29 08:26:54 -0400566 gpu->onResolveRenderTarget(texRT, sampler.proxy()->origin());
egdaniel8d2141f2016-09-02 11:19:13 -0700567 }
568
Brian Salomon514baff2016-11-17 15:17:07 -0500569 const GrSamplerParams& params = sampler.params();
egdaniel8d2141f2016-09-02 11:19:13 -0700570 // Check if we need to regenerate any mip maps
Brian Salomon514baff2016-11-17 15:17:07 -0500571 if (GrSamplerParams::kMipMap_FilterMode == params.filterMode()) {
egdaniel8d2141f2016-09-02 11:19:13 -0700572 if (vkTexture->texturePriv().mipMapsAreDirty()) {
Robert Phillipsb0e93a22017-08-29 08:26:54 -0400573 gpu->generateMipmap(vkTexture, sampler.proxy()->origin());
egdaniel8d2141f2016-09-02 11:19:13 -0700574 vkTexture->texturePriv().dirtyMipMaps(false);
egdaniel66933552016-08-24 07:22:19 -0700575 }
egdaniel8d2141f2016-09-02 11:19:13 -0700576 }
Brian Salomon18dfa982017-04-03 16:57:43 -0400577 set_texture_layout(vkTexture, gpu);
egdaniel9cb63402016-06-23 08:37:05 -0700578 }
579}
580
Greg Daniel500d58b2017-08-24 15:59:33 -0400581void GrVkGpuRTCommandBuffer::onDraw(const GrPipeline& pipeline,
582 const GrPrimitiveProcessor& primProc,
583 const GrMesh meshes[],
584 const GrPipeline::DynamicState dynamicStates[],
585 int meshCount,
586 const SkRect& bounds) {
Robert Phillips19e51dc2017-08-09 09:30:51 -0400587 SkASSERT(pipeline.renderTarget() == fRenderTarget);
Brian Salomonc293a292016-11-30 13:38:32 -0500588
egdaniel9cb63402016-06-23 08:37:05 -0700589 if (!meshCount) {
590 return;
591 }
egdaniel8d2141f2016-09-02 11:19:13 -0700592 prepare_sampled_images(primProc, fGpu);
bsalomonb58a2b42016-09-26 06:55:02 -0700593 GrFragmentProcessor::Iter iter(pipeline);
594 while (const GrFragmentProcessor* fp = iter.next()) {
595 prepare_sampled_images(*fp, fGpu);
egdaniel2f5792a2016-07-06 08:51:23 -0700596 }
Robert Phillipsbb581ce2017-05-29 15:05:15 -0400597 if (GrTexture* dstTexture = pipeline.peekDstTexture()) {
598 set_texture_layout(static_cast<GrVkTexture*>(dstTexture), fGpu);
Brian Salomon18dfa982017-04-03 16:57:43 -0400599 }
egdaniel2f5792a2016-07-06 08:51:23 -0700600
Chris Daltonbca46e22017-05-15 11:03:26 -0600601 GrPrimitiveType primitiveType = meshes[0].primitiveType();
egdaniel9cb63402016-06-23 08:37:05 -0700602 sk_sp<GrVkPipelineState> pipelineState = this->prepareDrawState(pipeline,
603 primProc,
Chris Dalton46983b72017-06-06 12:27:16 -0600604 primitiveType,
605 SkToBool(dynamicStates));
egdaniel9cb63402016-06-23 08:37:05 -0700606 if (!pipelineState) {
607 return;
608 }
609
Chris Dalton46983b72017-06-06 12:27:16 -0600610 CommandBufferInfo& cbInfo = fCommandBufferInfos[fCurrentCmdInfo];
611
egdaniel9cb63402016-06-23 08:37:05 -0700612 for (int i = 0; i < meshCount; ++i) {
613 const GrMesh& mesh = meshes[i];
Chris Daltonbca46e22017-05-15 11:03:26 -0600614 if (mesh.primitiveType() != primitiveType) {
Chris Dalton6f241802017-05-08 13:58:38 -0400615 // Technically we don't have to call this here (since there is a safety check in
616 // pipelineState:setData but this will allow for quicker freeing of resources if the
617 // pipelineState sits in a cache for a while.
618 pipelineState->freeTempResources(fGpu);
619 SkDEBUGCODE(pipelineState = nullptr);
Chris Daltonbca46e22017-05-15 11:03:26 -0600620 primitiveType = mesh.primitiveType();
Chris Dalton6f241802017-05-08 13:58:38 -0400621 pipelineState = this->prepareDrawState(pipeline,
622 primProc,
Chris Dalton46983b72017-06-06 12:27:16 -0600623 primitiveType,
624 SkToBool(dynamicStates));
Chris Dalton6f241802017-05-08 13:58:38 -0400625 if (!pipelineState) {
626 return;
egdaniel9cb63402016-06-23 08:37:05 -0700627 }
Chris Dalton6f241802017-05-08 13:58:38 -0400628 }
egdaniel9cb63402016-06-23 08:37:05 -0700629
Chris Dalton46983b72017-06-06 12:27:16 -0600630 if (dynamicStates) {
631 if (pipeline.getScissorState().enabled()) {
632 GrVkPipeline::SetDynamicScissorRectState(fGpu, cbInfo.currentCmdBuf(),
Robert Phillipsb0e93a22017-08-29 08:26:54 -0400633 fRenderTarget, pipeline.proxy()->origin(),
Robert Phillips19e51dc2017-08-09 09:30:51 -0400634 dynamicStates[i].fScissorRect);
Chris Dalton46983b72017-06-06 12:27:16 -0600635 }
636 }
637
Chris Daltonbca46e22017-05-15 11:03:26 -0600638 SkASSERT(pipelineState);
Chris Dalton114a3c02017-05-26 15:17:19 -0600639 mesh.sendToGpu(primProc, this);
egdaniel9cb63402016-06-23 08:37:05 -0700640 }
641
Greg Daniel36a77ee2016-10-18 10:33:25 -0400642 cbInfo.fBounds.join(bounds);
Chris Dalton114a3c02017-05-26 15:17:19 -0600643 cbInfo.fIsEmpty = false;
Greg Daniel36a77ee2016-10-18 10:33:25 -0400644
egdaniel9cb63402016-06-23 08:37:05 -0700645 // Technically we don't have to call this here (since there is a safety check in
646 // pipelineState:setData but this will allow for quicker freeing of resources if the
647 // pipelineState sits in a cache for a while.
648 pipelineState->freeTempResources(fGpu);
egdaniel066df7c2016-06-08 14:02:27 -0700649}
650
Greg Daniel500d58b2017-08-24 15:59:33 -0400651void GrVkGpuRTCommandBuffer::sendInstancedMeshToGpu(const GrPrimitiveProcessor& primProc,
652 GrPrimitiveType,
653 const GrBuffer* vertexBuffer,
654 int vertexCount,
655 int baseVertex,
656 const GrBuffer* instanceBuffer,
657 int instanceCount,
658 int baseInstance) {
Chris Dalton114a3c02017-05-26 15:17:19 -0600659 CommandBufferInfo& cbInfo = fCommandBufferInfos[fCurrentCmdInfo];
Chris Dalton1d616352017-05-31 12:51:23 -0600660 this->bindGeometry(primProc, nullptr, vertexBuffer, instanceBuffer);
661 cbInfo.currentCmdBuf()->draw(fGpu, vertexCount, instanceCount, baseVertex, baseInstance);
Chris Dalton114a3c02017-05-26 15:17:19 -0600662 fGpu->stats()->incNumDraws();
663}
664
Greg Daniel500d58b2017-08-24 15:59:33 -0400665void GrVkGpuRTCommandBuffer::sendIndexedInstancedMeshToGpu(const GrPrimitiveProcessor& primProc,
666 GrPrimitiveType,
667 const GrBuffer* indexBuffer,
668 int indexCount,
669 int baseIndex,
670 const GrBuffer* vertexBuffer,
671 int baseVertex,
672 const GrBuffer* instanceBuffer,
673 int instanceCount,
674 int baseInstance) {
Chris Dalton114a3c02017-05-26 15:17:19 -0600675 CommandBufferInfo& cbInfo = fCommandBufferInfos[fCurrentCmdInfo];
Chris Dalton1d616352017-05-31 12:51:23 -0600676 this->bindGeometry(primProc, indexBuffer, vertexBuffer, instanceBuffer);
677 cbInfo.currentCmdBuf()->drawIndexed(fGpu, indexCount, instanceCount,
678 baseIndex, baseVertex, baseInstance);
Chris Dalton114a3c02017-05-26 15:17:19 -0600679 fGpu->stats()->incNumDraws();
680}
681