MSL support global input vars as automatic function args.

Add Decoration qualified_alias element.
Virualize Compiler to_name() function.
MSL use qualified_alias instead of alias when inside entry-point function.
This commit is contained in:
Bill Hollings 2016-07-08 12:39:22 -04:00
Родитель 65cc931da0
Коммит c45e74f1c0
5 изменённых файлов: 41 добавлений и 19 удалений

Просмотреть файл

@ -706,6 +706,7 @@ struct Meta
struct Decoration
{
std::string alias;
std::string qualified_alias;
uint64_t decoration_flags = 0;
spv::BuiltIn builtin_type;
uint32_t location = 0;

Просмотреть файл

@ -691,6 +691,12 @@ const std::string &Compiler::get_member_name(uint32_t id, uint32_t index) const
return m.members[index].alias;
}
void Compiler::set_member_qualified_name(uint32_t id, uint32_t index, const std::string &name)
{
meta.at(id).members.resize(max(meta[id].members.size(), size_t(index) + 1));
meta.at(id).members[index].qualified_alias = name;
}
uint32_t Compiler::get_member_decoration(uint32_t id, uint32_t index, Decoration decoration) const
{
auto &dec = meta.at(id).members.at(index);

Просмотреть файл

@ -134,6 +134,9 @@ public:
// Sets the member identifier for OpTypeStruct ID, member number "index".
void set_member_name(uint32_t id, uint32_t index, const std::string &name);
// Sets the qualified member identifier for OpTypeStruct ID, member number "index".
void set_member_qualified_name(uint32_t id, uint32_t index, const std::string &name);
// Gets the decoration mask for a member of a struct, similar to get_decoration_mask.
uint64_t get_member_decoration_mask(uint32_t id, uint32_t index) const;
@ -288,7 +291,7 @@ protected:
std::unordered_set<uint32_t> selection_merge_targets;
std::unordered_set<uint32_t> multiselect_merge_targets;
std::string to_name(uint32_t id, bool allow_alias = true);
virtual std::string to_name(uint32_t id, bool allow_alias = true);
bool is_builtin_variable(const SPIRVariable &var) const;
bool is_immutable(uint32_t id) const;
bool is_member_builtin(const SPIRType &type, uint32_t index, spv::BuiltIn *builtin) const;

Просмотреть файл

@ -59,6 +59,7 @@ string CompilerMSL::compile(MSLConfiguration &msl_cfg, vector<MSLVertexAttr> *p_
extract_builtins();
localize_global_variables();
add_interface_structs();
extract_global_variables_from_functions();
// Do not deal with ES-isms like precision, older extensions and such.
options.es = false;
@ -162,10 +163,6 @@ void CompilerMSL::localize_global_variables()
iter++;
}
}
// For any global variable accessed directly by a function,
// extract that variable and add it as an argument to that function.
extract_global_variables_from_functions();
}
// For any global variable accessed directly by a function,
@ -180,7 +177,8 @@ void CompilerMSL::extract_global_variables_from_functions()
if (id.get_type() == TypeVariable)
{
auto &var = id.get<SPIRVariable>();
if (var.storage == StorageClassUniform ||
if (var.storage == StorageClassInput ||
var.storage == StorageClassUniform ||
var.storage == StorageClassUniformConstant ||
var.storage == StorageClassPushConstant)
global_var_ids.insert(var.self);
@ -189,13 +187,13 @@ void CompilerMSL::extract_global_variables_from_functions()
std::set<uint32_t> added_arg_ids;
std::set<uint32_t> processed_func_ids;
extract_global_variables_from_functions(execution.entry_point, added_arg_ids, global_var_ids, processed_func_ids);
extract_global_variables_from_function(execution.entry_point, added_arg_ids, global_var_ids, processed_func_ids);
}
// MSL does not support the use of global variables for shader input content.
// For any global variable accessed directly by the specified function, extract that variable,
// add it as an argument to that function, and the arg to the added_arg_ids collection.
void CompilerMSL::extract_global_variables_from_functions(uint32_t func_id,
void CompilerMSL::extract_global_variables_from_function(uint32_t func_id,
std::set<uint32_t>& added_arg_ids,
std::set<uint32_t>& global_var_ids,
std::set<uint32_t>& processed_func_ids)
@ -228,7 +226,7 @@ void CompilerMSL::extract_global_variables_from_functions(uint32_t func_id,
case OpFunctionCall: {
uint32_t inner_func_id = ops[2];
std::set<uint32_t> inner_func_args;
extract_global_variables_from_functions(inner_func_id, inner_func_args, global_var_ids, processed_func_ids);
extract_global_variables_from_function(inner_func_id, inner_func_args, global_var_ids, processed_func_ids);
added_arg_ids.insert(inner_func_args.begin(), inner_func_args.end());
break;
}
@ -247,6 +245,7 @@ void CompilerMSL::extract_global_variables_from_functions(uint32_t func_id,
func.add_parameter(type_id, next_id);
set<SPIRVariable>(next_id, type_id, StorageClassFunction);
set_name(next_id, get_name(arg_id));
meta[next_id].decoration.qualified_alias = meta[arg_id].decoration.qualified_alias;
next_id++;
}
}
@ -434,7 +433,7 @@ uint32_t CompilerMSL::add_interface_struct(StorageClass storage, uint32_t vtx_bi
// Update the original variable reference to include the structure reference
string qual_var_name = ib_var_ref + "." + mbr_name;
set_member_name(type.self, i, qual_var_name);
set_member_qualified_name(type.self, i, qual_var_name);
// Copy the variable location from the original variable to the member
uint32_t locn = get_member_decoration(type.self, i, DecorationLocation);
@ -469,7 +468,7 @@ uint32_t CompilerMSL::add_interface_struct(StorageClass storage, uint32_t vtx_bi
// Update the original variable reference to include the structure reference
string qual_var_name = ib_var_ref + "." + mbr_name;
meta[p_var->self].decoration.alias = qual_var_name;
meta[p_var->self].decoration.qualified_alias = qual_var_name;
// Copy the variable location from the original variable to the member
auto &dec = meta[p_var->self].decoration;
@ -1405,6 +1404,18 @@ string CompilerMSL::argument_decl(const SPIRFunction::Parameter &arg)
return join(constref ? "const " : "", type_to_glsl(type), "& ", to_name(var.self), type_to_array_glsl(type));
}
// If we're currently in the entry point function, and the object
// has a qualified name, use it, otherwise use the standard name.
string CompilerMSL::to_name(uint32_t id, bool allow_alias)
{
if (current_function && (current_function->self == execution.entry_point) ) {
string qual_name = meta.at(id).decoration.qualified_alias;
if ( !qual_name.empty() )
return qual_name;
}
return Compiler::to_name(id, allow_alias);
}
// Returns an MSL string describing the SPIR-V type
string CompilerMSL::type_to_glsl(const SPIRType &type)
{

Просмотреть файл

@ -108,12 +108,13 @@ protected:
std::string constant_expression(const SPIRConstant &c) override;
size_t get_declared_struct_member_size(const SPIRType &struct_type, uint32_t index) const override;
std::string to_func_call_arg(uint32_t id) override;
std::string to_name(uint32_t id, bool allow_alias = true) override;
void extract_builtins();
void add_builtin(spv::BuiltIn builtin_type);
void localize_global_variables();
void extract_global_variables_from_functions();
void extract_global_variables_from_functions(uint32_t func_id,
void extract_global_variables_from_function(uint32_t func_id,
std::set<uint32_t>& added_arg_ids,
std::set<uint32_t>& global_var_ids,
std::set<uint32_t>& processed_func_ids);