blob: 4e7a729e13f046d70f2ea13069ac02c7ff16bafe [file] [log] [blame]
Greg Daniel164a9f02016-02-22 09:56:40 -05001/*
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
Mike Kleinc0bd9f92019-04-23 12:05:21 -05008#include "src/gpu/vk/GrVkRenderTarget.h"
Greg Daniel164a9f02016-02-22 09:56:40 -05009
Mike Kleinc0bd9f92019-04-23 12:05:21 -050010#include "include/gpu/GrBackendSurface.h"
Greg Daniele2893f22020-10-13 10:20:06 -040011#include "include/gpu/GrDirectContext.h"
12#include "src/gpu/GrBackendSurfaceMutableStateImpl.h"
Adlai Hollera0693042020-10-14 11:23:11 -040013#include "src/gpu/GrDirectContextPriv.h"
Greg Daniele2893f22020-10-13 10:20:06 -040014#include "src/gpu/GrResourceProvider.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050015#include "src/gpu/vk/GrVkCommandBuffer.h"
Greg Daniel37fd6582020-09-14 12:36:09 -040016#include "src/gpu/vk/GrVkDescriptorSet.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050017#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"
Greg Daniel164a9f02016-02-22 09:56:40 -050022
Mike Kleinc0bd9f92019-04-23 12:05:21 -050023#include "include/gpu/vk/GrVkTypes.h"
jvanverthfd359ca2016-03-18 11:57:24 -070024
Greg Daniel164a9f02016-02-22 09:56:40 -050025#define VK_CALL(GPU, X) GR_VK_CALL(GPU->vkInterface(), X)
26
Greg Daniel7acddf52020-12-16 15:15:51 -050027static 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) {
Greg Daniel21774362020-09-14 10:36:43 -040035 index += 2;
36 }
Greg Daniel7acddf52020-12-16 15:15:51 -050037 if (selfDepFlags & GrVkRenderPass::SelfDependencyFlags::kForInputAttachment) {
Greg Daniel21774362020-09-14 10:36:43 -040038 index += 4;
39 }
Greg Daniel7acddf52020-12-16 15:15:51 -050040 if (selfDepFlags & GrVkRenderPass::SelfDependencyFlags::kForNonCoherentAdvBlend) {
41 index += 8;
42 }
43 if (loadFromReslove == GrVkRenderPass::LoadFromResolve::kLoad) {
44 index += 16;
45 }
Greg Daniel21774362020-09-14 10:36:43 -040046 return index;
47}
48
Greg Daniel164a9f02016-02-22 09:56:40 -050049// We're virtually derived from GrSurface (via GrRenderTarget) so its
50// constructor must be explicitly called.
51GrVkRenderTarget::GrVkRenderTarget(GrVkGpu* gpu,
Brian Salomona56a7462020-02-07 14:17:25 -050052 SkISize dimensions,
Greg Daniel2bc96d62021-09-13 13:08:02 -040053 sk_sp<GrVkImage> colorAttachment,
54 sk_sp<GrVkImage> resolveAttachment,
Greg Daniel00d6cf42021-03-05 22:50:08 +000055 CreateType createType)
56 : GrSurface(gpu, dimensions,
57 colorAttachment->isProtected() ? GrProtected::kYes : GrProtected::kNo)
Greg Danielb46add82019-01-02 14:51:29 -050058 // for the moment we only support 1:1 color to stencil
Greg Daniel00d6cf42021-03-05 22:50:08 +000059 , GrRenderTarget(gpu, dimensions, colorAttachment->numSamples(),
60 colorAttachment->isProtected() ? GrProtected::kYes : GrProtected::kNo)
61 , fColorAttachment(std::move(colorAttachment))
62 , fResolveAttachment(std::move(resolveAttachment))
Greg Daniel805c6222021-04-20 12:44:48 -040063 , fCachedFramebuffers() {
Greg Daniel00d6cf42021-03-05 22:50:08 +000064 SkASSERT(fColorAttachment);
Greg Daniel1e169372021-08-24 15:44:15 -040065
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
Greg Daniel00d6cf42021-03-05 22:50:08 +000074 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 }
Greg Daniel7b62dca2020-08-21 11:26:12 -040081}
Greg Daniel164a9f02016-02-22 09:56:40 -050082
Greg Danielb46add82019-01-02 14:51:29 -050083GrVkRenderTarget::GrVkRenderTarget(GrVkGpu* gpu,
Brian Salomona56a7462020-02-07 14:17:25 -050084 SkISize dimensions,
Greg Danielde4bbdb2021-04-13 14:23:23 -040085 sk_sp<GrVkFramebuffer> externalFramebuffer)
Greg Daniel00d6cf42021-03-05 22:50:08 +000086 : GrSurface(gpu, dimensions,
Greg Danielde4bbdb2021-04-13 14:23:23 -040087 externalFramebuffer->colorAttachment()->isProtected() ? GrProtected::kYes
88 : GrProtected::kNo)
Greg Daniel00d6cf42021-03-05 22:50:08 +000089 , GrRenderTarget(gpu, dimensions, 1,
Greg Danielde4bbdb2021-04-13 14:23:23 -040090 externalFramebuffer->colorAttachment()->isProtected() ? GrProtected::kYes
91 : GrProtected::kNo)
Greg Daniel21774362020-09-14 10:36:43 -040092 , fCachedFramebuffers()
Greg Danielde4bbdb2021-04-13 14:23:23 -040093 , 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));
Greg Daniel00d6cf42021-03-05 22:50:08 +0000101 this->setFlags();
Brian Salomonaa6ca0a2019-01-24 16:03:07 -0500102 this->registerWithCacheWrapped(GrWrapCacheable::kNo);
Greg Danielb46add82019-01-02 14:51:29 -0500103}
104
Greg Daniel00d6cf42021-03-05 22:50:08 +0000105void GrVkRenderTarget::setFlags() {
Greg Danielde4bbdb2021-04-13 14:23:23 -0400106 if (this->wrapsSecondaryCommandBuffer()) {
107 return;
108 }
Greg Daniel2bc96d62021-09-13 13:08:02 -0400109 GrVkImage* nonMSAAAttachment = this->nonMSAAAttachment();
Greg Daniel00d6cf42021-03-05 22:50:08 +0000110 if (nonMSAAAttachment && nonMSAAAttachment->supportsInputAttachmentUsage()) {
Greg Daniel638b2e82020-08-27 14:29:00 -0400111 this->setVkRTSupportsInputAttachment();
112 }
113}
114
Greg Daniel6c6caf42020-05-29 12:11:05 -0400115sk_sp<GrVkRenderTarget> GrVkRenderTarget::MakeWrappedRenderTarget(
Greg Daniele2893f22020-10-13 10:20:06 -0400116 GrVkGpu* gpu,
117 SkISize dimensions,
118 int sampleCnt,
119 const GrVkImageInfo& info,
Greg Daniel6c6caf42020-05-29 12:11:05 -0400120 sk_sp<GrBackendSurfaceMutableStateImpl> mutableState) {
Greg Daniel001c67f2018-06-26 13:51:57 -0400121 SkASSERT(VK_NULL_HANDLE != info.fImage);
egdaniel50ead532016-07-13 14:23:26 -0700122 SkASSERT(1 == info.fLevelCount);
Brian Salomon72c7b982020-10-06 10:07:38 -0400123 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
Greg Daniel2bc96d62021-09-13 13:08:02 -0400130 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);
Greg Daniel00d6cf42021-03-05 22:50:08 +0000138 if (!wrappedAttachment) {
egdanielb2df0c22016-05-13 11:30:37 -0700139 return nullptr;
Greg Daniel164a9f02016-02-22 09:56:40 -0500140 }
141
Greg Daniel2bc96d62021-09-13 13:08:02 -0400142 sk_sp<GrVkImage> colorAttachment;
Greg Daniel00d6cf42021-03-05 22:50:08 +0000143 colorAttachment = std::move(wrappedAttachment);
144
Greg Daniel1e169372021-08-24 15:44:15 -0400145 if (!colorAttachment) {
Greg Daniel00d6cf42021-03-05 22:50:08 +0000146 return nullptr;
Greg Daniel164a9f02016-02-22 09:56:40 -0500147 }
148
Greg Daniel1e169372021-08-24 15:44:15 -0400149 GrVkRenderTarget* vkRT = new GrVkRenderTarget(gpu,dimensions, std::move(colorAttachment),
Greg Daniel00d6cf42021-03-05 22:50:08 +0000150 nullptr, CreateType::kDirectlyWrapped);
Greg Daniel001c67f2018-06-26 13:51:57 -0400151 return sk_sp<GrVkRenderTarget>(vkRT);
Greg Daniel164a9f02016-02-22 09:56:40 -0500152}
153
Greg Danielb46add82019-01-02 14:51:29 -0500154sk_sp<GrVkRenderTarget> GrVkRenderTarget::MakeSecondaryCBRenderTarget(
Brian Salomona56a7462020-02-07 14:17:25 -0500155 GrVkGpu* gpu, SkISize dimensions, const GrVkDrawableInfo& vkInfo) {
Greg Daniele2893f22020-10-13 10:20:06 -0400156 const GrVkRenderPass* rp = gpu->resourceProvider().findCompatibleExternalRenderPass(
157 vkInfo.fCompatibleRenderPass, vkInfo.fColorAttachmentIndex);
Greg Danielb46add82019-01-02 14:51:29 -0500158 if (!rp) {
159 return nullptr;
160 }
161
Greg Daniel8daf3b72019-07-30 09:57:26 -0400162 if (vkInfo.fSecondaryCommandBuffer == VK_NULL_HANDLE) {
Greg Daniel070cbaf2019-01-03 17:35:54 -0500163 return nullptr;
164 }
165
Greg Daniel7f3408b2020-06-03 13:31:00 -0400166 // 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;
Greg Daniel7b62dca2020-08-21 11:26:12 -0400171 info.fImageUsageFlags = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT |
172 VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
Greg Daniel7f3408b2020-06-03 13:31:00 -0400173
174 sk_sp<GrBackendSurfaceMutableStateImpl> mutableState(new GrBackendSurfaceMutableStateImpl(
175 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_QUEUE_FAMILY_IGNORED));
176
Greg Daniel2bc96d62021-09-13 13:08:02 -0400177 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);
Greg Daniel00d6cf42021-03-05 22:50:08 +0000186
Greg Danielde4bbdb2021-04-13 14:23:23 -0400187 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));
Greg Danielb46add82019-01-02 14:51:29 -0500198
199 return sk_sp<GrVkRenderTarget>(vkRT);
200}
201
Greg Danielde4bbdb2021-04-13 14:23:23 -0400202GrBackendFormat GrVkRenderTarget::backendFormat() const {
203 if (this->wrapsSecondaryCommandBuffer()) {
Greg Daniel2bc96d62021-09-13 13:08:02 -0400204 return fExternalFramebuffer->colorAttachment()->backendFormat();
Greg Danielde4bbdb2021-04-13 14:23:23 -0400205 }
Greg Daniel2bc96d62021-09-13 13:08:02 -0400206 return fColorAttachment->backendFormat();
Greg Danielde4bbdb2021-04-13 14:23:23 -0400207}
208
Greg Daniel2bc96d62021-09-13 13:08:02 -0400209GrVkImage* GrVkRenderTarget::nonMSAAAttachment() const {
Greg Daniel00d6cf42021-03-05 22:50:08 +0000210 if (fColorAttachment->numSamples() == 1) {
211 return fColorAttachment.get();
212 } else {
213 return fResolveAttachment.get();
214 }
215}
216
Greg Daniel2bc96d62021-09-13 13:08:02 -0400217GrVkImage* GrVkRenderTarget::dynamicMSAAAttachment() {
Greg Daniel60ec6172021-04-16 11:31:58 -0400218 if (fDynamicMSAAAttachment) {
219 return fDynamicMSAAAttachment.get();
220 }
Greg Daniel2bc96d62021-09-13 13:08:02 -0400221 const GrVkImage* nonMSAAColorAttachment = this->colorAttachment();
Greg Daniel60ec6172021-04-16 11:31:58 -0400222 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
Greg Daniel77435592021-09-22 13:55:44 -0400229 GrMemoryless memoryless =
230 gpu->vkCaps().supportsMemorylessAttachments() ? GrMemoryless::kYes : GrMemoryless::kNo;
231
Greg Daniel60ec6172021-04-16 11:31:58 -0400232 sk_sp<GrAttachment> msaaAttachment =
Greg Daniel6610bed2021-05-13 13:15:31 -0400233 rp->getDiscardableMSAAAttachment(nonMSAAColorAttachment->dimensions(),
234 format,
235 gpu->caps()->internalMultisampleCount(format),
Greg Daniel77435592021-09-22 13:55:44 -0400236 GrProtected(nonMSAAColorAttachment->isProtected()),
237 memoryless);
Greg Daniel60ec6172021-04-16 11:31:58 -0400238 if (!msaaAttachment) {
239 return nullptr;
240 }
Greg Daniel2bc96d62021-09-13 13:08:02 -0400241 fDynamicMSAAAttachment = sk_sp<GrVkImage>(static_cast<GrVkImage*>(msaaAttachment.release()));
Greg Daniel60ec6172021-04-16 11:31:58 -0400242 return fDynamicMSAAAttachment.get();
243}
244
Greg Daniel2bc96d62021-09-13 13:08:02 -0400245GrVkImage* GrVkRenderTarget::msaaAttachment() {
Greg Daniel60ec6172021-04-16 11:31:58 -0400246 return this->colorAttachment()->numSamples() == 1 ? this->dynamicMSAAAttachment()
247 : this->colorAttachment();
248}
249
Greg Daniel1e169372021-08-24 15:44:15 -0400250bool 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
Chris Daltone0fe23a2021-04-23 13:11:44 -0600267bool GrVkRenderTarget::completeStencilAttachment(GrAttachment* stencil, bool useMSAASurface) {
Greg Danielb46add82019-01-02 14:51:29 -0500268 SkASSERT(!this->wrapsSecondaryCommandBuffer());
Greg Daniel1e169372021-08-24 15:44:15 -0400269 SkASSERT(!useMSAASurface ||
270 this->numSamples() > 1 ||
271 this->getVkGpu()->vkCaps().supportsDiscardableMSAAForDMSAA());
Greg Daniel164a9f02016-02-22 09:56:40 -0500272 return true;
273}
274
Greg Daniel60ec6172021-04-16 11:31:58 -0400275sk_sp<GrVkFramebuffer> GrVkRenderTarget::externalFramebuffer() const {
276 return fExternalFramebuffer;
Greg Danielde4bbdb2021-04-13 14:23:23 -0400277}
278
Greg Daniel21774362020-09-14 10:36:43 -0400279GrVkResourceProvider::CompatibleRPHandle GrVkRenderTarget::compatibleRenderPassHandle(
Greg Daniel7acddf52020-12-16 15:15:51 -0500280 bool withResolve,
281 bool withStencil,
282 SelfDependencyFlags selfDepFlags,
283 LoadFromResolve loadFromResolve) {
Greg Daniel21774362020-09-14 10:36:43 -0400284 SkASSERT(!this->wrapsSecondaryCommandBuffer());
285
Greg Daniel805c6222021-04-20 12:44:48 -0400286 const GrVkFramebuffer* fb =
287 this->getFramebuffer(withResolve, withStencil, selfDepFlags, loadFromResolve);
288 if (!fb) {
289 return {};
Robert Phillips96f22372020-05-20 12:31:18 -0400290 }
291
Greg Daniel805c6222021-04-20 12:44:48 -0400292 return fb->compatibleRenderPassHandle();
293}
Greg Daniel21774362020-09-14 10:36:43 -0400294
Greg Daniel805c6222021-04-20 12:44:48 -0400295const 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();
Greg Daniel21774362020-09-14 10:36:43 -0400310}
311
Greg Daniela92d7872021-04-07 11:08:36 -0400312std::pair<const GrVkRenderPass*, GrVkResourceProvider::CompatibleRPHandle>
Greg Daniel805c6222021-04-20 12:44:48 -0400313GrVkRenderTarget::createSimpleRenderPass(bool withResolve,
314 bool withStencil,
315 SelfDependencyFlags selfDepFlags,
316 LoadFromResolve loadFromResolve) {
Robert Phillips96f22372020-05-20 12:31:18 -0400317 SkASSERT(!this->wrapsSecondaryCommandBuffer());
318
319 GrVkResourceProvider& rp = this->getVkGpu()->resourceProvider();
Greg Daniel805c6222021-04-20 12:44:48 -0400320
321 GrVkResourceProvider::CompatibleRPHandle handle;
322 const GrVkRenderPass* renderPass = rp.findCompatibleRenderPass(
323 this, &handle, withResolve, withStencil, selfDepFlags,
Greg Daniel7acddf52020-12-16 15:15:51 -0500324 loadFromResolve);
Greg Daniel805c6222021-04-20 12:44:48 -0400325 SkASSERT(!renderPass || handle.isValid());
326 return {renderPass, handle};
Greg Danielfa3adf72019-11-07 09:53:41 -0500327}
Greg Daniel164a9f02016-02-22 09:56:40 -0500328
Greg Daniel7acddf52020-12-16 15:15:51 -0500329const 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);
Greg Daniel805c6222021-04-20 12:44:48 -0400335 SkASSERT(cacheIndex < GrVkRenderTarget::kNumCachedFramebuffers);
Greg Daniel21774362020-09-14 10:36:43 -0400336 if (auto fb = fCachedFramebuffers[cacheIndex]) {
Greg Daniel805c6222021-04-20 12:44:48 -0400337 return fb.get();
Greg Danielfa3adf72019-11-07 09:53:41 -0500338 }
Greg Daniel21774362020-09-14 10:36:43 -0400339
Greg Daniel805c6222021-04-20 12:44:48 -0400340 this->createFramebuffer(withResolve, withStencil, selfDepFlags, loadFromResolve);
341 return fCachedFramebuffers[cacheIndex].get();
Greg Danielfa3adf72019-11-07 09:53:41 -0500342}
343
Greg Daniel805c6222021-04-20 12:44:48 -0400344void GrVkRenderTarget::createFramebuffer(bool withResolve,
345 bool withStencil,
346 SelfDependencyFlags selfDepFlags,
347 LoadFromResolve loadFromResolve) {
Greg Danielfa3adf72019-11-07 09:53:41 -0500348 SkASSERT(!this->wrapsSecondaryCommandBuffer());
Greg Danielfa3adf72019-11-07 09:53:41 -0500349 GrVkGpu* gpu = this->getVkGpu();
Robert Phillips96f22372020-05-20 12:31:18 -0400350
Greg Daniela92d7872021-04-07 11:08:36 -0400351 auto[renderPass, compatibleHandle] =
Greg Daniel805c6222021-04-20 12:44:48 -0400352 this->createSimpleRenderPass(withResolve, withStencil, selfDepFlags, loadFromResolve);
Greg Danieled984762019-11-07 17:15:45 -0500353 if (!renderPass) {
Greg Daniel805c6222021-04-20 12:44:48 -0400354 return;
Greg Danieled984762019-11-07 17:15:45 -0500355 }
Greg Daniela92d7872021-04-07 11:08:36 -0400356 SkASSERT(compatibleHandle.isValid());
Robert Phillips96f22372020-05-20 12:31:18 -0400357
Greg Daniel7acddf52020-12-16 15:15:51 -0500358 int cacheIndex =
359 renderpass_features_to_index(withResolve, withStencil, selfDepFlags, loadFromResolve);
Greg Daniel805c6222021-04-20 12:44:48 -0400360 SkASSERT(cacheIndex < GrVkRenderTarget::kNumCachedFramebuffers);
Greg Daniel21774362020-09-14 10:36:43 -0400361
Greg Daniel2bc96d62021-09-13 13:08:02 -0400362 GrVkImage* resolve = withResolve ? this->resolveAttachment() : nullptr;
363 GrVkImage* colorAttachment = withResolve ? this->msaaAttachment() : this->colorAttachment();
Greg Daniel7acddf52020-12-16 15:15:51 -0500364
Robert Phillips96f22372020-05-20 12:31:18 -0400365 // Stencil attachment view is stored in the base RT stencil attachment
Greg Daniel1e169372021-08-24 15:44:15 -0400366 bool useMSAA = this->numSamples() > 1 || withResolve;
Greg Daniel2bc96d62021-09-13 13:08:02 -0400367 GrVkImage* stencil = withStencil ? static_cast<GrVkImage*>(this->getStencilAttachment(useMSAA))
368 : nullptr;
Greg Daniele2893f22020-10-13 10:20:06 -0400369 fCachedFramebuffers[cacheIndex] =
Greg Daniel805c6222021-04-20 12:44:48 -0400370 GrVkFramebuffer::Make(gpu, this->dimensions(),
371 sk_sp<const GrVkRenderPass>(renderPass),
372 colorAttachment, resolve, stencil, compatibleHandle);
Greg Daniel164a9f02016-02-22 09:56:40 -0500373}
374
Robert Phillips96f22372020-05-20 12:31:18 -0400375void GrVkRenderTarget::getAttachmentsDescriptor(GrVkRenderPass::AttachmentsDescriptor* desc,
376 GrVkRenderPass::AttachmentFlags* attachmentFlags,
Greg Daniel7acddf52020-12-16 15:15:51 -0500377 bool withResolve,
Greg Daniel60ec6172021-04-16 11:31:58 -0400378 bool withStencil) {
Greg Danielb46add82019-01-02 14:51:29 -0500379 SkASSERT(!this->wrapsSecondaryCommandBuffer());
Greg Daniel2bc96d62021-09-13 13:08:02 -0400380 const GrVkImage* colorAttachment =
Greg Daniel60ec6172021-04-16 11:31:58 -0400381 withResolve ? this->msaaAttachment() : this->colorAttachment();
382
383 desc->fColor.fFormat = colorAttachment->imageFormat();
384 desc->fColor.fSamples = colorAttachment->numSamples();
Greg Daniel164a9f02016-02-22 09:56:40 -0500385 *attachmentFlags = GrVkRenderPass::kColor_AttachmentFlag;
386 uint32_t attachmentCount = 1;
Greg Daniel164a9f02016-02-22 09:56:40 -0500387
Greg Daniel7acddf52020-12-16 15:15:51 -0500388 if (withResolve) {
389 desc->fResolve.fFormat = desc->fColor.fFormat;
390 desc->fResolve.fSamples = 1;
391 *attachmentFlags |= GrVkRenderPass::kResolve_AttachmentFlag;
392 ++attachmentCount;
393 }
394
Robert Phillips96f22372020-05-20 12:31:18 -0400395 if (withStencil) {
Greg Daniel1e169372021-08-24 15:44:15 -0400396 bool useMSAA = this->numSamples() > 1 || withResolve;
397 const GrAttachment* stencil = this->getStencilAttachment(useMSAA);
Robert Phillips96f22372020-05-20 12:31:18 -0400398 SkASSERT(stencil);
Greg Daniel2bc96d62021-09-13 13:08:02 -0400399 const GrVkImage* vkStencil = static_cast<const GrVkImage*>(stencil);
Jim Van Verthbb604082020-04-13 13:05:07 -0400400 desc->fStencil.fFormat = vkStencil->imageFormat();
Brian Salomonbdecacf2018-02-02 20:32:49 -0500401 desc->fStencil.fSamples = vkStencil->numSamples();
Chris Dalton57ab06c2021-04-22 12:57:28 -0600402 SkASSERT(desc->fStencil.fSamples == desc->fColor.fSamples);
Greg Daniel164a9f02016-02-22 09:56:40 -0500403 *attachmentFlags |= GrVkRenderPass::kStencil_AttachmentFlag;
404 ++attachmentCount;
405 }
406 desc->fAttachmentCount = attachmentCount;
407}
408
Robert Phillips24e2f6e2020-06-26 08:30:07 -0400409void 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
Greg Daniel1e169372021-08-24 15:44:15 -0400421 if (vkCaps.programInfoWillUseDiscardableMSAA(programInfo)) {
Greg Daniela1b5d7e2020-12-17 10:36:58 -0500422 desc->fResolve.fFormat = desc->fColor.fFormat;
423 desc->fResolve.fSamples = 1;
424 *flags |= GrVkRenderPass::kResolve_AttachmentFlag;
425 ++attachmentCount;
426 }
427
Chris Dalton57ab06c2021-04-22 12:57:28 -0600428 SkASSERT(!programInfo.isStencilEnabled() || programInfo.needsStencil());
429 if (programInfo.needsStencil()) {
Greg Daniel8ade5e82020-10-07 13:09:48 -0400430 VkFormat stencilFormat = vkCaps.preferredStencilFormat();
431 desc->fStencil.fFormat = stencilFormat;
Chris Dalton57ab06c2021-04-22 12:57:28 -0600432 desc->fStencil.fSamples = programInfo.numSamples();
433 SkASSERT(desc->fStencil.fSamples == desc->fColor.fSamples);
Robert Phillips24e2f6e2020-06-26 08:30:07 -0400434 *flags |= GrVkRenderPass::kStencil_AttachmentFlag;
435 ++attachmentCount;
436 }
437 desc->fAttachmentCount = attachmentCount;
438}
439
Greg Daniel164a9f02016-02-22 09:56:40 -0500440GrVkRenderTarget::~GrVkRenderTarget() {
441 // either release or abandon should have been called by the owner of this object.
Greg Daniel00d6cf42021-03-05 22:50:08 +0000442 SkASSERT(!fColorAttachment);
443 SkASSERT(!fResolveAttachment);
Greg Daniel805c6222021-04-20 12:44:48 -0400444 SkASSERT(!fDynamicMSAAAttachment);
Greg Daniel21774362020-09-14 10:36:43 -0400445
Greg Daniel805c6222021-04-20 12:44:48 -0400446 for (int i = 0; i < kNumCachedFramebuffers; ++i) {
Greg Daniel21774362020-09-14 10:36:43 -0400447 SkASSERT(!fCachedFramebuffers[i]);
Greg Daniel21774362020-09-14 10:36:43 -0400448 }
Greg Daniel37fd6582020-09-14 12:36:09 -0400449
450 SkASSERT(!fCachedInputDescriptorSet);
Greg Daniel164a9f02016-02-22 09:56:40 -0500451}
452
Greg Daniel164a9f02016-02-22 09:56:40 -0500453void GrVkRenderTarget::releaseInternalObjects() {
Greg Daniel00d6cf42021-03-05 22:50:08 +0000454 fColorAttachment.reset();
455 fResolveAttachment.reset();
Greg Daniel805c6222021-04-20 12:44:48 -0400456 fDynamicMSAAAttachment.reset();
Greg Daniel21774362020-09-14 10:36:43 -0400457
Greg Daniel805c6222021-04-20 12:44:48 -0400458 for (int i = 0; i < kNumCachedFramebuffers; ++i) {
Greg Daniel21774362020-09-14 10:36:43 -0400459 if (fCachedFramebuffers[i]) {
Greg Daniel805c6222021-04-20 12:44:48 -0400460 fCachedFramebuffers[i].reset();
Greg Daniel21774362020-09-14 10:36:43 -0400461 }
Greg Daniel164a9f02016-02-22 09:56:40 -0500462 }
Greg Daniel21774362020-09-14 10:36:43 -0400463
Greg Daniel37fd6582020-09-14 12:36:09 -0400464 if (fCachedInputDescriptorSet) {
465 fCachedInputDescriptorSet->recycle();
466 fCachedInputDescriptorSet = nullptr;
467 }
468
Greg Danielde4bbdb2021-04-13 14:23:23 -0400469 fExternalFramebuffer.reset();
Greg Daniel164a9f02016-02-22 09:56:40 -0500470}
471
Greg Daniel164a9f02016-02-22 09:56:40 -0500472void GrVkRenderTarget::onRelease() {
473 this->releaseInternalObjects();
Greg Daniel164a9f02016-02-22 09:56:40 -0500474 GrRenderTarget::onRelease();
475}
476
477void GrVkRenderTarget::onAbandon() {
Greg Danielf0e04f02019-12-04 15:17:54 -0500478 this->releaseInternalObjects();
Greg Daniel164a9f02016-02-22 09:56:40 -0500479 GrRenderTarget::onAbandon();
480}
481
Robert Phillipsb67821d2017-12-13 15:00:45 -0500482GrBackendRenderTarget GrVkRenderTarget::getBackendRenderTarget() const {
Greg Danielb46add82019-01-02 14:51:29 -0500483 SkASSERT(!this->wrapsSecondaryCommandBuffer());
Greg Daniel80ef70e2021-03-10 16:17:21 -0500484 // This should only get called with a non-released GrVkRenderTargets.
485 SkASSERT(!this->wasDestroyed());
Greg Daniel00d6cf42021-03-05 22:50:08 +0000486 // If we have a resolve attachment that is what we return for the backend render target
Greg Daniel2bc96d62021-09-13 13:08:02 -0400487 const GrVkImage* beAttachment = this->externalAttachment();
Greg Daniel00d6cf42021-03-05 22:50:08 +0000488 return GrBackendRenderTarget(beAttachment->width(), beAttachment->height(),
489 beAttachment->vkImageInfo(), beAttachment->getMutableState());
Brian Salomon72c7b982020-10-06 10:07:38 -0400490}
491
Greg Daniel164a9f02016-02-22 09:56:40 -0500492GrVkGpu* GrVkRenderTarget::getVkGpu() const {
493 SkASSERT(!this->wasDestroyed());
494 return static_cast<GrVkGpu*>(this->getGpu());
495}