bevy/crates/bevy_render/src/pipeline/pipeline_layout.rs

131 lines
4.8 KiB
Rust
Raw Normal View History

use super::{BindGroupDescriptor, VertexBufferDescriptor, VertexBufferDescriptors};
2020-06-04 03:08:20 +00:00
use crate::shader::{ShaderLayout, GL_VERTEX_INDEX};
2020-03-10 06:08:09 +00:00
use std::{collections::HashMap, hash::Hash};
#[derive(Clone, Debug, Default)]
2020-03-10 06:08:09 +00:00
pub struct PipelineLayout {
pub bind_groups: Vec<BindGroupDescriptor>,
pub vertex_buffer_descriptors: Vec<VertexBufferDescriptor>,
2020-03-10 06:08:09 +00:00
}
impl PipelineLayout {
pub fn get_bind_group(&self, index: u32) -> Option<&BindGroupDescriptor> {
self.bind_groups
.iter()
.find(|bind_group| bind_group.index == index)
}
2020-03-10 06:08:09 +00:00
pub fn from_shader_layouts(shader_layouts: &mut [ShaderLayout]) -> Self {
let mut bind_groups = HashMap::<u32, BindGroupDescriptor>::new();
let mut vertex_buffer_descriptors = Vec::new();
for shader_layout in shader_layouts.iter_mut() {
2020-03-10 06:08:09 +00:00
for shader_bind_group in shader_layout.bind_groups.iter_mut() {
match bind_groups.get_mut(&shader_bind_group.index) {
Some(bind_group) => {
for shader_binding in shader_bind_group.bindings.iter() {
if let Some(binding) = bind_group
.bindings
.iter()
.find(|binding| binding.index == shader_binding.index)
{
if binding != shader_binding {
panic!("Binding {} in BindGroup {} does not match across all shader types: {:?} {:?}", binding.index, bind_group.index, binding, shader_binding);
}
} else {
2020-03-28 05:41:45 +00:00
bind_group.bindings.push(shader_binding.clone());
2020-03-10 06:08:09 +00:00
}
}
}
None => {
bind_groups.insert(shader_bind_group.index, shader_bind_group.clone());
}
}
}
}
for vertex_buffer_descriptor in shader_layouts[0].vertex_buffer_descriptors.iter() {
vertex_buffer_descriptors.push(vertex_buffer_descriptor.clone());
}
2020-03-10 06:08:09 +00:00
let mut bind_groups_result = bind_groups
.drain()
.map(|(_, value)| value)
.collect::<Vec<BindGroupDescriptor>>();
2020-03-10 06:08:09 +00:00
// NOTE: for some reason bind groups need to be sorted by index. this is likely an issue with bevy and not with wgpu
// TODO: try removing this
2020-03-10 06:08:09 +00:00
bind_groups_result.sort_by(|a, b| a.index.partial_cmp(&b.index).unwrap());
2020-03-10 06:08:09 +00:00
PipelineLayout {
bind_groups: bind_groups_result,
vertex_buffer_descriptors,
}
}
pub fn sync_vertex_buffer_descriptors(
&mut self,
vertex_buffer_descriptors: &VertexBufferDescriptors,
) {
for vertex_buffer_descriptor in self.vertex_buffer_descriptors.iter_mut() {
if let Some(graph_descriptor) =
vertex_buffer_descriptors.get(&vertex_buffer_descriptor.name)
{
vertex_buffer_descriptor.sync_with_descriptor(graph_descriptor);
} else if vertex_buffer_descriptor.name == GL_VERTEX_INDEX {
// GL_VERTEX_INDEX is a special attribute set on our behalf
continue;
} else {
panic!(
"Encountered unsupported Vertex Buffer: {}",
vertex_buffer_descriptor.name
);
}
2020-03-10 06:08:09 +00:00
}
}
}
#[derive(Hash, Clone, Debug, Eq, PartialEq, Ord, PartialOrd)]
pub struct UniformProperty {
pub name: String,
pub property_type: UniformPropertyType,
}
#[derive(Hash, Clone, Debug, Eq, PartialEq, Ord, PartialOrd)]
pub enum UniformPropertyType {
// TODO: Use VertexFormat here
UInt,
2020-03-10 06:08:09 +00:00
Int,
IVec2,
2020-03-10 06:08:09 +00:00
Float,
UVec4,
2020-05-03 19:35:07 +00:00
Vec2,
2020-03-10 06:08:09 +00:00
Vec3,
Vec4,
Mat3,
Mat4,
Struct(Vec<UniformProperty>),
Array(Box<UniformPropertyType>, usize),
}
impl UniformPropertyType {
pub fn get_size(&self) -> u64 {
match self {
UniformPropertyType::UInt => 4,
2020-03-10 06:08:09 +00:00
UniformPropertyType::Int => 4,
UniformPropertyType::IVec2 => 4 * 2,
2020-03-10 06:08:09 +00:00
UniformPropertyType::Float => 4,
UniformPropertyType::UVec4 => 4 * 4,
2020-05-03 19:35:07 +00:00
UniformPropertyType::Vec2 => 4 * 2,
2020-03-10 06:08:09 +00:00
UniformPropertyType::Vec3 => 4 * 3,
UniformPropertyType::Vec4 => 4 * 4,
UniformPropertyType::Mat3 => 4 * 4 * 3,
UniformPropertyType::Mat4 => 4 * 4 * 4,
UniformPropertyType::Struct(properties) => properties
.iter()
.map(|p| p.property_type.get_size())
.fold(0, |total, size| total + size),
UniformPropertyType::Array(property, length) => property.get_size() * *length as u64,
}
}
}