pathfinder: set vertex buffer descriptors
This commit is contained in:
		
							parent
							
								
									35e1d8b498
								
							
						
					
					
						commit
						ef2e5a1ba3
					
				| @ -21,3 +21,4 @@ pathfinder_color = { path = "../pathfinder/color" } | ||||
| pathfinder_canvas = { path = "../pathfinder/canvas" } | ||||
| 
 | ||||
| zerocopy = "0.3.0" | ||||
| byteorder = "1.3" | ||||
|  | ||||
| @ -22,15 +22,16 @@ use bevy_render::{ | ||||
|     }, | ||||
|     Color, | ||||
| }; | ||||
| use byteorder::{NativeEndian, WriteBytesExt}; | ||||
| use pathfinder_canvas::vec2i; | ||||
| use pathfinder_geometry::{rect::RectI, vector::Vector2I}; | ||||
| use pathfinder_gpu::{ | ||||
|     BufferData, BufferTarget, BufferUploadMode, Device, FeatureLevel, ProgramKind, RenderState, | ||||
|     RenderTarget, ShaderKind, TextureData, TextureDataRef, TextureSamplingFlags, VertexAttrClass, | ||||
|     VertexAttrDescriptor, VertexAttrType, | ||||
|     RenderTarget, ShaderKind, TextureData, TextureDataRef, TextureSamplingFlags, UniformData, | ||||
|     VertexAttrClass, VertexAttrDescriptor, VertexAttrType, | ||||
| }; | ||||
| use pathfinder_resources::ResourceLoader; | ||||
| use std::{borrow::Cow, cell::RefCell, collections::HashMap, mem, rc::Rc, time::Duration}; | ||||
| use std::{borrow::Cow, cell::RefCell, collections::HashMap, mem, rc::Rc, time::Duration, ops::Range}; | ||||
| use zerocopy::AsBytes; | ||||
| 
 | ||||
| pub struct BevyPathfinderDevice<'a> { | ||||
| @ -59,10 +60,31 @@ impl<'a> BevyPathfinderDevice<'a> { | ||||
| 
 | ||||
|     pub fn prepare_to_draw(&self, render_state: &RenderState<BevyPathfinderDevice>) { | ||||
|         let pass_descriptor = self.create_pass_descriptor(render_state); | ||||
|         self.update_pipline_descriptor(render_state, &pass_descriptor); | ||||
|         // setup uniforms
 | ||||
|         self.setup_pipline_descriptor(render_state, &pass_descriptor, &render_state.vertex_array.requested_descriptors.borrow()); | ||||
|         // TODO: setup uniforms
 | ||||
|         let mut render_context = self.render_context.borrow_mut(); | ||||
|         let render_resource_assignments = RenderResourceAssignments::default(); | ||||
|         let mut render_resource_assignments = RenderResourceAssignments::default(); | ||||
|         for (i, vertex_buffer) in render_state | ||||
|             .vertex_array | ||||
|             .vertex_buffers | ||||
|             .borrow() | ||||
|             .iter() | ||||
|             .enumerate() | ||||
|         { | ||||
|             let resource = vertex_buffer.handle.borrow().unwrap(); | ||||
|             let mut indices_resource = None; | ||||
|             if i == 0 { | ||||
|                 if let Some(ref index_buffer) = *render_state.vertex_array.index_buffer.borrow() { | ||||
|                     indices_resource = Some(index_buffer.handle.borrow().unwrap()); | ||||
|                 } | ||||
|             } | ||||
|             render_resource_assignments.set_vertex_buffer(get_vertex_buffer_name(i), resource, indices_resource); | ||||
|         } | ||||
| 
 | ||||
|         // if let Some(ref index_buffer) = *render_state.vertex_array.index_buffer.borrow() {
 | ||||
|         //     let resource = index_buffer.handle.borrow().unwrap();
 | ||||
|         //     pass.set_index_buffer(resource, 0);
 | ||||
|         // }
 | ||||
|         render_context.begin_pass( | ||||
|             &pass_descriptor, | ||||
|             &render_resource_assignments, | ||||
| @ -81,21 +103,8 @@ impl<'a> BevyPathfinderDevice<'a> { | ||||
|                     pass.set_stencil_reference(stencil_state.reference); | ||||
|                 } | ||||
| 
 | ||||
|                 for (i, vertex_buffer) in render_state | ||||
|                     .vertex_array | ||||
|                     .vertex_buffers | ||||
|                     .borrow() | ||||
|                     .iter() | ||||
|                     .enumerate() | ||||
|                 { | ||||
|                     let resource = vertex_buffer.handle.borrow().unwrap(); | ||||
|                     pass.set_vertex_buffer(i as u32, resource, 0); | ||||
|                 } | ||||
| 
 | ||||
|                 if let Some(ref index_buffer) = *render_state.vertex_array.index_buffer.borrow(){ | ||||
|                     let resource = index_buffer.handle.borrow().unwrap(); | ||||
|                     pass.set_index_buffer(resource, 0); | ||||
|                 } 
 | ||||
|                 let pipeline_descriptor = render_state.program.pipeline_descriptor.borrow(); | ||||
|                 pass.set_render_resources(&pipeline_descriptor, &render_resource_assignments); | ||||
|             }, | ||||
|         ) | ||||
|     } | ||||
| @ -119,16 +128,37 @@ impl<'a> BevyPathfinderDevice<'a> { | ||||
|         Some(TextureFormat::Bgra8UnormSrgb) | ||||
|     } | ||||
| 
 | ||||
