blob: fef6b7292847045ce69267a085021a54d4df8536 [file] [log] [blame]
Greg Daniel164a9f02016-02-22 09:56:40 -05001/*
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 "GrVkTexture.h"
9#include "GrVkGpu.h"
10#include "GrVkImageView.h"
jvanverth62340062016-04-26 08:01:44 -070011#include "GrTexturePriv.h"
Greg Daniel164a9f02016-02-22 09:56:40 -050012#include "GrVkUtil.h"
13
jvanverthfd359ca2016-03-18 11:57:24 -070014#include "vk/GrVkTypes.h"
15
Greg Daniel164a9f02016-02-22 09:56:40 -050016#define VK_CALL(GPU, X) GR_VK_CALL(GPU->vkInterface(), X)
17
18// Because this class is virtually derived from GrSurface we must explicitly call its constructor.
19GrVkTexture::GrVkTexture(GrVkGpu* gpu,
kkinnunen2e6055b2016-04-22 01:48:29 -070020 SkBudgeted budgeted,
Greg Daniel164a9f02016-02-22 09:56:40 -050021 const GrSurfaceDesc& desc,
egdanielb2df0c22016-05-13 11:30:37 -070022 const GrVkImageInfo& info,
Greg Daniel164a9f02016-02-22 09:56:40 -050023 const GrVkImageView* view)
kkinnunen2e6055b2016-04-22 01:48:29 -070024 : GrSurface(gpu, desc)
egdanielb2df0c22016-05-13 11:30:37 -070025 , GrVkImage(info, GrVkImage::kNot_Wrapped)
jvanverth900bd4a2016-04-29 13:53:12 -070026 , INHERITED(gpu, desc, kSampler2D_GrSLType, desc.fIsMipMapped)
brianosmanf05ab1b2016-05-12 11:01:10 -070027 , fTextureView(view)
28 , fLinearTextureView(nullptr) {
kkinnunen2e6055b2016-04-22 01:48:29 -070029 this->registerWithCache(budgeted);
30}
31
32GrVkTexture::GrVkTexture(GrVkGpu* gpu,
33 Wrapped,
34 const GrSurfaceDesc& desc,
egdanielb2df0c22016-05-13 11:30:37 -070035 const GrVkImageInfo& info,
36 const GrVkImageView* view,
37 GrVkImage::Wrapped wrapped)
kkinnunen2e6055b2016-04-22 01:48:29 -070038 : GrSurface(gpu, desc)
egdanielb2df0c22016-05-13 11:30:37 -070039 , GrVkImage(info, wrapped)
jvanverth900bd4a2016-04-29 13:53:12 -070040 , INHERITED(gpu, desc, kSampler2D_GrSLType, desc.fIsMipMapped)
brianosmanf05ab1b2016-05-12 11:01:10 -070041 , fTextureView(view)
42 , fLinearTextureView(nullptr) {
kkinnunen2e6055b2016-04-22 01:48:29 -070043 this->registerWithCacheWrapped();
Greg Daniel164a9f02016-02-22 09:56:40 -050044}
45
46// Because this class is virtually derived from GrSurface we must explicitly call its constructor.
47GrVkTexture::GrVkTexture(GrVkGpu* gpu,
48 const GrSurfaceDesc& desc,
egdanielb2df0c22016-05-13 11:30:37 -070049 const GrVkImageInfo& info,
50 const GrVkImageView* view,
51 GrVkImage::Wrapped wrapped)
kkinnunen2e6055b2016-04-22 01:48:29 -070052 : GrSurface(gpu, desc)
egdanielb2df0c22016-05-13 11:30:37 -070053 , GrVkImage(info, wrapped)
jvanverth900bd4a2016-04-29 13:53:12 -070054 , INHERITED(gpu, desc, kSampler2D_GrSLType, desc.fIsMipMapped)
brianosmanf05ab1b2016-05-12 11:01:10 -070055 , fTextureView(view)
egdanielb2df0c22016-05-13 11:30:37 -070056 , fLinearTextureView(nullptr) {
Greg Daniel164a9f02016-02-22 09:56:40 -050057}
58
kkinnunen2e6055b2016-04-22 01:48:29 -070059GrVkTexture* GrVkTexture::CreateNewTexture(GrVkGpu* gpu, SkBudgeted budgeted,
60 const GrSurfaceDesc& desc,
Greg Daniel164a9f02016-02-22 09:56:40 -050061 const GrVkImage::ImageDesc& imageDesc) {
62 SkASSERT(imageDesc.fUsageFlags & VK_IMAGE_USAGE_SAMPLED_BIT);
63
egdanielb2df0c22016-05-13 11:30:37 -070064 GrVkImageInfo info;
65 if (!GrVkImage::InitImageInfo(gpu, imageDesc, &info)) {
Greg Daniel164a9f02016-02-22 09:56:40 -050066 return nullptr;
67 }
68
egdanielb2df0c22016-05-13 11:30:37 -070069 const GrVkImageView* imageView = GrVkImageView::Create(gpu, info.fImage, info.fFormat,
70 GrVkImageView::kColor_Type,
71 info.fLevelCount);
72 if (!imageView) {
73 GrVkImage::DestroyImageInfo(gpu, &info);
74 return nullptr;
75 }
Greg Daniel164a9f02016-02-22 09:56:40 -050076
egdanielb2df0c22016-05-13 11:30:37 -070077 return new GrVkTexture(gpu, budgeted, desc, info, imageView);
Greg Daniel164a9f02016-02-22 09:56:40 -050078}
79
kkinnunen2e6055b2016-04-22 01:48:29 -070080GrVkTexture* GrVkTexture::CreateWrappedTexture(GrVkGpu* gpu,
81 const GrSurfaceDesc& desc,
82 GrWrapOwnership ownership,
egdanielb2df0c22016-05-13 11:30:37 -070083 const GrVkImageInfo* info) {
jvanverthfd359ca2016-03-18 11:57:24 -070084 SkASSERT(info);
85 // Wrapped textures require both image and allocation (because they can be mapped)
86 SkASSERT(VK_NULL_HANDLE != info->fImage && VK_NULL_HANDLE != info->fAlloc);
Greg Daniel164a9f02016-02-22 09:56:40 -050087
egdanielb2df0c22016-05-13 11:30:37 -070088 const GrVkImageView* imageView = GrVkImageView::Create(gpu, info->fImage, info->fFormat,
89 GrVkImageView::kColor_Type,
90 info->fLevelCount);
91 if (!imageView) {
jvanverthfd359ca2016-03-18 11:57:24 -070092 return nullptr;
93 }
94
egdanielb2df0c22016-05-13 11:30:37 -070095 GrVkImage::Wrapped wrapped = kBorrow_GrWrapOwnership == ownership ? GrVkImage::kBorrowed_Wrapped
96 : GrVkImage::kAdopted_Wrapped;
jvanverthfd359ca2016-03-18 11:57:24 -070097
egdanielb2df0c22016-05-13 11:30:37 -070098 return new GrVkTexture(gpu, kWrapped, desc, *info, imageView, wrapped);
Greg Daniel164a9f02016-02-22 09:56:40 -050099}
100
101GrVkTexture::~GrVkTexture() {
102 // either release or abandon should have been called by the owner of this object.
103 SkASSERT(!fTextureView);
brianosmanf05ab1b2016-05-12 11:01:10 -0700104 SkASSERT(!fLinearTextureView);
Greg Daniel164a9f02016-02-22 09:56:40 -0500105}
106
107void GrVkTexture::onRelease() {
108 // we create this and don't hand it off, so we should always destroy it
109 if (fTextureView) {
110 fTextureView->unref(this->getVkGpu());
111 fTextureView = nullptr;
112 }
113
brianosmanf05ab1b2016-05-12 11:01:10 -0700114 if (fLinearTextureView) {
115 fLinearTextureView->unref(this->getVkGpu());
116 fLinearTextureView = nullptr;
117 }
118
kkinnunen2e6055b2016-04-22 01:48:29 -0700119 this->releaseImage(this->getVkGpu());
Greg Daniel164a9f02016-02-22 09:56:40 -0500120
121 INHERITED::onRelease();
122}
123
124void GrVkTexture::onAbandon() {
125 if (fTextureView) {
126 fTextureView->unrefAndAbandon();
127 fTextureView = nullptr;
128 }
129
brianosmanf05ab1b2016-05-12 11:01:10 -0700130 if (fLinearTextureView) {
131 fLinearTextureView->unrefAndAbandon();
132 fLinearTextureView = nullptr;
133 }
134
Greg Daniel164a9f02016-02-22 09:56:40 -0500135 this->abandonImage();
136 INHERITED::onAbandon();
137}
138
139GrBackendObject GrVkTexture::getTextureHandle() const {
egdanielb2df0c22016-05-13 11:30:37 -0700140 return (GrBackendObject)&fInfo;
Greg Daniel164a9f02016-02-22 09:56:40 -0500141}
142
143GrVkGpu* GrVkTexture::getVkGpu() const {
144 SkASSERT(!this->wasDestroyed());
145 return static_cast<GrVkGpu*>(this->getGpu());
146}
jvanverth62340062016-04-26 08:01:44 -0700147
brianosmanf05ab1b2016-05-12 11:01:10 -0700148const GrVkImageView* GrVkTexture::textureView(bool allowSRGB) {
149 VkFormat linearFormat;
egdanielb2df0c22016-05-13 11:30:37 -0700150 if (allowSRGB || !GrVkFormatIsSRGB(fInfo.fFormat, &linearFormat)) {
brianosmanf05ab1b2016-05-12 11:01:10 -0700151 return fTextureView;
152 }
153
154 if (!fLinearTextureView) {
egdanielb2df0c22016-05-13 11:30:37 -0700155 fLinearTextureView = GrVkImageView::Create(this->getVkGpu(), fInfo.fImage,
brianosmanf05ab1b2016-05-12 11:01:10 -0700156 linearFormat, GrVkImageView::kColor_Type,
egdanielb2df0c22016-05-13 11:30:37 -0700157 fInfo.fLevelCount);
brianosmanf05ab1b2016-05-12 11:01:10 -0700158 SkASSERT(fLinearTextureView);
159 }
160
161 return fLinearTextureView;
162}
163
jvanverth900bd4a2016-04-29 13:53:12 -0700164bool GrVkTexture::reallocForMipmap(const GrVkGpu* gpu, uint32_t mipLevels) {
165 if (mipLevels == 1) {
166 // don't need to do anything for a 1x1 texture
167 return false;
168 }
169
egdanielb2df0c22016-05-13 11:30:37 -0700170 const GrVkResource* oldResource = this->resource();
jvanverth62340062016-04-26 08:01:44 -0700171
jvanverth900bd4a2016-04-29 13:53:12 -0700172 // We shouldn't realloc something that doesn't belong to us
egdanielb2df0c22016-05-13 11:30:37 -0700173 if (fIsBorrowed) {
jvanverth900bd4a2016-04-29 13:53:12 -0700174 return false;
175 }
176
jvanverth62340062016-04-26 08:01:44 -0700177 // Does this even make sense for rendertargets?
178 bool renderTarget = SkToBool(fDesc.fFlags & kRenderTarget_GrSurfaceFlag);
179
180 VkImageUsageFlags usageFlags = VK_IMAGE_USAGE_SAMPLED_BIT;
181 if (renderTarget) {
182 usageFlags |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
183 }
184 usageFlags |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
185
jvanverth62340062016-04-26 08:01:44 -0700186 GrVkImage::ImageDesc imageDesc;
187 imageDesc.fImageType = VK_IMAGE_TYPE_2D;
egdanielb2df0c22016-05-13 11:30:37 -0700188 imageDesc.fFormat = fInfo.fFormat;
jvanverth62340062016-04-26 08:01:44 -0700189 imageDesc.fWidth = fDesc.fWidth;
190 imageDesc.fHeight = fDesc.fHeight;
191 imageDesc.fLevels = mipLevels;
192 imageDesc.fSamples = 1;
193 imageDesc.fImageTiling = VK_IMAGE_TILING_OPTIMAL;
194 imageDesc.fUsageFlags = usageFlags;
195 imageDesc.fMemProps = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
196
egdanielb2df0c22016-05-13 11:30:37 -0700197 GrVkImageInfo info;
198 if (!GrVkImage::InitImageInfo(gpu, imageDesc, &info)) {
199 return nullptr;
jvanverth62340062016-04-26 08:01:44 -0700200 }
201
202 // have to create a new image view for new resource
203 const GrVkImageView* oldView = fTextureView;
egdanielb2df0c22016-05-13 11:30:37 -0700204 VkImage image = info.fImage;
205 const GrVkImageView* textureView = GrVkImageView::Create(gpu, image, info.fFormat,
jvanverth62340062016-04-26 08:01:44 -0700206 GrVkImageView::kColor_Type, mipLevels);
207 if (!textureView) {
egdanielb2df0c22016-05-13 11:30:37 -0700208 GrVkImage::DestroyImageInfo(gpu, &info);
jvanverth62340062016-04-26 08:01:44 -0700209 return false;
210 }
211
212 oldResource->unref(gpu);
213 oldView->unref(gpu);
brianosmanf05ab1b2016-05-12 11:01:10 -0700214 if (fLinearTextureView) {
215 fLinearTextureView->unref(gpu);
216 fLinearTextureView = nullptr;
217 }
egdanielb2df0c22016-05-13 11:30:37 -0700218
219 this->setNewResource(info.fImage, info.fAlloc);
jvanverth62340062016-04-26 08:01:44 -0700220 fTextureView = textureView;
egdanielb2df0c22016-05-13 11:30:37 -0700221 fInfo = info;
jvanverth62340062016-04-26 08:01:44 -0700222 this->texturePriv().setMaxMipMapLevel(mipLevels);
223
224 return true;
225}