mirror of
https://github.com/vulkano-rs/vulkano.git
synced 2024-11-22 06:45:23 +00:00
More SPIR-V parsing
This commit is contained in:
parent
8f76d6f74e
commit
8c5caabf4e
@ -66,6 +66,7 @@ pub enum ParseError {
|
|||||||
IncompleteInstruction,
|
IncompleteInstruction,
|
||||||
UnknownCapability(u32),
|
UnknownCapability(u32),
|
||||||
UnknownExecutionModel(u32),
|
UnknownExecutionModel(u32),
|
||||||
|
UnknownStorageClass(u32),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
@ -79,10 +80,23 @@ pub struct Spirv {
|
|||||||
pub enum Instruction {
|
pub enum Instruction {
|
||||||
Unknown(u16, Vec<u32>),
|
Unknown(u16, Vec<u32>),
|
||||||
Nop,
|
Nop,
|
||||||
|
Name { target_id: u32, name: String },
|
||||||
|
MemberName { target_id: u32, member: u32, name: String },
|
||||||
ExtInstImport { result_id: u32, name: String },
|
ExtInstImport { result_id: u32, name: String },
|
||||||
EntryPoint { execution: ExecutionModel, id: u32, name: String, interface: Vec<u32> },
|
EntryPoint { execution: ExecutionModel, id: u32, name: String, interface: Vec<u32> },
|
||||||
Capability(Capability),
|
Capability(Capability),
|
||||||
|
TypeVoid { result_id: u32 },
|
||||||
|
TypeBool { result_id: u32 },
|
||||||
|
TypeInt { result_id: u32, width: u32, signedness: bool },
|
||||||
|
TypeFloat { result_id: u32, width: u32 },
|
||||||
|
TypeVector { result_id: u32, component_id: u32, count: u32 },
|
||||||
|
TypeArray { result_id: u32, type_id: u32, length_id: u32 },
|
||||||
|
TypeRuntimeArray { result_id: u32, type_id: u32 },
|
||||||
|
TypeStruct { result_id: u32, member_types: Vec<u32> },
|
||||||
|
TypeOpaque { result_id: u32, name: String },
|
||||||
|
TypePointer { result_id: u32, storage_class: StorageClass, type_id: u32 },
|
||||||
FunctionEnd,
|
FunctionEnd,
|
||||||
|
Variable { result_type_id: u32, result_id: u32, storage_class: StorageClass, initializer: Option<u32> },
|
||||||
Kill,
|
Kill,
|
||||||
Return,
|
Return,
|
||||||
}
|
}
|
||||||
@ -105,6 +119,8 @@ fn parse_instruction(i: &[u32]) -> Result<(Instruction, &[u32]), ParseError> {
|
|||||||
fn decode_instruction(opcode: u16, operands: &[u32]) -> Result<Instruction, ParseError> {
|
fn decode_instruction(opcode: u16, operands: &[u32]) -> Result<Instruction, ParseError> {
|
||||||
Ok(match opcode {
|
Ok(match opcode {
|
||||||
0 => Instruction::Nop,
|
0 => Instruction::Nop,
|
||||||
|
5 => Instruction::Name { target_id: operands[0], name: parse_string(&operands[1..]).0 },
|
||||||
|
6 => Instruction::MemberName { target_id: operands[0], member: operands[1], name: parse_string(&operands[2..]).0 },
|
||||||
11 => Instruction::ExtInstImport {
|
11 => Instruction::ExtInstImport {
|
||||||
result_id: operands[0],
|
result_id: operands[0],
|
||||||
name: parse_string(&operands[1..]).0
|
name: parse_string(&operands[1..]).0
|
||||||
@ -119,7 +135,22 @@ fn decode_instruction(opcode: u16, operands: &[u32]) -> Result<Instruction, Pars
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
17 => Instruction::Capability(try!(Capability::from_num(operands[0]))),
|
17 => Instruction::Capability(try!(Capability::from_num(operands[0]))),
|
||||||
|
19 => Instruction::TypeVoid { result_id: operands[0] },
|
||||||
|
20 => Instruction::TypeBool { result_id: operands[0] },
|
||||||
|
21 => Instruction::TypeInt { result_id: operands[0], width: operands[1], signedness: operands[2] != 0 },
|
||||||
|
22 => Instruction::TypeFloat { result_id: operands[0], width: operands[1] },
|
||||||
|
23 => Instruction::TypeVector { result_id: operands[0], component_id: operands[1], count: operands[2] },
|
||||||
|
28 => Instruction::TypeArray { result_id: operands[0], type_id: operands[1], length_id: operands[2] },
|
||||||
|
29 => Instruction::TypeRuntimeArray { result_id: operands[0], type_id: operands[1] },
|
||||||
|
30 => Instruction::TypeStruct { result_id: operands[0], member_types: operands[1..].to_owned() },
|
||||||
|
31 => Instruction::TypeOpaque { result_id: operands[0], name: parse_string(&operands[1..]).0 },
|
||||||
|
32 => Instruction::TypePointer { result_id: operands[0], storage_class: try!(StorageClass::from_num(operands[1])), type_id: operands[2] },
|
||||||
56 => Instruction::FunctionEnd,
|
56 => Instruction::FunctionEnd,
|
||||||
|
59 => Instruction::Variable {
|
||||||
|
result_type_id: operands[0], result_id: operands[1],
|
||||||
|
storage_class: try!(StorageClass::from_num(operands[2])),
|
||||||
|
initializer: operands.get(3).map(|&v| v)
|
||||||
|
},
|
||||||
252 => Instruction::Kill,
|
252 => Instruction::Kill,
|
||||||
253 => Instruction::Return,
|
253 => Instruction::Return,
|
||||||
_ => Instruction::Unknown(opcode, operands.to_owned()),
|
_ => Instruction::Unknown(opcode, operands.to_owned()),
|
||||||
@ -289,13 +320,49 @@ impl ExecutionModel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub enum StorageClass {
|
||||||
|
UniformConstant,
|
||||||
|
Input,
|
||||||
|
Uniform,
|
||||||
|
Output,
|
||||||
|
Workgroup,
|
||||||
|
CrossWorkgroup,
|
||||||
|
Private,
|
||||||
|
Function,
|
||||||
|
Generic,
|
||||||
|
PushConstant,
|
||||||
|
AtomicCounter,
|
||||||
|
Image,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl StorageClass {
|
||||||
|
fn from_num(num: u32) -> Result<StorageClass, ParseError> {
|
||||||
|
match num {
|
||||||
|
0 => Ok(StorageClass::UniformConstant),
|
||||||
|
1 => Ok(StorageClass::Input),
|
||||||
|
2 => Ok(StorageClass::Uniform),
|
||||||
|
3 => Ok(StorageClass::Output),
|
||||||
|
4 => Ok(StorageClass::Workgroup),
|
||||||
|
5 => Ok(StorageClass::CrossWorkgroup),
|
||||||
|
6 => Ok(StorageClass::Private),
|
||||||
|
7 => Ok(StorageClass::Function),
|
||||||
|
8 => Ok(StorageClass::Generic),
|
||||||
|
9 => Ok(StorageClass::PushConstant),
|
||||||
|
10 => Ok(StorageClass::AtomicCounter),
|
||||||
|
11 => Ok(StorageClass::Image),
|
||||||
|
_ => Err(ParseError::UnknownStorageClass(num)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use parse;
|
use parse;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test() {
|
fn test() {
|
||||||
let data = include_bytes!("../tests/frag.spv");
|
let data = include_bytes!("../examples/example.spv");
|
||||||
parse::parse_spirv(data).unwrap();
|
println!("{:?}", parse::parse_spirv(data).unwrap());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user