MSL: Inherit interpolation qualifiers through recursive composites.

This commit is contained in:
Hans-Kristian Arntzen 2024-04-15 15:44:21 +02:00
parent 8edbda4206
commit dc6db52356
5 changed files with 115 additions and 10 deletions

View File

@ -0,0 +1,37 @@
#include <metal_stdlib>
#include <simd/simd.h>
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;
}

View File

@ -0,0 +1,37 @@
#include <metal_stdlib>
#include <simd/simd.h>
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;
}

View File

@ -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;
}

View File

@ -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<SPIRFunction>(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<SPIRType>(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
{

View File

@ -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);