Atm it only handles the basic metadata in modules. Doesn't generate code for functions, or types. Type handling is just a placeholder %undefined_type.pull/3/head
parent
3a3d9b46f4
commit
6036a5fe90
@ -0,0 +1,87 @@
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
||||
use crate::compiler::Module;
|
||||
use std::{fmt::Write, ops::Add};
|
||||
|
||||
pub fn fix_name(name: &String) -> String {
|
||||
format!("%{}", name.clone().replace("-", "_"))
|
||||
}
|
||||
|
||||
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()
|
||||
.map(|c| format!("{:?}", c))
|
||||
.collect();
|
||||
for cap in capabilities {
|
||||
ops.push((None, vec!["OpCapability".to_string(), cap]));
|
||||
}
|
||||
|
||||
let memory_model_address = match module.memory_model.addressing_model {
|
||||
crate::compiler::AddressingModel::Logical => "Logical",
|
||||
crate::compiler::AddressingModel::Physical32 => "Physical32",
|
||||
crate::compiler::AddressingModel::Physical64 => "Physical64",
|
||||
crate::compiler::AddressingModel::PhysicalStorageBuffer64 => "PhysicalStorageBuffer64",
|
||||
};
|
||||
let memory_model_model = match module.memory_model.memory_model {
|
||||
crate::compiler::MemoryModel::Simple => "Simple",
|
||||
crate::compiler::MemoryModel::GLSL450 => "GLSL450",
|
||||
crate::compiler::MemoryModel::OpenCL => "OpenCL",
|
||||
_ => todo!(),
|
||||
};
|
||||
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 {
|
||||
crate::compiler::ExecutionModel::Fragment => "Fragment",
|
||||
crate::compiler::ExecutionModel::Vertex => "Vertex",
|
||||
};
|
||||
let name = entry.name;
|
||||
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()]));
|
||||
}
|
||||
|
||||
for global in module.globals {
|
||||
let name = fix_name(&global.name);
|
||||
let typ = global.typ;
|
||||
let storage_class = match global.storage_class {
|
||||
crate::compiler::StorageClass::Input => "Input",
|
||||
crate::compiler::StorageClass::Output => "Output",
|
||||
crate::compiler::StorageClass::Undefined => panic!("Bound a non-declared variable"),
|
||||
};
|
||||
let typ_id = "%undefined_type";
|
||||
ops.push((Some(name.clone()), vec!["OpVariable".to_string(), typ_id.to_string(), storage_class.to_string()]));
|
||||
for dec in global.decorations {
|
||||
// Decorations have the format Location 0, or Builtin FragCoord
|
||||
let dec = match dec {
|
||||
crate::compiler::Decoration::Location(loc) => format!("Location {}", loc),
|
||||
crate::compiler::Decoration::BuiltIn(builtin) => {
|
||||
let builtin = match builtin {
|
||||
crate::compiler::BuiltinDecoration::FragCoord => "FragCoord",
|
||||
};
|
||||
format!("BuiltIn {}", builtin)
|
||||
},
|
||||
};
|
||||
ops.push((None, vec!["OpDecorate".to_string(), name.clone(), dec]));
|
||||
}
|
||||
}
|
||||
|
||||
for op in ops {
|
||||
if op.0.is_some() {
|
||||
write!(spirv_asm, "{} = ", op.0.unwrap()).unwrap();
|
||||
}
|
||||
for arg in op.1 {
|
||||
write!(spirv_asm, "{} ", arg).unwrap();
|
||||
}
|
||||
writeln!(spirv_asm).unwrap();
|
||||
}
|
||||
spirv_asm
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
#[test]
|
||||
fn test_emit() {
|
||||
use crate::compiler::*;
|
||||
use crate::parser::*;
|
||||
use crate::compiler::backend::*;
|
||||
let src = "
|
||||
(module Shader Logical GLSL450)
|
||||
(import :std GLSL.std.450)
|
||||
(bind (frag-coord:*v4f32i) (BuiltIn FragCoord))
|
||||
(bind (out-color:*v4f32o) (Location 0))
|
||||
(dec frag-coord:*v4f32i Input)
|
||||
(dec out-color:*v4f32o Output)
|
||||
(entry main Fragment OriginUpperLeft (:frag-coord :out-color))
|
||||
(fun (main)
|
||||
(store-ptr (out-color)
|
||||
(v4f32i (/ (.xy (load-ptr frag-coord))
|
||||
(v2f32 1920.0 1080.0))
|
||||
1.0
|
||||
1.0)))
|
||||
";
|
||||
let mut ast = parse(tokenize(src));
|
||||
let module = meta_compile(&mut ast);
|
||||
let res = spirv_meta(module);
|
||||
println!("{}", res);
|
||||
}
|
Loading…
Reference in new issue