From c45e74f1c092e9495be6cfdd5b95706b719a2851 Mon Sep 17 00:00:00 2001 From: Bill Hollings Date: Fri, 8 Jul 2016 12:39:22 -0400 Subject: [PATCH] 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. --- spirv_common.hpp | 1 + spirv_cross.cpp | 6 ++++++ spirv_cross.hpp | 5 ++++- spirv_msl.cpp | 39 +++++++++++++++++++++++++-------------- spirv_msl.hpp | 9 +++++---- 5 files changed, 41 insertions(+), 19 deletions(-) diff --git a/spirv_common.hpp b/spirv_common.hpp index f7d3f30..8fa37e9 100644 --- a/spirv_common.hpp +++ b/spirv_common.hpp @@ -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; diff --git a/spirv_cross.cpp b/spirv_cross.cpp index d5fcb07..e8353f5 100644 --- a/spirv_cross.cpp +++ b/spirv_cross.cpp @@ -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); diff --git a/spirv_cross.hpp b/spirv_cross.hpp index 06a2aac..3bd6060 100644 --- a/spirv_cross.hpp +++ b/spirv_cross.hpp @@ -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 selection_merge_targets; std::unordered_set 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; diff --git a/spirv_msl.cpp b/spirv_msl.cpp index 032c728..8322d57 100644 --- a/spirv_msl.cpp +++ b/spirv_msl.cpp @@ -58,7 +58,8 @@ string CompilerMSL::compile(MSLConfiguration &msl_cfg, vector *p_ extract_builtins(); localize_global_variables(); - add_interface_structs(); + 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(); - if (var.storage == StorageClassUniform || + if (var.storage == StorageClassInput || + var.storage == StorageClassUniform || var.storage == StorageClassUniformConstant || var.storage == StorageClassPushConstant) global_var_ids.insert(var.self); @@ -189,16 +187,16 @@ void CompilerMSL::extract_global_variables_from_functions() std::set added_arg_ids; std::set 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, - std::set& added_arg_ids, - std::set& global_var_ids, - std::set& processed_func_ids) +void CompilerMSL::extract_global_variables_from_function(uint32_t func_id, + std::set& added_arg_ids, + std::set& global_var_ids, + std::set& processed_func_ids) { // Avoid processing a function more than once if ( processed_func_ids.find(func_id) != processed_func_ids.end() ) @@ -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 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(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) { diff --git a/spirv_msl.hpp b/spirv_msl.hpp index bc2e574..89e20a3 100644 --- a/spirv_msl.hpp +++ b/spirv_msl.hpp @@ -108,15 +108,16 @@ 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, - std::set& added_arg_ids, - std::set& global_var_ids, - std::set& processed_func_ids); + void extract_global_variables_from_function(uint32_t func_id, + std::set& added_arg_ids, + std::set& global_var_ids, + std::set& processed_func_ids); void add_interface_structs(); void bind_vertex_attributes(std::set &bindings); uint32_t add_interface_struct(spv::StorageClass storage, uint32_t vtx_binding = 0);