From abd38b9076a60955774aa7ed2942403862255c6e Mon Sep 17 00:00:00 2001 From: chyyran Date: Wed, 21 Dec 2022 22:03:38 -0500 Subject: [PATCH] vk: create sampler set --- librashader-common/src/vk.rs | 32 +++++++- librashader-runtime-gl/src/samplers.rs | 4 +- librashader-runtime-vk/src/draw_quad.rs | 12 ++- librashader-runtime-vk/src/filter_chain.rs | 10 +-- librashader-runtime-vk/src/lib.rs | 1 + librashader-runtime-vk/src/samplers.rs | 92 ++++++++++++++++++++++ 6 files changed, 141 insertions(+), 10 deletions(-) diff --git a/librashader-common/src/vk.rs b/librashader-common/src/vk.rs index 1383bf3..e1ffa67 100644 --- a/librashader-common/src/vk.rs +++ b/librashader-common/src/vk.rs @@ -1,4 +1,4 @@ -use crate::{ImageFormat, Size}; +use crate::{FilterMode, ImageFormat, Size, WrapMode}; use ash::vk; impl From for vk::Format { @@ -87,3 +87,33 @@ impl From> for vk::Extent3D { } } } + +impl From for vk::Filter { + fn from(value: FilterMode) -> Self { + match value { + FilterMode::Linear => vk::Filter::LINEAR, + FilterMode::Nearest => vk::Filter::NEAREST + } + } +} + + +impl From for vk::SamplerMipmapMode { + fn from(value: FilterMode) -> Self { + match value { + FilterMode::Linear => vk::SamplerMipmapMode::LINEAR, + FilterMode::Nearest => vk::SamplerMipmapMode::NEAREST + } + } +} + +impl From 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 + } + } +} \ No newline at end of file diff --git a/librashader-runtime-gl/src/samplers.rs b/librashader-runtime-gl/src/samplers.rs index 10267b9..ca53b74 100644 --- a/librashader-runtime-gl/src/samplers.rs +++ b/librashader-runtime-gl/src/samplers.rs @@ -8,9 +8,9 @@ pub struct 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}"); - *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) { diff --git a/librashader-runtime-vk/src/draw_quad.rs b/librashader-runtime-vk/src/draw_quad.rs index 53bbb21..2d24351 100644 --- a/librashader-runtime-vk/src/draw_quad.rs +++ b/librashader-runtime-vk/src/draw_quad.rs @@ -1,9 +1,17 @@ +#[rustfmt::skip] static VBO_OFFSCREEN_MVP: &[f32; 16] = &[ // 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] = &[ // 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, ]; diff --git a/librashader-runtime-vk/src/filter_chain.rs b/librashader-runtime-vk/src/filter_chain.rs index 04f146a..8aac9e4 100644 --- a/librashader-runtime-vk/src/filter_chain.rs +++ b/librashader-runtime-vk/src/filter_chain.rs @@ -19,6 +19,7 @@ use librashader_runtime::uniforms::UniformStorage; use rustc_hash::FxHashMap; use std::error::Error; use std::path::Path; +use crate::samplers::SamplerSet; pub struct Vulkan { // physical_device: vk::PhysicalDevice, @@ -126,13 +127,12 @@ pub struct FilterChainVulkan { } pub(crate) struct FilterCommon { - // pub(crate) luts: FxHashMap, - // pub samplers: SamplerSet, + pub(crate) luts: FxHashMap, + pub samplers: SamplerSet, // pub output_textures: Box<[Option]>, // pub feedback_textures: Box<[Option]>, // pub history_textures: Box<[Option]>, // pub config: FilterMutable, - luts: FxHashMap, } pub type FilterChainOptionsVulkan = (); @@ -161,10 +161,10 @@ impl FilterChainVulkan { let filters = Self::init_passes(&device, passes, &semantics, 3)?; let luts = FilterChainVulkan::load_luts(&device, &preset.textures)?; - + let samplers = SamplerSet::new(&device.device)?; eprintln!("filters initialized ok."); Ok(FilterChainVulkan { - common: FilterCommon { luts }, + common: FilterCommon { luts, samplers }, passes: filters, }) } diff --git a/librashader-runtime-vk/src/lib.rs b/librashader-runtime-vk/src/lib.rs index 4df7671..3ddea92 100644 --- a/librashader-runtime-vk/src/lib.rs +++ b/librashader-runtime-vk/src/lib.rs @@ -12,6 +12,7 @@ mod renderpass; mod util; mod vulkan_primitives; mod vulkan_state; +mod samplers; #[cfg(test)] mod tests { diff --git a/librashader-runtime-vk/src/samplers.rs b/librashader-runtime-vk/src/samplers.rs index e69de29..1618bd0 100644 --- a/librashader-runtime-vk/src/samplers.rs +++ b/librashader-runtime-vk/src/samplers.rs @@ -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 { + 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 { + 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 }) + } +}