[msl] fix initialization of arrayed members, enable METAL snapshot of quad-vert

This commit is contained in:
Dzmitry Malyshau
2021-03-26 23:52:55 -04:00
committed by Dzmitry Malyshau
parent e47ff2dc26
commit f2155d49d1
3 changed files with 134 additions and 6 deletions

View File

@@ -205,6 +205,39 @@ impl<W: Write> Writer<W> {
Ok(())
}
fn put_initialization_component(
&mut self,
component: Handle<crate::Expression>,
context: &ExpressionContext,
) -> Result<(), Error> {
// we can't initialize the array members just like other members,
// we have to unwrap them one level deeper...
let component_res = &context.info[component].ty;
if let crate::TypeInner::Array {
size: crate::ArraySize::Constant(const_handle),
..
} = *component_res.inner_with(&context.module.types)
{
//HACK: we are forcefully duplicating the expression here,
// it would be nice to find a more C++ idiomatic solution for initializing array members
let size = context.module.constants[const_handle]
.to_array_length()
.unwrap();
write!(self.out, "{{")?;
for j in 0..size {
if j != 0 {
write!(self.out, ",")?;
}
self.put_expression(component, context, false)?;
write!(self.out, "[{}]", j)?;
}
write!(self.out, "}}")?;
} else {
self.put_expression(component, context, true)?;
}
Ok(())
}
fn put_expression(
&mut self,
expr_handle: Handle<crate::Expression>,
@@ -301,7 +334,7 @@ impl<W: Write> Writer<W> {
if i != 0 {
write!(self.out, ", ")?;
}
self.put_expression(component, context, true)?;
self.put_initialization_component(component, context)?;
}
write!(self.out, "}}")?;
}
@@ -819,11 +852,31 @@ impl<W: Write> Writer<W> {
self.put_expression(expr_handle, &context.expression, true)?;
writeln!(self.out, ";")?;
write!(self.out, "{}return {} {{", level, struct_name)?;
for index in 0..members.len() as u32 {
for (index, member) in members.iter().enumerate() {
let comma = if index == 0 { "" } else { "," };
let name =
&self.names[&NameKey::StructMember(result_ty, index)];
write!(self.out, "{} {}.{}", comma, tmp, name)?;
let name = &self.names
[&NameKey::StructMember(result_ty, index as u32)];
// logic similar to `put_initialization_component`
if let crate::TypeInner::Array {
size: crate::ArraySize::Constant(const_handle),
..
} = context.expression.module.types[member.ty].inner
{
let size = context.expression.module.constants
[const_handle]
.to_array_length()
.unwrap();
write!(self.out, "{} {{", comma)?;
for j in 0..size {
if j != 0 {
write!(self.out, ",")?;
}
write!(self.out, "{}.{}[{}]", tmp, name, j)?;
}
write!(self.out, "}}")?;
} else {
write!(self.out, "{} {}.{}", comma, tmp, name)?;
}
}
}
_ => {

View File

@@ -0,0 +1,75 @@
---
source: tests/snapshots.rs
expression: msl
---
#include <metal_stdlib>
#include <simd/simd.h>
constexpr constant unsigned const_0u = 0u;
constexpr constant unsigned const_1u = 1u;
constexpr constant unsigned const_2u = 2u;
constexpr constant unsigned const_3u = 3u;
constexpr constant unsigned const_1u1 = 1u;
constexpr constant int const_0i = 0;
constexpr constant float const_0f = 0.0;
constexpr constant float const_1f = 1.0;
typedef float type;
typedef metal::float2 type1;
typedef thread type1 *type2;
typedef thread type1 *type3;
typedef metal::float4 type4;
typedef uint type5;
typedef type type6[const_1u1];
struct gl_PerVertex {
type4 gl_Position;
type gl_PointSize;
type6 gl_ClipDistance;
type6 gl_CullDistance;
};
typedef thread gl_PerVertex *type7;
typedef int type8;
typedef thread type4 *type9;
struct type10 {
type1 member;
type4 gl_Position1;
type gl_PointSize1;
type6 gl_ClipDistance1;
};
void main1(
type1 v_uv,
type1 a_uv,
gl_PerVertex _,
type1 a_pos
) {
v_uv = a_uv;
type1 _expr9 = a_pos;
_.gl_Position = metal::float4(_expr9.x, _expr9.y, const_0f, const_1f);
return;
}
struct main2Input {
type1 a_uv1 [[attribute(1)]];
type1 a_pos1 [[attribute(0)]];
};
struct main2Output {
type1 member [[user(loc0)]];
type4 gl_Position1 [[position]];
type gl_PointSize1 [[point_size]];
type6 gl_ClipDistance1 [[clip_distance]];
};
vertex main2Output main2(
main2Input varyings [[stage_in]]
) {
type1 v_uv = {};
type1 a_uv = {};
gl_PerVertex _ = {};
type1 a_pos = {};
const auto a_uv1 = varyings.a_uv1;
const auto a_pos1 = varyings.a_pos1;
a_uv = a_uv1;
a_pos = a_pos1;
main1(v_uv, a_uv, _, a_pos);
const auto _tmp = type10 {v_uv, _.gl_Position, _.gl_PointSize, {_.gl_ClipDistance[0]}};
return main2Output { _tmp.member, _tmp.gl_Position1, _tmp.gl_PointSize1, {_tmp.gl_ClipDistance1[0]} };
}

View File

@@ -286,7 +286,7 @@ fn convert_spv(name: &str, targets: Targets) {
#[cfg(feature = "spv-in")]
#[test]
fn convert_spv_quad_vert() {
convert_spv("quad-vert", Targets::empty());
convert_spv("quad-vert", Targets::METAL);
}
#[cfg(feature = "spv-in")]