vk: create sampler set

This commit is contained in:
chyyran 2022-12-21 22:03:38 -05:00
parent 12da07a1cf
commit abd38b9076
6 changed files with 141 additions and 10 deletions

View file

@ -1,4 +1,4 @@
use crate::{ImageFormat, Size}; use crate::{FilterMode, ImageFormat, Size, WrapMode};
use ash::vk; use ash::vk;
impl From<ImageFormat> for vk::Format { impl From<ImageFormat> for vk::Format {
@ -87,3 +87,33 @@ impl From<Size<u32>> for vk::Extent3D {
} }
} }
} }
impl From<FilterMode> for vk::Filter {
fn from(value: FilterMode) -> Self {
match value {
FilterMode::Linear => vk::Filter::LINEAR,
FilterMode::Nearest => vk::Filter::NEAREST
}
}
}
impl From<FilterMode> for vk::SamplerMipmapMode {
fn from(value: FilterMode) -> Self {
match value {
FilterMode::Linear => vk::SamplerMipmapMode::LINEAR,
FilterMode::Nearest => vk::SamplerMipmapMode::NEAREST
}
}
}
impl From<WrapMode> for vk::SamplerAddressMode {
fn from(value: WrapMode) -> Self {
match value {
WrapMode::ClampToBorder => vk::SamplerAddressMode::CLAMP_TO_BORDER,
WrapMode::ClampToEdge => vk::SamplerAddressMode::CLAMP_TO_EDGE,
WrapMode::Repeat => vk::SamplerAddressMode::REPEAT,
WrapMode::MirroredRepeat => vk::SamplerAddressMode::MIRRORED_REPEAT
}
}
}

View file

