GrVkGpuCommandBuffer.cpp revision 29df76096fd30941086324902a82656df2d8becd
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"
129cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel#include "GrPipeline.h"
139cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel#include "GrRenderTargetPriv.h"
149cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel#include "GrTextureAccess.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"
23066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel
249cb6340a62a5d748e4189d50e51fa527c8c80c03egdanielvoid get_vk_load_store_ops(const GrGpuCommandBuffer::LoadAndStoreInfo& info,
25066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel                           VkAttachmentLoadOp* loadOp, VkAttachmentStoreOp* storeOp) {
269cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    switch (info.fLoadOp) {
279cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel        case GrGpuCommandBuffer::LoadOp::kLoad:
28066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel            *loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
29066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel            break;
309cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel        case GrGpuCommandBuffer::LoadOp::kClear:
31066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel            *loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
32066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel            break;
339cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel        case GrGpuCommandBuffer::LoadOp::kDiscard:
34066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel            *loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
359cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel            break;
369cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel        default:
379cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel            SK_ABORT("Invalid LoadOp");
389cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel            *loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
399cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    }
409cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
419cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    switch (info.fStoreOp) {
429cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel        case GrGpuCommandBuffer::StoreOp::kStore:
43066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel            *storeOp = VK_ATTACHMENT_STORE_OP_STORE;
44066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel            break;
459cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel        case GrGpuCommandBuffer::StoreOp::kDiscard:
46066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel            *storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
47066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel            break;
480bbc3713de2f51c17fad935ccfd87dd68c7062efbrianosman        default:
499cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel            SK_ABORT("Invalid StoreOp");
500bbc3713de2f51c17fad935ccfd87dd68c7062efbrianosman            *storeOp = VK_ATTACHMENT_STORE_OP_STORE;
51066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel    }
52066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel}
53066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel
54066df7ca911b65d416783f3bec6f4f1662948ad5egdanielGrVkGpuCommandBuffer::GrVkGpuCommandBuffer(GrVkGpu* gpu,
559cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                                           GrVkRenderTarget* target,
569cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                                           const LoadAndStoreInfo& colorInfo,
579cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                                           const LoadAndStoreInfo& stencilInfo)
589cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    : fGpu(gpu)
599cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    , fRenderTarget(target)
609cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    , fIsEmpty(true) {
61066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel    VkAttachmentLoadOp vkLoadOp;
62066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel    VkAttachmentStoreOp vkStoreOp;
63066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel
649cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    get_vk_load_store_ops(colorInfo, &vkLoadOp, &vkStoreOp);
65066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel    GrVkRenderPass::LoadStoreOps vkColorOps(vkLoadOp, vkStoreOp);
66066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel
679cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    get_vk_load_store_ops(stencilInfo, &vkLoadOp, &vkStoreOp);
68066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel    GrVkRenderPass::LoadStoreOps vkStencilOps(vkLoadOp, vkStoreOp);
699cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
70066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel    GrVkRenderPass::LoadStoreOps vkResolveOps(VK_ATTACHMENT_LOAD_OP_LOAD,
71066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel                                              VK_ATTACHMENT_STORE_OP_STORE);
72066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel
739cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    const GrVkResourceProvider::CompatibleRPHandle& rpHandle = target->compatibleRenderPassHandle();
74066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel    if (rpHandle.isValid()) {
75066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel        fRenderPass = fGpu->resourceProvider().findRenderPass(rpHandle,
76066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel                                                              vkColorOps,
77066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel                                                              vkResolveOps,
78066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel                                                              vkStencilOps);
79066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel    } else {
809cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel        fRenderPass = fGpu->resourceProvider().findRenderPass(*target,
81066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel                                                              vkColorOps,
82066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel                                                              vkResolveOps,
83066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel                                                              vkStencilOps);
84066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel    }
85066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel
869cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    GrColorToRGBAFloat(colorInfo.fClearColor, fColorClearValue.color.float32);
879cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
887ec92413307c9da43c013d1e4e15716a44059810jvanverth    fCommandBuffer = gpu->resourceProvider().findOrCreateSecondaryCommandBuffer();
897ec92413307c9da43c013d1e4e15716a44059810jvanverth    fCommandBuffer->begin(gpu, target->framebuffer(), fRenderPass);
90066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel}
91066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel
92066df7ca911b65d416783f3bec6f4f1662948ad5egdanielGrVkGpuCommandBuffer::~GrVkGpuCommandBuffer() {
93066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel    fCommandBuffer->unref(fGpu);
94066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel    fRenderPass->unref(fGpu);
95066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel}
96066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel
979cb6340a62a5d748e4189d50e51fa527c8c80c03egdanielGrGpu* GrVkGpuCommandBuffer::gpu() { return fGpu; }
989cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
99066df7ca911b65d416783f3bec6f4f1662948ad5egdanielvoid GrVkGpuCommandBuffer::end() {
100066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel    fCommandBuffer->end(fGpu);
101066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel}
102066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel
1039cb6340a62a5d748e4189d50e51fa527c8c80c03egdanielvoid GrVkGpuCommandBuffer::onSubmit(const SkIRect& bounds) {
104ce3bfb1ed155880585b2d0bb0a8d3e43306e23f2egdaniel    // Change layout of our render target so it can be used as the color attachment. Currently
105ce3bfb1ed155880585b2d0bb0a8d3e43306e23f2egdaniel    // we don't attach the resolve to the framebuffer so no need to change its layout.
106ce3bfb1ed155880585b2d0bb0a8d3e43306e23f2egdaniel    GrVkImage* targetImage = fRenderTarget->msaaImage() ? fRenderTarget->msaaImage()
107ce3bfb1ed155880585b2d0bb0a8d3e43306e23f2egdaniel                                                        : fRenderTarget;
108ce3bfb1ed155880585b2d0bb0a8d3e43306e23f2egdaniel    targetImage->setImageLayout(fGpu,
109ce3bfb1ed155880585b2d0bb0a8d3e43306e23f2egdaniel                                VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
110ce3bfb1ed155880585b2d0bb0a8d3e43306e23f2egdaniel                                VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
111ce3bfb1ed155880585b2d0bb0a8d3e43306e23f2egdaniel                                VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
112ce3bfb1ed155880585b2d0bb0a8d3e43306e23f2egdaniel                                false);
1139cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
1149cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    // If we are using a stencil attachment we also need to update its layout
1159cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    if (GrStencilAttachment* stencil = fRenderTarget->renderTargetPriv().getStencilAttachment()) {
1169cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel        GrVkStencilAttachment* vkStencil = (GrVkStencilAttachment*)stencil;
1179cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel        vkStencil->setImageLayout(fGpu,
1189cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                                  VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
1199cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                                  VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT |
1209cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                                  VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT,
1219cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                                  VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
1229cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                                  false);
1239cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    }
1249cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
1259cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    for (int i = 0; i < fSampledImages.count(); ++i) {
1269cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel        fSampledImages[i]->setImageLayout(fGpu,
1279cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                                          VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
1289cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                                          VK_ACCESS_SHADER_READ_BIT,
1299cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                                          VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT,
1309cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                                          false);
1319cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    }
1329cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
1339cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    fGpu->submitSecondaryCommandBuffer(fCommandBuffer, fRenderPass, &fColorClearValue,
1349cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                                       fRenderTarget, bounds);
1359cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel}
1369cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
13737535c9ecef67a56cad293535f8626b1d60f7c08egdanielvoid GrVkGpuCommandBuffer::discard(GrRenderTarget* target) {
13837535c9ecef67a56cad293535f8626b1d60f7c08egdaniel    if (fIsEmpty) {
13937535c9ecef67a56cad293535f8626b1d60f7c08egdaniel        // We will change the render pass to do a clear load instead
14037535c9ecef67a56cad293535f8626b1d60f7c08egdaniel        GrVkRenderPass::LoadStoreOps vkColorOps(VK_ATTACHMENT_LOAD_OP_DONT_CARE,
14137535c9ecef67a56cad293535f8626b1d60f7c08egdaniel                                                VK_ATTACHMENT_STORE_OP_STORE);
14237535c9ecef67a56cad293535f8626b1d60f7c08egdaniel        GrVkRenderPass::LoadStoreOps vkStencilOps(VK_ATTACHMENT_LOAD_OP_DONT_CARE,
14337535c9ecef67a56cad293535f8626b1d60f7c08egdaniel                                                  VK_ATTACHMENT_STORE_OP_STORE);
14437535c9ecef67a56cad293535f8626b1d60f7c08egdaniel        GrVkRenderPass::LoadStoreOps vkResolveOps(VK_ATTACHMENT_LOAD_OP_DONT_CARE,
14537535c9ecef67a56cad293535f8626b1d60f7c08egdaniel                                                  VK_ATTACHMENT_STORE_OP_STORE);
14637535c9ecef67a56cad293535f8626b1d60f7c08egdaniel
14737535c9ecef67a56cad293535f8626b1d60f7c08egdaniel        const GrVkRenderPass* oldRP = fRenderPass;
14837535c9ecef67a56cad293535f8626b1d60f7c08egdaniel
14937535c9ecef67a56cad293535f8626b1d60f7c08egdaniel        GrVkRenderTarget* vkRT = static_cast<GrVkRenderTarget*>(target);
15037535c9ecef67a56cad293535f8626b1d60f7c08egdaniel        const GrVkResourceProvider::CompatibleRPHandle& rpHandle =
15137535c9ecef67a56cad293535f8626b1d60f7c08egdaniel            vkRT->compatibleRenderPassHandle();
15237535c9ecef67a56cad293535f8626b1d60f7c08egdaniel        if (rpHandle.isValid()) {
15337535c9ecef67a56cad293535f8626b1d60f7c08egdaniel            fRenderPass = fGpu->resourceProvider().findRenderPass(rpHandle,
15437535c9ecef67a56cad293535f8626b1d60f7c08egdaniel                                                                  vkColorOps,
15537535c9ecef67a56cad293535f8626b1d60f7c08egdaniel                                                                  vkResolveOps,
15637535c9ecef67a56cad293535f8626b1d60f7c08egdaniel                                                                  vkStencilOps);
15737535c9ecef67a56cad293535f8626b1d60f7c08egdaniel        } else {
15837535c9ecef67a56cad293535f8626b1d60f7c08egdaniel            fRenderPass = fGpu->resourceProvider().findRenderPass(*vkRT,
15937535c9ecef67a56cad293535f8626b1d60f7c08egdaniel                                                                  vkColorOps,
16037535c9ecef67a56cad293535f8626b1d60f7c08egdaniel                                                                  vkResolveOps,
16137535c9ecef67a56cad293535f8626b1d60f7c08egdaniel                                                                  vkStencilOps);
16237535c9ecef67a56cad293535f8626b1d60f7c08egdaniel        }
16337535c9ecef67a56cad293535f8626b1d60f7c08egdaniel
16437535c9ecef67a56cad293535f8626b1d60f7c08egdaniel        SkASSERT(fRenderPass->isCompatible(*oldRP));
16537535c9ecef67a56cad293535f8626b1d60f7c08egdaniel        oldRP->unref(fGpu);
16637535c9ecef67a56cad293535f8626b1d60f7c08egdaniel    }
16737535c9ecef67a56cad293535f8626b1d60f7c08egdaniel}
16837535c9ecef67a56cad293535f8626b1d60f7c08egdaniel
1699cb6340a62a5d748e4189d50e51fa527c8c80c03egdanielvoid GrVkGpuCommandBuffer::onClearStencilClip(GrRenderTarget* target,
17029df76096fd30941086324902a82656df2d8becdcsmartdalton                                              const GrFixedClip& clip,
17129df76096fd30941086324902a82656df2d8becdcsmartdalton                                              bool insideStencilMask) {
1729cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    SkASSERT(target);
1739cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
1749cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    GrVkRenderTarget* vkRT = static_cast<GrVkRenderTarget*>(target);
1759cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    GrStencilAttachment* sb = target->renderTargetPriv().getStencilAttachment();
1769cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    // this should only be called internally when we know we have a
1779cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    // stencil buffer.
1789cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    SkASSERT(sb);
1799cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    int stencilBitCount = sb->bits();
1809cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
1819cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    // The contract with the callers does not guarantee that we preserve all bits in the stencil
1829cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    // during this clear. Thus we will clear the entire stencil to the desired value.
1839cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
1849cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    VkClearDepthStencilValue vkStencilColor;
1859cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    memset(&vkStencilColor, 0, sizeof(VkClearDepthStencilValue));
18629df76096fd30941086324902a82656df2d8becdcsmartdalton    if (insideStencilMask) {
1879cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel        vkStencilColor.stencil = (1 << (stencilBitCount - 1));
1889cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    } else {
1899cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel        vkStencilColor.stencil = 0;
1909cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    }
1919cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
1929cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    VkClearRect clearRect;
1939cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    // Flip rect if necessary
19429df76096fd30941086324902a82656df2d8becdcsmartdalton    SkIRect vkRect;
19529df76096fd30941086324902a82656df2d8becdcsmartdalton    if (!clip.scissorEnabled()) {
19629df76096fd30941086324902a82656df2d8becdcsmartdalton        vkRect.setXYWH(0, 0, vkRT->width(), vkRT->height());
19729df76096fd30941086324902a82656df2d8becdcsmartdalton    } else if (kBottomLeft_GrSurfaceOrigin != vkRT->origin()) {
19829df76096fd30941086324902a82656df2d8becdcsmartdalton        vkRect = clip.scissorRect();
19929df76096fd30941086324902a82656df2d8becdcsmartdalton    } else {
20029df76096fd30941086324902a82656df2d8becdcsmartdalton        const SkIRect& scissor = clip.scissorRect();
20129df76096fd30941086324902a82656df2d8becdcsmartdalton        vkRect.setLTRB(scissor.fLeft, vkRT->height() - scissor.fBottom,
20229df76096fd30941086324902a82656df2d8becdcsmartdalton                       scissor.fRight, vkRT->height() - scissor.fTop);
2039cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    }
2049cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
2059cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    clearRect.rect.offset = { vkRect.fLeft, vkRect.fTop };
2069cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    clearRect.rect.extent = { (uint32_t)vkRect.width(), (uint32_t)vkRect.height() };
2079cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
2089cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    clearRect.baseArrayLayer = 0;
2099cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    clearRect.layerCount = 1;
2109cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
2119cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    uint32_t stencilIndex;
2129cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    SkAssertResult(fRenderPass->stencilAttachmentIndex(&stencilIndex));
2139cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
2149cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    VkClearAttachment attachment;
2159cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    attachment.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT;
2169cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    attachment.colorAttachment = 0; // this value shouldn't matter
2179cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    attachment.clearValue.depthStencil = vkStencilColor;
2189cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
2199cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    fCommandBuffer->clearAttachments(fGpu, 1, &attachment, 1, &clearRect);
2209cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    fIsEmpty = false;
2219cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel}
2229cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
22329df76096fd30941086324902a82656df2d8becdcsmartdaltonvoid GrVkGpuCommandBuffer::onClear(GrRenderTarget* target, const GrFixedClip& clip, GrColor color) {
2249cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    // parent class should never let us get here with no RT
2259cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    SkASSERT(target);
2269cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
2279cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    VkClearColorValue vkColor;
2289cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    GrColorToRGBAFloat(color, vkColor.float32);
2299cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
2309cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    GrVkRenderTarget* vkRT = static_cast<GrVkRenderTarget*>(target);
2319cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
23229df76096fd30941086324902a82656df2d8becdcsmartdalton    if (fIsEmpty && !clip.scissorEnabled()) {
2339cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel        // We will change the render pass to do a clear load instead
2349cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel        GrVkRenderPass::LoadStoreOps vkColorOps(VK_ATTACHMENT_LOAD_OP_CLEAR,
2359cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                                                VK_ATTACHMENT_STORE_OP_STORE);
2369cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel        GrVkRenderPass::LoadStoreOps vkStencilOps(VK_ATTACHMENT_LOAD_OP_LOAD,
2379cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                                                  VK_ATTACHMENT_STORE_OP_STORE);
2389cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel        GrVkRenderPass::LoadStoreOps vkResolveOps(VK_ATTACHMENT_LOAD_OP_LOAD,
2399cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                                                  VK_ATTACHMENT_STORE_OP_STORE);
2409cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
2419cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel        const GrVkRenderPass* oldRP = fRenderPass;
2429cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
2439cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel        const GrVkResourceProvider::CompatibleRPHandle& rpHandle =
2449cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel            vkRT->compatibleRenderPassHandle();
2459cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel        if (rpHandle.isValid()) {
2469cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel            fRenderPass = fGpu->resourceProvider().findRenderPass(rpHandle,
2479cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                                                                  vkColorOps,
2489cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                                                                  vkResolveOps,
2499cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                                                                  vkStencilOps);
2509cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel        } else {
2519cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel            fRenderPass = fGpu->resourceProvider().findRenderPass(*vkRT,
2529cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                                                                  vkColorOps,
2539cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                                                                  vkResolveOps,
2549cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                                                                  vkStencilOps);
2559cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel        }
2569cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
2579cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel        SkASSERT(fRenderPass->isCompatible(*oldRP));
2589cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel        oldRP->unref(fGpu);
2599cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
2609cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel        GrColorToRGBAFloat(color, fColorClearValue.color.float32);
2619cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel        return;
2629cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    }
2639cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
2649cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    // We always do a sub rect clear with clearAttachments since we are inside a render pass
2659cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    VkClearRect clearRect;
2669cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    // Flip rect if necessary
26729df76096fd30941086324902a82656df2d8becdcsmartdalton    SkIRect vkRect;
26829df76096fd30941086324902a82656df2d8becdcsmartdalton    if (!clip.scissorEnabled()) {
26929df76096fd30941086324902a82656df2d8becdcsmartdalton        vkRect.setXYWH(0, 0, vkRT->width(), vkRT->height());
27029df76096fd30941086324902a82656df2d8becdcsmartdalton    } else if (kBottomLeft_GrSurfaceOrigin != vkRT->origin()) {
27129df76096fd30941086324902a82656df2d8becdcsmartdalton        vkRect = clip.scissorRect();
27229df76096fd30941086324902a82656df2d8becdcsmartdalton    } else {
27329df76096fd30941086324902a82656df2d8becdcsmartdalton        const SkIRect& scissor = clip.scissorRect();
27429df76096fd30941086324902a82656df2d8becdcsmartdalton        vkRect.setLTRB(scissor.fLeft, vkRT->height() - scissor.fBottom,
27529df76096fd30941086324902a82656df2d8becdcsmartdalton                       scissor.fRight, vkRT->height() - scissor.fTop);
2769cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    }
2779cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    clearRect.rect.offset = { vkRect.fLeft, vkRect.fTop };
2789cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    clearRect.rect.extent = { (uint32_t)vkRect.width(), (uint32_t)vkRect.height() };
2799cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    clearRect.baseArrayLayer = 0;
2809cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    clearRect.layerCount = 1;
2819cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
2829cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    uint32_t colorIndex;
2839cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    SkAssertResult(fRenderPass->colorAttachmentIndex(&colorIndex));
2849cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
2859cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    VkClearAttachment attachment;
2869cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    attachment.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
2879cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    attachment.colorAttachment = colorIndex;
2889cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    attachment.clearValue.color = vkColor;
2899cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
2909cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    fCommandBuffer->clearAttachments(fGpu, 1, &attachment, 1, &clearRect);
2919cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    fIsEmpty = false;
2929cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    return;
2939cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel}
2949cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
2959cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel////////////////////////////////////////////////////////////////////////////////
2969cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
2979cb6340a62a5d748e4189d50e51fa527c8c80c03egdanielvoid GrVkGpuCommandBuffer::bindGeometry(const GrPrimitiveProcessor& primProc,
2989cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                                        const GrNonInstancedMesh& mesh) {
2999cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    // There is no need to put any memory barriers to make sure host writes have finished here.
3009cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    // When a command buffer is submitted to a queue, there is an implicit memory barrier that
3019cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    // occurs for all host writes. Additionally, BufferMemoryBarriers are not allowed inside of
3029cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    // an active RenderPass.
303485a12003ab48b54965d6f7172f3183358919d8ecsmartdalton    SkASSERT(!mesh.vertexBuffer()->isCPUBacked());
3049cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    GrVkVertexBuffer* vbuf;
3059cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    vbuf = (GrVkVertexBuffer*)mesh.vertexBuffer();
3069cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    SkASSERT(vbuf);
3079cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    SkASSERT(!vbuf->isMapped());
3089cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
3099cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    fCommandBuffer->bindVertexBuffer(fGpu, vbuf);
3109cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
3119cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    if (mesh.isIndexed()) {
312485a12003ab48b54965d6f7172f3183358919d8ecsmartdalton        SkASSERT(!mesh.indexBuffer()->isCPUBacked());
3139cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel        GrVkIndexBuffer* ibuf = (GrVkIndexBuffer*)mesh.indexBuffer();
3149cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel        SkASSERT(ibuf);
3159cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel        SkASSERT(!ibuf->isMapped());
3169cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
3179cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel        fCommandBuffer->bindIndexBuffer(fGpu, ibuf);
3189cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    }
3199cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel}
3209cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
3219cb6340a62a5d748e4189d50e51fa527c8c80c03egdanielsk_sp<GrVkPipelineState> GrVkGpuCommandBuffer::prepareDrawState(
3229cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                                                               const GrPipeline& pipeline,
3239cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                                                               const GrPrimitiveProcessor& primProc,
3249cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                                                               GrPrimitiveType primitiveType,
3259cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                                                               const GrVkRenderPass& renderPass) {
3269cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    sk_sp<GrVkPipelineState> pipelineState =
3279cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel        fGpu->resourceProvider().findOrCreateCompatiblePipelineState(pipeline,
3289cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                                                                     primProc,
3299cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                                                                     primitiveType,
3309cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                                                                     renderPass);
3319cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    if (!pipelineState) {
3329cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel        return pipelineState;
3339cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    }
3349cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
3359cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    pipelineState->setData(fGpu, primProc, pipeline);
3369cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
3379cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    pipelineState->bind(fGpu, fCommandBuffer);
3389cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
3399cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    GrVkPipeline::SetDynamicState(fGpu, fCommandBuffer, pipeline);
3409cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
3419cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    return pipelineState;
3429cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel}
3439cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
3449cb6340a62a5d748e4189d50e51fa527c8c80c03egdanielstatic void append_sampled_images(const GrProcessor& processor,
34550ead53ac97deb23310916e3736c3f5e2d8f7f4begdaniel                                  GrVkGpu* gpu,
3469cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                                  SkTArray<GrVkImage*>* sampledImages) {
3479cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    if (int numTextures = processor.numTextures()) {
3489cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel        GrVkImage** images = sampledImages->push_back_n(numTextures);
3499cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel        int i = 0;
3509cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel        do {
3519cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel            const GrTextureAccess& texAccess = processor.textureAccess(i);
3529cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel            GrVkTexture* vkTexture = static_cast<GrVkTexture*>(processor.texture(i));
3539cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel            SkASSERT(vkTexture);
35466933552f1723c4a2b248711ab3d43921401e8e6egdaniel
35566933552f1723c4a2b248711ab3d43921401e8e6egdaniel            // We may need to resolve the texture first if it is also a render target
35666933552f1723c4a2b248711ab3d43921401e8e6egdaniel            GrVkRenderTarget* texRT = static_cast<GrVkRenderTarget*>(vkTexture->asRenderTarget());
35766933552f1723c4a2b248711ab3d43921401e8e6egdaniel            if (texRT) {
35866933552f1723c4a2b248711ab3d43921401e8e6egdaniel                gpu->onResolveRenderTarget(texRT);
35966933552f1723c4a2b248711ab3d43921401e8e6egdaniel            }
36066933552f1723c4a2b248711ab3d43921401e8e6egdaniel
3619cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel            const GrTextureParams& params = texAccess.getParams();
3629cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel            // Check if we need to regenerate any mip maps
3639cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel            if (GrTextureParams::kMipMap_FilterMode == params.filterMode()) {
3649cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                if (vkTexture->texturePriv().mipMapsAreDirty()) {
3659cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                    gpu->generateMipmap(vkTexture);
3669cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                    vkTexture->texturePriv().dirtyMipMaps(false);
3679cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                }
3689cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel            }
3699cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
3709cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel            images[i] = vkTexture;
3719cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel        } while (++i < numTextures);
3729cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
3739cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    }
3749cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel}
3759cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
3769cb6340a62a5d748e4189d50e51fa527c8c80c03egdanielvoid GrVkGpuCommandBuffer::onDraw(const GrPipeline& pipeline,
3779cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                                  const GrPrimitiveProcessor& primProc,
3789cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                                  const GrMesh* meshes,
3799cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                                  int meshCount) {
3809cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    if (!meshCount) {
3819cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel        return;
3829cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    }
3839cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    GrRenderTarget* rt = pipeline.getRenderTarget();
3849cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    GrVkRenderTarget* vkRT = static_cast<GrVkRenderTarget*>(rt);
3859cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    const GrVkRenderPass* renderPass = vkRT->simpleRenderPass();
3869cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    SkASSERT(renderPass);
3879cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
3882f5792a06c87efd5f9295b7b7bb714aac118bd2aegdaniel    append_sampled_images(primProc, fGpu, &fSampledImages);
3892f5792a06c87efd5f9295b7b7bb714aac118bd2aegdaniel    for (int i = 0; i < pipeline.numFragmentProcessors(); ++i) {
3902f5792a06c87efd5f9295b7b7bb714aac118bd2aegdaniel        append_sampled_images(pipeline.getFragmentProcessor(i), fGpu, &fSampledImages);
3912f5792a06c87efd5f9295b7b7bb714aac118bd2aegdaniel    }
3922f5792a06c87efd5f9295b7b7bb714aac118bd2aegdaniel    append_sampled_images(pipeline.getXferProcessor(), fGpu, &fSampledImages);
3932f5792a06c87efd5f9295b7b7bb714aac118bd2aegdaniel
3949cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    GrPrimitiveType primitiveType = meshes[0].primitiveType();
3959cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    sk_sp<GrVkPipelineState> pipelineState = this->prepareDrawState(pipeline,
3969cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                                                                    primProc,
3979cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                                                                    primitiveType,
3989cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                                                                    *renderPass);
3999cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    if (!pipelineState) {
4009cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel        return;
4019cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    }
4029cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
4039cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    for (int i = 0; i < meshCount; ++i) {
4049cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel        const GrMesh& mesh = meshes[i];
4059cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel        GrMesh::Iterator iter;
4069cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel        const GrNonInstancedMesh* nonIdxMesh = iter.init(mesh);
4079cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel        do {
4089cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel            if (nonIdxMesh->primitiveType() != primitiveType) {
4099cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                // Technically we don't have to call this here (since there is a safety check in
4109cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                // pipelineState:setData but this will allow for quicker freeing of resources if the
4119cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                // pipelineState sits in a cache for a while.
4129cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                pipelineState->freeTempResources(fGpu);
4139cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                SkDEBUGCODE(pipelineState = nullptr);
4149cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                primitiveType = nonIdxMesh->primitiveType();
4159cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                pipelineState = this->prepareDrawState(pipeline,
4169cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                                                       primProc,
4179cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                                                       primitiveType,
4189cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                                                       *renderPass);
4199cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                if (!pipelineState) {
4209cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                    return;
4219cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                }
4229cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel            }
4239cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel            SkASSERT(pipelineState);
4249cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel            this->bindGeometry(primProc, *nonIdxMesh);
4259cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
4269cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel            if (nonIdxMesh->isIndexed()) {
4279cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                fCommandBuffer->drawIndexed(fGpu,
4289cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                                            nonIdxMesh->indexCount(),
4299cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                                            1,
4309cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                                            nonIdxMesh->startIndex(),
4319cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                                            nonIdxMesh->startVertex(),
4329cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                                            0);
4339cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel            } else {
4349cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                fCommandBuffer->draw(fGpu,
4359cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                                     nonIdxMesh->vertexCount(),
4369cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                                     1,
4379cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                                     nonIdxMesh->startVertex(),
4389cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                                     0);
4399cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel            }
4409cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel            fIsEmpty = false;
4419cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
4429cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel            fGpu->stats()->incNumDraws();
4439cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel        } while ((nonIdxMesh = iter.next()));
4449cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    }
4459cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
4469cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    // Technically we don't have to call this here (since there is a safety check in
4479cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    // pipelineState:setData but this will allow for quicker freeing of resources if the
4489cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    // pipelineState sits in a cache for a while.
4499cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    pipelineState->freeTempResources(fGpu);
450066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel}
451066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel
452