cyborg/src/shader.rs

88 lines
2.6 KiB
Rust

use std::fs::{File, read_to_string};
pub fn parse_wgsl(source: &String) -> naga::Module {
// Create Parser
let mut parser = naga::front::wgsl::Parser::new();
// Create empty Module
let mut module = naga::Module::default();
// Attempt to parse the source code
let module_result = parser.parse(source.as_str());
match module_result {
Ok(in_mod) => {
//println!("{:?}", in_mod);
module = in_mod;
},
Err(error) => { println!("Parsing error:\n{}", error) }
}
// Return the Module
module
}
pub fn generate_wgsl(module: &naga::Module) -> String {
// Create options for the Writer
let wgsl_flags = naga::back::wgsl::WriterFlags::empty();
// Create a string buffer for the Writer to use
let mut wgsl_buffer = String::new();
// Create validator (to check if module is OK)
let mut validator = naga::valid::Validator::new(naga::valid::ValidationFlags::empty(), naga::valid::Capabilities::empty());
// Get ModuleInfo (produced by a syntax validator)
let module_info = validator.validate(&module).unwrap();
// Create the Writer itself
let mut wgsl_writer = naga::back::wgsl::Writer::new(&mut wgsl_buffer, wgsl_flags);
// Attempt to write
wgsl_writer.write(&module, &module_info).expect("wgsl write failed");
wgsl_buffer
}
pub fn add_includes(source: &String) -> String {
let mut combined = String::new();
let source_lines = source.lines();
for line in source_lines {
// Get a vector of the words in the line
let mut words: Vec<&str> = line.split(" ").collect();
// Check if this is an include statement
if words[0] == "#include" {
// Get the rest of the line
words.remove(0);
let file_path: String = words.join(" ");
// Get the code from the included file
let included = read_to_string(file_path).unwrap();
combined = format!("{}\n{}", combined, included);
} else {
combined = format!("{}\n{}", combined, line);
}
}
combined
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn preprocess_file() {
// Generate a shader and preprocess it
let mut source = read_to_string("src/shader.wgsl").unwrap();
source = add_includes(&source);
// Parse the WGSL into a usable module
let module = parse_wgsl(&source);
// Generate a valid WGSL string from the module
let gen_wgsl = generate_wgsl(&module);
}
}