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