@@ -1125,53 +1125,61 @@ impl crate::Device for super::Device {
11251125 let vs_info;
11261126 let ts_info;
11271127 let ms_info;
1128+
1129+ // Create the pipeline descriptor and do vertex/mesh pipeline specific setup
11281130 let descriptor = match desc. vertex_processor {
11291131 crate :: VertexProcessor :: Standard {
11301132 vertex_buffers,
11311133 ref vertex_stage,
11321134 } => {
1135+ // Vertex pipeline specific setup
1136+
11331137 let descriptor = metal:: RenderPipelineDescriptor :: new ( ) ;
11341138 ts_info = None ;
11351139 ms_info = None ;
1136- vs_info = Some ( {
1137- let mut vertex_buffer_mappings =
1138- Vec :: < naga:: back:: msl:: VertexBufferMapping > :: new ( ) ;
1139- for ( i, vbl) in vertex_buffers. iter ( ) . enumerate ( ) {
1140- let mut attributes = Vec :: < naga:: back:: msl:: AttributeMapping > :: new ( ) ;
1141- for attribute in vbl. attributes . iter ( ) {
1142- attributes. push ( naga:: back:: msl:: AttributeMapping {
1143- shader_location : attribute. shader_location ,
1144- offset : attribute. offset as u32 ,
1145- format : convert_vertex_format_to_naga ( attribute. format ) ,
1146- } ) ;
1147- }
11481140
1149- vertex_buffer_mappings. push ( naga:: back:: msl:: VertexBufferMapping {
1150- id : self . shared . private_caps . max_vertex_buffers - 1 - i as u32 ,
1151- stride : if vbl. array_stride > 0 {
1152- vbl. array_stride . try_into ( ) . unwrap ( )
1153- } else {
1154- vbl. attributes
1155- . iter ( )
1156- . map ( |attribute| attribute. offset + attribute. format . size ( ) )
1157- . max ( )
1158- . unwrap_or ( 0 )
1159- . try_into ( )
1160- . unwrap ( )
1161- } ,
1162- step_mode : match ( vbl. array_stride == 0 , vbl. step_mode ) {
1163- ( true , _) => naga:: back:: msl:: VertexBufferStepMode :: Constant ,
1164- ( false , wgt:: VertexStepMode :: Vertex ) => {
1165- naga:: back:: msl:: VertexBufferStepMode :: ByVertex
1166- }
1167- ( false , wgt:: VertexStepMode :: Instance ) => {
1168- naga:: back:: msl:: VertexBufferStepMode :: ByInstance
1169- }
1170- } ,
1171- attributes,
1141+ // Collect vertex buffer mappings
1142+ let mut vertex_buffer_mappings =
1143+ Vec :: < naga:: back:: msl:: VertexBufferMapping > :: new ( ) ;
1144+ for ( i, vbl) in vertex_buffers. iter ( ) . enumerate ( ) {
1145+ let mut attributes = Vec :: < naga:: back:: msl:: AttributeMapping > :: new ( ) ;
1146+ for attribute in vbl. attributes . iter ( ) {
1147+ attributes. push ( naga:: back:: msl:: AttributeMapping {
1148+ shader_location : attribute. shader_location ,
1149+ offset : attribute. offset as u32 ,
1150+ format : convert_vertex_format_to_naga ( attribute. format ) ,
11721151 } ) ;
11731152 }
11741153
1154+ let mapping = naga:: back:: msl:: VertexBufferMapping {
1155+ id : self . shared . private_caps . max_vertex_buffers - 1 - i as u32 ,
1156+ stride : if vbl. array_stride > 0 {
1157+ vbl. array_stride . try_into ( ) . unwrap ( )
1158+ } else {
1159+ vbl. attributes
1160+ . iter ( )
1161+ . map ( |attribute| attribute. offset + attribute. format . size ( ) )
1162+ . max ( )
1163+ . unwrap_or ( 0 )
1164+ . try_into ( )
1165+ . unwrap ( )
1166+ } ,
1167+ step_mode : match ( vbl. array_stride == 0 , vbl. step_mode ) {
1168+ ( true , _) => naga:: back:: msl:: VertexBufferStepMode :: Constant ,
1169+ ( false , wgt:: VertexStepMode :: Vertex ) => {
1170+ naga:: back:: msl:: VertexBufferStepMode :: ByVertex
1171+ }
1172+ ( false , wgt:: VertexStepMode :: Instance ) => {
1173+ naga:: back:: msl:: VertexBufferStepMode :: ByInstance
1174+ }
1175+ } ,
1176+ attributes,
1177+ } ;
1178+ vertex_buffer_mappings. push ( mapping) ;
1179+ }
1180+
1181+ // Setup vertex shader
1182+ {
11751183 let vs = self . load_shader (
11761184 vertex_stage,
11771185 & vertex_buffer_mappings,
@@ -1188,16 +1196,18 @@ impl crate::Device for super::Device {
11881196 ) ;
11891197 }
11901198
1191- super :: PipelineStageInfo {
1199+ vs_info = Some ( super :: PipelineStageInfo {
11921200 push_constants : desc. layout . push_constants_infos . vs ,
11931201 sizes_slot : desc. layout . per_stage_map . vs . sizes_buffer ,
11941202 sized_bindings : vs. sized_bindings ,
11951203 vertex_buffer_mappings,
11961204 library : Some ( vs. library ) ,
11971205 raw_wg_size : Default :: default ( ) ,
11981206 work_group_memory_sizes : vec ! [ ] ,
1199- }
1200- } ) ;
1207+ } ) ;
1208+ }
1209+
1210+ // Validate vertex buffer count
12011211 if desc. layout . total_counters . vs . buffers + ( vertex_buffers. len ( ) as u32 )
12021212 > self . shared . private_caps . max_vertex_buffers
12031213 {
@@ -1212,6 +1222,7 @@ impl crate::Device for super::Device {
12121222 ) ) ;
12131223 }
12141224
1225+ // Set the pipeline vertex buffer info
12151226 if !vertex_buffers. is_empty ( ) {
12161227 let vertex_descriptor = metal:: VertexDescriptor :: new ( ) ;
12171228 for ( i, vb) in vertex_buffers. iter ( ) . enumerate ( ) {
@@ -1250,14 +1261,19 @@ impl crate::Device for super::Device {
12501261 }
12511262 descriptor. set_vertex_descriptor ( Some ( vertex_descriptor) ) ;
12521263 }
1264+
12531265 MetalGenericRenderPipelineDescriptor :: Standard ( descriptor)
12541266 }
12551267 crate :: VertexProcessor :: Mesh {
12561268 ref task_stage,
12571269 ref mesh_stage,
12581270 } => {
1271+ // Mesh pipeline specific setup
1272+
12591273 vs_info = None ;
12601274 let descriptor = metal:: MeshRenderPipelineDescriptor :: new ( ) ;
1275+
1276+ // Setup task stage
12611277 if let Some ( ref task_stage) = task_stage {
12621278 let ts = self . load_shader (
12631279 task_stage,
@@ -1285,6 +1301,8 @@ impl crate::Device for super::Device {
12851301 } else {
12861302 ts_info = None ;
12871303 }
1304+
1305+ // Setup mesh stage
12881306 {
12891307 let ms = self . load_shader (
12901308 mesh_stage,
@@ -1310,9 +1328,13 @@ impl crate::Device for super::Device {
13101328 work_group_memory_sizes : ms. wg_memory_sizes ,
13111329 } ) ;
13121330 }
1331+
13131332 MetalGenericRenderPipelineDescriptor :: Mesh ( descriptor)
13141333 }
13151334 } ;
1335+
1336+ // Standard and mesh render pipeline descriptors don't inherit from the same interface, despite sharing
1337+ // many methods. This function lets us call a function by name on whichever descriptor we are using.
13161338 macro_rules! descriptor_fn {
13171339 ( $method: ident $( ( $( $args: expr) ,* ) ) ? ) => {
13181340 match descriptor {
@@ -1372,6 +1394,7 @@ impl crate::Device for super::Device {
13721394 }
13731395 } ;
13741396
1397+ // Setup pipeline color attachments
13751398 for ( i, ct) in desc. color_targets . iter ( ) . enumerate ( ) {
13761399 let at_descriptor = descriptor_fn ! ( color_attachments( ) )
13771400 . object_at ( i as u64 )
@@ -1402,6 +1425,7 @@ impl crate::Device for super::Device {
14021425 }
14031426 }
14041427
1428+ // Setup depth stencil state
14051429 let depth_stencil = match desc. depth_stencil {
14061430 Some ( ref ds) => {
14071431 let raw_format = self . shared . private_caps . map_format ( ds. format ) ;
@@ -1424,6 +1448,7 @@ impl crate::Device for super::Device {
14241448 None => None ,
14251449 } ;
14261450
1451+ // Setup multisample state
14271452 if desc. multisample . count != 1 {
14281453 //TODO: handle sample mask
14291454 match descriptor {
@@ -1440,36 +1465,26 @@ impl crate::Device for super::Device {
14401465 //descriptor.set_alpha_to_one_enabled(desc.multisample.alpha_to_one_enabled);
14411466 }
14421467
1468+ // Set debug label
14431469 if let Some ( name) = desc. label {
14441470 descriptor_fn ! ( set_label( name) ) ;
14451471 }
14461472
1473+ // Create the pipeline from descriptor
14471474 let raw = match descriptor {
1448- MetalGenericRenderPipelineDescriptor :: Standard ( d) => self
1449- . shared
1450- . device
1451- . lock ( )
1452- . new_render_pipeline_state ( & d)
1453- . map_err ( |e| {
1454- crate :: PipelineError :: Linkage (
1455- wgt:: ShaderStages :: VERTEX | wgt:: ShaderStages :: FRAGMENT ,
1456- format ! ( "new_render_pipeline_state: {e:?}" ) ,
1457- )
1458- } ) ?,
1459- MetalGenericRenderPipelineDescriptor :: Mesh ( d) => self
1460- . shared
1461- . device
1462- . lock ( )
1463- . new_mesh_render_pipeline_state ( & d)
1464- . map_err ( |e| {
1465- crate :: PipelineError :: Linkage (
1466- wgt:: ShaderStages :: TASK
1467- | wgt:: ShaderStages :: MESH
1468- | wgt:: ShaderStages :: FRAGMENT ,
1469- format ! ( "new_mesh_render_pipeline_state: {e:?}" ) ,
1470- )
1471- } ) ?,
1472- } ;
1475+ MetalGenericRenderPipelineDescriptor :: Standard ( d) => {
1476+ self . shared . device . lock ( ) . new_render_pipeline_state ( & d)
1477+ }
1478+ MetalGenericRenderPipelineDescriptor :: Mesh ( d) => {
1479+ self . shared . device . lock ( ) . new_mesh_render_pipeline_state ( & d)
1480+ }
1481+ }
1482+ . map_err ( |e| {
1483+ crate :: PipelineError :: Linkage (
1484+ wgt:: ShaderStages :: VERTEX | wgt:: ShaderStages :: FRAGMENT ,
1485+ format ! ( "new_render_pipeline_state: {e:?}" ) ,
1486+ )
1487+ } ) ?;
14731488
14741489 self . counters . render_pipelines . add ( 1 ) ;
14751490
0 commit comments