Skip to content

Commit

Permalink
delegate layout reflection to RenderResourceContext
Browse files Browse the repository at this point in the history
  • Loading branch information
mrk-its committed Oct 16, 2020
1 parent 7ba4584 commit 0e43afb
Show file tree
Hide file tree
Showing 9 changed files with 93 additions and 88 deletions.
4 changes: 2 additions & 2 deletions crates/bevy_pbr/src/entity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,15 @@ impl Default for PbrComponents {
FORWARD_PIPELINE_HANDLE,
PipelineSpecialization {
dynamic_bindings: vec![
// Transform
DynamicBinding {
bind_group: 2,
binding: 0,
name: "Transform".to_string(),
},
// StandardMaterial_albedo
DynamicBinding {
bind_group: 3,
binding: 0,
name: "StandardMaterial_albedo".to_string(),
},
],
..Default::default()
Expand Down
68 changes: 2 additions & 66 deletions crates/bevy_render/src/pipeline/pipeline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,12 @@ use super::{
CompareFunction, CullMode, DepthStencilStateDescriptor, FrontFace, IndexFormat,
PrimitiveTopology, RasterizationStateDescriptor, StencilStateFaceDescriptor,
},
BindType, DynamicBinding, PipelineLayout, StencilStateDescriptor, VertexBufferDescriptors,
PipelineLayout, StencilStateDescriptor
};
use crate::{
shader::{Shader, ShaderStages},
shader::ShaderStages,
texture::TextureFormat,
};
use bevy_asset::Assets;

#[derive(Clone, Debug)]
pub struct PipelineDescriptor {
Expand Down Expand Up @@ -115,67 +114,4 @@ impl PipelineDescriptor {
pub fn get_layout_mut(&mut self) -> Option<&mut PipelineLayout> {
self.layout.as_mut()
}

/// 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 `dynamic_bindings` has values, shader uniforms will be set to "dynamic" if there is a matching binding in the list
///
/// 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.
pub fn reflect_layout(
&mut self,
shaders: &Assets<Shader>,
bevy_conventions: bool,
vertex_buffer_descriptors: Option<&VertexBufferDescriptors>,
dynamic_bindings: &[DynamicBinding],
) {
let vertex_spirv = shaders.get(&self.shader_stages.vertex).unwrap();
let fragment_spirv = self
.shader_stages
.fragment
.as_ref()
.map(|handle| shaders.get(&handle).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(bevy_conventions).unwrap());
}

let mut layout = PipelineLayout::from_shader_layouts(&mut layouts);
if let Some(vertex_buffer_descriptors) = vertex_buffer_descriptors {
layout.sync_vertex_buffer_descriptors(vertex_buffer_descriptors);
}

if !dynamic_bindings.is_empty() {
// set binding uniforms to dynamic if render resource bindings use dynamic
for bind_group in layout.bind_groups.iter_mut() {
let mut binding_changed = false;
for binding in bind_group.bindings.iter_mut() {
let current = DynamicBinding {
bind_group: bind_group.index,
binding: binding.index,
};

if dynamic_bindings.contains(&current) {
if let BindType::Uniform {
ref mut dynamic, ..
} = binding.bind_type
{
*dynamic = true;
binding_changed = true;
}
}
}

if binding_changed {
bind_group.update_id();
}
}
}

self.layout = Some(layout);
}
}
14 changes: 9 additions & 5 deletions crates/bevy_render/src/pipeline/pipeline_compiler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ struct SpecializedPipeline {
pub struct DynamicBinding {
pub bind_group: u32,
pub binding: u32,
pub name: String,
}

#[derive(Debug, Default)]
Expand Down Expand Up @@ -158,11 +159,14 @@ impl PipelineCompiler {
)
});

specialized_descriptor.reflect_layout(
shaders,
true,
Some(vertex_buffer_descriptors),
&pipeline_specialization.dynamic_bindings,
specialized_descriptor.layout = Some(
render_resource_context.reflect_pipeline_layout(
&shaders,
&specialized_descriptor.shader_stages,
true,
Some(vertex_buffer_descriptors),
&pipeline_specialization.dynamic_bindings,
)
);

specialized_descriptor.sample_count = pipeline_specialization.sample_count;
Expand Down
66 changes: 64 additions & 2 deletions crates/bevy_render/src/renderer/render_resource_context.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
use crate::{
pipeline::{BindGroupDescriptorId, PipelineDescriptor},
pipeline::{
BindGroupDescriptorId, BindType, DynamicBinding, PipelineDescriptor, PipelineLayout,
VertexBufferDescriptors,
},
renderer::{BindGroup, BufferId, BufferInfo, RenderResourceId, SamplerId, TextureId},
shader::Shader,
shader::{Shader, ShaderLayout, ShaderStages},
texture::{SamplerDescriptor, TextureDescriptor},
};
use bevy_asset::{Assets, Handle, HandleUntyped};
Expand Down Expand Up @@ -60,6 +63,65 @@ pub trait RenderResourceContext: Downcast + Send + Sync + 'static {
bind_group: &BindGroup,
);
fn clear_bind_groups(&self);
/// 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 `dynamic_bindings` has values, shader uniforms will be set to "dynamic" if there is a matching binding in the list
///
/// 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.
fn reflect_pipeline_layout(
&self,
shaders: &Assets<Shader>,
shader_stages: &ShaderStages,
enforce_bevy_conventions: bool,
vertex_buffer_descriptors: Option<&VertexBufferDescriptors>,
dynamic_bindings: &[DynamicBinding],
) -> PipelineLayout {
// TODO: maybe move this default implementation to PipelineLayout?
let mut shader_layouts: Vec<ShaderLayout> = shader_stages
.iter()
.map(|handle| {
shaders
.get(&handle)
.unwrap()
.reflect_layout(enforce_bevy_conventions)
.unwrap()
})
.collect();
let mut layout = PipelineLayout::from_shader_layouts(&mut shader_layouts);
if !dynamic_bindings.is_empty() {
// set binding uniforms to dynamic if render resource bindings use dynamic
for bind_group in layout.bind_groups.iter_mut() {
let mut binding_changed = false;
for binding in bind_group.bindings.iter_mut() {
let current = (bind_group.index, binding.index);
if dynamic_bindings
.iter()
.any(|b| (b.bind_group, b.binding) == current)
{
if let BindType::Uniform {
ref mut dynamic, ..
} = binding.bind_type
{
*dynamic = true;
binding_changed = true;
}
}
}

if binding_changed {
bind_group.update_id();
}
}
}
if let Some(vertex_buffer_descriptors) = vertex_buffer_descriptors {
layout.sync_vertex_buffer_descriptors(vertex_buffer_descriptors);
}
layout
}
}

