librashader/librashader-runtime-gl/src/samplers.rs

79 lines
2.6 KiB
Rust
Raw Normal View History

2024-02-06 10:39:01 +11:00
use crate::error;
use crate::error::FilterChainError;
use glow::HasContext;
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 {
*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> {
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
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
}
}