2024-02-06 10:39:01 +11:00
|
|
|
use crate::error;
|
|
|
|
use crate::error::FilterChainError;
|
|
|
|
use glow::HasContext;
|
2024-02-15 09:54:49 +11:00
|
|
|
use librashader_common::map::FastHashMap;
|
2024-02-15 11:22:25 +11:00
|
|
|
use librashader_common::{FilterMode, WrapMode};
|
2022-11-27 08:47:48 +11:00
|
|
|
|
|
|
|
pub struct SamplerSet {
|
|
|
|
// todo: may need to deal with differences in mip filter.
|
2024-02-06 10:39:01 +11:00
|
|
|
samplers: FastHashMap<(WrapMode, FilterMode, FilterMode), glow::Sampler>,
|
2022-11-27 08:47:48 +11:00
|
|
|
}
|
|
|
|
|
|
|
|
impl SamplerSet {
|
2023-02-17 10:19:38 +11:00
|
|
|
#[inline(always)]
|
2024-02-06 10:39:01 +11:00
|
|
|
pub fn get(&self, wrap: WrapMode, filter: FilterMode, mipmap: FilterMode) -> glow::Sampler {
|
2023-02-17 10:19:38 +11:00
|
|
|
// SAFETY: the sampler set is complete for the matrix
|
|
|
|
// wrap x filter x mipmap
|
|
|
|
unsafe {
|
2023-02-17 13:16:42 +11:00
|
|
|
*self
|
|
|
|
.samplers
|
|
|
|
.get(&(wrap, filter, mipmap))
|
|
|
|
.unwrap_unchecked()
|
2023-02-17 10:19:38 +11:00
|
|
|
}
|
2022-11-27 08:47:48 +11:00
|
|
|
}
|
|
|
|
|
2024-02-06 10:39:01 +11:00
|
|
|
fn make_sampler(
|
|
|
|
context: &glow::Context,
|
|
|
|
sampler: glow::Sampler,
|
|
|
|
wrap: WrapMode,
|
|
|
|
filter: FilterMode,
|
|
|
|
mip: FilterMode,
|
|
|
|
) {
|
2022-11-27 08:47:48 +11:00
|
|
|
unsafe {
|
2024-02-06 10:39:01 +11:00
|
|
|
context.sampler_parameter_i32(sampler, glow::TEXTURE_WRAP_S, wrap.into());
|
|
|
|
context.sampler_parameter_i32(sampler, glow::TEXTURE_WRAP_T, wrap.into());
|
|
|
|
context.sampler_parameter_i32(sampler, glow::TEXTURE_MAG_FILTER, filter.into());
|
|
|
|
context.sampler_parameter_i32(
|
2022-11-27 08:47:48 +11:00
|
|
|
sampler,
|
2024-02-06 10:39:01 +11:00
|
|
|
glow::TEXTURE_MIN_FILTER,
|
|
|
|
filter.gl_mip(mip) as i32,
|
2022-11-27 08:47:48 +11:00
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-02-06 10:39:01 +11:00
|
|
|
pub fn new(context: &glow::Context) -> error::Result<SamplerSet> {
|
2024-02-15 09:54:49 +11:00
|
|
|
let mut samplers = FastHashMap::default();
|
2022-11-30 17:38:05 +11:00
|
|
|
let wrap_modes = &[
|
|
|
|
WrapMode::ClampToBorder,
|
|
|
|
WrapMode::ClampToEdge,
|
|
|
|
WrapMode::Repeat,
|
|
|
|
WrapMode::MirroredRepeat,
|
|
|
|
];
|
2022-11-27 08:47:48 +11:00
|
|
|
for wrap_mode in wrap_modes {
|
2023-02-17 10:19:38 +11:00
|
|
|
for filter_mode in &[FilterMode::Linear, FilterMode::Nearest] {
|
|
|
|
for mip_filter in &[FilterMode::Linear, FilterMode::Nearest] {
|
|
|
|
unsafe {
|
2024-02-06 10:39:01 +11:00
|
|
|
let sampler = context
|
|
|
|
.create_sampler()
|
|
|
|
.map_err(|_| FilterChainError::GlSamplerError)?;
|
|
|
|
|
|
|
|
SamplerSet::make_sampler(
|
|
|
|
context,
|
|
|
|
sampler,
|
|
|
|
*wrap_mode,
|
|
|
|
*filter_mode,
|
|
|
|
*mip_filter,
|
|
|
|
);
|
2022-11-27 08:47:48 +11:00
|
|
|
|
2023-02-17 13:16:42 +11:00
|
|
|
samplers.insert((*wrap_mode, *filter_mode, *mip_filter), sampler);
|
2023-02-17 10:19:38 +11:00
|
|
|
}
|
|
|
|
}
|
2022-11-27 08:47:48 +11:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-02-17 10:19:38 +11:00
|
|
|
// assert all samplers were created.
|
|
|
|
assert_eq!(samplers.len(), wrap_modes.len() * 2 * 2);
|
2024-02-06 10:39:01 +11:00
|
|
|
Ok(SamplerSet { samplers })
|
2022-11-27 08:47:48 +11:00
|
|
|
}
|
|
|
|
}
|