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