1cb93a386Sopenharmony_ci/*
2cb93a386Sopenharmony_ci * Copyright 2015 Google Inc.
3cb93a386Sopenharmony_ci *
4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be
5cb93a386Sopenharmony_ci * found in the LICENSE file.
6cb93a386Sopenharmony_ci */
7cb93a386Sopenharmony_ci
8cb93a386Sopenharmony_ci#include "src/gpu/vk/GrVkRenderTarget.h"
9cb93a386Sopenharmony_ci
10cb93a386Sopenharmony_ci#include "include/gpu/GrBackendSurface.h"
11cb93a386Sopenharmony_ci#include "include/gpu/GrDirectContext.h"
12cb93a386Sopenharmony_ci#include "src/gpu/GrBackendSurfaceMutableStateImpl.h"
13cb93a386Sopenharmony_ci#include "src/gpu/GrDirectContextPriv.h"
14cb93a386Sopenharmony_ci#include "src/gpu/GrResourceProvider.h"
15cb93a386Sopenharmony_ci#include "src/gpu/vk/GrVkCommandBuffer.h"
16cb93a386Sopenharmony_ci#include "src/gpu/vk/GrVkDescriptorSet.h"
17cb93a386Sopenharmony_ci#include "src/gpu/vk/GrVkFramebuffer.h"
18cb93a386Sopenharmony_ci#include "src/gpu/vk/GrVkGpu.h"
19cb93a386Sopenharmony_ci#include "src/gpu/vk/GrVkImageView.h"
20cb93a386Sopenharmony_ci#include "src/gpu/vk/GrVkResourceProvider.h"
21cb93a386Sopenharmony_ci#include "src/gpu/vk/GrVkUtil.h"
22cb93a386Sopenharmony_ci
23cb93a386Sopenharmony_ci#include "include/gpu/vk/GrVkTypes.h"
24cb93a386Sopenharmony_ci
25cb93a386Sopenharmony_ci#define VK_CALL(GPU, X) GR_VK_CALL(GPU->vkInterface(), X)
26cb93a386Sopenharmony_ci
27cb93a386Sopenharmony_cistatic int renderpass_features_to_index(bool hasResolve, bool hasStencil,
28cb93a386Sopenharmony_ci                                        GrVkRenderPass::SelfDependencyFlags selfDepFlags,
29cb93a386Sopenharmony_ci                                        GrVkRenderPass::LoadFromResolve loadFromReslove) {
30cb93a386Sopenharmony_ci    int index = 0;
31cb93a386Sopenharmony_ci    if (hasResolve) {
32cb93a386Sopenharmony_ci        index += 1;
33cb93a386Sopenharmony_ci    }
34cb93a386Sopenharmony_ci    if (hasStencil) {
35cb93a386Sopenharmony_ci        index += 2;
36cb93a386Sopenharmony_ci    }
37cb93a386Sopenharmony_ci    if (selfDepFlags & GrVkRenderPass::SelfDependencyFlags::kForInputAttachment) {
38cb93a386Sopenharmony_ci        index += 4;
39cb93a386Sopenharmony_ci    }
40cb93a386Sopenharmony_ci    if (selfDepFlags & GrVkRenderPass::SelfDependencyFlags::kForNonCoherentAdvBlend) {
41cb93a386Sopenharmony_ci        index += 8;
42cb93a386Sopenharmony_ci    }
43cb93a386Sopenharmony_ci    if (loadFromReslove == GrVkRenderPass::LoadFromResolve::kLoad) {
44cb93a386Sopenharmony_ci        index += 16;
45cb93a386Sopenharmony_ci    }
46cb93a386Sopenharmony_ci    return index;
47cb93a386Sopenharmony_ci}
48cb93a386Sopenharmony_ci
49cb93a386Sopenharmony_ci// We're virtually derived from GrSurface (via GrRenderTarget) so its
50cb93a386Sopenharmony_ci// constructor must be explicitly called.
51cb93a386Sopenharmony_ciGrVkRenderTarget::GrVkRenderTarget(GrVkGpu* gpu,
52cb93a386Sopenharmony_ci                                   SkISize dimensions,
53cb93a386Sopenharmony_ci                                   sk_sp<GrVkImage> colorAttachment,
54cb93a386Sopenharmony_ci                                   sk_sp<GrVkImage> resolveAttachment,
55cb93a386Sopenharmony_ci                                   CreateType createType)
56cb93a386Sopenharmony_ci        : GrSurface(gpu, dimensions,
57cb93a386Sopenharmony_ci                    colorAttachment->isProtected() ? GrProtected::kYes : GrProtected::kNo)
58cb93a386Sopenharmony_ci        // for the moment we only support 1:1 color to stencil
59cb93a386Sopenharmony_ci        , GrRenderTarget(gpu, dimensions, colorAttachment->numSamples(),
60cb93a386Sopenharmony_ci                         colorAttachment->isProtected() ? GrProtected::kYes : GrProtected::kNo)
61cb93a386Sopenharmony_ci        , fColorAttachment(std::move(colorAttachment))
62cb93a386Sopenharmony_ci        , fResolveAttachment(std::move(resolveAttachment))
63cb93a386Sopenharmony_ci        , fCachedFramebuffers() {
64cb93a386Sopenharmony_ci    SkASSERT(fColorAttachment);
65cb93a386Sopenharmony_ci
66cb93a386Sopenharmony_ci    if (fColorAttachment->numSamples() == 1 && fColorAttachment->supportsInputAttachmentUsage()) {
67cb93a386Sopenharmony_ci        SkASSERT(!resolveAttachment);
68cb93a386Sopenharmony_ci        // When we have a single sampled color attachment, we set both the color and resolve
69cb93a386Sopenharmony_ci        // to the same attachment. This way if we use DMAA on this render target we will resolve
70cb93a386Sopenharmony_ci        // to the single target attachment.
71cb93a386Sopenharmony_ci        fResolveAttachment = fColorAttachment;
72cb93a386Sopenharmony_ci    }
73cb93a386Sopenharmony_ci
74cb93a386Sopenharmony_ci    SkASSERT(!resolveAttachment ||
75cb93a386Sopenharmony_ci             (fResolveAttachment->isProtected() == fColorAttachment->isProtected()));
76cb93a386Sopenharmony_ci    SkASSERT(SkToBool(fColorAttachment->vkUsageFlags() & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT));
77cb93a386Sopenharmony_ci    this->setFlags();
78cb93a386Sopenharmony_ci    if (createType == CreateType::kDirectlyWrapped) {
79cb93a386Sopenharmony_ci        this->registerWithCacheWrapped(GrWrapCacheable::kNo);
80cb93a386Sopenharmony_ci    }
81cb93a386Sopenharmony_ci}
82cb93a386Sopenharmony_ci
83cb93a386Sopenharmony_ciGrVkRenderTarget::GrVkRenderTarget(GrVkGpu* gpu,
84cb93a386Sopenharmony_ci                                   SkISize dimensions,
85cb93a386Sopenharmony_ci                                   sk_sp<GrVkFramebuffer> externalFramebuffer)
86cb93a386Sopenharmony_ci        : GrSurface(gpu, dimensions,
87cb93a386Sopenharmony_ci                    externalFramebuffer->colorAttachment()->isProtected() ? GrProtected::kYes
88cb93a386Sopenharmony_ci                                                                          : GrProtected::kNo)
89cb93a386Sopenharmony_ci        , GrRenderTarget(gpu, dimensions, 1,
90cb93a386Sopenharmony_ci                         externalFramebuffer->colorAttachment()->isProtected() ? GrProtected::kYes
91cb93a386Sopenharmony_ci                                                                               : GrProtected::kNo)
92cb93a386Sopenharmony_ci        , fCachedFramebuffers()
93cb93a386Sopenharmony_ci        , fExternalFramebuffer(externalFramebuffer) {
94cb93a386Sopenharmony_ci    SkASSERT(fExternalFramebuffer);
95cb93a386Sopenharmony_ci    SkASSERT(!fColorAttachment);
96cb93a386Sopenharmony_ci    SkDEBUGCODE(auto colorAttachment = fExternalFramebuffer->colorAttachment());
97cb93a386Sopenharmony_ci    SkASSERT(colorAttachment);
98cb93a386Sopenharmony_ci    SkASSERT(colorAttachment->numSamples() == 1);
99cb93a386Sopenharmony_ci    SkASSERT(SkToBool(colorAttachment->vkUsageFlags() & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT));
100cb93a386Sopenharmony_ci    SkASSERT(!SkToBool(colorAttachment->vkUsageFlags() & VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT));
101cb93a386Sopenharmony_ci    this->setFlags();
102cb93a386Sopenharmony_ci    this->registerWithCacheWrapped(GrWrapCacheable::kNo);
103cb93a386Sopenharmony_ci}
104cb93a386Sopenharmony_ci
105cb93a386Sopenharmony_civoid GrVkRenderTarget::setFlags() {
106cb93a386Sopenharmony_ci    if (this->wrapsSecondaryCommandBuffer()) {
107cb93a386Sopenharmony_ci        return;
108cb93a386Sopenharmony_ci    }
109cb93a386Sopenharmony_ci    GrVkImage* nonMSAAAttachment = this->nonMSAAAttachment();
110cb93a386Sopenharmony_ci    if (nonMSAAAttachment && nonMSAAAttachment->supportsInputAttachmentUsage()) {
111cb93a386Sopenharmony_ci        this->setVkRTSupportsInputAttachment();
112cb93a386Sopenharmony_ci    }
113cb93a386Sopenharmony_ci}
114cb93a386Sopenharmony_ci
115cb93a386Sopenharmony_cisk_sp<GrVkRenderTarget> GrVkRenderTarget::MakeWrappedRenderTarget(
116cb93a386Sopenharmony_ci        GrVkGpu* gpu,
117cb93a386Sopenharmony_ci        SkISize dimensions,
118cb93a386Sopenharmony_ci        int sampleCnt,
119cb93a386Sopenharmony_ci        const GrVkImageInfo& info,
120cb93a386Sopenharmony_ci        sk_sp<GrBackendSurfaceMutableStateImpl> mutableState) {
121cb93a386Sopenharmony_ci    SkASSERT(VK_NULL_HANDLE != info.fImage);
122cb93a386Sopenharmony_ci    SkASSERT(1 == info.fLevelCount);
123cb93a386Sopenharmony_ci    SkASSERT(sampleCnt >= 1 && info.fSampleCount >= 1);
124cb93a386Sopenharmony_ci
125cb93a386Sopenharmony_ci    int wrappedImageSampleCnt = static_cast<int>(info.fSampleCount);
126cb93a386Sopenharmony_ci    if (sampleCnt != wrappedImageSampleCnt && wrappedImageSampleCnt != 1) {
127cb93a386Sopenharmony_ci        return nullptr;
128cb93a386Sopenharmony_ci    }
129cb93a386Sopenharmony_ci
130cb93a386Sopenharmony_ci    sk_sp<GrVkImage> wrappedAttachment =
131cb93a386Sopenharmony_ci            GrVkImage::MakeWrapped(gpu,
132cb93a386Sopenharmony_ci                                   dimensions,
133cb93a386Sopenharmony_ci                                   info,
134cb93a386Sopenharmony_ci                                   std::move(mutableState),
135cb93a386Sopenharmony_ci                                   GrAttachment::UsageFlags::kColorAttachment,
136cb93a386Sopenharmony_ci                                   kBorrow_GrWrapOwnership,
137cb93a386Sopenharmony_ci                                   GrWrapCacheable::kNo);
138cb93a386Sopenharmony_ci    if (!wrappedAttachment) {
139cb93a386Sopenharmony_ci        return nullptr;
140cb93a386Sopenharmony_ci    }
141cb93a386Sopenharmony_ci
142cb93a386Sopenharmony_ci    sk_sp<GrVkImage> colorAttachment;
143cb93a386Sopenharmony_ci    colorAttachment = std::move(wrappedAttachment);
144cb93a386Sopenharmony_ci
145cb93a386Sopenharmony_ci    if (!colorAttachment) {
146cb93a386Sopenharmony_ci        return nullptr;
147cb93a386Sopenharmony_ci    }
148cb93a386Sopenharmony_ci
149cb93a386Sopenharmony_ci    GrVkRenderTarget* vkRT = new GrVkRenderTarget(gpu,dimensions, std::move(colorAttachment),
150cb93a386Sopenharmony_ci                                                  nullptr, CreateType::kDirectlyWrapped);
151cb93a386Sopenharmony_ci    return sk_sp<GrVkRenderTarget>(vkRT);
152cb93a386Sopenharmony_ci}
153cb93a386Sopenharmony_ci
154cb93a386Sopenharmony_cisk_sp<GrVkRenderTarget> GrVkRenderTarget::MakeSecondaryCBRenderTarget(
155cb93a386Sopenharmony_ci        GrVkGpu* gpu, SkISize dimensions, const GrVkDrawableInfo& vkInfo) {
156cb93a386Sopenharmony_ci    const GrVkRenderPass* rp = gpu->resourceProvider().findCompatibleExternalRenderPass(
157cb93a386Sopenharmony_ci            vkInfo.fCompatibleRenderPass, vkInfo.fColorAttachmentIndex);
158cb93a386Sopenharmony_ci    if (!rp) {
159cb93a386Sopenharmony_ci        return nullptr;
160cb93a386Sopenharmony_ci    }
161cb93a386Sopenharmony_ci
162cb93a386Sopenharmony_ci    if (vkInfo.fSecondaryCommandBuffer == VK_NULL_HANDLE) {
163cb93a386Sopenharmony_ci        return nullptr;
164cb93a386Sopenharmony_ci    }
165cb93a386Sopenharmony_ci
166cb93a386Sopenharmony_ci    // We only set the few properties of the GrVkImageInfo that we know like layout and format. The
167cb93a386Sopenharmony_ci    // others we keep at the default "null" values.
168cb93a386Sopenharmony_ci    GrVkImageInfo info;
169cb93a386Sopenharmony_ci    info.fImageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
170cb93a386Sopenharmony_ci    info.fFormat = vkInfo.fFormat;
171cb93a386Sopenharmony_ci    info.fImageUsageFlags = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT |
172cb93a386Sopenharmony_ci                            VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
173cb93a386Sopenharmony_ci
174cb93a386Sopenharmony_ci    sk_sp<GrBackendSurfaceMutableStateImpl> mutableState(new GrBackendSurfaceMutableStateImpl(
175cb93a386Sopenharmony_ci            VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_QUEUE_FAMILY_IGNORED));
176cb93a386Sopenharmony_ci
177cb93a386Sopenharmony_ci    sk_sp<GrVkImage> colorAttachment =
178cb93a386Sopenharmony_ci            GrVkImage::MakeWrapped(gpu,
179cb93a386Sopenharmony_ci                                   dimensions,
180cb93a386Sopenharmony_ci                                   info,
181cb93a386Sopenharmony_ci                                   std::move(mutableState),
182cb93a386Sopenharmony_ci                                   GrAttachment::UsageFlags::kColorAttachment,
183cb93a386Sopenharmony_ci                                   kBorrow_GrWrapOwnership,
184cb93a386Sopenharmony_ci                                   GrWrapCacheable::kNo,
185cb93a386Sopenharmony_ci                                   true);
186cb93a386Sopenharmony_ci
187cb93a386Sopenharmony_ci    std::unique_ptr<GrVkSecondaryCommandBuffer> scb(
188cb93a386Sopenharmony_ci            GrVkSecondaryCommandBuffer::Create(vkInfo.fSecondaryCommandBuffer, rp));
189cb93a386Sopenharmony_ci    if (!scb) {
190cb93a386Sopenharmony_ci        return nullptr;
191cb93a386Sopenharmony_ci    }
192cb93a386Sopenharmony_ci
193cb93a386Sopenharmony_ci    sk_sp<GrVkFramebuffer> framebuffer(new GrVkFramebuffer(
194cb93a386Sopenharmony_ci            gpu, std::move(colorAttachment), sk_sp<const GrVkRenderPass>(rp),
195cb93a386Sopenharmony_ci            std::move(scb)));
196cb93a386Sopenharmony_ci
197cb93a386Sopenharmony_ci    GrVkRenderTarget* vkRT = new GrVkRenderTarget(gpu, dimensions, std::move(framebuffer));
198cb93a386Sopenharmony_ci
199cb93a386Sopenharmony_ci    return sk_sp<GrVkRenderTarget>(vkRT);
200cb93a386Sopenharmony_ci}
201cb93a386Sopenharmony_ci
202cb93a386Sopenharmony_ciGrBackendFormat GrVkRenderTarget::backendFormat() const {
203cb93a386Sopenharmony_ci    if (this->wrapsSecondaryCommandBuffer()) {
204cb93a386Sopenharmony_ci        return fExternalFramebuffer->colorAttachment()->backendFormat();
205cb93a386Sopenharmony_ci    }
206cb93a386Sopenharmony_ci    return fColorAttachment->backendFormat();
207cb93a386Sopenharmony_ci}
208cb93a386Sopenharmony_ci
209cb93a386Sopenharmony_ciGrVkImage* GrVkRenderTarget::nonMSAAAttachment() const {
210cb93a386Sopenharmony_ci    if (fColorAttachment->numSamples() == 1) {
211cb93a386Sopenharmony_ci        return fColorAttachment.get();
212cb93a386Sopenharmony_ci    } else {
213cb93a386Sopenharmony_ci        return fResolveAttachment.get();
214cb93a386Sopenharmony_ci    }
215cb93a386Sopenharmony_ci}
216cb93a386Sopenharmony_ci
217cb93a386Sopenharmony_ciGrVkImage* GrVkRenderTarget::dynamicMSAAAttachment() {
218cb93a386Sopenharmony_ci    if (fDynamicMSAAAttachment) {
219cb93a386Sopenharmony_ci        return fDynamicMSAAAttachment.get();
220cb93a386Sopenharmony_ci    }
221cb93a386Sopenharmony_ci    const GrVkImage* nonMSAAColorAttachment = this->colorAttachment();
222cb93a386Sopenharmony_ci    SkASSERT(nonMSAAColorAttachment->numSamples() == 1);
223cb93a386Sopenharmony_ci
224cb93a386Sopenharmony_ci    GrVkGpu* gpu = this->getVkGpu();
225cb93a386Sopenharmony_ci    auto rp = gpu->getContext()->priv().resourceProvider();
226cb93a386Sopenharmony_ci
227cb93a386Sopenharmony_ci    const GrBackendFormat& format = nonMSAAColorAttachment->backendFormat();
228cb93a386Sopenharmony_ci
229cb93a386Sopenharmony_ci    GrMemoryless memoryless =
230cb93a386Sopenharmony_ci            gpu->vkCaps().supportsMemorylessAttachments() ? GrMemoryless::kYes : GrMemoryless::kNo;
231cb93a386Sopenharmony_ci
232cb93a386Sopenharmony_ci    sk_sp<GrAttachment> msaaAttachment =
233cb93a386Sopenharmony_ci            rp->getDiscardableMSAAAttachment(nonMSAAColorAttachment->dimensions(),
234cb93a386Sopenharmony_ci                                             format,
235cb93a386Sopenharmony_ci                                             gpu->caps()->internalMultisampleCount(format),
236cb93a386Sopenharmony_ci                                             GrProtected(nonMSAAColorAttachment->isProtected()),
237cb93a386Sopenharmony_ci                                             memoryless);
238cb93a386Sopenharmony_ci    if (!msaaAttachment) {
239cb93a386Sopenharmony_ci        return nullptr;
240cb93a386Sopenharmony_ci    }
241cb93a386Sopenharmony_ci    fDynamicMSAAAttachment = sk_sp<GrVkImage>(static_cast<GrVkImage*>(msaaAttachment.release()));
242cb93a386Sopenharmony_ci    return fDynamicMSAAAttachment.get();
243cb93a386Sopenharmony_ci}
244cb93a386Sopenharmony_ci
245cb93a386Sopenharmony_ciGrVkImage* GrVkRenderTarget::msaaAttachment() {
246cb93a386Sopenharmony_ci    return this->colorAttachment()->numSamples() == 1 ? this->dynamicMSAAAttachment()
247cb93a386Sopenharmony_ci                                                      : this->colorAttachment();
248cb93a386Sopenharmony_ci}
249cb93a386Sopenharmony_ci
250cb93a386Sopenharmony_cibool GrVkRenderTarget::canAttemptStencilAttachment(bool useMSAASurface) const {
251cb93a386Sopenharmony_ci    SkASSERT(!useMSAASurface || this->numSamples() > 1 ||
252cb93a386Sopenharmony_ci             this->getVkGpu()->vkCaps().supportsDiscardableMSAAForDMSAA());
253cb93a386Sopenharmony_ci    if (!useMSAASurface && this->numSamples() > 1) {
254cb93a386Sopenharmony_ci        return false;
255cb93a386Sopenharmony_ci    }
256cb93a386Sopenharmony_ci    bool validMSAA = true;
257cb93a386Sopenharmony_ci    if (useMSAASurface) {
258cb93a386Sopenharmony_ci        validMSAA = this->numSamples() > 1 ||
259cb93a386Sopenharmony_ci                    (this->getVkGpu()->vkCaps().supportsDiscardableMSAAForDMSAA() &&
260cb93a386Sopenharmony_ci                     this->colorAttachment()->supportsInputAttachmentUsage());
261cb93a386Sopenharmony_ci    }
262cb93a386Sopenharmony_ci    // We don't know the status of the stencil attachment for wrapped external secondary command
263cb93a386Sopenharmony_ci    // buffers so we just assume we don't have one.
264cb93a386Sopenharmony_ci    return validMSAA && !this->wrapsSecondaryCommandBuffer();
265cb93a386Sopenharmony_ci}
266cb93a386Sopenharmony_ci
267cb93a386Sopenharmony_cibool GrVkRenderTarget::completeStencilAttachment(GrAttachment* stencil, bool useMSAASurface) {
268cb93a386Sopenharmony_ci    SkASSERT(!this->wrapsSecondaryCommandBuffer());
269cb93a386Sopenharmony_ci    SkASSERT(!useMSAASurface ||
270cb93a386Sopenharmony_ci             this->numSamples() > 1 ||
271cb93a386Sopenharmony_ci             this->getVkGpu()->vkCaps().supportsDiscardableMSAAForDMSAA());
272cb93a386Sopenharmony_ci    return true;
273cb93a386Sopenharmony_ci}
274cb93a386Sopenharmony_ci
275cb93a386Sopenharmony_cisk_sp<GrVkFramebuffer> GrVkRenderTarget::externalFramebuffer() const {
276cb93a386Sopenharmony_ci    return fExternalFramebuffer;
277cb93a386Sopenharmony_ci}
278cb93a386Sopenharmony_ci
279cb93a386Sopenharmony_ciGrVkResourceProvider::CompatibleRPHandle GrVkRenderTarget::compatibleRenderPassHandle(
280cb93a386Sopenharmony_ci        bool withResolve,
281cb93a386Sopenharmony_ci        bool withStencil,
282cb93a386Sopenharmony_ci        SelfDependencyFlags selfDepFlags,
283cb93a386Sopenharmony_ci        LoadFromResolve loadFromResolve) {
284cb93a386Sopenharmony_ci    SkASSERT(!this->wrapsSecondaryCommandBuffer());
285cb93a386Sopenharmony_ci
286cb93a386Sopenharmony_ci    const GrVkFramebuffer* fb =
287cb93a386Sopenharmony_ci            this->getFramebuffer(withResolve, withStencil, selfDepFlags, loadFromResolve);
288cb93a386Sopenharmony_ci    if (!fb) {
289cb93a386Sopenharmony_ci        return {};
290cb93a386Sopenharmony_ci    }
291cb93a386Sopenharmony_ci
292cb93a386Sopenharmony_ci    return fb->compatibleRenderPassHandle();
293cb93a386Sopenharmony_ci}
294cb93a386Sopenharmony_ci
295cb93a386Sopenharmony_ciconst GrVkRenderPass* GrVkRenderTarget::getSimpleRenderPass(bool withResolve,
296cb93a386Sopenharmony_ci                                                            bool withStencil,
297cb93a386Sopenharmony_ci                                                            SelfDependencyFlags selfDepFlags,
298cb93a386Sopenharmony_ci                                                            LoadFromResolve loadFromResolve) {
299cb93a386Sopenharmony_ci    if (this->wrapsSecondaryCommandBuffer()) {
300cb93a386Sopenharmony_ci         return fExternalFramebuffer->externalRenderPass();
301cb93a386Sopenharmony_ci    }
302cb93a386Sopenharmony_ci
303cb93a386Sopenharmony_ci    const GrVkFramebuffer* fb =
304cb93a386Sopenharmony_ci            this->getFramebuffer(withResolve, withStencil, selfDepFlags, loadFromResolve);
305cb93a386Sopenharmony_ci    if (!fb) {
306cb93a386Sopenharmony_ci        return nullptr;
307cb93a386Sopenharmony_ci    }
308cb93a386Sopenharmony_ci
309cb93a386Sopenharmony_ci    return fb->compatibleRenderPass();
310cb93a386Sopenharmony_ci}
311cb93a386Sopenharmony_ci
312cb93a386Sopenharmony_cistd::pair<const GrVkRenderPass*, GrVkResourceProvider::CompatibleRPHandle>
313cb93a386Sopenharmony_ciGrVkRenderTarget::createSimpleRenderPass(bool withResolve,
314cb93a386Sopenharmony_ci                                         bool withStencil,
315cb93a386Sopenharmony_ci                                         SelfDependencyFlags selfDepFlags,
316cb93a386Sopenharmony_ci                                         LoadFromResolve loadFromResolve) {
317cb93a386Sopenharmony_ci    SkASSERT(!this->wrapsSecondaryCommandBuffer());
318cb93a386Sopenharmony_ci
319cb93a386Sopenharmony_ci    GrVkResourceProvider& rp = this->getVkGpu()->resourceProvider();
320cb93a386Sopenharmony_ci
321cb93a386Sopenharmony_ci    GrVkResourceProvider::CompatibleRPHandle handle;
322cb93a386Sopenharmony_ci    const GrVkRenderPass* renderPass = rp.findCompatibleRenderPass(
323cb93a386Sopenharmony_ci            this, &handle, withResolve, withStencil, selfDepFlags,
324cb93a386Sopenharmony_ci            loadFromResolve);
325cb93a386Sopenharmony_ci    SkASSERT(!renderPass || handle.isValid());
326cb93a386Sopenharmony_ci    return {renderPass, handle};
327cb93a386Sopenharmony_ci}
328cb93a386Sopenharmony_ci
329cb93a386Sopenharmony_ciconst GrVkFramebuffer* GrVkRenderTarget::getFramebuffer(bool withResolve,
330cb93a386Sopenharmony_ci                                                        bool withStencil,
331cb93a386Sopenharmony_ci                                                        SelfDependencyFlags selfDepFlags,
332cb93a386Sopenharmony_ci                                                        LoadFromResolve loadFromResolve) {
333cb93a386Sopenharmony_ci    int cacheIndex =
334cb93a386Sopenharmony_ci            renderpass_features_to_index(withResolve, withStencil, selfDepFlags, loadFromResolve);
335cb93a386Sopenharmony_ci    SkASSERT(cacheIndex < GrVkRenderTarget::kNumCachedFramebuffers);
336cb93a386Sopenharmony_ci    if (auto fb = fCachedFramebuffers[cacheIndex]) {
337cb93a386Sopenharmony_ci        return fb.get();
338cb93a386Sopenharmony_ci    }
339cb93a386Sopenharmony_ci
340cb93a386Sopenharmony_ci    this->createFramebuffer(withResolve, withStencil, selfDepFlags, loadFromResolve);
341cb93a386Sopenharmony_ci    return fCachedFramebuffers[cacheIndex].get();
342cb93a386Sopenharmony_ci}
343cb93a386Sopenharmony_ci
344cb93a386Sopenharmony_civoid GrVkRenderTarget::createFramebuffer(bool withResolve,
345cb93a386Sopenharmony_ci                                         bool withStencil,
346cb93a386Sopenharmony_ci                                         SelfDependencyFlags selfDepFlags,
347cb93a386Sopenharmony_ci                                         LoadFromResolve loadFromResolve) {
348cb93a386Sopenharmony_ci    SkASSERT(!this->wrapsSecondaryCommandBuffer());
349cb93a386Sopenharmony_ci    GrVkGpu* gpu = this->getVkGpu();
350cb93a386Sopenharmony_ci
351cb93a386Sopenharmony_ci    auto[renderPass, compatibleHandle] =
352cb93a386Sopenharmony_ci            this->createSimpleRenderPass(withResolve, withStencil, selfDepFlags, loadFromResolve);
353cb93a386Sopenharmony_ci    if (!renderPass) {
354cb93a386Sopenharmony_ci        return;
355cb93a386Sopenharmony_ci    }
356cb93a386Sopenharmony_ci    SkASSERT(compatibleHandle.isValid());
357cb93a386Sopenharmony_ci
358cb93a386Sopenharmony_ci    int cacheIndex =
359cb93a386Sopenharmony_ci            renderpass_features_to_index(withResolve, withStencil, selfDepFlags, loadFromResolve);
360cb93a386Sopenharmony_ci    SkASSERT(cacheIndex < GrVkRenderTarget::kNumCachedFramebuffers);
361cb93a386Sopenharmony_ci
362cb93a386Sopenharmony_ci    GrVkImage* resolve = withResolve ? this->resolveAttachment() : nullptr;
363cb93a386Sopenharmony_ci    GrVkImage* colorAttachment = withResolve ? this->msaaAttachment() : this->colorAttachment();
364cb93a386Sopenharmony_ci
365cb93a386Sopenharmony_ci    // Stencil attachment view is stored in the base RT stencil attachment
366cb93a386Sopenharmony_ci    bool useMSAA = this->numSamples() > 1 || withResolve;
367cb93a386Sopenharmony_ci    GrVkImage* stencil =  withStencil ? static_cast<GrVkImage*>(this->getStencilAttachment(useMSAA))
368cb93a386Sopenharmony_ci                                      : nullptr;
369cb93a386Sopenharmony_ci    fCachedFramebuffers[cacheIndex] =
370cb93a386Sopenharmony_ci            GrVkFramebuffer::Make(gpu, this->dimensions(),
371cb93a386Sopenharmony_ci                                  sk_sp<const GrVkRenderPass>(renderPass),
372cb93a386Sopenharmony_ci                                  colorAttachment, resolve, stencil, compatibleHandle);
373cb93a386Sopenharmony_ci}
374cb93a386Sopenharmony_ci
375cb93a386Sopenharmony_civoid GrVkRenderTarget::getAttachmentsDescriptor(GrVkRenderPass::AttachmentsDescriptor* desc,
376cb93a386Sopenharmony_ci                                                GrVkRenderPass::AttachmentFlags* attachmentFlags,
377cb93a386Sopenharmony_ci                                                bool withResolve,
378cb93a386Sopenharmony_ci                                                bool withStencil) {
379cb93a386Sopenharmony_ci    SkASSERT(!this->wrapsSecondaryCommandBuffer());
380cb93a386Sopenharmony_ci    const GrVkImage* colorAttachment =
381cb93a386Sopenharmony_ci            withResolve ? this->msaaAttachment() : this->colorAttachment();
382cb93a386Sopenharmony_ci
383cb93a386Sopenharmony_ci    desc->fColor.fFormat = colorAttachment->imageFormat();
384cb93a386Sopenharmony_ci    desc->fColor.fSamples = colorAttachment->numSamples();
385cb93a386Sopenharmony_ci    *attachmentFlags = GrVkRenderPass::kColor_AttachmentFlag;
386cb93a386Sopenharmony_ci    uint32_t attachmentCount = 1;
387cb93a386Sopenharmony_ci
388cb93a386Sopenharmony_ci    if (withResolve) {
389cb93a386Sopenharmony_ci        desc->fResolve.fFormat = desc->fColor.fFormat;
390cb93a386Sopenharmony_ci        desc->fResolve.fSamples = 1;
391cb93a386Sopenharmony_ci        *attachmentFlags |= GrVkRenderPass::kResolve_AttachmentFlag;
392cb93a386Sopenharmony_ci        ++attachmentCount;
393cb93a386Sopenharmony_ci    }
394cb93a386Sopenharmony_ci
395cb93a386Sopenharmony_ci    if (withStencil) {
396cb93a386Sopenharmony_ci        bool useMSAA = this->numSamples() > 1 || withResolve;
397cb93a386Sopenharmony_ci        const GrAttachment* stencil = this->getStencilAttachment(useMSAA);
398cb93a386Sopenharmony_ci        SkASSERT(stencil);
399cb93a386Sopenharmony_ci        const GrVkImage* vkStencil = static_cast<const GrVkImage*>(stencil);
400cb93a386Sopenharmony_ci        desc->fStencil.fFormat = vkStencil->imageFormat();
401cb93a386Sopenharmony_ci        desc->fStencil.fSamples = vkStencil->numSamples();
402cb93a386Sopenharmony_ci        SkASSERT(desc->fStencil.fSamples == desc->fColor.fSamples);
403cb93a386Sopenharmony_ci        *attachmentFlags |= GrVkRenderPass::kStencil_AttachmentFlag;
404cb93a386Sopenharmony_ci        ++attachmentCount;
405cb93a386Sopenharmony_ci    }
406cb93a386Sopenharmony_ci    desc->fAttachmentCount = attachmentCount;
407cb93a386Sopenharmony_ci}
408cb93a386Sopenharmony_ci
409cb93a386Sopenharmony_civoid GrVkRenderTarget::ReconstructAttachmentsDescriptor(const GrVkCaps& vkCaps,
410cb93a386Sopenharmony_ci                                                        const GrProgramInfo& programInfo,
411cb93a386Sopenharmony_ci                                                        GrVkRenderPass::AttachmentsDescriptor* desc,
412cb93a386Sopenharmony_ci                                                        GrVkRenderPass::AttachmentFlags* flags) {
413cb93a386Sopenharmony_ci    VkFormat format;
414cb93a386Sopenharmony_ci    SkAssertResult(programInfo.backendFormat().asVkFormat(&format));
415cb93a386Sopenharmony_ci
416cb93a386Sopenharmony_ci    desc->fColor.fFormat = format;
417cb93a386Sopenharmony_ci    desc->fColor.fSamples = programInfo.numSamples();
418cb93a386Sopenharmony_ci    *flags = GrVkRenderPass::kColor_AttachmentFlag;
419cb93a386Sopenharmony_ci    uint32_t attachmentCount = 1;
420cb93a386Sopenharmony_ci
421cb93a386Sopenharmony_ci    if (vkCaps.programInfoWillUseDiscardableMSAA(programInfo)) {
422cb93a386Sopenharmony_ci        desc->fResolve.fFormat = desc->fColor.fFormat;
423cb93a386Sopenharmony_ci        desc->fResolve.fSamples = 1;
424cb93a386Sopenharmony_ci        *flags |= GrVkRenderPass::kResolve_AttachmentFlag;
425cb93a386Sopenharmony_ci        ++attachmentCount;
426cb93a386Sopenharmony_ci    }
427cb93a386Sopenharmony_ci
428cb93a386Sopenharmony_ci    SkASSERT(!programInfo.isStencilEnabled() || programInfo.needsStencil());
429cb93a386Sopenharmony_ci    if (programInfo.needsStencil()) {
430cb93a386Sopenharmony_ci        VkFormat stencilFormat = vkCaps.preferredStencilFormat();
431cb93a386Sopenharmony_ci        desc->fStencil.fFormat = stencilFormat;
432cb93a386Sopenharmony_ci        desc->fStencil.fSamples = programInfo.numSamples();
433cb93a386Sopenharmony_ci        SkASSERT(desc->fStencil.fSamples == desc->fColor.fSamples);
434cb93a386Sopenharmony_ci        *flags |= GrVkRenderPass::kStencil_AttachmentFlag;
435cb93a386Sopenharmony_ci        ++attachmentCount;
436cb93a386Sopenharmony_ci    }
437cb93a386Sopenharmony_ci    desc->fAttachmentCount = attachmentCount;
438cb93a386Sopenharmony_ci}
439cb93a386Sopenharmony_ci
440cb93a386Sopenharmony_ciGrVkRenderTarget::~GrVkRenderTarget() {
441cb93a386Sopenharmony_ci    // either release or abandon should have been called by the owner of this object.
442cb93a386Sopenharmony_ci    SkASSERT(!fColorAttachment);
443cb93a386Sopenharmony_ci    SkASSERT(!fResolveAttachment);
444cb93a386Sopenharmony_ci    SkASSERT(!fDynamicMSAAAttachment);
445cb93a386Sopenharmony_ci
446cb93a386Sopenharmony_ci    for (int i = 0; i < kNumCachedFramebuffers; ++i) {
447cb93a386Sopenharmony_ci        SkASSERT(!fCachedFramebuffers[i]);
448cb93a386Sopenharmony_ci    }
449cb93a386Sopenharmony_ci
450cb93a386Sopenharmony_ci    SkASSERT(!fCachedInputDescriptorSet);
451cb93a386Sopenharmony_ci}
452cb93a386Sopenharmony_ci
453cb93a386Sopenharmony_civoid GrVkRenderTarget::releaseInternalObjects() {
454cb93a386Sopenharmony_ci    fColorAttachment.reset();
455cb93a386Sopenharmony_ci    fResolveAttachment.reset();
456cb93a386Sopenharmony_ci    fDynamicMSAAAttachment.reset();
457cb93a386Sopenharmony_ci
458cb93a386Sopenharmony_ci    for (int i = 0; i < kNumCachedFramebuffers; ++i) {
459cb93a386Sopenharmony_ci        if (fCachedFramebuffers[i]) {
460cb93a386Sopenharmony_ci            fCachedFramebuffers[i].reset();
461cb93a386Sopenharmony_ci        }
462cb93a386Sopenharmony_ci    }
463cb93a386Sopenharmony_ci
464cb93a386Sopenharmony_ci    if (fCachedInputDescriptorSet) {
465cb93a386Sopenharmony_ci        fCachedInputDescriptorSet->recycle();
466cb93a386Sopenharmony_ci        fCachedInputDescriptorSet = nullptr;
467cb93a386Sopenharmony_ci    }
468cb93a386Sopenharmony_ci
469cb93a386Sopenharmony_ci    fExternalFramebuffer.reset();
470cb93a386Sopenharmony_ci}
471cb93a386Sopenharmony_ci
472cb93a386Sopenharmony_civoid GrVkRenderTarget::onRelease() {
473cb93a386Sopenharmony_ci    this->releaseInternalObjects();
474cb93a386Sopenharmony_ci    GrRenderTarget::onRelease();
475cb93a386Sopenharmony_ci}
476cb93a386Sopenharmony_ci
477cb93a386Sopenharmony_civoid GrVkRenderTarget::onAbandon() {
478cb93a386Sopenharmony_ci    this->releaseInternalObjects();
479cb93a386Sopenharmony_ci    GrRenderTarget::onAbandon();
480cb93a386Sopenharmony_ci}
481cb93a386Sopenharmony_ci
482cb93a386Sopenharmony_ciGrBackendRenderTarget GrVkRenderTarget::getBackendRenderTarget() const {
483cb93a386Sopenharmony_ci    SkASSERT(!this->wrapsSecondaryCommandBuffer());
484cb93a386Sopenharmony_ci    // This should only get called with a non-released GrVkRenderTargets.
485cb93a386Sopenharmony_ci    SkASSERT(!this->wasDestroyed());
486cb93a386Sopenharmony_ci    // If we have a resolve attachment that is what we return for the backend render target
487cb93a386Sopenharmony_ci    const GrVkImage* beAttachment = this->externalAttachment();
488cb93a386Sopenharmony_ci    return GrBackendRenderTarget(beAttachment->width(), beAttachment->height(),
489cb93a386Sopenharmony_ci                                 beAttachment->vkImageInfo(), beAttachment->getMutableState());
490cb93a386Sopenharmony_ci}
491cb93a386Sopenharmony_ci
492cb93a386Sopenharmony_ciGrVkGpu* GrVkRenderTarget::getVkGpu() const {
493cb93a386Sopenharmony_ci    SkASSERT(!this->wasDestroyed());
494cb93a386Sopenharmony_ci    return static_cast<GrVkGpu*>(this->getGpu());
495cb93a386Sopenharmony_ci}
496