diff --git a/src/back/msl/mod.rs b/src/back/msl/mod.rs index 0b067a329f..23b63794c9 100644 --- a/src/back/msl/mod.rs +++ b/src/back/msl/mod.rs @@ -100,6 +100,9 @@ pub struct Options { pub spirv_cross_compatibility: bool, /// Don't panic on missing bindings, instead generate invalid MSL. pub fake_missing_bindings: bool, + /// Allow `BuiltIn::PointSize` in the vertex shader. + /// Metal doesn't like this for non-point primitive topologies. + pub allow_point_size: bool, } impl Default for Options { @@ -109,6 +112,7 @@ impl Default for Options { binding_map: BindingMap::default(), spirv_cross_compatibility: false, fake_missing_bindings: true, + allow_point_size: true, } } } diff --git a/src/back/msl/writer.rs b/src/back/msl/writer.rs index 08aa6cbd9f..5d3f761199 100644 --- a/src/back/msl/writer.rs +++ b/src/back/msl/writer.rs @@ -150,6 +150,7 @@ struct ExpressionContext<'a> { origin: FunctionOrigin, info: &'a FunctionInfo, module: &'a crate::Module, + options: &'a Options, } impl<'a> ExpressionContext<'a> { @@ -770,8 +771,16 @@ impl Writer { self.put_expression(expr_handle, context, true)?; writeln!(self.out, ";")?; write!(self.out, "{}return {} {{", level, struct_name)?; + let mut is_first = true; for (index, member) in members.iter().enumerate() { - let comma = if index == 0 { "" } else { "," }; + if !context.options.allow_point_size + && member.binding + == Some(crate::Binding::BuiltIn(crate::BuiltIn::PointSize)) + { + continue; + } + let comma = if is_first { "" } else { "," }; + is_first = false; let name = &self.names[&NameKey::StructMember(result_ty, index as u32)]; // logic similar to `put_initialization_component` if let crate::TypeInner::Array { @@ -1373,6 +1382,7 @@ impl Writer { origin: FunctionOrigin::Handle(fun_handle), info: fun_info, module, + options, }, mod_info, result_struct: None, @@ -1501,6 +1511,11 @@ impl Writer { for (name, ty, binding) in result_members { let type_name = &self.names[&NameKey::Type(ty)]; let binding = binding.ok_or(Error::Validation)?; + if !options.allow_point_size + && *binding == crate::Binding::BuiltIn(crate::BuiltIn::PointSize) + { + continue; + } let resolved = options.resolve_local_binding(binding, out_mode)?; write!(self.out, "{}{} {}", INDENT, type_name, name)?; resolved.try_fmt_decorated(&mut self.out, "")?; @@ -1655,6 +1670,7 @@ impl Writer { origin: FunctionOrigin::EntryPoint(ep_index as _), info: fun_info, module, + options, }, mod_info, result_struct: Some(&stage_out_name), diff --git a/tests/snapshots.rs b/tests/snapshots.rs index 9bddce1ca2..d6bd5e8870 100644 --- a/tests/snapshots.rs +++ b/tests/snapshots.rs @@ -176,6 +176,7 @@ fn check_output_msl( binding_map, spirv_cross_compatibility: false, fake_missing_bindings: false, + allow_point_size: true, }; let (msl, _) = msl::write_string(module, info, &options).unwrap();