• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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