blob: 0b2c4914ad202475211bfbeba11f24fb1d9cf70e [file] [log] [blame]
Timothy Liang2eb8e022018-08-09 12:55:28 -04001/*
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(
Michael Ludwigf23a1522018-12-10 11:36:13 -050013 GrSamplerState::WrapMode wrapMode, const GrCaps& caps) {
Timothy Liang2eb8e022018-08-09 12:55:28 -040014 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;
Michael Ludwigf23a1522018-12-10 11:36:13 -050021 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
Timothy Liang2eb8e022018-08-09 12:55:28 -040031 }
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;
Michael Ludwigf23a1522018-12-10 11:36:13 -050050 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());
Timothy Liang2eb8e022018-08-09 12:55:28 -040054 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}