presets: allow quark source paths
This commit is contained in:
parent
b00f1f92f4
commit
34b54b18e1
8
Cargo.lock
generated
8
Cargo.lock
generated
|
@ -1277,6 +1277,7 @@ dependencies = [
|
||||||
name = "librashader-presets"
|
name = "librashader-presets"
|
||||||
version = "0.1.3"
|
version = "0.1.3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"bml",
|
||||||
"glob",
|
"glob",
|
||||||
"librashader-common 0.1.3",
|
"librashader-common 0.1.3",
|
||||||
"nom",
|
"nom",
|
||||||
|
@ -1285,13 +1286,6 @@ dependencies = [
|
||||||
"thiserror",
|
"thiserror",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "librashader-quark"
|
|
||||||
version = "0.1.0"
|
|
||||||
dependencies = [
|
|
||||||
"bml",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "librashader-reflect"
|
name = "librashader-reflect"
|
||||||
version = "0.1.3"
|
version = "0.1.3"
|
||||||
|
|
|
@ -12,7 +12,6 @@ members = [
|
||||||
"librashader-runtime-vk",
|
"librashader-runtime-vk",
|
||||||
"librashader-cache",
|
"librashader-cache",
|
||||||
"librashader-capi",
|
"librashader-capi",
|
||||||
"librashader-quark",
|
|
||||||
"librashader-build-script",
|
"librashader-build-script",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,8 @@ nom_locate = "4.0.0"
|
||||||
librashader-common = { path = "../librashader-common", version = "0.1.3" }
|
librashader-common = { path = "../librashader-common", version = "0.1.3" }
|
||||||
num-traits = "0.2"
|
num-traits = "0.2"
|
||||||
|
|
||||||
|
bml = "0.3.1"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
parse_legacy_glsl = []
|
parse_legacy_glsl = []
|
||||||
|
|
||||||
|
|
|
@ -30,6 +30,9 @@ pub enum ParsePresetError {
|
||||||
/// The shader preset did not contain valid UTF-8 bytes.
|
/// The shader preset did not contain valid UTF-8 bytes.
|
||||||
#[error("expected utf8 bytes but got invalid utf8")]
|
#[error("expected utf8 bytes but got invalid utf8")]
|
||||||
Utf8Error(Vec<u8>),
|
Utf8Error(Vec<u8>),
|
||||||
|
/// Error parsing BML file.
|
||||||
|
#[error("error parsing quark bml")]
|
||||||
|
BmlError(#[from] bml::BmlError)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The kind of error that may occur in parsing.
|
/// The kind of error that may occur in parsing.
|
||||||
|
|
|
@ -12,5 +12,7 @@
|
||||||
mod error;
|
mod error;
|
||||||
mod parse;
|
mod parse;
|
||||||
mod preset;
|
mod preset;
|
||||||
|
mod quark;
|
||||||
|
|
||||||
pub use error::*;
|
pub use error::*;
|
||||||
pub use preset::*;
|
pub use preset::*;
|
||||||
|
|
|
@ -9,6 +9,9 @@ mod value;
|
||||||
|
|
||||||
pub(crate) type Span<'a> = LocatedSpan<&'a str>;
|
pub(crate) type Span<'a> = LocatedSpan<&'a str>;
|
||||||
pub(crate) use token::Token;
|
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::error::ParsePresetError;
|
||||||
use crate::parse::preset::resolve_values;
|
use crate::parse::preset::resolve_values;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use librashader_common::ImageFormat;
|
use librashader_common::ImageFormat;
|
||||||
use crate::parse::remove_if;
|
use crate::parse::{remove_if, ShaderType};
|
||||||
use crate::parse::value::Value;
|
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<Value>) -> ShaderPreset {
|
pub fn resolve_values(mut values: Vec<Value>) -> ShaderPreset {
|
||||||
let textures: Vec<TextureConfig> = values
|
let textures: Vec<TextureConfig> = values
|
||||||
|
@ -60,9 +60,9 @@ pub fn resolve_values(mut values: Vec<Value>) -> ShaderPreset {
|
||||||
.unwrap_or(0);
|
.unwrap_or(0);
|
||||||
|
|
||||||
for shader in 0..shader_count {
|
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,
|
&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<Value> = values
|
let shader_values: Vec<Value> = values
|
||||||
.drain_filter(|v| v.shader_index() == Some(shader))
|
.drain_filter(|v| v.shader_index() == Some(shader))
|
||||||
|
@ -139,7 +139,7 @@ pub fn resolve_values(mut values: Vec<Value>) -> ShaderPreset {
|
||||||
|
|
||||||
let shader = ShaderPassConfig {
|
let shader = ShaderPassConfig {
|
||||||
id,
|
id,
|
||||||
name,
|
source_path: ShaderPath::Slang(name),
|
||||||
alias: shader_values.iter().find_map(|f| match f {
|
alias: shader_values.iter().find_map(|f| match f {
|
||||||
Value::Alias(_, value) => Some(value.to_string()),
|
Value::Alias(_, value) => Some(value.to_string()),
|
||||||
_ => None,
|
_ => None,
|
||||||
|
|
|
@ -16,11 +16,25 @@ use std::io::Read;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum ShaderStage {
|
||||||
|
Fragment,
|
||||||
|
Vertex,
|
||||||
|
Geometry
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum ShaderType {
|
||||||
|
Slang,
|
||||||
|
Quark(ShaderStage)
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Value {
|
pub enum Value {
|
||||||
ShaderCount(i32),
|
ShaderCount(i32),
|
||||||
FeedbackPass(i32),
|
FeedbackPass(i32),
|
||||||
Shader(i32, PathBuf),
|
Shader(i32, ShaderType, PathBuf),
|
||||||
ScaleX(i32, ScaleFactor),
|
ScaleX(i32, ScaleFactor),
|
||||||
ScaleY(i32, ScaleFactor),
|
ScaleY(i32, ScaleFactor),
|
||||||
Scale(i32, ScaleFactor),
|
Scale(i32, ScaleFactor),
|
||||||
|
@ -47,7 +61,7 @@ pub enum Value {
|
||||||
impl Value {
|
impl Value {
|
||||||
pub(crate) fn shader_index(&self) -> Option<i32> {
|
pub(crate) fn shader_index(&self) -> Option<i32> {
|
||||||
match self {
|
match self {
|
||||||
Value::Shader(i, _) => Some(*i),
|
Value::Shader(i, _, _) => Some(*i),
|
||||||
Value::ScaleX(i, _) => Some(*i),
|
Value::ScaleX(i, _) => Some(*i),
|
||||||
Value::ScaleY(i, _) => Some(*i),
|
Value::ScaleY(i, _) => Some(*i),
|
||||||
Value::Scale(i, _) => Some(*i),
|
Value::Scale(i, _) => Some(*i),
|
||||||
|
@ -202,6 +216,7 @@ fn load_child_reference_strings(
|
||||||
Ok(reference_strings.into())
|
Ok(reference_strings.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// todo: move this to slang
|
||||||
pub fn parse_preset(path: impl AsRef<Path>) -> Result<Vec<Value>, ParsePresetError> {
|
pub fn parse_preset(path: impl AsRef<Path>) -> Result<Vec<Value>, ParsePresetError> {
|
||||||
let path = path.as_ref();
|
let path = path.as_ref();
|
||||||
let path = path
|
let path = path
|
||||||
|
@ -217,6 +232,7 @@ pub fn parse_preset(path: impl AsRef<Path>) -> Result<Vec<Value>, ParsePresetErr
|
||||||
parse_values(tokens, path)
|
parse_values(tokens, path)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// todo: move this to slang
|
||||||
pub fn parse_values(
|
pub fn parse_values(
|
||||||
mut tokens: Vec<Token>,
|
mut tokens: Vec<Token>,
|
||||||
root_path: impl AsRef<Path>,
|
root_path: impl AsRef<Path>,
|
||||||
|
@ -299,7 +315,7 @@ pub fn parse_values(
|
||||||
relative_path
|
relative_path
|
||||||
.canonicalize()
|
.canonicalize()
|
||||||
.map_err(|e| ParsePresetError::IOError(relative_path.clone(), e))?;
|
.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))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ pub struct ShaderPassConfig {
|
||||||
/// The index of the shader pass relative to its parent preset.
|
/// The index of the shader pass relative to its parent preset.
|
||||||
pub id: i32,
|
pub id: i32,
|
||||||
/// The fully qualified path to the shader pass source file.
|
/// 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.
|
/// The alias of the shader pass if available.
|
||||||
pub alias: Option<String>,
|
pub alias: Option<String>,
|
||||||
/// The filtering mode that this shader pass should expect.
|
/// 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<PathBuf>, fragment: Option<PathBuf> }
|
||||||
|
}
|
||||||
|
|
||||||
#[repr(i32)]
|
#[repr(i32)]
|
||||||
#[derive(Default, Copy, Clone, Debug)]
|
#[derive(Default, Copy, Clone, Debug)]
|
||||||
/// The scaling type for the shader pass.
|
/// The scaling type for the shader pass.
|
||||||
|
|
68
librashader-presets/src/quark/mod.rs
Normal file
68
librashader-presets/src/quark/mod.rs
Normal file
|
@ -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<Path>) -> Result<BmlNode, ParsePresetError> {
|
||||||
|
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<Vec<Value>, 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);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -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"
|
|
|
@ -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<Path>) -> Result<BmlNode, Box<dyn Error>> {
|
|
||||||
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);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -6,7 +6,7 @@ use crate::reflect::semantics::{
|
||||||
Semantic, ShaderSemantics, TextureSemantics, UniformSemantic, UniqueSemantics,
|
Semantic, ShaderSemantics, TextureSemantics, UniformSemantic, UniqueSemantics,
|
||||||
};
|
};
|
||||||
use librashader_preprocess::{PreprocessError, ShaderSource};
|
use librashader_preprocess::{PreprocessError, ShaderSource};
|
||||||
use librashader_presets::{ShaderPassConfig, TextureConfig};
|
use librashader_presets::{ShaderPassConfig, ShaderPath, TextureConfig};
|
||||||
use rustc_hash::FxHashMap;
|
use rustc_hash::FxHashMap;
|
||||||
|
|
||||||
/// Artifacts of a reflected and compiled shader pass.
|
/// Artifacts of a reflected and compiled shader pass.
|
||||||
|
@ -83,7 +83,13 @@ where
|
||||||
let passes = passes
|
let passes = passes
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|shader| {
|
.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 compiled = C::compile(&source)?;
|
||||||
let reflect = T::from_compilation(compiled)?;
|
let reflect = T::from_compilation(compiled)?;
|
||||||
|
|
|
@ -61,7 +61,7 @@ pub mod presets {
|
||||||
let iters: Result<Vec<Vec<ShaderParameter>>, PreprocessError> = preset
|
let iters: Result<Vec<Vec<ShaderParameter>>, PreprocessError> = preset
|
||||||
.shaders
|
.shaders
|
||||||
.iter()
|
.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();
|
.collect();
|
||||||
let iters = iters?;
|
let iters = iters?;
|
||||||
Ok(iters.into_iter().flatten())
|
Ok(iters.into_iter().flatten())
|
||||||
|
|
Loading…
Reference in a new issue