mirror of
https://github.com/bkaradzic/bgfx.git
synced 2026-02-17 20:52:36 +01:00
Updated spirv-cross.
This commit is contained in:
committed by
Branimir Karadžić
parent
1a4e866800
commit
3d59e16fd7
8
3rdparty/spirv-cross/spirv_cross.cpp
vendored
8
3rdparty/spirv-cross/spirv_cross.cpp
vendored
@@ -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 &&
|
||||
|
||||
1
3rdparty/spirv-cross/spirv_cross.hpp
vendored
1
3rdparty/spirv-cross/spirv_cross.hpp
vendored
@@ -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;
|
||||
|
||||
62
3rdparty/spirv-cross/spirv_glsl.cpp
vendored
62
3rdparty/spirv-cross/spirv_glsl.cpp
vendored
@@ -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<SPIRType>(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<SPIRExpression>(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<SPIRType>(result_type);
|
||||
std::swap(dummy_type.columns, dummy_type.vecsize);
|
||||
transposed_type_id = ir.increase_bound_by(1);
|
||||
set<SPIRType>(transposed_type_id, dummy_type);
|
||||
}
|
||||
|
||||
statement(declare_temporary(transposed_type_id, result_id), rhs, ";");
|
||||
auto &e = set<SPIRExpression>(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<SPIRVariable>(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<SPIRExpression>(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]);
|
||||
|
||||
2
3rdparty/spirv-cross/spirv_glsl.hpp
vendored
2
3rdparty/spirv-cross/spirv_glsl.hpp
vendored
@@ -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<std::string> &arglist);
|
||||
|
||||
41
3rdparty/spirv-cross/spirv_hlsl.cpp
vendored
41
3rdparty/spirv-cross/spirv_hlsl.cpp
vendored
@@ -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<SPIRVariable>([&](uint32_t, SPIRVariable &var) {
|
||||
auto &type = this->get<SPIRType>(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 };
|
||||
|
||||
1
3rdparty/spirv-cross/spirv_hlsl.hpp
vendored
1
3rdparty/spirv-cross/spirv_hlsl.hpp
vendored
@@ -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;
|
||||
|
||||
|
||||
91
3rdparty/spirv-cross/spirv_msl.cpp
vendored
91
3rdparty/spirv-cross/spirv_msl.cpp
vendored
@@ -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<sampler> ", 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<SPIRType>(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<SPIRType>(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<T> 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<std::string> &CompilerMSL::get_reserved_keyword_set()
|
||||
"quad_broadcast",
|
||||
"thread",
|
||||
"threadgroup",
|
||||
"signed",
|
||||
};
|
||||
|
||||
return keywords;
|
||||
@@ -16395,6 +16422,7 @@ const std::unordered_set<std::string> &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<SPIRFunction>(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;");
|
||||
});
|
||||
|
||||
4
3rdparty/spirv-cross/spirv_msl.hpp
vendored
4
3rdparty/spirv-cross/spirv_msl.hpp
vendored
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user