| /* |
| * 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<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() && 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]); |
| } |