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