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