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