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