impl dyn RenderResourceContext {
Expand Down
1 change: 0 additions & 1 deletion crates/bevy_render/src/shader/shader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,6 @@ impl ShaderStages {
fragment: None,
}
}

pub fn iter(&self) -> ShaderStagesIterator {
ShaderStagesIterator {
shader_stages: &self,
Expand Down
6 changes: 4 additions & 2 deletions crates/bevy_sprite/src/entity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,13 @@ impl Default for SpriteComponents {
DynamicBinding {
bind_group: 2,
binding: 0,
name: "Transform".to_string(),
},
// Sprite
DynamicBinding {
bind_group: 2,
binding: 1,
name: "Sprite_size".to_string(),
},
],
..Default::default()
Expand Down Expand Up @@ -83,15 +85,15 @@ impl Default for SpriteSheetComponents {
SPRITE_SHEET_PIPELINE_HANDLE,
PipelineSpecialization {
dynamic_bindings: vec![
// Transform
DynamicBinding {
bind_group: 2,
binding: 0,
name: "Transform".to_string(),
},
// TextureAtlasSprite
DynamicBinding {
bind_group: 2,
binding: 1,
name: "TextureAtlasSprite".to_string(),
},
],
..Default::default()
Expand Down
10 changes: 6 additions & 4 deletions crates/bevy_ui/src/entity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,15 +36,15 @@ impl Default for NodeComponents {
UI_PIPELINE_HANDLE,
PipelineSpecialization {
dynamic_bindings: vec![
// Transform
DynamicBinding {
bind_group: 1,
binding: 0,
name: "Transform".to_string(),
},
// Node_size
DynamicBinding {
bind_group: 1,
binding: 1,
name: "Node_size".to_string(),
},
],
..Default::default()
Expand Down Expand Up @@ -86,11 +86,13 @@ impl Default for ImageComponents {
DynamicBinding {
bind_group: 1,
binding: 0,
name: "Transform".to_string(),
},
// Node_size
DynamicBinding {
bind_group: 1,
binding: 1,
name: "Node_size".to_string(),
},
],
..Default::default()
Expand Down Expand Up @@ -162,15 +164,15 @@ impl Default for ButtonComponents {
UI_PIPELINE_HANDLE,
PipelineSpecialization {
dynamic_bindings: vec![
// Transform
DynamicBinding {
bind_group: 1,
binding: 0,
name: "Transform".to_string(),
},
// Node_size
DynamicBinding {
bind_group: 1,
binding: 1,
name: "Node_size".to_string(),
},
],
..Default::default()
Expand Down
4 changes: 2 additions & 2 deletions examples/shader/shader_custom_material.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,15 +88,15 @@ fn setup(
// NOTE: in the future you wont need to manually declare dynamic bindings
PipelineSpecialization {
dynamic_bindings: vec![
// Transform
DynamicBinding {
bind_group: 1,
binding: 0,
name: "Transform".to_string(),
},
// MyMaterial_color
DynamicBinding {
bind_group: 1,
binding: 1,
name: "MyMaterial_color".to_string(),
},
],
..Default::default()
Expand Down
8 changes: 4 additions & 4 deletions examples/shader/shader_defs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,15 +109,15 @@ fn setup(
// NOTE: in the future you wont need to manually declare dynamic bindings
PipelineSpecialization {
dynamic_bindings: vec![
// Transform
DynamicBinding {
bind_group: 1,
binding: 0,
name: "Transform".to_string(),
},
// MyMaterial_color
DynamicBinding {
bind_group: 1,
binding: 1,
name: "MyMaterial_color".to_string(),
},
],
..Default::default()
Expand All @@ -135,15 +135,15 @@ fn setup(
// NOTE: in the future you wont need to manually declare dynamic bindings
PipelineSpecialization {
dynamic_bindings: vec![
// Transform
DynamicBinding {
bind_group: 1,
binding: 0,
name: "Transform".to_string(),
},
// MyMaterial_color
DynamicBinding {
bind_group: 1,
binding: 1,
name: "MyMaterial_color".to_string(),
},
],
..Default::default()
Expand Down

0 comments on commit 0e43afb

Please sign in to comment.