GrMtlSampler.mm 3.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  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. #include "src/gpu/mtl/GrMtlSampler.h"
  8. #include "src/gpu/mtl/GrMtlGpu.h"
  9. #if !__has_feature(objc_arc)
  10. #error This file must be compiled with Arc. Use -fobjc-arc flag
  11. #endif
  12. static 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. GrMtlSampler* GrMtlSampler::Create(const GrMtlGpu* gpu, const GrSamplerState& samplerState,
  36. uint32_t maxMipLevel) {
  37. static MTLSamplerMinMagFilter mtlMinMagFilterModes[] = {
  38. MTLSamplerMinMagFilterNearest,
  39. MTLSamplerMinMagFilterLinear,
  40. MTLSamplerMinMagFilterLinear
  41. };
  42. GR_STATIC_ASSERT((int)GrSamplerState::Filter::kNearest == 0);
  43. GR_STATIC_ASSERT((int)GrSamplerState::Filter::kBilerp == 1);
  44. GR_STATIC_ASSERT((int)GrSamplerState::Filter::kMipMap == 2);
  45. auto samplerDesc = [[MTLSamplerDescriptor alloc] init];
  46. samplerDesc.rAddressMode = MTLSamplerAddressModeClampToEdge;
  47. samplerDesc.sAddressMode = wrap_mode_to_mtl_sampler_address(samplerState.wrapModeX(),
  48. gpu->mtlCaps());
  49. samplerDesc.tAddressMode = wrap_mode_to_mtl_sampler_address(samplerState.wrapModeY(),
  50. gpu->mtlCaps());
  51. samplerDesc.magFilter = mtlMinMagFilterModes[static_cast<int>(samplerState.filter())];
  52. samplerDesc.minFilter = mtlMinMagFilterModes[static_cast<int>(samplerState.filter())];
  53. samplerDesc.mipFilter = MTLSamplerMipFilterLinear;
  54. samplerDesc.lodMinClamp = 0.0f;
  55. bool useMipMaps = GrSamplerState::Filter::kMipMap == samplerState.filter() && maxMipLevel > 0;
  56. samplerDesc.lodMaxClamp = !useMipMaps ? 0.0f : (float)(maxMipLevel);
  57. samplerDesc.maxAnisotropy = 1.0f;
  58. samplerDesc.normalizedCoordinates = true;
  59. samplerDesc.compareFunction = MTLCompareFunctionNever;
  60. return new GrMtlSampler([gpu->device() newSamplerStateWithDescriptor: samplerDesc],
  61. GenerateKey(samplerState, maxMipLevel));
  62. }
  63. GrMtlSampler::Key GrMtlSampler::GenerateKey(const GrSamplerState& samplerState,
  64. uint32_t maxMipLevel) {
  65. const int kTileModeXShift = 2;
  66. const int kTileModeYShift = 4;
  67. const int kMipLevelShift = 6;
  68. SkASSERT(static_cast<int>(samplerState.filter()) <= 3);
  69. Key samplerKey = static_cast<uint16_t>(samplerState.filter());
  70. SkASSERT(static_cast<int>(samplerState.wrapModeX()) <= 3);
  71. samplerKey |= (static_cast<uint16_t>(samplerState.wrapModeX()) << kTileModeXShift);
  72. SkASSERT(static_cast<int>(samplerState.wrapModeY()) <= 3);
  73. samplerKey |= (static_cast<uint16_t>(samplerState.wrapModeY()) << kTileModeYShift);
  74. bool useMipMaps = GrSamplerState::Filter::kMipMap == samplerState.filter() && maxMipLevel > 0;
  75. samplerKey |= (!useMipMaps ? 0 : (uint16_t) maxMipLevel) << kMipLevelShift;
  76. return samplerKey;
  77. }