2023-01-17 15:09:07 +11:00
|
|
|
//! Shader preprocessing for librashader
|
2022-10-21 16:12:17 +11:00
|
|
|
mod error;
|
|
|
|
mod include;
|
2022-10-22 12:04:00 +11:00
|
|
|
mod pragma;
|
2022-10-22 17:54:06 +11:00
|
|
|
mod stage;
|
2022-10-21 16:12:17 +11:00
|
|
|
|
2022-10-23 15:59:18 +11:00
|
|
|
use crate::include::read_source;
|
2022-10-21 16:12:17 +11:00
|
|
|
pub use error::*;
|
2022-11-29 17:57:04 +11:00
|
|
|
use librashader_common::ImageFormat;
|
2023-01-16 06:06:38 +11:00
|
|
|
use rustc_hash::FxHashMap;
|
2023-01-16 10:21:01 +11:00
|
|
|
use std::path::Path;
|
2022-10-22 17:54:06 +11:00
|
|
|
|
2022-12-01 14:50:57 +11:00
|
|
|
/// The source file for a single shader pass.
|
2022-11-22 08:13:37 +11:00
|
|
|
#[derive(Debug, Clone, PartialEq)]
|
|
|
|
pub struct ShaderSource {
|
2022-12-01 14:50:57 +11:00
|
|
|
/// The source contents for the vertex shader.
|
2022-11-22 08:13:37 +11:00
|
|
|
pub vertex: String,
|
2022-12-01 14:50:57 +11:00
|
|
|
|
|
|
|
/// The source contents for the fragment shader.
|
2022-11-22 08:13:37 +11:00
|
|
|
pub fragment: String,
|
2022-12-01 14:50:57 +11:00
|
|
|
|
|
|
|
/// The alias of the shader if available.
|
2022-11-22 08:13:37 +11:00
|
|
|
pub name: Option<String>,
|
2022-12-01 14:50:57 +11:00
|
|
|
|
|
|
|
/// The list of shader parameters found in the shader source.
|
2023-01-16 06:06:38 +11:00
|
|
|
pub parameters: FxHashMap<String, ShaderParameter>,
|
2022-12-01 14:50:57 +11:00
|
|
|
|
|
|
|
/// The image format the shader expects.
|
2022-11-29 17:57:04 +11:00
|
|
|
pub format: ImageFormat,
|
2022-11-22 08:13:37 +11:00
|
|
|
}
|
|
|
|
|
2022-12-01 14:50:57 +11:00
|
|
|
/// A user tweakable parameter for the shader as declared in source.
|
2022-11-22 08:13:37 +11:00
|
|
|
#[derive(Debug, Clone, PartialEq)]
|
|
|
|
pub struct ShaderParameter {
|
2022-12-01 14:50:57 +11:00
|
|
|
/// The name of the parameter.
|
2022-11-22 08:13:37 +11:00
|
|
|
pub id: String,
|
2022-12-01 14:50:57 +11:00
|
|
|
/// The description of the parameter.
|
2022-11-22 08:13:37 +11:00
|
|
|
pub description: String,
|
2022-12-01 14:50:57 +11:00
|
|
|
/// The initial value the parameter is set to.
|
2022-11-22 08:13:37 +11:00
|
|
|
pub initial: f32,
|
2022-12-01 14:50:57 +11:00
|
|
|
/// The minimum value that the parameter can be set to.
|
2022-11-22 08:13:37 +11:00
|
|
|
pub minimum: f32,
|
2022-12-01 14:50:57 +11:00
|
|
|
/// The maximum value that the parameter can be set to.
|
2022-11-22 08:13:37 +11:00
|
|
|
pub maximum: f32,
|
2022-12-01 14:50:57 +11:00
|
|
|
/// The step by which this parameter can be incremented or decremented.
|
2022-11-22 08:13:37 +11:00
|
|
|
pub step: f32,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl ShaderSource {
|
2022-12-01 14:50:57 +11:00
|
|
|
/// Load the source file at the given path, resolving includes relative to the location of the
|
|
|
|
/// source file.
|
2022-11-22 08:13:37 +11:00
|
|
|
pub fn load(path: impl AsRef<Path>) -> Result<ShaderSource, PreprocessError> {
|
|
|
|
load_shader_source(path)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-10-22 17:54:06 +11:00
|
|
|
pub(crate) trait SourceOutput {
|
|
|
|
fn push_line(&mut self, str: &str);
|
|
|
|
fn mark_line(&mut self, line_no: usize, comment: &str) {
|
2022-10-23 15:59:18 +11:00
|
|
|
#[cfg(feature = "line_directives")]
|
2022-10-22 17:54:06 +11:00
|
|
|
self.push_line(&format!("#line {} \"{}\"", line_no, comment))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl SourceOutput for String {
|
|
|
|
fn push_line(&mut self, str: &str) {
|
|
|
|
self.push_str(str);
|
|
|
|
self.push('\n');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-11-22 08:13:37 +11:00
|
|
|
pub(crate) fn load_shader_source(path: impl AsRef<Path>) -> Result<ShaderSource, PreprocessError> {
|
2022-10-22 17:54:06 +11:00
|
|
|
let source = read_source(path)?;
|
|
|
|
let meta = pragma::parse_pragma_meta(&source)?;
|
|
|
|
let text = stage::process_stages(&source)?;
|
2023-01-16 10:21:01 +11:00
|
|
|
let parameters = FxHashMap::from_iter(meta.parameters.into_iter().map(|p| (p.id.clone(), p)));
|
2022-10-22 17:54:06 +11:00
|
|
|
|
|
|
|
Ok(ShaderSource {
|
|
|
|
vertex: text.vertex,
|
|
|
|
fragment: text.fragment,
|
|
|
|
name: meta.name,
|
2023-01-16 06:06:38 +11:00
|
|
|
parameters,
|
2022-10-22 17:54:06 +11:00
|
|
|
format: meta.format,
|
|
|
|
})
|
|
|
|
}
|
2022-10-21 16:12:17 +11:00
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
mod test {
|
|
|
|
use crate::include::read_source;
|
2022-10-22 17:54:06 +11:00
|
|
|
use crate::{load_shader_source, pragma};
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
pub fn load_file() {
|
2022-10-23 15:59:18 +11:00
|
|
|
let result = load_shader_source(
|
|
|
|
"../test/slang-shaders/blurs/shaders/royale/blur3x3-last-pass.slang",
|
|
|
|
)
|
|
|
|
.unwrap();
|
|
|
|
eprintln!("{:#}", result.vertex)
|
2022-10-22 17:54:06 +11:00
|
|
|
}
|
2022-10-22 14:37:47 +11:00
|
|
|
|
2022-10-21 16:12:17 +11:00
|
|
|
#[test]
|
|
|
|
pub fn preprocess_file() {
|
2022-10-22 12:04:00 +11:00
|
|
|
let result =
|
|
|
|
read_source("../test/slang-shaders/blurs/shaders/royale/blur3x3-last-pass.slang")
|
|
|
|
.unwrap();
|
2022-10-21 16:12:17 +11:00
|
|
|
eprintln!("{result}")
|
|
|
|
}
|
2022-10-22 14:37:47 +11:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
pub fn get_param_pragmas() {
|
2022-10-23 15:59:18 +11:00
|
|
|
let result = read_source(
|
|
|
|
"../test/slang-shaders/crt/shaders/crt-maximus-royale/src/ntsc_pass1.slang",
|
|
|
|
)
|
|
|
|
.unwrap();
|
2022-10-22 14:37:47 +11:00
|
|
|
|
2022-10-23 15:59:18 +11:00
|
|
|
let params = pragma::parse_pragma_meta(result).unwrap();
|
2022-10-22 14:37:47 +11:00
|
|
|
eprintln!("{params:?}")
|
|
|
|
}
|
2022-10-22 12:04:00 +11:00
|
|
|
}
|