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