@ -8,9 +8,9 @@ pub struct SamplerSet {
} }
impl SamplerSet { impl SamplerSet {
pub fn get(&self, wrap: WrapMode, filter: FilterMode, mip: FilterMode) -> GLuint { pub fn get(&self, wrap: WrapMode, filter: FilterMode, mipmap: FilterMode) -> GLuint {
// eprintln!("{wrap}, {filter}, {mip}"); // eprintln!("{wrap}, {filter}, {mip}");
*self.samplers.get(&(wrap, filter, mip)).unwrap() *self.samplers.get(&(wrap, filter, mipmap)).unwrap()
} }
fn make_sampler(sampler: GLuint, wrap: WrapMode, filter: FilterMode, mip: FilterMode) { fn make_sampler(sampler: GLuint, wrap: WrapMode, filter: FilterMode, mip: FilterMode) {

View file

@ -1,9 +1,17 @@
#[rustfmt::skip]
static VBO_OFFSCREEN_MVP: &[f32; 16] = &[ static VBO_OFFSCREEN_MVP: &[f32; 16] = &[
// Offscreen // Offscreen
-1.0, -1.0, 0.0, 0.0, -1.0, 1.0, 0.0, 1.0, 1.0, -1.0, 1.0, 0.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 0.0, 0.0,
-1.0, 1.0, 0.0, 1.0,
1.0, -1.0, 1.0, 0.0,
1.0, 1.0, 1.0, 1.0,
]; ];
#[rustfmt::skip]
static VBO_DEFAULT_FINAL_MVP: &[f32; 16] = &[ static VBO_DEFAULT_FINAL_MVP: &[f32; 16] = &[
// Final // Final
0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0, 0.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0,
0.0, 1.0, 0.0, 1.0,
1.0, 0.0, 1.0, 0.0,
1.0, 1.0, 1.0, 1.0,
]; ];

View file

@ -19,6 +19,7 @@ use librashader_runtime::uniforms::UniformStorage;
use rustc_hash::FxHashMap; use rustc_hash::FxHashMap;
use std::error::Error; use std::error::Error;
use std::path::Path; use std::path::Path;
use crate::samplers::SamplerSet;
pub struct Vulkan { pub struct Vulkan {
// physical_device: vk::PhysicalDevice, // physical_device: vk::PhysicalDevice,
@ -126,13 +127,12 @@ pub struct FilterChainVulkan {
} }
pub(crate) struct FilterCommon { pub(crate) struct FilterCommon {
// pub(crate) luts: FxHashMap<usize, LutTexture>, pub(crate) luts: FxHashMap<usize, LutTexture>,
// pub samplers: SamplerSet, pub samplers: SamplerSet,
// pub output_textures: Box<[Option<Texture>]>, // pub output_textures: Box<[Option<Texture>]>,
// pub feedback_textures: Box<[Option<Texture>]>, // pub feedback_textures: Box<[Option<Texture>]>,
// pub history_textures: Box<[Option<Texture>]>, // pub history_textures: Box<[Option<Texture>]>,
// pub config: FilterMutable, // pub config: FilterMutable,
luts: FxHashMap<usize, LutTexture>,
} }
pub type FilterChainOptionsVulkan = (); pub type FilterChainOptionsVulkan = ();
@ -161,10 +161,10 @@ impl FilterChainVulkan {
let filters = Self::init_passes(&device, passes, &semantics, 3)?; let filters = Self::init_passes(&device, passes, &semantics, 3)?;
let luts = FilterChainVulkan::load_luts(&device, &preset.textures)?; let luts = FilterChainVulkan::load_luts(&device, &preset.textures)?;
let samplers = SamplerSet::new(&device.device)?;
eprintln!("filters initialized ok."); eprintln!("filters initialized ok.");
Ok(FilterChainVulkan { Ok(FilterChainVulkan {
common: FilterCommon { luts }, common: FilterCommon { luts, samplers },
passes: filters, passes: filters,
}) })
} }

View file

@ -12,6 +12,7 @@ mod renderpass;
mod util; mod util;
mod vulkan_primitives; mod vulkan_primitives;
mod vulkan_state; mod vulkan_state;
mod samplers;
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {

View file

@ -0,0 +1,92 @@
use ash::vk;
use rustc_hash::FxHashMap;
use librashader_common::{FilterMode, WrapMode};
use crate::error;
pub struct VulkanSampler {
pub handle: vk::Sampler,
device: ash::Device
}
impl VulkanSampler {
pub fn new(device: &ash::Device, wrap: WrapMode, filter: FilterMode, mipmap: FilterMode) -> error::Result<VulkanSampler> {
let create_info = vk::SamplerCreateInfo::builder()
.mip_lod_bias(0.0)
.max_anisotropy(1.0)
.compare_enable(false)
.min_lod(0.0)
.max_lod(vk::LOD_CLAMP_NONE)
.unnormalized_coordinates(false)
.border_color(vk::BorderColor::FLOAT_TRANSPARENT_BLACK)
.mag_filter(filter.into())
.min_filter(filter.into())
.mipmap_mode(mipmap.into())
.address_mode_u(wrap.into())
.address_mode_v(wrap.into())
.address_mode_w(wrap.into())
.build();
let sampler = unsafe {
device.create_sampler(&create_info, None)?
};
Ok(VulkanSampler {
handle: sampler,
device: device.clone()
})
}
}
impl Drop for VulkanSampler {
fn drop(&mut self) {
if self.handle != vk::Sampler::null() {
unsafe {
self.device.destroy_sampler(self.handle, None);
}
}
}
}
pub struct SamplerSet {
// todo: may need to deal with differences in mip filter.
samplers: FxHashMap<(WrapMode, FilterMode, FilterMode), VulkanSampler>,
}
impl SamplerSet {
pub fn get(&self, wrap: WrapMode, filter: FilterMode, mipmap: FilterMode) -> &VulkanSampler {
// eprintln!("{wrap}, {filter}, {mip}");
self.samplers.get(&(wrap, filter, mipmap)).unwrap()
}
pub fn new(device: &ash::Device) -> error::Result<SamplerSet> {
let mut samplers = FxHashMap::default();
let wrap_modes = &[
WrapMode::ClampToBorder,
WrapMode::ClampToEdge,
WrapMode::Repeat,
WrapMode::MirroredRepeat,
];
for wrap_mode in wrap_modes {
samplers.insert(
(*wrap_mode, FilterMode::Linear, FilterMode::Linear),
VulkanSampler::new(device, *wrap_mode, FilterMode::Linear, FilterMode::Linear)?,
);
samplers.insert(
(*wrap_mode, FilterMode::Linear, FilterMode::Nearest),
VulkanSampler::new(device, *wrap_mode, FilterMode::Linear, FilterMode::Nearest)?,
);
samplers.insert(
(*wrap_mode, FilterMode::Nearest, FilterMode::Nearest),
VulkanSampler::new(device, *wrap_mode, FilterMode::Nearest, FilterMode::Nearest)?
);
samplers.insert(
(*wrap_mode, FilterMode::Nearest, FilterMode::Linear),
VulkanSampler::new(device, *wrap_mode, FilterMode::Nearest, FilterMode::Linear)?
);
}
Ok(SamplerSet { samplers })
}
}