From 2b8f9d31b7ec2775e45721f95cf287023b884be7 Mon Sep 17 00:00:00 2001 From: Gray Olson Date: Thu, 24 Sep 2020 22:45:22 -0700 Subject: [PATCH 1/3] index buffer specialization --- crates/bevy_gltf/src/loader.rs | 10 +++-- crates/bevy_render/src/draw.rs | 13 +----- crates/bevy_render/src/mesh/mesh.rs | 44 +++++++++---------- .../src/pipeline/pipeline_compiler.rs | 5 ++- .../src/pipeline/render_pipelines.rs | 28 +++++++----- .../src/pipeline/state_descriptors.rs | 2 +- 6 files changed, 51 insertions(+), 51 deletions(-) diff --git a/crates/bevy_gltf/src/loader.rs b/crates/bevy_gltf/src/loader.rs index 4016d7d6631f4..f62ed044cbfed 100644 --- a/crates/bevy_gltf/src/loader.rs +++ b/crates/bevy_gltf/src/loader.rs @@ -1,11 +1,11 @@ use bevy_render::{ - mesh::{Mesh, VertexAttribute}, + mesh::{Indices, Mesh, VertexAttribute}, pipeline::PrimitiveTopology, }; use anyhow::Result; use bevy_asset::AssetLoader; -use gltf::{buffer::Source, mesh::Mode}; +use gltf::{buffer::Source, mesh::{Mode, util::ReadIndices}}; use std::{fs, io, path::Path}; use thiserror::Error; @@ -98,7 +98,11 @@ fn load_node(buffer_data: &[Vec], node: &gltf::Node, depth: i32) -> Result>()); + mesh.indices = match indices { + ReadIndices::U8(iter) => Some(Indices::U16(iter.map(|i| i as u16).collect())), + ReadIndices::U16(iter) => Some(Indices::U16(iter.collect())), + ReadIndices::U32(iter) => Some(Indices::U32(iter.collect())), + } }; return Ok(mesh); diff --git a/crates/bevy_render/src/draw.rs b/crates/bevy_render/src/draw.rs index f1ec867ea9b67..7ac303498e652 100644 --- a/crates/bevy_render/src/draw.rs +++ b/crates/bevy_render/src/draw.rs @@ -341,8 +341,7 @@ impl<'a> DrawContext<'a> { &self, draw: &mut Draw, render_resource_bindings: &[&RenderResourceBindings], - ) -> Result>, DrawError> { - let mut indices = None; + ) -> Result<(), DrawError> { let pipeline = self.current_pipeline.ok_or(DrawError::NoPipelineSet)?; let pipeline_descriptor = self .pipelines @@ -359,13 +358,6 @@ impl<'a> DrawContext<'a> { { draw.set_vertex_buffer(slot as u32, vertex_buffer, 0); if let Some(index_buffer) = index_buffer { - if let Some(buffer_info) = - self.render_resource_context.get_buffer_info(index_buffer) - { - indices = Some(0..(buffer_info.size / 2) as u32); - } else { - panic!("expected buffer type"); - } draw.set_index_buffer(index_buffer, 0); } @@ -373,8 +365,7 @@ impl<'a> DrawContext<'a> { } } } - - Ok(indices) + Ok(()) } } diff --git a/crates/bevy_render/src/mesh/mesh.rs b/crates/bevy_render/src/mesh/mesh.rs index 1eefc844b9144..1b3b52eb68ee6 100644 --- a/crates/bevy_render/src/mesh/mesh.rs +++ b/crates/bevy_render/src/mesh/mesh.rs @@ -1,11 +1,5 @@ use super::Vertex; -use crate::{ - pipeline::{ - AsVertexBufferDescriptor, IndexFormat, PrimitiveTopology, RenderPipelines, - VertexBufferDescriptor, VertexBufferDescriptors, VertexFormat, - }, - renderer::{BufferInfo, BufferUsage, RenderResourceContext, RenderResourceId}, -}; +use crate::{pipeline::{AsVertexBufferDescriptor, IndexFormat, PrimitiveTopology, RenderPipelines, VertexBufferDescriptor, VertexBufferDescriptors, VertexFormat}, renderer::{BufferInfo, BufferUsage, RenderResourceContext, RenderResourceId}}; use bevy_app::prelude::{EventReader, Events}; use bevy_asset::{AssetEvent, Assets, Handle}; use bevy_core::AsBytes; @@ -106,11 +100,17 @@ pub enum MeshToVertexBufferError { }, } +#[derive(Debug)] +pub enum Indices { + U16(Vec), + U32(Vec), +} + #[derive(Debug)] pub struct Mesh { pub primitive_topology: PrimitiveTopology, pub attributes: Vec, - pub indices: Option>, + pub indices: Option, } impl Mesh { @@ -159,23 +159,17 @@ impl Mesh { Ok(bytes) } - pub fn get_index_buffer_bytes(&self, index_format: IndexFormat) -> Option> { - self.indices.as_ref().map(|indices| match index_format { - IndexFormat::Uint16 => indices - .iter() - .map(|i| *i as u16) - .collect::>() - .as_slice() - .as_bytes() - .to_vec(), - IndexFormat::Uint32 => indices.as_slice().as_bytes().to_vec(), + pub fn get_index_buffer_bytes(&self) -> Option> { + self.indices.as_ref().map(|indices| match &indices { + Indices::U16(indices) => indices.as_slice().as_bytes().to_vec(), + Indices::U32(indices) => indices.as_slice().as_bytes().to_vec(), }) } } /// Generation for some primitive shape meshes. pub mod shape { - use super::{Mesh, VertexAttribute}; + use super::{Indices, Mesh, VertexAttribute}; use crate::pipeline::PrimitiveTopology; use bevy_math::*; use hexasphere::Hexasphere; @@ -237,14 +231,14 @@ pub mod shape { uvs.push(*uv); } - let indices = vec![ + let indices = Indices::U16(vec![ 0, 1, 2, 2, 3, 0, // top 4, 5, 6, 6, 7, 4, // bottom 8, 9, 10, 10, 11, 8, // right 12, 13, 14, 14, 15, 12, // left 16, 17, 18, 18, 19, 16, // front 20, 21, 22, 22, 23, 20, // back - ]; + ]); Mesh { primitive_topology: PrimitiveTopology::TriangleList, @@ -333,7 +327,7 @@ pub mod shape { ] }; - let indices = vec![0, 2, 1, 0, 3, 2]; + let indices = Indices::U16(vec![0, 2, 1, 0, 3, 2]); let mut positions = Vec::new(); let mut normals = Vec::new(); @@ -373,7 +367,7 @@ pub mod shape { ([-extent, 0.0, -extent], [0.0, 1.0, 0.0], [0.0, 1.0]), ]; - let indices = vec![0, 2, 1, 0, 3, 2]; + let indices = Indices::U16(vec![0, 2, 1, 0, 3, 2]); let mut positions = Vec::new(); let mut normals = Vec::new(); @@ -455,6 +449,8 @@ pub mod shape { hexasphere.get_indices(i, &mut indices); } + let indices = Indices::U32(indices); + Mesh { primitive_topology: PrimitiveTopology::TriangleList, attributes: vec![ @@ -544,7 +540,7 @@ pub fn mesh_resource_provider_system( &vertex_bytes, ); - let index_bytes = mesh.get_index_buffer_bytes(IndexFormat::Uint16).unwrap(); + let index_bytes = mesh.get_index_buffer_bytes().unwrap(); let index_buffer = render_resource_context.create_buffer_with_data( BufferInfo { buffer_usage: BufferUsage::INDEX, diff --git a/crates/bevy_render/src/pipeline/pipeline_compiler.rs b/crates/bevy_render/src/pipeline/pipeline_compiler.rs index a619e7075985a..597773d6d9fa6 100644 --- a/crates/bevy_render/src/pipeline/pipeline_compiler.rs +++ b/crates/bevy_render/src/pipeline/pipeline_compiler.rs @@ -1,4 +1,4 @@ -use super::{state_descriptors::PrimitiveTopology, PipelineDescriptor, VertexBufferDescriptors}; +use super::{IndexFormat, PipelineDescriptor, VertexBufferDescriptors, state_descriptors::PrimitiveTopology}; use crate::{ renderer::RenderResourceContext, shader::{Shader, ShaderSource}, @@ -14,6 +14,7 @@ pub struct PipelineSpecialization { pub shader_specialization: ShaderSpecialization, pub primitive_topology: PrimitiveTopology, pub dynamic_bindings: Vec, + pub index_format: IndexFormat, pub sample_count: u32, } @@ -24,6 +25,7 @@ impl Default for PipelineSpecialization { shader_specialization: Default::default(), primitive_topology: Default::default(), dynamic_bindings: Default::default(), + index_format: IndexFormat::Uint16, } } } @@ -161,6 +163,7 @@ impl PipelineCompiler { specialized_descriptor.sample_count = pipeline_specialization.sample_count; specialized_descriptor.primitive_topology = pipeline_specialization.primitive_topology; + specialized_descriptor.index_format = pipeline_specialization.index_format; let specialized_pipeline_handle = pipelines.add(specialized_descriptor); render_resource_context.create_render_pipeline( diff --git a/crates/bevy_render/src/pipeline/render_pipelines.rs b/crates/bevy_render/src/pipeline/render_pipelines.rs index 24b53985ab4c4..3db2becb335ad 100644 --- a/crates/bevy_render/src/pipeline/render_pipelines.rs +++ b/crates/bevy_render/src/pipeline/render_pipelines.rs @@ -1,10 +1,6 @@ -use super::{PipelineDescriptor, PipelineSpecialization}; -use crate::{ - draw::{Draw, DrawContext}, - prelude::Msaa, - renderer::RenderResourceBindings, -}; -use bevy_asset::Handle; +use super::{IndexFormat, PipelineDescriptor, PipelineSpecialization}; +use crate::{draw::{Draw, DrawContext}, mesh::Indices, mesh::Mesh, prelude::Msaa, renderer::RenderResourceBindings}; +use bevy_asset::{Assets, Handle}; use bevy_ecs::{Query, Res, ResMut}; use bevy_property::Properties; @@ -75,15 +71,25 @@ pub fn draw_render_pipelines_system( mut draw_context: DrawContext, mut render_resource_bindings: ResMut, msaa: Res, - mut query: Query<(&mut Draw, &mut RenderPipelines)>, + meshes: Res>, + mut query: Query<(&mut Draw, &mut RenderPipelines, &Handle)>, ) { - for (mut draw, mut render_pipelines) in &mut query.iter() { + for (mut draw, mut render_pipelines, mesh_handle) in &mut query.iter() { if !draw.is_visible { continue; } + + let mesh = meshes.get(mesh_handle).unwrap(); + let (index_range, index_format) = match mesh.indices.as_ref() { + Some(Indices::U32(indices)) => (Some(0..indices.len() as u32), IndexFormat::Uint32), + Some(Indices::U16(indices)) => (Some(0..indices.len() as u32), IndexFormat::Uint16), + None => (None, IndexFormat::Uint16), + }; + let render_pipelines = &mut *render_pipelines; for pipeline in render_pipelines.pipelines.iter_mut() { pipeline.specialization.sample_count = msaa.samples; + pipeline.specialization.index_format = index_format; } for render_pipeline in render_pipelines.pipelines.iter() { @@ -103,10 +109,10 @@ pub fn draw_render_pipelines_system( ], ) .unwrap(); - let indices = draw_context + draw_context .set_vertex_buffers_from_bindings(&mut draw, &[&render_pipelines.bindings]) .unwrap(); - if let Some(indices) = indices { + if let Some(indices) = index_range.clone() { draw.draw_indexed(indices, 0, 0..1); } } diff --git a/crates/bevy_render/src/pipeline/state_descriptors.rs b/crates/bevy_render/src/pipeline/state_descriptors.rs index 01adaa0e948e3..8e75f95050012 100644 --- a/crates/bevy_render/src/pipeline/state_descriptors.rs +++ b/crates/bevy_render/src/pipeline/state_descriptors.rs @@ -182,7 +182,7 @@ impl Default for BlendOperation { } } -#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)] +#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq, Serialize, Deserialize, Property)] pub enum IndexFormat { Uint16 = 0, Uint32 = 1, From 8a8e14392276a8a0a127c6848d83073f7cac63f5 Mon Sep 17 00:00:00 2001 From: Gray Olson Date: Thu, 24 Sep 2020 23:13:32 -0700 Subject: [PATCH 2/3] fmt --- crates/bevy_gltf/src/loader.rs | 5 ++++- crates/bevy_render/src/mesh/mesh.rs | 8 +++++++- crates/bevy_render/src/pipeline/pipeline_compiler.rs | 4 +++- crates/bevy_render/src/pipeline/render_pipelines.rs | 7 ++++++- 4 files changed, 20 insertions(+), 4 deletions(-) diff --git a/crates/bevy_gltf/src/loader.rs b/crates/bevy_gltf/src/loader.rs index f62ed044cbfed..fe5d92d692fed 100644 --- a/crates/bevy_gltf/src/loader.rs +++ b/crates/bevy_gltf/src/loader.rs @@ -5,7 +5,10 @@ use bevy_render::{ use anyhow::Result; use bevy_asset::AssetLoader; -use gltf::{buffer::Source, mesh::{Mode, util::ReadIndices}}; +use gltf::{ + buffer::Source, + mesh::{util::ReadIndices, Mode}, +}; use std::{fs, io, path::Path}; use thiserror::Error; diff --git a/crates/bevy_render/src/mesh/mesh.rs b/crates/bevy_render/src/mesh/mesh.rs index 1b3b52eb68ee6..c7527c242c750 100644 --- a/crates/bevy_render/src/mesh/mesh.rs +++ b/crates/bevy_render/src/mesh/mesh.rs @@ -1,5 +1,11 @@ use super::Vertex; -use crate::{pipeline::{AsVertexBufferDescriptor, IndexFormat, PrimitiveTopology, RenderPipelines, VertexBufferDescriptor, VertexBufferDescriptors, VertexFormat}, renderer::{BufferInfo, BufferUsage, RenderResourceContext, RenderResourceId}}; +use crate::{ + pipeline::{ + AsVertexBufferDescriptor, IndexFormat, PrimitiveTopology, RenderPipelines, + VertexBufferDescriptor, VertexBufferDescriptors, VertexFormat, + }, + renderer::{BufferInfo, BufferUsage, RenderResourceContext, RenderResourceId}, +}; use bevy_app::prelude::{EventReader, Events}; use bevy_asset::{AssetEvent, Assets, Handle}; use bevy_core::AsBytes; diff --git a/crates/bevy_render/src/pipeline/pipeline_compiler.rs b/crates/bevy_render/src/pipeline/pipeline_compiler.rs index 597773d6d9fa6..d611b62ea7c61 100644 --- a/crates/bevy_render/src/pipeline/pipeline_compiler.rs +++ b/crates/bevy_render/src/pipeline/pipeline_compiler.rs @@ -1,4 +1,6 @@ -use super::{IndexFormat, PipelineDescriptor, VertexBufferDescriptors, state_descriptors::PrimitiveTopology}; +use super::{ + state_descriptors::PrimitiveTopology, IndexFormat, PipelineDescriptor, VertexBufferDescriptors, +}; use crate::{ renderer::RenderResourceContext, shader::{Shader, ShaderSource}, diff --git a/crates/bevy_render/src/pipeline/render_pipelines.rs b/crates/bevy_render/src/pipeline/render_pipelines.rs index 3db2becb335ad..7d97165ea846c 100644 --- a/crates/bevy_render/src/pipeline/render_pipelines.rs +++ b/crates/bevy_render/src/pipeline/render_pipelines.rs @@ -1,5 +1,10 @@ use super::{IndexFormat, PipelineDescriptor, PipelineSpecialization}; -use crate::{draw::{Draw, DrawContext}, mesh::Indices, mesh::Mesh, prelude::Msaa, renderer::RenderResourceBindings}; +use crate::{ + draw::{Draw, DrawContext}, + mesh::{Indices, Mesh}, + prelude::Msaa, + renderer::RenderResourceBindings, +}; use bevy_asset::{Assets, Handle}; use bevy_ecs::{Query, Res, ResMut}; use bevy_property::Properties; From f92a309eb0aae595306b45df0b6e847cc44f156e Mon Sep 17 00:00:00 2001 From: Gray Olson Date: Fri, 25 Sep 2020 00:53:45 -0700 Subject: [PATCH 3/3] clippy --- crates/bevy_render/src/mesh/mesh.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/bevy_render/src/mesh/mesh.rs b/crates/bevy_render/src/mesh/mesh.rs index c7527c242c750..b717e4e30efc6 100644 --- a/crates/bevy_render/src/mesh/mesh.rs +++ b/crates/bevy_render/src/mesh/mesh.rs @@ -1,8 +1,8 @@ use super::Vertex; use crate::{ pipeline::{ - AsVertexBufferDescriptor, IndexFormat, PrimitiveTopology, RenderPipelines, - VertexBufferDescriptor, VertexBufferDescriptors, VertexFormat, + AsVertexBufferDescriptor, PrimitiveTopology, RenderPipelines, VertexBufferDescriptor, + VertexBufferDescriptors, VertexFormat, }, renderer::{BufferInfo, BufferUsage, RenderResourceContext, RenderResourceId}, };