• 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 "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