use super::gpu::arc::ArcSampler;
use std::collections::HashMap;
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Sampler {
pub clamp_u: ClampMode,
pub clamp_v: ClampMode,
pub clamp_w: ClampMode,
pub mag: FilterMode,
pub min: FilterMode,
}
impl Sampler {
pub fn linear_clamp() -> Self {
Sampler {
clamp_u: ClampMode::Clamp,
clamp_v: ClampMode::Clamp,
clamp_w: ClampMode::Clamp,
mag: FilterMode::Linear,
min: FilterMode::Linear,
}
}
pub fn nearest_clamp() -> Self {
Sampler {
mag: FilterMode::Nearest,
min: FilterMode::Nearest,
..Self::linear_clamp()
}
}
}
impl Default for Sampler {
fn default() -> Self {
Self::linear_clamp()
}
}
impl<'a> From<Sampler> for wgpu::SamplerDescriptor<'a> {
fn from(sampler: Sampler) -> Self {
wgpu::SamplerDescriptor {
label: None,
address_mode_u: sampler.clamp_u.into(),
address_mode_v: sampler.clamp_v.into(),
address_mode_w: sampler.clamp_w.into(),
mag_filter: sampler.mag.into(),
min_filter: sampler.min.into(),
mipmap_filter: wgpu::FilterMode::Linear,
lod_min_clamp: 0.0,
lod_max_clamp: 1.0,
compare: None,
anisotropy_clamp: 1,
border_color: None,
}
}
}
impl From<FilterMode> for Sampler {
fn from(filter: FilterMode) -> Self {
match filter {
FilterMode::Nearest => Self::nearest_clamp(),
FilterMode::Linear => Self::linear_clamp(),
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum ClampMode {
Clamp,
Repeat,
MirrorRepeat,
}
impl From<ClampMode> for wgpu::AddressMode {
fn from(clamp: ClampMode) -> Self {
match clamp {
ClampMode::Clamp => wgpu::AddressMode::ClampToEdge,
ClampMode::Repeat => wgpu::AddressMode::Repeat,
ClampMode::MirrorRepeat => wgpu::AddressMode::MirrorRepeat,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum FilterMode {
Nearest,
Linear,
}
impl From<FilterMode> for wgpu::FilterMode {
fn from(filter: FilterMode) -> Self {
match filter {
FilterMode::Nearest => wgpu::FilterMode::Nearest,
FilterMode::Linear => wgpu::FilterMode::Linear,
}
}
}
#[derive(Debug)]
pub(crate) struct SamplerCache {
cache: HashMap<Sampler, ArcSampler>,
}
impl SamplerCache {
pub fn new() -> Self {
SamplerCache {
cache: Default::default(),
}
}
pub fn get(&mut self, device: &wgpu::Device, sampler: Sampler) -> ArcSampler {
self.cache
.entry(sampler)
.or_insert_with(|| ArcSampler::new(device.create_sampler(&sampler.into())))
.clone()
}
}