Pass down orig_id to type_to_array_glsl as well.

Allows UBO/SSBO resources in MSL to get the layout-derived size as well.
This commit is contained in:
Hans-Kristian Arntzen 2024-05-21 13:41:40 +02:00
parent b236352fef
commit 8b3aa21944
6 changed files with 51 additions and 42 deletions

View File

@ -40,7 +40,7 @@ void CompilerCPP::emit_buffer_block(const SPIRVariable &var)
emit_block_struct(type);
auto buffer_name = to_name(type.self);
statement("internal::Resource<", buffer_name, type_to_array_glsl(type), "> ", instance_name, "__;");
statement("internal::Resource<", buffer_name, type_to_array_glsl(type, var.self), "> ", instance_name, "__;");
statement_no_indent("#define ", instance_name, " __res->", instance_name, "__.get()");
resource_registrations.push_back(
join("s.register_resource(", instance_name, "__", ", ", descriptor_set, ", ", binding, ");"));
@ -68,7 +68,7 @@ void CompilerCPP::emit_interface_block(const SPIRVariable &var)
else
buffer_name = type_to_glsl(type);
statement("internal::", qual, "<", buffer_name, type_to_array_glsl(type), "> ", instance_name, "__;");
statement("internal::", qual, "<", buffer_name, type_to_array_glsl(type, var.self), "> ", instance_name, "__;");
statement_no_indent("#define ", instance_name, " __res->", instance_name, "__.get()");
resource_registrations.push_back(join("s.register_", lowerqual, "(", instance_name, "__", ", ", location, ");"));
statement("");
@ -100,14 +100,14 @@ void CompilerCPP::emit_uniform(const SPIRVariable &var)
if (type.basetype == SPIRType::Image || type.basetype == SPIRType::SampledImage ||
type.basetype == SPIRType::AtomicCounter)
{
statement("internal::Resource<", type_name, type_to_array_glsl(type), "> ", instance_name, "__;");
statement("internal::Resource<", type_name, type_to_array_glsl(type, var.self), "> ", instance_name, "__;");
statement_no_indent("#define ", instance_name, " __res->", instance_name, "__.get()");
resource_registrations.push_back(
join("s.register_resource(", instance_name, "__", ", ", descriptor_set, ", ", binding, ");"));
}
else
{
statement("internal::UniformConstant<", type_name, type_to_array_glsl(type), "> ", instance_name, "__;");
statement("internal::UniformConstant<", type_name, type_to_array_glsl(type, var.self), "> ", instance_name, "__;");
statement_no_indent("#define ", instance_name, " __res->", instance_name, "__.get()");
resource_registrations.push_back(
join("s.register_uniform_constant(", instance_name, "__", ", ", location, ");"));
@ -130,7 +130,7 @@ void CompilerCPP::emit_push_constant_block(const SPIRVariable &var)
auto buffer_name = to_name(type.self);
auto instance_name = to_name(var.self);
statement("internal::PushConstant<", buffer_name, type_to_array_glsl(type), "> ", instance_name, ";");
statement("internal::PushConstant<", buffer_name, type_to_array_glsl(type, var.self), "> ", instance_name, ";");
statement_no_indent("#define ", instance_name, " __res->", instance_name, ".get()");
resource_registrations.push_back(join("s.register_push_constant(", instance_name, "__", ");"));
statement("");

View File

@ -2434,7 +2434,7 @@ void CompilerGLSL::emit_buffer_reference_block(uint32_t type_id, bool forward_de
else
{
auto &pointee_type = get_pointee_type(type);
statement(type_to_glsl(pointee_type), " value", type_to_array_glsl(pointee_type), ";");
statement(type_to_glsl(pointee_type), " value", type_to_array_glsl(pointee_type, 0), ";");
}
end_scope_decl();
@ -2513,7 +2513,7 @@ void CompilerGLSL::emit_buffer_block_native(const SPIRVariable &var)
// It will need to be reset if we have to recompile.
preserve_alias_on_reset(var.self);
add_resource_name(var.self);
end_scope_decl(to_name(var.self) + type_to_array_glsl(type));
end_scope_decl(to_name(var.self) + type_to_array_glsl(type, var.self));
statement("");
}
@ -2780,7 +2780,7 @@ void CompilerGLSL::emit_interface_block(const SPIRVariable &var)
}
add_resource_name(var.self);
end_scope_decl(join(to_name(var.self), type_to_array_glsl(type)));
end_scope_decl(join(to_name(var.self), type_to_array_glsl(type, var.self)));
statement("");
}
}
@ -3977,7 +3977,7 @@ void CompilerGLSL::emit_output_variable_initializer(const SPIRVariable &var)
auto &c = get<SPIRConstant>(var.initializer);
for (uint32_t j = 0; j < array_size; j++)
exprs.push_back(to_expression(get<SPIRConstant>(c.subconstants[j]).subconstants[i]));
statement("const ", type_to_glsl(array_type), " ", lut_name, type_to_array_glsl(array_type), " = ",
statement("const ", type_to_glsl(array_type), " ", lut_name, type_to_array_glsl(array_type, 0), " = ",
type_to_glsl_constructor(array_type), "(", merge(exprs, ", "), ");");
}
@ -4035,7 +4035,7 @@ void CompilerGLSL::emit_output_variable_initializer(const SPIRVariable &var)
else if (is_control_point)
{
auto lut_name = join("_", var.self, "_init");
statement("const ", type_to_glsl(type), " ", lut_name, type_to_array_glsl(type),
statement("const ", type_to_glsl(type), " ", lut_name, type_to_array_glsl(type, 0),
" = ", to_expression(var.initializer), ";");
entry_func.fixup_hooks_in.push_back([&, lut_name]() {
statement(to_expression(var.self), "[gl_InvocationID] = ", lut_name, "[gl_InvocationID];");
@ -4060,7 +4060,7 @@ void CompilerGLSL::emit_output_variable_initializer(const SPIRVariable &var)
{
auto lut_name = join("_", var.self, "_init");
statement("const ", type_to_glsl(type), " ", lut_name,
type_to_array_glsl(type), " = ", to_expression(var.initializer), ";");
type_to_array_glsl(type, var.self), " = ", to_expression(var.initializer), ";");
entry_func.fixup_hooks_in.push_back([&, lut_name, is_patch]() {
if (is_patch)
{
@ -12204,7 +12204,7 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction)
if (emit_return_value_as_argument)
{
statement(type_to_glsl(return_type), " ", to_name(id), type_to_array_glsl(return_type), ";");
statement(type_to_glsl(return_type), " ", to_name(id), type_to_array_glsl(return_type, 0), ";");
arglist.push_back(to_name(id));
}
@ -15175,7 +15175,7 @@ string CompilerGLSL::variable_decl(const SPIRType &type, const string &name, uin
{
string type_name = type_to_glsl(type, id);
remap_variable_type_name(type, name, type_name);
return join(type_name, " ", name, type_to_array_glsl(type));
return join(type_name, " ", name, type_to_array_glsl(type, id));
}
bool CompilerGLSL::variable_decl_is_remapped_storage(const SPIRVariable &var, StorageClass storage) const
@ -15532,7 +15532,7 @@ string CompilerGLSL::to_array_size(const SPIRType &type, uint32_t index)
return "";
}
string CompilerGLSL::type_to_array_glsl(const SPIRType &type)
string CompilerGLSL::type_to_array_glsl(const SPIRType &type, uint32_t)
{
if (type.pointer && type.storage == StorageClassPhysicalStorageBufferEXT && type.basetype != SPIRType::Struct)
{
@ -16096,7 +16096,7 @@ void CompilerGLSL::emit_function_prototype(SPIRFunction &func, const Bitset &ret
auto &type = get<SPIRType>(func.return_type);
decl += flags_to_qualifiers_glsl(type, return_flags);
decl += type_to_glsl(type);
decl += type_to_array_glsl(type);
decl += type_to_array_glsl(type, 0);
decl += " ";
if (func.self == ir.default_entry_point)

View File

@ -564,8 +564,8 @@ protected:
Options options;
virtual std::string type_to_array_glsl(
const SPIRType &type); // Allow Metal to use the array<T> template to make arrays a value type
// Allow Metal to use the array<T> template to make arrays a value type
virtual std::string type_to_array_glsl(const SPIRType &type, uint32_t variable_id);
std::string to_array_size(const SPIRType &type, uint32_t index);
uint32_t to_array_size_literal(const SPIRType &type, uint32_t index) const;
uint32_t to_array_size_literal(const SPIRType &type) const;

View File

@ -1002,7 +1002,7 @@ void CompilerHLSL::emit_interface_block_member_in_struct(const SPIRVariable &var
statement(to_interpolation_qualifiers(get_member_decoration_bitset(type.self, member_index)),
type_to_glsl(mbr_type),
" ", mbr_name, type_to_array_glsl(mbr_type),
" ", mbr_name, type_to_array_glsl(mbr_type, var.self),
" : ", semantic, ";");
// Structs and arrays should consume more locations.
@ -2277,7 +2277,7 @@ void CompilerHLSL::emit_resources()
// Need out variable since HLSL does not support returning arrays.
auto &type = get<SPIRType>(type_id);
auto type_str = type_to_glsl(type);
auto type_arr_str = type_to_array_glsl(type);
auto type_arr_str = type_to_array_glsl(type, 0);
statement("void spvSelectComposite(out ", type_str, " out_value", type_arr_str, ", bool cond, ",
type_str, " true_val", type_arr_str, ", ",
type_str, " false_val", type_arr_str, ")");
@ -2679,7 +2679,7 @@ void CompilerHLSL::emit_buffer_block(const SPIRVariable &var)
type_name = is_readonly ? "ByteAddressBuffer" : is_interlocked ? "RasterizerOrderedByteAddressBuffer" : "RWByteAddressBuffer";
add_resource_name(var.self);
statement(is_coherent ? "globallycoherent " : "", type_name, " ", to_name(var.self), type_to_array_glsl(type),
statement(is_coherent ? "globallycoherent " : "", type_name, " ", to_name(var.self), type_to_array_glsl(type, var.self),
to_resource_binding(var), ";");
}
else
@ -2766,7 +2766,7 @@ void CompilerHLSL::emit_buffer_block(const SPIRVariable &var)
}
emit_struct(get<SPIRType>(type.self));
statement("ConstantBuffer<", to_name(type.self), "> ", to_name(var.self), type_to_array_glsl(type),
statement("ConstantBuffer<", to_name(type.self), "> ", to_name(var.self), type_to_array_glsl(type, var.self),
to_resource_binding(var), ";");
}
}
@ -2952,7 +2952,7 @@ void CompilerHLSL::emit_function_prototype(SPIRFunction &func, const Bitset &ret
out_argument += type_to_glsl(type);
out_argument += " ";
out_argument += "spvReturnValue";
out_argument += type_to_array_glsl(type);
out_argument += type_to_array_glsl(type, 0);
arglist.push_back(std::move(out_argument));
}
@ -2978,7 +2978,7 @@ void CompilerHLSL::emit_function_prototype(SPIRFunction &func, const Bitset &ret
{
// Manufacture automatic sampler arg for SampledImage texture
arglist.push_back(join(is_depth_image(arg_type, arg.id) ? "SamplerComparisonState " : "SamplerState ",
to_sampler_expression(arg.id), type_to_array_glsl(arg_type)));
to_sampler_expression(arg.id), type_to_array_glsl(arg_type, arg.id)));
}
// Hold a pointer to the parameter so we can invalidate the readonly field if needed.
@ -4076,16 +4076,16 @@ void CompilerHLSL::emit_modern_uniform(const SPIRVariable &var)
is_coherent = has_decoration(var.self, DecorationCoherent);
statement(is_coherent ? "globallycoherent " : "", image_type_hlsl_modern(type, var.self), " ",
to_name(var.self), type_to_array_glsl(type), to_resource_binding(var), ";");
to_name(var.self), type_to_array_glsl(type, var.self), to_resource_binding(var), ";");
if (type.basetype == SPIRType::SampledImage && type.image.dim != DimBuffer)
{
// For combined image samplers, also emit a combined image sampler.
if (is_depth_image(type, var.self))
statement("SamplerComparisonState ", to_sampler_expression(var.self), type_to_array_glsl(type),
statement("SamplerComparisonState ", to_sampler_expression(var.self), type_to_array_glsl(type, var.self),
to_resource_binding_sampler(var), ";");
else
statement("SamplerState ", to_sampler_expression(var.self), type_to_array_glsl(type),
statement("SamplerState ", to_sampler_expression(var.self), type_to_array_glsl(type, var.self),
to_resource_binding_sampler(var), ";");
}
break;
@ -4093,10 +4093,10 @@ void CompilerHLSL::emit_modern_uniform(const SPIRVariable &var)
case SPIRType::Sampler:
if (comparison_ids.count(var.self))
statement("SamplerComparisonState ", to_name(var.self), type_to_array_glsl(type), to_resource_binding(var),
statement("SamplerComparisonState ", to_name(var.self), type_to_array_glsl(type, var.self), to_resource_binding(var),
";");
else
statement("SamplerState ", to_name(var.self), type_to_array_glsl(type), to_resource_binding(var), ";");
statement("SamplerState ", to_name(var.self), type_to_array_glsl(type, var.self), to_resource_binding(var), ";");
break;
default:

View File

@ -1325,7 +1325,7 @@ void CompilerMSL::emit_entry_point_declarations()
is_using_builtin_array = true;
statement(get_argument_address_space(var), " ", type_to_glsl(type), "* ", to_restrict(var_id, true), name,
type_to_array_glsl(type), " =");
type_to_array_glsl(type, var_id), " =");
uint32_t array_size = to_array_size_literal(type);
begin_scope();
@ -1454,7 +1454,7 @@ void CompilerMSL::emit_entry_point_declarations()
is_using_builtin_array = true;
statement(desc_addr_space, " auto& ", to_restrict(var_id, true), to_name(var_id), " = (", addr_space, " ",
type_to_glsl(type), "* ", desc_addr_space, " (&)",
type_to_array_glsl(type), ")", ir.meta[alias_id].decoration.qualified_alias, ";");
type_to_array_glsl(type, var_id), ")", ir.meta[alias_id].decoration.qualified_alias, ";");
is_using_builtin_array = false;
}
}
@ -3488,7 +3488,7 @@ void CompilerMSL::emit_local_masked_variable(const SPIRVariable &masked_var, boo
get_entry_point().output_vertices;
statement("threadgroup ", type_to_glsl(type), " ",
"spvStorage", to_name(masked_var.self), "[", max_num_instances, "]",
type_to_array_glsl(type), ";");
type_to_array_glsl(type, 0), ";");
// Assign a threadgroup slice to each PrimitiveID.
// We assume here that workgroup size is rounded to 32,
@ -10887,7 +10887,7 @@ void CompilerMSL::emit_function_prototype(SPIRFunction &func, const Bitset &)
decl += "thread ";
decl += type_to_glsl(type);
decl += " (&spvReturnValue)";
decl += type_to_array_glsl(type);
decl += type_to_array_glsl(type, 0);
if (!func.arguments.empty())
decl += ", ";
}
@ -12370,7 +12370,7 @@ string CompilerMSL::to_struct_member(const SPIRType &type, uint32_t member_type_
variable_storage_requires_stage_io(StorageClassInput)));
if (is_ib_in_out && is_member_builtin(type, index, &builtin))
is_using_builtin_array = true;
array_type = type_to_array_glsl(physical_type);
array_type = type_to_array_glsl(physical_type, orig_id);
}
if (orig_id)
@ -12940,14 +12940,14 @@ uint32_t CompilerMSL::get_or_allocate_builtin_output_member_location(spv::BuiltI
string CompilerMSL::func_type_decl(SPIRType &type)
{
// The regular function return type. If not processing the entry point function, that's all we need
string return_type = type_to_glsl(type) + type_to_array_glsl(type);
string return_type = type_to_glsl(type) + type_to_array_glsl(type, 0);
if (!processing_entry_point)
return return_type;
// If an outgoing interface block has been defined, and it should be returned, override the entry point return type
bool ep_should_return_output = !get_is_rasterization_disabled();
if (stage_out_var_id && ep_should_return_output)
return_type = type_to_glsl(get_stage_out_struct_type()) + type_to_array_glsl(type);
return_type = type_to_glsl(get_stage_out_struct_type()) + type_to_array_glsl(type, 0);
// Prepend a entry type, based on the execution model
string entry_type;
@ -14814,7 +14814,7 @@ string CompilerMSL::argument_decl(const SPIRFunction::Parameter &arg)
}
decl += to_expression(name_id);
decl += ")";
decl += type_to_array_glsl(type);
decl += type_to_array_glsl(type, name_id);
}
else
{
@ -14865,7 +14865,7 @@ string CompilerMSL::argument_decl(const SPIRFunction::Parameter &arg)
}
else
{
auto array_size_decl = type_to_array_glsl(type);
auto array_size_decl = type_to_array_glsl(type, name_id);
if (array_size_decl.empty())
decl += "& ";
else
@ -15605,7 +15605,7 @@ string CompilerMSL::type_to_glsl(const SPIRType &type, uint32_t id)
return type_to_glsl(type, id, false);
}
string CompilerMSL::type_to_array_glsl(const SPIRType &type)
string CompilerMSL::type_to_array_glsl(const SPIRType &type, uint32_t variable_id)
{
// Allow Metal to use the array<T> template to make arrays a value type
switch (type.basetype)
@ -15613,11 +15613,20 @@ string CompilerMSL::type_to_array_glsl(const SPIRType &type)
case SPIRType::AtomicCounter:
case SPIRType::ControlPointArray:
case SPIRType::RayQuery:
return CompilerGLSL::type_to_array_glsl(type);
return CompilerGLSL::type_to_array_glsl(type, variable_id);
default:
if (type_is_array_of_pointers(type) || using_builtin_array())
return CompilerGLSL::type_to_array_glsl(type);
{
const SPIRVariable *var = variable_id ? &get<SPIRVariable>(variable_id) : nullptr;
if (var && (var->storage == StorageClassUniform || var->storage == StorageClassStorageBuffer) &&
is_array(get_variable_data_type(*var)))
{
return join("[", get_resource_array_size(type, variable_id), "]");
}
else
return CompilerGLSL::type_to_array_glsl(type, variable_id);
}
else
return "";
}
@ -18022,7 +18031,7 @@ void CompilerMSL::emit_argument_buffer_aliased_descriptor(const SPIRVariable &al
is_using_builtin_array = true;
bool needs_post_cast_deref = !is_array(data_type);
string ref_type = needs_post_cast_deref ? "&" : join("(&)", type_to_array_glsl(var_type));
string ref_type = needs_post_cast_deref ? "&" : join("(&)", type_to_array_glsl(var_type, aliased_var.self));
if (is_var_runtime_size_array(aliased_var))
{

View File

@ -862,7 +862,7 @@ protected:
void emit_block_hints(const SPIRBlock &block) override;
// Allow Metal to use the array<T> template to make arrays a value type
std::string type_to_array_glsl(const SPIRType &type) override;
std::string type_to_array_glsl(const SPIRType &type, uint32_t variable_id) override;
std::string constant_op_expression(const SPIRConstantOp &cop) override;
bool variable_decl_is_remapped_storage(const SPIRVariable &variable, spv::StorageClass storage) const override;