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