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