mirror of
https://github.com/vulkano-rs/vulkano.git
synced 2024-11-21 22:34:43 +00:00
No longer hardcode vertex attributes
This commit is contained in:
parent
d9c13cb830
commit
84bf96f23e
@ -117,9 +117,10 @@ fn write_entry_point(doc: &parse::Spirv, instruction: &parse::Instruction) -> St
|
||||
_ => unreachable!()
|
||||
};
|
||||
|
||||
let (ty, f_name) = match *execution {
|
||||
let (ty, f_call) = match *execution {
|
||||
enums::ExecutionModel::ExecutionModelVertex => {
|
||||
let mut input_types = Vec::new();
|
||||
let mut attributes = Vec::new();
|
||||
|
||||
// TODO: sort types by location
|
||||
|
||||
@ -131,6 +132,12 @@ fn write_entry_point(doc: &parse::Spirv, instruction: &parse::Instruction) -> St
|
||||
if &result_id == interface =>
|
||||
{
|
||||
input_types.push(type_from_id(doc, result_type_id));
|
||||
let name = name_from_id(doc, result_id);
|
||||
let loc = match location_decoration(doc, result_id) {
|
||||
Some(l) => l,
|
||||
None => panic!("vertex attribute `{}` is missing a location", name)
|
||||
};
|
||||
attributes.push((loc, name));
|
||||
},
|
||||
_ => ()
|
||||
}
|
||||
@ -142,21 +149,26 @@ fn write_entry_point(doc: &parse::Spirv, instruction: &parse::Instruction) -> St
|
||||
if input.is_empty() { input } else { input + "," }
|
||||
};
|
||||
|
||||
let attributes = attributes.iter().map(|&(loc, ref name)| {
|
||||
format!("({}, ::std::borrow::Cow::Borrowed(\"{}\"))", loc, name)
|
||||
}).collect::<Vec<_>>().join(", ");
|
||||
|
||||
let t = format!("::vulkano::shader::VertexShaderEntryPoint<({input})>",
|
||||
input = input);
|
||||
(t, "vertex_shader_entry_point")
|
||||
let f = format!("vertex_shader_entry_point(::std::ffi::CStr::from_ptr(NAME.as_ptr() as *const _), vec![{}])", attributes);
|
||||
(t, f)
|
||||
},
|
||||
|
||||
enums::ExecutionModel::ExecutionModelTessellationControl => {
|
||||
(format!("::vulkano::shader::TessControlShaderEntryPoint"), "")
|
||||
(format!("::vulkano::shader::TessControlShaderEntryPoint"), String::new())
|
||||
},
|
||||
|
||||
enums::ExecutionModel::ExecutionModelTessellationEvaluation => {
|
||||
(format!("::vulkano::shader::TessEvaluationShaderEntryPoint"), "")
|
||||
(format!("::vulkano::shader::TessEvaluationShaderEntryPoint"), String::new())
|
||||
},
|
||||
|
||||
enums::ExecutionModel::ExecutionModelGeometry => {
|
||||
(format!("::vulkano::shader::GeometryShaderEntryPoint"), "")
|
||||
(format!("::vulkano::shader::GeometryShaderEntryPoint"), String::new())
|
||||
},
|
||||
|
||||
enums::ExecutionModel::ExecutionModelFragment => {
|
||||
@ -183,11 +195,11 @@ fn write_entry_point(doc: &parse::Spirv, instruction: &parse::Instruction) -> St
|
||||
|
||||
let t = format!("::vulkano::shader::FragmentShaderEntryPoint<({output})>",
|
||||
output = output);
|
||||
(t, "fragment_shader_entry_point")
|
||||
(t, format!("fragment_shader_entry_point(::std::ffi::CStr::from_ptr(NAME.as_ptr() as *const _))"))
|
||||
},
|
||||
|
||||
enums::ExecutionModel::ExecutionModelGLCompute => {
|
||||
(format!("::vulkano::shader::ComputeShaderEntryPoint"), "compute_shader_entry_point")
|
||||
(format!("::vulkano::shader::ComputeShaderEntryPoint"), format!("compute_shader_entry_point"))
|
||||
},
|
||||
|
||||
enums::ExecutionModel::ExecutionModelKernel => panic!("Kernels are not supported"),
|
||||
@ -200,13 +212,13 @@ fn write_entry_point(doc: &parse::Spirv, instruction: &parse::Instruction) -> St
|
||||
unsafe {{
|
||||
#[allow(dead_code)]
|
||||
static NAME: [u8; {ep_name_lenp1}] = [{encoded_ep_name}, 0]; // "{ep_name}"
|
||||
self.shader.{f_name}(::std::ffi::CStr::from_ptr(NAME.as_ptr() as *const _))
|
||||
self.shader.{f_call}
|
||||
}}
|
||||
}}
|
||||
"#, ep_name = ep_name, ep_name_lenp1 = ep_name.chars().count() + 1, ty = ty,
|
||||
encoded_ep_name = ep_name.chars().map(|c| (c as u32).to_string())
|
||||
.collect::<Vec<String>>().join(", "),
|
||||
f_name = f_name)
|
||||
f_call = f_call)
|
||||
}
|
||||
|
||||
fn type_from_id(doc: &parse::Spirv, searched: u32) -> String {
|
||||
@ -288,6 +300,20 @@ fn name_from_id(doc: &parse::Spirv, searched: u32) -> String {
|
||||
.unwrap_or("__unnamed".to_owned())
|
||||
}
|
||||
|
||||
fn location_decoration(doc: &parse::Spirv, searched: u32) -> Option<u32> {
|
||||
doc.instructions.iter().filter_map(|i| {
|
||||
if let &parse::Instruction::Decorate { target_id, decoration: enums::Decoration::DecorationLocation, ref params } = i {
|
||||
if target_id == searched {
|
||||
Some(params[0])
|
||||
} else {
|
||||
None
|
||||
}
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}).next()
|
||||
}
|
||||
|
||||
fn member_name_from_id(doc: &parse::Spirv, searched: u32, searched_member: u32) -> String {
|
||||
doc.instructions.iter().filter_map(|i| {
|
||||
if let &parse::Instruction::MemberName { target_id, member, ref name } = i {
|
||||
|
@ -100,6 +100,7 @@ pub enum Instruction {
|
||||
Constant { result_type_id: u32, result_id: u32, data: Vec<u32> },
|
||||
FunctionEnd,
|
||||
Variable { result_type_id: u32, result_id: u32, storage_class: StorageClass, initializer: Option<u32> },
|
||||
Decorate { target_id: u32, decoration: Decoration, params: Vec<u32> },
|
||||
Label { result_id: u32 },
|
||||
Branch { result_id: u32 },
|
||||
Kill,
|
||||
@ -170,6 +171,7 @@ fn decode_instruction(opcode: u16, operands: &[u32]) -> Result<Instruction, Pars
|
||||
storage_class: try!(StorageClass::from_num(operands[2])),
|
||||
initializer: operands.get(3).map(|&v| v)
|
||||
},
|
||||
71 => Instruction::Decorate { target_id: operands[0], decoration: try!(Decoration::from_num(operands[1])), params: operands[2..].to_owned() },
|
||||
248 => Instruction::Label { result_id: operands[0] },
|
||||
249 => Instruction::Branch { result_id: operands[0] },
|
||||
252 => Instruction::Kill,
|
||||
|
@ -92,7 +92,7 @@ impl<MV> GraphicsPipeline<MV>
|
||||
}
|
||||
}).collect::<Vec<_>>();
|
||||
|
||||
let attribute_descriptions = vertex_shader.attributes().iter().enumerate().map(|(loc, name)| {
|
||||
let attribute_descriptions = vertex_shader.attributes().iter().map(|&(loc, ref name)| {
|
||||
let (binding, info) = MV::attrib(name).expect("missing attr"); // TODO: error
|
||||
vk::VertexInputAttributeDescription {
|
||||
location: loc as u32,
|
||||
|
@ -52,14 +52,15 @@ impl ShaderModule {
|
||||
}))
|
||||
}
|
||||
|
||||
pub unsafe fn vertex_shader_entry_point<'a, V>(&'a self, name: &'a CStr)
|
||||
pub unsafe fn vertex_shader_entry_point<'a, V>(&'a self, name: &'a CStr,
|
||||
attributes: Vec<(u32, Cow<'static, str>)>)
|
||||
-> VertexShaderEntryPoint<'a, V>
|
||||
{
|
||||
VertexShaderEntryPoint {
|
||||
module: self,
|
||||
name: name,
|
||||
marker: PhantomData,
|
||||
attributes: vec!["position".into()], // FIXME:
|
||||
attributes: attributes,
|
||||
}
|
||||
}
|
||||
|
||||
@ -109,8 +110,7 @@ pub struct VertexShaderEntryPoint<'a, V> {
|
||||
module: &'a ShaderModule,
|
||||
name: &'a CStr,
|
||||
marker: PhantomData<V>,
|
||||
|
||||
attributes: Vec<Cow<'static, str>>,
|
||||
attributes: Vec<(u32, Cow<'static, str>)>,
|
||||
}
|
||||
|
||||
impl<'a, V> VertexShaderEntryPoint<'a, V> {
|
||||
@ -126,7 +126,7 @@ impl<'a, V> VertexShaderEntryPoint<'a, V> {
|
||||
|
||||
// TODO: change API
|
||||
#[inline]
|
||||
pub fn attributes(&self) -> &Vec<Cow<'static, str>> {
|
||||
pub fn attributes(&self) -> &[(u32, Cow<'static, str>)] {
|
||||
&self.attributes
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user