@@ -4,6 +4,7 @@ use std::ops::Range;
44
55use wgpu;
66
7+ pub use crate :: wgpu:: vertex:: VertexStepMode ;
78use crate :: wgpu:: {
89 bind,
910 gpu:: Gpu ,
@@ -81,6 +82,14 @@ pub struct VertexAttributeDesc {
8182 pub format : ColorFormat ,
8283}
8384
85+ /// Description of a single vertex buffer layout used by a pipeline.
86+ #[ derive( Clone , Debug ) ]
87+ struct VertexBufferLayoutDesc {
88+ array_stride : u64 ,
89+ step_mode : VertexStepMode ,
90+ attributes : Vec < VertexAttributeDesc > ,
91+ }
92+
8493/// Compare function used for depth and stencil tests.
8594#[ derive( Clone , Copy , Debug ) ]
8695pub enum CompareFunction {
@@ -301,7 +310,7 @@ impl RenderPipeline {
301310pub struct RenderPipelineBuilder < ' a > {
302311 label : Option < String > ,
303312 layout : Option < & ' a wgpu:: PipelineLayout > ,
304- vertex_buffers : Vec < ( u64 , Vec < VertexAttributeDesc > ) > ,
313+ vertex_buffers : Vec < VertexBufferLayoutDesc > ,
305314 cull_mode : CullingMode ,
306315 color_target_format : Option < wgpu:: TextureFormat > ,
307316 depth_stencil : Option < wgpu:: DepthStencilState > ,
@@ -340,7 +349,26 @@ impl<'a> RenderPipelineBuilder<'a> {
340349 array_stride : u64 ,
341350 attributes : Vec < VertexAttributeDesc > ,
342351 ) -> Self {
343- self . vertex_buffers . push ( ( array_stride, attributes) ) ;
352+ self = self . with_vertex_buffer_step_mode (
353+ array_stride,
354+ VertexStepMode :: Vertex ,
355+ attributes,
356+ ) ;
357+ return self ;
358+ }
359+
360+ /// Add a vertex buffer layout with attributes and an explicit step mode.
361+ pub fn with_vertex_buffer_step_mode (
362+ mut self ,
363+ array_stride : u64 ,
364+ step_mode : VertexStepMode ,
365+ attributes : Vec < VertexAttributeDesc > ,
366+ ) -> Self {
367+ self . vertex_buffers . push ( VertexBufferLayoutDesc {
368+ array_stride,
369+ step_mode,
370+ attributes,
371+ } ) ;
344372 return self ;
345373 }
346374
@@ -431,11 +459,12 @@ impl<'a> RenderPipelineBuilder<'a> {
431459 // storage stable for layout lifetimes.
432460 let mut attr_storage: Vec < Box < [ wgpu:: VertexAttribute ] > > = Vec :: new ( ) ;
433461 let mut strides: Vec < u64 > = Vec :: new ( ) ;
434- for ( stride, attrs) in & self . vertex_buffers {
462+ let mut step_modes: Vec < VertexStepMode > = Vec :: new ( ) ;
463+ for buffer_desc in & self . vertex_buffers {
435464 let mut raw_attrs: Vec < wgpu:: VertexAttribute > =
436- Vec :: with_capacity ( attrs . len ( ) ) ;
465+ Vec :: with_capacity ( buffer_desc . attributes . len ( ) ) ;
437466
438- for attribute in attrs . iter ( ) {
467+ for attribute in buffer_desc . attributes . iter ( ) {
439468 raw_attrs. push ( wgpu:: VertexAttribute {
440469 shader_location : attribute. shader_location ,
441470 offset : attribute. offset ,
@@ -444,15 +473,16 @@ impl<'a> RenderPipelineBuilder<'a> {
444473 }
445474 let boxed: Box < [ wgpu:: VertexAttribute ] > = raw_attrs. into_boxed_slice ( ) ;
446475 attr_storage. push ( boxed) ;
447- strides. push ( * stride) ;
476+ strides. push ( buffer_desc. array_stride ) ;
477+ step_modes. push ( buffer_desc. step_mode ) ;
448478 }
449479 // Now build layouts referencing the stable storage in `attr_storage`.
450480 let mut vbl: Vec < wgpu:: VertexBufferLayout < ' _ > > = Vec :: new ( ) ;
451481 for ( i, boxed) in attr_storage. iter ( ) . enumerate ( ) {
452482 let slice = boxed. as_ref ( ) ;
453483 vbl. push ( wgpu:: VertexBufferLayout {
454484 array_stride : strides[ i] ,
455- step_mode : wgpu :: VertexStepMode :: Vertex ,
485+ step_mode : step_modes [ i ] . to_wgpu ( ) ,
456486 attributes : slice,
457487 } ) ;
458488 }
@@ -511,3 +541,37 @@ impl<'a> RenderPipelineBuilder<'a> {
511541 } ;
512542 }
513543}
544+
545+ #[ cfg( test) ]
546+ mod tests {
547+ use super :: * ;
548+
549+ #[ test]
550+ fn vertex_step_mode_maps_to_wgpu ( ) {
551+ let vertex_mode = VertexStepMode :: Vertex . to_wgpu ( ) ;
552+ let instance_mode = VertexStepMode :: Instance . to_wgpu ( ) ;
553+
554+ assert_eq ! ( vertex_mode, wgpu:: VertexStepMode :: Vertex ) ;
555+ assert_eq ! ( instance_mode, wgpu:: VertexStepMode :: Instance ) ;
556+ }
557+
558+ #[ test]
559+ fn with_vertex_buffer_defaults_to_per_vertex_step_mode ( ) {
560+ let builder = RenderPipelineBuilder :: new ( ) . with_vertex_buffer (
561+ 16 ,
562+ vec ! [ VertexAttributeDesc {
563+ shader_location: 0 ,
564+ offset: 0 ,
565+ format: ColorFormat :: Rgb32Sfloat ,
566+ } ] ,
567+ ) ;
568+
569+ let vertex_buffers = & builder. vertex_buffers ;
570+
571+ assert_eq ! ( vertex_buffers. len( ) , 1 ) ;
572+ assert ! ( matches!(
573+ vertex_buffers[ 0 ] . step_mode,
574+ VertexStepMode :: Vertex
575+ ) ) ;
576+ }
577+ }
0 commit comments