GrVkGpuCommandBuffer.cpp revision ab015efc48c462ffdffebb45c02cd19efb254983
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,
4289cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                                        const GrNonInstancedMesh& mesh) {
42922bc8653d704584e13f35844dafb5ddeb9989127Greg Daniel    CommandBufferInfo& cbInfo = fCommandBufferInfos[fCurrentCmdInfo];
4309cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    // There is no need to put any memory barriers to make sure host writes have finished here.
4319cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    // When a command buffer is submitted to a queue, there is an implicit memory barrier that
4329cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    // occurs for all host writes. Additionally, BufferMemoryBarriers are not allowed inside of
4339cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    // an active RenderPass.
434485a12003ab48b54965d6f7172f3183358919d8ecsmartdalton    SkASSERT(!mesh.vertexBuffer()->isCPUBacked());
4359cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    GrVkVertexBuffer* vbuf;
4369cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    vbuf = (GrVkVertexBuffer*)mesh.vertexBuffer();
4379cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    SkASSERT(vbuf);
4389cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    SkASSERT(!vbuf->isMapped());
4399cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
44022bc8653d704584e13f35844dafb5ddeb9989127Greg Daniel    cbInfo.currentCmdBuf()->bindVertexBuffer(fGpu, vbuf);
4419cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
4429cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    if (mesh.isIndexed()) {
443485a12003ab48b54965d6f7172f3183358919d8ecsmartdalton        SkASSERT(!mesh.indexBuffer()->isCPUBacked());
4449cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel        GrVkIndexBuffer* ibuf = (GrVkIndexBuffer*)mesh.indexBuffer();
4459cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel        SkASSERT(ibuf);
4469cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel        SkASSERT(!ibuf->isMapped());
4479cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
44822bc8653d704584e13f35844dafb5ddeb9989127Greg Daniel        cbInfo.currentCmdBuf()->bindIndexBuffer(fGpu, ibuf);
4499cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    }
4509cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel}
4519cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
4529cb6340a62a5d748e4189d50e51fa527c8c80c03egdanielsk_sp<GrVkPipelineState> GrVkGpuCommandBuffer::prepareDrawState(
4539cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                                                               const GrPipeline& pipeline,
4549cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                                                               const GrPrimitiveProcessor& primProc,
45536a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel                                                               GrPrimitiveType primitiveType) {
45622bc8653d704584e13f35844dafb5ddeb9989127Greg Daniel    CommandBufferInfo& cbInfo = fCommandBufferInfos[fCurrentCmdInfo];
45722bc8653d704584e13f35844dafb5ddeb9989127Greg Daniel    SkASSERT(cbInfo.fRenderPass);
45836a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel
4599cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    sk_sp<GrVkPipelineState> pipelineState =
4609cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel        fGpu->resourceProvider().findOrCreateCompatiblePipelineState(pipeline,
4619cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                                                                     primProc,
4629cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                                                                     primitiveType,
46336a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel                                                                     *cbInfo.fRenderPass);
4649cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    if (!pipelineState) {
4659cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel        return pipelineState;
4669cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    }
4679cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
46822bc8653d704584e13f35844dafb5ddeb9989127Greg Daniel    if (!cbInfo.fIsEmpty &&
46922bc8653d704584e13f35844dafb5ddeb9989127Greg Daniel        fLastPipelineState && fLastPipelineState != pipelineState.get() &&
47022bc8653d704584e13f35844dafb5ddeb9989127Greg Daniel        fGpu->vkCaps().newSecondaryCBOnPipelineChange()) {
47122bc8653d704584e13f35844dafb5ddeb9989127Greg Daniel        this->addAdditionalCommandBuffer();
47222bc8653d704584e13f35844dafb5ddeb9989127Greg Daniel    }
47322bc8653d704584e13f35844dafb5ddeb9989127Greg Daniel    fLastPipelineState = pipelineState.get();
47422bc8653d704584e13f35844dafb5ddeb9989127Greg Daniel
4759cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    pipelineState->setData(fGpu, primProc, pipeline);
4769cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
47722bc8653d704584e13f35844dafb5ddeb9989127Greg Daniel    pipelineState->bind(fGpu, cbInfo.currentCmdBuf());
4789cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
47922bc8653d704584e13f35844dafb5ddeb9989127Greg Daniel    GrVkPipeline::SetDynamicState(fGpu, cbInfo.currentCmdBuf(), pipeline);
4809cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
4819cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    return pipelineState;
4829cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel}
4839cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
48418dfa980765bee6a1ce7c5f430cb32f487da6590Brian Salomonstatic void set_texture_layout(GrVkTexture* vkTexture, GrVkGpu* gpu) {
48518dfa980765bee6a1ce7c5f430cb32f487da6590Brian Salomon    // TODO: If we ever decide to create the secondary command buffers ahead of time before we
48618dfa980765bee6a1ce7c5f430cb32f487da6590Brian Salomon    // are actually going to submit them, we will need to track the sampled images and delay
48718dfa980765bee6a1ce7c5f430cb32f487da6590Brian Salomon    // adding the layout change/barrier until we are ready to submit.
48818dfa980765bee6a1ce7c5f430cb32f487da6590Brian Salomon    vkTexture->setImageLayout(gpu,
48918dfa980765bee6a1ce7c5f430cb32f487da6590Brian Salomon                              VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
49018dfa980765bee6a1ce7c5f430cb32f487da6590Brian Salomon                              VK_ACCESS_SHADER_READ_BIT,
49118dfa980765bee6a1ce7c5f430cb32f487da6590Brian Salomon                              VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT,
49218dfa980765bee6a1ce7c5f430cb32f487da6590Brian Salomon                              false);
49318dfa980765bee6a1ce7c5f430cb32f487da6590Brian Salomon}
49418dfa980765bee6a1ce7c5f430cb32f487da6590Brian Salomon
495ab015efc48c462ffdffebb45c02cd19efb254983Brian Salomonstatic void prepare_sampled_images(const GrResourceIOProcessor& processor, GrVkGpu* gpu) {
4960bbecb21ab82b3d742c491780bcc2e74be03efedBrian Salomon    for (int i = 0; i < processor.numTextureSamplers(); ++i) {
497ab015efc48c462ffdffebb45c02cd19efb254983Brian Salomon        const GrResourceIOProcessor::TextureSampler& sampler = processor.textureSampler(i);
498db4183d227b764b219e9e314dd5387ded4c38797Brian Salomon        GrVkTexture* vkTexture = static_cast<GrVkTexture*>(sampler.texture());
4998d2141f0dbb36b92d0e3feb23a08663c29b59db0egdaniel        SkASSERT(vkTexture);
50066933552f1723c4a2b248711ab3d43921401e8e6egdaniel
5018d2141f0dbb36b92d0e3feb23a08663c29b59db0egdaniel        // We may need to resolve the texture first if it is also a render target
5028d2141f0dbb36b92d0e3feb23a08663c29b59db0egdaniel        GrVkRenderTarget* texRT = static_cast<GrVkRenderTarget*>(vkTexture->asRenderTarget());
5038d2141f0dbb36b92d0e3feb23a08663c29b59db0egdaniel        if (texRT) {
5048d2141f0dbb36b92d0e3feb23a08663c29b59db0egdaniel            gpu->onResolveRenderTarget(texRT);
5058d2141f0dbb36b92d0e3feb23a08663c29b59db0egdaniel        }
5069cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
507514baff8be7f71111aa7bfb9b099a096b31e16ecBrian Salomon        const GrSamplerParams& params = sampler.params();
5088d2141f0dbb36b92d0e3feb23a08663c29b59db0egdaniel        // Check if we need to regenerate any mip maps
509514baff8be7f71111aa7bfb9b099a096b31e16ecBrian Salomon        if (GrSamplerParams::kMipMap_FilterMode == params.filterMode()) {
5108d2141f0dbb36b92d0e3feb23a08663c29b59db0egdaniel            if (vkTexture->texturePriv().mipMapsAreDirty()) {
5118d2141f0dbb36b92d0e3feb23a08663c29b59db0egdaniel                gpu->generateMipmap(vkTexture);
5128d2141f0dbb36b92d0e3feb23a08663c29b59db0egdaniel                vkTexture->texturePriv().dirtyMipMaps(false);
5138d2141f0dbb36b92d0e3feb23a08663c29b59db0egdaniel            }
5148d2141f0dbb36b92d0e3feb23a08663c29b59db0egdaniel        }
51518dfa980765bee6a1ce7c5f430cb32f487da6590Brian Salomon        set_texture_layout(vkTexture, gpu);
5169cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    }
5179cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel}
5189cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
5199cb6340a62a5d748e4189d50e51fa527c8c80c03egdanielvoid GrVkGpuCommandBuffer::onDraw(const GrPipeline& pipeline,
5209cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                                  const GrPrimitiveProcessor& primProc,
5219cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                                  const GrMesh* meshes,
52236a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel                                  int meshCount,
52336a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel                                  const SkRect& bounds) {
524c293a29bc2fced15ac44a66efa813d42cb3f2e0bBrian Salomon    GrVkRenderTarget* target = static_cast<GrVkRenderTarget*>(pipeline.getRenderTarget());
525c293a29bc2fced15ac44a66efa813d42cb3f2e0bBrian Salomon    if (!fRenderTarget) {
526c293a29bc2fced15ac44a66efa813d42cb3f2e0bBrian Salomon        this->init(target);
527c293a29bc2fced15ac44a66efa813d42cb3f2e0bBrian Salomon    }
528c293a29bc2fced15ac44a66efa813d42cb3f2e0bBrian Salomon    SkASSERT(target == fRenderTarget);
529c293a29bc2fced15ac44a66efa813d42cb3f2e0bBrian Salomon
5309cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    if (!meshCount) {
5319cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel        return;
5329cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    }
5338d2141f0dbb36b92d0e3feb23a08663c29b59db0egdaniel    prepare_sampled_images(primProc, fGpu);
534b58a2b4919aa67ab5bab1d497f26671d704654b4bsalomon    GrFragmentProcessor::Iter iter(pipeline);
535b58a2b4919aa67ab5bab1d497f26671d704654b4bsalomon    while (const GrFragmentProcessor* fp = iter.next()) {
536b58a2b4919aa67ab5bab1d497f26671d704654b4bsalomon        prepare_sampled_images(*fp, fGpu);
5372f5792a06c87efd5f9295b7b7bb714aac118bd2aegdaniel    }
53818dfa980765bee6a1ce7c5f430cb32f487da6590Brian Salomon    if (GrVkTexture* dstTexture = static_cast<GrVkTexture*>(pipeline.dstTexture())) {
53918dfa980765bee6a1ce7c5f430cb32f487da6590Brian Salomon        set_texture_layout(dstTexture, fGpu);
54018dfa980765bee6a1ce7c5f430cb32f487da6590Brian Salomon    }
5412f5792a06c87efd5f9295b7b7bb714aac118bd2aegdaniel
5429cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    GrPrimitiveType primitiveType = meshes[0].primitiveType();
5439cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    sk_sp<GrVkPipelineState> pipelineState = this->prepareDrawState(pipeline,
5449cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                                                                    primProc,
54536a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel                                                                    primitiveType);
5469cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    if (!pipelineState) {
5479cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel        return;
5489cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    }
5499cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
55022bc8653d704584e13f35844dafb5ddeb9989127Greg Daniel    CommandBufferInfo& cbInfo = fCommandBufferInfos[fCurrentCmdInfo];
55122bc8653d704584e13f35844dafb5ddeb9989127Greg Daniel
5529cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    for (int i = 0; i < meshCount; ++i) {
5539cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel        const GrMesh& mesh = meshes[i];
5549cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel        GrMesh::Iterator iter;
5559cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel        const GrNonInstancedMesh* nonIdxMesh = iter.init(mesh);
5569cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel        do {
5579cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel            if (nonIdxMesh->primitiveType() != primitiveType) {
5589cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                // Technically we don't have to call this here (since there is a safety check in
5599cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                // pipelineState:setData but this will allow for quicker freeing of resources if the
5609cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                // pipelineState sits in a cache for a while.
5619cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                pipelineState->freeTempResources(fGpu);
5629cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                SkDEBUGCODE(pipelineState = nullptr);
5639cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                primitiveType = nonIdxMesh->primitiveType();
5649cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                pipelineState = this->prepareDrawState(pipeline,
5659cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                                                       primProc,
56636a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel                                                       primitiveType);
5679cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                if (!pipelineState) {
5689cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                    return;
5699cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                }
5709cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel            }
5719cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel            SkASSERT(pipelineState);
5729cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel            this->bindGeometry(primProc, *nonIdxMesh);
5739cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
5749cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel            if (nonIdxMesh->isIndexed()) {
57522bc8653d704584e13f35844dafb5ddeb9989127Greg Daniel                cbInfo.currentCmdBuf()->drawIndexed(fGpu,
57636a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel                                                   nonIdxMesh->indexCount(),
57736a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel                                                   1,
57836a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel                                                   nonIdxMesh->startIndex(),
57936a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel                                                   nonIdxMesh->startVertex(),
58036a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel                                                   0);
58136a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel            } else {
58222bc8653d704584e13f35844dafb5ddeb9989127Greg Daniel                cbInfo.currentCmdBuf()->draw(fGpu,
58336a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel                                            nonIdxMesh->vertexCount(),
5849cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                                            1,
5859cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                                            nonIdxMesh->startVertex(),
5869cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                                            0);
5879cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel            }
58877b53f66bacd9a1d1c9df7d879a419b2abe069baGreg Daniel            cbInfo.fIsEmpty = false;
5899cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
5909cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel            fGpu->stats()->incNumDraws();
5919cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel        } while ((nonIdxMesh = iter.next()));
5929cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    }
5939cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
59436a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel    // Update command buffer bounds
59536a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel    cbInfo.fBounds.join(bounds);
59636a77ee494791989548b717515e3621b9c4ffe4eGreg Daniel
5979cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    // Technically we don't have to call this here (since there is a safety check in
5989cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    // pipelineState:setData but this will allow for quicker freeing of resources if the
5999cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    // pipelineState sits in a cache for a while.
6009cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel    pipelineState->freeTempResources(fGpu);
601066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel}
602066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel
603