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"
|
||||
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"
|
||||
|
|
|
@ -12,7 +12,6 @@ members = [
|
|||
"librashader-runtime-vk",
|
||||
"librashader-cache",
|
||||
"librashader-capi",
|
||||
"librashader-quark",
|
||||
"librashader-build-script",
|
||||
]
|
||||
|
||||
|
|
|
@ -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 = []
|
||||
|
||||
|
|
|
@ -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<u8>),
|
||||
/// Error parsing BML file.
|
||||
#[error("error parsing quark bml")]
|
||||
BmlError(#[from] bml::BmlError)
|
||||
}
|
||||
|
||||
/// The kind of error that may occur in parsing.
|
||||
|
|
|
@ -12,5 +12,7 @@
|
|||
mod error;
|
||||
mod parse;
|
||||
mod preset;
|
||||
mod quark;
|
||||
|
||||
pub use error::*;
|
||||
pub use preset::*;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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<Value>) -> ShaderPreset {
|
||||
let textures: Vec<TextureConfig> = values
|
||||
|
@ -60,9 +60,9 @@ pub fn resolve_values(mut values: Vec<Value>) -> 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<Value> = values
|
||||
.drain_filter(|v| v.shader_index() == Some(shader))
|
||||
|
@ -139,7 +139,7 @@ pub fn resolve_values(mut values: Vec<Value>) -> 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,
|
||||
|
|
|
@ -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<i32> {
|
||||
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<Path>) -> Result<Vec<Value>, ParsePresetError> {
|
||||
let path = path.as_ref();
|
||||
let path = path
|
||||
|
@ -217,6 +232,7 @@ pub fn parse_preset(path: impl AsRef<Path>) -> Result<Vec<Value>, ParsePresetErr
|
|||
parse_values(tokens, path)
|
||||
}
|
||||
|
||||
// todo: move this to slang
|
||||
pub fn parse_values(
|
||||
mut tokens: Vec<Token>,
|
||||
root_path: impl AsRef<Path>,
|
||||
|
@ -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))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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<String>,
|
||||
/// 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)]
|
||||
#[derive(Default, Copy, Clone, Debug)]
|
||||
/// 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,
|
||||
};
|
||||
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)?;
|
||||
|
|
|
@ -61,7 +61,7 @@ pub mod presets {
|
|||
let iters: Result<Vec<Vec<ShaderParameter>>, 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())
|
||||
|
|
Loading…
Reference in a new issue