| /* |
| * 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 "src/gpu/mtl/GrMtlSampler.h" |
| |
| #include "src/gpu/mtl/GrMtlGpu.h" |
| |
| #if !__has_feature(objc_arc) |
| #error This file must be compiled with Arc. Use -fobjc-arc flag |
| #endif |
| |
| 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 or |
| // older MacOS builds will fail if it's referenced, even if other code makes sure it's |
| // never used. |
| #ifdef SK_BUILD_FOR_MAC |
| if (@available(macOS 10.12, *)) { |
| SkASSERT(caps.clampToBorderSupport()); |
| return MTLSamplerAddressModeClampToBorderColor; |
| } else |
| #endif |
| { |
| SkASSERT(false); |
| return MTLSamplerAddressModeClampToEdge; |
| } |
| } |
| SK_ABORT("Unknown wrap mode."); |
| } |
| |
| GrMtlSampler* GrMtlSampler::Create(const GrMtlGpu* gpu, const GrSamplerState& samplerState) { |
| 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<int>(samplerState.filter())]; |
| samplerDesc.minFilter = mtlMinMagFilterModes[static_cast<int>(samplerState.filter())]; |
| samplerDesc.mipFilter = MTLSamplerMipFilterLinear; |
| samplerDesc.lodMinClamp = 0.0f; |
| bool useMipMaps = GrSamplerState::Filter::kMipMap == samplerState.filter(); |
| samplerDesc.lodMaxClamp = !useMipMaps ? 0.0f : 10000.0f; |
| samplerDesc.maxAnisotropy = 1.0f; |
| samplerDesc.normalizedCoordinates = true; |
| if (@available(macOS 10.11, iOS 9.0, *)) { |
| samplerDesc.compareFunction = MTLCompareFunctionNever; |
| } |
| |
| return new GrMtlSampler([gpu->device() newSamplerStateWithDescriptor: samplerDesc], |
| GenerateKey(samplerState)); |
| } |
| |
| GrMtlSampler::Key GrMtlSampler::GenerateKey(const GrSamplerState& samplerState) { |
| return GrSamplerState::GenerateKey(samplerState); |
| } |