MSL: Emit interface block members of array length 1 as arrays instead of scalars.
Test for array presence using is_array() instead of element count.
Add shaders-msl/vert/interface-block-single-element-array.vert regression test.
Fixes a regression error introduced in 3d4daab
.
This commit is contained in:
parent
d7cae5e7cd
commit
3bca246ad2
@ -0,0 +1,79 @@
|
||||
#pragma clang diagnostic ignored "-Wmissing-prototypes"
|
||||
#pragma clang diagnostic ignored "-Wmissing-braces"
|
||||
|
||||
#include <metal_stdlib>
|
||||
#include <simd/simd.h>
|
||||
|
||||
using namespace metal;
|
||||
|
||||
template<typename T, size_t Num>
|
||||
struct spvUnsafeArray
|
||||
{
|
||||
T elements[Num ? Num : 1];
|
||||
|
||||
thread T& operator [] (size_t pos) thread
|
||||
{
|
||||
return elements[pos];
|
||||
}
|
||||
constexpr const thread T& operator [] (size_t pos) const thread
|
||||
{
|
||||
return elements[pos];
|
||||
}
|
||||
|
||||
device T& operator [] (size_t pos) device
|
||||
{
|
||||
return elements[pos];
|
||||
}
|
||||
constexpr const device T& operator [] (size_t pos) const device
|
||||
{
|
||||
return elements[pos];
|
||||
}
|
||||
|
||||
constexpr const constant T& operator [] (size_t pos) const constant
|
||||
{
|
||||
return elements[pos];
|
||||
}
|
||||
|
||||
threadgroup T& operator [] (size_t pos) threadgroup
|
||||
{
|
||||
return elements[pos];
|
||||
}
|
||||
constexpr const threadgroup T& operator [] (size_t pos) const threadgroup
|
||||
{
|
||||
return elements[pos];
|
||||
}
|
||||
};
|
||||
|
||||
struct TDPickVertex
|
||||
{
|
||||
float4 c;
|
||||
spvUnsafeArray<float3, 1> uv;
|
||||
};
|
||||
|
||||
struct main0_out
|
||||
{
|
||||
float4 oTDVert_c [[user(locn0)]];
|
||||
float3 oTDVert_uv_0 [[user(locn1)]];
|
||||
float4 gl_Position [[position]];
|
||||
};
|
||||
|
||||
struct main0_in
|
||||
{
|
||||
float3 P [[attribute(0)]];
|
||||
float3 uv_0 [[attribute(1)]];
|
||||
};
|
||||
|
||||
vertex main0_out main0(main0_in in [[stage_in]])
|
||||
{
|
||||
main0_out out = {};
|
||||
TDPickVertex oTDVert = {};
|
||||
spvUnsafeArray<float3, 1> uv = {};
|
||||
uv[0] = in.uv_0;
|
||||
out.gl_Position = float4(in.P, 1.0);
|
||||
oTDVert.uv[0] = uv[0];
|
||||
oTDVert.c = float4(1.0);
|
||||
out.oTDVert_c = oTDVert.c;
|
||||
out.oTDVert_uv_0 = oTDVert.uv[0];
|
||||
return out;
|
||||
}
|
||||
|
@ -0,0 +1,79 @@
|
||||
#pragma clang diagnostic ignored "-Wmissing-prototypes"
|
||||
#pragma clang diagnostic ignored "-Wmissing-braces"
|
||||
|
||||
#include <metal_stdlib>
|
||||
#include <simd/simd.h>
|
||||
|
||||
using namespace metal;
|
||||
|
||||
template<typename T, size_t Num>
|
||||
struct spvUnsafeArray
|
||||
{
|
||||
T elements[Num ? Num : 1];
|
||||
|
||||
thread T& operator [] (size_t pos) thread
|
||||
{
|
||||
return elements[pos];
|
||||
}
|
||||
constexpr const thread T& operator [] (size_t pos) const thread
|
||||
{
|
||||
return elements[pos];
|
||||
}
|
||||
|
||||
device T& operator [] (size_t pos) device
|
||||
{
|
||||
return elements[pos];
|
||||
}
|
||||
constexpr const device T& operator [] (size_t pos) const device
|
||||
{
|
||||
return elements[pos];
|
||||
}
|
||||
|
||||
constexpr const constant T& operator [] (size_t pos) const constant
|
||||
{
|
||||
return elements[pos];
|
||||
}
|
||||
|
||||
threadgroup T& operator [] (size_t pos) threadgroup
|
||||
{
|
||||
return elements[pos];
|
||||
}
|
||||
constexpr const threadgroup T& operator [] (size_t pos) const threadgroup
|
||||
{
|
||||
return elements[pos];
|
||||
}
|
||||
};
|
||||
|
||||
struct TDPickVertex
|
||||
{
|
||||
float4 c;
|
||||
spvUnsafeArray<float3, 1> uv;
|
||||
};
|
||||
|
||||
struct main0_out
|
||||
{
|
||||
float4 oTDVert_c [[user(locn0)]];
|
||||
float3 oTDVert_uv_0 [[user(locn1)]];
|
||||
float4 gl_Position [[position]];
|
||||
};
|
||||
|
||||
struct main0_in
|
||||
{
|
||||
float3 P [[attribute(0)]];
|
||||
float3 uv_0 [[attribute(1)]];
|
||||
};
|
||||
|
||||
vertex main0_out main0(main0_in in [[stage_in]])
|
||||
{
|
||||
main0_out out = {};
|
||||
TDPickVertex oTDVert = {};
|
||||
spvUnsafeArray<float3, 1> uv = {};
|
||||
uv[0] = in.uv_0;
|
||||
out.gl_Position = float4(in.P, 1.0);
|
||||
oTDVert.uv[0] = uv[0];
|
||||
oTDVert.c = float4(1.0);
|
||||
out.oTDVert_c = oTDVert.c;
|
||||
out.oTDVert_uv_0 = oTDVert.uv[0];
|
||||
return out;
|
||||
}
|
||||
|
17
shaders-msl/vert/interface-block-single-element-array.vert
Normal file
17
shaders-msl/vert/interface-block-single-element-array.vert
Normal file
@ -0,0 +1,17 @@
|
||||
#version 460
|
||||
|
||||
layout(location = 0) out TDPickVertex
|
||||
{
|
||||
vec4 c;
|
||||
vec3 uv[1];
|
||||
} oTDVert;
|
||||
|
||||
layout(location = 0) in vec3 P;
|
||||
layout(location = 1) in vec3 uv[1];
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = vec4(P, 1.0);
|
||||
oTDVert.uv[0] = uv[0];
|
||||
oTDVert.c = vec4(1.);
|
||||
}
|
@ -2580,12 +2580,14 @@ void CompilerMSL::add_composite_member_variable_to_interface_block(StorageClass
|
||||
uint32_t mbr_type_id = var_type.member_types[mbr_idx];
|
||||
auto &mbr_type = get<SPIRType>(mbr_type_id);
|
||||
|
||||
bool mbr_is_indexable = false;
|
||||
uint32_t elem_cnt = 1;
|
||||
if (is_matrix(mbr_type))
|
||||
{
|
||||
if (is_array(mbr_type))
|
||||
SPIRV_CROSS_THROW("MSL cannot emit arrays-of-matrices in input and output variables.");
|
||||
|
||||
mbr_is_indexable = true;
|
||||
elem_cnt = mbr_type.columns;
|
||||
}
|
||||
else if (is_array(mbr_type))
|
||||
@ -2593,6 +2595,7 @@ void CompilerMSL::add_composite_member_variable_to_interface_block(StorageClass
|
||||
if (mbr_type.array.size() != 1)
|
||||
SPIRV_CROSS_THROW("MSL cannot emit arrays-of-arrays in input and output variables.");
|
||||
|
||||
mbr_is_indexable = true;
|
||||
elem_cnt = to_array_size_literal(mbr_type);
|
||||
}
|
||||
|
||||
@ -2628,8 +2631,8 @@ void CompilerMSL::add_composite_member_variable_to_interface_block(StorageClass
|
||||
{
|
||||
for (uint32_t i = 0; i < elem_cnt; i++)
|
||||
{
|
||||
string mbr_name = append_member_name(mbr_name_qual, var_type, mbr_idx) + (elem_cnt == 1 ? "" : join("_", i));
|
||||
string var_chain = join(var_chain_qual, ".", to_member_name(var_type, mbr_idx), (elem_cnt == 1 ? "" : join("[", i, "]")));
|
||||
string mbr_name = append_member_name(mbr_name_qual, var_type, mbr_idx) + (mbr_is_indexable ? join("_", i) : "");
|
||||
string var_chain = join(var_chain_qual, ".", to_member_name(var_type, mbr_idx), (mbr_is_indexable ? join("[", i, "]") : ""));
|
||||
uint32_t sub_mbr_cnt = uint32_t(mbr_type.member_types.size());
|
||||
for (uint32_t sub_mbr_idx = 0; sub_mbr_idx < sub_mbr_cnt; sub_mbr_idx++)
|
||||
{
|
||||
@ -2654,7 +2657,7 @@ void CompilerMSL::add_composite_member_variable_to_interface_block(StorageClass
|
||||
ib_type.member_types.push_back(usable_type->self);
|
||||
|
||||
// Give the member a name
|
||||
string mbr_name = ensure_valid_name(append_member_name(mbr_name_qual, var_type, mbr_idx) + (elem_cnt == 1 ? "" : join("_", i)), "m");
|
||||
string mbr_name = ensure_valid_name(append_member_name(mbr_name_qual, var_type, mbr_idx) + (mbr_is_indexable ? join("_", i) : ""), "m");
|
||||
set_member_name(ib_type.self, ib_mbr_idx, mbr_name);
|
||||
|
||||
// Once we determine the location of the first member within nested structures,
|
||||
@ -2718,7 +2721,7 @@ void CompilerMSL::add_composite_member_variable_to_interface_block(StorageClass
|
||||
// Unflatten or flatten from [[stage_in]] or [[stage_out]] as appropriate.
|
||||
if (!meta.strip_array && meta.allow_local_declaration)
|
||||
{
|
||||
string var_chain = join(var_chain_qual, ".", to_member_name(var_type, mbr_idx), (elem_cnt == 1 ? "" : join("[", i, "]")));
|
||||
string var_chain = join(var_chain_qual, ".", to_member_name(var_type, mbr_idx), (mbr_is_indexable ? join("[", i, "]") : ""));
|
||||
switch (storage)
|
||||
{
|
||||
case StorageClassInput:
|
||||
|
Loading…
Reference in New Issue
Block a user