|     pub fn update_pipline_descriptor( | ||||
|     pub fn setup_pipline_descriptor( | ||||
|         &self, | ||||
|         render_state: &RenderState<BevyPathfinderDevice>, | ||||
|         pass_descriptor: &PassDescriptor, | ||||
|         requested_vertex_descriptors: &HashMap<u32, VertexBufferDescriptor>, | ||||
|     ) { | ||||
|         if self.render_context.borrow().resources().get_asset_resource(render_state.program.pipeline_handle, 0).is_some() { | ||||
|             return | ||||
|         if self | ||||
|             .render_context | ||||
|             .borrow() | ||||
|             .resources() | ||||
|             .get_asset_resource(render_state.program.pipeline_handle, 0) | ||||
|             .is_some() | ||||
|         { | ||||
|             return; | ||||
|         } | ||||
|         
 | ||||
|         let mut pipeline_descriptor = render_state.program.pipeline_descriptor.borrow_mut(); | ||||
|         { | ||||
|             let mut layout = pipeline_descriptor.get_layout_mut().unwrap(); | ||||
|             let mut i = 0; | ||||
|             let mut descriptors = Vec::with_capacity(requested_vertex_descriptors.len()); | ||||
|             loop { | ||||
|                 if let Some(descriptor) = requested_vertex_descriptors.get(&i) { | ||||
|                     descriptors.push(descriptor.clone()); | ||||
|                     i += 1; 
 | ||||
|                 } else { | ||||
|                     break; | ||||
|                 } | ||||
|             } | ||||
|             layout.vertex_buffer_descriptors = descriptors; | ||||
|         } | ||||
| 
 | ||||
|         let color_texture_format = if let TextureAttachment::RenderResource(texture_resource) = | ||||
|             pass_descriptor | ||||
|                 .color_attachments | ||||
| @ -218,6 +248,15 @@ impl<'a> BevyPathfinderDevice<'a> { | ||||
|                 descriptor.stencil_back = stencil_descriptor; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         self.render_context | ||||
|             .borrow() | ||||
|             .resources() | ||||
|             .create_render_pipeline( | ||||
|                 render_state.program.pipeline_handle, | ||||
|                 &pipeline_descriptor, | ||||
|                 &self.shaders.borrow(), | ||||
|             ); | ||||
|     } | ||||
| 
 | ||||
|     pub fn create_pass_descriptor( | ||||
| @ -278,6 +317,114 @@ impl<'a> BevyPathfinderDevice<'a> { | ||||
|             sample_count: 1, | ||||
|         } | ||||
|     } | ||||
|     fn create_uniform_buffer(&self, uniforms: &[(&BevyUniform, UniformData)]) -> UniformBuffer { | ||||
|         let (mut uniform_buffer_data, mut uniform_buffer_ranges) = (vec![], vec![]); | ||||
|         for &(_, uniform_data) in uniforms.iter() { | ||||
|             let start_index = uniform_buffer_data.len(); | ||||
|             match uniform_data { | ||||
|                 UniformData::Float(value) => uniform_buffer_data | ||||
|                     .write_f32::<NativeEndian>(value) | ||||
|                     .unwrap(), | ||||
|                 UniformData::IVec2(vector) => { | ||||
|                     uniform_buffer_data | ||||
|                         .write_i32::<NativeEndian>(vector.x()) | ||||
|                         .unwrap(); | ||||
|                     uniform_buffer_data | ||||
|                         .write_i32::<NativeEndian>(vector.y()) | ||||
|                         .unwrap(); | ||||
|                 } | ||||
|                 UniformData::IVec3(values) => { | ||||
|                     uniform_buffer_data | ||||
|                         .write_i32::<NativeEndian>(values[0]) | ||||
|                         .unwrap(); | ||||
|                     uniform_buffer_data | ||||
|                         .write_i32::<NativeEndian>(values[1]) | ||||
|                         .unwrap(); | ||||
|                     uniform_buffer_data | ||||
|                         .write_i32::<NativeEndian>(values[2]) | ||||
|                         .unwrap(); | ||||
|                 } | ||||
|                 UniformData::Int(value) => uniform_buffer_data | ||||
|                     .write_i32::<NativeEndian>(value) | ||||
|                     .unwrap(), | ||||
|                 UniformData::Mat2(matrix) => { | ||||
|                     uniform_buffer_data | ||||
|                         .write_f32::<NativeEndian>(matrix.x()) | ||||
|                         .unwrap(); | ||||
|                     uniform_buffer_data | ||||
|                         .write_f32::<NativeEndian>(matrix.y()) | ||||
|                         .unwrap(); | ||||
|                     uniform_buffer_data | ||||
|                         .write_f32::<NativeEndian>(matrix.z()) | ||||
|                         .unwrap(); | ||||
|                     uniform_buffer_data | ||||
|                         .write_f32::<NativeEndian>(matrix.w()) | ||||
|                         .unwrap(); | ||||
|                 } | ||||
|                 UniformData::Mat4(matrix) => { | ||||
|                     for column in &matrix { | ||||
|                         uniform_buffer_data | ||||
|                             .write_f32::<NativeEndian>(column.x()) | ||||
|                             .unwrap(); | ||||
|                         uniform_buffer_data | ||||
|                             .write_f32::<NativeEndian>(column.y()) | ||||
|                             .unwrap(); | ||||
|                         uniform_buffer_data | ||||
|                             .write_f32::<NativeEndian>(column.z()) | ||||
|                             .unwrap(); | ||||
|                         uniform_buffer_data | ||||
|                             .write_f32::<NativeEndian>(column.w()) | ||||
|                             .unwrap(); | ||||
|                     } | ||||
|                 } | ||||
|                 UniformData::Vec2(vector) => { | ||||
|                     uniform_buffer_data | ||||
|                         .write_f32::<NativeEndian>(vector.x()) | ||||
|                         .unwrap(); | ||||
|                     uniform_buffer_data | ||||
|                         .write_f32::<NativeEndian>(vector.y()) | ||||
|                         .unwrap(); | ||||
|                 } | ||||
|                 UniformData::Vec3(array) => { | ||||
|                     uniform_buffer_data | ||||
|                         .write_f32::<NativeEndian>(array[0]) | ||||
|                         .unwrap(); | ||||
|                     uniform_buffer_data | ||||
|                         .write_f32::<NativeEndian>(array[1]) | ||||
|                         .unwrap(); | ||||
|                     uniform_buffer_data | ||||
|                         .write_f32::<NativeEndian>(array[2]) | ||||
|                         .unwrap(); | ||||
|                 } | ||||
|                 UniformData::Vec4(vector) => { | ||||
|                     uniform_buffer_data | ||||
|                         .write_f32::<NativeEndian>(vector.x()) | ||||
|                         .unwrap(); | ||||
|                     uniform_buffer_data | ||||
|                         .write_f32::<NativeEndian>(vector.y()) | ||||
|                         .unwrap(); | ||||
|                     uniform_buffer_data | ||||
|                         .write_f32::<NativeEndian>(vector.z()) | ||||
|                         .unwrap(); | ||||
|                     uniform_buffer_data | ||||
|                         .write_f32::<NativeEndian>(vector.w()) | ||||
|                         .unwrap(); | ||||
|                 } | ||||
|                 UniformData::TextureUnit(_) | UniformData::ImageUnit(_) => {} | ||||
|             } | ||||
|             // TODO: this padding might not be necessary
 | ||||
|             let end_index = uniform_buffer_data.len(); | ||||
|             while uniform_buffer_data.len() % 256 != 0 { | ||||
|                 uniform_buffer_data.push(0); | ||||
|             } | ||||
|             uniform_buffer_ranges.push(start_index..end_index); | ||||
|         } | ||||
| 
 | ||||
|         UniformBuffer { | ||||
|             data: uniform_buffer_data, | ||||
|             ranges: uniform_buffer_ranges, | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| pub struct BevyTimerQuery {} | ||||
| @ -482,6 +629,7 @@ impl<'a> Device for BevyPathfinderDevice<'a> { | ||||
|         bevy_attr: &BevyVertexAttr, | ||||
|         descriptor: &VertexAttrDescriptor, | ||||
|     ) { | ||||
|         println!("configure"); | ||||
|         let format = match (descriptor.class, descriptor.attr_type, descriptor.size) { | ||||
|             (VertexAttrClass::Int, VertexAttrType::I8, 2) => VertexFormat::Char2, | ||||
|             // (VertexAttrClass::Int, VertexAttrType::I8, 3) => VertexFormat::Char3,
 | ||||
| @ -564,7 +712,7 @@ impl<'a> Device for BevyPathfinderDevice<'a> { | ||||
|             requested_descriptors | ||||
|                 .entry(buffer_index) | ||||
|                 .or_insert_with(|| VertexBufferDescriptor { | ||||
|                     name: Cow::Borrowed("placeholder"), | ||||
|                     name: Cow::Borrowed(get_vertex_buffer_name(buffer_index as usize)), | ||||
|                     attributes: Vec::new(), | ||||
|                     step_mode, | ||||
|                     stride: descriptor.stride as u64, | ||||
| @ -924,3 +1072,23 @@ impl ToBevyCompareFunction for pathfinder_gpu::StencilFunc { | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| struct UniformBuffer { | ||||
|     data: Vec<u8>, | ||||
|     ranges: Vec<Range<usize>>, | ||||
| } | ||||
| 
 | ||||
| pub const pathfinder_vertex_buffer_0: &'static str = "P0";  
 | ||||
| pub const pathfinder_vertex_buffer_1: &'static str = "P1";  
 | ||||
| pub const pathfinder_vertex_buffer_2: &'static str = "P2";  
 | ||||
| pub const pathfinder_vertex_buffer_3: &'static str = "P3";  
 | ||||
| 
 | ||||
| pub fn get_vertex_buffer_name(index: usize) -> &'static str { | ||||
|     match index { | ||||
|         0 => pathfinder_vertex_buffer_0, | ||||
|         1 => pathfinder_vertex_buffer_1, | ||||
|         2 => pathfinder_vertex_buffer_2, | ||||
|         3 => pathfinder_vertex_buffer_3, | ||||
|         _ => panic!("encountered unknown vertex buffer index"), | ||||
|     } | ||||
| } | ||||
| @ -20,6 +20,7 @@ pub enum Command { | ||||
|         destination_array_layer: u32, | ||||
|         size: Extent3d, | ||||
|     }, | ||||
|     // TODO: Frees probably don't need to be queued?
 | ||||
|     FreeBuffer(RenderResource), | ||||
| } | ||||
| 
 | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Carter Anderson
						Carter Anderson