1066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel/*
2066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel* Copyright 2016 Google Inc.
3066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel*
4066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel* Use of this source code is governed by a BSD-style license that can be
5066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel* found in the LICENSE file.
6066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel*/
7066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel
8066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel#include "GrVkGpuCommandBuffer.h"
9066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel
1029df76096fd30941086324902a82656df2d8becdcsmartdalton#include "GrFixedClip.h"
119cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel#include "GrMesh.h"
12742e31de1599f3902810aecdf2e2e3eed3b40a09Brian Salomon#include "GrOpFlushState.h"
139cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel#include "GrPipeline.h"
149cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel#include "GrRenderTargetPriv.h"
159cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel#include "GrTexturePriv.h"
16066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel#include "GrVkCommandBuffer.h"
17066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel#include "GrVkGpu.h"
189cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel#include "GrVkPipeline.h"
19066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel#include "GrVkRenderPass.h"
20066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel#include "GrVkRenderTarget.h"
21066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel#include "GrVkResourceProvider.h"
229cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel#include "GrVkTexture.h"
2336a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel#include "SkRect.h"
24066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel
259cb6340a62a5d748e4189d50e51fa527c8c80c03egdanielvoid get_vk_load_store_ops(const GrGpuCommandBuffer::LoadAndStoreInfo& info,
26066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel                           VkAttachmentLoadOp* loadOp, VkAttachmentStoreOp* storeOp) {
279cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    switch (info.fLoadOp) {
289cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel        case GrGpuCommandBuffer::LoadOp::kLoad:
29066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel            *loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
30066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel            break;
319cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel        case GrGpuCommandBuffer::LoadOp::kClear:
32066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel            *loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
33066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel            break;
349cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel        case GrGpuCommandBuffer::LoadOp::kDiscard:
35066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel            *loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
369cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel            break;
379cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel        default:
389cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel            SK_ABORT("Invalid LoadOp");
399cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel            *loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
409cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    }
419cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
429cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    switch (info.fStoreOp) {
439cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel        case GrGpuCommandBuffer::StoreOp::kStore:
44066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel            *storeOp = VK_ATTACHMENT_STORE_OP_STORE;
45066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel            break;
469cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel        case GrGpuCommandBuffer::StoreOp::kDiscard:
47066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel            *storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
48066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel            break;
490bbc3713de2f51c17fad935ccfd87dd68c7062efbrianosman        default:
509cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel            SK_ABORT("Invalid StoreOp");
510bbc3713de2f51c17fad935ccfd87dd68c7062efbrianosman            *storeOp = VK_ATTACHMENT_STORE_OP_STORE;
52066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel    }
53066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel}
54066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel
55066df7ca911b65d416783f3bec6f4f1662948ad5egdanielGrVkGpuCommandBuffer::GrVkGpuCommandBuffer(GrVkGpu* gpu,
569cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                                           const LoadAndStoreInfo& colorInfo,
579cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                                           const LoadAndStoreInfo& stencilInfo)
589cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    : fGpu(gpu)
59c293a29bc2fced15ac44a66efa813d42cb3f2e0bBrian Salomon    , fRenderTarget(nullptr)
6022bc8653d704584e13f35844dafb5ddeb9989127Greg Daniel    , fClearColor(GrColor4f::FromGrColor(colorInfo.fClearColor))
6122bc8653d704584e13f35844dafb5ddeb9989127Greg Daniel    , fLastPipelineState(nullptr) {
62066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel
63c293a29bc2fced15ac44a66efa813d42cb3f2e0bBrian Salomon    get_vk_load_store_ops(colorInfo, &fVkColorLoadOp, &fVkColorStoreOp);
64066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel
65c293a29bc2fced15ac44a66efa813d42cb3f2e0bBrian Salomon    get_vk_load_store_ops(stencilInfo, &fVkStencilLoadOp, &fVkStencilStoreOp);
66c293a29bc2fced15ac44a66efa813d42cb3f2e0bBrian Salomon
6722bc8653d704584e13f35844dafb5ddeb9989127Greg Daniel    fCurrentCmdInfo = -1;
68c293a29bc2fced15ac44a66efa813d42cb3f2e0bBrian Salomon}
69c293a29bc2fced15ac44a66efa813d42cb3f2e0bBrian Salomon
70c293a29bc2fced15ac44a66efa813d42cb3f2e0bBrian Salomonvoid GrVkGpuCommandBuffer::init(GrVkRenderTarget* target) {
71c293a29bc2fced15ac44a66efa813d42cb3f2e0bBrian Salomon    SkASSERT(!fRenderTarget);
72c293a29bc2fced15ac44a66efa813d42cb3f2e0bBrian Salomon    fRenderTarget = target;
73c293a29bc2fced15ac44a66efa813d42cb3f2e0bBrian Salomon
74c293a29bc2fced15ac44a66efa813d42cb3f2e0bBrian Salomon    GrVkRenderPass::LoadStoreOps vkColorOps(fVkColorLoadOp, fVkColorStoreOp);
75c293a29bc2fced15ac44a66efa813d42cb3f2e0bBrian Salomon    GrVkRenderPass::LoadStoreOps vkStencilOps(fVkStencilLoadOp, fVkStencilStoreOp);
769cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
7736a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel    CommandBufferInfo& cbInfo = fCommandBufferInfos.push_back();
78c293a29bc2fced15ac44a66efa813d42cb3f2e0bBrian Salomon    SkASSERT(fCommandBufferInfos.count() == 1);
7922bc8653d704584e13f35844dafb5ddeb9989127Greg Daniel    fCurrentCmdInfo = 0;
8036a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel
819cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    const GrVkResourceProvider::CompatibleRPHandle& rpHandle = target->compatibleRenderPassHandle();
82066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel    if (rpHandle.isValid()) {
8336a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel        cbInfo.fRenderPass = fGpu->resourceProvider().findRenderPass(rpHandle,
8436a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel                                                                     vkColorOps,
8536a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel                                                                     vkStencilOps);
86066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel    } else {
8736a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel        cbInfo.fRenderPass = fGpu->resourceProvider().findRenderPass(*target,
8836a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel                                                                     vkColorOps,
8936a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel                                                                     vkStencilOps);
90066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel    }
91066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel
92c293a29bc2fced15ac44a66efa813d42cb3f2e0bBrian Salomon    cbInfo.fColorClearValue.color.float32[0] = fClearColor.fRGBA[0];
93c293a29bc2fced15ac44a66efa813d42cb3f2e0bBrian Salomon    cbInfo.fColorClearValue.color.float32[1] = fClearColor.fRGBA[1];
94c293a29bc2fced15ac44a66efa813d42cb3f2e0bBrian Salomon    cbInfo.fColorClearValue.color.float32[2] = fClearColor.fRGBA[2];
95c293a29bc2fced15ac44a66efa813d42cb3f2e0bBrian Salomon    cbInfo.fColorClearValue.color.float32[3] = fClearColor.fRGBA[3];
9636a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel
9736a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel    cbInfo.fBounds.setEmpty();
9877b53f66bacd9a1d1c9df7d879a419b2abe069baGreg Daniel    cbInfo.fIsEmpty = true;
9977b53f66bacd9a1d1c9df7d879a419b2abe069baGreg Daniel    cbInfo.fStartsWithClear = false;
1009cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
10122bc8653d704584e13f35844dafb5ddeb9989127Greg Daniel    cbInfo.fCommandBuffers.push_back(fGpu->resourceProvider().findOrCreateSecondaryCommandBuffer());
10222bc8653d704584e13f35844dafb5ddeb9989127Greg Daniel    cbInfo.currentCmdBuf()->begin(fGpu, target->framebuffer(), cbInfo.fRenderPass);
103066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel}
104066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel
105c293a29bc2fced15ac44a66efa813d42cb3f2e0bBrian Salomon
106066df7ca911b65d416783f3bec6f4f1662948ad5egdanielGrVkGpuCommandBuffer::~GrVkGpuCommandBuffer() {
10736a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel    for (int i = 0; i < fCommandBufferInfos.count(); ++i) {
10836a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel        CommandBufferInfo& cbInfo = fCommandBufferInfos[i];
10922bc8653d704584e13f35844dafb5ddeb9989127Greg Daniel        for (int j = 0; j < cbInfo.fCommandBuffers.count(); ++j) {
11022bc8653d704584e13f35844dafb5ddeb9989127Greg Daniel            cbInfo.fCommandBuffers[j]->unref(fGpu);
11122bc8653d704584e13f35844dafb5ddeb9989127Greg Daniel        }
11236a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel        cbInfo.fRenderPass->unref(fGpu);
11336a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel    }
114066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel}
115066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel
1169cb6340a62a5d748e4189d50e51fa527c8c80c03egdanielGrGpu* GrVkGpuCommandBuffer::gpu() { return fGpu; }
11765a09274184ffd25d446352a96d3890ea7e625faGreg DanielGrRenderTarget* GrVkGpuCommandBuffer::renderTarget() { return fRenderTarget; }
1189cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
119066df7ca911b65d416783f3bec6f4f1662948ad5egdanielvoid GrVkGpuCommandBuffer::end() {
12022bc8653d704584e13f35844dafb5ddeb9989127Greg Daniel    if (fCurrentCmdInfo >= 0) {
12122bc8653d704584e13f35844dafb5ddeb9989127Greg Daniel        fCommandBufferInfos[fCurrentCmdInfo].currentCmdBuf()->end(fGpu);
122c293a29bc2fced15ac44a66efa813d42cb3f2e0bBrian Salomon    }
123066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel}
124066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel
12536a77ee494791989548b717515e3621b9c4ffe4eGreg Danielvoid GrVkGpuCommandBuffer::onSubmit() {
126c293a29bc2fced15ac44a66efa813d42cb3f2e0bBrian Salomon    if (!fRenderTarget) {
127c293a29bc2fced15ac44a66efa813d42cb3f2e0bBrian Salomon        return;
128c293a29bc2fced15ac44a66efa813d42cb3f2e0bBrian Salomon    }
129ce3bfb1ed155880585b2d0bb0a8d3e43306e23f2egdaniel    // Change layout of our render target so it can be used as the color attachment. Currently
130ce3bfb1ed155880585b2d0bb0a8d3e43306e23f2egdaniel    // we don't attach the resolve to the framebuffer so no need to change its layout.
1318d2141f0dbb36b92d0e3feb23a08663c29b59db0egdaniel    GrVkImage* targetImage = fRenderTarget->msaaImage() ? fRenderTarget->msaaImage()
132ce3bfb1ed155880585b2d0bb0a8d3e43306e23f2egdaniel                                                        : fRenderTarget;
133bc9b2963bf9e39c47ae5c3ab94b8503b476f4f0eegdaniel
134bc9b2963bf9e39c47ae5c3ab94b8503b476f4f0eegdaniel    // Change layout of our render target so it can be used as the color attachment
135ce3bfb1ed155880585b2d0bb0a8d3e43306e23f2egdaniel    targetImage->setImageLayout(fGpu,
136ce3bfb1ed155880585b2d0bb0a8d3e43306e23f2egdaniel                                VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
137ce3bfb1ed155880585b2d0bb0a8d3e43306e23f2egdaniel                                VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
138bc9b2963bf9e39c47ae5c3ab94b8503b476f4f0eegdaniel                                VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT,
139ce3bfb1ed155880585b2d0bb0a8d3e43306e23f2egdaniel                                false);
1409cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
1419cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    // If we are using a stencil attachment we also need to update its layout
1429cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    if (GrStencilAttachment* stencil = fRenderTarget->renderTargetPriv().getStencilAttachment()) {
1439cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel        GrVkStencilAttachment* vkStencil = (GrVkStencilAttachment*)stencil;
1449cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel        vkStencil->setImageLayout(fGpu,
1459cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                                  VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
1469cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                                  VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT |
1479cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                                  VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT,
148bc9b2963bf9e39c47ae5c3ab94b8503b476f4f0eegdaniel                                  VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT,
1499cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                                  false);
1509cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    }
1519cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
15236a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel    for (int i = 0; i < fCommandBufferInfos.count(); ++i) {
15336a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel        CommandBufferInfo& cbInfo = fCommandBufferInfos[i];
15436a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel
15577b53f66bacd9a1d1c9df7d879a419b2abe069baGreg Daniel        for (int j = 0; j < cbInfo.fPreDrawUploads.count(); ++j) {
15677b53f66bacd9a1d1c9df7d879a419b2abe069baGreg Daniel            InlineUploadInfo& iuInfo = cbInfo.fPreDrawUploads[j];
15777b53f66bacd9a1d1c9df7d879a419b2abe069baGreg Daniel            iuInfo.fFlushState->doUpload(iuInfo.fUpload);
15877b53f66bacd9a1d1c9df7d879a419b2abe069baGreg Daniel        }
15977b53f66bacd9a1d1c9df7d879a419b2abe069baGreg Daniel
16077b53f66bacd9a1d1c9df7d879a419b2abe069baGreg Daniel        // TODO: We can't add this optimization yet since many things create a scratch texture which
16177b53f66bacd9a1d1c9df7d879a419b2abe069baGreg Daniel        // adds the discard immediately, but then don't draw to it right away. This causes the
16277b53f66bacd9a1d1c9df7d879a419b2abe069baGreg Daniel        // discard to be ignored and we get yelled at for loading uninitialized data. However, once
16377b53f66bacd9a1d1c9df7d879a419b2abe069baGreg Daniel        // MDP lands, the discard will get reordered with the rest of the draw commands and we can
16477b53f66bacd9a1d1c9df7d879a419b2abe069baGreg Daniel        // re-enable this.
16577b53f66bacd9a1d1c9df7d879a419b2abe069baGreg Daniel#if 0
16677b53f66bacd9a1d1c9df7d879a419b2abe069baGreg Daniel        if (cbInfo.fIsEmpty && !cbInfo.fStartsWithClear) {
16777b53f66bacd9a1d1c9df7d879a419b2abe069baGreg Daniel            // We have sumbitted no actual draw commands to the command buffer and we are not using
16877b53f66bacd9a1d1c9df7d879a419b2abe069baGreg Daniel            // the render pass to do a clear so there is no need to submit anything.
16977b53f66bacd9a1d1c9df7d879a419b2abe069baGreg Daniel            continue;
17077b53f66bacd9a1d1c9df7d879a419b2abe069baGreg Daniel        }
17177b53f66bacd9a1d1c9df7d879a419b2abe069baGreg Daniel#endif
17236a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel        if (cbInfo.fBounds.intersect(0, 0,
17336a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel                                     SkIntToScalar(fRenderTarget->width()),
17436a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel                                     SkIntToScalar(fRenderTarget->height()))) {
17536a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel            SkIRect iBounds;
17636a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel            cbInfo.fBounds.roundOut(&iBounds);
17736a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel
17822bc8653d704584e13f35844dafb5ddeb9989127Greg Daniel            fGpu->submitSecondaryCommandBuffer(cbInfo.fCommandBuffers, cbInfo.fRenderPass,
17936a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel                                               &cbInfo.fColorClearValue, fRenderTarget, iBounds);
18036a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel        }
18136a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel    }
1829cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel}
1839cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
184c293a29bc2fced15ac44a66efa813d42cb3f2e0bBrian Salomonvoid GrVkGpuCommandBuffer::discard(GrRenderTarget* rt) {
185c293a29bc2fced15ac44a66efa813d42cb3f2e0bBrian Salomon    GrVkRenderTarget* target = static_cast<GrVkRenderTarget*>(rt);
186c293a29bc2fced15ac44a66efa813d42cb3f2e0bBrian Salomon    if (!fRenderTarget) {
187c293a29bc2fced15ac44a66efa813d42cb3f2e0bBrian Salomon        this->init(target);
188c293a29bc2fced15ac44a66efa813d42cb3f2e0bBrian Salomon    }
189c293a29bc2fced15ac44a66efa813d42cb3f2e0bBrian Salomon    SkASSERT(target == fRenderTarget);
190c293a29bc2fced15ac44a66efa813d42cb3f2e0bBrian Salomon
19122bc8653d704584e13f35844dafb5ddeb9989127Greg Daniel    CommandBufferInfo& cbInfo = fCommandBufferInfos[fCurrentCmdInfo];
19277b53f66bacd9a1d1c9df7d879a419b2abe069baGreg Daniel    if (cbInfo.fIsEmpty) {
19337535c9ecef67a56cad293535f8626b1d60f7c08egdaniel        // We will change the render pass to do a clear load instead
19437535c9ecef67a56cad293535f8626b1d60f7c08egdaniel        GrVkRenderPass::LoadStoreOps vkColorOps(VK_ATTACHMENT_LOAD_OP_DONT_CARE,
19537535c9ecef67a56cad293535f8626b1d60f7c08egdaniel                                                VK_ATTACHMENT_STORE_OP_STORE);
19637535c9ecef67a56cad293535f8626b1d60f7c08egdaniel        GrVkRenderPass::LoadStoreOps vkStencilOps(VK_ATTACHMENT_LOAD_OP_DONT_CARE,
19737535c9ecef67a56cad293535f8626b1d60f7c08egdaniel                                                  VK_ATTACHMENT_STORE_OP_STORE);
19837535c9ecef67a56cad293535f8626b1d60f7c08egdaniel
19936a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel        const GrVkRenderPass* oldRP = cbInfo.fRenderPass;
20037535c9ecef67a56cad293535f8626b1d60f7c08egdaniel
20137535c9ecef67a56cad293535f8626b1d60f7c08egdaniel        const GrVkResourceProvider::CompatibleRPHandle& rpHandle =
20265a09274184ffd25d446352a96d3890ea7e625faGreg Daniel            fRenderTarget->compatibleRenderPassHandle();
20337535c9ecef67a56cad293535f8626b1d60f7c08egdaniel        if (rpHandle.isValid()) {
20436a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel            cbInfo.fRenderPass = fGpu->resourceProvider().findRenderPass(rpHandle,
20536a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel                                                                         vkColorOps,
20636a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel                                                                         vkStencilOps);
20737535c9ecef67a56cad293535f8626b1d60f7c08egdaniel        } else {
20836a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel            cbInfo.fRenderPass = fGpu->resourceProvider().findRenderPass(*fRenderTarget,
20936a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel                                                                         vkColorOps,
21036a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel                                                                         vkStencilOps);
21137535c9ecef67a56cad293535f8626b1d60f7c08egdaniel        }
21237535c9ecef67a56cad293535f8626b1d60f7c08egdaniel
21336a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel        SkASSERT(cbInfo.fRenderPass->isCompatible(*oldRP));
21437535c9ecef67a56cad293535f8626b1d60f7c08egdaniel        oldRP->unref(fGpu);
2155011f8547c6de936f20bc954d5fd131a52106f33Greg Daniel        cbInfo.fBounds.join(fRenderTarget->getBoundsRect());
21677b53f66bacd9a1d1c9df7d879a419b2abe069baGreg Daniel        cbInfo.fStartsWithClear = false;
21737535c9ecef67a56cad293535f8626b1d60f7c08egdaniel    }
21837535c9ecef67a56cad293535f8626b1d60f7c08egdaniel}
21937535c9ecef67a56cad293535f8626b1d60f7c08egdaniel
220c293a29bc2fced15ac44a66efa813d42cb3f2e0bBrian Salomonvoid GrVkGpuCommandBuffer::onClearStencilClip(GrRenderTarget* rt, const GrFixedClip& clip,
22129df76096fd30941086324902a82656df2d8becdcsmartdalton                                              bool insideStencilMask) {
222bf4a8f90c87dddf6290aa774536715e55e6a12f5csmartdalton    SkASSERT(!clip.hasWindowRectangles());
2239cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
224c293a29bc2fced15ac44a66efa813d42cb3f2e0bBrian Salomon    GrVkRenderTarget* target = static_cast<GrVkRenderTarget*>(rt);
225c293a29bc2fced15ac44a66efa813d42cb3f2e0bBrian Salomon    if (!fRenderTarget) {
226c293a29bc2fced15ac44a66efa813d42cb3f2e0bBrian Salomon        this->init(target);
227c293a29bc2fced15ac44a66efa813d42cb3f2e0bBrian Salomon    }
228c293a29bc2fced15ac44a66efa813d42cb3f2e0bBrian Salomon    SkASSERT(target == fRenderTarget);
229c293a29bc2fced15ac44a66efa813d42cb3f2e0bBrian Salomon
23022bc8653d704584e13f35844dafb5ddeb9989127Greg Daniel    CommandBufferInfo& cbInfo = fCommandBufferInfos[fCurrentCmdInfo];
23136a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel
23265a09274184ffd25d446352a96d3890ea7e625faGreg Daniel    GrStencilAttachment* sb = fRenderTarget->renderTargetPriv().getStencilAttachment();
2339cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    // this should only be called internally when we know we have a
2349cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    // stencil buffer.
2359cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    SkASSERT(sb);
2369cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    int stencilBitCount = sb->bits();
2379cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
2389cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    // The contract with the callers does not guarantee that we preserve all bits in the stencil
2399cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    // during this clear. Thus we will clear the entire stencil to the desired value.
2409cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
2419cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    VkClearDepthStencilValue vkStencilColor;
2429cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    memset(&vkStencilColor, 0, sizeof(VkClearDepthStencilValue));
24329df76096fd30941086324902a82656df2d8becdcsmartdalton    if (insideStencilMask) {
2449cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel        vkStencilColor.stencil = (1 << (stencilBitCount - 1));
2459cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    } else {
2469cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel        vkStencilColor.stencil = 0;
2479cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    }
2489cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
2499cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    VkClearRect clearRect;
2509cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    // Flip rect if necessary
25129df76096fd30941086324902a82656df2d8becdcsmartdalton    SkIRect vkRect;
25229df76096fd30941086324902a82656df2d8becdcsmartdalton    if (!clip.scissorEnabled()) {
25365a09274184ffd25d446352a96d3890ea7e625faGreg Daniel        vkRect.setXYWH(0, 0, fRenderTarget->width(), fRenderTarget->height());
25465a09274184ffd25d446352a96d3890ea7e625faGreg Daniel    } else if (kBottomLeft_GrSurfaceOrigin != fRenderTarget->origin()) {
25529df76096fd30941086324902a82656df2d8becdcsmartdalton        vkRect = clip.scissorRect();
25629df76096fd30941086324902a82656df2d8becdcsmartdalton    } else {
25729df76096fd30941086324902a82656df2d8becdcsmartdalton        const SkIRect& scissor = clip.scissorRect();
25865a09274184ffd25d446352a96d3890ea7e625faGreg Daniel        vkRect.setLTRB(scissor.fLeft, fRenderTarget->height() - scissor.fBottom,
25965a09274184ffd25d446352a96d3890ea7e625faGreg Daniel                       scissor.fRight, fRenderTarget->height() - scissor.fTop);
2609cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    }
2619cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
2629cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    clearRect.rect.offset = { vkRect.fLeft, vkRect.fTop };
2639cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    clearRect.rect.extent = { (uint32_t)vkRect.width(), (uint32_t)vkRect.height() };
2649cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
2659cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    clearRect.baseArrayLayer = 0;
2669cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    clearRect.layerCount = 1;
2679cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
2689cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    uint32_t stencilIndex;
26936a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel    SkAssertResult(cbInfo.fRenderPass->stencilAttachmentIndex(&stencilIndex));
2709cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
2719cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    VkClearAttachment attachment;
2729cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    attachment.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT;
2739cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    attachment.colorAttachment = 0; // this value shouldn't matter
2749cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    attachment.clearValue.depthStencil = vkStencilColor;
2759cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
27622bc8653d704584e13f35844dafb5ddeb9989127Greg Daniel    cbInfo.currentCmdBuf()->clearAttachments(fGpu, 1, &attachment, 1, &clearRect);
27777b53f66bacd9a1d1c9df7d879a419b2abe069baGreg Daniel    cbInfo.fIsEmpty = false;
27836a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel
27936a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel    // Update command buffer bounds
28036a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel    if (!clip.scissorEnabled()) {
28136a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel        cbInfo.fBounds.join(fRenderTarget->getBoundsRect());
28236a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel    } else {
28336a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel        cbInfo.fBounds.join(SkRect::Make(clip.scissorRect()));
28436a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel    }
2859cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel}
2869cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
287c293a29bc2fced15ac44a66efa813d42cb3f2e0bBrian Salomonvoid GrVkGpuCommandBuffer::onClear(GrRenderTarget* rt, const GrFixedClip& clip, GrColor color) {
2889cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    // parent class should never let us get here with no RT
289bf4a8f90c87dddf6290aa774536715e55e6a12f5csmartdalton    SkASSERT(!clip.hasWindowRectangles());
2909cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
291c293a29bc2fced15ac44a66efa813d42cb3f2e0bBrian Salomon    GrVkRenderTarget* target = static_cast<GrVkRenderTarget*>(rt);
292c293a29bc2fced15ac44a66efa813d42cb3f2e0bBrian Salomon    if (!fRenderTarget) {
293c293a29bc2fced15ac44a66efa813d42cb3f2e0bBrian Salomon        this->init(target);
294c293a29bc2fced15ac44a66efa813d42cb3f2e0bBrian Salomon    }
295c293a29bc2fced15ac44a66efa813d42cb3f2e0bBrian Salomon    SkASSERT(target == fRenderTarget);
296c293a29bc2fced15ac44a66efa813d42cb3f2e0bBrian Salomon
29722bc8653d704584e13f35844dafb5ddeb9989127Greg Daniel    CommandBufferInfo& cbInfo = fCommandBufferInfos[fCurrentCmdInfo];
29836a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel
2999cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    VkClearColorValue vkColor;
3009cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    GrColorToRGBAFloat(color, vkColor.float32);
3019cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
30277b53f66bacd9a1d1c9df7d879a419b2abe069baGreg Daniel    if (cbInfo.fIsEmpty && !clip.scissorEnabled()) {
3039cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel        // We will change the render pass to do a clear load instead
3049cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel        GrVkRenderPass::LoadStoreOps vkColorOps(VK_ATTACHMENT_LOAD_OP_CLEAR,
3059cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                                                VK_ATTACHMENT_STORE_OP_STORE);
3069cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel        GrVkRenderPass::LoadStoreOps vkStencilOps(VK_ATTACHMENT_LOAD_OP_LOAD,
3079cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                                                  VK_ATTACHMENT_STORE_OP_STORE);
3089cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
30936a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel        const GrVkRenderPass* oldRP = cbInfo.fRenderPass;
3109cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
3119cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel        const GrVkResourceProvider::CompatibleRPHandle& rpHandle =
31265a09274184ffd25d446352a96d3890ea7e625faGreg Daniel            fRenderTarget->compatibleRenderPassHandle();
3139cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel        if (rpHandle.isValid()) {
31436a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel            cbInfo.fRenderPass = fGpu->resourceProvider().findRenderPass(rpHandle,
31536a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel                                                                         vkColorOps,
31636a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel                                                                         vkStencilOps);
3179cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel        } else {
31836a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel            cbInfo.fRenderPass = fGpu->resourceProvider().findRenderPass(*fRenderTarget,
31936a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel                                                                         vkColorOps,
32036a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel                                                                         vkStencilOps);
3219cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel        }
3229cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
32336a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel        SkASSERT(cbInfo.fRenderPass->isCompatible(*oldRP));
3249cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel        oldRP->unref(fGpu);
3259cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
32636a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel        GrColorToRGBAFloat(color, cbInfo.fColorClearValue.color.float32);
32777b53f66bacd9a1d1c9df7d879a419b2abe069baGreg Daniel        cbInfo.fStartsWithClear = true;
32836a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel
32936a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel        // Update command buffer bounds
33036a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel        cbInfo.fBounds.join(fRenderTarget->getBoundsRect());
3319cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel        return;
3329cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    }
3339cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
3349cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    // We always do a sub rect clear with clearAttachments since we are inside a render pass
3359cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    VkClearRect clearRect;
3369cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    // Flip rect if necessary
33729df76096fd30941086324902a82656df2d8becdcsmartdalton    SkIRect vkRect;
33829df76096fd30941086324902a82656df2d8becdcsmartdalton    if (!clip.scissorEnabled()) {
33965a09274184ffd25d446352a96d3890ea7e625faGreg Daniel        vkRect.setXYWH(0, 0, fRenderTarget->width(), fRenderTarget->height());
34065a09274184ffd25d446352a96d3890ea7e625faGreg Daniel    } else if (kBottomLeft_GrSurfaceOrigin != fRenderTarget->origin()) {
34129df76096fd30941086324902a82656df2d8becdcsmartdalton        vkRect = clip.scissorRect();
34229df76096fd30941086324902a82656df2d8becdcsmartdalton    } else {
34329df76096fd30941086324902a82656df2d8becdcsmartdalton        const SkIRect& scissor = clip.scissorRect();
34465a09274184ffd25d446352a96d3890ea7e625faGreg Daniel        vkRect.setLTRB(scissor.fLeft, fRenderTarget->height() - scissor.fBottom,
34565a09274184ffd25d446352a96d3890ea7e625faGreg Daniel                       scissor.fRight, fRenderTarget->height() - scissor.fTop);
3469cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    }
3479cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    clearRect.rect.offset = { vkRect.fLeft, vkRect.fTop };
3489cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    clearRect.rect.extent = { (uint32_t)vkRect.width(), (uint32_t)vkRect.height() };
3499cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    clearRect.baseArrayLayer = 0;
3509cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    clearRect.layerCount = 1;
3519cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
3529cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    uint32_t colorIndex;
35336a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel    SkAssertResult(cbInfo.fRenderPass->colorAttachmentIndex(&colorIndex));
3549cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
3559cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    VkClearAttachment attachment;
3569cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    attachment.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3579cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    attachment.colorAttachment = colorIndex;
3589cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    attachment.clearValue.color = vkColor;
3599cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
36022bc8653d704584e13f35844dafb5ddeb9989127Greg Daniel    cbInfo.currentCmdBuf()->clearAttachments(fGpu, 1, &attachment, 1, &clearRect);
36177b53f66bacd9a1d1c9df7d879a419b2abe069baGreg Daniel    cbInfo.fIsEmpty = false;
36236a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel
36336a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel    // Update command buffer bounds
36436a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel    if (!clip.scissorEnabled()) {
36536a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel        cbInfo.fBounds.join(fRenderTarget->getBoundsRect());
36636a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel    } else {
36736a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel        cbInfo.fBounds.join(SkRect::Make(clip.scissorRect()));
36836a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel    }
3699cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    return;
3709cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel}
3719cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
37277b53f66bacd9a1d1c9df7d879a419b2abe069baGreg Danielvoid GrVkGpuCommandBuffer::addAdditionalCommandBuffer() {
37322bc8653d704584e13f35844dafb5ddeb9989127Greg Daniel    CommandBufferInfo& cbInfo = fCommandBufferInfos[fCurrentCmdInfo];
37422bc8653d704584e13f35844dafb5ddeb9989127Greg Daniel    cbInfo.currentCmdBuf()->end(fGpu);
37522bc8653d704584e13f35844dafb5ddeb9989127Greg Daniel    cbInfo.fCommandBuffers.push_back(fGpu->resourceProvider().findOrCreateSecondaryCommandBuffer());
37622bc8653d704584e13f35844dafb5ddeb9989127Greg Daniel    cbInfo.currentCmdBuf()->begin(fGpu, fRenderTarget->framebuffer(), cbInfo.fRenderPass);
37722bc8653d704584e13f35844dafb5ddeb9989127Greg Daniel}
37822bc8653d704584e13f35844dafb5ddeb9989127Greg Daniel
37922bc8653d704584e13f35844dafb5ddeb9989127Greg Danielvoid GrVkGpuCommandBuffer::addAdditionalRenderPass() {
38022bc8653d704584e13f35844dafb5ddeb9989127Greg Daniel    fCommandBufferInfos[fCurrentCmdInfo].currentCmdBuf()->end(fGpu);
38177b53f66bacd9a1d1c9df7d879a419b2abe069baGreg Daniel
38277b53f66bacd9a1d1c9df7d879a419b2abe069baGreg Daniel    CommandBufferInfo& cbInfo = fCommandBufferInfos.push_back();
38322bc8653d704584e13f35844dafb5ddeb9989127Greg Daniel    fCurrentCmdInfo++;
38477b53f66bacd9a1d1c9df7d879a419b2abe069baGreg Daniel
38577b53f66bacd9a1d1c9df7d879a419b2abe069baGreg Daniel    GrVkRenderPass::LoadStoreOps vkColorOps(VK_ATTACHMENT_LOAD_OP_LOAD,
38677b53f66bacd9a1d1c9df7d879a419b2abe069baGreg Daniel                                            VK_ATTACHMENT_STORE_OP_STORE);
38777b53f66bacd9a1d1c9df7d879a419b2abe069baGreg Daniel    GrVkRenderPass::LoadStoreOps vkStencilOps(VK_ATTACHMENT_LOAD_OP_LOAD,
38877b53f66bacd9a1d1c9df7d879a419b2abe069baGreg Daniel                                              VK_ATTACHMENT_STORE_OP_STORE);
38977b53f66bacd9a1d1c9df7d879a419b2abe069baGreg Daniel
39077b53f66bacd9a1d1c9df7d879a419b2abe069baGreg Daniel    const GrVkResourceProvider::CompatibleRPHandle& rpHandle =
39177b53f66bacd9a1d1c9df7d879a419b2abe069baGreg Daniel            fRenderTarget->compatibleRenderPassHandle();
39277b53f66bacd9a1d1c9df7d879a419b2abe069baGreg Daniel    if (rpHandle.isValid()) {
39377b53f66bacd9a1d1c9df7d879a419b2abe069baGreg Daniel        cbInfo.fRenderPass = fGpu->resourceProvider().findRenderPass(rpHandle,
39477b53f66bacd9a1d1c9df7d879a419b2abe069baGreg Daniel                                                                     vkColorOps,
39577b53f66bacd9a1d1c9df7d879a419b2abe069baGreg Daniel                                                                     vkStencilOps);
39677b53f66bacd9a1d1c9df7d879a419b2abe069baGreg Daniel    } else {
39777b53f66bacd9a1d1c9df7d879a419b2abe069baGreg Daniel        cbInfo.fRenderPass = fGpu->resourceProvider().findRenderPass(*fRenderTarget,
39877b53f66bacd9a1d1c9df7d879a419b2abe069baGreg Daniel                                                                     vkColorOps,
39977b53f66bacd9a1d1c9df7d879a419b2abe069baGreg Daniel                                                                     vkStencilOps);
40077b53f66bacd9a1d1c9df7d879a419b2abe069baGreg Daniel    }
40177b53f66bacd9a1d1c9df7d879a419b2abe069baGreg Daniel
40222bc8653d704584e13f35844dafb5ddeb9989127Greg Daniel    cbInfo.fCommandBuffers.push_back(fGpu->resourceProvider().findOrCreateSecondaryCommandBuffer());
40377b53f66bacd9a1d1c9df7d879a419b2abe069baGreg Daniel    // It shouldn't matter what we set the clear color to here since we will assume loading of the
40477b53f66bacd9a1d1c9df7d879a419b2abe069baGreg Daniel    // attachment.
40577b53f66bacd9a1d1c9df7d879a419b2abe069baGreg Daniel    memset(&cbInfo.fColorClearValue, 0, sizeof(VkClearValue));
40677b53f66bacd9a1d1c9df7d879a419b2abe069baGreg Daniel    cbInfo.fBounds.setEmpty();
40777b53f66bacd9a1d1c9df7d879a419b2abe069baGreg Daniel    cbInfo.fIsEmpty = true;
40877b53f66bacd9a1d1c9df7d879a419b2abe069baGreg Daniel    cbInfo.fStartsWithClear = false;
40977b53f66bacd9a1d1c9df7d879a419b2abe069baGreg Daniel
41022bc8653d704584e13f35844dafb5ddeb9989127Greg Daniel    cbInfo.currentCmdBuf()->begin(fGpu, fRenderTarget->framebuffer(), cbInfo.fRenderPass);
41177b53f66bacd9a1d1c9df7d879a419b2abe069baGreg Daniel}
41277b53f66bacd9a1d1c9df7d879a419b2abe069baGreg Daniel
413dbd11ec106e3726b09bf5d240c9fcbf6a671a570Greg Danielvoid GrVkGpuCommandBuffer::inlineUpload(GrOpFlushState* state, GrDrawOp::DeferredUploadFn& upload,
414dbd11ec106e3726b09bf5d240c9fcbf6a671a570Greg Daniel                                        GrRenderTarget* rt) {
415dbd11ec106e3726b09bf5d240c9fcbf6a671a570Greg Daniel    GrVkRenderTarget* target = static_cast<GrVkRenderTarget*>(rt);
416dbd11ec106e3726b09bf5d240c9fcbf6a671a570Greg Daniel    if (!fRenderTarget) {
417dbd11ec106e3726b09bf5d240c9fcbf6a671a570Greg Daniel        this->init(target);
418dbd11ec106e3726b09bf5d240c9fcbf6a671a570Greg Daniel    }
41922bc8653d704584e13f35844dafb5ddeb9989127Greg Daniel    if (!fCommandBufferInfos[fCurrentCmdInfo].fIsEmpty) {
42022bc8653d704584e13f35844dafb5ddeb9989127Greg Daniel        this->addAdditionalRenderPass();
42177b53f66bacd9a1d1c9df7d879a419b2abe069baGreg Daniel    }
42222bc8653d704584e13f35844dafb5ddeb9989127Greg Daniel    fCommandBufferInfos[fCurrentCmdInfo].fPreDrawUploads.emplace_back(state, upload);
42377b53f66bacd9a1d1c9df7d879a419b2abe069baGreg Daniel}
42477b53f66bacd9a1d1c9df7d879a419b2abe069baGreg Daniel
4259cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel////////////////////////////////////////////////////////////////////////////////
4269cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
4279cb6340a62a5d748e4189d50e51fa527c8c80c03egdanielvoid GrVkGpuCommandBuffer::bindGeometry(const GrPrimitiveProcessor& primProc,
428ff926502069d0ddafaecc18dc08973762e4befd2Chris Dalton                                        const GrBuffer* indexBuffer,
4291d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton                                        const GrBuffer* vertexBuffer,
4301d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton                                        const GrBuffer* instanceBuffer) {
431ff926502069d0ddafaecc18dc08973762e4befd2Chris Dalton    GrVkSecondaryCommandBuffer* currCmdBuf = fCommandBufferInfos[fCurrentCmdInfo].currentCmdBuf();
4329cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    // There is no need to put any memory barriers to make sure host writes have finished here.
4339cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    // When a command buffer is submitted to a queue, there is an implicit memory barrier that
4349cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    // occurs for all host writes. Additionally, BufferMemoryBarriers are not allowed inside of
4359cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    // an active RenderPass.
4369cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
4371d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton    // Here our vertex and instance inputs need to match the same 0-based bindings they were
4381d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton    // assigned in GrVkPipeline. That is, vertex first (if any) followed by instance.
4391d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton    uint32_t binding = 0;
4401d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton
4411d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton    if (primProc.hasVertexAttribs()) {
4421d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton        SkASSERT(vertexBuffer);
4431d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton        SkASSERT(!vertexBuffer->isCPUBacked());
4441d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton        SkASSERT(!vertexBuffer->isMapped());
4451d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton
4461d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton        currCmdBuf->bindInputBuffer(fGpu, binding++,
4471d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton                                    static_cast<const GrVkVertexBuffer*>(vertexBuffer));
4481d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton    }
4491d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton
4501d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton    if (primProc.hasInstanceAttribs()) {
4511d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton        SkASSERT(instanceBuffer);
4521d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton        SkASSERT(!instanceBuffer->isCPUBacked());
4531d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton        SkASSERT(!instanceBuffer->isMapped());
4541d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton
4551d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton        currCmdBuf->bindInputBuffer(fGpu, binding++,
4561d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton                                    static_cast<const GrVkVertexBuffer*>(instanceBuffer));
4571d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton    }
4589cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
459ff926502069d0ddafaecc18dc08973762e4befd2Chris Dalton    if (indexBuffer) {
460ff926502069d0ddafaecc18dc08973762e4befd2Chris Dalton        SkASSERT(indexBuffer);
461ff926502069d0ddafaecc18dc08973762e4befd2Chris Dalton        SkASSERT(!indexBuffer->isMapped());
462ff926502069d0ddafaecc18dc08973762e4befd2Chris Dalton        SkASSERT(!indexBuffer->isCPUBacked());
4639cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
464ff926502069d0ddafaecc18dc08973762e4befd2Chris Dalton        currCmdBuf->bindIndexBuffer(fGpu, static_cast<const GrVkIndexBuffer*>(indexBuffer));
4659cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    }
4669cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel}
4679cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
4689cb6340a62a5d748e4189d50e51fa527c8c80c03egdanielsk_sp<GrVkPipelineState> GrVkGpuCommandBuffer::prepareDrawState(
4699cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                                                               const GrPipeline& pipeline,
4709cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                                                               const GrPrimitiveProcessor& primProc,
47146983b7dd88603bb2a9a3c3e1ce3e147f5615f2fChris Dalton                                                               GrPrimitiveType primitiveType,
47246983b7dd88603bb2a9a3c3e1ce3e147f5615f2fChris Dalton                                                               bool hasDynamicState) {
47322bc8653d704584e13f35844dafb5ddeb9989127Greg Daniel    CommandBufferInfo& cbInfo = fCommandBufferInfos[fCurrentCmdInfo];
47422bc8653d704584e13f35844dafb5ddeb9989127Greg Daniel    SkASSERT(cbInfo.fRenderPass);
47536a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel
4769cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    sk_sp<GrVkPipelineState> pipelineState =
4779cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel        fGpu->resourceProvider().findOrCreateCompatiblePipelineState(pipeline,
4789cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                                                                     primProc,
4799cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                                                                     primitiveType,
48036a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel                                                                     *cbInfo.fRenderPass);
4819cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    if (!pipelineState) {
4829cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel        return pipelineState;
4839cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    }
4849cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
48522bc8653d704584e13f35844dafb5ddeb9989127Greg Daniel    if (!cbInfo.fIsEmpty &&
48622bc8653d704584e13f35844dafb5ddeb9989127Greg Daniel        fLastPipelineState && fLastPipelineState != pipelineState.get() &&
487e3cd691090cadd09c121d670e535fa7cb3230686Greg Daniel        fGpu->vkCaps().newCBOnPipelineChange()) {
48822bc8653d704584e13f35844dafb5ddeb9989127Greg Daniel        this->addAdditionalCommandBuffer();
48922bc8653d704584e13f35844dafb5ddeb9989127Greg Daniel    }
49022bc8653d704584e13f35844dafb5ddeb9989127Greg Daniel    fLastPipelineState = pipelineState.get();
49122bc8653d704584e13f35844dafb5ddeb9989127Greg Daniel
4929cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    pipelineState->setData(fGpu, primProc, pipeline);
4939cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
49422bc8653d704584e13f35844dafb5ddeb9989127Greg Daniel    pipelineState->bind(fGpu, cbInfo.currentCmdBuf());
4959cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
49646983b7dd88603bb2a9a3c3e1ce3e147f5615f2fChris Dalton    GrRenderTarget* rt = pipeline.getRenderTarget();
49746983b7dd88603bb2a9a3c3e1ce3e147f5615f2fChris Dalton
49846983b7dd88603bb2a9a3c3e1ce3e147f5615f2fChris Dalton    if (!pipeline.getScissorState().enabled()) {
49946983b7dd88603bb2a9a3c3e1ce3e147f5615f2fChris Dalton        GrVkPipeline::SetDynamicScissorRectState(fGpu, cbInfo.currentCmdBuf(), rt,
50046983b7dd88603bb2a9a3c3e1ce3e147f5615f2fChris Dalton                                                 SkIRect::MakeWH(rt->width(), rt->height()));
50146983b7dd88603bb2a9a3c3e1ce3e147f5615f2fChris Dalton    } else if (!hasDynamicState) {
50246983b7dd88603bb2a9a3c3e1ce3e147f5615f2fChris Dalton        GrVkPipeline::SetDynamicScissorRectState(fGpu, cbInfo.currentCmdBuf(), rt,
50346983b7dd88603bb2a9a3c3e1ce3e147f5615f2fChris Dalton                                                 pipeline.getScissorState().rect());
50446983b7dd88603bb2a9a3c3e1ce3e147f5615f2fChris Dalton    }
50546983b7dd88603bb2a9a3c3e1ce3e147f5615f2fChris Dalton    GrVkPipeline::SetDynamicViewportState(fGpu, cbInfo.currentCmdBuf(), rt);
50646983b7dd88603bb2a9a3c3e1ce3e147f5615f2fChris Dalton    GrVkPipeline::SetDynamicBlendConstantState(fGpu, cbInfo.currentCmdBuf(), rt->config(),
50746983b7dd88603bb2a9a3c3e1ce3e147f5615f2fChris Dalton                                               pipeline.getXferProcessor());
5089cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
5099cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    return pipelineState;
5109cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel}
5119cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
51218dfa980765bee6a1ce7c5f430cb32f487da6590Brian Salomonstatic void set_texture_layout(GrVkTexture* vkTexture, GrVkGpu* gpu) {
51318dfa980765bee6a1ce7c5f430cb32f487da6590Brian Salomon    // TODO: If we ever decide to create the secondary command buffers ahead of time before we
51418dfa980765bee6a1ce7c5f430cb32f487da6590Brian Salomon    // are actually going to submit them, we will need to track the sampled images and delay
51518dfa980765bee6a1ce7c5f430cb32f487da6590Brian Salomon    // adding the layout change/barrier until we are ready to submit.
51618dfa980765bee6a1ce7c5f430cb32f487da6590Brian Salomon    vkTexture->setImageLayout(gpu,
51718dfa980765bee6a1ce7c5f430cb32f487da6590Brian Salomon                              VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
51818dfa980765bee6a1ce7c5f430cb32f487da6590Brian Salomon                              VK_ACCESS_SHADER_READ_BIT,
51918dfa980765bee6a1ce7c5f430cb32f487da6590Brian Salomon                              VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT,
52018dfa980765bee6a1ce7c5f430cb32f487da6590Brian Salomon                              false);
52118dfa980765bee6a1ce7c5f430cb32f487da6590Brian Salomon}
52218dfa980765bee6a1ce7c5f430cb32f487da6590Brian Salomon
523ab015efc48c462ffdffebb45c02cd19efb254983Brian Salomonstatic void prepare_sampled_images(const GrResourceIOProcessor& processor, GrVkGpu* gpu) {
5240bbecb21ab82b3d742c491780bcc2e74be03efedBrian Salomon    for (int i = 0; i < processor.numTextureSamplers(); ++i) {
525ab015efc48c462ffdffebb45c02cd19efb254983Brian Salomon        const GrResourceIOProcessor::TextureSampler& sampler = processor.textureSampler(i);
5269bee2e5894bb8dd374392f238bc429e16f239583Robert Phillips        GrVkTexture* vkTexture = static_cast<GrVkTexture*>(sampler.peekTexture());
52766933552f1723c4a2b248711ab3d43921401e8e6egdaniel
5288d2141f0dbb36b92d0e3feb23a08663c29b59db0egdaniel        // We may need to resolve the texture first if it is also a render target
5298d2141f0dbb36b92d0e3feb23a08663c29b59db0egdaniel        GrVkRenderTarget* texRT = static_cast<GrVkRenderTarget*>(vkTexture->asRenderTarget());
5308d2141f0dbb36b92d0e3feb23a08663c29b59db0egdaniel        if (texRT) {
5318d2141f0dbb36b92d0e3feb23a08663c29b59db0egdaniel            gpu->onResolveRenderTarget(texRT);
5328d2141f0dbb36b92d0e3feb23a08663c29b59db0egdaniel        }
5339cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
534514baff8be7f71111aa7bfb9b099a096b31e16ecBrian Salomon        const GrSamplerParams& params = sampler.params();
5358d2141f0dbb36b92d0e3feb23a08663c29b59db0egdaniel        // Check if we need to regenerate any mip maps
536514baff8be7f71111aa7bfb9b099a096b31e16ecBrian Salomon        if (GrSamplerParams::kMipMap_FilterMode == params.filterMode()) {
5378d2141f0dbb36b92d0e3feb23a08663c29b59db0egdaniel            if (vkTexture->texturePriv().mipMapsAreDirty()) {
5388d2141f0dbb36b92d0e3feb23a08663c29b59db0egdaniel                gpu->generateMipmap(vkTexture);
5398d2141f0dbb36b92d0e3feb23a08663c29b59db0egdaniel                vkTexture->texturePriv().dirtyMipMaps(false);
5408d2141f0dbb36b92d0e3feb23a08663c29b59db0egdaniel            }
5418d2141f0dbb36b92d0e3feb23a08663c29b59db0egdaniel        }
54218dfa980765bee6a1ce7c5f430cb32f487da6590Brian Salomon        set_texture_layout(vkTexture, gpu);
5439cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    }
5449cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel}
5459cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
5469cb6340a62a5d748e4189d50e51fa527c8c80c03egdanielvoid GrVkGpuCommandBuffer::onDraw(const GrPipeline& pipeline,
5479cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                                  const GrPrimitiveProcessor& primProc,
54846983b7dd88603bb2a9a3c3e1ce3e147f5615f2fChris Dalton                                  const GrMesh meshes[],
54946983b7dd88603bb2a9a3c3e1ce3e147f5615f2fChris Dalton                                  const GrPipeline::DynamicState dynamicStates[],
55036a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel                                  int meshCount,
55136a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel                                  const SkRect& bounds) {
552c293a29bc2fced15ac44a66efa813d42cb3f2e0bBrian Salomon    GrVkRenderTarget* target = static_cast<GrVkRenderTarget*>(pipeline.getRenderTarget());
553c293a29bc2fced15ac44a66efa813d42cb3f2e0bBrian Salomon    if (!fRenderTarget) {
554c293a29bc2fced15ac44a66efa813d42cb3f2e0bBrian Salomon        this->init(target);
555c293a29bc2fced15ac44a66efa813d42cb3f2e0bBrian Salomon    }
556c293a29bc2fced15ac44a66efa813d42cb3f2e0bBrian Salomon    SkASSERT(target == fRenderTarget);
557c293a29bc2fced15ac44a66efa813d42cb3f2e0bBrian Salomon
5589cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    if (!meshCount) {
5599cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel        return;
5609cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    }
5618d2141f0dbb36b92d0e3feb23a08663c29b59db0egdaniel    prepare_sampled_images(primProc, fGpu);
562b58a2b4919aa67ab5bab1d497f26671d704654b4bsalomon    GrFragmentProcessor::Iter iter(pipeline);
563b58a2b4919aa67ab5bab1d497f26671d704654b4bsalomon    while (const GrFragmentProcessor* fp = iter.next()) {
564b58a2b4919aa67ab5bab1d497f26671d704654b4bsalomon        prepare_sampled_images(*fp, fGpu);
5652f5792a06c87efd5f9295b7b7bb714aac118bd2aegdaniel    }
566bb581ce30f55360fd3a12e7f5aa1fe324b16d085Robert Phillips    if (GrTexture* dstTexture = pipeline.peekDstTexture()) {
567bb581ce30f55360fd3a12e7f5aa1fe324b16d085Robert Phillips        set_texture_layout(static_cast<GrVkTexture*>(dstTexture), fGpu);
56818dfa980765bee6a1ce7c5f430cb32f487da6590Brian Salomon    }
5692f5792a06c87efd5f9295b7b7bb714aac118bd2aegdaniel
570bca46e29e9f96999df0b38fb9359e71b73217c94Chris Dalton    GrPrimitiveType primitiveType = meshes[0].primitiveType();
5719cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    sk_sp<GrVkPipelineState> pipelineState = this->prepareDrawState(pipeline,
5729cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                                                                    primProc,
57346983b7dd88603bb2a9a3c3e1ce3e147f5615f2fChris Dalton                                                                    primitiveType,
57446983b7dd88603bb2a9a3c3e1ce3e147f5615f2fChris Dalton                                                                    SkToBool(dynamicStates));
5759cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    if (!pipelineState) {
5769cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel        return;
5779cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    }
5789cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
57946983b7dd88603bb2a9a3c3e1ce3e147f5615f2fChris Dalton    CommandBufferInfo& cbInfo = fCommandBufferInfos[fCurrentCmdInfo];
58046983b7dd88603bb2a9a3c3e1ce3e147f5615f2fChris Dalton
5819cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    for (int i = 0; i < meshCount; ++i) {
5829cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel        const GrMesh& mesh = meshes[i];
583bca46e29e9f96999df0b38fb9359e71b73217c94Chris Dalton        if (mesh.primitiveType() != primitiveType) {
5846f24180a99bc486cf4cee5da1a45225e7ff263d7Chris Dalton            // Technically we don't have to call this here (since there is a safety check in
5856f24180a99bc486cf4cee5da1a45225e7ff263d7Chris Dalton            // pipelineState:setData but this will allow for quicker freeing of resources if the
5866f24180a99bc486cf4cee5da1a45225e7ff263d7Chris Dalton            // pipelineState sits in a cache for a while.
5876f24180a99bc486cf4cee5da1a45225e7ff263d7Chris Dalton            pipelineState->freeTempResources(fGpu);
5886f24180a99bc486cf4cee5da1a45225e7ff263d7Chris Dalton            SkDEBUGCODE(pipelineState = nullptr);
589bca46e29e9f96999df0b38fb9359e71b73217c94Chris Dalton            primitiveType = mesh.primitiveType();
5906f24180a99bc486cf4cee5da1a45225e7ff263d7Chris Dalton            pipelineState = this->prepareDrawState(pipeline,
5916f24180a99bc486cf4cee5da1a45225e7ff263d7Chris Dalton                                                   primProc,
59246983b7dd88603bb2a9a3c3e1ce3e147f5615f2fChris Dalton                                                   primitiveType,
59346983b7dd88603bb2a9a3c3e1ce3e147f5615f2fChris Dalton                                                   SkToBool(dynamicStates));
5946f24180a99bc486cf4cee5da1a45225e7ff263d7Chris Dalton            if (!pipelineState) {
5956f24180a99bc486cf4cee5da1a45225e7ff263d7Chris Dalton                return;
5969cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel            }
5976f24180a99bc486cf4cee5da1a45225e7ff263d7Chris Dalton        }
5989cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
59946983b7dd88603bb2a9a3c3e1ce3e147f5615f2fChris Dalton        if (dynamicStates) {
60046983b7dd88603bb2a9a3c3e1ce3e147f5615f2fChris Dalton            if (pipeline.getScissorState().enabled()) {
60146983b7dd88603bb2a9a3c3e1ce3e147f5615f2fChris Dalton                GrVkPipeline::SetDynamicScissorRectState(fGpu, cbInfo.currentCmdBuf(),
60246983b7dd88603bb2a9a3c3e1ce3e147f5615f2fChris Dalton                                                         target, dynamicStates[i].fScissorRect);
60346983b7dd88603bb2a9a3c3e1ce3e147f5615f2fChris Dalton            }
60446983b7dd88603bb2a9a3c3e1ce3e147f5615f2fChris Dalton        }
60546983b7dd88603bb2a9a3c3e1ce3e147f5615f2fChris Dalton
606bca46e29e9f96999df0b38fb9359e71b73217c94Chris Dalton        SkASSERT(pipelineState);
607114a3c0b2b26c84b9d0907a99fd8ab7938631246Chris Dalton        mesh.sendToGpu(primProc, this);
6089cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    }
6099cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
61036a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel    cbInfo.fBounds.join(bounds);
611114a3c0b2b26c84b9d0907a99fd8ab7938631246Chris Dalton    cbInfo.fIsEmpty = false;
61236a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel
6139cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    // Technically we don't have to call this here (since there is a safety check in
6149cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    // pipelineState:setData but this will allow for quicker freeing of resources if the
6159cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    // pipelineState sits in a cache for a while.
6169cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    pipelineState->freeTempResources(fGpu);
617066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel}
618066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel
6191d6163577c8a4f1372208e2c9e03b1a69906d385Chris Daltonvoid GrVkGpuCommandBuffer::sendInstancedMeshToGpu(const GrPrimitiveProcessor& primProc,
6201d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton                                                  GrPrimitiveType,
6211d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton                                                  const GrBuffer* vertexBuffer,
6221d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton                                                  int vertexCount,
6231d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton                                                  int baseVertex,
6241d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton                                                  const GrBuffer* instanceBuffer,
6251d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton                                                  int instanceCount,
6261d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton                                                  int baseInstance) {
627114a3c0b2b26c84b9d0907a99fd8ab7938631246Chris Dalton    CommandBufferInfo& cbInfo = fCommandBufferInfos[fCurrentCmdInfo];
6281d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton    this->bindGeometry(primProc, nullptr, vertexBuffer, instanceBuffer);
6291d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton    cbInfo.currentCmdBuf()->draw(fGpu, vertexCount, instanceCount, baseVertex, baseInstance);
630114a3c0b2b26c84b9d0907a99fd8ab7938631246Chris Dalton    fGpu->stats()->incNumDraws();
631114a3c0b2b26c84b9d0907a99fd8ab7938631246Chris Dalton}
632114a3c0b2b26c84b9d0907a99fd8ab7938631246Chris Dalton
6331d6163577c8a4f1372208e2c9e03b1a69906d385Chris Daltonvoid GrVkGpuCommandBuffer::sendIndexedInstancedMeshToGpu(const GrPrimitiveProcessor& primProc,
6341d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton                                                         GrPrimitiveType,
6351d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton                                                         const GrBuffer* indexBuffer,
6361d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton                                                         int indexCount,
6371d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton                                                         int baseIndex,
6381d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton                                                         const GrBuffer* vertexBuffer,
6391d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton                                                         int baseVertex,
6401d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton                                                         const GrBuffer* instanceBuffer,
6411d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton                                                         int instanceCount,
6421d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton                                                         int baseInstance) {
643114a3c0b2b26c84b9d0907a99fd8ab7938631246Chris Dalton    CommandBufferInfo& cbInfo = fCommandBufferInfos[fCurrentCmdInfo];
6441d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton    this->bindGeometry(primProc, indexBuffer, vertexBuffer, instanceBuffer);
6451d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton    cbInfo.currentCmdBuf()->drawIndexed(fGpu, indexCount, instanceCount,
6461d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton                                        baseIndex, baseVertex, baseInstance);
647114a3c0b2b26c84b9d0907a99fd8ab7938631246Chris Dalton    fGpu->stats()->incNumDraws();
648114a3c0b2b26c84b9d0907a99fd8ab7938631246Chris Dalton}
649114a3c0b2b26c84b9d0907a99fd8ab7938631246Chris Dalton
650