• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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