diff --git a/Cargo.lock b/Cargo.lock index 0e54942..20e4c0e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -531,16 +531,16 @@ dependencies = [ "bitflags 1.3.2", "clap_lex 0.2.4", "indexmap 1.9.3", - "strsim", + "strsim 0.10.0", "termcolor", "textwrap", ] [[package]] name = "clap" -version = "4.4.18" +version = "4.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e578d6ec4194633722ccf9544794b71b1385c3c027efe0c55db226fc880865c" +checksum = "80c21025abd42669a92efc996ef13cfb2c5c627858421ea58d5c3b331a6c134f" dependencies = [ "clap_builder", "clap_derive", @@ -548,21 +548,21 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.4.18" +version = "4.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4df4df40ec50c46000231c914968278b1eb05098cf8f1b3a518a95030e71d1c7" +checksum = "458bf1f341769dfcf849846f65dffdf9146daa56bcd2a47cb4e1de9915567c99" dependencies = [ "anstream", "anstyle", - "clap_lex 0.6.0", - "strsim", + "clap_lex 0.7.0", + "strsim 0.11.0", ] [[package]] name = "clap_derive" -version = "4.4.7" +version = "4.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf9804afaaf59a91e75b022a30fb7229a7901f60c755489cc61c9b423b836442" +checksum = "307bc0538d5f0f83b8248db3087aa92fe504e4691294d0c96c0eabc33f47ba47" dependencies = [ "heck", "proc-macro2", @@ -581,9 +581,9 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.6.0" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1" +checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" [[package]] name = "cmake" @@ -927,7 +927,7 @@ dependencies = [ "ident_case", "proc-macro2", "quote", - "strsim", + "strsim 0.10.0", "syn 1.0.109", ] @@ -1355,9 +1355,9 @@ dependencies = [ [[package]] name = "glslang-sys" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d76f2d75ad6e8a12c26e77ed6443a9369ef7957daf361e751c3489a97f8b816" +checksum = "6a47e052f086ec9b43df0bca02c1675c2a89bceb5386dd64382dc36143930985" dependencies = [ "cc", "glob", @@ -1591,12 +1591,12 @@ dependencies = [ [[package]] name = "is-terminal" -version = "0.4.10" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bad00257d07be169d870ab665980b06cdb366d792ad690bf2e76876dc503455" +checksum = "fe8f25ce1159c7740ff0b9b2f5cdf4a8428742ba7c112b9f20f22cd5219c7dab" dependencies = [ "hermit-abi 0.3.5", - "rustix", + "libc", "windows-sys 0.52.0", ] @@ -1630,9 +1630,9 @@ checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" [[package]] name = "jobserver" -version = "0.1.27" +version = "0.1.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c37f63953c4c63420ed5fd3d6d398c719489b9f872b9fa683262f8edd363c7d" +checksum = "ab46a6e9526ddef3ae7f787c06f0f2600639ba80ea3eade3d8e670a2230f51d6" dependencies = [ "libc", ] @@ -1747,7 +1747,7 @@ name = "librashader-build-script" version = "0.1.0" dependencies = [ "cbindgen", - "clap 4.4.18", + "clap 4.5.0", ] [[package]] @@ -1836,6 +1836,9 @@ dependencies = [ "nom", "nom_locate", "num-traits", + "once_cell", + "regex", + "rustc-hash", "thiserror", ] @@ -2980,7 +2983,7 @@ dependencies = [ "ab_glyph", "log", "memmap2 0.9.4", - "smithay-client-toolkit 0.18.0", + "smithay-client-toolkit 0.18.1", "tiny-skia 0.11.4", ] @@ -3098,9 +3101,9 @@ dependencies = [ [[package]] name = "smithay-client-toolkit" -version = "0.18.0" +version = "0.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60e3d9941fa3bacf7c2bf4b065304faa14164151254cd16ce1b1bc8fc381600f" +checksum = "922fd3eeab3bd820d76537ce8f582b1cf951eceb5475c28500c7457d9d17f53a" dependencies = [ "bitflags 2.4.2", "calloop 0.12.4", @@ -3194,6 +3197,12 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" +[[package]] +name = "strsim" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ee073c9e4cd00e28217186dbe12796d692868f432bf2e97ee73bed0c56dfa01" + [[package]] name = "syn" version = "1.0.109" @@ -4221,7 +4230,7 @@ dependencies = [ "redox_syscall 0.3.5", "rustix", "sctk-adwaita 0.8.1", - "smithay-client-toolkit 0.18.0", + "smithay-client-toolkit 0.18.1", "smol_str", "unicode-segmentation", "wasm-bindgen", diff --git a/librashader-presets/Cargo.toml b/librashader-presets/Cargo.toml index 18e2358..8bb9fce 100644 --- a/librashader-presets/Cargo.toml +++ b/librashader-presets/Cargo.toml @@ -17,7 +17,10 @@ nom = "7.1.1" nom_locate = "4.0.0" librashader-common = { path = "../librashader-common", version = "0.2.0-beta.7" } num-traits = "0.2" - +once_cell = "1" +# we don't need unicode +regex = { version = "1", default-features = false, features = ["perf"] } +rustc-hash = "1.1.0" [features] parse_legacy_glsl = [] diff --git a/librashader-presets/src/lib.rs b/librashader-presets/src/lib.rs index 3200ffd..b21e4d1 100644 --- a/librashader-presets/src/lib.rs +++ b/librashader-presets/src/lib.rs @@ -8,6 +8,8 @@ //! //! Re-exported as [`librashader::presets`](https://docs.rs/librashader/latest/librashader/presets/index.html). +#![allow(stable_features)] +#![feature(os_str_bytes)] #![allow(unstable_name_collisions)] mod error; @@ -16,4 +18,5 @@ mod parse; mod preset; pub use error::*; +pub use parse::context; pub use preset::*; diff --git a/librashader-presets/src/parse/context.rs b/librashader-presets/src/parse/context.rs new file mode 100644 index 0000000..6a02847 --- /dev/null +++ b/librashader-presets/src/parse/context.rs @@ -0,0 +1,358 @@ +use nom::AsBytes; +use once_cell::sync::Lazy; +use regex::bytes::Regex; +use rustc_hash::FxHashMap; +use std::collections::VecDeque; +use std::ffi::{OsStr, OsString}; +use std::fmt::{Debug, Display, Formatter, Write}; +use std::hash::Hash; +use std::ops::Add; +use std::path::{Component, Path, PathBuf}; + +#[repr(u32)] +#[derive(Debug, Copy, Clone)] +pub enum VideoDriver { + None = 0, + GlCore, + Gl, + Vulkan, + Direct3D11, + Direct3D9Hlsl, + Direct3D12, + Metal, +} + +impl Display for VideoDriver { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + match self { + VideoDriver::None => f.write_str("null"), + VideoDriver::GlCore => f.write_str("glcore"), + VideoDriver::Gl => f.write_str("gl"), + VideoDriver::Vulkan => f.write_str("vulkan"), + VideoDriver::Direct3D11 => f.write_str("d3d11"), + VideoDriver::Direct3D9Hlsl => f.write_str("d3d9_hlsl"), + VideoDriver::Direct3D12 => f.write_str("d3d12"), + VideoDriver::Metal => f.write_str("metal"), + } + } +} + +#[repr(u32)] +#[derive(Debug, Copy, Clone)] +pub enum ShaderExtension { + Slang = 0, + Glsl, + Cg, +} + +impl Display for ShaderExtension { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + match self { + ShaderExtension::Slang => f.write_str("slang"), + ShaderExtension::Glsl => f.write_str("glsl"), + ShaderExtension::Cg => f.write_str("cg"), + } + } +} + +#[repr(u32)] +#[derive(Debug, Copy, Clone)] +pub enum PresetExtension { + Slangp = 0, + Glslp, + Cgp, +} + +impl Display for PresetExtension { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + match self { + PresetExtension::Slangp => f.write_str("slangp"), + PresetExtension::Glslp => f.write_str("glslp"), + PresetExtension::Cgp => f.write_str("cgp"), + } + } +} + +#[repr(u32)] +#[derive(Debug, Copy, Clone)] +pub enum Rotation { + /// Zero + Zero = 0, + /// 90 degrees + Right = 1, + /// 180 degrees + Straight = 2, + /// 270 degrees + Reflex = 3, +} + +impl Add for Rotation { + type Output = Rotation; + + fn add(self, rhs: Self) -> Self::Output { + let lhs = self as u32; + let out = lhs + rhs as u32; + let out = out % 4; + match out { + 0 => Rotation::Zero, + 1 => Rotation::Right, + 2 => Rotation::Straight, + 3 => Rotation::Reflex, + _ => unreachable!(), + } + } +} + +impl Display for Rotation { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + match self { + Rotation::Zero => f.write_str("0"), + Rotation::Right => f.write_str("90"), + Rotation::Straight => f.write_str("180"), + Rotation::Reflex => f.write_str("270"), + } + } +} + +#[repr(u32)] +#[derive(Debug, Copy, Clone)] +pub enum Orientation { + Vertical = 0, + Horizontal, +} + +impl Display for Orientation { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + match self { + Orientation::Vertical => f.write_str("VERT"), + Orientation::Horizontal => f.write_str("HORZ"), + } + } +} + +#[derive(Debug, Clone)] +pub enum ContextItem { + ContentDirectory(String), + CoreName(String), + GameName(String), + Preset(String), + PresetDirectory(String), + VideoDriver(VideoDriver), + VideoDriverShaderExtension(ShaderExtension), + VideoDriverPresetExtension(PresetExtension), + CoreRequestedRotation(Rotation), + AllowCoreRotation(bool), + UserRotation(Rotation), + FinalRotation(Rotation), + ScreenOrientation(Rotation), + ViewAspectOrientation(Orientation), + CoreAspectOrientation(Orientation), + ExternContext(String, String), +} + +impl ContextItem { + fn toggle_str(v: bool) -> &'static str { + if v { + "ON" + } else { + "OFF" + } + } + + pub fn key(&self) -> &str { + match self { + ContextItem::ContentDirectory(_) => "CONTENT-DIR", + ContextItem::CoreName(_) => "CORE", + ContextItem::GameName(_) => "GAME", + ContextItem::Preset(_) => "PRESET", + ContextItem::PresetDirectory(_) => "PRESET_DIR", + ContextItem::VideoDriver(_) => "VID-DRV", + ContextItem::CoreRequestedRotation(_) => "CORE-REQ-ROT", + ContextItem::AllowCoreRotation(_) => "VID-ALLOW-CORE-ROT", + ContextItem::UserRotation(_) => "VID-USER-ROT", + ContextItem::FinalRotation(_) => "VID-FINAL-ROT", + ContextItem::ScreenOrientation(_) => "SCREEN-ORIENT", + ContextItem::ViewAspectOrientation(_) => "VIEW-ASPECT-ORIENT", + ContextItem::CoreAspectOrientation(_) => "CORE-ASPECT-ORIENT", + ContextItem::VideoDriverShaderExtension(_) => "VID-DRV-SHADER-EXT", + ContextItem::VideoDriverPresetExtension(_) => "VID-DRV-PRESET-EXT", + ContextItem::ExternContext(key, _) => key, + } + } +} + +impl Display for ContextItem { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + match self { + ContextItem::ContentDirectory(v) => f.write_str(v), + ContextItem::CoreName(v) => f.write_str(v), + ContextItem::GameName(v) => f.write_str(v), + ContextItem::Preset(v) => f.write_str(v), + ContextItem::PresetDirectory(v) => f.write_str(v), + ContextItem::VideoDriver(v) => f.write_fmt(format_args!("{}", v)), + ContextItem::CoreRequestedRotation(v) => { + f.write_fmt(format_args!("{}-{}", self.key(), v)) + } + ContextItem::AllowCoreRotation(v) => f.write_fmt(format_args!( + "{}-{}", + self.key(), + ContextItem::toggle_str(*v) + )), + ContextItem::UserRotation(v) => f.write_fmt(format_args!("{}-{}", self.key(), v)), + ContextItem::FinalRotation(v) => f.write_fmt(format_args!("{}-{}", self.key(), v)), + ContextItem::ScreenOrientation(v) => f.write_fmt(format_args!("{}-{}", self.key(), v)), + ContextItem::ViewAspectOrientation(v) => { + f.write_fmt(format_args!("{}-{}", self.key(), v)) + } + ContextItem::CoreAspectOrientation(v) => { + f.write_fmt(format_args!("{}-{}", self.key(), v)) + } + ContextItem::VideoDriverShaderExtension(v) => f.write_fmt(format_args!("{}", v)), + ContextItem::VideoDriverPresetExtension(v) => f.write_fmt(format_args!("{}", v)), + ContextItem::ExternContext(_, v) => f.write_fmt(format_args!("{}", v)), + } + } +} + +/// A builder for preset wildcard context. +/// +/// Any items added after will have higher priority +/// when passed to the shader preset parser. +/// +/// When passed to the preset parser, the preset parser +/// will automatically add inferred items at lowest priority. +/// +/// Any items added by the user will override the automatically +/// inferred items. +#[derive(Debug, Clone)] +pub struct WildcardContext(VecDeque); + +impl WildcardContext { + /// Create a new wildcard context. + pub fn new() -> Self { + Self(VecDeque::new()) + } + + /// Prepend an item to the context builder. + pub fn prepend_item(&mut self, item: ContextItem) { + self.0.push_front(item); + } + + /// Append an item to the context builder. + /// The new item will take precedence over all items added before it. + pub fn append_item(&mut self, item: ContextItem) { + self.0.push_back(item); + } + + /// Prepend sensible defaults for the given video driver. + /// + /// Any values added, either previously or afterwards will not be overridden. + pub fn add_video_driver_defaults(&mut self, video_driver: VideoDriver) { + self.0.push_front(ContextItem::VideoDriverPresetExtension( + PresetExtension::Slangp, + )); + self.0.push_front(ContextItem::VideoDriverShaderExtension( + ShaderExtension::Slang, + )); + self.0.push_front(ContextItem::VideoDriver(video_driver)); + } + + /// Prepend default entries from the path of the preset. + /// + /// Any values added, either previously or afterwards will not be overridden. + pub fn add_path_defaults(&mut self, path: impl AsRef) { + let path = path.as_ref(); + if let Some(preset_name) = path.file_stem() { + let preset_name = preset_name.to_string_lossy(); + self.0.push_front(ContextItem::Preset(preset_name.into())) + } + + if let Some(preset_dir_name) = path.parent().and_then(|p| { + if !p.is_dir() { + return None; + }; + p.file_name() + }) { + let preset_dir_name = preset_dir_name.to_string_lossy(); + self.0 + .push_front(ContextItem::PresetDirectory(preset_dir_name.into())) + } + } + + pub(crate) fn to_hashmap(mut self) -> FxHashMap { + let mut map = FxHashMap::default(); + let last_user_rot = self + .0 + .iter() + .rfind(|i| matches!(i, ContextItem::UserRotation(_))); + let last_core_rot = self + .0 + .iter() + .rfind(|i| matches!(i, ContextItem::CoreRequestedRotation(_))); + + let final_rot = match (last_core_rot, last_user_rot) { + (Some(ContextItem::UserRotation(u)), None) => Some(ContextItem::FinalRotation(*u)), + (None, Some(ContextItem::CoreRequestedRotation(c))) => { + Some(ContextItem::FinalRotation(*c)) + } + (Some(ContextItem::UserRotation(u)), Some(ContextItem::CoreRequestedRotation(c))) => { + Some(ContextItem::FinalRotation(*u + *c)) + } + _ => None, + }; + + if let Some(final_rot) = final_rot { + self.prepend_item(final_rot); + } + + for item in self.0 { + map.insert(String::from(item.key()), item.to_string()); + } + + map + } +} + +pub fn apply_context(path: &mut PathBuf, context: &FxHashMap) { + static WILDCARD_REGEX: Lazy = Lazy::new(|| Regex::new("\\$([A-Z-_]+)\\$").unwrap()); + if context.is_empty() { + return; + } + // Don't want to do any extra work if there's no match. + if !WILDCARD_REGEX.is_match(path.as_os_str().as_encoded_bytes()) { + return; + } + + let mut new_path = PathBuf::with_capacity(path.capacity()); + for component in path.components() { + match component { + Component::Normal(path) => { + let haystack = path.as_encoded_bytes(); + let replaced = + WILDCARD_REGEX.replace_all(haystack, |caps: ®ex::bytes::Captures| { + let Some(name) = caps.get(1) else { + return caps[0].to_vec(); + }; + + let Ok(key) = std::str::from_utf8(name.as_bytes()) else { + return caps[0].to_vec(); + }; + if let Some(replacement) = context.get(key) { + return OsString::from(replacement.to_string()).into_encoded_bytes(); + } + return caps[0].to_vec(); + }); + + // SAFETY: The original source is valid encoded bytes, and our replacement is + // valid encoded bytes. This upholds the safety requirements of `from_encoded_bytes_unchecked`. + new_path.push(unsafe { OsStr::from_encoded_bytes_unchecked(&replaced.as_ref()) }) + } + _ => new_path.push(component), + } + } + + // If no wildcards are found within the path, or the path after replacing the wildcards does not exist on disk, the path returned will be unaffected. + if let Ok(true) = new_path.try_exists() { + *path = new_path; + } +} diff --git a/librashader-presets/src/parse/mod.rs b/librashader-presets/src/parse/mod.rs index 41d4eed..3d64398 100644 --- a/librashader-presets/src/parse/mod.rs +++ b/librashader-presets/src/parse/mod.rs @@ -4,6 +4,7 @@ use std::path::Path; use nom_locate::LocatedSpan; use std::str; +pub mod context; mod preset; mod token; mod value; @@ -12,6 +13,7 @@ pub(crate) type Span<'a> = LocatedSpan<&'a str>; pub(crate) use token::Token; use crate::error::ParsePresetError; +use crate::parse::context::{VideoDriver, WildcardContext}; use crate::parse::preset::resolve_values; use crate::parse::value::parse_preset; use crate::ShaderPreset; @@ -22,12 +24,37 @@ pub(crate) fn remove_if(values: &mut Vec, f: impl FnMut(&T) -> bool) -> Op impl ShaderPreset { /// Try to parse the shader preset at the given path. + /// + /// This will add path defaults to the wildcard resolution context. pub fn try_parse(path: impl AsRef) -> Result { - ShaderPreset::try_parse_with_context(path, HashMap::new()) + let mut context = WildcardContext::new(); + context.add_path_defaults(path.as_ref()); + let values = parse_preset(path, WildcardContext::new())?; + Ok(resolve_values(values)) } /// Try to parse the shader preset at the given path. - pub fn try_parse_with_context(path: impl AsRef, context: HashMap) -> Result { + /// + /// This will add path and driver defaults to the wildcard resolution context. + pub fn try_parse_with_driver_context( + path: impl AsRef, + driver: VideoDriver, + ) -> Result { + let mut context = WildcardContext::new(); + context.add_path_defaults(path.as_ref()); + context.add_video_driver_defaults(driver); + let values = parse_preset(path, context)?; + Ok(resolve_values(values)) + } + + /// Try to parse the shader preset at the given path, with the exact provided context. + /// + /// This function does not change any of the values in the provided context, except calculating `VID-FINAL-ROT` + /// if `CORE-REQ-ROT` and `VID-USER-ROT` is present. + pub fn try_parse_with_context( + path: impl AsRef, + context: WildcardContext, + ) -> Result { let values = parse_preset(path, context)?; Ok(resolve_values(values)) } diff --git a/librashader-presets/src/parse/value.rs b/librashader-presets/src/parse/value.rs index f4af450..ff989ea 100644 --- a/librashader-presets/src/parse/value.rs +++ b/librashader-presets/src/parse/value.rs @@ -1,5 +1,5 @@ use crate::error::{ParseErrorKind, ParsePresetError}; -use crate::parse::{remove_if, Span, Token}; +use crate::parse::{context, remove_if, Span, Token}; use crate::{ScaleFactor, ScaleType}; use nom::bytes::complete::tag; use nom::character::complete::digit1; @@ -11,12 +11,14 @@ use num_traits::cast::ToPrimitive; use crate::parse::token::do_lex; use librashader_common::{FilterMode, WrapMode}; +use rustc_hash::FxHashMap; use std::fs::File; use std::io::Read; use std::path::{Path, PathBuf}; use std::str::FromStr; use crate::extract_if::MakeExtractIf; +use crate::parse::context::WildcardContext; #[derive(Debug)] pub enum Value { @@ -154,7 +156,7 @@ pub const SHADER_MAX_REFERENCE_DEPTH: usize = 16; fn load_child_reference_strings( root_references: Vec, root_path: impl AsRef, - context: &HashMap + context: &FxHashMap, ) -> Result, ParsePresetError> { let root_path = root_path.as_ref(); @@ -170,7 +172,7 @@ fn load_child_reference_strings( // enter the current root reference_depth += 1; // canonicalize current root - apply_context(&mut reference_root, context); + context::apply_context(&mut reference_root, context); let reference_root = reference_root .canonicalize() .map_err(|e| ParsePresetError::IOError(reference_root.to_path_buf(), e))?; @@ -179,11 +181,11 @@ fn load_child_reference_strings( // println!("Resolving {referenced_paths:?} against {reference_root:?}."); for path in referenced_paths { - let mut path = reference_root - .join(path.clone()); - apply_context(&mut path, context); + let mut path = reference_root.join(path.clone()); + context::apply_context(&mut path, context); - let mut path = path.canonicalize() + let mut path = path + .canonicalize() .map_err(|e| ParsePresetError::IOError(path.clone(), e))?; // println!("Opening {:?}", path); let mut reference_contents = String::new(); @@ -209,14 +211,15 @@ fn load_child_reference_strings( Ok(reference_strings.into()) } -fn apply_context(path: &mut PathBuf, context: &HashMap) { - -} - -pub fn parse_preset(path: impl AsRef, context: HashMap) -> Result, ParsePresetError> { +pub(crate) fn parse_preset( + path: impl AsRef, + context: WildcardContext, +) -> Result, ParsePresetError> { let path = path.as_ref(); let mut path = path.to_path_buf(); - apply_context(&mut path, &context); + let context = context.to_hashmap(); + + context::apply_context(&mut path, &context); let path = path .canonicalize() @@ -235,7 +238,7 @@ pub fn parse_preset(path: impl AsRef, context: HashMap) -> pub fn parse_values( mut tokens: Vec, root_path: impl AsRef, - context: HashMap + context: FxHashMap, ) -> Result, ParsePresetError> { let mut root_path = root_path.as_ref().to_path_buf(); if root_path.is_relative() { diff --git a/librashader-presets/tests/parse_all.rs b/librashader-presets/tests/parse_all.rs index 01375be..adf85e3 100644 --- a/librashader-presets/tests/parse_all.rs +++ b/librashader-presets/tests/parse_all.rs @@ -1,5 +1,7 @@ use glob::glob; +use librashader_presets::context::{ContextItem, VideoDriver, WildcardContext}; use librashader_presets::ShaderPreset; +use std::collections::HashMap; #[test] fn parses_all_slang_presets() { @@ -17,3 +19,17 @@ fn parses_problematic() { let path = "../test/Mega_Bezel_Packs/Duimon-Mega-Bezel/Presets/Advanced/Nintendo_NDS_DREZ/NDS-[DREZ]-[Native]-[ADV]-[Guest]-[Night].slangp"; ShaderPreset::try_parse(path).expect(&format!("Failed to parse {}", path)); } + +#[test] +fn parses_wildcard() { + let path = + "../test/shaders_slang/bezel/Mega_Bezel/resource/wildcard-examples/Preset-01-Core.slangp"; + let mut context = WildcardContext::new(); + + context.add_video_driver_defaults(VideoDriver::Vulkan); + + context.append_item(ContextItem::CoreName(String::from("image display"))); + + ShaderPreset::try_parse_with_context(path, context) + .expect(&format!("Failed to parse {}", path)); +} diff --git a/librashader-reflect/src/front/glslang.rs b/librashader-reflect/src/front/glslang.rs index 4527b5a..fd3fa90 100644 --- a/librashader-reflect/src/front/glslang.rs +++ b/librashader-reflect/src/front/glslang.rs @@ -1,5 +1,5 @@ -use glslang::{CompilerOptions, ShaderInput}; use crate::error::ShaderCompileError; +use glslang::{CompilerOptions, ShaderInput}; use librashader_preprocess::ShaderSource; #[cfg(feature = "serialize")] @@ -37,27 +37,17 @@ pub(crate) fn compile_spirv( source_language: glslang::SourceLanguage::GLSL, target: glslang::Target::Vulkan { version: glslang::VulkanVersion::Vulkan1_0, - spirv_version: glslang::SpirvVersion::SPIRV1_0 + spirv_version: glslang::SpirvVersion::SPIRV1_0, }, version_profile: None, }; let vertex = glslang::ShaderSource::from(source.vertex.as_str()); - let vertex = ShaderInput::new( - &vertex, - glslang::ShaderStage::Vertex, - &options, - None, - )?; + let vertex = ShaderInput::new(&vertex, glslang::ShaderStage::Vertex, &options, None)?; let vertex = compiler.create_shader(vertex)?; let fragment = glslang::ShaderSource::from(source.fragment.as_str()); - let fragment = ShaderInput::new( - &fragment, - glslang::ShaderStage::Fragment, - &options, - None, - )?; + let fragment = ShaderInput::new(&fragment, glslang::ShaderStage::Fragment, &options, None)?; let fragment = compiler.create_shader(fragment)?; let vertex = Vec::from(vertex.compile()?);