diff --git a/reference/opt/shaders-msl/frag/block-io-inherited-interpolation-qualifiers.frag b/reference/opt/shaders-msl/frag/block-io-inherited-interpolation-qualifiers.frag new file mode 100644 index 00000000..73ba2866 --- /dev/null +++ b/reference/opt/shaders-msl/frag/block-io-inherited-interpolation-qualifiers.frag @@ -0,0 +1,37 @@ +#include +#include + +using namespace metal; + +struct Foo +{ + float2 M; + float F; +}; + +struct V +{ + Foo foo; +}; + +struct main0_out +{ + float Fo [[color(0)]]; +}; + +struct main0_in +{ + float2 m_13_foo_M [[user(locn0), flat]]; + float m_13_foo_F [[user(locn1), flat]]; +}; + +fragment main0_out main0(main0_in in [[stage_in]]) +{ + main0_out out = {}; + V _13 = {}; + _13.foo.M = in.m_13_foo_M; + _13.foo.F = in.m_13_foo_F; + out.Fo = _13.foo.F; + return out; +} + diff --git a/reference/shaders-msl/frag/block-io-inherited-interpolation-qualifiers.frag b/reference/shaders-msl/frag/block-io-inherited-interpolation-qualifiers.frag new file mode 100644 index 00000000..73ba2866 --- /dev/null +++ b/reference/shaders-msl/frag/block-io-inherited-interpolation-qualifiers.frag @@ -0,0 +1,37 @@ +#include +#include + +using namespace metal; + +struct Foo +{ + float2 M; + float F; +}; + +struct V +{ + Foo foo; +}; + +struct main0_out +{ + float Fo [[color(0)]]; +}; + +struct main0_in +{ + float2 m_13_foo_M [[user(locn0), flat]]; + float m_13_foo_F [[user(locn1), flat]]; +}; + +fragment main0_out main0(main0_in in [[stage_in]]) +{ + main0_out out = {}; + V _13 = {}; + _13.foo.M = in.m_13_foo_M; + _13.foo.F = in.m_13_foo_F; + out.Fo = _13.foo.F; + return out; +} + diff --git a/shaders-msl/frag/block-io-inherited-interpolation-qualifiers.frag b/shaders-msl/frag/block-io-inherited-interpolation-qualifiers.frag new file mode 100644 index 00000000..b98e4853 --- /dev/null +++ b/shaders-msl/frag/block-io-inherited-interpolation-qualifiers.frag @@ -0,0 +1,15 @@ +#version 450 + +struct Foo +{ + vec2 M; + float F; +}; + +layout(location = 0) in V { flat Foo foo; }; +layout(location = 0) out float Fo; + +void main() +{ + Fo = foo.F; +} diff --git a/spirv_msl.cpp b/spirv_msl.cpp index ddbeb903..218caaf8 100644 --- a/spirv_msl.cpp +++ b/spirv_msl.cpp @@ -2921,20 +2921,35 @@ void CompilerMSL::add_composite_member_variable_to_interface_block(StorageClass uint32_t mbr_idx, InterfaceBlockMeta &meta, const string &mbr_name_qual, const string &var_chain_qual, - uint32_t &location, uint32_t &var_mbr_idx) + uint32_t &location, uint32_t &var_mbr_idx, + const Bitset &interpolation_qual) { auto &entry_func = get(ir.default_entry_point); BuiltIn builtin = BuiltInMax; bool is_builtin = is_member_builtin(var_type, mbr_idx, &builtin); - bool is_flat = - has_member_decoration(var_type.self, mbr_idx, DecorationFlat) || has_decoration(var.self, DecorationFlat); - bool is_noperspective = has_member_decoration(var_type.self, mbr_idx, DecorationNoPerspective) || + bool is_flat = interpolation_qual.get(DecorationFlat) || + has_member_decoration(var_type.self, mbr_idx, DecorationFlat) || + has_decoration(var.self, DecorationFlat); + bool is_noperspective = interpolation_qual.get(DecorationNoPerspective) || + has_member_decoration(var_type.self, mbr_idx, DecorationNoPerspective) || has_decoration(var.self, DecorationNoPerspective); - bool is_centroid = has_member_decoration(var_type.self, mbr_idx, DecorationCentroid) || + bool is_centroid = interpolation_qual.get(DecorationCentroid) || + has_member_decoration(var_type.self, mbr_idx, DecorationCentroid) || has_decoration(var.self, DecorationCentroid); - bool is_sample = - has_member_decoration(var_type.self, mbr_idx, DecorationSample) || has_decoration(var.self, DecorationSample); + bool is_sample = interpolation_qual.get(DecorationSample) || + has_member_decoration(var_type.self, mbr_idx, DecorationSample) || + has_decoration(var.self, DecorationSample); + + Bitset inherited_qual; + if (is_flat) + inherited_qual.set(DecorationFlat); + if (is_noperspective) + inherited_qual.set(DecorationNoPerspective); + if (is_centroid) + inherited_qual.set(DecorationCentroid); + if (is_sample) + inherited_qual.set(DecorationSample); uint32_t mbr_type_id = var_type.member_types[mbr_idx]; auto &mbr_type = get(mbr_type_id); @@ -2998,7 +3013,7 @@ void CompilerMSL::add_composite_member_variable_to_interface_block(StorageClass add_composite_member_variable_to_interface_block(storage, ib_var_ref, ib_type, var, mbr_type, sub_mbr_idx, meta, mbr_name, var_chain, - location, var_mbr_idx); + location, var_mbr_idx, inherited_qual); // FIXME: Recursive structs and tessellation breaks here. var_mbr_idx++; } @@ -3684,7 +3699,7 @@ void CompilerMSL::add_variable_to_interface_block(StorageClass storage, const st add_composite_member_variable_to_interface_block(storage, ib_var_ref, ib_type, var, var_type, mbr_idx, meta, mbr_name_qual, var_chain_qual, - location, var_mbr_idx); + location, var_mbr_idx, {}); } else { diff --git a/spirv_msl.hpp b/spirv_msl.hpp index c9896df7..dbfe7ef9 100644 --- a/spirv_msl.hpp +++ b/spirv_msl.hpp @@ -951,7 +951,8 @@ protected: uint32_t mbr_idx, InterfaceBlockMeta &meta, const std::string &mbr_name_qual, const std::string &var_chain_qual, - uint32_t &location, uint32_t &var_mbr_idx); + uint32_t &location, uint32_t &var_mbr_idx, + const Bitset &interpolation_qual); void add_tess_level_input_to_interface_block(const std::string &ib_var_ref, SPIRType &ib_type, SPIRVariable &var); void add_tess_level_input(const std::string &base_ref, const std::string &mbr_name, SPIRVariable &var);