GrVkGpuCommandBuffer.cpp revision 8d2141f0dbb36b92d0e3feb23a08663c29b59db0
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.
1068d2141f0dbb36b92d0e3feb23a08663c29b59db0egdaniel    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    fGpu->submitSecondaryCommandBuffer(fCommandBuffer, fRenderPass, &fColorClearValue,
1269cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                                       fRenderTarget, bounds);
1279cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel}
1289cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
12937535c9ecef67a56cad293535f8626b1d60f7c08egdanielvoid GrVkGpuCommandBuffer::discard(GrRenderTarget* target) {
13037535c9ecef67a56cad293535f8626b1d60f7c08egdaniel    if (fIsEmpty) {
13137535c9ecef67a56cad293535f8626b1d60f7c08egdaniel        // We will change the render pass to do a clear load instead
13237535c9ecef67a56cad293535f8626b1d60f7c08egdaniel        GrVkRenderPass::LoadStoreOps vkColorOps(VK_ATTACHMENT_LOAD_OP_DONT_CARE,
13337535c9ecef67a56cad293535f8626b1d60f7c08egdaniel                                                VK_ATTACHMENT_STORE_OP_STORE);
13437535c9ecef67a56cad293535f8626b1d60f7c08egdaniel        GrVkRenderPass::LoadStoreOps vkStencilOps(VK_ATTACHMENT_LOAD_OP_DONT_CARE,
13537535c9ecef67a56cad293535f8626b1d60f7c08egdaniel                                                  VK_ATTACHMENT_STORE_OP_STORE);
13637535c9ecef67a56cad293535f8626b1d60f7c08egdaniel        GrVkRenderPass::LoadStoreOps vkResolveOps(VK_ATTACHMENT_LOAD_OP_DONT_CARE,
13737535c9ecef67a56cad293535f8626b1d60f7c08egdaniel                                                  VK_ATTACHMENT_STORE_OP_STORE);
13837535c9ecef67a56cad293535f8626b1d60f7c08egdaniel
13937535c9ecef67a56cad293535f8626b1d60f7c08egdaniel        const GrVkRenderPass* oldRP = fRenderPass;
14037535c9ecef67a56cad293535f8626b1d60f7c08egdaniel
14137535c9ecef67a56cad293535f8626b1d60f7c08egdaniel        GrVkRenderTarget* vkRT = static_cast<GrVkRenderTarget*>(target);
14237535c9ecef67a56cad293535f8626b1d60f7c08egdaniel        const GrVkResourceProvider::CompatibleRPHandle& rpHandle =
14337535c9ecef67a56cad293535f8626b1d60f7c08egdaniel            vkRT->compatibleRenderPassHandle();
14437535c9ecef67a56cad293535f8626b1d60f7c08egdaniel        if (rpHandle.isValid()) {
14537535c9ecef67a56cad293535f8626b1d60f7c08egdaniel            fRenderPass = fGpu->resourceProvider().findRenderPass(rpHandle,
14637535c9ecef67a56cad293535f8626b1d60f7c08egdaniel                                                                  vkColorOps,
14737535c9ecef67a56cad293535f8626b1d60f7c08egdaniel                                                                  vkResolveOps,
14837535c9ecef67a56cad293535f8626b1d60f7c08egdaniel                                                                  vkStencilOps);
14937535c9ecef67a56cad293535f8626b1d60f7c08egdaniel        } else {
15037535c9ecef67a56cad293535f8626b1d60f7c08egdaniel            fRenderPass = fGpu->resourceProvider().findRenderPass(*vkRT,
15137535c9ecef67a56cad293535f8626b1d60f7c08egdaniel                                                                  vkColorOps,
15237535c9ecef67a56cad293535f8626b1d60f7c08egdaniel                                                                  vkResolveOps,
15337535c9ecef67a56cad293535f8626b1d60f7c08egdaniel                                                                  vkStencilOps);
15437535c9ecef67a56cad293535f8626b1d60f7c08egdaniel        }
15537535c9ecef67a56cad293535f8626b1d60f7c08egdaniel
15637535c9ecef67a56cad293535f8626b1d60f7c08egdaniel        SkASSERT(fRenderPass->isCompatible(*oldRP));
15737535c9ecef67a56cad293535f8626b1d60f7c08egdaniel        oldRP->unref(fGpu);
15837535c9ecef67a56cad293535f8626b1d60f7c08egdaniel    }
15937535c9ecef67a56cad293535f8626b1d60f7c08egdaniel}
16037535c9ecef67a56cad293535f8626b1d60f7c08egdaniel
1619cb6340a62a5d748e4189d50e51fa527c8c80c03egdanielvoid GrVkGpuCommandBuffer::onClearStencilClip(GrRenderTarget* target,
16229df76096fd30941086324902a82656df2d8becdcsmartdalton                                              const GrFixedClip& clip,
16329df76096fd30941086324902a82656df2d8becdcsmartdalton                                              bool insideStencilMask) {
1649cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    SkASSERT(target);
1659cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
1669cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    GrVkRenderTarget* vkRT = static_cast<GrVkRenderTarget*>(target);
1679cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    GrStencilAttachment* sb = target->renderTargetPriv().getStencilAttachment();
1689cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    // this should only be called internally when we know we have a
1699cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    // stencil buffer.
1709cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    SkASSERT(sb);
1719cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    int stencilBitCount = sb->bits();
1729cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
1739cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    // The contract with the callers does not guarantee that we preserve all bits in the stencil
1749cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    // during this clear. Thus we will clear the entire stencil to the desired value.
1759cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
1769cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    VkClearDepthStencilValue vkStencilColor;
1779cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    memset(&vkStencilColor, 0, sizeof(VkClearDepthStencilValue));
17829df76096fd30941086324902a82656df2d8becdcsmartdalton    if (insideStencilMask) {
1799cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel        vkStencilColor.stencil = (1 << (stencilBitCount - 1));
1809cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    } else {
1819cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel        vkStencilColor.stencil = 0;
1829cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    }
1839cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
1849cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    VkClearRect clearRect;
1859cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    // Flip rect if necessary
18629df76096fd30941086324902a82656df2d8becdcsmartdalton    SkIRect vkRect;
18729df76096fd30941086324902a82656df2d8becdcsmartdalton    if (!clip.scissorEnabled()) {
18829df76096fd30941086324902a82656df2d8becdcsmartdalton        vkRect.setXYWH(0, 0, vkRT->width(), vkRT->height());
18929df76096fd30941086324902a82656df2d8becdcsmartdalton    } else if (kBottomLeft_GrSurfaceOrigin != vkRT->origin()) {
19029df76096fd30941086324902a82656df2d8becdcsmartdalton        vkRect = clip.scissorRect();
19129df76096fd30941086324902a82656df2d8becdcsmartdalton    } else {
19229df76096fd30941086324902a82656df2d8becdcsmartdalton        const SkIRect& scissor = clip.scissorRect();
19329df76096fd30941086324902a82656df2d8becdcsmartdalton        vkRect.setLTRB(scissor.fLeft, vkRT->height() - scissor.fBottom,
19429df76096fd30941086324902a82656df2d8becdcsmartdalton                       scissor.fRight, vkRT->height() - scissor.fTop);
1959cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    }
1969cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
1979cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    clearRect.rect.offset = { vkRect.fLeft, vkRect.fTop };
1989cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    clearRect.rect.extent = { (uint32_t)vkRect.width(), (uint32_t)vkRect.height() };
1999cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
2009cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    clearRect.baseArrayLayer = 0;
2019cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    clearRect.layerCount = 1;
2029cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
2039cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    uint32_t stencilIndex;
2049cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    SkAssertResult(fRenderPass->stencilAttachmentIndex(&stencilIndex));
2059cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
2069cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    VkClearAttachment attachment;
2079cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    attachment.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT;
2089cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    attachment.colorAttachment = 0; // this value shouldn't matter
2099cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    attachment.clearValue.depthStencil = vkStencilColor;
2109cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
2119cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    fCommandBuffer->clearAttachments(fGpu, 1, &attachment, 1, &clearRect);
2129cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    fIsEmpty = false;
2139cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel}
2149cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
21529df76096fd30941086324902a82656df2d8becdcsmartdaltonvoid GrVkGpuCommandBuffer::onClear(GrRenderTarget* target, const GrFixedClip& clip, GrColor color) {
2169cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    // parent class should never let us get here with no RT
2179cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    SkASSERT(target);
2189cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
2199cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    VkClearColorValue vkColor;
2209cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    GrColorToRGBAFloat(color, vkColor.float32);
2219cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
2229cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    GrVkRenderTarget* vkRT = static_cast<GrVkRenderTarget*>(target);
2239cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
22429df76096fd30941086324902a82656df2d8becdcsmartdalton    if (fIsEmpty && !clip.scissorEnabled()) {
2259cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel        // We will change the render pass to do a clear load instead
2269cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel        GrVkRenderPass::LoadStoreOps vkColorOps(VK_ATTACHMENT_LOAD_OP_CLEAR,
2279cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                                                VK_ATTACHMENT_STORE_OP_STORE);
2289cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel        GrVkRenderPass::LoadStoreOps vkStencilOps(VK_ATTACHMENT_LOAD_OP_LOAD,
2299cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                                                  VK_ATTACHMENT_STORE_OP_STORE);
2309cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel        GrVkRenderPass::LoadStoreOps vkResolveOps(VK_ATTACHMENT_LOAD_OP_LOAD,
2319cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                                                  VK_ATTACHMENT_STORE_OP_STORE);
2329cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
2339cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel        const GrVkRenderPass* oldRP = fRenderPass;
2349cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
2359cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel        const GrVkResourceProvider::CompatibleRPHandle& rpHandle =
2369cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel            vkRT->compatibleRenderPassHandle();
2379cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel        if (rpHandle.isValid()) {
2389cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel            fRenderPass = fGpu->resourceProvider().findRenderPass(rpHandle,
2399cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                                                                  vkColorOps,
2409cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                                                                  vkResolveOps,
2419cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                                                                  vkStencilOps);
2429cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel        } else {
2439cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel            fRenderPass = fGpu->resourceProvider().findRenderPass(*vkRT,
2449cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                                                                  vkColorOps,
2459cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                                                                  vkResolveOps,
2469cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                                                                  vkStencilOps);
2479cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel        }
2489cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
2499cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel        SkASSERT(fRenderPass->isCompatible(*oldRP));
2509cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel        oldRP->unref(fGpu);
2519cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
2529cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel        GrColorToRGBAFloat(color, fColorClearValue.color.float32);
2539cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel        return;
2549cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    }
2559cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
2569cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    // We always do a sub rect clear with clearAttachments since we are inside a render pass
2579cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    VkClearRect clearRect;
2589cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    // Flip rect if necessary
25929df76096fd30941086324902a82656df2d8becdcsmartdalton    SkIRect vkRect;
26029df76096fd30941086324902a82656df2d8becdcsmartdalton    if (!clip.scissorEnabled()) {
26129df76096fd30941086324902a82656df2d8becdcsmartdalton        vkRect.setXYWH(0, 0, vkRT->width(), vkRT->height());
26229df76096fd30941086324902a82656df2d8becdcsmartdalton    } else if (kBottomLeft_GrSurfaceOrigin != vkRT->origin()) {
26329df76096fd30941086324902a82656df2d8becdcsmartdalton        vkRect = clip.scissorRect();
26429df76096fd30941086324902a82656df2d8becdcsmartdalton    } else {
26529df76096fd30941086324902a82656df2d8becdcsmartdalton        const SkIRect& scissor = clip.scissorRect();
26629df76096fd30941086324902a82656df2d8becdcsmartdalton        vkRect.setLTRB(scissor.fLeft, vkRT->height() - scissor.fBottom,
26729df76096fd30941086324902a82656df2d8becdcsmartdalton                       scissor.fRight, vkRT->height() - scissor.fTop);
2689cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    }
2699cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    clearRect.rect.offset = { vkRect.fLeft, vkRect.fTop };
2709cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    clearRect.rect.extent = { (uint32_t)vkRect.width(), (uint32_t)vkRect.height() };
2719cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    clearRect.baseArrayLayer = 0;
2729cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    clearRect.layerCount = 1;
2739cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
2749cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    uint32_t colorIndex;
2759cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    SkAssertResult(fRenderPass->colorAttachmentIndex(&colorIndex));
2769cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
2779cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    VkClearAttachment attachment;
2789cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    attachment.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
2799cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    attachment.colorAttachment = colorIndex;
2809cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    attachment.clearValue.color = vkColor;
2819cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
2829cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    fCommandBuffer->clearAttachments(fGpu, 1, &attachment, 1, &clearRect);
2839cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    fIsEmpty = false;
2849cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    return;
2859cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel}
2869cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
2879cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel////////////////////////////////////////////////////////////////////////////////
2889cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
2899cb6340a62a5d748e4189d50e51fa527c8c80c03egdanielvoid GrVkGpuCommandBuffer::bindGeometry(const GrPrimitiveProcessor& primProc,
2909cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                                        const GrNonInstancedMesh& mesh) {
2919cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    // There is no need to put any memory barriers to make sure host writes have finished here.
2929cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    // When a command buffer is submitted to a queue, there is an implicit memory barrier that
2939cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    // occurs for all host writes. Additionally, BufferMemoryBarriers are not allowed inside of
2949cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    // an active RenderPass.
295485a12003ab48b54965d6f7172f3183358919d8ecsmartdalton    SkASSERT(!mesh.vertexBuffer()->isCPUBacked());
2969cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    GrVkVertexBuffer* vbuf;
2979cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    vbuf = (GrVkVertexBuffer*)mesh.vertexBuffer();
2989cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    SkASSERT(vbuf);
2999cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    SkASSERT(!vbuf->isMapped());
3009cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
3019cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    fCommandBuffer->bindVertexBuffer(fGpu, vbuf);
3029cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
3039cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    if (mesh.isIndexed()) {
304485a12003ab48b54965d6f7172f3183358919d8ecsmartdalton        SkASSERT(!mesh.indexBuffer()->isCPUBacked());
3059cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel        GrVkIndexBuffer* ibuf = (GrVkIndexBuffer*)mesh.indexBuffer();
3069cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel        SkASSERT(ibuf);
3079cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel        SkASSERT(!ibuf->isMapped());
3089cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
3099cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel        fCommandBuffer->bindIndexBuffer(fGpu, ibuf);
3109cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    }
3119cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel}
3129cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
3139cb6340a62a5d748e4189d50e51fa527c8c80c03egdanielsk_sp<GrVkPipelineState> GrVkGpuCommandBuffer::prepareDrawState(
3149cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                                                               const GrPipeline& pipeline,
3159cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                                                               const GrPrimitiveProcessor& primProc,
3169cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                                                               GrPrimitiveType primitiveType,
3179cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                                                               const GrVkRenderPass& renderPass) {
3189cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    sk_sp<GrVkPipelineState> pipelineState =
3199cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel        fGpu->resourceProvider().findOrCreateCompatiblePipelineState(pipeline,
3209cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                                                                     primProc,
3219cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                                                                     primitiveType,
3229cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                                                                     renderPass);
3239cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    if (!pipelineState) {
3249cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel        return pipelineState;
3259cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    }
3269cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
3279cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    pipelineState->setData(fGpu, primProc, pipeline);
3289cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
3299cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    pipelineState->bind(fGpu, fCommandBuffer);
3309cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
3319cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    GrVkPipeline::SetDynamicState(fGpu, fCommandBuffer, pipeline);
3329cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
3339cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    return pipelineState;
3349cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel}
3359cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
3368d2141f0dbb36b92d0e3feb23a08663c29b59db0egdanielstatic void prepare_sampled_images(const GrProcessor& processor, GrVkGpu* gpu) {
3378d2141f0dbb36b92d0e3feb23a08663c29b59db0egdaniel    for (int i = 0; i < processor.numTextures(); ++i) {
3388d2141f0dbb36b92d0e3feb23a08663c29b59db0egdaniel        const GrTextureAccess& texAccess = processor.textureAccess(i);
3398d2141f0dbb36b92d0e3feb23a08663c29b59db0egdaniel        GrVkTexture* vkTexture = static_cast<GrVkTexture*>(processor.texture(i));
3408d2141f0dbb36b92d0e3feb23a08663c29b59db0egdaniel        SkASSERT(vkTexture);
34166933552f1723c4a2b248711ab3d43921401e8e6egdaniel
3428d2141f0dbb36b92d0e3feb23a08663c29b59db0egdaniel        // We may need to resolve the texture first if it is also a render target
3438d2141f0dbb36b92d0e3feb23a08663c29b59db0egdaniel        GrVkRenderTarget* texRT = static_cast<GrVkRenderTarget*>(vkTexture->asRenderTarget());
3448d2141f0dbb36b92d0e3feb23a08663c29b59db0egdaniel        if (texRT) {
3458d2141f0dbb36b92d0e3feb23a08663c29b59db0egdaniel            gpu->onResolveRenderTarget(texRT);
3468d2141f0dbb36b92d0e3feb23a08663c29b59db0egdaniel        }
3479cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
3488d2141f0dbb36b92d0e3feb23a08663c29b59db0egdaniel        const GrTextureParams& params = texAccess.getParams();
3498d2141f0dbb36b92d0e3feb23a08663c29b59db0egdaniel        // Check if we need to regenerate any mip maps
3508d2141f0dbb36b92d0e3feb23a08663c29b59db0egdaniel        if (GrTextureParams::kMipMap_FilterMode == params.filterMode()) {
3518d2141f0dbb36b92d0e3feb23a08663c29b59db0egdaniel            if (vkTexture->texturePriv().mipMapsAreDirty()) {
3528d2141f0dbb36b92d0e3feb23a08663c29b59db0egdaniel                gpu->generateMipmap(vkTexture);
3538d2141f0dbb36b92d0e3feb23a08663c29b59db0egdaniel                vkTexture->texturePriv().dirtyMipMaps(false);
3548d2141f0dbb36b92d0e3feb23a08663c29b59db0egdaniel            }
3558d2141f0dbb36b92d0e3feb23a08663c29b59db0egdaniel        }
3569cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
3578d2141f0dbb36b92d0e3feb23a08663c29b59db0egdaniel        // TODO: If we ever decide to create the secondary command buffers ahead of time before we
3588d2141f0dbb36b92d0e3feb23a08663c29b59db0egdaniel        // are actually going to submit them, we will need to track the sampled images and delay
3598d2141f0dbb36b92d0e3feb23a08663c29b59db0egdaniel        // adding the layout change/barrier until we are ready to submit.
3608d2141f0dbb36b92d0e3feb23a08663c29b59db0egdaniel        vkTexture->setImageLayout(gpu,
3618d2141f0dbb36b92d0e3feb23a08663c29b59db0egdaniel                                  VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
3628d2141f0dbb36b92d0e3feb23a08663c29b59db0egdaniel                                  VK_ACCESS_SHADER_READ_BIT,
3638d2141f0dbb36b92d0e3feb23a08663c29b59db0egdaniel                                  VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT,
3648d2141f0dbb36b92d0e3feb23a08663c29b59db0egdaniel                                  false);
3659cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    }
3669cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel}
3679cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
3689cb6340a62a5d748e4189d50e51fa527c8c80c03egdanielvoid GrVkGpuCommandBuffer::onDraw(const GrPipeline& pipeline,
3699cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                                  const GrPrimitiveProcessor& primProc,
3709cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                                  const GrMesh* meshes,
3719cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                                  int meshCount) {
3729cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    if (!meshCount) {
3739cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel        return;
3749cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    }
3759cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    GrRenderTarget* rt = pipeline.getRenderTarget();
3769cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    GrVkRenderTarget* vkRT = static_cast<GrVkRenderTarget*>(rt);
3779cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    const GrVkRenderPass* renderPass = vkRT->simpleRenderPass();
3789cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    SkASSERT(renderPass);
3799cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
3808d2141f0dbb36b92d0e3feb23a08663c29b59db0egdaniel    prepare_sampled_images(primProc, fGpu);
3812f5792a06c87efd5f9295b7b7bb714aac118bd2aegdaniel    for (int i = 0; i < pipeline.numFragmentProcessors(); ++i) {
3828d2141f0dbb36b92d0e3feb23a08663c29b59db0egdaniel        prepare_sampled_images(pipeline.getFragmentProcessor(i), fGpu);
3832f5792a06c87efd5f9295b7b7bb714aac118bd2aegdaniel    }
3848d2141f0dbb36b92d0e3feb23a08663c29b59db0egdaniel    prepare_sampled_images(pipeline.getXferProcessor(), fGpu);
3852f5792a06c87efd5f9295b7b7bb714aac118bd2aegdaniel
3869cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    GrPrimitiveType primitiveType = meshes[0].primitiveType();
3879cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    sk_sp<GrVkPipelineState> pipelineState = this->prepareDrawState(pipeline,
3889cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                                                                    primProc,
3899cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                                                                    primitiveType,
3909cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                                                                    *renderPass);
3919cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    if (!pipelineState) {
3929cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel        return;
3939cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    }
3949cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
3959cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    for (int i = 0; i < meshCount; ++i) {
3969cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel        const GrMesh& mesh = meshes[i];
3979cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel        GrMesh::Iterator iter;
3989cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel        const GrNonInstancedMesh* nonIdxMesh = iter.init(mesh);
3999cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel        do {
4009cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel            if (nonIdxMesh->primitiveType() != primitiveType) {
4019cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                // Technically we don't have to call this here (since there is a safety check in
4029cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                // pipelineState:setData but this will allow for quicker freeing of resources if the
4039cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                // pipelineState sits in a cache for a while.
4049cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                pipelineState->freeTempResources(fGpu);
4059cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                SkDEBUGCODE(pipelineState = nullptr);
4069cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                primitiveType = nonIdxMesh->primitiveType();
4079cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                pipelineState = this->prepareDrawState(pipeline,
4089cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                                                       primProc,
4099cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                                                       primitiveType,
4109cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                                                       *renderPass);
4119cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                if (!pipelineState) {
4129cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                    return;
4139cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                }
4149cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel            }
4159cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel            SkASSERT(pipelineState);
4169cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel            this->bindGeometry(primProc, *nonIdxMesh);
4179cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
4189cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel            if (nonIdxMesh->isIndexed()) {
4199cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                fCommandBuffer->drawIndexed(fGpu,
4209cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                                            nonIdxMesh->indexCount(),
4219cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                                            1,
4229cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                                            nonIdxMesh->startIndex(),
4239cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                                            nonIdxMesh->startVertex(),
4249cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                                            0);
4259cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel            } else {
4269cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                fCommandBuffer->draw(fGpu,
4279cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                                     nonIdxMesh->vertexCount(),
4289cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                                     1,
4299cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                                     nonIdxMesh->startVertex(),
4309cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                                     0);
4319cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel            }
4329cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel            fIsEmpty = false;
4339cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
4349cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel            fGpu->stats()->incNumDraws();
4359cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel        } while ((nonIdxMesh = iter.next()));
4369cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    }
4379cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
4389cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    // Technically we don't have to call this here (since there is a safety check in
4399cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    // pipelineState:setData but this will allow for quicker freeing of resources if the
4409cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    // pipelineState sits in a cache for a while.
4419cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    pipelineState->freeTempResources(fGpu);
442066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel}
443066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel
444