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