#![allow(dead_code)]
pub const SPIRV_MAGIC: u32 = 0x07230203;
pub const SPIRV_VERSION_1_5: u32 = 0x00010500;
pub struct SpirVExport {
pub magic: u32,
pub version: u32,
pub bound: u32,
pub words: Vec<u32>,
pub entry_points: Vec<String>,
}
pub fn new_spirv_export() -> SpirVExport {
SpirVExport {
magic: SPIRV_MAGIC,
version: SPIRV_VERSION_1_5,
bound: 1,
words: vec![SPIRV_MAGIC, SPIRV_VERSION_1_5, 0, 1, 0],
entry_points: Vec::new(),
}
}
pub fn add_spirv_entry_point(exp: &mut SpirVExport, name: &str) {
exp.entry_points.push(name.to_string());
}
pub fn spirv_entry_point_count(exp: &SpirVExport) -> usize {
exp.entry_points.len()
}
pub fn spirv_word_count(exp: &SpirVExport) -> usize {
exp.words.len()
}
pub fn spirv_byte_size(exp: &SpirVExport) -> usize {
exp.words.len() * 4
}
pub fn spirv_to_bytes(exp: &SpirVExport) -> Vec<u8> {
exp.words.iter().flat_map(|w| w.to_le_bytes()).collect()
}
pub fn validate_spirv_magic(exp: &SpirVExport) -> bool {
exp.magic == SPIRV_MAGIC
}
pub fn spirv_has_valid_header(exp: &SpirVExport) -> bool {
exp.words.len() >= 5 && exp.words[0] == SPIRV_MAGIC
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn new_export_has_magic() {
let exp = new_spirv_export();
assert_eq!(exp.magic, SPIRV_MAGIC );
}
#[test]
fn validate_magic_passes() {
let exp = new_spirv_export();
assert!(validate_spirv_magic(&exp) );
}
#[test]
fn new_export_has_valid_header() {
let exp = new_spirv_export();
assert!(spirv_has_valid_header(&exp) );
}
#[test]
fn byte_size_is_word_count_times_4() {
let exp = new_spirv_export();
assert_eq!(
spirv_byte_size(&exp),
spirv_word_count(&exp) * 4
);
}
#[test]
fn to_bytes_starts_with_magic() {
let exp = new_spirv_export();
let bytes = spirv_to_bytes(&exp);
let magic = u32::from_le_bytes([bytes[0], bytes[1], bytes[2], bytes[3]]);
assert_eq!(magic, SPIRV_MAGIC );
}
#[test]
fn add_entry_point_increments() {
let mut exp = new_spirv_export();
add_spirv_entry_point(&mut exp, "main");
assert_eq!(spirv_entry_point_count(&exp), 1 );
}
#[test]
fn version_is_1_5() {
let exp = new_spirv_export();
assert_eq!(exp.version, SPIRV_VERSION_1_5 );
}
#[test]
fn to_bytes_length_correct() {
let exp = new_spirv_export();
let bytes = spirv_to_bytes(&exp);
assert_eq!(
bytes.len(),
spirv_byte_size(&exp)
);
}
#[test]
fn multiple_entry_points() {
let mut exp = new_spirv_export();
add_spirv_entry_point(&mut exp, "vs_main");
add_spirv_entry_point(&mut exp, "fs_main");
assert_eq!(spirv_entry_point_count(&exp), 2 );
}
}