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