2 * Copyright 2015 Google Inc.
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
9 #include "src/gpu/ganesh/vk/GrVkTexture.h"
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"
18 #include "include/gpu/vk/GrVkTypes.h"
20 #define VK_CALL(GPU, X) GR_VK_CALL(GPU->vkInterface(), X)
22 // Because this class is virtually derived from GrSurface we must explicitly call its constructor.
23 GrVkTexture::GrVkTexture(GrVkGpu* gpu,
26 sk_sp<GrVkImage> texture,
27 GrMipmapStatus mipmapStatus,
28 std::string_view label)
31 texture->isProtected() ? GrProtected::kYes : GrProtected::kNo,
35 texture->isProtected() ? GrProtected::kYes : GrProtected::kNo,
39 , fTexture(std::move(texture))
40 , fDescSetCache(kMaxCachedDescSets) {
41 SkASSERT((GrMipmapStatus::kNotAllocated == mipmapStatus) == (1 == fTexture->mipLevels()));
42 // We don't support creating external GrVkTextures
43 SkASSERT(!fTexture->ycbcrConversionInfo().isValid() ||
44 !fTexture->ycbcrConversionInfo().fExternalFormat);
45 SkASSERT(SkToBool(fTexture->vkUsageFlags() & VK_IMAGE_USAGE_SAMPLED_BIT));
46 this->registerWithCache(budgeted);
47 if (GrVkFormatIsCompressed(fTexture->imageFormat())) {
52 GrVkTexture::GrVkTexture(GrVkGpu* gpu,
54 sk_sp<GrVkImage> texture,
55 GrMipmapStatus mipmapStatus,
56 GrWrapCacheable cacheable,
59 std::string_view label)
62 texture->isProtected() ? GrProtected::kYes : GrProtected::kNo,
66 texture->isProtected() ? GrProtected::kYes : GrProtected::kNo,
67 isExternal ? GrTextureType::kExternal : GrTextureType::k2D,
70 , fTexture(std::move(texture))
71 , fDescSetCache(kMaxCachedDescSets) {
72 SkASSERT((GrMipmapStatus::kNotAllocated == mipmapStatus) == (1 == fTexture->mipLevels()));
73 SkASSERT(SkToBool(fTexture->vkUsageFlags() & VK_IMAGE_USAGE_SAMPLED_BIT));
74 if (ioType == kRead_GrIOType) {
77 this->registerWithCacheWrapped(cacheable);
80 // Because this class is virtually derived from GrSurface we must explicitly call its constructor.
81 GrVkTexture::GrVkTexture(GrVkGpu* gpu,
83 sk_sp<GrVkImage> texture,
84 GrMipmapStatus mipmapStatus,
85 std::string_view label)
88 texture->isProtected() ? GrProtected::kYes : GrProtected::kNo,
92 texture->isProtected() ? GrProtected::kYes : GrProtected::kNo,
96 , fTexture(std::move(texture))
97 , fDescSetCache(kMaxCachedDescSets) {
98 SkASSERT((GrMipmapStatus::kNotAllocated == mipmapStatus) == (1 == fTexture->mipLevels()));
99 // Since this ctor is only called from GrVkTextureRenderTarget, we can't have a ycbcr conversion
100 // since we don't support that on render targets.
101 SkASSERT(!fTexture->ycbcrConversionInfo().isValid());
102 SkASSERT(SkToBool(fTexture->vkUsageFlags() & VK_IMAGE_USAGE_SAMPLED_BIT));
105 sk_sp<GrVkTexture> GrVkTexture::MakeNewTexture(GrVkGpu* gpu, SkBudgeted budgeted,
107 VkFormat format, uint32_t mipLevels,
108 GrProtected isProtected,
109 GrMipmapStatus mipmapStatus,
110 std::string_view label) {
111 sk_sp<GrVkImage> texture = GrVkImage::MakeTexture(
112 gpu, dimensions, format, mipLevels, GrRenderable::kNo, /*numSamples=*/1, budgeted,
118 return sk_sp<GrVkTexture>(new GrVkTexture(
119 gpu, budgeted, dimensions, std::move(texture), mipmapStatus, label));
122 sk_sp<GrVkTexture> GrVkTexture::MakeWrappedTexture(
123 GrVkGpu* gpu, SkISize dimensions, GrWrapOwnership wrapOwnership, GrWrapCacheable cacheable,
124 GrIOType ioType, const GrVkImageInfo& info,
125 sk_sp<GrBackendSurfaceMutableStateImpl> mutableState) {
126 // Adopted textures require both image and allocation because we're responsible for freeing
127 SkASSERT(VK_NULL_HANDLE != info.fImage &&
128 (kBorrow_GrWrapOwnership == wrapOwnership || VK_NULL_HANDLE != info.fAlloc.fMemory));
130 sk_sp<GrVkImage> texture = GrVkImage::MakeWrapped(gpu,
133 std::move(mutableState),
134 GrAttachment::UsageFlags::kTexture,
141 GrMipmapStatus mipmapStatus = info.fLevelCount > 1 ? GrMipmapStatus::kValid
142 : GrMipmapStatus::kNotAllocated;
144 bool isExternal = info.fYcbcrConversionInfo.isValid() &&
145 (info.fYcbcrConversionInfo.fExternalFormat != 0);
146 isExternal |= (info.fImageTiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT);
147 return sk_sp<GrVkTexture>(new GrVkTexture(gpu,
157 GrVkTexture::~GrVkTexture() {
158 // either release or abandon should have been called by the owner of this object.
162 void GrVkTexture::onRelease() {
165 fDescSetCache.reset();
167 GrTexture::onRelease();
170 struct GrVkTexture::DescriptorCacheEntry {
171 DescriptorCacheEntry(const GrVkDescriptorSet* fDescSet, GrVkGpu* gpu)
172 : fDescriptorSet(fDescSet), fGpu(gpu) {}
173 ~DescriptorCacheEntry() {
174 if (fDescriptorSet) {
175 fDescriptorSet->recycle();
179 const GrVkDescriptorSet* fDescriptorSet;
183 void GrVkTexture::onAbandon() {
186 fDescSetCache.reset();
188 GrTexture::onAbandon();
191 GrBackendTexture GrVkTexture::getBackendTexture() const {
192 return GrBackendTexture(fTexture->width(), fTexture->height(), fTexture->vkImageInfo(),
193 fTexture->getMutableState());
196 GrVkGpu* GrVkTexture::getVkGpu() const {
197 SkASSERT(!this->wasDestroyed());
198 return static_cast<GrVkGpu*>(this->getGpu());
201 const GrVkImageView* GrVkTexture::textureView() { return fTexture->textureView(); }
203 const GrVkDescriptorSet* GrVkTexture::cachedSingleDescSet(GrSamplerState state) {
204 if (std::unique_ptr<DescriptorCacheEntry>* e = fDescSetCache.find(state)) {
205 return (*e)->fDescriptorSet;
210 void GrVkTexture::addDescriptorSetToCache(const GrVkDescriptorSet* descSet, GrSamplerState state) {
211 SkASSERT(!fDescSetCache.find(state));
213 fDescSetCache.insert(state, std::make_unique<DescriptorCacheEntry>(descSet, this->getVkGpu()));