xref: /aosp_15_r20/external/skia/src/gpu/graphite/mtl/MtlTextureInfo.mm (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1*c8dee2aaSAndroid Build Coastguard Worker/*
2*c8dee2aaSAndroid Build Coastguard Worker * Copyright 2024 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#include "include/core/SkString.h"
8*c8dee2aaSAndroid Build Coastguard Worker#include "include/gpu/graphite/mtl/MtlGraphiteTypes.h"
9*c8dee2aaSAndroid Build Coastguard Worker#include "src/gpu/graphite/TextureInfoPriv.h"
10*c8dee2aaSAndroid Build Coastguard Worker#include "src/gpu/graphite/mtl/MtlGraphiteTypesPriv.h"
11*c8dee2aaSAndroid Build Coastguard Worker#include "src/gpu/mtl/MtlUtilsPriv.h"
12*c8dee2aaSAndroid Build Coastguard Worker
13*c8dee2aaSAndroid Build Coastguard Worker#include <cstdint>
14*c8dee2aaSAndroid Build Coastguard Worker
15*c8dee2aaSAndroid Build Coastguard Worker#import <Metal/Metal.h>
16*c8dee2aaSAndroid Build Coastguard Worker
17*c8dee2aaSAndroid Build Coastguard Workernamespace skgpu::graphite {
18*c8dee2aaSAndroid Build Coastguard Worker
19*c8dee2aaSAndroid Build Coastguard Workerclass MtlTextureInfoData final : public TextureInfoData {
20*c8dee2aaSAndroid Build Coastguard Workerpublic:
21*c8dee2aaSAndroid Build Coastguard Worker    MtlTextureInfoData(MtlTextureSpec m) : fMtlSpec(m) {}
22*c8dee2aaSAndroid Build Coastguard Worker
23*c8dee2aaSAndroid Build Coastguard Worker#if defined(SK_DEBUG)
24*c8dee2aaSAndroid Build Coastguard Worker    skgpu::BackendApi type() const override { return skgpu::BackendApi::kMetal; }
25*c8dee2aaSAndroid Build Coastguard Worker#endif
26*c8dee2aaSAndroid Build Coastguard Worker
27*c8dee2aaSAndroid Build Coastguard Worker    MtlTextureSpec spec() const { return fMtlSpec; }
28*c8dee2aaSAndroid Build Coastguard Worker
29*c8dee2aaSAndroid Build Coastguard Workerprivate:
30*c8dee2aaSAndroid Build Coastguard Worker    MtlTextureSpec fMtlSpec;
31*c8dee2aaSAndroid Build Coastguard Worker
32*c8dee2aaSAndroid Build Coastguard Worker    size_t bytesPerPixel() const override {
33*c8dee2aaSAndroid Build Coastguard Worker        return MtlFormatBytesPerBlock(fMtlSpec.fFormat);
34*c8dee2aaSAndroid Build Coastguard Worker    }
35*c8dee2aaSAndroid Build Coastguard Worker
36*c8dee2aaSAndroid Build Coastguard Worker    SkTextureCompressionType compressionType() const override {
37*c8dee2aaSAndroid Build Coastguard Worker        return MtlFormatToCompressionType(fMtlSpec.fFormat);
38*c8dee2aaSAndroid Build Coastguard Worker    }
39*c8dee2aaSAndroid Build Coastguard Worker
40*c8dee2aaSAndroid Build Coastguard Worker    bool isMemoryless() const override {
41*c8dee2aaSAndroid Build Coastguard Worker        if (@available(macOS 11.0, iOS 10.0, tvOS 10.0, *)) {
42*c8dee2aaSAndroid Build Coastguard Worker            return fMtlSpec.fStorageMode == MTLStorageModeMemoryless;
43*c8dee2aaSAndroid Build Coastguard Worker        }
44*c8dee2aaSAndroid Build Coastguard Worker        return false;
45*c8dee2aaSAndroid Build Coastguard Worker    }
46*c8dee2aaSAndroid Build Coastguard Worker
47*c8dee2aaSAndroid Build Coastguard Worker    SkString toString() const override {
48*c8dee2aaSAndroid Build Coastguard Worker        return SkStringPrintf("Metal(%s,", fMtlSpec.toString().c_str());
49*c8dee2aaSAndroid Build Coastguard Worker    }
50*c8dee2aaSAndroid Build Coastguard Worker
51*c8dee2aaSAndroid Build Coastguard Worker    SkString toRPAttachmentString(uint32_t sampleCount) const override {
52*c8dee2aaSAndroid Build Coastguard Worker        return SkStringPrintf(
53*c8dee2aaSAndroid Build Coastguard Worker                "Metal(f=%u,s=%u)", static_cast<unsigned int>(fMtlSpec.fFormat), sampleCount);
54*c8dee2aaSAndroid Build Coastguard Worker    }
55*c8dee2aaSAndroid Build Coastguard Worker
56*c8dee2aaSAndroid Build Coastguard Worker    void copyTo(AnyTextureInfoData& dstData) const override {
57*c8dee2aaSAndroid Build Coastguard Worker        // Don't assert that dstData is a metal type because it could be
58*c8dee2aaSAndroid Build Coastguard Worker        // uninitialized and that assert would fail.
59*c8dee2aaSAndroid Build Coastguard Worker        dstData.emplace<MtlTextureInfoData>(fMtlSpec);
60*c8dee2aaSAndroid Build Coastguard Worker    }
61*c8dee2aaSAndroid Build Coastguard Worker
62*c8dee2aaSAndroid Build Coastguard Worker    bool equal(const TextureInfoData* that) const override {
63*c8dee2aaSAndroid Build Coastguard Worker        SkASSERT(!that || that->type() == skgpu::BackendApi::kMetal);
64*c8dee2aaSAndroid Build Coastguard Worker        if (auto otherMtl = static_cast<const MtlTextureInfoData*>(that)) {
65*c8dee2aaSAndroid Build Coastguard Worker            return fMtlSpec == otherMtl->fMtlSpec;
66*c8dee2aaSAndroid Build Coastguard Worker        }
67*c8dee2aaSAndroid Build Coastguard Worker        return false;
68*c8dee2aaSAndroid Build Coastguard Worker    }
69*c8dee2aaSAndroid Build Coastguard Worker
70*c8dee2aaSAndroid Build Coastguard Worker    bool isCompatible(const TextureInfoData* that) const override {
71*c8dee2aaSAndroid Build Coastguard Worker        SkASSERT(!that || that->type() == skgpu::BackendApi::kMetal);
72*c8dee2aaSAndroid Build Coastguard Worker        if (auto otherMtl = static_cast<const MtlTextureInfoData*>(that)) {
73*c8dee2aaSAndroid Build Coastguard Worker            return fMtlSpec.isCompatible(otherMtl->fMtlSpec);
74*c8dee2aaSAndroid Build Coastguard Worker        }
75*c8dee2aaSAndroid Build Coastguard Worker        return false;
76*c8dee2aaSAndroid Build Coastguard Worker    }
77*c8dee2aaSAndroid Build Coastguard Worker};
78*c8dee2aaSAndroid Build Coastguard Worker
79*c8dee2aaSAndroid Build Coastguard Workerstatic const MtlTextureInfoData* get_and_cast_data(const TextureInfo& info) {
80*c8dee2aaSAndroid Build Coastguard Worker    auto data = TextureInfoPriv::GetData(info);
81*c8dee2aaSAndroid Build Coastguard Worker    SkASSERT(!data || data->type() == skgpu::BackendApi::kMetal);
82*c8dee2aaSAndroid Build Coastguard Worker    return static_cast<const MtlTextureInfoData*>(data);
83*c8dee2aaSAndroid Build Coastguard Worker}
84*c8dee2aaSAndroid Build Coastguard Worker
85*c8dee2aaSAndroid Build Coastguard Workernamespace TextureInfos {
86*c8dee2aaSAndroid Build Coastguard Workerskgpu::graphite::TextureInfo MakeMetal(CFTypeRef mtlTexture) {
87*c8dee2aaSAndroid Build Coastguard Worker    return MakeMetal(MtlTextureInfo(mtlTexture));
88*c8dee2aaSAndroid Build Coastguard Worker}
89*c8dee2aaSAndroid Build Coastguard Worker
90*c8dee2aaSAndroid Build Coastguard Workerskgpu::graphite::TextureInfo MakeMetal(const MtlTextureInfo& mtlInfo) {
91*c8dee2aaSAndroid Build Coastguard Worker    return TextureInfoPriv::Make(skgpu::BackendApi::kMetal,
92*c8dee2aaSAndroid Build Coastguard Worker                                 mtlInfo.fSampleCount,
93*c8dee2aaSAndroid Build Coastguard Worker                                 mtlInfo.fMipmapped,
94*c8dee2aaSAndroid Build Coastguard Worker                                 Protected::kNo,
95*c8dee2aaSAndroid Build Coastguard Worker                                 MtlTextureInfoData(mtlInfo));
96*c8dee2aaSAndroid Build Coastguard Worker}
97*c8dee2aaSAndroid Build Coastguard Worker
98*c8dee2aaSAndroid Build Coastguard Workerbool GetMtlTextureInfo(const TextureInfo& info, MtlTextureInfo* out) {
99*c8dee2aaSAndroid Build Coastguard Worker    if (!info.isValid() || info.backend() != skgpu::BackendApi::kMetal) {
100*c8dee2aaSAndroid Build Coastguard Worker        return false;
101*c8dee2aaSAndroid Build Coastguard Worker    }
102*c8dee2aaSAndroid Build Coastguard Worker    SkASSERT(out);
103*c8dee2aaSAndroid Build Coastguard Worker    const MtlTextureInfoData* mtlData = get_and_cast_data(info);
104*c8dee2aaSAndroid Build Coastguard Worker    SkASSERT(mtlData);
105*c8dee2aaSAndroid Build Coastguard Worker    *out = MtlTextureSpecToTextureInfo(mtlData->spec(), info.numSamples(), info.mipmapped());
106*c8dee2aaSAndroid Build Coastguard Worker    return true;
107*c8dee2aaSAndroid Build Coastguard Worker}
108*c8dee2aaSAndroid Build Coastguard Worker
109*c8dee2aaSAndroid Build Coastguard Worker// This cannot return a const reference or we get a warning about returning
110*c8dee2aaSAndroid Build Coastguard Worker// a reference to a temporary local variable.
111*c8dee2aaSAndroid Build Coastguard WorkerMtlTextureSpec GetMtlTextureSpec(const TextureInfo& info) {
112*c8dee2aaSAndroid Build Coastguard Worker    SkASSERT(info.isValid() && info.backend() == skgpu::BackendApi::kMetal);
113*c8dee2aaSAndroid Build Coastguard Worker    const MtlTextureInfoData* mtlData = get_and_cast_data(info);
114*c8dee2aaSAndroid Build Coastguard Worker    SkASSERT(mtlData);
115*c8dee2aaSAndroid Build Coastguard Worker    return mtlData->spec();
116*c8dee2aaSAndroid Build Coastguard Worker}
117*c8dee2aaSAndroid Build Coastguard Worker
118*c8dee2aaSAndroid Build Coastguard WorkerMTLPixelFormat GetMTLPixelFormat(const TextureInfo& info) {
119*c8dee2aaSAndroid Build Coastguard Worker    SkASSERT(info.isValid() && info.backend() == skgpu::BackendApi::kMetal);
120*c8dee2aaSAndroid Build Coastguard Worker    const MtlTextureInfoData* mtlData = get_and_cast_data(info);
121*c8dee2aaSAndroid Build Coastguard Worker    SkASSERT(mtlData);
122*c8dee2aaSAndroid Build Coastguard Worker    return mtlData->spec().fFormat;
123*c8dee2aaSAndroid Build Coastguard Worker}
124*c8dee2aaSAndroid Build Coastguard Worker
125*c8dee2aaSAndroid Build Coastguard WorkerMTLTextureUsage GetMTLTextureUsage(const TextureInfo& info) {
126*c8dee2aaSAndroid Build Coastguard Worker    SkASSERT(info.isValid() && info.backend() == skgpu::BackendApi::kMetal);
127*c8dee2aaSAndroid Build Coastguard Worker    const MtlTextureInfoData* mtlData = get_and_cast_data(info);
128*c8dee2aaSAndroid Build Coastguard Worker    SkASSERT(mtlData);
129*c8dee2aaSAndroid Build Coastguard Worker    return mtlData->spec().fUsage;
130*c8dee2aaSAndroid Build Coastguard Worker}
131*c8dee2aaSAndroid Build Coastguard Worker
132*c8dee2aaSAndroid Build Coastguard Workerbool GetMtlFramebufferOnly(const TextureInfo& info) {
133*c8dee2aaSAndroid Build Coastguard Worker    SkASSERT(info.isValid() && info.backend() == skgpu::BackendApi::kMetal);
134*c8dee2aaSAndroid Build Coastguard Worker    const MtlTextureInfoData* mtlData = get_and_cast_data(info);
135*c8dee2aaSAndroid Build Coastguard Worker    SkASSERT(mtlData);
136*c8dee2aaSAndroid Build Coastguard Worker    return mtlData->spec().fFramebufferOnly;
137*c8dee2aaSAndroid Build Coastguard Worker}
138*c8dee2aaSAndroid Build Coastguard Worker
139*c8dee2aaSAndroid Build Coastguard Worker}  // namespace TextureInfos
140*c8dee2aaSAndroid Build Coastguard Worker
141*c8dee2aaSAndroid Build Coastguard Worker}  // namespace skgpu::graphite
142