1use std::collections::HashMap;
2
3use crate::{assets::singleton_asset::LazyResource, wgpu::backend::WGPUBackend};
4
5#[derive(Clone, Copy, PartialEq, Eq, Hash)]
9pub enum SamplerKind {
10 LinearRepeat,
12 LinearClamp,
14 LinearClampNoMip,
16 Nearest,
18 NearestClampBorder,
22 CompareLess,
25}
26
27impl SamplerKind {
28 pub fn descriptor(&self) -> wgpu::SamplerDescriptor<'static> {
39 match self {
40 SamplerKind::LinearRepeat => wgpu::SamplerDescriptor {
41 address_mode_u: wgpu::AddressMode::Repeat,
42 address_mode_v: wgpu::AddressMode::Repeat,
43 address_mode_w: wgpu::AddressMode::Repeat,
44 mag_filter: wgpu::FilterMode::Linear,
45 min_filter: wgpu::FilterMode::Linear,
46 mipmap_filter: wgpu::MipmapFilterMode::Linear,
47 ..Default::default()
48 },
49 SamplerKind::LinearClamp => wgpu::SamplerDescriptor {
50 address_mode_u: wgpu::AddressMode::ClampToEdge,
51 address_mode_v: wgpu::AddressMode::ClampToEdge,
52 address_mode_w: wgpu::AddressMode::ClampToEdge,
53 mag_filter: wgpu::FilterMode::Linear,
54 min_filter: wgpu::FilterMode::Linear,
55 mipmap_filter: wgpu::MipmapFilterMode::Linear,
56 ..Default::default()
57 },
58 SamplerKind::LinearClampNoMip => wgpu::SamplerDescriptor {
59 address_mode_u: wgpu::AddressMode::ClampToEdge,
60 address_mode_v: wgpu::AddressMode::ClampToEdge,
61 address_mode_w: wgpu::AddressMode::ClampToEdge,
62 mag_filter: wgpu::FilterMode::Linear,
63 min_filter: wgpu::FilterMode::Linear,
64 mipmap_filter: wgpu::MipmapFilterMode::Linear,
65 lod_min_clamp: 0.0,
66 lod_max_clamp: 0.0,
67 ..Default::default()
68 },
69 SamplerKind::Nearest => wgpu::SamplerDescriptor {
70 mag_filter: wgpu::FilterMode::Nearest,
71 min_filter: wgpu::FilterMode::Nearest,
72 mipmap_filter: wgpu::MipmapFilterMode::Linear,
73 ..Default::default()
74 },
75 SamplerKind::NearestClampBorder => {
76 let address_mode = if cfg!(target_arch = "wasm32") {
77 wgpu::AddressMode::ClampToEdge
78 } else {
79 wgpu::AddressMode::ClampToBorder
80 };
81 wgpu::SamplerDescriptor {
82 address_mode_u: address_mode,
83 address_mode_v: address_mode,
84 address_mode_w: address_mode,
85 mag_filter: wgpu::FilterMode::Nearest,
86 min_filter: wgpu::FilterMode::Nearest,
87 mipmap_filter: wgpu::MipmapFilterMode::Nearest,
88 border_color: if cfg!(target_arch = "wasm32") {
89 None
90 } else {
91 Some(wgpu::SamplerBorderColor::OpaqueWhite)
92 },
93 ..Default::default()
94 }
95 }
96 SamplerKind::CompareLess => wgpu::SamplerDescriptor {
97 address_mode_u: wgpu::AddressMode::ClampToEdge,
98 address_mode_v: wgpu::AddressMode::ClampToEdge,
99 address_mode_w: wgpu::AddressMode::ClampToEdge,
100 mag_filter: wgpu::FilterMode::Linear,
101 min_filter: wgpu::FilterMode::Linear,
102 mipmap_filter: wgpu::MipmapFilterMode::Linear,
103 compare: Some(wgpu::CompareFunction::Less),
104 ..Default::default()
105 },
106 }
107 }
108}
109
110const ALL_SAMPLER_KINDS: [SamplerKind; 6] = [
111 SamplerKind::LinearRepeat,
112 SamplerKind::LinearClamp,
113 SamplerKind::LinearClampNoMip,
114 SamplerKind::Nearest,
115 SamplerKind::NearestClampBorder,
116 SamplerKind::CompareLess,
117];
118
119pub struct GlobalSamplers {
122 samplers: HashMap<SamplerKind, wgpu::Sampler>,
123}
124
125impl GlobalSamplers {
126 pub fn get(&self, kind: SamplerKind) -> &wgpu::Sampler {
129 self.samplers
130 .get(&kind)
131 .expect("GlobalSamplers: all SamplerKind variants are built at construction")
132 }
133}
134
135impl LazyResource<WGPUBackend> for GlobalSamplers {
136 type Deps<'a> = ();
137
138 fn construct<'a>(backend: &WGPUBackend, _deps: &()) -> Option<Self> {
139 let samplers = ALL_SAMPLER_KINDS
140 .iter()
141 .map(|&kind| (kind, backend.device.create_sampler(&kind.descriptor())))
142 .collect();
143 Some(Self { samplers })
144 }
145}