1/* 2 * Copyright 2018 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8#include "GrMtlSampler.h" 9 10#include "GrMtlGpu.h" 11 12static inline MTLSamplerAddressMode wrap_mode_to_mtl_sampler_address( 13 GrSamplerState::WrapMode wrapMode, const GrCaps& caps) { 14 switch (wrapMode) { 15 case GrSamplerState::WrapMode::kClamp: 16 return MTLSamplerAddressModeClampToEdge; 17 case GrSamplerState::WrapMode::kRepeat: 18 return MTLSamplerAddressModeRepeat; 19 case GrSamplerState::WrapMode::kMirrorRepeat: 20 return MTLSamplerAddressModeMirrorRepeat; 21 case GrSamplerState::WrapMode::kClampToBorder: 22 // Must guard the reference to the clamp to border address mode by macro since iOS 23 // builds will fail if it's referenced, even if other code makes sure it's never used. 24#ifdef SK_BUILD_FOR_IOS 25 SkASSERT(false); 26 return MTLSamplerAddressModeClampToEdge; 27#else 28 SkASSERT(caps.clampToBorderSupport()); 29 return MTLSamplerAddressModeClampToBorderColor; 30#endif 31 } 32 SK_ABORT("Unknown wrap mode."); 33 return MTLSamplerAddressModeClampToEdge; 34} 35 36GrMtlSampler* GrMtlSampler::Create(const GrMtlGpu* gpu, const GrSamplerState& samplerState, 37 uint32_t maxMipLevel) { 38 static MTLSamplerMinMagFilter mtlMinMagFilterModes[] = { 39 MTLSamplerMinMagFilterNearest, 40 MTLSamplerMinMagFilterLinear, 41 MTLSamplerMinMagFilterLinear 42 }; 43 44 GR_STATIC_ASSERT((int)GrSamplerState::Filter::kNearest == 0); 45 GR_STATIC_ASSERT((int)GrSamplerState::Filter::kBilerp == 1); 46 GR_STATIC_ASSERT((int)GrSamplerState::Filter::kMipMap == 2); 47 48 auto samplerDesc = [[MTLSamplerDescriptor alloc] init]; 49 samplerDesc.rAddressMode = MTLSamplerAddressModeClampToEdge; 50 samplerDesc.sAddressMode = wrap_mode_to_mtl_sampler_address(samplerState.wrapModeX(), 51 gpu->mtlCaps()); 52 samplerDesc.tAddressMode = wrap_mode_to_mtl_sampler_address(samplerState.wrapModeY(), 53 gpu->mtlCaps()); 54 samplerDesc.magFilter = mtlMinMagFilterModes[static_cast<int>(samplerState.filter())]; 55 samplerDesc.minFilter = mtlMinMagFilterModes[static_cast<int>(samplerState.filter())]; 56 samplerDesc.mipFilter = MTLSamplerMipFilterLinear; 57 samplerDesc.lodMinClamp = 0.0f; 58 bool useMipMaps = GrSamplerState::Filter::kMipMap == samplerState.filter() && maxMipLevel > 0; 59 samplerDesc.lodMaxClamp = !useMipMaps ? 0.0f : (float)(maxMipLevel); 60 samplerDesc.maxAnisotropy = 1.0f; 61 samplerDesc.normalizedCoordinates = true; 62 samplerDesc.compareFunction = MTLCompareFunctionNever; 63 64 return new GrMtlSampler([gpu->device() newSamplerStateWithDescriptor: samplerDesc]); 65} 66