From 34b54b18e119dd1e456190749cb279c34409d605 Mon Sep 17 00:00:00 2001 From: chyyran Date: Thu, 23 Feb 2023 22:55:39 -0500 Subject: [PATCH] presets: allow quark source paths --- Cargo.lock | 8 +-- Cargo.toml | 1 - librashader-presets/Cargo.toml | 2 + librashader-presets/src/error.rs | 3 + librashader-presets/src/lib.rs | 2 + librashader-presets/src/parse/mod.rs | 3 + librashader-presets/src/parse/preset.rs | 10 ++-- librashader-presets/src/parse/value.rs | 22 ++++++- librashader-presets/src/preset.rs | 11 +++- librashader-presets/src/quark/mod.rs | 68 ++++++++++++++++++++++ librashader-quark/Cargo.toml | 9 --- librashader-quark/src/lib.rs | 40 ------------- librashader-reflect/src/reflect/presets.rs | 10 +++- librashader/src/lib.rs | 2 +- 14 files changed, 122 insertions(+), 69 deletions(-) create mode 100644 librashader-presets/src/quark/mod.rs delete mode 100644 librashader-quark/Cargo.toml delete mode 100644 librashader-quark/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index 191f7e3..569fab8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1277,6 +1277,7 @@ dependencies = [ name = "librashader-presets" version = "0.1.3" dependencies = [ + "bml", "glob", "librashader-common 0.1.3", "nom", @@ -1285,13 +1286,6 @@ dependencies = [ "thiserror", ] -[[package]] -name = "librashader-quark" -version = "0.1.0" -dependencies = [ - "bml", -] - [[package]] name = "librashader-reflect" version = "0.1.3" diff --git a/Cargo.toml b/Cargo.toml index 05e163c..24d3fb9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,7 +12,6 @@ members = [ "librashader-runtime-vk", "librashader-cache", "librashader-capi", - "librashader-quark", "librashader-build-script", ] diff --git a/librashader-presets/Cargo.toml b/librashader-presets/Cargo.toml index 32a89ce..e11d22e 100644 --- a/librashader-presets/Cargo.toml +++ b/librashader-presets/Cargo.toml @@ -18,6 +18,8 @@ nom_locate = "4.0.0" librashader-common = { path = "../librashader-common", version = "0.1.3" } num-traits = "0.2" +bml = "0.3.1" + [features] parse_legacy_glsl = [] diff --git a/librashader-presets/src/error.rs b/librashader-presets/src/error.rs index 795a19d..803c57e 100644 --- a/librashader-presets/src/error.rs +++ b/librashader-presets/src/error.rs @@ -30,6 +30,9 @@ pub enum ParsePresetError { /// The shader preset did not contain valid UTF-8 bytes. #[error("expected utf8 bytes but got invalid utf8")] Utf8Error(Vec), + /// Error parsing BML file. + #[error("error parsing quark bml")] + BmlError(#[from] bml::BmlError) } /// The kind of error that may occur in parsing. diff --git a/librashader-presets/src/lib.rs b/librashader-presets/src/lib.rs index 46ff435..4831693 100644 --- a/librashader-presets/src/lib.rs +++ b/librashader-presets/src/lib.rs @@ -12,5 +12,7 @@ mod error; mod parse; mod preset; +mod quark; + pub use error::*; pub use preset::*; diff --git a/librashader-presets/src/parse/mod.rs b/librashader-presets/src/parse/mod.rs index 88afc9f..693c53f 100644 --- a/librashader-presets/src/parse/mod.rs +++ b/librashader-presets/src/parse/mod.rs @@ -9,6 +9,9 @@ mod value; pub(crate) type Span<'a> = LocatedSpan<&'a str>; pub(crate) use token::Token; +pub(crate) use value::Value; +pub(crate) use value::ShaderType; +pub(crate) use value::ShaderStage; use crate::error::ParsePresetError; use crate::parse::preset::resolve_values; diff --git a/librashader-presets/src/parse/preset.rs b/librashader-presets/src/parse/preset.rs index 1d1c041..8206a03 100644 --- a/librashader-presets/src/parse/preset.rs +++ b/librashader-presets/src/parse/preset.rs @@ -1,7 +1,7 @@ use librashader_common::ImageFormat; -use crate::parse::remove_if; +use crate::parse::{remove_if, ShaderType}; use crate::parse::value::Value; -use crate::{ParameterConfig, Scale2D, Scaling, ShaderPassConfig, ShaderPreset, TextureConfig}; +use crate::{ParameterConfig, Scale2D, Scaling, ShaderPassConfig, ShaderPath, ShaderPreset, TextureConfig}; pub fn resolve_values(mut values: Vec) -> ShaderPreset { let textures: Vec = values @@ -60,9 +60,9 @@ pub fn resolve_values(mut values: Vec) -> ShaderPreset { .unwrap_or(0); for shader in 0..shader_count { - if let Some(Value::Shader(id, name)) = remove_if( + if let Some(Value::Shader(id, ShaderType::Slang, name)) = remove_if( &mut values, - |v| matches!(*v, Value::Shader(shader_index, _) if shader_index == shader), + |v| matches!(*v, Value::Shader(shader_index, ShaderType::Slang, _) if shader_index == shader), ) { let shader_values: Vec = values .drain_filter(|v| v.shader_index() == Some(shader)) @@ -139,7 +139,7 @@ pub fn resolve_values(mut values: Vec) -> ShaderPreset { let shader = ShaderPassConfig { id, - name, + source_path: ShaderPath::Slang(name), alias: shader_values.iter().find_map(|f| match f { Value::Alias(_, value) => Some(value.to_string()), _ => None, diff --git a/librashader-presets/src/parse/value.rs b/librashader-presets/src/parse/value.rs index b82b067..59094a7 100644 --- a/librashader-presets/src/parse/value.rs +++ b/librashader-presets/src/parse/value.rs @@ -16,11 +16,25 @@ use std::io::Read; use std::path::{Path, PathBuf}; use std::str::FromStr; + +#[derive(Debug)] +pub enum ShaderStage { + Fragment, + Vertex, + Geometry +} + +#[derive(Debug)] +pub enum ShaderType { + Slang, + Quark(ShaderStage) +} + #[derive(Debug)] pub enum Value { ShaderCount(i32), FeedbackPass(i32), - Shader(i32, PathBuf), + Shader(i32, ShaderType, PathBuf), ScaleX(i32, ScaleFactor), ScaleY(i32, ScaleFactor), Scale(i32, ScaleFactor), @@ -47,7 +61,7 @@ pub enum Value { impl Value { pub(crate) fn shader_index(&self) -> Option { match self { - Value::Shader(i, _) => Some(*i), + Value::Shader(i, _, _) => Some(*i), Value::ScaleX(i, _) => Some(*i), Value::ScaleY(i, _) => Some(*i), Value::Scale(i, _) => Some(*i), @@ -202,6 +216,7 @@ fn load_child_reference_strings( Ok(reference_strings.into()) } +// todo: move this to slang pub fn parse_preset(path: impl AsRef) -> Result, ParsePresetError> { let path = path.as_ref(); let path = path @@ -217,6 +232,7 @@ pub fn parse_preset(path: impl AsRef) -> Result, ParsePresetErr parse_values(tokens, path) } +// todo: move this to slang pub fn parse_values( mut tokens: Vec, root_path: impl AsRef, @@ -299,7 +315,7 @@ pub fn parse_values( relative_path .canonicalize() .map_err(|e| ParsePresetError::IOError(relative_path.clone(), e))?; - values.push(Value::Shader(index, relative_path)) + values.push(Value::Shader(index, ShaderType::Slang, relative_path)) } } diff --git a/librashader-presets/src/preset.rs b/librashader-presets/src/preset.rs index ff37252..ef7d402 100644 --- a/librashader-presets/src/preset.rs +++ b/librashader-presets/src/preset.rs @@ -10,7 +10,7 @@ pub struct ShaderPassConfig { /// The index of the shader pass relative to its parent preset. pub id: i32, /// The fully qualified path to the shader pass source file. - pub name: PathBuf, + pub source_path: ShaderPath, /// The alias of the shader pass if available. pub alias: Option, /// The filtering mode that this shader pass should expect. @@ -41,6 +41,15 @@ impl ShaderPassConfig { } } +#[derive(Clone, Debug)] +/// The path to a shader. +pub enum ShaderPath { + /// Slang combined shader + Slang(PathBuf), + /// Quark split vertex/fragment shaders. + Quark { vertex: Option, fragment: Option } +} + #[repr(i32)] #[derive(Default, Copy, Clone, Debug)] /// The scaling type for the shader pass. diff --git a/librashader-presets/src/quark/mod.rs b/librashader-presets/src/quark/mod.rs new file mode 100644 index 0000000..dbb01cb --- /dev/null +++ b/librashader-presets/src/quark/mod.rs @@ -0,0 +1,68 @@ +use std::error::Error; +use std::fs::File; +use std::io::Read; +use std::path::{Path, PathBuf}; +use std::str::FromStr; +use bml::BmlNode; +use librashader_common::FilterMode; +use crate::parse::{ShaderStage, ShaderType, Value}; +use crate::ParsePresetError; + +fn parse_bml_node(path: impl AsRef) -> Result { + let path = path.as_ref(); + let path = path + .canonicalize() + .map_err(|e| ParsePresetError::IOError(path.to_path_buf(), e))?; + + let mut manifest_path = path.join("manifest.bml"); + let mut contents = String::new(); + File::open(&manifest_path) + .and_then(|mut f| f.read_to_string(&mut contents)) + .map_err(|e| ParsePresetError::IOError(path.to_path_buf(), e))?; + // BML expects a newline. + contents.push_str("\n"); + let contents = contents.to_string(); + Ok(bml::BmlNode::try_from(&*contents)?) +} + +fn parse_values(node: &BmlNode) -> Result, ParsePresetError>{ + let programs = node.named("program"); + let program_len = programs.len(); + let mut values = Vec::new(); + for (index, programs) in programs.chain(node.named("output")).enumerate() { + if let Some(filter) = programs.named("filter").next() { + // NOPANIC: infallible + values.push(Value::FilterMode(index as i32, FilterMode::from_str(filter.value().trim()).unwrap())) + } + if let Some(vertex) = programs.named("vertex").next() { + values.push(Value::Shader(index as i32, ShaderType::Quark(ShaderStage::Vertex), PathBuf::from_str(vertex.value().trim()) + .expect("Infallible"))) + } + if let Some(fragment) = programs.named("fragment").next() { + values.push(Value::Shader(index as i32, ShaderType::Quark(ShaderStage::Fragment), PathBuf::from_str(fragment.value().trim()) + .expect("Infallible"))) + } + + } + + + eprintln!("{values:?}"); + + Ok(values) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn parse_shader() { + let preset = parse_bml_node("../test/quark-shaders/CRT-Royale.shader").unwrap(); + let values = parse_values(&preset); + for program in preset.named("program").chain(preset.named("output")) { + eprintln!("{:?}", program); + + } + + } +} \ No newline at end of file diff --git a/librashader-quark/Cargo.toml b/librashader-quark/Cargo.toml deleted file mode 100644 index 42589df..0000000 --- a/librashader-quark/Cargo.toml +++ /dev/null @@ -1,9 +0,0 @@ -[package] -name = "librashader-quark" -version = "0.1.0" -edition = "2021" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -bml = "0.3.1" \ No newline at end of file diff --git a/librashader-quark/src/lib.rs b/librashader-quark/src/lib.rs deleted file mode 100644 index f457c4b..0000000 --- a/librashader-quark/src/lib.rs +++ /dev/null @@ -1,40 +0,0 @@ -use std::error::Error; -use std::fs::File; -use std::io::Read; -use std::path::Path; -use bml::BmlNode; - -pub fn add(left: usize, right: usize) -> usize { - left + right -} - -pub fn parse_preset(path: impl AsRef) -> Result> { - let path = path.as_ref(); - let path = path - .canonicalize()?; - - let mut manifest_path = path.join("manifest.bml"); - let mut contents = String::new(); - File::open(&manifest_path) - .and_then(|mut f| f.read_to_string(&mut contents))?; - // BML expects a newline. - contents.push_str("\n"); - let contents = contents.to_string(); - Ok(bml::BmlNode::try_from(&*contents)?) -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn parse_shader() { - let preset = parse_preset("../test/quark-shaders/CRT-Royale.shader").unwrap(); - - for program in preset.named("program") { - eprintln!("{:?}", program); - - } - - } -} diff --git a/librashader-reflect/src/reflect/presets.rs b/librashader-reflect/src/reflect/presets.rs index 31c9a60..213ceca 100644 --- a/librashader-reflect/src/reflect/presets.rs +++ b/librashader-reflect/src/reflect/presets.rs @@ -6,7 +6,7 @@ use crate::reflect::semantics::{ Semantic, ShaderSemantics, TextureSemantics, UniformSemantic, UniqueSemantics, }; use librashader_preprocess::{PreprocessError, ShaderSource}; -use librashader_presets::{ShaderPassConfig, TextureConfig}; +use librashader_presets::{ShaderPassConfig, ShaderPath, TextureConfig}; use rustc_hash::FxHashMap; /// Artifacts of a reflected and compiled shader pass. @@ -83,7 +83,13 @@ where let passes = passes .into_iter() .map(|shader| { - let source: ShaderSource = ShaderSource::load(&shader.name)?; + + let source = match &shader.source_path { + ShaderPath::Slang(source_path) => ShaderSource::load(source_path)?, + ShaderPath::Quark { vertex, fragment } => { + panic!("quark shaders not implemented") + } + }; let compiled = C::compile(&source)?; let reflect = T::from_compilation(compiled)?; diff --git a/librashader/src/lib.rs b/librashader/src/lib.rs index 555381d..4d3c348 100644 --- a/librashader/src/lib.rs +++ b/librashader/src/lib.rs @@ -61,7 +61,7 @@ pub mod presets { let iters: Result>, PreprocessError> = preset .shaders .iter() - .map(|s| ShaderSource::load(&s.name).map(|s| s.parameters.into_values().collect())) + .map(|s| ShaderSource::load(&s.source_path).map(|s| s.parameters.into_values().collect())) .collect(); let iters = iters?; Ok(iters.into_iter().flatten())