mirror of
https://github.com/vulkano-rs/vulkano.git
synced 2024-11-22 06:45:23 +00:00
More prototyping for reflection
This commit is contained in:
parent
cbbc535cfb
commit
66d55cad0a
9
shader-parser/examples/example.rs
Normal file
9
shader-parser/examples/example.rs
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
extern crate shader_parser;
|
||||||
|
|
||||||
|
use std::io::Cursor;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let content = include_bytes!("example.spv");
|
||||||
|
let output = shader_parser::reflect(Cursor::new(&content[..])).unwrap();
|
||||||
|
println!("{}", output);
|
||||||
|
}
|
BIN
shader-parser/examples/example.spv
Normal file
BIN
shader-parser/examples/example.spv
Normal file
Binary file not shown.
@ -14,9 +14,108 @@ pub fn reflect<R>(mut spirv: R) -> Result<String, Error>
|
|||||||
// now parsing the document
|
// now parsing the document
|
||||||
let doc = try!(parse::parse_spirv(&data));
|
let doc = try!(parse::parse_spirv(&data));
|
||||||
|
|
||||||
unimplemented!()
|
let mut output = String::new();
|
||||||
|
|
||||||
|
for instruction in doc.instructions.iter() {
|
||||||
|
match instruction {
|
||||||
|
&parse::Instruction::Variable { result_type_id, result_id, ref storage_class, .. } => {
|
||||||
|
match *storage_class {
|
||||||
|
parse::StorageClass::UniformConstant => (),
|
||||||
|
parse::StorageClass::Uniform => (),
|
||||||
|
parse::StorageClass::PushConstant => (),
|
||||||
|
_ => continue
|
||||||
|
};
|
||||||
|
|
||||||
|
let name = name_from_id(&doc, result_id);
|
||||||
|
output.push_str(&format!("{}: {};", name, type_from_id(&doc, result_type_id)));
|
||||||
|
},
|
||||||
|
_ => ()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(output)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn name_from_id(doc: &parse::Spirv, searched: u32) -> String {
|
||||||
|
doc.instructions.iter().filter_map(|i| {
|
||||||
|
if let &parse::Instruction::Name { target_id, ref name } = i {
|
||||||
|
if target_id == searched {
|
||||||
|
Some(name.clone())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}).next().and_then(|n| if !n.is_empty() { Some(n) } else { None })
|
||||||
|
.unwrap_or("__unnamed".to_owned())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn member_name_from_id(doc: &parse::Spirv, searched: u32, searched_member: u32) -> String {
|
||||||
|
doc.instructions.iter().filter_map(|i| {
|
||||||
|
if let &parse::Instruction::MemberName { target_id, member, ref name } = i {
|
||||||
|
if target_id == searched && member == searched_member {
|
||||||
|
Some(name.clone())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}).next().and_then(|n| if !n.is_empty() { Some(n) } else { None })
|
||||||
|
.unwrap_or("__unnamed".to_owned())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn type_from_id(doc: &parse::Spirv, searched: u32) -> String {
|
||||||
|
for instruction in doc.instructions.iter() {
|
||||||
|
match instruction {
|
||||||
|
&parse::Instruction::TypeVoid { result_id } if result_id == searched => {
|
||||||
|
return "()".to_owned()
|
||||||
|
},
|
||||||
|
&parse::Instruction::TypeBool { result_id } if result_id == searched => {
|
||||||
|
return "bool".to_owned()
|
||||||
|
},
|
||||||
|
&parse::Instruction::TypeInt { result_id, width, signedness } if result_id == searched => {
|
||||||
|
return "i32".to_owned()
|
||||||
|
},
|
||||||
|
&parse::Instruction::TypeFloat { result_id, width } if result_id == searched => {
|
||||||
|
return "f32".to_owned()
|
||||||
|
},
|
||||||
|
&parse::Instruction::TypeVector { result_id, component_id, count } if result_id == searched => {
|
||||||
|
let t = type_from_id(doc, component_id);
|
||||||
|
return format!("[{}; {}]", t, count);
|
||||||
|
},
|
||||||
|
&parse::Instruction::TypeArray { result_id, type_id, length_id } if result_id == searched => {
|
||||||
|
let t = type_from_id(doc, type_id);
|
||||||
|
return format!("[{}; {}]", t, length_id); // FIXME:
|
||||||
|
},
|
||||||
|
&parse::Instruction::TypeRuntimeArray { result_id, type_id } if result_id == searched => {
|
||||||
|
let t = type_from_id(doc, type_id);
|
||||||
|
return format!("[{}]", t);
|
||||||
|
},
|
||||||
|
&parse::Instruction::TypeStruct { result_id, ref member_types } if result_id == searched => {
|
||||||
|
let name = name_from_id(doc, result_id);
|
||||||
|
let members = member_types.iter().enumerate().map(|(offset, &member)| {
|
||||||
|
let ty = type_from_id(doc, member);
|
||||||
|
let name = member_name_from_id(doc, result_id, offset as u32);
|
||||||
|
format!("\t{}: {}", name, ty)
|
||||||
|
}).collect::<Vec<_>>();
|
||||||
|
return format!("struct {} {{\n{}\n}}", name, members.join(",\n"));
|
||||||
|
},
|
||||||
|
&parse::Instruction::TypeOpaque { result_id, ref name } if result_id == searched => {
|
||||||
|
},
|
||||||
|
&parse::Instruction::TypePointer { result_id, type_id, .. } if result_id == searched => {
|
||||||
|
let t = type_from_id(doc, type_id);
|
||||||
|
return format!("*const {}", t);
|
||||||
|
},
|
||||||
|
_ => ()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
panic!("Type #{} not found", searched)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
IoError(IoError),
|
IoError(IoError),
|
||||||
ParseError(ParseError),
|
ParseError(ParseError),
|
||||||
|
@ -403,6 +403,6 @@ mod test {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test() {
|
fn test() {
|
||||||
let data = include_bytes!("../examples/example.spv");
|
let data = include_bytes!("../examples/example.spv");
|
||||||
println!("{:?}", parse::parse_spirv(data).unwrap());
|
println!("{:#?}", parse::parse_spirv(data).unwrap());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user