mirror of
https://github.com/vulkano-rs/vulkano.git
synced 2024-11-25 00:04:15 +00:00
Merge pull request #129 from tomaka/tess-geom-fix
Fix shader interfaces for tessellation and geometry shaders
This commit is contained in:
commit
150fe7474f
@ -27,7 +27,17 @@ pub fn write_entry_point(doc: &parse::Spirv, instruction: &parse::Instruction) -
|
||||
let capitalized_ep_name: String = ep_name.chars().take(1).flat_map(|c| c.to_uppercase())
|
||||
.chain(ep_name.chars().skip(1)).collect();
|
||||
|
||||
let interface_structs = write_interface_structs(doc, &capitalized_ep_name, interface);
|
||||
let interface_structs = write_interface_structs(doc, &capitalized_ep_name, interface,
|
||||
match *execution {
|
||||
enums::ExecutionModel::ExecutionModelTessellationControl => true,
|
||||
enums::ExecutionModel::ExecutionModelTessellationEvaluation => true,
|
||||
enums::ExecutionModel::ExecutionModelGeometry => true,
|
||||
_ => false
|
||||
},
|
||||
match *execution {
|
||||
enums::ExecutionModel::ExecutionModelTessellationControl => true,
|
||||
_ => false,
|
||||
});
|
||||
|
||||
let (ty, f_call) = match *execution {
|
||||
enums::ExecutionModel::ExecutionModelVertex => {
|
||||
@ -86,7 +96,8 @@ pub fn write_entry_point(doc: &parse::Spirv, instruction: &parse::Instruction) -
|
||||
(interface_structs, entry_point)
|
||||
}
|
||||
|
||||
fn write_interface_structs(doc: &parse::Spirv, capitalized_ep_name: &str, interface: &[u32])
|
||||
fn write_interface_structs(doc: &parse::Spirv, capitalized_ep_name: &str, interface: &[u32],
|
||||
ignore_first_array_in: bool, ignore_first_array_out: bool)
|
||||
-> String
|
||||
{
|
||||
let mut input_elements = Vec::new();
|
||||
@ -103,13 +114,9 @@ fn write_interface_structs(doc: &parse::Spirv, capitalized_ep_name: &str, interf
|
||||
continue;
|
||||
}
|
||||
|
||||
if is_builtin(doc, result_type_id) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let to_write = match storage_class {
|
||||
&enums::StorageClass::StorageClassInput => &mut input_elements,
|
||||
&enums::StorageClass::StorageClassOutput => &mut output_elements,
|
||||
let (to_write, ignore_first_array) = match storage_class {
|
||||
&enums::StorageClass::StorageClassInput => (&mut input_elements, ignore_first_array_in),
|
||||
&enums::StorageClass::StorageClassOutput => (&mut output_elements, ignore_first_array_out),
|
||||
_ => continue
|
||||
};
|
||||
|
||||
@ -121,7 +128,7 @@ fn write_interface_structs(doc: &parse::Spirv, capitalized_ep_name: &str, interf
|
||||
None => panic!("Attribute `{}` (id {}) is missing a location", name, result_id)
|
||||
};
|
||||
|
||||
to_write.push((loc, name, format_from_id(doc, result_type_id)));
|
||||
to_write.push((loc, name, format_from_id(doc, result_type_id, ignore_first_array)));
|
||||
},
|
||||
_ => ()
|
||||
}
|
||||
|
@ -189,17 +189,24 @@ impl From<ParseError> for Error {
|
||||
}
|
||||
|
||||
/// Returns the vulkano `Format` and number of occupied locations from an id.
|
||||
fn format_from_id(doc: &parse::Spirv, searched: u32) -> (String, usize) {
|
||||
///
|
||||
/// If `ignore_first_array` is true, the function expects the outermost instruction to be
|
||||
/// `OpTypeArray`. If it's the case, the OpTypeArray will be ignored. If not, the function will
|
||||
/// panic.
|
||||
fn format_from_id(doc: &parse::Spirv, searched: u32, ignore_first_array: bool) -> (String, usize) {
|
||||
for instruction in doc.instructions.iter() {
|
||||
match instruction {
|
||||
&parse::Instruction::TypeInt { result_id, width, signedness } if result_id == searched => {
|
||||
assert!(!ignore_first_array);
|
||||
return ("R32Sint".to_owned(), 1);
|
||||
},
|
||||
&parse::Instruction::TypeFloat { result_id, width } if result_id == searched => {
|
||||
assert!(!ignore_first_array);
|
||||
return ("R32Sfloat".to_owned(), 1);
|
||||
},
|
||||
&parse::Instruction::TypeVector { result_id, component_id, count } if result_id == searched => {
|
||||
let (format, sz) = format_from_id(doc, component_id);
|
||||
assert!(!ignore_first_array);
|
||||
let (format, sz) = format_from_id(doc, component_id, false);
|
||||
assert!(format.starts_with("R32"));
|
||||
assert_eq!(sz, 1);
|
||||
let format = if count == 1 {
|
||||
@ -216,11 +223,16 @@ fn format_from_id(doc: &parse::Spirv, searched: u32) -> (String, usize) {
|
||||
return (format, sz);
|
||||
},
|
||||
&parse::Instruction::TypeMatrix { result_id, column_type_id, column_count } if result_id == searched => {
|
||||
let (format, sz) = format_from_id(doc, column_type_id);
|
||||
assert!(!ignore_first_array);
|
||||
let (format, sz) = format_from_id(doc, column_type_id, false);
|
||||
return (format, sz * column_count as usize);
|
||||
},
|
||||
&parse::Instruction::TypeArray { result_id, type_id, length_id } if result_id == searched => {
|
||||
let (format, sz) = format_from_id(doc, type_id);
|
||||
if ignore_first_array {
|
||||
return format_from_id(doc, type_id, false);
|
||||
}
|
||||
|
||||
let (format, sz) = format_from_id(doc, type_id, false);
|
||||
let len = doc.instructions.iter().filter_map(|e| {
|
||||
match e { &parse::Instruction::Constant { result_id, ref data, .. } if result_id == length_id => Some(data.clone()), _ => None }
|
||||
}).next().expect("failed to find array length");
|
||||
@ -228,7 +240,7 @@ fn format_from_id(doc: &parse::Spirv, searched: u32) -> (String, usize) {
|
||||
return (format, sz * len as usize);
|
||||
},
|
||||
&parse::Instruction::TypePointer { result_id, type_id, .. } if result_id == searched => {
|
||||
return format_from_id(doc, type_id);
|
||||
return format_from_id(doc, type_id, ignore_first_array);
|
||||
},
|
||||
_ => ()
|
||||
}
|
||||
@ -357,6 +369,37 @@ fn is_builtin(doc: &parse::Spirv, id: u32) -> bool {
|
||||
{
|
||||
return true;
|
||||
},
|
||||
parse::Instruction::MemberDecorate { target_id,
|
||||
decoration: enums::Decoration::DecorationBuiltIn,
|
||||
.. } if target_id == id =>
|
||||
{
|
||||
return true;
|
||||
},
|
||||
_ => ()
|
||||
}
|
||||
}
|
||||
|
||||
for instruction in &doc.instructions {
|
||||
match *instruction {
|
||||
parse::Instruction::Variable { result_type_id, result_id, ref storage_class, .. }
|
||||
if result_id == id =>
|
||||
{
|
||||
return is_builtin(doc, result_type_id);
|
||||
},
|
||||
parse::Instruction::TypeArray { result_id, type_id, .. } if result_id == id => {
|
||||
return is_builtin(doc, type_id);
|
||||
},
|
||||
parse::Instruction::TypeRuntimeArray { result_id, type_id } if result_id == id => {
|
||||
return is_builtin(doc, type_id);
|
||||
},
|
||||
parse::Instruction::TypeStruct { result_id, ref member_types } if result_id == id => {
|
||||
for &mem in member_types {
|
||||
if is_builtin(doc, mem) { return true; }
|
||||
}
|
||||
},
|
||||
parse::Instruction::TypePointer { result_id, type_id, .. } if result_id == id => {
|
||||
return is_builtin(doc, type_id);
|
||||
},
|
||||
_ => ()
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user