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