toggle-able "bevy conventions" in shaders

This commit is contained in:
Carter Anderson 2020-05-07 19:09:25 -07:00
parent 3d65a0d236
commit 5e5df2bb87
4 changed files with 28 additions and 19 deletions

View file

@ -135,6 +135,9 @@ impl PipelineDescriptor {
/// Reflects the pipeline layout from its shaders.
///
/// If `bevy_conventions` is true, it will be assumed that the shader follows "bevy shader conventions". These allow
/// richer reflection, such as inferred Vertex Buffer names and inferred instancing.
///
/// If `vertex_buffer_descriptors` is set, the pipeline's vertex buffers
/// will inherit their layouts from global descriptors, otherwise the layout will be assumed to be complete / local.
///
@ -143,6 +146,7 @@ impl PipelineDescriptor {
pub fn reflect_layout(
&mut self,
shaders: &AssetStorage<Shader>,
bevy_conventions: bool,
vertex_buffer_descriptors: Option<&VertexBufferDescriptors>,
dynamic_uniform_lookup: Option<(&RenderResourceAssignments, &dyn RenderResourceContext)>,
) {
@ -153,9 +157,9 @@ impl PipelineDescriptor {
.as_ref()
.map(|handle| shaders.get(&handle).unwrap());
let mut layouts = vec![vertex_spirv.reflect_layout().unwrap()];
let mut layouts = vec![vertex_spirv.reflect_layout(bevy_conventions).unwrap()];
if let Some(ref fragment_spirv) = fragment_spirv {
layouts.push(fragment_spirv.reflect_layout().unwrap());
layouts.push(fragment_spirv.reflect_layout(bevy_conventions).unwrap());
}
let mut layout = PipelineLayout::from_shader_layouts(&mut layouts);

View file

@ -113,6 +113,7 @@ impl PipelineCompiler {
compiled_pipeline_descriptor.reflect_layout(
shaders,
true,
Some(vertex_buffer_descriptors),
Some((render_resource_assignments, render_resource_context)),
);

View file

@ -88,9 +88,9 @@ impl Shader {
}
}
pub fn reflect_layout(&self) -> Option<ShaderLayout> {
pub fn reflect_layout(&self, enforce_bevy_conventions: bool) -> Option<ShaderLayout> {
if let ShaderSource::Spirv(ref spirv) = self.source {
Some(ShaderLayout::from_spirv(spirv.as_slice()))
Some(ShaderLayout::from_spirv(spirv.as_slice(), enforce_bevy_conventions))
} else {
panic!("Cannot reflect layout of non-SpirV shader. Try compiling this shader to SpirV first using self.get_spirv_shader()");
}

View file

@ -36,7 +36,7 @@ pub struct ShaderLayout {
}
impl ShaderLayout {
pub fn from_spirv(spirv_data: &[u32]) -> ShaderLayout {
pub fn from_spirv(spirv_data: &[u32], bevy_conventions: bool) -> ShaderLayout {
match ShaderModule::load_u8_data(spirv_data.as_bytes()) {
Ok(ref mut module) => {
let entry_point_name = module.get_entry_point_name();
@ -62,21 +62,25 @@ impl ShaderLayout {
for vertex_attribute_descriptor in vertex_attribute_descriptors.drain(..) {
let mut instance = false;
let current_buffer_name = {
let parts = vertex_attribute_descriptor
.name
.splitn(3, "_")
.collect::<Vec<&str>>();
if parts.len() == 3 {
if parts[0] == "I" {
instance = true;
parts[1].to_string()
} else {
if bevy_conventions {
let parts = vertex_attribute_descriptor
.name
.splitn(3, "_")
.collect::<Vec<&str>>();
if parts.len() == 3 {
if parts[0] == "I" {
instance = true;
parts[1].to_string()
} else {
parts[0].to_string()
}
} else if parts.len() == 2 {
parts[0].to_string()
} else {
panic!("Vertex attributes must follow the form BUFFERNAME_PROPERTYNAME. For example: Vertex_Position");
}
} else if parts.len() == 2 {
parts[0].to_string()
} else {
panic!("Vertex attributes must follow the form BUFFERNAME_PROPERTYNAME. For example: Vertex_Position");
"DefaultVertex".to_string()
}
};
@ -360,7 +364,7 @@ mod tests {
)
.get_spirv_shader(None);
let layout = vertex_shader.reflect_layout().unwrap();
let layout = vertex_shader.reflect_layout(true).unwrap();
assert_eq!(
layout,
ShaderLayout {
@ -459,6 +463,6 @@ mod tests {
)
.get_spirv_shader(None);
let _layout = vertex_shader.reflect_layout().unwrap();
let _layout = vertex_shader.reflect_layout(true).unwrap();
}
}