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