xref: /aosp_15_r20/external/skia/src/gpu/graphite/mtl/MtlTexture.mm (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1*c8dee2aaSAndroid Build Coastguard Worker/*
2*c8dee2aaSAndroid Build Coastguard Worker * Copyright 2021 Google LLC
3*c8dee2aaSAndroid Build Coastguard Worker *
4*c8dee2aaSAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license that can be
5*c8dee2aaSAndroid Build Coastguard Worker * found in the LICENSE file.
6*c8dee2aaSAndroid Build Coastguard Worker */
7*c8dee2aaSAndroid Build Coastguard Worker
8*c8dee2aaSAndroid Build Coastguard Worker#include "src/gpu/graphite/mtl/MtlTexture.h"
9*c8dee2aaSAndroid Build Coastguard Worker
10*c8dee2aaSAndroid Build Coastguard Worker#include "include/gpu/MutableTextureState.h"
11*c8dee2aaSAndroid Build Coastguard Worker#include "include/gpu/graphite/TextureInfo.h"
12*c8dee2aaSAndroid Build Coastguard Worker#include "include/gpu/graphite/mtl/MtlGraphiteTypes.h"
13*c8dee2aaSAndroid Build Coastguard Worker#include "src/core/SkMipmap.h"
14*c8dee2aaSAndroid Build Coastguard Worker#include "src/gpu/graphite/mtl/MtlCaps.h"
15*c8dee2aaSAndroid Build Coastguard Worker#include "src/gpu/graphite/mtl/MtlGraphiteTypesPriv.h"
16*c8dee2aaSAndroid Build Coastguard Worker#include "src/gpu/graphite/mtl/MtlSharedContext.h"
17*c8dee2aaSAndroid Build Coastguard Worker#include "src/gpu/mtl/MtlUtilsPriv.h"
18*c8dee2aaSAndroid Build Coastguard Worker
19*c8dee2aaSAndroid Build Coastguard Workernamespace skgpu::graphite {
20*c8dee2aaSAndroid Build Coastguard Worker
21*c8dee2aaSAndroid Build Coastguard Workersk_cfp<id<MTLTexture>> MtlTexture::MakeMtlTexture(const MtlSharedContext* sharedContext,
22*c8dee2aaSAndroid Build Coastguard Worker                                                  SkISize dimensions,
23*c8dee2aaSAndroid Build Coastguard Worker                                                  const TextureInfo& info) {
24*c8dee2aaSAndroid Build Coastguard Worker    const Caps* caps = sharedContext->caps();
25*c8dee2aaSAndroid Build Coastguard Worker    if (dimensions.width() > caps->maxTextureSize() ||
26*c8dee2aaSAndroid Build Coastguard Worker        dimensions.height() > caps->maxTextureSize()) {
27*c8dee2aaSAndroid Build Coastguard Worker        return nullptr;
28*c8dee2aaSAndroid Build Coastguard Worker    }
29*c8dee2aaSAndroid Build Coastguard Worker
30*c8dee2aaSAndroid Build Coastguard Worker    const MtlTextureSpec mtlSpec = TextureInfos::GetMtlTextureSpec(info);
31*c8dee2aaSAndroid Build Coastguard Worker    SkASSERT(!mtlSpec.fFramebufferOnly);
32*c8dee2aaSAndroid Build Coastguard Worker
33*c8dee2aaSAndroid Build Coastguard Worker    if (mtlSpec.fUsage & MTLTextureUsageShaderRead && !caps->isTexturable(info)) {
34*c8dee2aaSAndroid Build Coastguard Worker        return nullptr;
35*c8dee2aaSAndroid Build Coastguard Worker    }
36*c8dee2aaSAndroid Build Coastguard Worker
37*c8dee2aaSAndroid Build Coastguard Worker    if (mtlSpec.fUsage & MTLTextureUsageRenderTarget &&
38*c8dee2aaSAndroid Build Coastguard Worker        !(caps->isRenderable(info) || MtlFormatIsDepthOrStencil(mtlSpec.fFormat))) {
39*c8dee2aaSAndroid Build Coastguard Worker        return nullptr;
40*c8dee2aaSAndroid Build Coastguard Worker    }
41*c8dee2aaSAndroid Build Coastguard Worker
42*c8dee2aaSAndroid Build Coastguard Worker    if (mtlSpec.fUsage & MTLTextureUsageShaderWrite && !caps->isStorage(info)) {
43*c8dee2aaSAndroid Build Coastguard Worker        return nullptr;
44*c8dee2aaSAndroid Build Coastguard Worker    }
45*c8dee2aaSAndroid Build Coastguard Worker
46*c8dee2aaSAndroid Build Coastguard Worker    int numMipLevels = 1;
47*c8dee2aaSAndroid Build Coastguard Worker    if (info.mipmapped() == Mipmapped::kYes) {
48*c8dee2aaSAndroid Build Coastguard Worker        numMipLevels = SkMipmap::ComputeLevelCount(dimensions.width(), dimensions.height()) + 1;
49*c8dee2aaSAndroid Build Coastguard Worker    }
50*c8dee2aaSAndroid Build Coastguard Worker
51*c8dee2aaSAndroid Build Coastguard Worker    sk_cfp<MTLTextureDescriptor*> desc([[MTLTextureDescriptor alloc] init]);
52*c8dee2aaSAndroid Build Coastguard Worker    (*desc).textureType = (info.numSamples() > 1) ? MTLTextureType2DMultisample : MTLTextureType2D;
53*c8dee2aaSAndroid Build Coastguard Worker    (*desc).pixelFormat = mtlSpec.fFormat;
54*c8dee2aaSAndroid Build Coastguard Worker    (*desc).width = dimensions.width();
55*c8dee2aaSAndroid Build Coastguard Worker    (*desc).height = dimensions.height();
56*c8dee2aaSAndroid Build Coastguard Worker    (*desc).depth = 1;
57*c8dee2aaSAndroid Build Coastguard Worker    (*desc).mipmapLevelCount = numMipLevels;
58*c8dee2aaSAndroid Build Coastguard Worker    (*desc).sampleCount = info.numSamples();
59*c8dee2aaSAndroid Build Coastguard Worker    (*desc).arrayLength = 1;
60*c8dee2aaSAndroid Build Coastguard Worker    (*desc).usage = mtlSpec.fUsage;
61*c8dee2aaSAndroid Build Coastguard Worker    (*desc).storageMode = mtlSpec.fStorageMode;
62*c8dee2aaSAndroid Build Coastguard Worker
63*c8dee2aaSAndroid Build Coastguard Worker    sk_cfp<id<MTLTexture>> texture([sharedContext->device() newTextureWithDescriptor:desc.get()]);
64*c8dee2aaSAndroid Build Coastguard Worker    return texture;
65*c8dee2aaSAndroid Build Coastguard Worker}
66*c8dee2aaSAndroid Build Coastguard Worker
67*c8dee2aaSAndroid Build Coastguard WorkerMtlTexture::MtlTexture(const MtlSharedContext* sharedContext,
68*c8dee2aaSAndroid Build Coastguard Worker                       SkISize dimensions,
69*c8dee2aaSAndroid Build Coastguard Worker                       const TextureInfo& info,
70*c8dee2aaSAndroid Build Coastguard Worker                       sk_cfp<id<MTLTexture>> texture,
71*c8dee2aaSAndroid Build Coastguard Worker                       Ownership ownership,
72*c8dee2aaSAndroid Build Coastguard Worker                       skgpu::Budgeted budgeted)
73*c8dee2aaSAndroid Build Coastguard Worker        : Texture(sharedContext,
74*c8dee2aaSAndroid Build Coastguard Worker                  dimensions,
75*c8dee2aaSAndroid Build Coastguard Worker                  info,
76*c8dee2aaSAndroid Build Coastguard Worker                  /*mutableState=*/nullptr,
77*c8dee2aaSAndroid Build Coastguard Worker                  ownership,
78*c8dee2aaSAndroid Build Coastguard Worker                  budgeted)
79*c8dee2aaSAndroid Build Coastguard Worker        , fTexture(std::move(texture)) {}
80*c8dee2aaSAndroid Build Coastguard Worker
81*c8dee2aaSAndroid Build Coastguard Workersk_sp<Texture> MtlTexture::Make(const MtlSharedContext* sharedContext,
82*c8dee2aaSAndroid Build Coastguard Worker                                SkISize dimensions,
83*c8dee2aaSAndroid Build Coastguard Worker                                const TextureInfo& info,
84*c8dee2aaSAndroid Build Coastguard Worker                                skgpu::Budgeted budgeted) {
85*c8dee2aaSAndroid Build Coastguard Worker    sk_cfp<id<MTLTexture>> texture = MakeMtlTexture(sharedContext, dimensions, info);
86*c8dee2aaSAndroid Build Coastguard Worker    if (!texture) {
87*c8dee2aaSAndroid Build Coastguard Worker        return nullptr;
88*c8dee2aaSAndroid Build Coastguard Worker    }
89*c8dee2aaSAndroid Build Coastguard Worker    return sk_sp<Texture>(new MtlTexture(sharedContext,
90*c8dee2aaSAndroid Build Coastguard Worker                                         dimensions,
91*c8dee2aaSAndroid Build Coastguard Worker                                         info,
92*c8dee2aaSAndroid Build Coastguard Worker                                         std::move(texture),
93*c8dee2aaSAndroid Build Coastguard Worker                                         Ownership::kOwned,
94*c8dee2aaSAndroid Build Coastguard Worker                                         budgeted));
95*c8dee2aaSAndroid Build Coastguard Worker}
96*c8dee2aaSAndroid Build Coastguard Worker
97*c8dee2aaSAndroid Build Coastguard Workersk_sp<Texture> MtlTexture::MakeWrapped(const MtlSharedContext* sharedContext,
98*c8dee2aaSAndroid Build Coastguard Worker                                       SkISize dimensions,
99*c8dee2aaSAndroid Build Coastguard Worker                                       const TextureInfo& info,
100*c8dee2aaSAndroid Build Coastguard Worker                                       sk_cfp<id<MTLTexture>> texture) {
101*c8dee2aaSAndroid Build Coastguard Worker    return sk_sp<Texture>(new MtlTexture(sharedContext,
102*c8dee2aaSAndroid Build Coastguard Worker                                         dimensions,
103*c8dee2aaSAndroid Build Coastguard Worker                                         info,
104*c8dee2aaSAndroid Build Coastguard Worker                                         std::move(texture),
105*c8dee2aaSAndroid Build Coastguard Worker                                         Ownership::kWrapped,
106*c8dee2aaSAndroid Build Coastguard Worker                                         skgpu::Budgeted::kNo));
107*c8dee2aaSAndroid Build Coastguard Worker}
108*c8dee2aaSAndroid Build Coastguard Worker
109*c8dee2aaSAndroid Build Coastguard Workervoid MtlTexture::freeGpuData() {
110*c8dee2aaSAndroid Build Coastguard Worker    fTexture.reset();
111*c8dee2aaSAndroid Build Coastguard Worker}
112*c8dee2aaSAndroid Build Coastguard Worker
113*c8dee2aaSAndroid Build Coastguard Worker
114*c8dee2aaSAndroid Build Coastguard Workervoid MtlTexture::setBackendLabel(char const* label) {
115*c8dee2aaSAndroid Build Coastguard Worker    SkASSERT(label);
116*c8dee2aaSAndroid Build Coastguard Worker#ifdef SK_ENABLE_MTL_DEBUG_INFO
117*c8dee2aaSAndroid Build Coastguard Worker    NSString* labelStr = @(label);
118*c8dee2aaSAndroid Build Coastguard Worker    this->mtlTexture().label = labelStr;
119*c8dee2aaSAndroid Build Coastguard Worker#endif
120*c8dee2aaSAndroid Build Coastguard Worker}
121*c8dee2aaSAndroid Build Coastguard Worker
122*c8dee2aaSAndroid Build Coastguard Worker} // namespace skgpu::graphite
123*c8dee2aaSAndroid Build Coastguard Worker
124