presets: finish quark preset parser to values IR
This commit is contained in:
parent
e522421df2
commit
b648892090
|
@ -5,4 +5,4 @@ pub fn main() {
|
|||
println!("cargo:rustc-link-arg=/DELAYLOAD:dxcompiler.dll");
|
||||
println!("cargo:rustc-link-arg=/DELAYLOAD:d3d12.dll");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@ pub enum ParsePresetError {
|
|||
Utf8Error(Vec<u8>),
|
||||
/// Error parsing BML file.
|
||||
#[error("error parsing quark bml")]
|
||||
BmlError(#[from] bml::BmlError)
|
||||
BmlError(#[from] bml::BmlError),
|
||||
}
|
||||
|
||||
/// The kind of error that may occur in parsing.
|
||||
|
|
|
@ -2,14 +2,14 @@ use std::path::Path;
|
|||
|
||||
mod value;
|
||||
|
||||
pub(crate) use value::Value;
|
||||
pub(crate) use value::ShaderType;
|
||||
pub(crate) use value::ShaderStage;
|
||||
pub(crate) use value::ShaderType;
|
||||
pub(crate) use value::Value;
|
||||
|
||||
use crate::error::ParsePresetError;
|
||||
use value::resolve_values;
|
||||
use crate::slang::parse_preset;
|
||||
use crate::ShaderPreset;
|
||||
use value::resolve_values;
|
||||
|
||||
impl ShaderPreset {
|
||||
/// Try to parse the shader preset at the given path.
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
use crate::{ParameterConfig, remove_if, Scale2D, ScaleFactor, ScaleType, Scaling, ShaderPassConfig, ShaderPath, ShaderPreset, TextureConfig};
|
||||
use crate::{
|
||||
remove_if, ParameterConfig, Scale2D, ScaleFactor, ScaleType, Scaling, ShaderPassConfig,
|
||||
ShaderPath, ShaderPreset, TextureConfig,
|
||||
};
|
||||
use librashader_common::{FilterMode, ImageFormat, WrapMode};
|
||||
use std::path::PathBuf;
|
||||
|
||||
|
@ -6,13 +9,13 @@ use std::path::PathBuf;
|
|||
pub enum ShaderStage {
|
||||
Fragment,
|
||||
Vertex,
|
||||
Geometry
|
||||
Geometry,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum ShaderType {
|
||||
Slang,
|
||||
Quark(ShaderStage)
|
||||
Quark(ShaderStage),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -193,13 +196,19 @@ pub fn resolve_values(mut values: Vec<Value>) -> ShaderPreset {
|
|||
})
|
||||
.unwrap_or(false);
|
||||
|
||||
let framebuffer_format = if srgb_frambuffer {
|
||||
Some(ImageFormat::R8G8B8A8Srgb)
|
||||
} else if float_framebuffer {
|
||||
Some(ImageFormat::R16G16B16A16Sfloat)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let framebuffer_format_override = shader_values
|
||||
.iter()
|
||||
.find_map(|f| match f {
|
||||
Value::FormatOverride(_, value) => Some(Some(*value)),
|
||||
_ => None,
|
||||
})
|
||||
.unwrap_or(if srgb_frambuffer {
|
||||
Some(ImageFormat::R8G8B8A8Srgb)
|
||||
} else if float_framebuffer {
|
||||
Some(ImageFormat::R16G16B16A16Sfloat)
|
||||
} else {
|
||||
None
|
||||
});
|
||||
|
||||
let shader = ShaderPassConfig {
|
||||
id,
|
||||
|
@ -229,7 +238,7 @@ pub fn resolve_values(mut values: Vec<Value>) -> ShaderPreset {
|
|||
_ => None,
|
||||
})
|
||||
.unwrap_or(0),
|
||||
framebuffer_format_override: framebuffer_format,
|
||||
framebuffer_format_override,
|
||||
mipmap_input: shader_values
|
||||
.iter()
|
||||
.find_map(|f| match f {
|
||||
|
|
|
@ -47,7 +47,10 @@ pub enum ShaderPath {
|
|||
/// Slang combined shader
|
||||
Slang(PathBuf),
|
||||
/// Quark split vertex/fragment shaders.
|
||||
Quark { vertex: Option<PathBuf>, fragment: Option<PathBuf> }
|
||||
Quark {
|
||||
vertex: Option<PathBuf>,
|
||||
fragment: Option<PathBuf>,
|
||||
},
|
||||
}
|
||||
|
||||
#[repr(i32)]
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
use std::f32;
|
||||
use crate::parse::{ShaderStage, ShaderType, Value};
|
||||
use crate::{ParseErrorKind, ParsePresetError, ScaleFactor, ScaleType};
|
||||
use bml::BmlNode;
|
||||
use librashader_common::{FilterMode, ImageFormat, WrapMode};
|
||||
use std::fs::File;
|
||||
use std::io::Read;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::str::FromStr;
|
||||
use bml::BmlNode;
|
||||
use librashader_common::{FilterMode, ImageFormat, WrapMode};
|
||||
use crate::parse::{ShaderStage, ShaderType, Value};
|
||||
use crate::{ParseErrorKind, ParsePresetError};
|
||||
|
||||
fn parse_bml_node(path: impl AsRef<Path>) -> Result<BmlNode, ParsePresetError> {
|
||||
let path = path.as_ref();
|
||||
|
@ -24,19 +25,97 @@ fn parse_bml_node(path: impl AsRef<Path>) -> Result<BmlNode, ParsePresetError> {
|
|||
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();
|
||||
|
||||
|
||||
fn parse_scale(scale: &str) -> Result<(ScaleType, ScaleFactor), ParsePresetError> {
|
||||
if scale.ends_with("%") {
|
||||
let value = f32::from_str(scale.trim_end_matches("%"))
|
||||
.map_err(|_| {
|
||||
eprintln!("{scale}");
|
||||
ParsePresetError::ParserError {
|
||||
offset: 0,
|
||||
row: 0,
|
||||
col: 0,
|
||||
kind: ParseErrorKind::UnsignedInt,
|
||||
}
|
||||
})? as f32 / 100.0;
|
||||
|
||||
Ok((ScaleType::Input, ScaleFactor::Float(value)))
|
||||
} else {
|
||||
// allowed to end in " px"
|
||||
let value = i32::from_str(scale.trim_end_matches(" px"))
|
||||
.map_err(|_| {
|
||||
eprintln!("{scale}");
|
||||
ParsePresetError::ParserError {
|
||||
offset: 0,
|
||||
row: 0,
|
||||
col: 0,
|
||||
kind: ParseErrorKind::UnsignedInt,
|
||||
}
|
||||
})?;
|
||||
|
||||
Ok((ScaleType::Absolute, ScaleFactor::Absolute(value)))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fn parse_values(node: &BmlNode, root: impl AsRef<Path>) -> Result<Vec<Value>, ParsePresetError> {
|
||||
let mut values = Vec::new();
|
||||
for (index, programs) in programs.chain(node.named("output")).enumerate() {
|
||||
if let Some(filter) = programs.named("filter").next() {
|
||||
|
||||
for (index, (name, program)) in node.nodes().enumerate() {
|
||||
eprintln!("{}, {:?}", name, program);
|
||||
|
||||
if let Some(filter) = program.named("filter").next() {
|
||||
// NOPANIC: infallible
|
||||
values.push(Value::FilterMode(index as i32, FilterMode::from_str(filter.value().trim()).unwrap()))
|
||||
values.push(Value::FilterMode(
|
||||
index as i32,
|
||||
FilterMode::from_str(filter.value().trim()).unwrap(),
|
||||
))
|
||||
}
|
||||
if let Some(wrap) = programs.named("wrap").next() {
|
||||
values.push(Value::WrapMode(index as i32, WrapMode::from_str(wrap.value().trim()).unwrap()))
|
||||
if let Some(wrap) = program.named("wrap").next() {
|
||||
values.push(Value::WrapMode(
|
||||
index as i32,
|
||||
WrapMode::from_str(wrap.value().trim()).unwrap(),
|
||||
))
|
||||
}
|
||||
if let Some(format) = programs.named("format").next() {
|
||||
|
||||
if let Some(height) = program.named("height").next() {
|
||||
let height = height.value().trim();
|
||||
let (scale_type, factor) = parse_scale(height)?;
|
||||
values.push(Value::ScaleTypeY(
|
||||
index as i32,
|
||||
scale_type,
|
||||
));
|
||||
values.push(Value::ScaleY(
|
||||
index as i32,
|
||||
factor,
|
||||
))
|
||||
} else if name != "input" {
|
||||
values.push(Value::ScaleTypeY(
|
||||
index as i32,
|
||||
ScaleType::Viewport,
|
||||
))
|
||||
}
|
||||
|
||||
if let Some(width) = program.named("width").next() {
|
||||
let width = width.value().trim();
|
||||
let (scale_type, factor) = parse_scale(width)?;
|
||||
values.push(Value::ScaleTypeY(
|
||||
index as i32,
|
||||
scale_type,
|
||||
));
|
||||
values.push(Value::ScaleY(
|
||||
index as i32,
|
||||
factor,
|
||||
))
|
||||
} else if name != "input" {
|
||||
values.push(Value::ScaleTypeY(
|
||||
index as i32,
|
||||
ScaleType::Viewport,
|
||||
))
|
||||
}
|
||||
|
||||
if let Some(format) = program.named("format").next() {
|
||||
let format = match format.value() {
|
||||
"rgba8" => ImageFormat::R8G8B8A8Unorm,
|
||||
"rgb10a2" => ImageFormat::A2B10G10R10UnormPack32,
|
||||
|
@ -53,9 +132,11 @@ fn parse_values(node: &BmlNode) -> Result<Vec<Value>, ParsePresetError>{
|
|||
|
||||
values.push(Value::FormatOverride(index as i32, format));
|
||||
}
|
||||
if let Some(modulo) = programs.named("modulo").next() {
|
||||
let modulo = u32::from_str(modulo.value())
|
||||
.map_err(|_| ParsePresetError::ParserError {
|
||||
|
||||
|
||||
if let Some(modulo) = program.named("modulo").next() {
|
||||
let modulo =
|
||||
u32::from_str(modulo.value()).map_err(|_| ParsePresetError::ParserError {
|
||||
offset: index,
|
||||
row: 0,
|
||||
col: 0,
|
||||
|
@ -63,33 +144,62 @@ fn parse_values(node: &BmlNode) -> Result<Vec<Value>, ParsePresetError>{
|
|||
})?;
|
||||
values.push(Value::FrameCountMod(index as i32, modulo))
|
||||
}
|
||||
if let Some(vertex) = programs.named("vertex").next() {
|
||||
let path = PathBuf::from_str(vertex.value().trim())
|
||||
.expect("Infallible");
|
||||
let path = path.canonicalize()
|
||||
|
||||
|
||||
|
||||
if let Some(vertex) = program.named("vertex").next() {
|
||||
let mut path = root.as_ref().to_path_buf();
|
||||
path.push(vertex.value());
|
||||
let path = path
|
||||
.canonicalize()
|
||||
.map_err(|e| ParsePresetError::IOError(path.to_path_buf(), e))?;
|
||||
|
||||
values.push(Value::Shader(index as i32, ShaderType::Quark(ShaderStage::Vertex), path))
|
||||
}
|
||||
if let Some(fragment) = programs.named("fragment").next() {
|
||||
let path = PathBuf::from_str(fragment.value().trim())
|
||||
.expect("Infallible");
|
||||
let path = path.canonicalize()
|
||||
.map_err(|e| ParsePresetError::IOError(path.to_path_buf(), e))?;
|
||||
|
||||
|
||||
values.push(Value::Shader(index as i32, ShaderType::Quark(ShaderStage::Fragment), path))
|
||||
values.push(Value::Shader(
|
||||
index as i32,
|
||||
ShaderType::Quark(ShaderStage::Vertex),
|
||||
path,
|
||||
))
|
||||
}
|
||||
|
||||
|
||||
if let Some(fragment) = program.named("fragment").next() {
|
||||
let mut path = root.as_ref().to_path_buf();
|
||||
path.push(fragment.value());
|
||||
|
||||
let path = path
|
||||
.canonicalize()
|
||||
.map_err(|e| ParsePresetError::IOError(path.to_path_buf(), e))?;
|
||||
|
||||
values.push(Value::Shader(
|
||||
index as i32,
|
||||
ShaderType::Quark(ShaderStage::Fragment),
|
||||
path,
|
||||
))
|
||||
}
|
||||
|
||||
for (index, texture) in program.named("pixmap").enumerate() {
|
||||
let mut path = root.as_ref().to_path_buf();
|
||||
path.push(texture.value());
|
||||
let path = path
|
||||
.canonicalize()
|
||||
.map_err(|e| ParsePresetError::IOError(path.to_path_buf(), e))?;
|
||||
|
||||
values.push(Value::Texture {
|
||||
name: index.to_string(),
|
||||
filter_mode: texture.named("filter")
|
||||
.next()
|
||||
.map(|filter| FilterMode::from_str(filter.value().trim()).unwrap())
|
||||
.unwrap_or_default(),
|
||||
wrap_mode: texture.named("wrap")
|
||||
.next()
|
||||
.map(|wrap| WrapMode::from_str(wrap.value().trim()).unwrap())
|
||||
.unwrap_or_default(),
|
||||
mipmap: false,
|
||||
path,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
eprintln!("{values:?}");
|
||||
|
||||
Ok(values)
|
||||
}
|
||||
|
||||
|
@ -100,11 +210,8 @@ mod tests {
|
|||
#[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);
|
||||
|
||||
}
|
||||
let values = parse_values(&preset, "../test/quark-shaders/CRT-Royale.shader");
|
||||
eprintln!("{values:#?}");
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,4 +6,3 @@ pub(crate) type Span<'a> = LocatedSpan<&'a str>;
|
|||
use nom_locate::LocatedSpan;
|
||||
pub use parse::parse_preset;
|
||||
pub use parse::parse_values;
|
||||
|
||||
|
|
|
@ -1,18 +1,18 @@
|
|||
use crate::parse::{ShaderType, Value};
|
||||
use crate::slang::token::{do_lex, Token};
|
||||
use crate::slang::Span;
|
||||
use crate::{remove_if, ParseErrorKind, ParsePresetError, ScaleFactor, ScaleType};
|
||||
use librashader_common::{FilterMode, WrapMode};
|
||||
use nom::bytes::complete::tag;
|
||||
use nom::character::complete::digit1;
|
||||
use nom::combinator::{eof, map_res};
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::fs::File;
|
||||
use librashader_common::{FilterMode, WrapMode};
|
||||
use std::collections::VecDeque;
|
||||
use std::str::FromStr;
|
||||
use std::io::Read;
|
||||
use nom::IResult;
|
||||
use num_traits::ToPrimitive;
|
||||
use crate::{ParseErrorKind, ParsePresetError, remove_if, ScaleFactor, ScaleType};
|
||||
use crate::parse::{ShaderType, Value};
|
||||
use crate::slang::Span;
|
||||
use crate::slang::token::{do_lex, Token};
|
||||
use std::collections::VecDeque;
|
||||
use std::fs::File;
|
||||
use std::io::Read;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::str::FromStr;
|
||||
|
||||
fn from_int(input: Span) -> Result<i32, ParsePresetError> {
|
||||
// Presets like to commit ✨CRIMES✨ and end their lines with a ";".
|
||||
|
|
|
@ -6,12 +6,12 @@ use nom::character::complete::{char, line_ending, multispace1, not_line_ending};
|
|||
use nom::combinator::{eof, map_res, value};
|
||||
use nom::error::{ErrorKind, ParseError};
|
||||
|
||||
use crate::slang::Span;
|
||||
use nom::sequence::delimited;
|
||||
use nom::{
|
||||
bytes::complete::tag, character::complete::multispace0, IResult, InputIter, InputLength,
|
||||
InputTake,
|
||||
};
|
||||
use crate::slang::Span;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Token<'a> {
|
||||
|
|
|
@ -83,7 +83,6 @@ where
|
|||
let passes = passes
|
||||
.into_iter()
|
||||
.map(|shader| {
|
||||
|
||||
let source = match &shader.source_path {
|
||||
ShaderPath::Slang(source_path) => ShaderSource::load(source_path)?,
|
||||
ShaderPath::Quark { vertex, fragment } => {
|
||||
|
|
|
@ -12,8 +12,7 @@ use librashader_runtime_d3d11::options::FilterChainOptionsD3D11;
|
|||
// const FILTER_PATH: &str =
|
||||
// "../test/Mega_Bezel_Packs/Duimon-Mega-Bezel/Presets/Advanced/Nintendo_GBA_SP/GBA_SP-[ADV]-[LCD-GRID].slangp";
|
||||
|
||||
const FILTER_PATH: &str =
|
||||
"../test/shaders_slang/scalefx/scalefx-9x.slangp";
|
||||
const FILTER_PATH: &str = "../test/shaders_slang/scalefx/scalefx-9x.slangp";
|
||||
|
||||
// const FILTER_PATH: &str = "../test/slang-shaders/test/history.slangp";
|
||||
// const FILTER_PATH: &str = "../test/slang-shaders/test/feedback.slangp";
|
||||
|
|
|
@ -61,7 +61,9 @@ pub mod presets {
|
|||
let iters: Result<Vec<Vec<ShaderParameter>>, PreprocessError> = preset
|
||||
.shaders
|
||||
.iter()
|
||||
.map(|s| ShaderSource::load(&s.source_path).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