blob: 27cb119efc78ee66a4b36430cd3cee5e996723d1 [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
10#include "GrRenderTargetPriv.h"
11#include "GrVkCommandBuffer.h"
12#include "GrVkFramebuffer.h"
13#include "GrVkGpu.h"
14#include "GrVkImageView.h"
15#include "GrVkResourceProvider.h"
16#include "GrVkUtil.h"
17
jvanverthfd359ca2016-03-18 11:57:24 -070018#include "vk/GrVkTypes.h"
19
Greg Daniel164a9f02016-02-22 09:56:40 -050020#define VK_CALL(GPU, X) GR_VK_CALL(GPU->vkInterface(), X)
21
22// We're virtually derived from GrSurface (via GrRenderTarget) so its
23// constructor must be explicitly called.
24GrVkRenderTarget::GrVkRenderTarget(GrVkGpu* gpu,
kkinnunen2e6055b2016-04-22 01:48:29 -070025 SkBudgeted budgeted,
Greg Daniel164a9f02016-02-22 09:56:40 -050026 const GrSurfaceDesc& desc,
egdanielb2df0c22016-05-13 11:30:37 -070027 const GrVkImageInfo& info,
28 const GrVkImageInfo& msaaInfo,
Greg Daniel164a9f02016-02-22 09:56:40 -050029 const GrVkImageView* colorAttachmentView,
egdanielb2df0c22016-05-13 11:30:37 -070030 const GrVkImageView* resolveAttachmentView,
Greg Daniel1591c382017-08-17 15:37:20 -040031 GrBackendObjectOwnership ownership)
kkinnunen2e6055b2016-04-22 01:48:29 -070032 : GrSurface(gpu, desc)
Greg Daniel1591c382017-08-17 15:37:20 -040033 , GrVkImage(info, ownership)
Greg Daniel164a9f02016-02-22 09:56:40 -050034 // for the moment we only support 1:1 color to stencil
Jim Van Verth6a40abc2017-11-02 16:56:09 +000035 , GrRenderTarget(gpu, desc)
Greg Daniel164a9f02016-02-22 09:56:40 -050036 , fColorAttachmentView(colorAttachmentView)
Greg Daniel1591c382017-08-17 15:37:20 -040037 , fMSAAImage(new GrVkImage(msaaInfo, GrBackendObjectOwnership::kOwned))
Greg Daniel164a9f02016-02-22 09:56:40 -050038 , fResolveAttachmentView(resolveAttachmentView)
egdaniel50ead532016-07-13 14:23:26 -070039 , fFramebuffer(nullptr)
Greg Daniel164a9f02016-02-22 09:56:40 -050040 , fCachedSimpleRenderPass(nullptr) {
41 SkASSERT(desc.fSampleCnt);
Greg Daniel164a9f02016-02-22 09:56:40 -050042 this->createFramebuffer(gpu);
kkinnunen2e6055b2016-04-22 01:48:29 -070043 this->registerWithCache(budgeted);
Greg Daniel164a9f02016-02-22 09:56:40 -050044}
45
46// We're virtually derived from GrSurface (via GrRenderTarget) so its
47// constructor must be explicitly called.
48GrVkRenderTarget::GrVkRenderTarget(GrVkGpu* gpu,
49 const GrSurfaceDesc& desc,
egdanielb2df0c22016-05-13 11:30:37 -070050 const GrVkImageInfo& info,
51 const GrVkImageInfo& msaaInfo,
Greg Daniel164a9f02016-02-22 09:56:40 -050052 const GrVkImageView* colorAttachmentView,
egdanielb2df0c22016-05-13 11:30:37 -070053 const GrVkImageView* resolveAttachmentView,
Greg Daniel1591c382017-08-17 15:37:20 -040054 GrBackendObjectOwnership ownership)
kkinnunen2e6055b2016-04-22 01:48:29 -070055 : GrSurface(gpu, desc)
Greg Daniel1591c382017-08-17 15:37:20 -040056 , GrVkImage(info, ownership)
Greg Daniel164a9f02016-02-22 09:56:40 -050057 // for the moment we only support 1:1 color to stencil
Jim Van Verth6a40abc2017-11-02 16:56:09 +000058 , GrRenderTarget(gpu, desc)
Greg Daniel164a9f02016-02-22 09:56:40 -050059 , fColorAttachmentView(colorAttachmentView)
Greg Daniel1591c382017-08-17 15:37:20 -040060 , fMSAAImage(new GrVkImage(msaaInfo, GrBackendObjectOwnership::kOwned))
Greg Daniel164a9f02016-02-22 09:56:40 -050061 , fResolveAttachmentView(resolveAttachmentView)
egdaniel50ead532016-07-13 14:23:26 -070062 , fFramebuffer(nullptr)
Greg Daniel164a9f02016-02-22 09:56:40 -050063 , fCachedSimpleRenderPass(nullptr) {
64 SkASSERT(desc.fSampleCnt);
Greg Daniel164a9f02016-02-22 09:56:40 -050065 this->createFramebuffer(gpu);
Greg Daniel164a9f02016-02-22 09:56:40 -050066}
67
68// We're virtually derived from GrSurface (via GrRenderTarget) so its
69// constructor must be explicitly called.
70GrVkRenderTarget::GrVkRenderTarget(GrVkGpu* gpu,
kkinnunen2e6055b2016-04-22 01:48:29 -070071 SkBudgeted budgeted,
Greg Daniel164a9f02016-02-22 09:56:40 -050072 const GrSurfaceDesc& desc,
egdanielb2df0c22016-05-13 11:30:37 -070073 const GrVkImageInfo& info,
74 const GrVkImageView* colorAttachmentView,
Greg Daniel1591c382017-08-17 15:37:20 -040075 GrBackendObjectOwnership ownership)
kkinnunen2e6055b2016-04-22 01:48:29 -070076 : GrSurface(gpu, desc)
Greg Daniel1591c382017-08-17 15:37:20 -040077 , GrVkImage(info, ownership)
Jim Van Verth6a40abc2017-11-02 16:56:09 +000078 , GrRenderTarget(gpu, desc)
Greg Daniel164a9f02016-02-22 09:56:40 -050079 , fColorAttachmentView(colorAttachmentView)
egdanielb2df0c22016-05-13 11:30:37 -070080 , fMSAAImage(nullptr)
Greg Daniel164a9f02016-02-22 09:56:40 -050081 , fResolveAttachmentView(nullptr)
egdaniel50ead532016-07-13 14:23:26 -070082 , fFramebuffer(nullptr)
Greg Daniel164a9f02016-02-22 09:56:40 -050083 , fCachedSimpleRenderPass(nullptr) {
84 SkASSERT(!desc.fSampleCnt);
Greg Daniel164a9f02016-02-22 09:56:40 -050085 this->createFramebuffer(gpu);
kkinnunen2e6055b2016-04-22 01:48:29 -070086 this->registerWithCache(budgeted);
Greg Daniel164a9f02016-02-22 09:56:40 -050087}
88
89// We're virtually derived from GrSurface (via GrRenderTarget) so its
90// constructor must be explicitly called.
91GrVkRenderTarget::GrVkRenderTarget(GrVkGpu* gpu,
92 const GrSurfaceDesc& desc,
egdanielb2df0c22016-05-13 11:30:37 -070093 const GrVkImageInfo& info,
94 const GrVkImageView* colorAttachmentView,
Greg Daniel1591c382017-08-17 15:37:20 -040095 GrBackendObjectOwnership ownership)
kkinnunen2e6055b2016-04-22 01:48:29 -070096 : GrSurface(gpu, desc)
Greg Daniel1591c382017-08-17 15:37:20 -040097 , GrVkImage(info, ownership)
Jim Van Verth6a40abc2017-11-02 16:56:09 +000098 , GrRenderTarget(gpu, desc)
Greg Daniel164a9f02016-02-22 09:56:40 -050099 , fColorAttachmentView(colorAttachmentView)
egdanielb2df0c22016-05-13 11:30:37 -0700100 , fMSAAImage(nullptr)
Greg Daniel164a9f02016-02-22 09:56:40 -0500101 , fResolveAttachmentView(nullptr)
egdaniel50ead532016-07-13 14:23:26 -0700102 , fFramebuffer(nullptr)
Greg Daniel164a9f02016-02-22 09:56:40 -0500103 , fCachedSimpleRenderPass(nullptr) {
104 SkASSERT(!desc.fSampleCnt);
Greg Daniel164a9f02016-02-22 09:56:40 -0500105 this->createFramebuffer(gpu);
106}
107
108GrVkRenderTarget*
109GrVkRenderTarget::Create(GrVkGpu* gpu,
kkinnunen2e6055b2016-04-22 01:48:29 -0700110 SkBudgeted budgeted,
Greg Daniel164a9f02016-02-22 09:56:40 -0500111 const GrSurfaceDesc& desc,
egdanielb2df0c22016-05-13 11:30:37 -0700112 const GrVkImageInfo& info,
Greg Daniel1591c382017-08-17 15:37:20 -0400113 GrBackendObjectOwnership ownership) {
egdaniel50ead532016-07-13 14:23:26 -0700114 SkASSERT(1 == info.fLevelCount);
Greg Daniel164a9f02016-02-22 09:56:40 -0500115 VkFormat pixelFormat;
116 GrPixelConfigToVkFormat(desc.fConfig, &pixelFormat);
halcanary9d524f22016-03-29 09:03:52 -0700117
Greg Daniel164a9f02016-02-22 09:56:40 -0500118 VkImage colorImage;
119
120 // create msaa surface if necessary
egdanielb2df0c22016-05-13 11:30:37 -0700121 GrVkImageInfo msInfo;
Greg Daniel164a9f02016-02-22 09:56:40 -0500122 const GrVkImageView* resolveAttachmentView = nullptr;
123 if (desc.fSampleCnt) {
124 GrVkImage::ImageDesc msImageDesc;
125 msImageDesc.fImageType = VK_IMAGE_TYPE_2D;
126 msImageDesc.fFormat = pixelFormat;
127 msImageDesc.fWidth = desc.fWidth;
128 msImageDesc.fHeight = desc.fHeight;
129 msImageDesc.fLevels = 1;
130 msImageDesc.fSamples = desc.fSampleCnt;
131 msImageDesc.fImageTiling = VK_IMAGE_TILING_OPTIMAL;
egdaniel4bcd62e2016-08-31 07:37:31 -0700132 msImageDesc.fUsageFlags = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
133 VK_IMAGE_USAGE_TRANSFER_DST_BIT |
134 VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
Greg Daniel164a9f02016-02-22 09:56:40 -0500135 msImageDesc.fMemProps = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
136
egdanielb2df0c22016-05-13 11:30:37 -0700137 if (!GrVkImage::InitImageInfo(gpu, msImageDesc, &msInfo)) {
Greg Daniel164a9f02016-02-22 09:56:40 -0500138 return nullptr;
139 }
140
141 // Set color attachment image
egdanielb2df0c22016-05-13 11:30:37 -0700142 colorImage = msInfo.fImage;
Greg Daniel164a9f02016-02-22 09:56:40 -0500143
144 // Create Resolve attachment view
egdanielb2df0c22016-05-13 11:30:37 -0700145 resolveAttachmentView = GrVkImageView::Create(gpu, info.fImage, pixelFormat,
jvanverth62340062016-04-26 08:01:44 -0700146 GrVkImageView::kColor_Type, 1);
Greg Daniel164a9f02016-02-22 09:56:40 -0500147 if (!resolveAttachmentView) {
egdanielb2df0c22016-05-13 11:30:37 -0700148 GrVkImage::DestroyImageInfo(gpu, &msInfo);
Greg Daniel164a9f02016-02-22 09:56:40 -0500149 return nullptr;
150 }
151 } else {
152 // Set color attachment image
egdanielb2df0c22016-05-13 11:30:37 -0700153 colorImage = info.fImage;
Greg Daniel164a9f02016-02-22 09:56:40 -0500154 }
155
156 // Get color attachment view
157 const GrVkImageView* colorAttachmentView = GrVkImageView::Create(gpu, colorImage, pixelFormat,
jvanverth62340062016-04-26 08:01:44 -0700158 GrVkImageView::kColor_Type, 1);
Greg Daniel164a9f02016-02-22 09:56:40 -0500159 if (!colorAttachmentView) {
egdanielb2df0c22016-05-13 11:30:37 -0700160 if (desc.fSampleCnt) {
Greg Daniel164a9f02016-02-22 09:56:40 -0500161 resolveAttachmentView->unref(gpu);
egdanielb2df0c22016-05-13 11:30:37 -0700162 GrVkImage::DestroyImageInfo(gpu, &msInfo);
Greg Daniel164a9f02016-02-22 09:56:40 -0500163 }
egdanielb2df0c22016-05-13 11:30:37 -0700164 return nullptr;
Greg Daniel164a9f02016-02-22 09:56:40 -0500165 }
166
167 GrVkRenderTarget* texRT;
egdanielb2df0c22016-05-13 11:30:37 -0700168 if (desc.fSampleCnt) {
169 texRT = new GrVkRenderTarget(gpu, budgeted, desc, info, msInfo,
Greg Daniel1591c382017-08-17 15:37:20 -0400170 colorAttachmentView, resolveAttachmentView, ownership);
Greg Daniel164a9f02016-02-22 09:56:40 -0500171 } else {
Greg Daniel1591c382017-08-17 15:37:20 -0400172 texRT = new GrVkRenderTarget(gpu, budgeted, desc, info, colorAttachmentView, ownership);
Greg Daniel164a9f02016-02-22 09:56:40 -0500173 }
174
175 return texRT;
176}
177
178GrVkRenderTarget*
179GrVkRenderTarget::CreateNewRenderTarget(GrVkGpu* gpu,
kkinnunen2e6055b2016-04-22 01:48:29 -0700180 SkBudgeted budgeted,
Greg Daniel164a9f02016-02-22 09:56:40 -0500181 const GrSurfaceDesc& desc,
Greg Daniel164a9f02016-02-22 09:56:40 -0500182 const GrVkImage::ImageDesc& imageDesc) {
183 SkASSERT(imageDesc.fUsageFlags & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
184
egdanielb2df0c22016-05-13 11:30:37 -0700185 GrVkImageInfo info;
186 if (!GrVkImage::InitImageInfo(gpu, imageDesc, &info)) {
Greg Daniel164a9f02016-02-22 09:56:40 -0500187 return nullptr;
188 }
189
egdanielb2df0c22016-05-13 11:30:37 -0700190 GrVkRenderTarget* rt = GrVkRenderTarget::Create(gpu, budgeted, desc, info,
Greg Daniel1591c382017-08-17 15:37:20 -0400191 GrBackendObjectOwnership::kOwned);
egdanielb2df0c22016-05-13 11:30:37 -0700192 if (!rt) {
193 GrVkImage::DestroyImageInfo(gpu, &info);
194 }
Greg Daniel164a9f02016-02-22 09:56:40 -0500195 return rt;
196}
197
bungeman6bd52842016-10-27 09:30:08 -0700198sk_sp<GrVkRenderTarget>
199GrVkRenderTarget::MakeWrappedRenderTarget(GrVkGpu* gpu,
200 const GrSurfaceDesc& desc,
bungeman6bd52842016-10-27 09:30:08 -0700201 const GrVkImageInfo* info) {
jvanverthfd359ca2016-03-18 11:57:24 -0700202 SkASSERT(info);
jvanverthfd359ca2016-03-18 11:57:24 -0700203 SkASSERT(VK_NULL_HANDLE != info->fImage);
jvanverthfd359ca2016-03-18 11:57:24 -0700204
bungeman6bd52842016-10-27 09:30:08 -0700205 return sk_sp<GrVkRenderTarget>(
Greg Daniel1591c382017-08-17 15:37:20 -0400206 GrVkRenderTarget::Create(gpu, SkBudgeted::kNo, desc, *info,
207 GrBackendObjectOwnership::kBorrowed));
Greg Daniel164a9f02016-02-22 09:56:40 -0500208}
209
210bool GrVkRenderTarget::completeStencilAttachment() {
211 this->createFramebuffer(this->getVkGpu());
212 return true;
213}
214
215void GrVkRenderTarget::createFramebuffer(GrVkGpu* gpu) {
216 if (fFramebuffer) {
217 fFramebuffer->unref(gpu);
218 }
219 if (fCachedSimpleRenderPass) {
220 fCachedSimpleRenderPass->unref(gpu);
221 }
222
223 // Vulkan requires us to create a compatible renderpass before we can create our framebuffer,
224 // so we use this to get a (cached) basic renderpass, only for creation.
egdanield62e28b2016-06-07 08:43:30 -0700225 fCachedSimpleRenderPass =
226 gpu->resourceProvider().findCompatibleRenderPass(*this, &fCompatibleRPHandle);
Greg Daniel164a9f02016-02-22 09:56:40 -0500227
228 // Stencil attachment view is stored in the base RT stencil attachment
229 const GrVkImageView* stencilView = this->stencilAttachmentView();
230 fFramebuffer = GrVkFramebuffer::Create(gpu, this->width(), this->height(),
231 fCachedSimpleRenderPass, fColorAttachmentView,
egdanielce3bfb12016-08-26 11:05:13 -0700232 stencilView);
Greg Daniel164a9f02016-02-22 09:56:40 -0500233 SkASSERT(fFramebuffer);
234}
235
236void GrVkRenderTarget::getAttachmentsDescriptor(
237 GrVkRenderPass::AttachmentsDescriptor* desc,
238 GrVkRenderPass::AttachmentFlags* attachmentFlags) const {
239 int colorSamples = this->numColorSamples();
240 VkFormat colorFormat;
241 GrPixelConfigToVkFormat(this->config(), &colorFormat);
242 desc->fColor.fFormat = colorFormat;
243 desc->fColor.fSamples = colorSamples ? colorSamples : 1;
244 *attachmentFlags = GrVkRenderPass::kColor_AttachmentFlag;
245 uint32_t attachmentCount = 1;
Greg Daniel164a9f02016-02-22 09:56:40 -0500246
247 const GrStencilAttachment* stencil = this->renderTargetPriv().getStencilAttachment();
248 if (stencil) {
249 const GrVkStencilAttachment* vkStencil = static_cast<const GrVkStencilAttachment*>(stencil);
250 desc->fStencil.fFormat = vkStencil->vkFormat();
251 desc->fStencil.fSamples = vkStencil->numSamples() ? vkStencil->numSamples() : 1;
252 // Currently in vulkan stencil and color attachments must all have same number of samples
253 SkASSERT(desc->fColor.fSamples == desc->fStencil.fSamples);
254 *attachmentFlags |= GrVkRenderPass::kStencil_AttachmentFlag;
255 ++attachmentCount;
256 }
257 desc->fAttachmentCount = attachmentCount;
258}
259
260GrVkRenderTarget::~GrVkRenderTarget() {
261 // either release or abandon should have been called by the owner of this object.
egdanielb2df0c22016-05-13 11:30:37 -0700262 SkASSERT(!fMSAAImage);
Greg Daniel164a9f02016-02-22 09:56:40 -0500263 SkASSERT(!fResolveAttachmentView);
264 SkASSERT(!fColorAttachmentView);
265 SkASSERT(!fFramebuffer);
266 SkASSERT(!fCachedSimpleRenderPass);
267}
268
269void GrVkRenderTarget::addResources(GrVkCommandBuffer& commandBuffer) const {
270 commandBuffer.addResource(this->framebuffer());
Greg Daniel164a9f02016-02-22 09:56:40 -0500271 commandBuffer.addResource(this->colorAttachmentView());
egdanielce3bfb12016-08-26 11:05:13 -0700272 commandBuffer.addResource(this->msaaImageResource() ? this->msaaImageResource()
273 : this->resource());
Greg Daniel164a9f02016-02-22 09:56:40 -0500274 if (this->stencilImageResource()) {
275 commandBuffer.addResource(this->stencilImageResource());
276 commandBuffer.addResource(this->stencilAttachmentView());
277 }
278}
279
280void GrVkRenderTarget::releaseInternalObjects() {
281 GrVkGpu* gpu = this->getVkGpu();
282
egdanielb2df0c22016-05-13 11:30:37 -0700283 if (fMSAAImage) {
284 fMSAAImage->releaseImage(gpu);
Greg Daniel2db32322017-04-03 10:29:43 -0400285 fMSAAImage.reset();
Greg Daniel164a9f02016-02-22 09:56:40 -0500286 }
287
288 if (fResolveAttachmentView) {
289 fResolveAttachmentView->unref(gpu);
290 fResolveAttachmentView = nullptr;
291 }
292 if (fColorAttachmentView) {
293 fColorAttachmentView->unref(gpu);
294 fColorAttachmentView = nullptr;
295 }
296 if (fFramebuffer) {
297 fFramebuffer->unref(gpu);
298 fFramebuffer = nullptr;
299 }
300 if (fCachedSimpleRenderPass) {
301 fCachedSimpleRenderPass->unref(gpu);
302 fCachedSimpleRenderPass = nullptr;
303 }
304}
305
306void GrVkRenderTarget::abandonInternalObjects() {
egdanielb2df0c22016-05-13 11:30:37 -0700307 if (fMSAAImage) {
308 fMSAAImage->abandonImage();
Greg Daniel2db32322017-04-03 10:29:43 -0400309 fMSAAImage.reset();
Greg Daniel164a9f02016-02-22 09:56:40 -0500310 }
311
312 if (fResolveAttachmentView) {
313 fResolveAttachmentView->unrefAndAbandon();
314 fResolveAttachmentView = nullptr;
315 }
316 if (fColorAttachmentView) {
317 fColorAttachmentView->unrefAndAbandon();
318 fColorAttachmentView = nullptr;
319 }
320 if (fFramebuffer) {
321 fFramebuffer->unrefAndAbandon();
322 fFramebuffer = nullptr;
323 }
324 if (fCachedSimpleRenderPass) {
325 fCachedSimpleRenderPass->unrefAndAbandon();
326 fCachedSimpleRenderPass = nullptr;
327 }
328}
329
330void GrVkRenderTarget::onRelease() {
331 this->releaseInternalObjects();
kkinnunen2e6055b2016-04-22 01:48:29 -0700332 this->releaseImage(this->getVkGpu());
Greg Daniel164a9f02016-02-22 09:56:40 -0500333 GrRenderTarget::onRelease();
334}
335
336void GrVkRenderTarget::onAbandon() {
337 this->abandonInternalObjects();
338 this->abandonImage();
339 GrRenderTarget::onAbandon();
340}
341
342
343GrBackendObject GrVkRenderTarget::getRenderTargetHandle() const {
egdaniel580fa592016-08-31 11:03:50 -0700344 // If the render target is multisampled, we currently return the ImageInfo for the resolved
345 // image. If we only wrap the msaa target (currently not implemented) we should return a handle
346 // to that instead.
347 return (GrBackendObject)&fInfo;
Greg Daniel164a9f02016-02-22 09:56:40 -0500348}
349
egdanielb2df0c22016-05-13 11:30:37 -0700350const GrVkResource* GrVkRenderTarget::stencilImageResource() const {
Greg Daniel164a9f02016-02-22 09:56:40 -0500351 const GrStencilAttachment* stencil = this->renderTargetPriv().getStencilAttachment();
352 if (stencil) {
353 const GrVkStencilAttachment* vkStencil = static_cast<const GrVkStencilAttachment*>(stencil);
354 return vkStencil->imageResource();
355 }
356
357 return nullptr;
358}
359
360const GrVkImageView* GrVkRenderTarget::stencilAttachmentView() const {
361 const GrStencilAttachment* stencil = this->renderTargetPriv().getStencilAttachment();
362 if (stencil) {
363 const GrVkStencilAttachment* vkStencil = static_cast<const GrVkStencilAttachment*>(stencil);
364 return vkStencil->stencilView();
365 }
366
367 return nullptr;
368}
369
370
371GrVkGpu* GrVkRenderTarget::getVkGpu() const {
372 SkASSERT(!this->wasDestroyed());
373 return static_cast<GrVkGpu*>(this->getGpu());
374}