blob: bca72d589fa2d1d82d9db3a7da0072b00726108c [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
8#include "GrVkRenderTarget.h"
9
Robert Phillipsb67821d2017-12-13 15:00:45 -050010#include "GrBackendSurface.h"
Greg Daniel164a9f02016-02-22 09:56:40 -050011#include "GrRenderTargetPriv.h"
12#include "GrVkCommandBuffer.h"
13#include "GrVkFramebuffer.h"
14#include "GrVkGpu.h"
15#include "GrVkImageView.h"
16#include "GrVkResourceProvider.h"
17#include "GrVkUtil.h"
18
jvanverthfd359ca2016-03-18 11:57:24 -070019#include "vk/GrVkTypes.h"
20
Greg Daniel164a9f02016-02-22 09:56:40 -050021#define VK_CALL(GPU, X) GR_VK_CALL(GPU->vkInterface(), X)
22
23// We're virtually derived from GrSurface (via GrRenderTarget) so its
24// constructor must be explicitly called.
25GrVkRenderTarget::GrVkRenderTarget(GrVkGpu* gpu,
26 const GrSurfaceDesc& desc,
egdanielb2df0c22016-05-13 11:30:37 -070027 const GrVkImageInfo& info,
Greg Daniel52e16d92018-04-10 09:34:07 -040028 sk_sp<GrVkImageLayout> layout,
egdanielb2df0c22016-05-13 11:30:37 -070029 const GrVkImageInfo& msaaInfo,
Greg Daniel52e16d92018-04-10 09:34:07 -040030 sk_sp<GrVkImageLayout> msaaLayout,
Greg Daniel164a9f02016-02-22 09:56:40 -050031 const GrVkImageView* colorAttachmentView,
Greg Daniel001c67f2018-06-26 13:51:57 -040032 const GrVkImageView* resolveAttachmentView)
kkinnunen2e6055b2016-04-22 01:48:29 -070033 : GrSurface(gpu, desc)
Greg Daniel001c67f2018-06-26 13:51:57 -040034 , GrVkImage(info, std::move(layout), GrBackendObjectOwnership::kBorrowed)
Greg Daniel164a9f02016-02-22 09:56:40 -050035 // for the moment we only support 1:1 color to stencil
Jim Van Verth6a40abc2017-11-02 16:56:09 +000036 , GrRenderTarget(gpu, desc)
Greg Daniel164a9f02016-02-22 09:56:40 -050037 , fColorAttachmentView(colorAttachmentView)
Greg Daniel52e16d92018-04-10 09:34:07 -040038 , fMSAAImage(new GrVkImage(msaaInfo, std::move(msaaLayout), GrBackendObjectOwnership::kOwned))
Greg Daniel164a9f02016-02-22 09:56:40 -050039 , fResolveAttachmentView(resolveAttachmentView)
egdaniel50ead532016-07-13 14:23:26 -070040 , fFramebuffer(nullptr)
Greg Daniel164a9f02016-02-22 09:56:40 -050041 , fCachedSimpleRenderPass(nullptr) {
Brian Salomonbdecacf2018-02-02 20:32:49 -050042 SkASSERT(desc.fSampleCnt > 1);
Greg Daniel164a9f02016-02-22 09:56:40 -050043 this->createFramebuffer(gpu);
Greg Daniel001c67f2018-06-26 13:51:57 -040044 this->registerWithCacheWrapped();
Greg Daniel164a9f02016-02-22 09:56:40 -050045}
46
47// We're virtually derived from GrSurface (via GrRenderTarget) so its
48// constructor must be explicitly called.
49GrVkRenderTarget::GrVkRenderTarget(GrVkGpu* gpu,
50 const GrSurfaceDesc& desc,
egdanielb2df0c22016-05-13 11:30:37 -070051 const GrVkImageInfo& info,
Greg Daniel52e16d92018-04-10 09:34:07 -040052 sk_sp<GrVkImageLayout> layout,
egdanielb2df0c22016-05-13 11:30:37 -070053 const GrVkImageInfo& msaaInfo,
Greg Daniel52e16d92018-04-10 09:34:07 -040054 sk_sp<GrVkImageLayout> msaaLayout,
Greg Daniel164a9f02016-02-22 09:56:40 -050055 const GrVkImageView* colorAttachmentView,
egdanielb2df0c22016-05-13 11:30:37 -070056 const GrVkImageView* resolveAttachmentView,
Greg Daniel1591c382017-08-17 15:37:20 -040057 GrBackendObjectOwnership ownership)
kkinnunen2e6055b2016-04-22 01:48:29 -070058 : GrSurface(gpu, desc)
Greg Daniel52e16d92018-04-10 09:34:07 -040059 , GrVkImage(info, std::move(layout), ownership)
Greg Daniel164a9f02016-02-22 09:56:40 -050060 // for the moment we only support 1:1 color to stencil
Jim Van Verth6a40abc2017-11-02 16:56:09 +000061 , GrRenderTarget(gpu, desc)
Greg Daniel164a9f02016-02-22 09:56:40 -050062 , fColorAttachmentView(colorAttachmentView)
Greg Daniel52e16d92018-04-10 09:34:07 -040063 , fMSAAImage(new GrVkImage(msaaInfo, std::move(msaaLayout), GrBackendObjectOwnership::kOwned))
Greg Daniel164a9f02016-02-22 09:56:40 -050064 , fResolveAttachmentView(resolveAttachmentView)
egdaniel50ead532016-07-13 14:23:26 -070065 , fFramebuffer(nullptr)
Greg Daniel164a9f02016-02-22 09:56:40 -050066 , fCachedSimpleRenderPass(nullptr) {
Brian Salomonbdecacf2018-02-02 20:32:49 -050067 SkASSERT(desc.fSampleCnt > 1);
Greg Daniel164a9f02016-02-22 09:56:40 -050068 this->createFramebuffer(gpu);
Greg Daniel164a9f02016-02-22 09:56:40 -050069}
70
71// We're virtually derived from GrSurface (via GrRenderTarget) so its
72// constructor must be explicitly called.
73GrVkRenderTarget::GrVkRenderTarget(GrVkGpu* gpu,
74 const GrSurfaceDesc& desc,
egdanielb2df0c22016-05-13 11:30:37 -070075 const GrVkImageInfo& info,
Greg Daniel52e16d92018-04-10 09:34:07 -040076 sk_sp<GrVkImageLayout> layout,
Greg Daniel001c67f2018-06-26 13:51:57 -040077 const GrVkImageView* colorAttachmentView)
kkinnunen2e6055b2016-04-22 01:48:29 -070078 : GrSurface(gpu, desc)
Greg Daniel001c67f2018-06-26 13:51:57 -040079 , GrVkImage(info, std::move(layout), GrBackendObjectOwnership::kBorrowed)
Jim Van Verth6a40abc2017-11-02 16:56:09 +000080 , GrRenderTarget(gpu, desc)
Greg Daniel164a9f02016-02-22 09:56:40 -050081 , fColorAttachmentView(colorAttachmentView)
egdanielb2df0c22016-05-13 11:30:37 -070082 , fMSAAImage(nullptr)
Greg Daniel164a9f02016-02-22 09:56:40 -050083 , fResolveAttachmentView(nullptr)
egdaniel50ead532016-07-13 14:23:26 -070084 , fFramebuffer(nullptr)
Greg Daniel164a9f02016-02-22 09:56:40 -050085 , fCachedSimpleRenderPass(nullptr) {
Brian Salomonbdecacf2018-02-02 20:32:49 -050086 SkASSERT(1 == desc.fSampleCnt);
Greg Daniel164a9f02016-02-22 09:56:40 -050087 this->createFramebuffer(gpu);
Greg Daniel001c67f2018-06-26 13:51:57 -040088 this->registerWithCacheWrapped();
Greg Daniel164a9f02016-02-22 09:56:40 -050089}
90
91// We're virtually derived from GrSurface (via GrRenderTarget) so its
92// constructor must be explicitly called.
93GrVkRenderTarget::GrVkRenderTarget(GrVkGpu* gpu,
94 const GrSurfaceDesc& desc,
egdanielb2df0c22016-05-13 11:30:37 -070095 const GrVkImageInfo& info,
Greg Daniel52e16d92018-04-10 09:34:07 -040096 sk_sp<GrVkImageLayout> layout,
egdanielb2df0c22016-05-13 11:30:37 -070097 const GrVkImageView* colorAttachmentView,
Greg Daniel1591c382017-08-17 15:37:20 -040098 GrBackendObjectOwnership ownership)
kkinnunen2e6055b2016-04-22 01:48:29 -070099 : GrSurface(gpu, desc)
Greg Daniel52e16d92018-04-10 09:34:07 -0400100 , GrVkImage(info, std::move(layout), ownership)
Jim Van Verth6a40abc2017-11-02 16:56:09 +0000101 , GrRenderTarget(gpu, desc)
Greg Daniel164a9f02016-02-22 09:56:40 -0500102 , fColorAttachmentView(colorAttachmentView)
egdanielb2df0c22016-05-13 11:30:37 -0700103 , fMSAAImage(nullptr)
Greg Daniel164a9f02016-02-22 09:56:40 -0500104 , fResolveAttachmentView(nullptr)
egdaniel50ead532016-07-13 14:23:26 -0700105 , fFramebuffer(nullptr)
Greg Daniel164a9f02016-02-22 09:56:40 -0500106 , fCachedSimpleRenderPass(nullptr) {
Brian Salomonbdecacf2018-02-02 20:32:49 -0500107 SkASSERT(1 == desc.fSampleCnt);
Greg Daniel164a9f02016-02-22 09:56:40 -0500108 this->createFramebuffer(gpu);
109}
110
Greg Daniel001c67f2018-06-26 13:51:57 -0400111sk_sp<GrVkRenderTarget>
112GrVkRenderTarget::MakeWrappedRenderTarget(GrVkGpu* gpu,
113 const GrSurfaceDesc& desc,
114 const GrVkImageInfo& info,
115 sk_sp<GrVkImageLayout> layout) {
116 SkASSERT(VK_NULL_HANDLE != info.fImage);
117
egdaniel50ead532016-07-13 14:23:26 -0700118 SkASSERT(1 == info.fLevelCount);
Greg Daniel164a9f02016-02-22 09:56:40 -0500119 VkFormat pixelFormat;
120 GrPixelConfigToVkFormat(desc.fConfig, &pixelFormat);
halcanary9d524f22016-03-29 09:03:52 -0700121
Greg Daniel164a9f02016-02-22 09:56:40 -0500122 VkImage colorImage;
123
124 // create msaa surface if necessary
egdanielb2df0c22016-05-13 11:30:37 -0700125 GrVkImageInfo msInfo;
Greg Daniel52e16d92018-04-10 09:34:07 -0400126 sk_sp<GrVkImageLayout> msLayout;
Greg Daniel164a9f02016-02-22 09:56:40 -0500127 const GrVkImageView* resolveAttachmentView = nullptr;
Brian Salomonbdecacf2018-02-02 20:32:49 -0500128 if (desc.fSampleCnt > 1) {
Greg Daniel164a9f02016-02-22 09:56:40 -0500129 GrVkImage::ImageDesc msImageDesc;
130 msImageDesc.fImageType = VK_IMAGE_TYPE_2D;
131 msImageDesc.fFormat = pixelFormat;
132 msImageDesc.fWidth = desc.fWidth;
133 msImageDesc.fHeight = desc.fHeight;
134 msImageDesc.fLevels = 1;
135 msImageDesc.fSamples = desc.fSampleCnt;
136 msImageDesc.fImageTiling = VK_IMAGE_TILING_OPTIMAL;
egdaniel4bcd62e2016-08-31 07:37:31 -0700137 msImageDesc.fUsageFlags = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
138 VK_IMAGE_USAGE_TRANSFER_DST_BIT |
139 VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
Greg Daniel164a9f02016-02-22 09:56:40 -0500140 msImageDesc.fMemProps = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
141
egdanielb2df0c22016-05-13 11:30:37 -0700142 if (!GrVkImage::InitImageInfo(gpu, msImageDesc, &msInfo)) {
Greg Daniel164a9f02016-02-22 09:56:40 -0500143 return nullptr;
144 }
145
146 // Set color attachment image
egdanielb2df0c22016-05-13 11:30:37 -0700147 colorImage = msInfo.fImage;
Greg Daniel164a9f02016-02-22 09:56:40 -0500148
149 // Create Resolve attachment view
egdanielb2df0c22016-05-13 11:30:37 -0700150 resolveAttachmentView = GrVkImageView::Create(gpu, info.fImage, pixelFormat,
jvanverth62340062016-04-26 08:01:44 -0700151 GrVkImageView::kColor_Type, 1);
Greg Daniel164a9f02016-02-22 09:56:40 -0500152 if (!resolveAttachmentView) {
egdanielb2df0c22016-05-13 11:30:37 -0700153 GrVkImage::DestroyImageInfo(gpu, &msInfo);
Greg Daniel164a9f02016-02-22 09:56:40 -0500154 return nullptr;
155 }
Greg Daniel52e16d92018-04-10 09:34:07 -0400156 msLayout.reset(new GrVkImageLayout(msInfo.fImageLayout));
Greg Daniel164a9f02016-02-22 09:56:40 -0500157 } else {
158 // Set color attachment image
egdanielb2df0c22016-05-13 11:30:37 -0700159 colorImage = info.fImage;
Greg Daniel164a9f02016-02-22 09:56:40 -0500160 }
161
162 // Get color attachment view
163 const GrVkImageView* colorAttachmentView = GrVkImageView::Create(gpu, colorImage, pixelFormat,
jvanverth62340062016-04-26 08:01:44 -0700164 GrVkImageView::kColor_Type, 1);
Greg Daniel164a9f02016-02-22 09:56:40 -0500165 if (!colorAttachmentView) {
Brian Salomonbdecacf2018-02-02 20:32:49 -0500166 if (desc.fSampleCnt > 1) {
Greg Daniel164a9f02016-02-22 09:56:40 -0500167 resolveAttachmentView->unref(gpu);
egdanielb2df0c22016-05-13 11:30:37 -0700168 GrVkImage::DestroyImageInfo(gpu, &msInfo);
Greg Daniel164a9f02016-02-22 09:56:40 -0500169 }
egdanielb2df0c22016-05-13 11:30:37 -0700170 return nullptr;
Greg Daniel164a9f02016-02-22 09:56:40 -0500171 }
172
Greg Daniel001c67f2018-06-26 13:51:57 -0400173 GrVkRenderTarget* vkRT;
Brian Salomonbdecacf2018-02-02 20:32:49 -0500174 if (desc.fSampleCnt > 1) {
Greg Daniel001c67f2018-06-26 13:51:57 -0400175 vkRT = new GrVkRenderTarget(gpu, desc, info, std::move(layout), msInfo,
176 std::move(msLayout), colorAttachmentView,
177 resolveAttachmentView);
Greg Daniel164a9f02016-02-22 09:56:40 -0500178 } else {
Greg Daniel001c67f2018-06-26 13:51:57 -0400179 vkRT = new GrVkRenderTarget(gpu, desc, info, std::move(layout), colorAttachmentView);
Greg Daniel164a9f02016-02-22 09:56:40 -0500180 }
181
Greg Daniel001c67f2018-06-26 13:51:57 -0400182 return sk_sp<GrVkRenderTarget>(vkRT);
Greg Daniel164a9f02016-02-22 09:56:40 -0500183}
184
185bool GrVkRenderTarget::completeStencilAttachment() {
186 this->createFramebuffer(this->getVkGpu());
187 return true;
188}
189
190void GrVkRenderTarget::createFramebuffer(GrVkGpu* gpu) {
191 if (fFramebuffer) {
192 fFramebuffer->unref(gpu);
193 }
194 if (fCachedSimpleRenderPass) {
195 fCachedSimpleRenderPass->unref(gpu);
196 }
197
198 // Vulkan requires us to create a compatible renderpass before we can create our framebuffer,
199 // so we use this to get a (cached) basic renderpass, only for creation.
egdanield62e28b2016-06-07 08:43:30 -0700200 fCachedSimpleRenderPass =
201 gpu->resourceProvider().findCompatibleRenderPass(*this, &fCompatibleRPHandle);
Greg Daniel164a9f02016-02-22 09:56:40 -0500202
203 // Stencil attachment view is stored in the base RT stencil attachment
204 const GrVkImageView* stencilView = this->stencilAttachmentView();
205 fFramebuffer = GrVkFramebuffer::Create(gpu, this->width(), this->height(),
206 fCachedSimpleRenderPass, fColorAttachmentView,
egdanielce3bfb12016-08-26 11:05:13 -0700207 stencilView);
Greg Daniel164a9f02016-02-22 09:56:40 -0500208 SkASSERT(fFramebuffer);
209}
210
211void GrVkRenderTarget::getAttachmentsDescriptor(
212 GrVkRenderPass::AttachmentsDescriptor* desc,
213 GrVkRenderPass::AttachmentFlags* attachmentFlags) const {
Greg Daniel164a9f02016-02-22 09:56:40 -0500214 VkFormat colorFormat;
215 GrPixelConfigToVkFormat(this->config(), &colorFormat);
216 desc->fColor.fFormat = colorFormat;
Brian Salomonbdecacf2018-02-02 20:32:49 -0500217 desc->fColor.fSamples = this->numColorSamples();
Greg Daniel164a9f02016-02-22 09:56:40 -0500218 *attachmentFlags = GrVkRenderPass::kColor_AttachmentFlag;
219 uint32_t attachmentCount = 1;
Greg Daniel164a9f02016-02-22 09:56:40 -0500220
221 const GrStencilAttachment* stencil = this->renderTargetPriv().getStencilAttachment();
222 if (stencil) {
223 const GrVkStencilAttachment* vkStencil = static_cast<const GrVkStencilAttachment*>(stencil);
224 desc->fStencil.fFormat = vkStencil->vkFormat();
Brian Salomonbdecacf2018-02-02 20:32:49 -0500225 desc->fStencil.fSamples = vkStencil->numSamples();
Greg Daniel164a9f02016-02-22 09:56:40 -0500226 // Currently in vulkan stencil and color attachments must all have same number of samples
227 SkASSERT(desc->fColor.fSamples == desc->fStencil.fSamples);
228 *attachmentFlags |= GrVkRenderPass::kStencil_AttachmentFlag;
229 ++attachmentCount;
230 }
231 desc->fAttachmentCount = attachmentCount;
232}
233
234GrVkRenderTarget::~GrVkRenderTarget() {
235 // either release or abandon should have been called by the owner of this object.
egdanielb2df0c22016-05-13 11:30:37 -0700236 SkASSERT(!fMSAAImage);
Greg Daniel164a9f02016-02-22 09:56:40 -0500237 SkASSERT(!fResolveAttachmentView);
238 SkASSERT(!fColorAttachmentView);
239 SkASSERT(!fFramebuffer);
240 SkASSERT(!fCachedSimpleRenderPass);
241}
242
243void GrVkRenderTarget::addResources(GrVkCommandBuffer& commandBuffer) const {
244 commandBuffer.addResource(this->framebuffer());
Greg Daniel164a9f02016-02-22 09:56:40 -0500245 commandBuffer.addResource(this->colorAttachmentView());
egdanielce3bfb12016-08-26 11:05:13 -0700246 commandBuffer.addResource(this->msaaImageResource() ? this->msaaImageResource()
247 : this->resource());
Greg Daniel164a9f02016-02-22 09:56:40 -0500248 if (this->stencilImageResource()) {
249 commandBuffer.addResource(this->stencilImageResource());
250 commandBuffer.addResource(this->stencilAttachmentView());
251 }
252}
253
254void GrVkRenderTarget::releaseInternalObjects() {
255 GrVkGpu* gpu = this->getVkGpu();
256
egdanielb2df0c22016-05-13 11:30:37 -0700257 if (fMSAAImage) {
258 fMSAAImage->releaseImage(gpu);
Greg Daniel2db32322017-04-03 10:29:43 -0400259 fMSAAImage.reset();
Greg Daniel164a9f02016-02-22 09:56:40 -0500260 }
261
262 if (fResolveAttachmentView) {
263 fResolveAttachmentView->unref(gpu);
264 fResolveAttachmentView = nullptr;
265 }
266 if (fColorAttachmentView) {
267 fColorAttachmentView->unref(gpu);
268 fColorAttachmentView = nullptr;
269 }
270 if (fFramebuffer) {
271 fFramebuffer->unref(gpu);
272 fFramebuffer = nullptr;
273 }
274 if (fCachedSimpleRenderPass) {
275 fCachedSimpleRenderPass->unref(gpu);
276 fCachedSimpleRenderPass = nullptr;
277 }
278}
279
280void GrVkRenderTarget::abandonInternalObjects() {
egdanielb2df0c22016-05-13 11:30:37 -0700281 if (fMSAAImage) {
282 fMSAAImage->abandonImage();
Greg Daniel2db32322017-04-03 10:29:43 -0400283 fMSAAImage.reset();
Greg Daniel164a9f02016-02-22 09:56:40 -0500284 }
285
286 if (fResolveAttachmentView) {
287 fResolveAttachmentView->unrefAndAbandon();
288 fResolveAttachmentView = nullptr;
289 }
290 if (fColorAttachmentView) {
291 fColorAttachmentView->unrefAndAbandon();
292 fColorAttachmentView = nullptr;
293 }
294 if (fFramebuffer) {
295 fFramebuffer->unrefAndAbandon();
296 fFramebuffer = nullptr;
297 }
298 if (fCachedSimpleRenderPass) {
299 fCachedSimpleRenderPass->unrefAndAbandon();
300 fCachedSimpleRenderPass = nullptr;
301 }
302}
303
304void GrVkRenderTarget::onRelease() {
305 this->releaseInternalObjects();
kkinnunen2e6055b2016-04-22 01:48:29 -0700306 this->releaseImage(this->getVkGpu());
Greg Daniel164a9f02016-02-22 09:56:40 -0500307 GrRenderTarget::onRelease();
308}
309
310void GrVkRenderTarget::onAbandon() {
311 this->abandonInternalObjects();
312 this->abandonImage();
313 GrRenderTarget::onAbandon();
314}
315
316
Robert Phillipsb67821d2017-12-13 15:00:45 -0500317GrBackendRenderTarget GrVkRenderTarget::getBackendRenderTarget() const {
Greg Daniel8a3f55c2018-03-14 17:32:12 +0000318 return GrBackendRenderTarget(this->width(), this->height(), this->numColorSamples(),
Greg Daniel323fbcf2018-04-10 13:46:30 -0400319 fInfo, this->grVkImageLayout());
Robert Phillipsb67821d2017-12-13 15:00:45 -0500320}
321
egdanielb2df0c22016-05-13 11:30:37 -0700322const GrVkResource* GrVkRenderTarget::stencilImageResource() const {
Greg Daniel164a9f02016-02-22 09:56:40 -0500323 const GrStencilAttachment* stencil = this->renderTargetPriv().getStencilAttachment();
324 if (stencil) {
325 const GrVkStencilAttachment* vkStencil = static_cast<const GrVkStencilAttachment*>(stencil);
326 return vkStencil->imageResource();
327 }
328
329 return nullptr;
330}
331
332const GrVkImageView* GrVkRenderTarget::stencilAttachmentView() const {
333 const GrStencilAttachment* stencil = this->renderTargetPriv().getStencilAttachment();
334 if (stencil) {
335 const GrVkStencilAttachment* vkStencil = static_cast<const GrVkStencilAttachment*>(stencil);
336 return vkStencil->stencilView();
337 }
338
339 return nullptr;
340}
341
342
343GrVkGpu* GrVkRenderTarget::getVkGpu() const {
344 SkASSERT(!this->wasDestroyed());
345 return static_cast<GrVkGpu*>(this->getGpu());
346}