/* * Copyright 2018 Google Inc. * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include "GrMtlSampler.h" #include "GrMtlGpu.h" static inline MTLSamplerAddressMode wrap_mode_to_mtl_sampler_address( GrSamplerState::WrapMode wrapMode, const GrCaps& caps) { switch (wrapMode) { case GrSamplerState::WrapMode::kClamp: return MTLSamplerAddressModeClampToEdge; case GrSamplerState::WrapMode::kRepeat: return MTLSamplerAddressModeRepeat; case GrSamplerState::WrapMode::kMirrorRepeat: return MTLSamplerAddressModeMirrorRepeat; case GrSamplerState::WrapMode::kClampToBorder: // Must guard the reference to the clamp to border address mode by macro since iOS // builds will fail if it's referenced, even if other code makes sure it's never used. #ifdef SK_BUILD_FOR_IOS SkASSERT(false); return MTLSamplerAddressModeClampToEdge; #else SkASSERT(caps.clampToBorderSupport()); return MTLSamplerAddressModeClampToBorderColor; #endif } SK_ABORT("Unknown wrap mode."); return MTLSamplerAddressModeClampToEdge; } GrMtlSampler* GrMtlSampler::Create(const GrMtlGpu* gpu, const GrSamplerState& samplerState, uint32_t maxMipLevel) { static MTLSamplerMinMagFilter mtlMinMagFilterModes[] = { MTLSamplerMinMagFilterNearest, MTLSamplerMinMagFilterLinear, MTLSamplerMinMagFilterLinear }; GR_STATIC_ASSERT((int)GrSamplerState::Filter::kNearest == 0); GR_STATIC_ASSERT((int)GrSamplerState::Filter::kBilerp == 1); GR_STATIC_ASSERT((int)GrSamplerState::Filter::kMipMap == 2); auto samplerDesc = [[MTLSamplerDescriptor alloc] init]; samplerDesc.rAddressMode = MTLSamplerAddressModeClampToEdge; samplerDesc.sAddressMode = wrap_mode_to_mtl_sampler_address(samplerState.wrapModeX(), gpu->mtlCaps()); samplerDesc.tAddressMode = wrap_mode_to_mtl_sampler_address(samplerState.wrapModeY(), gpu->mtlCaps()); samplerDesc.magFilter = mtlMinMagFilterModes[static_cast(samplerState.filter())]; samplerDesc.minFilter = mtlMinMagFilterModes[static_cast(samplerState.filter())]; samplerDesc.mipFilter = MTLSamplerMipFilterLinear; samplerDesc.lodMinClamp = 0.0f; bool useMipMaps = GrSamplerState::Filter::kMipMap == samplerState.filter() && maxMipLevel > 0; samplerDesc.lodMaxClamp = !useMipMaps ? 0.0f : (float)(maxMipLevel); samplerDesc.maxAnisotropy = 1.0f; samplerDesc.normalizedCoordinates = true; samplerDesc.compareFunction = MTLCompareFunctionNever; return new GrMtlSampler([gpu->device() newSamplerStateWithDescriptor: samplerDesc]); }