pull/3/head
itycodes 3 weeks ago
parent e80c32419c
commit 1e1d0911e4

@ -2,8 +2,8 @@
mod tests;
use crate::compiler::Module;
use std::fmt::Write;
use std::fmt;
use std::fmt::Write;
use super::StorageClass;
@ -19,12 +19,10 @@ pub enum Type {
impl fmt::Display for Type {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Type::Pointer(typ, storage_class) => {
match storage_class {
StorageClass::Input => write!(f, "*{}i", typ),
StorageClass::Output => write!(f, "*{}o", typ),
StorageClass::Undefined => panic!("Bound a non-declared variable"),
}
Type::Pointer(typ, storage_class) => match storage_class {
StorageClass::Input => write!(f, "*{}i", typ),
StorageClass::Output => write!(f, "*{}o", typ),
StorageClass::Undefined => panic!("Bound a non-declared variable"),
},
Type::Vector(typ, size) => write!(f, "v{}{}", size, typ),
Type::Float(size) => write!(f, "f{}", size),
@ -55,46 +53,61 @@ pub fn parse_type(typ: &String) -> Type {
};
let typ = typ.chars().take(typ.len() - 1).collect::<String>();
Type::Pointer(Box::new(parse_type(&typ)), storage_class)
},
}
'v' => {
let mut chars = typ.chars();
chars.next();
let size = chars.next().unwrap().to_digit(10).unwrap();
let typ = chars.collect::<String>();
Type::Vector(Box::new(parse_type(&typ)), size)
},
}
'f' => {
let size = typ.chars().skip(1).collect::<String>().parse().unwrap();
Type::Float(size)
},
}
's' => {
let size = typ.chars().skip(1).collect::<String>().parse().unwrap();
Type::Int(size)
},
}
'u' => {
let size = typ.chars().skip(1).collect::<String>().parse().unwrap();
Type::Unsigned(size)
},
}
_ => panic!("Invalid type"),
}
}
fn emit_type(typ: Type, ops: &mut Vec<(String, String)>) {
match &typ {
Type::Unsigned(size) => {
ops.push((format!("%u{}", size).to_string(), format!("OpTypeInt {}", size)));
},
ops.push((
format!("%u{}", size).to_string(),
format!("OpTypeInt {}", size),
));
}
Type::Int(size) => {
ops.push((format!("%s{}", size).to_string(), format!("OpTypeInt {}", size)));
},
ops.push((
format!("%s{}", size).to_string(),
format!("OpTypeInt {}", size),
));
}
Type::Float(size) => {
ops.push((format!("%f{}", size).to_string(), format!("OpTypeFloat {}", size)));
},
ops.push((
format!("%f{}", size).to_string(),
format!("OpTypeFloat {}", size),
));
}
Type::Vector(in_typ, size) => {
emit_type(*in_typ.clone(), ops);
ops.push((fix_name(&typ.to_string()), format!("OpTypeVector {} {}", fix_name(&in_typ.clone().to_string()), size)))
},
ops.push((
fix_name(&typ.to_string()),
format!(
"OpTypeVector {} {}",
fix_name(&in_typ.clone().to_string()),
size
),
))
}
Type::Pointer(in_typ, storage_class) => {
emit_type(*in_typ.clone(), ops);
let typ_id = fix_name(&typ.to_string());
@ -103,8 +116,15 @@ fn emit_type(typ: Type, ops: &mut Vec<(String, String)>) {
StorageClass::Output => "Output",
StorageClass::Undefined => panic!("Bound a non-declared variable"),
};
ops.push((typ_id, format!("OpTypePointer {} {}", storage_class, fix_name(&in_typ.to_string()))))
},
ops.push((
typ_id,
format!(
"OpTypePointer {} {}",
storage_class,
fix_name(&in_typ.to_string())
),
))
}
}
}
@ -125,7 +145,9 @@ pub fn spirv_meta(module: Module) -> String {
let mut spirv_asm = String::new();
let mut ops: Vec<(Option<String>, Vec<String>)> = Vec::new();
let capabilities: Vec<String> = module.capabilities.iter()
let capabilities: Vec<String> = module
.capabilities
.iter()
.map(|c| format!("{:?}", c))
.collect();
for cap in capabilities {
@ -144,7 +166,14 @@ pub fn spirv_meta(module: Module) -> String {
crate::compiler::MemoryModel::OpenCL => "OpenCL",
_ => todo!(),
};
ops.push((None, vec!["OpMemoryModel".to_string(), memory_model_address.to_string(), memory_model_model.to_string()]));
ops.push((
None,
vec![
"OpMemoryModel".to_string(),
memory_model_address.to_string(),
memory_model_model.to_string(),
],
));
for entry in module.entry_points {
let exec_model = match entry.execution_model {
@ -152,14 +181,32 @@ pub fn spirv_meta(module: Module) -> String {
crate::compiler::ExecutionModel::Vertex => "Vertex",
};
let name = entry.name;
let interface: Vec<String> = entry.interface.iter()
let interface: Vec<String> = entry
.interface
.iter()
.map(|i| fix_name(&i.to_string()))
.collect();
let exec_mode = match entry.execution_mode {
crate::compiler::ExecutionMode::OriginUpperLeft => "OriginUpperLeft",
};
ops.push((None, vec!["OpEntryPoint".to_string(), exec_model.to_string(), fix_name(&name), format!("\"{}\"", name), interface.join(" ")]));
ops.push((None, vec!["OpExecutionMode".to_string(), fix_name(&name), exec_mode.to_string()]));
ops.push((
None,
vec![
"OpEntryPoint".to_string(),
exec_model.to_string(),
fix_name(&name),
format!("\"{}\"", name),
interface.join(" "),
],
));
ops.push((
None,
vec![
"OpExecutionMode".to_string(),
fix_name(&name),
exec_mode.to_string(),
],
));
}
for global in module.globals {
@ -178,7 +225,14 @@ pub fn spirv_meta(module: Module) -> String {
}
ops.push((Some(op.0), vec![op.1]));
}
ops.push((Some(name.clone()), vec!["OpVariable".to_string(), fix_name(&_typ), storage_class.to_string()]));
ops.push((
Some(name.clone()),
vec![
"OpVariable".to_string(),
fix_name(&_typ),
storage_class.to_string(),
],
));
for dec in global.decorations {
// Decorations have the format Location 0, or Builtin FragCoord
let dec = match dec {
@ -188,7 +242,7 @@ pub fn spirv_meta(module: Module) -> String {
crate::compiler::BuiltinDecoration::FragCoord => "FragCoord",
};
format!("BuiltIn {}", builtin)
},
}
};
ops.push((None, vec!["OpDecorate".to_string(), name.clone(), dec]));
}
@ -204,4 +258,4 @@ pub fn spirv_meta(module: Module) -> String {
writeln!(spirv_asm).unwrap();
}
spirv_asm
}
}

@ -339,4 +339,3 @@ pub fn meta_compile(ast: &mut Ast) -> Module {
}
module
}

@ -93,4 +93,3 @@ fn test_compile() {
dbg!(&test_module);
assert_eq!(module, test_module);
}

Loading…
Cancel
Save