blob: 6bfdf3e8cf884792365cd216711caed1545355f8 [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 "GrVkTextureRenderTarget.h"
9
10#include "GrRenderTargetPriv.h"
11#include "GrVkGpu.h"
12#include "GrVkImageView.h"
13#include "GrVkUtil.h"
14
jvanverthfd359ca2016-03-18 11:57:24 -070015#include "vk/GrVkTypes.h"
16
Greg Daniel164a9f02016-02-22 09:56:40 -050017#define VK_CALL(GPU, X) GR_VK_CALL(GPU->vkInterface(), X)
18
kkinnunen2e6055b2016-04-22 01:48:29 -070019template<typename ResourceType>
20GrVkTextureRenderTarget* GrVkTextureRenderTarget::Create(GrVkGpu* gpu,
21 ResourceType resourceType,
22 const GrSurfaceDesc& desc,
23 VkFormat format,
24 const GrVkImage::Resource* imageResource) {
Greg Daniel164a9f02016-02-22 09:56:40 -050025 VkImage image = imageResource->fImage;
26 // Create the texture ImageView
27 const GrVkImageView* imageView = GrVkImageView::Create(gpu, image, format,
28 GrVkImageView::kColor_Type);
29 if (!imageView) {
30 return nullptr;
31 }
32
33 VkFormat pixelFormat;
34 GrPixelConfigToVkFormat(desc.fConfig, &pixelFormat);
35
36 VkImage colorImage;
37
38 // create msaa surface if necessary
39 const GrVkImage::Resource* msaaImageResource = nullptr;
40 const GrVkImageView* resolveAttachmentView = nullptr;
41 if (desc.fSampleCnt) {
42 GrVkImage::ImageDesc msImageDesc;
43 msImageDesc.fImageType = VK_IMAGE_TYPE_2D;
44 msImageDesc.fFormat = pixelFormat;
45 msImageDesc.fWidth = desc.fWidth;
46 msImageDesc.fHeight = desc.fHeight;
47 msImageDesc.fLevels = 1;
48 msImageDesc.fSamples = desc.fSampleCnt;
49 msImageDesc.fImageTiling = VK_IMAGE_TILING_OPTIMAL;
50 msImageDesc.fUsageFlags = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
51 msImageDesc.fMemProps = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
52
53 msaaImageResource = GrVkImage::CreateResource(gpu, msImageDesc);
54
55 if (!msaaImageResource) {
56 imageView->unref(gpu);
57 return nullptr;
58 }
59
60 // Set color attachment image
61 colorImage = msaaImageResource->fImage;
62
63 // Create resolve attachment view if necessary.
64 // If the format matches, this is the same as the texture imageView.
65 if (pixelFormat == format) {
66 resolveAttachmentView = imageView;
67 resolveAttachmentView->ref();
68 } else {
69 resolveAttachmentView = GrVkImageView::Create(gpu, image, pixelFormat,
70 GrVkImageView::kColor_Type);
71 if (!resolveAttachmentView) {
72 msaaImageResource->unref(gpu);
73 imageView->unref(gpu);
74 return nullptr;
75 }
76 }
77 } else {
78 // Set color attachment image
79 colorImage = imageResource->fImage;
80 }
81
82 const GrVkImageView* colorAttachmentView;
83 // Get color attachment view.
84 // If the format matches and there's no multisampling,
85 // this is the same as the texture imageView
86 if (pixelFormat == format && !resolveAttachmentView) {
87 colorAttachmentView = imageView;
88 colorAttachmentView->ref();
89 } else {
90 colorAttachmentView = GrVkImageView::Create(gpu, colorImage, pixelFormat,
91 GrVkImageView::kColor_Type);
92 if (!colorAttachmentView) {
93 if (msaaImageResource) {
94 resolveAttachmentView->unref(gpu);
95 msaaImageResource->unref(gpu);
96 }
97 imageView->unref(gpu);
98 return nullptr;
99 }
100 }
Greg Daniel164a9f02016-02-22 09:56:40 -0500101 GrVkTextureRenderTarget* texRT;
102 if (msaaImageResource) {
kkinnunen2e6055b2016-04-22 01:48:29 -0700103 texRT = new GrVkTextureRenderTarget(gpu, resourceType, desc,
Greg Daniel164a9f02016-02-22 09:56:40 -0500104 imageResource, imageView, msaaImageResource,
105 colorAttachmentView,
106 resolveAttachmentView);
107 msaaImageResource->unref(gpu);
108 } else {
kkinnunen2e6055b2016-04-22 01:48:29 -0700109 texRT = new GrVkTextureRenderTarget(gpu, resourceType, desc,
Greg Daniel164a9f02016-02-22 09:56:40 -0500110 imageResource, imageView,
111 colorAttachmentView);
112 }
113 return texRT;
114}
115
116GrVkTextureRenderTarget*
117GrVkTextureRenderTarget::CreateNewTextureRenderTarget(GrVkGpu* gpu,
kkinnunen2e6055b2016-04-22 01:48:29 -0700118 SkBudgeted budgeted,
119 const GrSurfaceDesc& desc,
120 const GrVkImage::ImageDesc& imageDesc) {
Greg Daniel164a9f02016-02-22 09:56:40 -0500121 SkASSERT(imageDesc.fUsageFlags & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
122 SkASSERT(imageDesc.fUsageFlags & VK_IMAGE_USAGE_SAMPLED_BIT);
123
124 const GrVkImage::Resource* imageRsrc = GrVkImage::CreateResource(gpu, imageDesc);
125
126 if (!imageRsrc) {
127 return nullptr;
128 }
129
kkinnunen2e6055b2016-04-22 01:48:29 -0700130 GrVkTextureRenderTarget* trt = Create(gpu, budgeted, desc, imageDesc.fFormat,
131 imageRsrc);
Greg Daniel164a9f02016-02-22 09:56:40 -0500132 // Create() will increment the refCount of the image resource if it succeeds
133 imageRsrc->unref(gpu);
134
135 return trt;
136}
137
138GrVkTextureRenderTarget*
139GrVkTextureRenderTarget::CreateWrappedTextureRenderTarget(GrVkGpu* gpu,
140 const GrSurfaceDesc& desc,
kkinnunen2e6055b2016-04-22 01:48:29 -0700141 GrWrapOwnership ownership,
halcanary9d524f22016-03-29 09:03:52 -0700142 VkFormat format,
jvanverthfd359ca2016-03-18 11:57:24 -0700143 const GrVkTextureInfo* info) {
144 SkASSERT(info);
145 // Wrapped textures require both image and allocation (because they can be mapped)
146 SkASSERT(VK_NULL_HANDLE != info->fImage && VK_NULL_HANDLE != info->fAlloc);
Greg Daniel164a9f02016-02-22 09:56:40 -0500147
jvanverthfd359ca2016-03-18 11:57:24 -0700148 GrVkImage::Resource::Flags flags = (VK_IMAGE_TILING_LINEAR == info->fImageTiling)
149 ? Resource::kLinearTiling_Flag : Resource::kNo_Flags;
150
jvanverthfe170d22016-03-22 13:15:44 -0700151 const GrVkImage::Resource* imageResource;
kkinnunen2e6055b2016-04-22 01:48:29 -0700152 if (kBorrow_GrWrapOwnership == ownership) {
egdaniel58a8d922016-04-21 08:03:10 -0700153 imageResource = new GrVkImage::BorrowedResource(info->fImage,
154 info->fAlloc,
155 flags,
156 info->fFormat);
jvanverthfe170d22016-03-22 13:15:44 -0700157 } else {
egdaniel58a8d922016-04-21 08:03:10 -0700158 imageResource = new GrVkImage::Resource(info->fImage, info->fAlloc, flags, info->fFormat);
jvanverthfe170d22016-03-22 13:15:44 -0700159 }
jvanverthfd359ca2016-03-18 11:57:24 -0700160 if (!imageResource) {
161 return nullptr;
162 }
kkinnunen2e6055b2016-04-22 01:48:29 -0700163 GrVkTextureRenderTarget* trt = Create(gpu, kWrapped, desc, format, imageResource);
jvanverthfd359ca2016-03-18 11:57:24 -0700164 if (trt) {
165 trt->fCurrentLayout = info->fImageLayout;
166 }
167 // Create() will increment the refCount of the image resource if it succeeds
168 imageResource->unref(gpu);
169
170 return trt;
Greg Daniel164a9f02016-02-22 09:56:40 -0500171}