Transpiler skeleton and first bits of MSL support

This commit is contained in:
Dzmitry Malyshau 2018-09-12 21:28:55 -04:00
parent d39bb42f9a
commit ed96c2b8e0
5 changed files with 133 additions and 0 deletions

4
.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
/target
**/*.rs.bk
Cargo.lock
.DS_Store

11
Cargo.toml Normal file
View File

@ -0,0 +1,11 @@
[package]
name = "javelin"
version = "0.1.0"
authors = ["Dzmitry Malyshau <kvarkus@gmail.com>"]
[dependencies]
rspirv = "0.5"
spirv_headers = "1"
[dev-dependencies]
env_logger = "0.5"

19
examples/convert.rs Normal file
View File

@ -0,0 +1,19 @@
extern crate env_logger;
extern crate javelin;
use std::{env, fs};
fn main() {
env_logger::init();
let args = env::args().collect::<Vec<_>>();
let input = fs::read(&args[1]).unwrap();
let mut transpiler = javelin::Transpiler::new();
let module = transpiler.load(&input).unwrap();
let options = javelin::msl::Options {};
let msl = module.to_msl(&options).unwrap();
println!("{}", msl);
}

69
src/lib.rs Normal file
View File

@ -0,0 +1,69 @@
extern crate rspirv;
extern crate spirv_headers;
pub mod msl;
use std::collections::HashMap;
pub struct Transpiler {
}
pub struct Module {
raw: rspirv::mr::Module,
entry_points: HashMap<String, EntryPoint>,
}
pub struct EntryPoint {
pub cleansed_name: String,
pub exec_model: spirv_headers::ExecutionModel,
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub enum LoadError {
Parsing,
}
impl Transpiler {
pub fn new() -> Self {
Transpiler {
}
}
pub fn load(&mut self, spv: &[u8]) -> Result<Module, LoadError> {
let mut loader = rspirv::mr::Loader::new();
rspirv::binary::Parser::new(spv, &mut loader)
.parse()
.map_err(|_| LoadError::Parsing)?;
let raw = loader.module();
let entry_points = raw.entry_points
.iter()
.map(|ep| {
let name = match ep.operands[2] {
rspirv::mr::Operand::LiteralString(ref name) => name.to_string(),
ref other => panic!("Unexpected entry point operand {:?}", other),
};
let ep = EntryPoint {
cleansed_name: name.clone(), //TODO
exec_model: match ep.operands[0] {
rspirv::mr::Operand::ExecutionModel(model) => model,
ref other => panic!("Unexpected execution model operand {:?}", other),
},
};
(name, ep)
})
.collect();
Ok(Module {
raw,
entry_points,
})
}
}
impl Module {
pub fn entry_points(&self) -> &HashMap<String, EntryPoint> {
&self.entry_points
}
}

30
src/msl.rs Normal file
View File

@ -0,0 +1,30 @@
use std::fmt::{Error as FmtError, Write};
use Module;
pub struct Options {
}
#[derive(Debug)]
pub enum Error {
Format(FmtError)
}
impl From<FmtError> for Error {
fn from(e: FmtError) -> Self {
Error::Format(e)
}
}
impl Module {
pub fn to_msl(&self, _options: &Options) -> Result<String, Error> {
let mut out = String::new();
writeln!(out, "#include <metal_stdlib>")?;
writeln!(out, "#include <simd/simd.h>")?;
writeln!(out, "using namespace metal;")?;
Ok(out)
}
}