From 5e5df2bb87fb92b58d599cca5610ba996d5d628e Mon Sep 17 00:00:00 2001 From: Carter Anderson Date: Thu, 7 May 2020 19:09:25 -0700 Subject: [PATCH] toggle-able "bevy conventions" in shaders --- crates/bevy_render/src/pipeline/pipeline.rs | 8 +++-- .../src/pipeline/pipeline_compiler.rs | 1 + crates/bevy_render/src/shader/shader.rs | 4 +-- .../bevy_render/src/shader/shader_reflect.rs | 34 +++++++++++-------- 4 files changed, 28 insertions(+), 19 deletions(-) diff --git a/crates/bevy_render/src/pipeline/pipeline.rs b/crates/bevy_render/src/pipeline/pipeline.rs index 6c172ba16e..71e18ec00d 100644 --- a/crates/bevy_render/src/pipeline/pipeline.rs +++ b/crates/bevy_render/src/pipeline/pipeline.rs @@ -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, + 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); diff --git a/crates/bevy_render/src/pipeline/pipeline_compiler.rs b/crates/bevy_render/src/pipeline/pipeline_compiler.rs index 4094a3eadb..c2fbb492e0 100644 --- a/crates/bevy_render/src/pipeline/pipeline_compiler.rs +++ b/crates/bevy_render/src/pipeline/pipeline_compiler.rs @@ -113,6 +113,7 @@ impl PipelineCompiler { compiled_pipeline_descriptor.reflect_layout( shaders, + true, Some(vertex_buffer_descriptors), Some((render_resource_assignments, render_resource_context)), ); diff --git a/crates/bevy_render/src/shader/shader.rs b/crates/bevy_render/src/shader/shader.rs index 5e7c324393..09408733be 100644 --- a/crates/bevy_render/src/shader/shader.rs +++ b/crates/bevy_render/src/shader/shader.rs @@ -88,9 +88,9 @@ impl Shader { } } - pub fn reflect_layout(&self) -> Option { + pub fn reflect_layout(&self, enforce_bevy_conventions: bool) -> Option { 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()"); } diff --git a/crates/bevy_render/src/shader/shader_reflect.rs b/crates/bevy_render/src/shader/shader_reflect.rs index da040b16e9..d0194c41d8 100644 --- a/crates/bevy_render/src/shader/shader_reflect.rs +++ b/crates/bevy_render/src/shader/shader_reflect.rs @@ -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::>(); - 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::>(); + 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(); } }