blob: b6a40324d4caedab926ed9a33fbafada720401c9 [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"
15#include "src/gpu/vk/GrVkAttachment.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050016#include "src/gpu/vk/GrVkCommandBuffer.h"
Greg Daniel37fd6582020-09-14 12:36:09 -040017#include "src/gpu/vk/GrVkDescriptorSet.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050018#include "src/gpu/vk/GrVkFramebuffer.h"
19#include "src/gpu/vk/GrVkGpu.h"
20#include "src/gpu/vk/GrVkImageView.h"
21#include "src/gpu/vk/GrVkResourceProvider.h"
22#include "src/gpu/vk/GrVkUtil.h"
Greg Daniel164a9f02016-02-22 09:56:40 -050023
Mike Kleinc0bd9f92019-04-23 12:05:21 -050024#include "include/gpu/vk/GrVkTypes.h"
jvanverthfd359ca2016-03-18 11:57:24 -070025
Greg Daniel164a9f02016-02-22 09:56:40 -050026#define VK_CALL(GPU, X) GR_VK_CALL(GPU->vkInterface(), X)
27
Greg Daniel7acddf52020-12-16 15:15:51 -050028static int renderpass_features_to_index(bool hasResolve, bool hasStencil,
29 GrVkRenderPass::SelfDependencyFlags selfDepFlags,
30 GrVkRenderPass::LoadFromResolve loadFromReslove) {
31 int index = 0;
32 if (hasResolve) {
33 index += 1;
34 }
35 if (hasStencil) {
Greg Daniel21774362020-09-14 10:36:43 -040036 index += 2;
37 }
Greg Daniel7acddf52020-12-16 15:15:51 -050038 if (selfDepFlags & GrVkRenderPass::SelfDependencyFlags::kForInputAttachment) {
Greg Daniel21774362020-09-14 10:36:43 -040039 index += 4;
40 }
Greg Daniel7acddf52020-12-16 15:15:51 -050041 if (selfDepFlags & GrVkRenderPass::SelfDependencyFlags::kForNonCoherentAdvBlend) {
42 index += 8;
43 }
44 if (loadFromReslove == GrVkRenderPass::LoadFromResolve::kLoad) {
45 index += 16;
46 }
Greg Daniel21774362020-09-14 10:36:43 -040047 return index;
48}
49
Greg Daniel164a9f02016-02-22 09:56:40 -050050// We're virtually derived from GrSurface (via GrRenderTarget) so its
51// constructor must be explicitly called.
52GrVkRenderTarget::GrVkRenderTarget(GrVkGpu* gpu,
Brian Salomona56a7462020-02-07 14:17:25 -050053 SkISize dimensions,
Greg Daniel00d6cf42021-03-05 22:50:08 +000054 sk_sp<GrVkAttachment> colorAttachment,
55 sk_sp<GrVkAttachment> resolveAttachment,
56 CreateType createType)
57 : GrSurface(gpu, dimensions,
58 colorAttachment->isProtected() ? GrProtected::kYes : GrProtected::kNo)
Greg Danielb46add82019-01-02 14:51:29 -050059 // for the moment we only support 1:1 color to stencil
Greg Daniel00d6cf42021-03-05 22:50:08 +000060 , GrRenderTarget(gpu, dimensions, colorAttachment->numSamples(),
61 colorAttachment->isProtected() ? GrProtected::kYes : GrProtected::kNo)
62 , fColorAttachment(std::move(colorAttachment))
63 , fResolveAttachment(std::move(resolveAttachment))
Greg Daniel21774362020-09-14 10:36:43 -040064 , fCachedFramebuffers()
65 , fCachedRenderPasses() {
Greg Daniel00d6cf42021-03-05 22:50:08 +000066 SkASSERT(fColorAttachment);
67 SkASSERT(!resolveAttachment ||
68 (fResolveAttachment->isProtected() == fColorAttachment->isProtected()));
69 SkASSERT(SkToBool(fColorAttachment->vkUsageFlags() & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT));
70 this->setFlags();
71 if (createType == CreateType::kDirectlyWrapped) {
72 this->registerWithCacheWrapped(GrWrapCacheable::kNo);
73 }
Greg Daniel7b62dca2020-08-21 11:26:12 -040074}
Greg Daniel164a9f02016-02-22 09:56:40 -050075
Greg Danielb46add82019-01-02 14:51:29 -050076GrVkRenderTarget::GrVkRenderTarget(GrVkGpu* gpu,
Brian Salomona56a7462020-02-07 14:17:25 -050077 SkISize dimensions,
Greg Daniel00d6cf42021-03-05 22:50:08 +000078 sk_sp<GrVkAttachment> colorAttachment,
Greg Danielb46add82019-01-02 14:51:29 -050079 const GrVkRenderPass* renderPass,
Greg Daniel8daf3b72019-07-30 09:57:26 -040080 VkCommandBuffer secondaryCommandBuffer)
Greg Daniel00d6cf42021-03-05 22:50:08 +000081 : GrSurface(gpu, dimensions,
82 colorAttachment->isProtected() ? GrProtected::kYes : GrProtected::kNo)
83 , GrRenderTarget(gpu, dimensions, 1,
84 colorAttachment->isProtected() ? GrProtected::kYes : GrProtected::kNo)
85 , fColorAttachment(std::move(colorAttachment))
Greg Daniel21774362020-09-14 10:36:43 -040086 , fCachedFramebuffers()
87 , fCachedRenderPasses()
Greg Danielb46add82019-01-02 14:51:29 -050088 , fSecondaryCommandBuffer(secondaryCommandBuffer) {
Greg Daniel00d6cf42021-03-05 22:50:08 +000089 SkASSERT(fColorAttachment->numSamples() == 1);
Greg Daniel8daf3b72019-07-30 09:57:26 -040090 SkASSERT(fSecondaryCommandBuffer != VK_NULL_HANDLE);
Greg Daniel00d6cf42021-03-05 22:50:08 +000091 SkASSERT(SkToBool(fColorAttachment->vkUsageFlags() & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT));
92 SkASSERT(!SkToBool(fColorAttachment->vkUsageFlags() & VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT));
93 this->setFlags();
Brian Salomonaa6ca0a2019-01-24 16:03:07 -050094 this->registerWithCacheWrapped(GrWrapCacheable::kNo);
Greg Daniel21774362020-09-14 10:36:43 -040095 // We use the cached renderpass with no stencil and no extra dependencies to hold the external
96 // render pass.
Greg Daniel7acddf52020-12-16 15:15:51 -050097 int exteralRPIndex = renderpass_features_to_index(false, false, SelfDependencyFlags::kNone,
98 LoadFromResolve::kNo);
Greg Daniel21774362020-09-14 10:36:43 -040099 fCachedRenderPasses[exteralRPIndex] = renderPass;
Greg Danielb46add82019-01-02 14:51:29 -0500100}
101
Greg Daniel00d6cf42021-03-05 22:50:08 +0000102void GrVkRenderTarget::setFlags() {
103 GrVkAttachment* nonMSAAAttachment = this->nonMSAAAttachment();
104 if (nonMSAAAttachment && nonMSAAAttachment->supportsInputAttachmentUsage()) {
Greg Daniel638b2e82020-08-27 14:29:00 -0400105 this->setVkRTSupportsInputAttachment();
106 }
107}
108
Greg Daniel6c6caf42020-05-29 12:11:05 -0400109sk_sp<GrVkRenderTarget> GrVkRenderTarget::MakeWrappedRenderTarget(
Greg Daniele2893f22020-10-13 10:20:06 -0400110 GrVkGpu* gpu,
111 SkISize dimensions,
112 int sampleCnt,
113 const GrVkImageInfo& info,
Greg Daniel6c6caf42020-05-29 12:11:05 -0400114 sk_sp<GrBackendSurfaceMutableStateImpl> mutableState) {
Greg Daniel001c67f2018-06-26 13:51:57 -0400115 SkASSERT(VK_NULL_HANDLE != info.fImage);
egdaniel50ead532016-07-13 14:23:26 -0700116 SkASSERT(1 == info.fLevelCount);
Brian Salomon72c7b982020-10-06 10:07:38 -0400117 SkASSERT(sampleCnt >= 1 && info.fSampleCount >= 1);
118
119 int wrappedImageSampleCnt = static_cast<int>(info.fSampleCount);
120 if (sampleCnt != wrappedImageSampleCnt && wrappedImageSampleCnt != 1) {
121 return nullptr;
122 }
123
Greg Daniel00d6cf42021-03-05 22:50:08 +0000124 sk_sp<GrVkAttachment> wrappedAttachment =
125 GrVkAttachment::MakeWrapped(gpu, dimensions, info, std::move(mutableState),
126 GrAttachment::UsageFlags::kColorAttachment,
127 kBorrow_GrWrapOwnership, GrWrapCacheable::kNo);
128 if (!wrappedAttachment) {
egdanielb2df0c22016-05-13 11:30:37 -0700129 return nullptr;
Greg Daniel164a9f02016-02-22 09:56:40 -0500130 }
131
Greg Daniel00d6cf42021-03-05 22:50:08 +0000132 sk_sp<GrVkAttachment> colorAttachment;
133 colorAttachment = std::move(wrappedAttachment);
134
135 if (!colorAttachment) {
136 return nullptr;
Greg Daniel164a9f02016-02-22 09:56:40 -0500137 }
138
Greg Daniel00d6cf42021-03-05 22:50:08 +0000139 GrVkRenderTarget* vkRT = new GrVkRenderTarget(gpu, dimensions, std::move(colorAttachment),
140 nullptr, CreateType::kDirectlyWrapped);
Greg Daniel001c67f2018-06-26 13:51:57 -0400141 return sk_sp<GrVkRenderTarget>(vkRT);
Greg Daniel164a9f02016-02-22 09:56:40 -0500142}
143
Greg Danielb46add82019-01-02 14:51:29 -0500144sk_sp<GrVkRenderTarget> GrVkRenderTarget::MakeSecondaryCBRenderTarget(
Brian Salomona56a7462020-02-07 14:17:25 -0500145 GrVkGpu* gpu, SkISize dimensions, const GrVkDrawableInfo& vkInfo) {
Greg Daniele2893f22020-10-13 10:20:06 -0400146 const GrVkRenderPass* rp = gpu->resourceProvider().findCompatibleExternalRenderPass(
147 vkInfo.fCompatibleRenderPass, vkInfo.fColorAttachmentIndex);
Greg Danielb46add82019-01-02 14:51:29 -0500148 if (!rp) {
149 return nullptr;
150 }
151
Greg Daniel8daf3b72019-07-30 09:57:26 -0400152 if (vkInfo.fSecondaryCommandBuffer == VK_NULL_HANDLE) {
Greg Daniel070cbaf2019-01-03 17:35:54 -0500153 return nullptr;
154 }
155
Greg Daniel7f3408b2020-06-03 13:31:00 -0400156 // We only set the few properties of the GrVkImageInfo that we know like layout and format. The
157 // others we keep at the default "null" values.
158 GrVkImageInfo info;
159 info.fImageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
160 info.fFormat = vkInfo.fFormat;
Greg Daniel7b62dca2020-08-21 11:26:12 -0400161 info.fImageUsageFlags = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT |
162 VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
Greg Daniel7f3408b2020-06-03 13:31:00 -0400163
164 sk_sp<GrBackendSurfaceMutableStateImpl> mutableState(new GrBackendSurfaceMutableStateImpl(
165 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_QUEUE_FAMILY_IGNORED));
166
Greg Daniel00d6cf42021-03-05 22:50:08 +0000167 sk_sp<GrVkAttachment> scbAttachment =
168 GrVkAttachment::MakeWrapped(gpu, dimensions, info, std::move(mutableState),
169 GrAttachment::UsageFlags::kColorAttachment,
170 kBorrow_GrWrapOwnership, GrWrapCacheable::kNo, true);
171
172 GrVkRenderTarget* vkRT = new GrVkRenderTarget(gpu, dimensions, std::move(scbAttachment),
Greg Daniel6c6caf42020-05-29 12:11:05 -0400173 rp, vkInfo.fSecondaryCommandBuffer);
Greg Danielb46add82019-01-02 14:51:29 -0500174
175 return sk_sp<GrVkRenderTarget>(vkRT);
176}
177
Greg Daniel00d6cf42021-03-05 22:50:08 +0000178GrVkAttachment* GrVkRenderTarget::nonMSAAAttachment() const {
179 if (fColorAttachment->numSamples() == 1) {
180 return fColorAttachment.get();
181 } else {
182 return fResolveAttachment.get();
183 }
184}
185
Greg Daniel164a9f02016-02-22 09:56:40 -0500186bool GrVkRenderTarget::completeStencilAttachment() {
Greg Danielb46add82019-01-02 14:51:29 -0500187 SkASSERT(!this->wrapsSecondaryCommandBuffer());
Greg Daniel164a9f02016-02-22 09:56:40 -0500188 return true;
189}
190
Greg Daniel21774362020-09-14 10:36:43 -0400191const GrVkRenderPass* GrVkRenderTarget::externalRenderPass() const {
192 SkASSERT(this->wrapsSecondaryCommandBuffer());
193 // We use the cached render pass with no attachments or self dependencies to hold the
194 // external render pass.
Greg Daniel7acddf52020-12-16 15:15:51 -0500195 int exteralRPIndex = renderpass_features_to_index(false, false, SelfDependencyFlags::kNone,
196 LoadFromResolve::kNo);
Greg Daniel21774362020-09-14 10:36:43 -0400197 return fCachedRenderPasses[exteralRPIndex];
198}
199
200GrVkResourceProvider::CompatibleRPHandle GrVkRenderTarget::compatibleRenderPassHandle(
Greg Daniel7acddf52020-12-16 15:15:51 -0500201 bool withResolve,
202 bool withStencil,
203 SelfDependencyFlags selfDepFlags,
204 LoadFromResolve loadFromResolve) {
Greg Daniel21774362020-09-14 10:36:43 -0400205 SkASSERT(!this->wrapsSecondaryCommandBuffer());
206
Greg Daniel7acddf52020-12-16 15:15:51 -0500207 int cacheIndex =
208 renderpass_features_to_index(withResolve, withStencil, selfDepFlags, loadFromResolve);
Greg Daniel21774362020-09-14 10:36:43 -0400209 SkASSERT(cacheIndex < GrVkRenderTarget::kNumCachedRenderPasses);
210
211 GrVkResourceProvider::CompatibleRPHandle* pRPHandle;
212 pRPHandle = &fCompatibleRPHandles[cacheIndex];
213
214 if (!pRPHandle->isValid()) {
Greg Daniel7acddf52020-12-16 15:15:51 -0500215 this->createSimpleRenderPass(withResolve, withStencil, selfDepFlags, loadFromResolve);
Robert Phillips96f22372020-05-20 12:31:18 -0400216 }
217
Greg Daniel21774362020-09-14 10:36:43 -0400218#ifdef SK_DEBUG
219 const GrVkRenderPass* rp = fCachedRenderPasses[cacheIndex];
220 SkASSERT(pRPHandle->isValid() == SkToBool(rp));
221 if (rp) {
222 SkASSERT(selfDepFlags == rp->selfDependencyFlags());
223 }
224#endif
225
226 return *pRPHandle;
227}
228
Greg Daniel7acddf52020-12-16 15:15:51 -0500229const GrVkRenderPass* GrVkRenderTarget::getSimpleRenderPass(bool withResolve,
230 bool withStencil,
231 SelfDependencyFlags selfDepFlags,
232 LoadFromResolve loadFromResolve) {
233 int cacheIndex = renderpass_features_to_index(withResolve, withStencil, selfDepFlags,
234 loadFromResolve);
Greg Daniel21774362020-09-14 10:36:43 -0400235 SkASSERT(cacheIndex < GrVkRenderTarget::kNumCachedRenderPasses);
236 if (const GrVkRenderPass* rp = fCachedRenderPasses[cacheIndex]) {
237 return rp;
238 }
239
Greg Daniel7acddf52020-12-16 15:15:51 -0500240 return this->createSimpleRenderPass(withResolve, withStencil, selfDepFlags, loadFromResolve);
Robert Phillips96f22372020-05-20 12:31:18 -0400241}
242
Greg Daniel7acddf52020-12-16 15:15:51 -0500243const GrVkRenderPass* GrVkRenderTarget::createSimpleRenderPass(bool withResolve,
244 bool withStencil,
245 SelfDependencyFlags selfDepFlags,
246 LoadFromResolve loadFromResolve) {
Robert Phillips96f22372020-05-20 12:31:18 -0400247 SkASSERT(!this->wrapsSecondaryCommandBuffer());
248
249 GrVkResourceProvider& rp = this->getVkGpu()->resourceProvider();
Greg Daniel7acddf52020-12-16 15:15:51 -0500250 int cacheIndex = renderpass_features_to_index(withResolve, withStencil, selfDepFlags,
251 loadFromResolve);
Greg Daniel21774362020-09-14 10:36:43 -0400252 SkASSERT(cacheIndex < GrVkRenderTarget::kNumCachedRenderPasses);
253 SkASSERT(!fCachedRenderPasses[cacheIndex]);
254 fCachedRenderPasses[cacheIndex] = rp.findCompatibleRenderPass(
Greg Daniel7acddf52020-12-16 15:15:51 -0500255 *this, &fCompatibleRPHandles[cacheIndex], withResolve, withStencil, selfDepFlags,
256 loadFromResolve);
Greg Daniel21774362020-09-14 10:36:43 -0400257 return fCachedRenderPasses[cacheIndex];
Greg Danielfa3adf72019-11-07 09:53:41 -0500258}
Greg Daniel164a9f02016-02-22 09:56:40 -0500259
Greg Daniel7acddf52020-12-16 15:15:51 -0500260const GrVkFramebuffer* GrVkRenderTarget::getFramebuffer(bool withResolve,
261 bool withStencil,
262 SelfDependencyFlags selfDepFlags,
263 LoadFromResolve loadFromResolve) {
264 int cacheIndex =
265 renderpass_features_to_index(withResolve, withStencil, selfDepFlags, loadFromResolve);
Greg Daniel21774362020-09-14 10:36:43 -0400266 SkASSERT(cacheIndex < GrVkRenderTarget::kNumCachedRenderPasses);
267 if (auto fb = fCachedFramebuffers[cacheIndex]) {
268 return fb;
Greg Danielfa3adf72019-11-07 09:53:41 -0500269 }
Greg Daniel21774362020-09-14 10:36:43 -0400270
Greg Daniel7acddf52020-12-16 15:15:51 -0500271 return this->createFramebuffer(withResolve, withStencil, selfDepFlags, loadFromResolve);
Greg Danielfa3adf72019-11-07 09:53:41 -0500272}
273
Greg Daniel7acddf52020-12-16 15:15:51 -0500274const GrVkFramebuffer* GrVkRenderTarget::createFramebuffer(bool withResolve,
275 bool withStencil,
276 SelfDependencyFlags selfDepFlags,
277 LoadFromResolve loadFromResolve) {
Greg Danielfa3adf72019-11-07 09:53:41 -0500278 SkASSERT(!this->wrapsSecondaryCommandBuffer());
Greg Danielfa3adf72019-11-07 09:53:41 -0500279 GrVkGpu* gpu = this->getVkGpu();
Robert Phillips96f22372020-05-20 12:31:18 -0400280
Greg Daniel7acddf52020-12-16 15:15:51 -0500281 const GrVkRenderPass* renderPass =
282 this->getSimpleRenderPass(withResolve, withStencil, selfDepFlags, loadFromResolve);
Greg Danieled984762019-11-07 17:15:45 -0500283 if (!renderPass) {
284 return nullptr;
285 }
Robert Phillips96f22372020-05-20 12:31:18 -0400286
Greg Daniel7acddf52020-12-16 15:15:51 -0500287 int cacheIndex =
288 renderpass_features_to_index(withResolve, withStencil, selfDepFlags, loadFromResolve);
Greg Daniel21774362020-09-14 10:36:43 -0400289 SkASSERT(cacheIndex < GrVkRenderTarget::kNumCachedRenderPasses);
290
Greg Daniel7acddf52020-12-16 15:15:51 -0500291 const GrVkImageView* resolveView = withResolve ? this->resolveAttachmentView() : nullptr;
292
Robert Phillips96f22372020-05-20 12:31:18 -0400293 // Stencil attachment view is stored in the base RT stencil attachment
294 const GrVkImageView* stencilView = withStencil ? this->stencilAttachmentView() : nullptr;
Greg Daniele2893f22020-10-13 10:20:06 -0400295 fCachedFramebuffers[cacheIndex] =
296 GrVkFramebuffer::Create(gpu, this->width(), this->height(), renderPass,
Greg Daniel00d6cf42021-03-05 22:50:08 +0000297 this->colorAttachmentView(), resolveView, stencilView);
Robert Phillips96f22372020-05-20 12:31:18 -0400298
Greg Daniel21774362020-09-14 10:36:43 -0400299 return fCachedFramebuffers[cacheIndex];
Greg Daniel164a9f02016-02-22 09:56:40 -0500300}
301
Robert Phillips96f22372020-05-20 12:31:18 -0400302void GrVkRenderTarget::getAttachmentsDescriptor(GrVkRenderPass::AttachmentsDescriptor* desc,
303 GrVkRenderPass::AttachmentFlags* attachmentFlags,
Greg Daniel7acddf52020-12-16 15:15:51 -0500304 bool withResolve,
Robert Phillips96f22372020-05-20 12:31:18 -0400305 bool withStencil) const {
Greg Danielb46add82019-01-02 14:51:29 -0500306 SkASSERT(!this->wrapsSecondaryCommandBuffer());
Greg Daniel00d6cf42021-03-05 22:50:08 +0000307 desc->fColor.fFormat = fColorAttachment->imageFormat();
308 desc->fColor.fSamples = fColorAttachment->numSamples();
Greg Daniel164a9f02016-02-22 09:56:40 -0500309 *attachmentFlags = GrVkRenderPass::kColor_AttachmentFlag;
310 uint32_t attachmentCount = 1;
Greg Daniel164a9f02016-02-22 09:56:40 -0500311
Greg Daniel7acddf52020-12-16 15:15:51 -0500312 if (withResolve) {
313 desc->fResolve.fFormat = desc->fColor.fFormat;
314 desc->fResolve.fSamples = 1;
315 *attachmentFlags |= GrVkRenderPass::kResolve_AttachmentFlag;
316 ++attachmentCount;
317 }
318
Robert Phillips96f22372020-05-20 12:31:18 -0400319 if (withStencil) {
Greg Danielc0d69152020-10-08 14:59:00 -0400320 const GrAttachment* stencil = this->getStencilAttachment();
Robert Phillips96f22372020-05-20 12:31:18 -0400321 SkASSERT(stencil);
Greg Danielc0d69152020-10-08 14:59:00 -0400322 const GrVkAttachment* vkStencil = static_cast<const GrVkAttachment*>(stencil);
Jim Van Verthbb604082020-04-13 13:05:07 -0400323 desc->fStencil.fFormat = vkStencil->imageFormat();
Brian Salomonbdecacf2018-02-02 20:32:49 -0500324 desc->fStencil.fSamples = vkStencil->numSamples();
Chris Dalton60061052019-11-11 16:37:24 -0700325#ifdef SK_DEBUG
326 if (this->getVkGpu()->caps()->mixedSamplesSupport()) {
327 SkASSERT(desc->fStencil.fSamples >= desc->fColor.fSamples);
328 } else {
329 SkASSERT(desc->fStencil.fSamples == desc->fColor.fSamples);
330 }
331#endif
Greg Daniel164a9f02016-02-22 09:56:40 -0500332 *attachmentFlags |= GrVkRenderPass::kStencil_AttachmentFlag;
333 ++attachmentCount;
334 }
335 desc->fAttachmentCount = attachmentCount;
336}
337
Robert Phillips24e2f6e2020-06-26 08:30:07 -0400338void GrVkRenderTarget::ReconstructAttachmentsDescriptor(const GrVkCaps& vkCaps,
339 const GrProgramInfo& programInfo,
340 GrVkRenderPass::AttachmentsDescriptor* desc,
341 GrVkRenderPass::AttachmentFlags* flags) {
342 VkFormat format;
343 SkAssertResult(programInfo.backendFormat().asVkFormat(&format));
344
345 desc->fColor.fFormat = format;
346 desc->fColor.fSamples = programInfo.numSamples();
347 *flags = GrVkRenderPass::kColor_AttachmentFlag;
348 uint32_t attachmentCount = 1;
349
Greg Daniela1b5d7e2020-12-17 10:36:58 -0500350 if (programInfo.targetSupportsVkResolveLoad() && vkCaps.preferDiscardableMSAAAttachment()) {
351 desc->fResolve.fFormat = desc->fColor.fFormat;
352 desc->fResolve.fSamples = 1;
353 *flags |= GrVkRenderPass::kResolve_AttachmentFlag;
354 ++attachmentCount;
355 }
356
Robert Phillips24e2f6e2020-06-26 08:30:07 -0400357 SkASSERT(!programInfo.isStencilEnabled() || programInfo.numStencilSamples());
358 if (programInfo.numStencilSamples()) {
Greg Daniel8ade5e82020-10-07 13:09:48 -0400359 VkFormat stencilFormat = vkCaps.preferredStencilFormat();
360 desc->fStencil.fFormat = stencilFormat;
Robert Phillips24e2f6e2020-06-26 08:30:07 -0400361 desc->fStencil.fSamples = programInfo.numStencilSamples();
362#ifdef SK_DEBUG
363 if (vkCaps.mixedSamplesSupport()) {
364 SkASSERT(desc->fStencil.fSamples >= desc->fColor.fSamples);
365 } else {
366 SkASSERT(desc->fStencil.fSamples == desc->fColor.fSamples);
367 }
368#endif
369 *flags |= GrVkRenderPass::kStencil_AttachmentFlag;
370 ++attachmentCount;
371 }
372 desc->fAttachmentCount = attachmentCount;
373}
374
Greg Daniel7acddf52020-12-16 15:15:51 -0500375const GrVkDescriptorSet* GrVkRenderTarget::inputDescSet(GrVkGpu* gpu, bool forResolve) {
Greg Daniel00d6cf42021-03-05 22:50:08 +0000376 SkASSERT((forResolve && fResolveAttachment->supportsInputAttachmentUsage()) ||
377 (!forResolve && fColorAttachment->supportsInputAttachmentUsage()));
Greg Daniel7acddf52020-12-16 15:15:51 -0500378 SkASSERT(this->numSamples() <= 1 || forResolve);
Greg Daniel00d6cf42021-03-05 22:50:08 +0000379
Greg Daniel37fd6582020-09-14 12:36:09 -0400380 if (fCachedInputDescriptorSet) {
381 return fCachedInputDescriptorSet;
382 }
383 fCachedInputDescriptorSet = gpu->resourceProvider().getInputDescriptorSet();
384
385 if (!fCachedInputDescriptorSet) {
386 return nullptr;
387 }
388
389 VkDescriptorImageInfo imageInfo;
390 memset(&imageInfo, 0, sizeof(VkDescriptorImageInfo));
391 imageInfo.sampler = VK_NULL_HANDLE;
Greg Daniel7acddf52020-12-16 15:15:51 -0500392 imageInfo.imageView = forResolve ? this->resolveAttachmentView()->imageView()
393 : this->colorAttachmentView()->imageView();
394 imageInfo.imageLayout = forResolve ? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
395 : VK_IMAGE_LAYOUT_GENERAL;
Greg Daniel37fd6582020-09-14 12:36:09 -0400396
397 VkWriteDescriptorSet writeInfo;
398 memset(&writeInfo, 0, sizeof(VkWriteDescriptorSet));
399 writeInfo.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
400 writeInfo.pNext = nullptr;
401 writeInfo.dstSet = *fCachedInputDescriptorSet->descriptorSet();
402 writeInfo.dstBinding = GrVkUniformHandler::kInputBinding;
403 writeInfo.dstArrayElement = 0;
404 writeInfo.descriptorCount = 1;
405 writeInfo.descriptorType = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT;
406 writeInfo.pImageInfo = &imageInfo;
407 writeInfo.pBufferInfo = nullptr;
408 writeInfo.pTexelBufferView = nullptr;
409
410 GR_VK_CALL(gpu->vkInterface(), UpdateDescriptorSets(gpu->device(), 1, &writeInfo, 0, nullptr));
411
412 return fCachedInputDescriptorSet;
413}
414
Greg Daniel164a9f02016-02-22 09:56:40 -0500415GrVkRenderTarget::~GrVkRenderTarget() {
416 // either release or abandon should have been called by the owner of this object.
Greg Daniel00d6cf42021-03-05 22:50:08 +0000417 SkASSERT(!fColorAttachment);
418 SkASSERT(!fResolveAttachment);
Greg Daniel21774362020-09-14 10:36:43 -0400419
420 for (int i = 0; i < kNumCachedRenderPasses; ++i) {
421 SkASSERT(!fCachedFramebuffers[i]);
422 SkASSERT(!fCachedRenderPasses[i]);
423 }
Greg Daniel37fd6582020-09-14 12:36:09 -0400424
425 SkASSERT(!fCachedInputDescriptorSet);
Greg Daniel164a9f02016-02-22 09:56:40 -0500426}
427
Greg Daniele2893f22020-10-13 10:20:06 -0400428void GrVkRenderTarget::addResources(GrVkCommandBuffer& commandBuffer,
Greg Daniel7acddf52020-12-16 15:15:51 -0500429 const GrVkRenderPass& renderPass) {
Greg Daniel609e1a92020-12-11 14:18:19 -0500430 commandBuffer.addGrSurface(sk_ref_sp<const GrSurface>(this));
Greg Daniel7acddf52020-12-16 15:15:51 -0500431 commandBuffer.addResource(this->getFramebuffer(renderPass));
Greg Daniel164a9f02016-02-22 09:56:40 -0500432 commandBuffer.addResource(this->colorAttachmentView());
Greg Daniel00d6cf42021-03-05 22:50:08 +0000433 commandBuffer.addResource(fColorAttachment->resource());
434
Greg Daniel164a9f02016-02-22 09:56:40 -0500435 if (this->stencilImageResource()) {
436 commandBuffer.addResource(this->stencilImageResource());
437 commandBuffer.addResource(this->stencilAttachmentView());
438 }
Greg Daniel7acddf52020-12-16 15:15:51 -0500439 if (renderPass.hasResolveAttachment()) {
Greg Daniel00d6cf42021-03-05 22:50:08 +0000440 SkASSERT(fResolveAttachment);
441 commandBuffer.addResource(fResolveAttachment->resource());
Greg Daniel7acddf52020-12-16 15:15:51 -0500442 commandBuffer.addResource(this->resolveAttachmentView());
443 }
Greg Daniel164a9f02016-02-22 09:56:40 -0500444}
445
446void GrVkRenderTarget::releaseInternalObjects() {
Greg Daniel00d6cf42021-03-05 22:50:08 +0000447 fColorAttachment.reset();
448 fResolveAttachment.reset();
Greg Daniel21774362020-09-14 10:36:43 -0400449
450 for (int i = 0; i < kNumCachedRenderPasses; ++i) {
451 if (fCachedFramebuffers[i]) {
452 fCachedFramebuffers[i]->unref();
453 fCachedFramebuffers[i] = nullptr;
454 }
455 if (fCachedRenderPasses[i]) {
456 fCachedRenderPasses[i]->unref();
457 fCachedRenderPasses[i] = nullptr;
458 }
Greg Daniel164a9f02016-02-22 09:56:40 -0500459 }
Greg Daniel21774362020-09-14 10:36:43 -0400460
Greg Daniel37fd6582020-09-14 12:36:09 -0400461 if (fCachedInputDescriptorSet) {
462 fCachedInputDescriptorSet->recycle();
463 fCachedInputDescriptorSet = nullptr;
464 }
465
Greg Daniel32d6c8d2019-11-25 16:23:50 -0500466 for (int i = 0; i < fGrSecondaryCommandBuffers.count(); ++i) {
467 SkASSERT(fGrSecondaryCommandBuffers[i]);
Jim Van Verth5082df12020-03-11 16:14:51 -0400468 fGrSecondaryCommandBuffers[i]->releaseResources();
Greg Daniel32d6c8d2019-11-25 16:23:50 -0500469 }
470 fGrSecondaryCommandBuffers.reset();
Greg Daniel164a9f02016-02-22 09:56:40 -0500471}
472
Greg Daniel164a9f02016-02-22 09:56:40 -0500473void GrVkRenderTarget::onRelease() {
474 this->releaseInternalObjects();
Greg Daniel164a9f02016-02-22 09:56:40 -0500475 GrRenderTarget::onRelease();
476}
477
478void GrVkRenderTarget::onAbandon() {
Greg Danielf0e04f02019-12-04 15:17:54 -0500479 this->releaseInternalObjects();
Greg Daniel164a9f02016-02-22 09:56:40 -0500480 GrRenderTarget::onAbandon();
481}
482
Robert Phillipsb67821d2017-12-13 15:00:45 -0500483GrBackendRenderTarget GrVkRenderTarget::getBackendRenderTarget() const {
Greg Danielb46add82019-01-02 14:51:29 -0500484 SkASSERT(!this->wrapsSecondaryCommandBuffer());
Greg Daniel80ef70e2021-03-10 16:17:21 -0500485 // This should only get called with a non-released GrVkRenderTargets.
486 SkASSERT(!this->wasDestroyed());
Greg Daniel00d6cf42021-03-05 22:50:08 +0000487 // If we have a resolve attachment that is what we return for the backend render target
488 const GrVkAttachment* beAttachment = this->externalAttachment();
489 return GrBackendRenderTarget(beAttachment->width(), beAttachment->height(),
490 beAttachment->vkImageInfo(), beAttachment->getMutableState());
Brian Salomon72c7b982020-10-06 10:07:38 -0400491}
492
Jim Van Verth3e192162020-03-10 16:23:16 -0400493const GrManagedResource* GrVkRenderTarget::stencilImageResource() const {
Greg Danielb46add82019-01-02 14:51:29 -0500494 SkASSERT(!this->wrapsSecondaryCommandBuffer());
Greg Danielc0d69152020-10-08 14:59:00 -0400495 const GrAttachment* stencil = this->getStencilAttachment();
Greg Daniel164a9f02016-02-22 09:56:40 -0500496 if (stencil) {
Greg Danielc0d69152020-10-08 14:59:00 -0400497 const GrVkAttachment* vkStencil = static_cast<const GrVkAttachment*>(stencil);
Greg Daniel164a9f02016-02-22 09:56:40 -0500498 return vkStencil->imageResource();
499 }
500
501 return nullptr;
502}
503
504const GrVkImageView* GrVkRenderTarget::stencilAttachmentView() const {
Greg Danielb46add82019-01-02 14:51:29 -0500505 SkASSERT(!this->wrapsSecondaryCommandBuffer());
Greg Danielc0d69152020-10-08 14:59:00 -0400506 const GrAttachment* stencil = this->getStencilAttachment();
Greg Daniel164a9f02016-02-22 09:56:40 -0500507 if (stencil) {
Greg Danielc0d69152020-10-08 14:59:00 -0400508 const GrVkAttachment* vkStencil = static_cast<const GrVkAttachment*>(stencil);
Greg Daniel00d6cf42021-03-05 22:50:08 +0000509 return vkStencil->framebufferView();
Greg Daniel164a9f02016-02-22 09:56:40 -0500510 }
511
512 return nullptr;
513}
514
Greg Daniel164a9f02016-02-22 09:56:40 -0500515GrVkGpu* GrVkRenderTarget::getVkGpu() const {
516 SkASSERT(!this->wasDestroyed());
517 return static_cast<GrVkGpu*>(this->getGpu());
518}