xref: /third_party/skia/src/gpu/mtl/GrMtlSampler.mm (revision cb93a386)
1cb93a386Sopenharmony_ci/*
2cb93a386Sopenharmony_ci * Copyright 2018 Google Inc.
3cb93a386Sopenharmony_ci *
4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be
5cb93a386Sopenharmony_ci * found in the LICENSE file.
6cb93a386Sopenharmony_ci */
7cb93a386Sopenharmony_ci
8cb93a386Sopenharmony_ci#include "src/gpu/mtl/GrMtlSampler.h"
9cb93a386Sopenharmony_ci
10cb93a386Sopenharmony_ci#include "src/gpu/mtl/GrMtlGpu.h"
11cb93a386Sopenharmony_ci
12cb93a386Sopenharmony_ci#if !__has_feature(objc_arc)
13cb93a386Sopenharmony_ci#error This file must be compiled with Arc. Use -fobjc-arc flag
14cb93a386Sopenharmony_ci#endif
15cb93a386Sopenharmony_ci
16cb93a386Sopenharmony_ciGR_NORETAIN_BEGIN
17cb93a386Sopenharmony_ci
18cb93a386Sopenharmony_cistatic inline MTLSamplerAddressMode wrap_mode_to_mtl_sampler_address(
19cb93a386Sopenharmony_ci        GrSamplerState::WrapMode wrapMode, const GrCaps& caps) {
20cb93a386Sopenharmony_ci    switch (wrapMode) {
21cb93a386Sopenharmony_ci        case GrSamplerState::WrapMode::kClamp:
22cb93a386Sopenharmony_ci            return MTLSamplerAddressModeClampToEdge;
23cb93a386Sopenharmony_ci        case GrSamplerState::WrapMode::kRepeat:
24cb93a386Sopenharmony_ci            return MTLSamplerAddressModeRepeat;
25cb93a386Sopenharmony_ci        case GrSamplerState::WrapMode::kMirrorRepeat:
26cb93a386Sopenharmony_ci            return MTLSamplerAddressModeMirrorRepeat;
27cb93a386Sopenharmony_ci        case GrSamplerState::WrapMode::kClampToBorder:
28cb93a386Sopenharmony_ci            // Must guard the reference to the clamp to border address mode by macro since iOS or
29cb93a386Sopenharmony_ci            // older MacOS builds will fail if it's referenced, even if other code makes sure it's
30cb93a386Sopenharmony_ci            // never used.
31cb93a386Sopenharmony_ci#ifdef SK_BUILD_FOR_MAC
32cb93a386Sopenharmony_ci            if (@available(macOS 10.12, *)) {
33cb93a386Sopenharmony_ci                SkASSERT(caps.clampToBorderSupport());
34cb93a386Sopenharmony_ci                return MTLSamplerAddressModeClampToBorderColor;
35cb93a386Sopenharmony_ci            } else
36cb93a386Sopenharmony_ci#endif
37cb93a386Sopenharmony_ci            {
38cb93a386Sopenharmony_ci                SkASSERT(false);
39cb93a386Sopenharmony_ci                return MTLSamplerAddressModeClampToEdge;
40cb93a386Sopenharmony_ci            }
41cb93a386Sopenharmony_ci    }
42cb93a386Sopenharmony_ci    SK_ABORT("Unknown wrap mode.");
43cb93a386Sopenharmony_ci}
44cb93a386Sopenharmony_ci
45cb93a386Sopenharmony_ciGrMtlSampler* GrMtlSampler::Create(const GrMtlGpu* gpu, GrSamplerState samplerState) {
46cb93a386Sopenharmony_ci    MTLSamplerMinMagFilter minMagFilter = [&] {
47cb93a386Sopenharmony_ci        switch (samplerState.filter()) {
48cb93a386Sopenharmony_ci            case GrSamplerState::Filter::kNearest: return MTLSamplerMinMagFilterNearest;
49cb93a386Sopenharmony_ci            case GrSamplerState::Filter::kLinear:  return MTLSamplerMinMagFilterLinear;
50cb93a386Sopenharmony_ci        }
51cb93a386Sopenharmony_ci        SkUNREACHABLE;
52cb93a386Sopenharmony_ci    }();
53cb93a386Sopenharmony_ci
54cb93a386Sopenharmony_ci    MTLSamplerMipFilter mipFilter = [&] {
55cb93a386Sopenharmony_ci      switch (samplerState.mipmapMode()) {
56cb93a386Sopenharmony_ci          case GrSamplerState::MipmapMode::kNone:    return MTLSamplerMipFilterNotMipmapped;
57cb93a386Sopenharmony_ci          case GrSamplerState::MipmapMode::kNearest: return MTLSamplerMipFilterNearest;
58cb93a386Sopenharmony_ci          case GrSamplerState::MipmapMode::kLinear:  return MTLSamplerMipFilterLinear;
59cb93a386Sopenharmony_ci      }
60cb93a386Sopenharmony_ci      SkUNREACHABLE;
61cb93a386Sopenharmony_ci    }();
62cb93a386Sopenharmony_ci
63cb93a386Sopenharmony_ci    auto samplerDesc = [[MTLSamplerDescriptor alloc] init];
64cb93a386Sopenharmony_ci    samplerDesc.rAddressMode = MTLSamplerAddressModeClampToEdge;
65cb93a386Sopenharmony_ci    samplerDesc.sAddressMode = wrap_mode_to_mtl_sampler_address(samplerState.wrapModeX(),
66cb93a386Sopenharmony_ci                                                                gpu->mtlCaps());
67cb93a386Sopenharmony_ci    samplerDesc.tAddressMode = wrap_mode_to_mtl_sampler_address(samplerState.wrapModeY(),
68cb93a386Sopenharmony_ci                                                                gpu->mtlCaps());
69cb93a386Sopenharmony_ci    samplerDesc.magFilter = minMagFilter;
70cb93a386Sopenharmony_ci    samplerDesc.minFilter = minMagFilter;
71cb93a386Sopenharmony_ci    samplerDesc.mipFilter = mipFilter;
72cb93a386Sopenharmony_ci    samplerDesc.lodMinClamp = 0.0f;
73cb93a386Sopenharmony_ci    samplerDesc.lodMaxClamp = FLT_MAX;  // default value according to docs.
74cb93a386Sopenharmony_ci    samplerDesc.maxAnisotropy = 1.0f;
75cb93a386Sopenharmony_ci    samplerDesc.normalizedCoordinates = true;
76cb93a386Sopenharmony_ci    if (@available(macOS 10.11, iOS 9.0, *)) {
77cb93a386Sopenharmony_ci        samplerDesc.compareFunction = MTLCompareFunctionNever;
78cb93a386Sopenharmony_ci    }
79cb93a386Sopenharmony_ci
80cb93a386Sopenharmony_ci    return new GrMtlSampler([gpu->device() newSamplerStateWithDescriptor: samplerDesc],
81cb93a386Sopenharmony_ci                            GenerateKey(samplerState));
82cb93a386Sopenharmony_ci}
83cb93a386Sopenharmony_ci
84cb93a386Sopenharmony_ciGrMtlSampler::Key GrMtlSampler::GenerateKey(GrSamplerState samplerState) {
85cb93a386Sopenharmony_ci    return samplerState.asIndex();
86cb93a386Sopenharmony_ci}
87cb93a386Sopenharmony_ci
88cb93a386Sopenharmony_ciGR_NORETAIN_END
89