12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091 |
- /*
- * 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
- // 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],
- GenerateKey(samplerState, maxMipLevel));
- }
- GrMtlSampler::Key GrMtlSampler::GenerateKey(const GrSamplerState& samplerState,
- uint32_t maxMipLevel) {
- const int kTileModeXShift = 2;
- const int kTileModeYShift = 4;
- const int kMipLevelShift = 6;
- SkASSERT(static_cast<int>(samplerState.filter()) <= 3);
- Key samplerKey = static_cast<uint16_t>(samplerState.filter());
- SkASSERT(static_cast<int>(samplerState.wrapModeX()) <= 3);
- samplerKey |= (static_cast<uint16_t>(samplerState.wrapModeX()) << kTileModeXShift);
- SkASSERT(static_cast<int>(samplerState.wrapModeY()) <= 3);
- samplerKey |= (static_cast<uint16_t>(samplerState.wrapModeY()) << kTileModeYShift);
- bool useMipMaps = GrSamplerState::Filter::kMipMap == samplerState.filter() && maxMipLevel > 0;
- samplerKey |= (!useMipMaps ? 0 : (uint16_t) maxMipLevel) << kMipLevelShift;
- return samplerKey;
- }
|