1use std::collections::HashMap;
2
3use crate::{assets::singleton_asset::LazyResource, wgpu::backend::WGPUBackend};
4
5#[derive(Clone, Copy, PartialEq, Eq, Hash)]
6pub enum SamplerKind {
7 LinearRepeat,
8 LinearClamp,
9 LinearClampNoMip,
10 Nearest,
11 NearestClampBorder,
12 CompareLess,
13}
14
15impl SamplerKind {
16 pub fn descriptor(&self) -> wgpu::SamplerDescriptor<'static> {
17 match self {
18 SamplerKind::LinearRepeat => wgpu::SamplerDescriptor {
19 address_mode_u: wgpu::AddressMode::Repeat,
20 address_mode_v: wgpu::AddressMode::Repeat,
21 address_mode_w: wgpu::AddressMode::Repeat,
22 mag_filter: wgpu::FilterMode::Linear,
23 min_filter: wgpu::FilterMode::Linear,
24 mipmap_filter: wgpu::MipmapFilterMode::Linear,
25 ..Default::default()
26 },
27 SamplerKind::LinearClamp => wgpu::SamplerDescriptor {
28 address_mode_u: wgpu::AddressMode::ClampToEdge,
29 address_mode_v: wgpu::AddressMode::ClampToEdge,
30 address_mode_w: wgpu::AddressMode::ClampToEdge,
31 mag_filter: wgpu::FilterMode::Linear,
32 min_filter: wgpu::FilterMode::Linear,
33 mipmap_filter: wgpu::MipmapFilterMode::Linear,
34 ..Default::default()
35 },
36 SamplerKind::LinearClampNoMip => wgpu::SamplerDescriptor {
37 address_mode_u: wgpu::AddressMode::ClampToEdge,
38 address_mode_v: wgpu::AddressMode::ClampToEdge,
39 address_mode_w: wgpu::AddressMode::ClampToEdge,
40 mag_filter: wgpu::FilterMode::Linear,
41 min_filter: wgpu::FilterMode::Linear,
42 mipmap_filter: wgpu::MipmapFilterMode::Linear,
43 lod_min_clamp: 0.0,
44 lod_max_clamp: 0.0,
45 ..Default::default()
46 },
47 SamplerKind::Nearest => wgpu::SamplerDescriptor {
48 mag_filter: wgpu::FilterMode::Nearest,
49 min_filter: wgpu::FilterMode::Nearest,
50 mipmap_filter: wgpu::MipmapFilterMode::Linear,
51 ..Default::default()
52 },
53 SamplerKind::NearestClampBorder => wgpu::SamplerDescriptor {
54 address_mode_u: wgpu::AddressMode::ClampToBorder,
55 address_mode_v: wgpu::AddressMode::ClampToBorder,
56 address_mode_w: wgpu::AddressMode::ClampToBorder,
57 mag_filter: wgpu::FilterMode::Nearest,
58 min_filter: wgpu::FilterMode::Nearest,
59 mipmap_filter: wgpu::MipmapFilterMode::Nearest,
60 border_color: Some(wgpu::SamplerBorderColor::OpaqueWhite),
61 ..Default::default()
62 },
63 SamplerKind::CompareLess => wgpu::SamplerDescriptor {
64 address_mode_u: wgpu::AddressMode::ClampToEdge,
65 address_mode_v: wgpu::AddressMode::ClampToEdge,
66 address_mode_w: wgpu::AddressMode::ClampToEdge,
67 mag_filter: wgpu::FilterMode::Linear,
68 min_filter: wgpu::FilterMode::Linear,
69 mipmap_filter: wgpu::MipmapFilterMode::Linear,
70 compare: Some(wgpu::CompareFunction::Less),
71 ..Default::default()
72 },
73 }
74 }
75}
76
77const ALL_SAMPLER_KINDS: [SamplerKind; 6] = [
78 SamplerKind::LinearRepeat,
79 SamplerKind::LinearClamp,
80 SamplerKind::LinearClampNoMip,
81 SamplerKind::Nearest,
82 SamplerKind::NearestClampBorder,
83 SamplerKind::CompareLess,
84];
85
86pub struct GlobalSamplers {
89 samplers: HashMap<SamplerKind, wgpu::Sampler>,
90}
91
92impl GlobalSamplers {
93 pub fn get(&self, kind: SamplerKind) -> &wgpu::Sampler {
96 self.samplers
97 .get(&kind)
98 .expect("GlobalSamplers: all SamplerKind variants are built at construction")
99 }
100}
101
102impl LazyResource<WGPUBackend> for GlobalSamplers {
103 type Deps<'a> = ();
104
105 fn construct<'a>(backend: &WGPUBackend, _deps: &()) -> Option<Self> {
106 let samplers = ALL_SAMPLER_KINDS
107 .iter()
108 .map(|&kind| (kind, backend.device.create_sampler(&kind.descriptor())))
109 .collect();
110 Some(Self { samplers })
111 }
112}