1 /*
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 "GrTexturePriv.h"
12 #include "GrVkGpu.h"
13 #include "GrVkImageView.h"
14 #include "GrVkUtil.h"
15
16 #include "SkMipMap.h"
17
18 #include "vk/GrVkTypes.h"
19
20 #define VK_CALL(GPU, X) GR_VK_CALL(GPU->vkInterface(), X)
21
GrVkTextureRenderTarget(GrVkGpu * gpu,SkBudgeted budgeted,const GrSurfaceDesc & desc,const GrVkImageInfo & info,const GrVkImageView * texView,const GrVkImageInfo & msaaInfo,const GrVkImageView * colorAttachmentView,const GrVkImageView * resolveAttachmentView)22 GrVkTextureRenderTarget::GrVkTextureRenderTarget(GrVkGpu* gpu,
23 SkBudgeted budgeted,
24 const GrSurfaceDesc& desc,
25 const GrVkImageInfo& info,
26 const GrVkImageView* texView,
27 const GrVkImageInfo& msaaInfo,
28 const GrVkImageView* colorAttachmentView,
29 const GrVkImageView* resolveAttachmentView)
30 : GrSurface(gpu, desc)
31 , GrVkImage(info, GrVkImage::kNot_Wrapped)
32 , GrVkTexture(gpu, desc, info, texView, GrVkImage::kNot_Wrapped)
33 , GrVkRenderTarget(gpu, desc, info, msaaInfo, colorAttachmentView,
34 resolveAttachmentView, GrVkImage::kNot_Wrapped) {
35 this->registerWithCache(budgeted);
36 }
37
GrVkTextureRenderTarget(GrVkGpu * gpu,SkBudgeted budgeted,const GrSurfaceDesc & desc,const GrVkImageInfo & info,const GrVkImageView * texView,const GrVkImageView * colorAttachmentView)38 GrVkTextureRenderTarget::GrVkTextureRenderTarget(GrVkGpu* gpu,
39 SkBudgeted budgeted,
40 const GrSurfaceDesc& desc,
41 const GrVkImageInfo& info,
42 const GrVkImageView* texView,
43 const GrVkImageView* colorAttachmentView)
44 : GrSurface(gpu, desc)
45 , GrVkImage(info, GrVkImage::kNot_Wrapped)
46 , GrVkTexture(gpu, desc, info, texView, GrVkImage::kNot_Wrapped)
47 , GrVkRenderTarget(gpu, desc, info, colorAttachmentView, GrVkImage::kNot_Wrapped) {
48 this->registerWithCache(budgeted);
49 }
50
GrVkTextureRenderTarget(GrVkGpu * gpu,const GrSurfaceDesc & desc,const GrVkImageInfo & info,const GrVkImageView * texView,const GrVkImageInfo & msaaInfo,const GrVkImageView * colorAttachmentView,const GrVkImageView * resolveAttachmentView,GrVkImage::Wrapped wrapped)51 GrVkTextureRenderTarget::GrVkTextureRenderTarget(GrVkGpu* gpu,
52 const GrSurfaceDesc& desc,
53 const GrVkImageInfo& info,
54 const GrVkImageView* texView,
55 const GrVkImageInfo& msaaInfo,
56 const GrVkImageView* colorAttachmentView,
57 const GrVkImageView* resolveAttachmentView,
58 GrVkImage::Wrapped wrapped)
59 : GrSurface(gpu, desc)
60 , GrVkImage(info, wrapped)
61 , GrVkTexture(gpu, desc, info, texView, wrapped)
62 , GrVkRenderTarget(gpu, desc, info, msaaInfo, colorAttachmentView,
63 resolveAttachmentView, wrapped) {
64 this->registerWithCacheWrapped();
65 }
66
GrVkTextureRenderTarget(GrVkGpu * gpu,const GrSurfaceDesc & desc,const GrVkImageInfo & info,const GrVkImageView * texView,const GrVkImageView * colorAttachmentView,GrVkImage::Wrapped wrapped)67 GrVkTextureRenderTarget::GrVkTextureRenderTarget(GrVkGpu* gpu,
68 const GrSurfaceDesc& desc,
69 const GrVkImageInfo& info,
70 const GrVkImageView* texView,
71 const GrVkImageView* colorAttachmentView,
72 GrVkImage::Wrapped wrapped)
73 : GrSurface(gpu, desc)
74 , GrVkImage(info, wrapped)
75 , GrVkTexture(gpu, desc, info, texView, wrapped)
76 , GrVkRenderTarget(gpu, desc, info, colorAttachmentView, wrapped) {
77 this->registerWithCacheWrapped();
78 }
79
80
Make(GrVkGpu * gpu,const GrSurfaceDesc & desc,const GrVkImageInfo & info,SkBudgeted budgeted,GrVkImage::Wrapped wrapped)81 sk_sp<GrVkTextureRenderTarget> GrVkTextureRenderTarget::Make(GrVkGpu* gpu,
82 const GrSurfaceDesc& desc,
83 const GrVkImageInfo& info,
84 SkBudgeted budgeted,
85 GrVkImage::Wrapped wrapped) {
86 VkImage image = info.fImage;
87 // Create the texture ImageView
88 const GrVkImageView* imageView = GrVkImageView::Create(gpu, image, info.fFormat,
89 GrVkImageView::kColor_Type,
90 info.fLevelCount);
91 if (!imageView) {
92 return nullptr;
93 }
94
95 VkFormat pixelFormat;
96 GrPixelConfigToVkFormat(desc.fConfig, &pixelFormat);
97
98 VkImage colorImage;
99
100 // create msaa surface if necessary
101 GrVkImageInfo msInfo;
102 const GrVkImageView* resolveAttachmentView = nullptr;
103 if (desc.fSampleCnt) {
104 GrVkImage::ImageDesc msImageDesc;
105 msImageDesc.fImageType = VK_IMAGE_TYPE_2D;
106 msImageDesc.fFormat = pixelFormat;
107 msImageDesc.fWidth = desc.fWidth;
108 msImageDesc.fHeight = desc.fHeight;
109 msImageDesc.fLevels = 1;
110 msImageDesc.fSamples = desc.fSampleCnt;
111 msImageDesc.fImageTiling = VK_IMAGE_TILING_OPTIMAL;
112 msImageDesc.fUsageFlags = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
113 VK_IMAGE_USAGE_TRANSFER_DST_BIT |
114 VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
115 msImageDesc.fMemProps = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
116
117 if (!GrVkImage::InitImageInfo(gpu, msImageDesc, &msInfo)) {
118 imageView->unref(gpu);
119 return nullptr;
120 }
121
122 // Set color attachment image
123 colorImage = msInfo.fImage;
124
125 // Create resolve attachment view.
126 resolveAttachmentView = GrVkImageView::Create(gpu, image, pixelFormat,
127 GrVkImageView::kColor_Type,
128 info.fLevelCount);
129 if (!resolveAttachmentView) {
130 GrVkImage::DestroyImageInfo(gpu, &msInfo);
131 imageView->unref(gpu);
132 return nullptr;
133 }
134 } else {
135 // Set color attachment image
136 colorImage = info.fImage;
137 }
138
139 const GrVkImageView* colorAttachmentView = GrVkImageView::Create(gpu, colorImage, pixelFormat,
140 GrVkImageView::kColor_Type, 1);
141 if (!colorAttachmentView) {
142 if (desc.fSampleCnt) {
143 resolveAttachmentView->unref(gpu);
144 GrVkImage::DestroyImageInfo(gpu, &msInfo);
145 }
146 imageView->unref(gpu);
147 return nullptr;
148 }
149
150 sk_sp<GrVkTextureRenderTarget> texRT;
151 if (desc.fSampleCnt) {
152 if (GrVkImage::kNot_Wrapped == wrapped) {
153 texRT = sk_sp<GrVkTextureRenderTarget>(new GrVkTextureRenderTarget(
154 gpu, budgeted, desc,
155 info, imageView, msInfo,
156 colorAttachmentView,
157 resolveAttachmentView));
158 } else {
159 texRT = sk_sp<GrVkTextureRenderTarget>(new GrVkTextureRenderTarget(
160 gpu, desc,
161 info, imageView, msInfo,
162 colorAttachmentView,
163 resolveAttachmentView, wrapped));
164 }
165 } else {
166 if (GrVkImage::kNot_Wrapped == wrapped) {
167 texRT = sk_sp<GrVkTextureRenderTarget>(new GrVkTextureRenderTarget(
168 gpu, budgeted, desc,
169 info, imageView,
170 colorAttachmentView));
171 } else {
172 texRT = sk_sp<GrVkTextureRenderTarget>(new GrVkTextureRenderTarget(
173 gpu, desc,
174 info, imageView,
175 colorAttachmentView, wrapped));
176 }
177 }
178 return texRT;
179 }
180
181 sk_sp<GrVkTextureRenderTarget>
CreateNewTextureRenderTarget(GrVkGpu * gpu,SkBudgeted budgeted,const GrSurfaceDesc & desc,const GrVkImage::ImageDesc & imageDesc)182 GrVkTextureRenderTarget::CreateNewTextureRenderTarget(GrVkGpu* gpu,
183 SkBudgeted budgeted,
184 const GrSurfaceDesc& desc,
185 const GrVkImage::ImageDesc& imageDesc) {
186 SkASSERT(imageDesc.fUsageFlags & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
187 SkASSERT(imageDesc.fUsageFlags & VK_IMAGE_USAGE_SAMPLED_BIT);
188
189 GrVkImageInfo info;
190 if (!GrVkImage::InitImageInfo(gpu, imageDesc, &info)) {
191 return nullptr;
192 }
193
194 sk_sp<GrVkTextureRenderTarget> trt = Make(gpu, desc, info, budgeted, GrVkImage::kNot_Wrapped);
195 if (!trt) {
196 GrVkImage::DestroyImageInfo(gpu, &info);
197 }
198
199 return trt;
200 }
201
202 sk_sp<GrVkTextureRenderTarget>
MakeWrappedTextureRenderTarget(GrVkGpu * gpu,const GrSurfaceDesc & desc,GrWrapOwnership ownership,const GrVkImageInfo * info)203 GrVkTextureRenderTarget::MakeWrappedTextureRenderTarget(GrVkGpu* gpu,
204 const GrSurfaceDesc& desc,
205 GrWrapOwnership ownership,
206 const GrVkImageInfo* info) {
207 SkASSERT(info);
208 // Wrapped textures require both image and allocation (because they can be mapped)
209 SkASSERT(VK_NULL_HANDLE != info->fImage && VK_NULL_HANDLE != info->fAlloc.fMemory);
210
211 GrVkImage::Wrapped wrapped = kBorrow_GrWrapOwnership == ownership ? GrVkImage::kBorrowed_Wrapped
212 : GrVkImage::kAdopted_Wrapped;
213
214 return Make(gpu, desc, *info, SkBudgeted::kNo, wrapped);
215 }
216
updateForMipmap(GrVkGpu * gpu,const GrVkImageInfo & newInfo)217 bool GrVkTextureRenderTarget::updateForMipmap(GrVkGpu* gpu, const GrVkImageInfo& newInfo) {
218 VkFormat pixelFormat;
219 GrPixelConfigToVkFormat(this->config(), &pixelFormat);
220 if (this->numStencilSamples()) {
221 const GrVkImageView* resolveAttachmentView =
222 GrVkImageView::Create(gpu,
223 newInfo.fImage,
224 pixelFormat,
225 GrVkImageView::kColor_Type,
226 newInfo.fLevelCount);
227 if (!resolveAttachmentView) {
228 return false;
229 }
230 fResolveAttachmentView->unref(gpu);
231 fResolveAttachmentView = resolveAttachmentView;
232 } else {
233 const GrVkImageView* colorAttachmentView = GrVkImageView::Create(gpu,
234 newInfo.fImage,
235 pixelFormat,
236 GrVkImageView::kColor_Type,
237 1);
238 if (!colorAttachmentView) {
239 return false;
240 }
241 fColorAttachmentView->unref(gpu);
242 fColorAttachmentView = colorAttachmentView;
243 }
244
245 this->createFramebuffer(gpu);
246 return true;
247 }
248
onGpuMemorySize() const249 size_t GrVkTextureRenderTarget::onGpuMemorySize() const {
250 // The plus 1 is to account for the resolve texture.
251 int numColorSamples = this->numColorSamples() + 1;
252 return GrSurface::ComputeSize(this->config(), this->width(), this->height(),
253 numColorSamples, // TODO: this still correct?
254 this->texturePriv().hasMipMaps());
255 }
256