1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146
use super::ErrorCode; use bindings::root::*; use std::ptr; use std::os::raw::c_void; use std::ffi::CStr; #[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)] pub enum ExecutionModel { Vertex = 0, TessellationControl = 1, TessellationEvaluation = 2, Geometry = 3, Fragment = 4, GlCompute = 5, Kernel = 6, } impl ExecutionModel { fn from_raw(raw: spv::ExecutionModel) -> Result<ExecutionModel, ErrorCode> { match raw { spv::ExecutionModel::ExecutionModelVertex => Ok(ExecutionModel::Vertex), spv::ExecutionModel::ExecutionModelTessellationControl => { Ok(ExecutionModel::TessellationControl) } spv::ExecutionModel::ExecutionModelTessellationEvaluation => { Ok(ExecutionModel::TessellationEvaluation) } spv::ExecutionModel::ExecutionModelGeometry => Ok(ExecutionModel::Geometry), spv::ExecutionModel::ExecutionModelFragment => Ok(ExecutionModel::Fragment), spv::ExecutionModel::ExecutionModelGLCompute => Ok(ExecutionModel::GlCompute), spv::ExecutionModel::ExecutionModelKernel => Ok(ExecutionModel::Kernel), _ => Err(ErrorCode::Unhandled), } } } #[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)] pub struct WorkgroupSize { pub x: u32, pub y: u32, pub z: u32, } #[derive(Debug, Clone)] pub struct EntryPoint { pub name: String, pub execution_model: ExecutionModel, pub workgroup_size: WorkgroupSize, } #[derive(Debug, Clone)] pub struct Module<'a> { ir: &'a [u32], } impl<'a> Module<'a> { pub fn new(ir: &[u32]) -> Module { Module { ir } } } pub struct ParsedModule { pub entry_points: Vec<EntryPoint>, pub(crate) ir: Vec<u32>, } impl ParsedModule { fn new(ir: Vec<u32>, entry_points: Vec<EntryPoint>) -> ParsedModule { ParsedModule { entry_points, ir } } } #[derive(Debug, Clone)] pub struct ParserOptions; impl Default for ParserOptions { fn default() -> ParserOptions { ParserOptions } } #[derive(Debug, Clone)] pub struct Parser { _unconstructable: (), } impl Parser { pub fn new() -> Parser { Parser { _unconstructable: () } } pub fn parse( &self, module: &Module, _options: &ParserOptions, ) -> Result<ParsedModule, ErrorCode> { unsafe { let mut entry_points_raw = ptr::null_mut(); let mut entry_points_raw_length = 0 as usize; let mut ir = vec![0; module.ir.len()]; ir.copy_from_slice(module.ir); check!(sc_internal_compiler_base_parse( ir.as_ptr() as *const u32, ir.len() as usize, &mut entry_points_raw, &mut entry_points_raw_length, )); let entry_points = (0..entry_points_raw_length) .map(|offset| { let entry_point_raw_ptr = entry_points_raw.offset(offset as isize); let entry_point_raw = *entry_point_raw_ptr; let name = match CStr::from_ptr(entry_point_raw.name) .to_owned() .into_string() { Ok(n) => n, _ => return Err(ErrorCode::Unhandled), }; let entry_point = EntryPoint { name, execution_model: try!( ExecutionModel::from_raw(entry_point_raw.execution_model) ), workgroup_size: WorkgroupSize { x: entry_point_raw.workgroup_size_x, y: entry_point_raw.workgroup_size_y, z: entry_point_raw.workgroup_size_z, }, }; check!(sc_internal_free_pointer( entry_point_raw.name as *mut c_void, )); check!(sc_internal_free_pointer(entry_point_raw_ptr as *mut c_void)); Ok(entry_point) }) .collect::<Result<Vec<_>, _>>(); Ok(ParsedModule::new(ir, try!(entry_points))) } } }