diff --git a/.idea/src.iml b/.idea/src.iml
index c4fe321..276e6e4 100644
--- a/.idea/src.iml
+++ b/.idea/src.iml
@@ -4,6 +4,7 @@
+
diff --git a/Cargo.lock b/Cargo.lock
index 11d51fb..2897ffd 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -8,11 +8,16 @@ version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2c676a478f63e9fa2dd5368a42f28bba0d6c560b775f38583c8bbaa7fcd67c9c"
+[[package]]
+name = "librashader"
+version = "0.1.0"
+
[[package]]
name = "librashader-preprocess"
version = "0.1.0"
dependencies = [
- "librashader-presets",
+ "librashader",
+ "nom",
"thiserror",
]
diff --git a/Cargo.toml b/Cargo.toml
index 49ffb09..06e2d55 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,5 +1,6 @@
[workspace]
members = [
+ "librashader",
"librashader-presets",
"librashader-preprocess"
]
\ No newline at end of file
diff --git a/librashader-preprocess/Cargo.toml b/librashader-preprocess/Cargo.toml
index a950ed4..996d7f7 100644
--- a/librashader-preprocess/Cargo.toml
+++ b/librashader-preprocess/Cargo.toml
@@ -7,4 +7,5 @@ edition = "2021"
[dependencies]
thiserror = "1.0.37"
-librashader-presets = { path = "../librashader-presets" }
\ No newline at end of file
+nom = "7.1.1"
+librashader = { path = "../librashader"}
diff --git a/librashader-preprocess/src/include.rs b/librashader-preprocess/src/include.rs
index 1bf57a2..fae0c08 100644
--- a/librashader-preprocess/src/include.rs
+++ b/librashader-preprocess/src/include.rs
@@ -1,16 +1,20 @@
+use crate::PreprocessError;
use std::fs::File;
use std::io::Read;
-use std::str::Lines;
use std::path::Path;
-use crate::PreprocessError;
+use std::str::Lines;
-const GL_GOOGLE_CPP_STYLE_LINE_DIRECTIVE: &'static str = "#extension GL_GOOGLE_CPP_STYLE_LINE_DIRECTIVE : require";
+const GL_GOOGLE_CPP_STYLE_LINE_DIRECTIVE: &'static str =
+ "#extension GL_GOOGLE_CPP_STYLE_LINE_DIRECTIVE : require";
-trait PushLine {
+trait SourceOutput {
fn push_line(&mut self, str: &str);
+ fn mark_line(&mut self, line_no: usize, comment: &str) {
+ self.push_line(&format!("#line {} \"{}\"", line_no, comment))
+ }
}
-impl PushLine for String {
+impl SourceOutput for String {
fn push_line(&mut self, str: &str) {
self.push_str(str);
self.push('\n');
@@ -20,7 +24,8 @@ impl PushLine for String {
fn read_file(path: impl AsRef) -> Result {
let path = path.as_ref();
let mut source = String::new();
- File::open(path).and_then(|mut f| f.read_to_string(&mut source))
+ File::open(path)
+ .and_then(|mut f| f.read_to_string(&mut source))
.map_err(|e| PreprocessError::IOError(path.to_path_buf(), e))?;
Ok(source)
}
@@ -35,15 +40,15 @@ pub fn read_source(path: impl AsRef) -> Result {
if let Some(header) = lines.next() {
if !header.starts_with("#version ") {
- return Err(PreprocessError::MissingVersionHeader)
+ return Err(PreprocessError::MissingVersionHeader);
}
output.push_line(header);
} else {
- return Err(PreprocessError::UnexpectedEof)
+ return Err(PreprocessError::UnexpectedEof);
}
output.push_line(GL_GOOGLE_CPP_STYLE_LINE_DIRECTIVE);
- mark_line(2, path.file_name().and_then(|f| f.to_str()).unwrap_or(""), &mut output);
+ output.mark_line(2, path.file_name().and_then(|f| f.to_str()).unwrap_or(""));
preprocess(lines, path, &mut output)?;
Ok(output)
@@ -53,7 +58,11 @@ fn mark_line(line_no: usize, comment: &str, output: &mut String) {
output.push_line(&format!("#line {} \"{}\"", line_no, comment))
}
-fn preprocess(lines: Lines, file_name: impl AsRef, output: &mut String) -> Result<(), PreprocessError> {
+fn preprocess(
+ lines: Lines,
+ file_name: impl AsRef,
+ output: &mut String,
+) -> Result<(), PreprocessError> {
let file_name = file_name.as_ref();
let include_path = file_name.parent().unwrap();
let file_name = file_name.file_name().and_then(|f| f.to_str()).unwrap_or("");
@@ -62,7 +71,7 @@ fn preprocess(lines: Lines, file_name: impl AsRef, output: &mut String) ->
if line.starts_with("#include ") {
let include_file = line["#include ".len()..].trim().trim_matches('"');
if include_file.is_empty() {
- return Err(PreprocessError::UnexpectedEol(line_no))
+ return Err(PreprocessError::UnexpectedEol(line_no));
}
let mut include_path = include_path.to_path_buf();
@@ -72,19 +81,22 @@ fn preprocess(lines: Lines, file_name: impl AsRef, output: &mut String) ->
let source = source.trim();
let lines = source.lines();
- let include_file = include_path.file_name().and_then(|f| f.to_str()).unwrap_or("");
- mark_line(1, include_file, output);
+ let include_file = include_path
+ .file_name()
+ .and_then(|f| f.to_str())
+ .unwrap_or("");
+ output.mark_line(1, include_file);
preprocess(lines, include_path, output)?;
- mark_line(line_no + 1, file_name, output);
+ output.mark_line(line_no + 1, file_name);
continue;
}
if line.starts_with("#endif") || line.starts_with("#pragma") {
output.push_line(line);
- mark_line(line_no + 2, file_name, output);
+ output.mark_line(line_no + 2, file_name);
continue;
}
output.push_line(line)
}
Ok(())
-}
\ No newline at end of file
+}
diff --git a/librashader-preprocess/src/lib.rs b/librashader-preprocess/src/lib.rs
index f067149..3029c7b 100644
--- a/librashader-preprocess/src/lib.rs
+++ b/librashader-preprocess/src/lib.rs
@@ -1,15 +1,17 @@
mod error;
mod include;
+mod pragma;
pub use error::*;
-
#[cfg(test)]
mod test {
use crate::include::read_source;
#[test]
pub fn preprocess_file() {
- let result = read_source("../test/slang-shaders/blurs/shaders/royale/blur3x3-last-pass.slang").unwrap();
+ let result =
+ read_source("../test/slang-shaders/blurs/shaders/royale/blur3x3-last-pass.slang")
+ .unwrap();
eprintln!("{result}")
}
-}
\ No newline at end of file
+}
diff --git a/librashader-preprocess/src/pragma.rs b/librashader-preprocess/src/pragma.rs
new file mode 100644
index 0000000..96fc1d5
--- /dev/null
+++ b/librashader-preprocess/src/pragma.rs
@@ -0,0 +1,5 @@
+use librashader::ShaderParameter;
+
+pub fn parse_pragma_parameter(source: impl AsRef) -> Vec {
+
+}
\ No newline at end of file
diff --git a/librashader-presets/src/parse/mod.rs b/librashader-presets/src/parse/mod.rs
index fc904a4..a4e342f 100644
--- a/librashader-presets/src/parse/mod.rs
+++ b/librashader-presets/src/parse/mod.rs
@@ -13,14 +13,14 @@ pub(crate) use token::Token;
use crate::error::ParsePresetError;
use crate::parse::preset::resolve_values;
use crate::parse::value::parse_preset;
-use crate::Preset;
+use crate::ShaderPreset;
pub(crate) fn remove_if(values: &mut Vec, f: impl FnMut(&T) -> bool) -> Option {
values.iter().position(f).map(|idx| values.remove(idx))
}
-impl Preset {
- pub fn try_parse(path: impl AsRef) -> Result {
+impl ShaderPreset {
+ pub fn try_parse(path: impl AsRef) -> Result {
let values = parse_preset(path)?;
Ok(resolve_values(values))
}
@@ -28,14 +28,14 @@ impl Preset {
#[cfg(test)]
mod test {
- use crate::Preset;
+ use crate::ShaderPreset;
use std::path::PathBuf;
#[test]
pub fn parse_preset() {
let root =
PathBuf::from("../test/slang-shaders/ntsc/ntsc-256px-svideo.slangp");
- let basic = Preset::try_parse(root);
+ let basic = ShaderPreset::try_parse(root);
eprintln!("{:#?}", basic);
assert!(basic.is_ok());
}
diff --git a/librashader-presets/src/parse/preset.rs b/librashader-presets/src/parse/preset.rs
index 6a4c59c..76046b2 100644
--- a/librashader-presets/src/parse/preset.rs
+++ b/librashader-presets/src/parse/preset.rs
@@ -1,8 +1,8 @@
use crate::parse::remove_if;
use crate::parse::value::Value;
-use crate::{Parameter, Preset, Scale2D, Scaling, ShaderConfig, TextureConfig};
+use crate::{ParameterConfig, ShaderPreset, Scale2D, Scaling, ShaderPassConfig, TextureConfig};
-pub fn resolve_values(mut values: Vec) -> Preset {
+pub fn resolve_values(mut values: Vec) -> ShaderPreset {
let textures: Vec = values
.drain_filter(|f| matches!(*f, Value::Texture { .. }))
.map(|value| {
@@ -26,11 +26,11 @@ pub fn resolve_values(mut values: Vec) -> Preset {
}
})
.collect();
- let parameters: Vec = values
+ let parameters: Vec = values
.drain_filter(|f| matches!(*f, Value::Parameter { .. }))
.map(|value| {
if let Value::Parameter(name, value) = value {
- Parameter { name, value }
+ ParameterConfig { name, value }
} else {
unreachable!("values should be all of type parameters")
}
@@ -112,7 +112,7 @@ pub fn resolve_values(mut values: Vec) -> Preset {
scale_y = scale;
}
- let shader = ShaderConfig {
+ let shader = ShaderPassConfig {
id,
name,
alias: shader_values.iter().find_map(|f| match f {
@@ -178,7 +178,7 @@ pub fn resolve_values(mut values: Vec) -> Preset {
}
}
- Preset {
+ ShaderPreset {
shader_count,
feedback_pass,
shaders,
diff --git a/librashader-presets/src/preset.rs b/librashader-presets/src/preset.rs
index b878bcb..ecdfeb6 100644
--- a/librashader-presets/src/preset.rs
+++ b/librashader-presets/src/preset.rs
@@ -84,7 +84,7 @@ pub struct Scale2D {
}
#[derive(Debug, Clone)]
-pub struct ShaderConfig {
+pub struct ShaderPassConfig {
pub id: i32,
pub name: PathBuf,
pub alias: Option,
@@ -107,17 +107,17 @@ pub struct TextureConfig {
}
#[derive(Debug, Clone)]
-pub struct Parameter {
+pub struct ParameterConfig {
pub name: String,
pub value: f32,
}
#[derive(Debug, Clone)]
-pub struct Preset {
+pub struct ShaderPreset {
pub shader_count: i32,
pub feedback_pass: i32,
// Everything is in Vecs because the expect number of values is well below 64.
- pub shaders: Vec,
+ pub shaders: Vec,
pub textures: Vec,
- pub parameters: Vec,
+ pub parameters: Vec,
}
diff --git a/librashader/Cargo.toml b/librashader/Cargo.toml
new file mode 100644
index 0000000..7997b35
--- /dev/null
+++ b/librashader/Cargo.toml
@@ -0,0 +1,8 @@
+[package]
+name = "librashader"
+version = "0.1.0"
+edition = "2021"
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[dependencies]
diff --git a/librashader/src/lib.rs b/librashader/src/lib.rs
new file mode 100644
index 0000000..5cb8400
--- /dev/null
+++ b/librashader/src/lib.rs
@@ -0,0 +1,107 @@
+use std::convert::Infallible;
+use std::str::FromStr;
+
+pub struct ShaderSource {
+ pub vertex: String,
+ pub fragment: String,
+ pub name: Option,
+ pub parameters: Vec,
+ pub format: ShaderFormat,
+}
+
+pub struct ShaderParameter {
+ pub id: String,
+ pub description: String,
+ pub initial: f32,
+ pub minimum: f32,
+ pub maximum: f32,
+ pub step: f32,
+}
+
+#[repr(u32)]
+pub enum ShaderFormat {
+ Unknown = 0,
+
+ /* 8-bit */
+ R8Unorm,
+ R8Uint,
+ R8Sint,
+ R8G8Unorm,
+ R8G8Uint,
+ R8G8Sint,
+ R8G8B8A8Unorm,
+ R8G8B8A8Uint,
+ R8G8B8A8Sint,
+ R8G8B8A8Srgb,
+
+ /* 10-bit */
+ A2B10G10R10UnormPack32,
+ A2B10G10R10UintPack32,
+
+ /* 16-bit */
+ R16Uint,
+ R16Sint,
+ R16Sfloat,
+ R16G16Uint,
+ R16G16Sint,
+ R16G16Sfloat,
+ R16G16B16A16Uint,
+ R16G16B16A16Sint,
+ R16G16B16A16Sfloat,
+
+ /* 32-bit */
+ R32Uint,
+ R32Sint,
+ R32Sfloat,
+ R32G32Uint,
+ R32G32Sint,
+ R32G32Sfloat,
+ R32G32B32A32Uint,
+ R32G32B32A32Sint,
+ R32G32B32A32Sfloat,
+}
+
+impl FromStr for ShaderFormat {
+ type Err = Infallible;
+
+ fn from_str(s: &str) -> Result {
+ Ok(match s {
+ "UNKNOWN" => Self::Unknown,
+
+ "R8_UNORM" => Self::R8Unorm,
+ "R8_UINT" => Self::R8Uint,
+ "R8_SINT" => Self::R8Sint,
+ "R8G8_UNORM" => Self::R8G8Unorm,
+ "R8G8_UINT" => Self::R8Uint,
+ "R8G8_SINT" => Self::R8G8Sint,
+ "R8G8B8A8_UNORM" => Self::R8G8B8A8Unorm,
+ "R8G8B8A8_UINT" => Self::R8G8B8A8Uint,
+ "R8G8B8A8_SINT" => Self::R8G8B8A8Sint,
+ "R8G8B8A8_SRGB" => Self::R8G8B8A8Srgb,
+
+ "A2B10G10R10_UNORM_PACK32" => Self::A2B10G10R10UnormPack32,
+ "A2B10G10R10_UINT_PACK32" => Self::A2B10G10R10UintPack32,
+
+ "R16_UINT" => Self::R16Uint,
+ "R16_SINT" => Self::R16Sint,
+ "R16_SFLOAT" => Self::R16Sfloat,
+ "R16G16_UINT" => Self::R16G16Uint,
+ "R16G16_SINT" => Self::R16G16Sint,
+ "R16G16_SFLOAT" => Self::R16G16Sfloat,
+ "R16G16B16A16_UINT" => Self::R16G16B16A16Uint,
+ "R16G16B16A16_SINT" => Self::R16G16B16A16Sint,
+ "R16G16B16A16_SFLOAT" => Self::R16G16B16A16Sfloat,
+
+ "R32_UINT" => Self::R32Uint,
+ "R32_SINT" => Self::R32Sint,
+ "R32_SFLOAT" => Self::R32Sfloat,
+ "R32G32_UINT" => Self::R32G32Uint,
+ "R32G32_SINT" => Self::R32G32Sint,
+ "R32G32_SFLOAT" => Self::R32G32Sfloat,
+ "R32G32B32A32_UINT" => Self::R32G32A32Uint,
+ "R32G32B32A32_SINT" => Self::R32G32A32Sint,
+ "R32G32B32A32_SFLOAT" => Self::R32G32SA32float,
+ _ => Self::Unknown,
+ })
+ }
+}