1 /*
2 * Copyright 2022 Google LLC
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 "src/gpu/graphite/dawn/DawnSampler.h"
9
10 #include "include/core/SkSamplingOptions.h"
11 #include "src/gpu/graphite/dawn/DawnCaps.h"
12 #include "src/gpu/graphite/dawn/DawnSharedContext.h"
13
14 #include <cfloat>
15
16 namespace skgpu::graphite {
17
18 namespace {
19
filter_mode_to_dawn_filter_mode(SkFilterMode mode)20 wgpu::FilterMode filter_mode_to_dawn_filter_mode(SkFilterMode mode) {
21 switch (mode) {
22 case SkFilterMode::kNearest:
23 return wgpu::FilterMode::Nearest;
24 case SkFilterMode::kLinear:
25 return wgpu::FilterMode::Linear;
26 }
27 SkUNREACHABLE;
28 }
29
mipmap_mode_to_dawn_filter_mode(SkMipmapMode mode)30 wgpu::MipmapFilterMode mipmap_mode_to_dawn_filter_mode(SkMipmapMode mode) {
31 switch (mode) {
32 case SkMipmapMode::kNone:
33 // Dawn doesn't have none filter mode.
34 return wgpu::MipmapFilterMode::Nearest;
35 case SkMipmapMode::kNearest:
36 return wgpu::MipmapFilterMode::Nearest;
37 case SkMipmapMode::kLinear:
38 return wgpu::MipmapFilterMode::Linear;
39 }
40 SkUNREACHABLE;
41 }
42 }
43
DawnSampler(const DawnSharedContext * sharedContext,wgpu::Sampler sampler)44 DawnSampler::DawnSampler(const DawnSharedContext* sharedContext,
45 wgpu::Sampler sampler)
46 : Sampler(sharedContext)
47 , fSampler(std::move(sampler)) {}
48
tile_mode_to_dawn_address_mode(SkTileMode tileMode)49 static inline wgpu::AddressMode tile_mode_to_dawn_address_mode(SkTileMode tileMode) {
50 switch (tileMode) {
51 case SkTileMode::kClamp:
52 return wgpu::AddressMode::ClampToEdge;
53 case SkTileMode::kRepeat:
54 return wgpu::AddressMode::Repeat;
55 case SkTileMode::kMirror:
56 return wgpu::AddressMode::MirrorRepeat;
57 case SkTileMode::kDecal:
58 // Dawn doesn't support this mode.
59 return wgpu::AddressMode::ClampToEdge;
60 }
61 SkUNREACHABLE;
62 }
63
Make(const DawnSharedContext * sharedContext,const SkSamplingOptions & samplingOptions,SkTileMode xTileMode,SkTileMode yTileMode)64 sk_sp<DawnSampler> DawnSampler::Make(const DawnSharedContext* sharedContext,
65 const SkSamplingOptions& samplingOptions,
66 SkTileMode xTileMode,
67 SkTileMode yTileMode) {
68 wgpu::SamplerDescriptor desc;
69 desc.addressModeU = tile_mode_to_dawn_address_mode(xTileMode);
70 desc.addressModeV = tile_mode_to_dawn_address_mode(yTileMode);
71 desc.magFilter = filter_mode_to_dawn_filter_mode(samplingOptions.filter);
72 desc.minFilter = desc.magFilter;
73 desc.mipmapFilter = mipmap_mode_to_dawn_filter_mode(samplingOptions.mipmap);
74 desc.lodMinClamp = 0.0f;
75 if (samplingOptions.mipmap == SkMipmapMode::kNone) {
76 // Disabling mipmap by clamping max lod to first level only.
77 desc.lodMaxClamp = 0.0f;
78 } else {
79 desc.lodMaxClamp = FLT_MAX;
80 }
81 desc.maxAnisotropy = 1;
82 desc.compare = wgpu::CompareFunction::Undefined;
83
84 std::string label;
85 if (sharedContext->caps()->setBackendLabels()) {
86 static const char* tileModeLabels[] = {"Clamp", "Repeat", "Mirror", "Decal"};
87 static const char* minMagFilterLabels[] = {"Nearest", "Linear"};
88 static const char* mipFilterLabels[] = {"MipNone", "MipNearest", "MipLinear"};
89 label.append("X").append(tileModeLabels[static_cast<int>(xTileMode)]);
90 label.append("Y").append(tileModeLabels[static_cast<int>(yTileMode)]);
91 label.append(minMagFilterLabels[static_cast<int>(samplingOptions.filter)]);
92 label.append(mipFilterLabels[static_cast<int>(samplingOptions.mipmap)]);
93 desc.label = label.c_str();
94 }
95
96 auto sampler = sharedContext->device().CreateSampler(&desc);
97 if (!sampler) {
98 return {};
99 }
100 return sk_sp<DawnSampler>(new DawnSampler(sharedContext, std::move(sampler)));
101 }
102
freeGpuData()103 void DawnSampler::freeGpuData() {
104 fSampler = nullptr;
105 }
106
107 } // namespace skgpu::graphite
108
109