diff --git a/3rdparty/spirv-cross/spirv_cross.cpp b/3rdparty/spirv-cross/spirv_cross.cpp index c99febe93..2204e3911 100644 --- a/3rdparty/spirv-cross/spirv_cross.cpp +++ b/3rdparty/spirv-cross/spirv_cross.cpp @@ -742,6 +742,14 @@ bool Compiler::is_physical_pointer(const SPIRType &type) const return type.op == OpTypePointer && type.storage == StorageClassPhysicalStorageBuffer; } +bool Compiler::is_physical_or_buffer_pointer(const SPIRType &type) const +{ + return type.op == OpTypePointer && + (type.storage == StorageClassPhysicalStorageBuffer || type.storage == StorageClassUniform || + type.storage == StorageClassStorageBuffer || type.storage == StorageClassWorkgroup || + type.storage == StorageClassPushConstant); +} + bool Compiler::is_physical_pointer_to_buffer_block(const SPIRType &type) const { return is_physical_pointer(type) && get_pointee_type(type).self == type.parent_type && diff --git a/3rdparty/spirv-cross/spirv_cross.hpp b/3rdparty/spirv-cross/spirv_cross.hpp index 601ca2695..06f2b73f1 100644 --- a/3rdparty/spirv-cross/spirv_cross.hpp +++ b/3rdparty/spirv-cross/spirv_cross.hpp @@ -694,6 +694,7 @@ protected: bool is_array(const SPIRType &type) const; bool is_pointer(const SPIRType &type) const; bool is_physical_pointer(const SPIRType &type) const; + bool is_physical_or_buffer_pointer(const SPIRType &type) const; bool is_physical_pointer_to_buffer_block(const SPIRType &type) const; static bool is_runtime_size_array(const SPIRType &type); uint32_t expression_type_id(uint32_t id) const; diff --git a/3rdparty/spirv-cross/spirv_glsl.cpp b/3rdparty/spirv-cross/spirv_glsl.cpp index 3cb08f2c1..f9ce6cb09 100644 --- a/3rdparty/spirv-cross/spirv_glsl.cpp +++ b/3rdparty/spirv-cross/spirv_glsl.cpp @@ -5051,10 +5051,10 @@ void CompilerGLSL::emit_polyfills(uint32_t polyfills, bool relaxed) // Returns a string representation of the ID, usable as a function arg. // Default is to simply return the expression representation fo the arg ID. // Subclasses may override to modify the return value. -string CompilerGLSL::to_func_call_arg(const SPIRFunction::Parameter &, uint32_t id) +string CompilerGLSL::to_func_call_arg(const SPIRFunction::Parameter &arg, uint32_t id) { // BDA expects pointers through function interface. - if (is_physical_pointer(expression_type(id))) + if (!arg.alias_global_variable && is_physical_or_buffer_pointer(expression_type(id))) return to_pointer_expression(id); // Make sure that we use the name of the original variable, and not the parameter alias. @@ -6896,6 +6896,16 @@ void CompilerGLSL::emit_uninitialized_temporary(uint32_t result_type, uint32_t r } } +bool CompilerGLSL::can_declare_inline_temporary(uint32_t id) const +{ + if (!block_temporary_hoisting && current_continue_block && !hoisted_temporaries.count(id)) + return false; + if (hoisted_temporaries.count(id)) + return false; + + return true; +} + string CompilerGLSL::declare_temporary(uint32_t result_type, uint32_t result_id) { auto &type = get(result_type); @@ -6973,6 +6983,42 @@ SPIRExpression &CompilerGLSL::emit_op(uint32_t result_type, uint32_t result_id, } } +void CompilerGLSL::emit_transposed_op(uint32_t result_type, uint32_t result_id, const string &rhs, bool forwarding) +{ + if (forwarding && (forced_temporaries.find(result_id) == end(forced_temporaries))) + { + // Just forward it without temporary. + // If the forward is trivial, we do not force flushing to temporary for this expression. + forwarded_temporaries.insert(result_id); + auto &e = set(result_id, rhs, result_type, true); + e.need_transpose = true; + } + else if (can_declare_inline_temporary(result_id)) + { + // If expression isn't immutable, bind it to a temporary and make the new temporary immutable (they always are). + // Since the expression is transposed, we have to ensure the temporary is the transposed type. + + auto &transposed_type_id = extra_sub_expressions[result_id]; + if (!transposed_type_id) + { + auto dummy_type = get(result_type); + std::swap(dummy_type.columns, dummy_type.vecsize); + transposed_type_id = ir.increase_bound_by(1); + set(transposed_type_id, dummy_type); + } + + statement(declare_temporary(transposed_type_id, result_id), rhs, ";"); + auto &e = set(result_id, to_name(result_id), result_type, true); + e.need_transpose = true; + } + else + { + // If we cannot declare the temporary because it's already been hoisted, we don't have the + // chance to override the temporary type ourselves. Just transpose() the expression. + emit_op(result_type, result_id, join("transpose(", rhs, ")"), forwarding); + } +} + void CompilerGLSL::emit_unary_op(uint32_t result_type, uint32_t result_id, uint32_t op0, const char *op) { bool forward = should_forward(op0); @@ -11581,7 +11627,7 @@ bool CompilerGLSL::should_dereference(uint32_t id) // If id is a variable but not a phi variable, we should not dereference it. // BDA passed around as parameters are always pointers. if (auto *var = maybe_get(id)) - return (var->parameter && is_physical_pointer(type)) || var->phi_variable; + return (var->parameter && is_physical_or_buffer_pointer(type)) || var->phi_variable; if (auto *expr = maybe_get(id)) { @@ -11617,8 +11663,8 @@ bool CompilerGLSL::should_dereference(uint32_t id) bool CompilerGLSL::should_dereference_caller_param(uint32_t id) { const auto &type = expression_type(id); - // BDA is always passed around as pointers. - if (is_physical_pointer(type)) + // BDA is always passed around as pointers. Similarly, we need to pass variable buffer pointers as pointers. + if (is_physical_or_buffer_pointer(type)) return false; return should_dereference(id); @@ -13507,8 +13553,7 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction) auto expr = join(enclose_expression(to_unpacked_row_major_matrix_expression(ops[3])), " * ", enclose_expression(to_unpacked_row_major_matrix_expression(ops[2]))); bool forward = should_forward(ops[2]) && should_forward(ops[3]); - auto &e = emit_op(ops[0], ops[1], expr, forward); - e.need_transpose = true; + emit_transposed_op(ops[0], ops[1], expr, forward); a->need_transpose = true; b->need_transpose = true; inherit_expression_dependencies(ops[1], ops[2]); @@ -13531,8 +13576,7 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction) auto expr = join(enclose_expression(to_unpacked_row_major_matrix_expression(ops[2])), " * ", to_enclosed_unpacked_expression(ops[3])); bool forward = should_forward(ops[2]) && should_forward(ops[3]); - auto &e = emit_op(ops[0], ops[1], expr, forward); - e.need_transpose = true; + emit_transposed_op(ops[0], ops[1], expr, forward); a->need_transpose = true; inherit_expression_dependencies(ops[1], ops[2]); inherit_expression_dependencies(ops[1], ops[3]); diff --git a/3rdparty/spirv-cross/spirv_glsl.hpp b/3rdparty/spirv-cross/spirv_glsl.hpp index 78bff2d34..98e93ee99 100644 --- a/3rdparty/spirv-cross/spirv_glsl.hpp +++ b/3rdparty/spirv-cross/spirv_glsl.hpp @@ -763,6 +763,7 @@ protected: bool expression_read_implies_multiple_reads(uint32_t id) const; SPIRExpression &emit_op(uint32_t result_type, uint32_t result_id, const std::string &rhs, bool forward_rhs, bool suppress_usage_tracking = false); + void emit_transposed_op(uint32_t result_type, uint32_t result_id, const std::string &rhs, bool forward_rhs); void access_chain_internal_append_index(std::string &expr, uint32_t base, const SPIRType *type, AccessChainFlags flags, bool &access_chain_is_arrayed, uint32_t index); @@ -805,6 +806,7 @@ protected: const char *index_to_swizzle(uint32_t index); std::string remap_swizzle(const SPIRType &result_type, uint32_t input_components, const std::string &expr); std::string declare_temporary(uint32_t type, uint32_t id); + bool can_declare_inline_temporary(uint32_t id) const; void emit_uninitialized_temporary(uint32_t type, uint32_t id); SPIRExpression &emit_uninitialized_temporary_expression(uint32_t type, uint32_t id); virtual void append_global_func_args(const SPIRFunction &func, uint32_t index, SmallVector &arglist); diff --git a/3rdparty/spirv-cross/spirv_hlsl.cpp b/3rdparty/spirv-cross/spirv_hlsl.cpp index 7394a09e7..098beca55 100644 --- a/3rdparty/spirv-cross/spirv_hlsl.cpp +++ b/3rdparty/spirv-cross/spirv_hlsl.cpp @@ -491,9 +491,9 @@ string CompilerHLSL::type_to_glsl(const SPIRType &type, uint32_t id) case SPIRType::Double: return join("double", type.vecsize); case SPIRType::Int64: - return join("i64vec", type.vecsize); + return join("int64_t", type.vecsize); case SPIRType::UInt64: - return join("u64vec", type.vecsize); + return join("uint64_t", type.vecsize); default: return "???"; } @@ -1595,6 +1595,7 @@ void CompilerHLSL::replace_illegal_names() "Texture3D", "TextureCube", "TextureCubeArray", "true", "typedef", "triangle", "triangleadj", "TriangleStream", "uint", "uniform", "unorm", "unsigned", "vector", "vertexfragment", "VertexShader", "vertices", "void", "volatile", "while", + "signed", }; CompilerGLSL::replace_illegal_names(keywords); @@ -1709,9 +1710,11 @@ void CompilerHLSL::emit_resources() ir.for_each_typed_id([&](uint32_t, SPIRVariable &var) { auto &type = this->get(var.basetype); + bool is_hidden = is_hidden_io_variable(var); + if (var.storage != StorageClassFunction && !var.remapped_variable && type.pointer && (var.storage == StorageClassInput || var.storage == StorageClassOutput) && !is_builtin_variable(var) && - interface_variable_exists_in_entry_point(var.self)) + interface_variable_exists_in_entry_point(var.self) && !is_hidden) { // Builtin variables are handled separately. emit_interface_block_globally(var); @@ -1747,8 +1750,10 @@ void CompilerHLSL::emit_resources() if (var.storage != StorageClassInput && var.storage != StorageClassOutput) return; + bool is_hidden = is_hidden_io_variable(var); + if (!var.remapped_variable && type.pointer && !is_builtin_variable(var) && - interface_variable_exists_in_entry_point(var.self)) + interface_variable_exists_in_entry_point(var.self) && !is_hidden) { if (block) { @@ -3482,10 +3487,12 @@ void CompilerHLSL::emit_hlsl_entry_point() if (var.storage != StorageClassInput) return; + bool is_hidden = is_hidden_io_variable(var); + bool need_matrix_unroll = var.storage == StorageClassInput && execution.model == ExecutionModelVertex; if (!var.remapped_variable && type.pointer && !is_builtin_variable(var) && - interface_variable_exists_in_entry_point(var.self)) + interface_variable_exists_in_entry_point(var.self) && !is_hidden) { if (block) { @@ -7119,6 +7126,30 @@ bool CompilerHLSL::is_hlsl_force_storage_buffer_as_uav(ID id) const return (force_uav_buffer_bindings.find({ desc_set, binding }) != force_uav_buffer_bindings.end()); } +bool CompilerHLSL::is_hidden_io_variable(const SPIRVariable &var) const +{ + if (!is_hidden_variable(var)) + return false; + + // It is too risky to remove stage IO variables that are linkable since it affects link compatibility. + // For vertex inputs and fragment outputs, it's less of a concern and we want reflection data + // to match reality. + + bool is_external_linkage = + (get_execution_model() == ExecutionModelVertex && var.storage == StorageClassInput) || + (get_execution_model() == ExecutionModelFragment && var.storage == StorageClassOutput); + + if (!is_external_linkage) + return false; + + // Unused output I/O variables might still be required to implement framebuffer fetch. + if (var.storage == StorageClassOutput && !is_legacy() && + location_is_framebuffer_fetch(get_decoration(var.self, DecorationLocation)) != 0) + return false; + + return true; +} + void CompilerHLSL::set_hlsl_force_storage_buffer_as_uav(uint32_t desc_set, uint32_t binding) { SetBindingPair pair = { desc_set, binding }; diff --git a/3rdparty/spirv-cross/spirv_hlsl.hpp b/3rdparty/spirv-cross/spirv_hlsl.hpp index e4979dbd3..5f9c3139d 100644 --- a/3rdparty/spirv-cross/spirv_hlsl.hpp +++ b/3rdparty/spirv-cross/spirv_hlsl.hpp @@ -298,6 +298,7 @@ private: SPIRType::BaseType get_builtin_basetype(BuiltIn builtin, SPIRType::BaseType default_type) override; bool is_hlsl_force_storage_buffer_as_uav(ID id) const; + bool is_hidden_io_variable(const SPIRVariable &var) const; Options hlsl_options; diff --git a/3rdparty/spirv-cross/spirv_msl.cpp b/3rdparty/spirv-cross/spirv_msl.cpp index 1c07b524c..2dc148731 100644 --- a/3rdparty/spirv-cross/spirv_msl.cpp +++ b/3rdparty/spirv-cross/spirv_msl.cpp @@ -1514,7 +1514,7 @@ void CompilerMSL::emit_entry_point_declarations() if (is_array(type)) { is_using_builtin_array = true; - statement(get_argument_address_space(var), " ", type_to_glsl(type), "* ", to_restrict(var_id, true), name, + statement(get_variable_address_space(var), " ", type_to_glsl(type), "* ", to_restrict(var_id, true), name, type_to_array_glsl(type, var_id), " ="); uint32_t array_size = get_resource_array_size(type, var_id); @@ -1525,8 +1525,8 @@ void CompilerMSL::emit_entry_point_declarations() for (uint32_t i = 0; i < array_size; i++) { - statement("(", get_argument_address_space(var), " ", type_to_glsl(type), "* ", - to_restrict(var_id, false), ")((", get_argument_address_space(var), " char* ", + statement("(", get_variable_address_space(var), " ", type_to_glsl(type), "* ", + to_restrict(var_id, false), ")((", get_variable_address_space(var), " char* ", to_restrict(var_id, false), ")", to_name(arg_id), ".", dynamic_buffer.second.mbr_name, "[", i, "]", " + ", to_name(dynamic_offsets_buffer_id), "[", base_index + i, "]),"); } @@ -1537,9 +1537,9 @@ void CompilerMSL::emit_entry_point_declarations() } else { - statement(get_argument_address_space(var), " auto& ", to_restrict(var_id, true), name, " = *(", - get_argument_address_space(var), " ", type_to_glsl(type), "* ", to_restrict(var_id, false), ")((", - get_argument_address_space(var), " char* ", to_restrict(var_id, false), ")", to_name(arg_id), ".", + statement(get_variable_address_space(var), " auto& ", to_restrict(var_id, true), name, " = *(", + get_variable_address_space(var), " ", type_to_glsl(type), "* ", to_restrict(var_id, false), ")((", + get_variable_address_space(var), " char* ", to_restrict(var_id, false), ")", to_name(arg_id), ".", dynamic_buffer.second.mbr_name, " + ", to_name(dynamic_offsets_buffer_id), "[", base_index, "]);"); } } @@ -1594,7 +1594,7 @@ void CompilerMSL::emit_entry_point_declarations() statement("spvDescriptorArray ", name, "Smplr {", resource_name, "Smplr};"); break; case SPIRType::Struct: - statement("spvDescriptorArray<", get_argument_address_space(var), " ", type_to_glsl(buffer_type), "*> ", + statement("spvDescriptorArray<", get_variable_address_space(var), " ", type_to_glsl(buffer_type), "*> ", name, " {", resource_name, "};"); break; default: @@ -1605,7 +1605,7 @@ void CompilerMSL::emit_entry_point_declarations() else if (!type.array.empty() && type.basetype == SPIRType::Struct) { // Emit only buffer arrays here. - statement(get_argument_address_space(var), " ", type_to_glsl(buffer_type), "* ", + statement(get_variable_address_space(var), " ", type_to_glsl(buffer_type), "* ", to_restrict(var.self, true), name, "[] ="); begin_scope(); uint32_t array_size = get_resource_array_size(type, var.self); @@ -1629,7 +1629,7 @@ void CompilerMSL::emit_entry_point_declarations() continue; const auto &type = get_variable_data_type(var); - auto addr_space = get_argument_address_space(var); + auto addr_space = get_variable_address_space(var); // This resource name has already been added. auto name = to_name(var_id); @@ -10158,8 +10158,7 @@ void CompilerMSL::emit_instruction(const Instruction &instruction) enclose_expression(to_unpacked_row_major_matrix_expression(ops[2])), ")"); bool forward = should_forward(ops[2]) && should_forward(ops[3]); - auto &e = emit_op(ops[0], ops[1], expr, forward); - e.need_transpose = true; + emit_transposed_op(ops[0], ops[1], expr, forward); a->need_transpose = true; b->need_transpose = true; inherit_expression_dependencies(ops[1], ops[2]); @@ -11141,7 +11140,7 @@ void CompilerMSL::emit_atomic_func_op(uint32_t result_type, uint32_t result_id, } else if (var && ptr_type.storage != StorageClassPhysicalStorageBuffer) { - exp += get_argument_address_space(*var); + exp += get_variable_address_space(*var); } else { @@ -14034,11 +14033,17 @@ bool CompilerMSL::uses_explicit_early_fragment_test() } // In MSL, address space qualifiers are required for all pointer or reference variables -string CompilerMSL::get_argument_address_space(const SPIRVariable &argument) +string CompilerMSL::get_variable_address_space(const SPIRVariable &argument) { const auto &type = get(argument.basetype); - // BDA is always passed around by value. There is no storage class for the argument itself. - if (is_physical_pointer(type)) + return get_type_address_space(type, argument.self, true); +} + +string CompilerMSL::get_leaf_argument_address_space(const SPIRVariable &argument) +{ + const auto &type = get(argument.basetype); + // BDA and variable buffer pointer is always passed around by (pointer) value. There is no storage class for the argument itself. + if (is_physical_or_buffer_pointer(type)) return ""; return get_type_address_space(type, argument.self, true); } @@ -14115,6 +14120,7 @@ string CompilerMSL::get_type_address_space(const SPIRType &type, uint32_t id, bo } else if (!argument) { + // This is used for helper UBOs we insert ourselves. addr_space = "constant"; } else if (type_is_msl_framebuffer_fetch(type)) @@ -14122,6 +14128,7 @@ string CompilerMSL::get_type_address_space(const SPIRType &type, uint32_t id, bo // Subpass inputs are passed around by value. addr_space = ""; } + break; case StorageClassFunction: @@ -14638,7 +14645,7 @@ string CompilerMSL::entry_point_args_argument_buffer(bool append_comma) claimed_bindings.set(buffer_binding); - ep_args += get_argument_address_space(var) + " "; + ep_args += get_variable_address_space(var) + " "; if (recursive_inputs.count(type.self)) ep_args += string("void* ") + to_restrict(id, true) + to_name(id) + "_vp"; @@ -14852,7 +14859,7 @@ void CompilerMSL::entry_point_args_discrete_descriptors(string &ep_args) // Declare the primary alias as void* if (!ep_args.empty()) ep_args += ", "; - ep_args += get_argument_address_space(var) + " void* " + primary_name; + ep_args += get_variable_address_space(var) + " void* " + primary_name; ep_args += " [[buffer(" + convert_to_string(r.index) + ")"; if (interlocked_resources.count(var_id)) ep_args += ", raster_order_group(0)"; @@ -14900,7 +14907,7 @@ void CompilerMSL::entry_point_args_discrete_descriptors(string &ep_args) { if (!ep_args.empty()) ep_args += ", "; - ep_args += get_argument_address_space(var) + " " + type_to_glsl(type) + "* " + + ep_args += get_variable_address_space(var) + " " + type_to_glsl(type) + "* " + to_restrict(var_id, true) + r.name + "_" + convert_to_string(i); ep_args += " [[buffer(" + convert_to_string(r.index + i) + ")"; if (interlocked_resources.count(var_id)) @@ -14913,7 +14920,7 @@ void CompilerMSL::entry_point_args_discrete_descriptors(string &ep_args) { if (!ep_args.empty()) ep_args += ", "; - ep_args += get_argument_address_space(var) + " "; + ep_args += get_variable_address_space(var) + " "; if (recursive_inputs.count(type.self)) ep_args += string("void* ") + to_restrict(var_id, true) + r.name + "_vp"; @@ -15105,7 +15112,7 @@ void CompilerMSL::fix_up_shader_inputs_outputs() { recursive_inputs.insert(type.self); entry_func.fixup_hooks_in.push_back([this, &type, &var, var_id]() { - auto addr_space = get_argument_address_space(var); + auto addr_space = get_variable_address_space(var); auto var_name = to_name(var_id); statement(addr_space, " auto& ", to_restrict(var_id, true), var_name, " = *(", addr_space, " ", type_to_glsl(type), "*)", var_name, "_vp;"); @@ -15802,7 +15809,7 @@ string CompilerMSL::argument_decl(const SPIRFunction::Parameter &arg) // Physical pointer types are passed by pointer, not reference. auto &data_type = get_variable_data_type(var); - bool passed_by_value = is_physical_pointer(var_type); + bool passed_by_value = arg.alias_global_variable ? false : is_physical_or_buffer_pointer(var_type); auto &type = passed_by_value ? var_type : data_type; // If we need to modify the name of the variable, make sure we use the original variable. @@ -15845,7 +15852,7 @@ string CompilerMSL::argument_decl(const SPIRFunction::Parameter &arg) spv_function_implementations.count(SPVFuncImplDynamicImageSampler); // Allow Metal to use the array template to make arrays a value type - string address_space = get_argument_address_space(var); + string address_space = arg.alias_global_variable ? get_variable_address_space(var) : get_leaf_argument_address_space(var); bool builtin = has_decoration(var.self, DecorationBuiltIn); auto builtin_type = BuiltIn(get_decoration(arg.id, DecorationBuiltIn)); @@ -15942,10 +15949,29 @@ string CompilerMSL::argument_decl(const SPIRFunction::Parameter &arg) } else { - if (!address_space.empty()) - decl = join(address_space, " ", decl); - decl += " "; - decl += to_expression(name_id); + // Variable pointer to array is kinda awkward ... + bool pointer_to_logical_buffer_array = + !is_physical_pointer(type) && is_pointer(type) && + has_decoration(type.parent_type, DecorationArrayStride); + + if (pointer_to_logical_buffer_array) + { + decl.pop_back(); + decl += " (*"; + decl += to_expression(name_id); + decl += ")"; + bool old_is_using_builtin_array = is_using_builtin_array; + is_using_builtin_array = true; + decl += type_to_array_glsl(type, name_id); + is_using_builtin_array = old_is_using_builtin_array; + } + else + { + if (!address_space.empty()) + decl = join(address_space, " ", decl); + decl += " "; + decl += to_expression(name_id); + } } } else if (is_array(type) && !type_is_image) @@ -16252,6 +16278,7 @@ const std::unordered_set &CompilerMSL::get_reserved_keyword_set() "quad_broadcast", "thread", "threadgroup", + "signed", }; return keywords; @@ -16395,6 +16422,7 @@ const std::unordered_set &CompilerMSL::get_illegal_func_names() "uint16", "float8", "float16", + "signed", }; return illegal_func_names; @@ -16563,8 +16591,11 @@ string CompilerMSL::type_to_glsl(const SPIRType &type, uint32_t id, bool member) // the C-style nesting works right. // FIXME: This is somewhat of a hack. bool old_is_using_builtin_array = is_using_builtin_array; + bool pointer_to_buffer_array = is_pointer(type) && has_decoration(type.parent_type, DecorationArrayStride); if (is_physical_pointer(type)) is_using_builtin_array = false; + else if (pointer_to_buffer_array) + is_using_builtin_array = true; type_name = join(type_address_space, " ", type_to_glsl(*p_parent_type, id)); @@ -17930,7 +17961,10 @@ string CompilerMSL::builtin_qualifier(BuiltIn builtin) { // thread_execution_width is an alias for threads_per_simdgroup, and it's only available since 1.0, // but not in fragment. - return "thread_execution_width"; + if (msl_options.supports_msl_version(3, 0)) + return "threads_per_simdgroup"; + else + return "thread_execution_width"; } case BuiltInNumSubgroups: @@ -17960,6 +17994,7 @@ string CompilerMSL::builtin_qualifier(BuiltIn builtin) return "thread_index_in_simdgroup"; } else if (execution.model == ExecutionModelKernel || execution.model == ExecutionModelGLCompute || + execution.model == ExecutionModelTaskEXT || execution.model == ExecutionModelMeshEXT || execution.model == ExecutionModelTessellationControl || (execution.model == ExecutionModelVertex && msl_options.vertex_for_tessellation)) { @@ -19898,7 +19933,7 @@ void CompilerMSL::analyze_argument_buffers() { recursive_inputs.insert(type_id); auto &entry_func = this->get(ir.default_entry_point); - auto addr_space = get_argument_address_space(buffer_var); + auto addr_space = get_variable_address_space(buffer_var); entry_func.fixup_hooks_in.push_back([this, addr_space, buffer_name, buffer_type_name]() { statement(addr_space, " auto& ", buffer_name, " = *(", addr_space, " ", buffer_type_name, "*)", buffer_name, "_vp;"); }); diff --git a/3rdparty/spirv-cross/spirv_msl.hpp b/3rdparty/spirv-cross/spirv_msl.hpp index 75d3aa724..f63f5a234 100644 --- a/3rdparty/spirv-cross/spirv_msl.hpp +++ b/3rdparty/spirv-cross/spirv_msl.hpp @@ -1126,7 +1126,9 @@ protected: void mark_struct_members_packed(const SPIRType &type); void ensure_member_packing_rules_msl(SPIRType &ib_type, uint32_t index); bool validate_member_packing_rules_msl(const SPIRType &type, uint32_t index) const; - std::string get_argument_address_space(const SPIRVariable &argument); + std::string get_variable_address_space(const SPIRVariable &argument); + // Special case of get_variable_address_space which is only used for leaf functions. + std::string get_leaf_argument_address_space(const SPIRVariable &argument); std::string get_type_address_space(const SPIRType &type, uint32_t id, bool argument = false); bool decoration_flags_signal_volatile(const Bitset &flags) const; bool decoration_flags_signal_coherent(const Bitset &flags) const;