blob: 2c3ea4059f6004d0ff0a5b26a56d9c32aa2c5d22 [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,
31 GrVkImage::Wrapped wrapped)
kkinnunen2e6055b2016-04-22 01:48:29 -070032 : GrSurface(gpu, desc)
egdanielb2df0c22016-05-13 11:30:37 -070033 , GrVkImage(info, wrapped)
Greg Daniel164a9f02016-02-22 09:56:40 -050034 // for the moment we only support 1:1 color to stencil
kkinnunen2e6055b2016-04-22 01:48:29 -070035 , GrRenderTarget(gpu, desc, kUnified_SampleConfig)
Greg Daniel164a9f02016-02-22 09:56:40 -050036 , fFramebuffer(nullptr)
37 , fColorAttachmentView(colorAttachmentView)
egdaniel72ac55f2016-05-13 13:43:44 -070038 , fMSAAImage(new GrVkImage(msaaInfo, GrVkImage::kNot_Wrapped))
Greg Daniel164a9f02016-02-22 09:56:40 -050039 , fResolveAttachmentView(resolveAttachmentView)
40 , fCachedSimpleRenderPass(nullptr) {
41 SkASSERT(desc.fSampleCnt);
42 // The plus 1 is to account for the resolve texture.
43 fColorValuesPerPixel = desc.fSampleCnt + 1; // TODO: this still correct?
44 this->createFramebuffer(gpu);
kkinnunen2e6055b2016-04-22 01:48:29 -070045 this->registerWithCache(budgeted);
Greg Daniel164a9f02016-02-22 09:56:40 -050046}
47
48// We're virtually derived from GrSurface (via GrRenderTarget) so its
49// constructor must be explicitly called.
50GrVkRenderTarget::GrVkRenderTarget(GrVkGpu* gpu,
51 const GrSurfaceDesc& desc,
egdanielb2df0c22016-05-13 11:30:37 -070052 const GrVkImageInfo& info,
53 const GrVkImageInfo& msaaInfo,
Greg Daniel164a9f02016-02-22 09:56:40 -050054 const GrVkImageView* colorAttachmentView,
egdanielb2df0c22016-05-13 11:30:37 -070055 const GrVkImageView* resolveAttachmentView,
56 GrVkImage::Wrapped wrapped)
kkinnunen2e6055b2016-04-22 01:48:29 -070057 : GrSurface(gpu, desc)
egdanielb2df0c22016-05-13 11:30:37 -070058 , GrVkImage(info, wrapped)
Greg Daniel164a9f02016-02-22 09:56:40 -050059 // for the moment we only support 1:1 color to stencil
kkinnunen2e6055b2016-04-22 01:48:29 -070060 , GrRenderTarget(gpu, desc, kUnified_SampleConfig)
Greg Daniel164a9f02016-02-22 09:56:40 -050061 , fFramebuffer(nullptr)
62 , fColorAttachmentView(colorAttachmentView)
egdaniel72ac55f2016-05-13 13:43:44 -070063 , fMSAAImage(new GrVkImage(msaaInfo, GrVkImage::kNot_Wrapped))
Greg Daniel164a9f02016-02-22 09:56:40 -050064 , fResolveAttachmentView(resolveAttachmentView)
65 , fCachedSimpleRenderPass(nullptr) {
66 SkASSERT(desc.fSampleCnt);
67 // The plus 1 is to account for the resolve texture.
68 fColorValuesPerPixel = desc.fSampleCnt + 1; // TODO: this still correct?
69 this->createFramebuffer(gpu);
Greg Daniel164a9f02016-02-22 09:56:40 -050070}
71
72// We're virtually derived from GrSurface (via GrRenderTarget) so its
73// constructor must be explicitly called.
74GrVkRenderTarget::GrVkRenderTarget(GrVkGpu* gpu,
kkinnunen2e6055b2016-04-22 01:48:29 -070075 SkBudgeted budgeted,
Greg Daniel164a9f02016-02-22 09:56:40 -050076 const GrSurfaceDesc& desc,
egdanielb2df0c22016-05-13 11:30:37 -070077 const GrVkImageInfo& info,
78 const GrVkImageView* colorAttachmentView,
79 GrVkImage::Wrapped wrapped)
kkinnunen2e6055b2016-04-22 01:48:29 -070080 : GrSurface(gpu, desc)
egdanielb2df0c22016-05-13 11:30:37 -070081 , GrVkImage(info, wrapped)
kkinnunen2e6055b2016-04-22 01:48:29 -070082 , GrRenderTarget(gpu, desc, kUnified_SampleConfig)
Greg Daniel164a9f02016-02-22 09:56:40 -050083 , fFramebuffer(nullptr)
84 , fColorAttachmentView(colorAttachmentView)
egdanielb2df0c22016-05-13 11:30:37 -070085 , fMSAAImage(nullptr)
Greg Daniel164a9f02016-02-22 09:56:40 -050086 , fResolveAttachmentView(nullptr)
87 , fCachedSimpleRenderPass(nullptr) {
88 SkASSERT(!desc.fSampleCnt);
89 fColorValuesPerPixel = 1;
90 this->createFramebuffer(gpu);
kkinnunen2e6055b2016-04-22 01:48:29 -070091 this->registerWithCache(budgeted);
Greg Daniel164a9f02016-02-22 09:56:40 -050092}
93
94// We're virtually derived from GrSurface (via GrRenderTarget) so its
95// constructor must be explicitly called.
96GrVkRenderTarget::GrVkRenderTarget(GrVkGpu* gpu,
97 const GrSurfaceDesc& desc,
egdanielb2df0c22016-05-13 11:30:37 -070098 const GrVkImageInfo& info,
99 const GrVkImageView* colorAttachmentView,
100 GrVkImage::Wrapped wrapped)
kkinnunen2e6055b2016-04-22 01:48:29 -0700101 : GrSurface(gpu, desc)
egdanielb2df0c22016-05-13 11:30:37 -0700102 , GrVkImage(info, wrapped)
kkinnunen2e6055b2016-04-22 01:48:29 -0700103 , GrRenderTarget(gpu, desc, kUnified_SampleConfig)
Greg Daniel164a9f02016-02-22 09:56:40 -0500104 , fFramebuffer(nullptr)
105 , fColorAttachmentView(colorAttachmentView)
egdanielb2df0c22016-05-13 11:30:37 -0700106 , fMSAAImage(nullptr)
Greg Daniel164a9f02016-02-22 09:56:40 -0500107 , fResolveAttachmentView(nullptr)
108 , fCachedSimpleRenderPass(nullptr) {
109 SkASSERT(!desc.fSampleCnt);
110 fColorValuesPerPixel = 1;
111 this->createFramebuffer(gpu);
112}
113
114GrVkRenderTarget*
115GrVkRenderTarget::Create(GrVkGpu* gpu,
kkinnunen2e6055b2016-04-22 01:48:29 -0700116 SkBudgeted budgeted,
Greg Daniel164a9f02016-02-22 09:56:40 -0500117 const GrSurfaceDesc& desc,
egdanielb2df0c22016-05-13 11:30:37 -0700118 const GrVkImageInfo& info,
119 GrVkImage::Wrapped wrapped) {
Greg Daniel164a9f02016-02-22 09:56:40 -0500120 VkFormat pixelFormat;
121 GrPixelConfigToVkFormat(desc.fConfig, &pixelFormat);
halcanary9d524f22016-03-29 09:03:52 -0700122
Greg Daniel164a9f02016-02-22 09:56:40 -0500123 VkImage colorImage;
124
125 // create msaa surface if necessary
egdanielb2df0c22016-05-13 11:30:37 -0700126 GrVkImageInfo msInfo;
Greg Daniel164a9f02016-02-22 09:56:40 -0500127 const GrVkImageView* resolveAttachmentView = nullptr;
128 if (desc.fSampleCnt) {
129 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;
137 msImageDesc.fUsageFlags = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
138 msImageDesc.fMemProps = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
139
egdanielb2df0c22016-05-13 11:30:37 -0700140 if (!GrVkImage::InitImageInfo(gpu, msImageDesc, &msInfo)) {
Greg Daniel164a9f02016-02-22 09:56:40 -0500141 return nullptr;
142 }
143
144 // Set color attachment image
egdanielb2df0c22016-05-13 11:30:37 -0700145 colorImage = msInfo.fImage;
Greg Daniel164a9f02016-02-22 09:56:40 -0500146
147 // Create Resolve attachment view
egdanielb2df0c22016-05-13 11:30:37 -0700148 resolveAttachmentView = GrVkImageView::Create(gpu, info.fImage, pixelFormat,
jvanverth62340062016-04-26 08:01:44 -0700149 GrVkImageView::kColor_Type, 1);
Greg Daniel164a9f02016-02-22 09:56:40 -0500150 if (!resolveAttachmentView) {
egdanielb2df0c22016-05-13 11:30:37 -0700151 GrVkImage::DestroyImageInfo(gpu, &msInfo);
Greg Daniel164a9f02016-02-22 09:56:40 -0500152 return nullptr;
153 }
154 } else {
155 // Set color attachment image
egdanielb2df0c22016-05-13 11:30:37 -0700156 colorImage = info.fImage;
Greg Daniel164a9f02016-02-22 09:56:40 -0500157 }
158
159 // Get color attachment view
160 const GrVkImageView* colorAttachmentView = GrVkImageView::Create(gpu, colorImage, pixelFormat,
jvanverth62340062016-04-26 08:01:44 -0700161 GrVkImageView::kColor_Type, 1);
Greg Daniel164a9f02016-02-22 09:56:40 -0500162 if (!colorAttachmentView) {
egdanielb2df0c22016-05-13 11:30:37 -0700163 if (desc.fSampleCnt) {
Greg Daniel164a9f02016-02-22 09:56:40 -0500164 resolveAttachmentView->unref(gpu);
egdanielb2df0c22016-05-13 11:30:37 -0700165 GrVkImage::DestroyImageInfo(gpu, &msInfo);
Greg Daniel164a9f02016-02-22 09:56:40 -0500166 }
egdanielb2df0c22016-05-13 11:30:37 -0700167 return nullptr;
Greg Daniel164a9f02016-02-22 09:56:40 -0500168 }
169
170 GrVkRenderTarget* texRT;
egdanielb2df0c22016-05-13 11:30:37 -0700171 if (desc.fSampleCnt) {
172 texRT = new GrVkRenderTarget(gpu, budgeted, desc, info, msInfo,
173 colorAttachmentView, resolveAttachmentView, wrapped);
Greg Daniel164a9f02016-02-22 09:56:40 -0500174 } else {
egdanielb2df0c22016-05-13 11:30:37 -0700175 texRT = new GrVkRenderTarget(gpu, budgeted, desc, info, colorAttachmentView, wrapped);
Greg Daniel164a9f02016-02-22 09:56:40 -0500176 }
177
178 return texRT;
179}
180
181GrVkRenderTarget*
182GrVkRenderTarget::CreateNewRenderTarget(GrVkGpu* gpu,
kkinnunen2e6055b2016-04-22 01:48:29 -0700183 SkBudgeted budgeted,
Greg Daniel164a9f02016-02-22 09:56:40 -0500184 const GrSurfaceDesc& desc,
Greg Daniel164a9f02016-02-22 09:56:40 -0500185 const GrVkImage::ImageDesc& imageDesc) {
186 SkASSERT(imageDesc.fUsageFlags & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
187
egdanielb2df0c22016-05-13 11:30:37 -0700188 GrVkImageInfo info;
189 if (!GrVkImage::InitImageInfo(gpu, imageDesc, &info)) {
Greg Daniel164a9f02016-02-22 09:56:40 -0500190 return nullptr;
191 }
192
egdanielb2df0c22016-05-13 11:30:37 -0700193 GrVkRenderTarget* rt = GrVkRenderTarget::Create(gpu, budgeted, desc, info,
194 GrVkImage::kNot_Wrapped);
195 if (!rt) {
196 GrVkImage::DestroyImageInfo(gpu, &info);
197 }
Greg Daniel164a9f02016-02-22 09:56:40 -0500198 return rt;
199}
200
201GrVkRenderTarget*
202GrVkRenderTarget::CreateWrappedRenderTarget(GrVkGpu* gpu,
203 const GrSurfaceDesc& desc,
kkinnunen2e6055b2016-04-22 01:48:29 -0700204 GrWrapOwnership ownership,
egdanielb2df0c22016-05-13 11:30:37 -0700205 const GrVkImageInfo* info) {
jvanverthfd359ca2016-03-18 11:57:24 -0700206 SkASSERT(info);
207 // We can wrap a rendertarget without its allocation, as long as we don't take ownership
208 SkASSERT(VK_NULL_HANDLE != info->fImage);
kkinnunen2e6055b2016-04-22 01:48:29 -0700209 SkASSERT(VK_NULL_HANDLE != info->fAlloc || kAdopt_GrWrapOwnership != ownership);
Greg Daniel164a9f02016-02-22 09:56:40 -0500210
egdanielb2df0c22016-05-13 11:30:37 -0700211 GrVkImage::Wrapped wrapped = kBorrow_GrWrapOwnership == ownership ? GrVkImage::kBorrowed_Wrapped
212 : GrVkImage::kAdopted_Wrapped;
jvanverthfd359ca2016-03-18 11:57:24 -0700213
egdanielb2df0c22016-05-13 11:30:37 -0700214 GrVkRenderTarget* rt = GrVkRenderTarget::Create(gpu, SkBudgeted::kNo, desc, *info, wrapped);
jvanverthfe170d22016-03-22 13:15:44 -0700215
jvanverthfd359ca2016-03-18 11:57:24 -0700216 return rt;
Greg Daniel164a9f02016-02-22 09:56:40 -0500217}
218
219bool GrVkRenderTarget::completeStencilAttachment() {
220 this->createFramebuffer(this->getVkGpu());
221 return true;
222}
223
224void GrVkRenderTarget::createFramebuffer(GrVkGpu* gpu) {
225 if (fFramebuffer) {
226 fFramebuffer->unref(gpu);
227 }
228 if (fCachedSimpleRenderPass) {
229 fCachedSimpleRenderPass->unref(gpu);
230 }
231
232 // Vulkan requires us to create a compatible renderpass before we can create our framebuffer,
233 // so we use this to get a (cached) basic renderpass, only for creation.
234 fCachedSimpleRenderPass = gpu->resourceProvider().findOrCreateCompatibleRenderPass(*this);
235
236 // Stencil attachment view is stored in the base RT stencil attachment
237 const GrVkImageView* stencilView = this->stencilAttachmentView();
238 fFramebuffer = GrVkFramebuffer::Create(gpu, this->width(), this->height(),
239 fCachedSimpleRenderPass, fColorAttachmentView,
240 fResolveAttachmentView, stencilView);
241 SkASSERT(fFramebuffer);
242}
243
244void GrVkRenderTarget::getAttachmentsDescriptor(
245 GrVkRenderPass::AttachmentsDescriptor* desc,
246 GrVkRenderPass::AttachmentFlags* attachmentFlags) const {
247 int colorSamples = this->numColorSamples();
248 VkFormat colorFormat;
249 GrPixelConfigToVkFormat(this->config(), &colorFormat);
250 desc->fColor.fFormat = colorFormat;
251 desc->fColor.fSamples = colorSamples ? colorSamples : 1;
252 *attachmentFlags = GrVkRenderPass::kColor_AttachmentFlag;
253 uint32_t attachmentCount = 1;
254 if (colorSamples > 0) {
255 desc->fResolve.fFormat = colorFormat;
256 desc->fResolve.fSamples = 1;
257 *attachmentFlags |= GrVkRenderPass::kResolve_AttachmentFlag;
258 ++attachmentCount;
259 }
260
261 const GrStencilAttachment* stencil = this->renderTargetPriv().getStencilAttachment();
262 if (stencil) {
263 const GrVkStencilAttachment* vkStencil = static_cast<const GrVkStencilAttachment*>(stencil);
264 desc->fStencil.fFormat = vkStencil->vkFormat();
265 desc->fStencil.fSamples = vkStencil->numSamples() ? vkStencil->numSamples() : 1;
266 // Currently in vulkan stencil and color attachments must all have same number of samples
267 SkASSERT(desc->fColor.fSamples == desc->fStencil.fSamples);
268 *attachmentFlags |= GrVkRenderPass::kStencil_AttachmentFlag;
269 ++attachmentCount;
270 }
271 desc->fAttachmentCount = attachmentCount;
272}
273
274GrVkRenderTarget::~GrVkRenderTarget() {
275 // either release or abandon should have been called by the owner of this object.
egdanielb2df0c22016-05-13 11:30:37 -0700276 SkASSERT(!fMSAAImage);
Greg Daniel164a9f02016-02-22 09:56:40 -0500277 SkASSERT(!fResolveAttachmentView);
278 SkASSERT(!fColorAttachmentView);
279 SkASSERT(!fFramebuffer);
280 SkASSERT(!fCachedSimpleRenderPass);
281}
282
283void GrVkRenderTarget::addResources(GrVkCommandBuffer& commandBuffer) const {
284 commandBuffer.addResource(this->framebuffer());
285 commandBuffer.addResource(this->resource());
286 commandBuffer.addResource(this->colorAttachmentView());
287 if (this->msaaImageResource()) {
288 commandBuffer.addResource(this->msaaImageResource());
289 commandBuffer.addResource(this->resolveAttachmentView());
290 }
291 if (this->stencilImageResource()) {
292 commandBuffer.addResource(this->stencilImageResource());
293 commandBuffer.addResource(this->stencilAttachmentView());
294 }
295}
296
297void GrVkRenderTarget::releaseInternalObjects() {
298 GrVkGpu* gpu = this->getVkGpu();
299
egdanielb2df0c22016-05-13 11:30:37 -0700300 if (fMSAAImage) {
301 fMSAAImage->releaseImage(gpu);
302 fMSAAImage = nullptr;
Greg Daniel164a9f02016-02-22 09:56:40 -0500303 }
304
305 if (fResolveAttachmentView) {
306 fResolveAttachmentView->unref(gpu);
307 fResolveAttachmentView = nullptr;
308 }
309 if (fColorAttachmentView) {
310 fColorAttachmentView->unref(gpu);
311 fColorAttachmentView = nullptr;
312 }
313 if (fFramebuffer) {
314 fFramebuffer->unref(gpu);
315 fFramebuffer = nullptr;
316 }
317 if (fCachedSimpleRenderPass) {
318 fCachedSimpleRenderPass->unref(gpu);
319 fCachedSimpleRenderPass = nullptr;
320 }
321}
322
323void GrVkRenderTarget::abandonInternalObjects() {
egdanielb2df0c22016-05-13 11:30:37 -0700324 if (fMSAAImage) {
325 fMSAAImage->abandonImage();
326 fMSAAImage = nullptr;
Greg Daniel164a9f02016-02-22 09:56:40 -0500327 }
328
329 if (fResolveAttachmentView) {
330 fResolveAttachmentView->unrefAndAbandon();
331 fResolveAttachmentView = nullptr;
332 }
333 if (fColorAttachmentView) {
334 fColorAttachmentView->unrefAndAbandon();
335 fColorAttachmentView = nullptr;
336 }
337 if (fFramebuffer) {
338 fFramebuffer->unrefAndAbandon();
339 fFramebuffer = nullptr;
340 }
341 if (fCachedSimpleRenderPass) {
342 fCachedSimpleRenderPass->unrefAndAbandon();
343 fCachedSimpleRenderPass = nullptr;
344 }
345}
346
347void GrVkRenderTarget::onRelease() {
348 this->releaseInternalObjects();
kkinnunen2e6055b2016-04-22 01:48:29 -0700349 this->releaseImage(this->getVkGpu());
Greg Daniel164a9f02016-02-22 09:56:40 -0500350 GrRenderTarget::onRelease();
351}
352
353void GrVkRenderTarget::onAbandon() {
354 this->abandonInternalObjects();
355 this->abandonImage();
356 GrRenderTarget::onAbandon();
357}
358
359
360GrBackendObject GrVkRenderTarget::getRenderTargetHandle() const {
361 // Currently just passing back the pointer to the main Image::Resource as the handle
362 return (GrBackendObject)&fResource;
363}
364
egdanielb2df0c22016-05-13 11:30:37 -0700365const GrVkResource* GrVkRenderTarget::stencilImageResource() const {
Greg Daniel164a9f02016-02-22 09:56:40 -0500366 const GrStencilAttachment* stencil = this->renderTargetPriv().getStencilAttachment();
367 if (stencil) {
368 const GrVkStencilAttachment* vkStencil = static_cast<const GrVkStencilAttachment*>(stencil);
369 return vkStencil->imageResource();
370 }
371
372 return nullptr;
373}
374
375const GrVkImageView* GrVkRenderTarget::stencilAttachmentView() const {
376 const GrStencilAttachment* stencil = this->renderTargetPriv().getStencilAttachment();
377 if (stencil) {
378 const GrVkStencilAttachment* vkStencil = static_cast<const GrVkStencilAttachment*>(stencil);
379 return vkStencil->stencilView();
380 }
381
382 return nullptr;
383}
384
385
386GrVkGpu* GrVkRenderTarget::getVkGpu() const {
387 SkASSERT(!this->wasDestroyed());
388 return static_cast<GrVkGpu*>(this->getGpu());
389}