• 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 
9 #include "src/gpu/ganesh/vk/GrVkTexture.h"
10 
11 #include "src/gpu/ganesh/GrTexture.h"
12 #include "src/gpu/ganesh/vk/GrVkDescriptorSet.h"
13 #include "src/gpu/ganesh/vk/GrVkGpu.h"
14 #include "src/gpu/ganesh/vk/GrVkImageView.h"
15 #include "src/gpu/ganesh/vk/GrVkTextureRenderTarget.h"
16 #include "src/gpu/ganesh/vk/GrVkUtil.h"
17 #include "src/gpu/vk/VulkanUtilsPriv.h"
18 
19 #include "include/gpu/vk/GrVkTypes.h"
20 
21 #define VK_CALL(GPU, X) GR_VK_CALL(GPU->vkInterface(), X)
22 
23 // Because this class is virtually derived from GrSurface we must explicitly call its constructor.
GrVkTexture(GrVkGpu * gpu,skgpu::Budgeted budgeted,SkISize dimensions,sk_sp<GrVkImage> texture,GrMipmapStatus mipmapStatus,std::string_view label)24 GrVkTexture::GrVkTexture(GrVkGpu* gpu,
25                          skgpu::Budgeted budgeted,
26                          SkISize dimensions,
27                          sk_sp<GrVkImage> texture,
28                          GrMipmapStatus mipmapStatus,
29                          std::string_view label)
30         : GrSurface(gpu,
31                     dimensions,
32                     texture->isProtected() ? GrProtected::kYes : GrProtected::kNo,
33                     label)
34         , GrTexture(gpu,
35                     dimensions,
36                     texture->isProtected() ? GrProtected::kYes : GrProtected::kNo,
37                     GrTextureType::k2D,
38                     mipmapStatus,
39                     label)
40         , fTexture(std::move(texture))
41         , fDescSetCache(kMaxCachedDescSets) {
42     SkASSERT((GrMipmapStatus::kNotAllocated == mipmapStatus) == (1 == fTexture->mipLevels()));
43     // We don't support creating external GrVkTextures
44     SkASSERT(!fTexture->ycbcrConversionInfo().isValid() ||
45              !fTexture->ycbcrConversionInfo().fExternalFormat);
46     SkASSERT(SkToBool(fTexture->vkUsageFlags() & VK_IMAGE_USAGE_SAMPLED_BIT));
47     this->registerWithCache(budgeted);
48     if (skgpu::VkFormatIsCompressed(fTexture->imageFormat())) {
49         this->setReadOnly();
50     }
51 }
52 
GrVkTexture(GrVkGpu * gpu,SkISize dimensions,sk_sp<GrVkImage> texture,GrMipmapStatus mipmapStatus,GrWrapCacheable cacheable,GrIOType ioType,bool isExternal,std::string_view label)53 GrVkTexture::GrVkTexture(GrVkGpu* gpu,
54                          SkISize dimensions,
55                          sk_sp<GrVkImage> texture,
56                          GrMipmapStatus mipmapStatus,
57                          GrWrapCacheable cacheable,
58                          GrIOType ioType,
59                          bool isExternal,
60                          std::string_view label)
61         : GrSurface(gpu,
62                     dimensions,
63                     texture->isProtected() ? GrProtected::kYes : GrProtected::kNo,
64                     label)
65         , GrTexture(gpu,
66                     dimensions,
67                     texture->isProtected() ? GrProtected::kYes : GrProtected::kNo,
68                     isExternal ? GrTextureType::kExternal : GrTextureType::k2D,
69                     mipmapStatus,
70                     label)
71         , fTexture(std::move(texture))
72         , fDescSetCache(kMaxCachedDescSets) {
73     SkASSERT((GrMipmapStatus::kNotAllocated == mipmapStatus) == (1 == fTexture->mipLevels()));
74     SkASSERT(SkToBool(fTexture->vkUsageFlags() & VK_IMAGE_USAGE_SAMPLED_BIT));
75     if (ioType == kRead_GrIOType) {
76         this->setReadOnly();
77     }
78     this->registerWithCacheWrapped(cacheable);
79 }
80 
81 // Because this class is virtually derived from GrSurface we must explicitly call its constructor.
GrVkTexture(GrVkGpu * gpu,SkISize dimensions,sk_sp<GrVkImage> texture,GrMipmapStatus mipmapStatus,std::string_view label)82 GrVkTexture::GrVkTexture(GrVkGpu* gpu,
83                          SkISize dimensions,
84                          sk_sp<GrVkImage> texture,
85                          GrMipmapStatus mipmapStatus,
86                          std::string_view label)
87         : GrSurface(gpu,
88                     dimensions,
89                     texture->isProtected() ? GrProtected::kYes : GrProtected::kNo,
90                     label)
91         , GrTexture(gpu,
92                     dimensions,
93                     texture->isProtected() ? GrProtected::kYes : GrProtected::kNo,
94                     GrTextureType::k2D,
95                     mipmapStatus,
96                     label)
97         , fTexture(std::move(texture))
98         , fDescSetCache(kMaxCachedDescSets) {
99     SkASSERT((GrMipmapStatus::kNotAllocated == mipmapStatus) == (1 == fTexture->mipLevels()));
100     // Since this ctor is only called from GrVkTextureRenderTarget, we can't have a ycbcr conversion
101     // since we don't support that on render targets.
102     SkASSERT(!fTexture->ycbcrConversionInfo().isValid());
103     SkASSERT(SkToBool(fTexture->vkUsageFlags() & VK_IMAGE_USAGE_SAMPLED_BIT));
104 }
105 
MakeNewTexture(GrVkGpu * gpu,skgpu::Budgeted budgeted,SkISize dimensions,VkFormat format,uint32_t mipLevels,GrProtected isProtected,GrMipmapStatus mipmapStatus,std::string_view label)106 sk_sp<GrVkTexture> GrVkTexture::MakeNewTexture(GrVkGpu* gpu,
107                                                skgpu::Budgeted budgeted,
108                                                SkISize dimensions,
109                                                VkFormat format,
110                                                uint32_t mipLevels,
111                                                GrProtected isProtected,
112                                                GrMipmapStatus mipmapStatus,
113                                                std::string_view label) {
114     sk_sp<GrVkImage> texture = GrVkImage::MakeTexture(
115             gpu, dimensions, format, mipLevels, GrRenderable::kNo, /*numSamples=*/1, budgeted,
116             isProtected);
117 
118     if (!texture) {
119         return nullptr;
120     }
121     return sk_sp<GrVkTexture>(new GrVkTexture(
122             gpu, budgeted, dimensions, std::move(texture), mipmapStatus, label));
123 }
124 
MakeWrappedTexture(GrVkGpu * gpu,SkISize dimensions,GrWrapOwnership wrapOwnership,GrWrapCacheable cacheable,GrIOType ioType,const GrVkImageInfo & info,sk_sp<skgpu::MutableTextureStateRef> mutableState)125 sk_sp<GrVkTexture> GrVkTexture::MakeWrappedTexture(
126         GrVkGpu* gpu, SkISize dimensions, GrWrapOwnership wrapOwnership, GrWrapCacheable cacheable,
127         GrIOType ioType, const GrVkImageInfo& info,
128         sk_sp<skgpu::MutableTextureStateRef> mutableState) {
129     // Adopted textures require both image and allocation because we're responsible for freeing
130     SkASSERT(VK_NULL_HANDLE != info.fImage &&
131              (kBorrow_GrWrapOwnership == wrapOwnership || VK_NULL_HANDLE != info.fAlloc.fMemory));
132 
133     sk_sp<GrVkImage> texture = GrVkImage::MakeWrapped(gpu,
134                                                       dimensions,
135                                                       info,
136                                                       std::move(mutableState),
137                                                       GrAttachment::UsageFlags::kTexture,
138                                                       wrapOwnership,
139                                                       cacheable,
140                                                       "VkImage_MakeWrappedTexture");
141     if (!texture) {
142         return nullptr;
143     }
144 
145     GrMipmapStatus mipmapStatus = info.fLevelCount > 1 ? GrMipmapStatus::kValid
146                                                        : GrMipmapStatus::kNotAllocated;
147 
148     bool isExternal = info.fYcbcrConversionInfo.isValid() &&
149                       (info.fYcbcrConversionInfo.fExternalFormat != 0);
150     isExternal |= (info.fImageTiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT);
151     return sk_sp<GrVkTexture>(new GrVkTexture(gpu,
152                                               dimensions,
153                                               std::move(texture),
154                                               mipmapStatus,
155                                               cacheable,
156                                               ioType,
157                                               isExternal,
158                                               /*label=*/"Vk_MakeWrappedTexture"));
159 }
160 
~GrVkTexture()161 GrVkTexture::~GrVkTexture() {
162     // either release or abandon should have been called by the owner of this object.
163     SkASSERT(!fTexture);
164 }
165 
onRelease()166 void GrVkTexture::onRelease() {
167     fTexture.reset();
168 
169     fDescSetCache.reset();
170 
171     GrTexture::onRelease();
172 }
173 
174 struct GrVkTexture::DescriptorCacheEntry {
DescriptorCacheEntryGrVkTexture::DescriptorCacheEntry175     DescriptorCacheEntry(const GrVkDescriptorSet* fDescSet, GrVkGpu* gpu)
176             : fDescriptorSet(fDescSet), fGpu(gpu) {}
~DescriptorCacheEntryGrVkTexture::DescriptorCacheEntry177     ~DescriptorCacheEntry() {
178         if (fDescriptorSet) {
179             fDescriptorSet->recycle();
180         }
181     }
182 
183     const GrVkDescriptorSet* fDescriptorSet;
184     GrVkGpu* fGpu;
185 };
186 
onAbandon()187 void GrVkTexture::onAbandon() {
188     fTexture.reset();
189 
190     fDescSetCache.reset();
191 
192     GrTexture::onAbandon();
193 }
194 
getBackendTexture() const195 GrBackendTexture GrVkTexture::getBackendTexture() const {
196     return GrBackendTexture(fTexture->width(), fTexture->height(), fTexture->vkImageInfo(),
197                             fTexture->getMutableState());
198 }
199 
getVkGpu() const200 GrVkGpu* GrVkTexture::getVkGpu() const {
201     SkASSERT(!this->wasDestroyed());
202     return static_cast<GrVkGpu*>(this->getGpu());
203 }
204 
textureView()205 const GrVkImageView* GrVkTexture::textureView() { return fTexture->textureView(); }
206 
cachedSingleDescSet(GrSamplerState state)207 const GrVkDescriptorSet* GrVkTexture::cachedSingleDescSet(GrSamplerState state) {
208     if (std::unique_ptr<DescriptorCacheEntry>* e = fDescSetCache.find(state)) {
209         return (*e)->fDescriptorSet;
210     }
211     return nullptr;
212 }
213 
addDescriptorSetToCache(const GrVkDescriptorSet * descSet,GrSamplerState state)214 void GrVkTexture::addDescriptorSetToCache(const GrVkDescriptorSet* descSet, GrSamplerState state) {
215     SkASSERT(!fDescSetCache.find(state));
216     descSet->ref();
217     fDescSetCache.insert(state, std::make_unique<DescriptorCacheEntry>(descSet, this->getVkGpu()));
218 }
219