Updated spirv-cross.

This commit is contained in:
Бранимир Караџић 2022-03-12 13:23:36 -08:00
parent 837eecfa16
commit 12e3ad2970
5 changed files with 72 additions and 9 deletions

View File

@ -349,7 +349,7 @@ void ParsedIR::set_name(ID id, const string &name)
void ParsedIR::set_member_name(TypeID id, uint32_t index, const string &name)
{
auto &m = meta[id];
m.members.resize(max(meta[id].members.size(), size_t(index) + 1));
m.members.resize(max(m.members.size(), size_t(index) + 1));
m.members[index].alias = name;
if (!is_valid_identifier(name) || is_reserved_identifier(name, true, false))
meta_needing_name_fixup.insert(id);
@ -451,8 +451,9 @@ void ParsedIR::set_decoration(ID id, Decoration decoration, uint32_t argument)
void ParsedIR::set_member_decoration(TypeID id, uint32_t index, Decoration decoration, uint32_t argument)
{
meta[id].members.resize(max(meta[id].members.size(), size_t(index) + 1));
auto &dec = meta[id].members[index];
auto &m = meta[id];
m.members.resize(max(m.members.size(), size_t(index) + 1));
auto &dec = m.members[index];
dec.decoration_flags.set(decoration);
switch (decoration)
@ -792,7 +793,8 @@ const Bitset &ParsedIR::get_decoration_bitset(ID id) const
void ParsedIR::set_member_decoration_string(TypeID id, uint32_t index, Decoration decoration, const string &argument)
{
meta[id].members.resize(max(meta[id].members.size(), size_t(index) + 1));
auto &m = meta[id];
m.members.resize(max(m.members.size(), size_t(index) + 1));
auto &dec = meta[id].members[index];
dec.decoration_flags.set(decoration);

View File

@ -656,6 +656,7 @@ string CompilerGLSL::compile()
backend.support_case_fallthrough = false;
// Scan the SPIR-V to find trivial uses of extensions.
fixup_anonymous_struct_names();
fixup_type_alias();
reorder_type_alias();
build_function_control_flow_graphs_and_analyze();
@ -15791,6 +15792,52 @@ void CompilerGLSL::reset_name_caches()
function_overloads.clear();
}
void CompilerGLSL::fixup_anonymous_struct_names(std::unordered_set<uint32_t> &visited, const SPIRType &type)
{
if (visited.count(type.self))
return;
visited.insert(type.self);
for (uint32_t i = 0; i < uint32_t(type.member_types.size()); i++)
{
auto &mbr_type = get<SPIRType>(type.member_types[i]);
if (mbr_type.basetype == SPIRType::Struct)
{
// If there are multiple aliases, the output might be somewhat unpredictable,
// but the only real alternative in that case is to do nothing, which isn't any better.
// This check should be fine in practice.
if (get_name(mbr_type.self).empty() && !get_member_name(type.self, i).empty())
{
auto anon_name = join("anon_", get_member_name(type.self, i));
ParsedIR::sanitize_underscores(anon_name);
set_name(mbr_type.self, anon_name);
}
fixup_anonymous_struct_names(visited, mbr_type);
}
}
}
void CompilerGLSL::fixup_anonymous_struct_names()
{
// HLSL codegen can often end up emitting anonymous structs inside blocks, which
// breaks GL linking since all names must match ...
// Try to emit sensible code, so attempt to find such structs and emit anon_$member.
// Breaks exponential explosion with weird type trees.
std::unordered_set<uint32_t> visited;
ir.for_each_typed_id<SPIRType>([&](uint32_t, SPIRType &type) {
if (type.basetype == SPIRType::Struct &&
(has_decoration(type.self, DecorationBlock) ||
has_decoration(type.self, DecorationBufferBlock)))
{
fixup_anonymous_struct_names(visited, type);
}
});
}
void CompilerGLSL::fixup_type_alias()
{
// Due to how some backends work, the "master" type of type_alias must be a block-like type if it exists.

View File

@ -946,6 +946,8 @@ protected:
void fixup_type_alias();
void reorder_type_alias();
void fixup_anonymous_struct_names();
void fixup_anonymous_struct_names(std::unordered_set<uint32_t> &visited, const SPIRType &type);
static const char *vector_swizzle(int vecsize, int index);

View File

@ -5820,6 +5820,7 @@ string CompilerHLSL::compile()
// SM 4.1 does not support precise for some reason.
backend.support_precise_qualifier = hlsl_options.shader_model >= 50 || hlsl_options.shader_model == 40;
fixup_anonymous_struct_names();
fixup_type_alias();
reorder_type_alias();
build_function_control_flow_graphs_and_analyze();

View File

@ -1371,6 +1371,7 @@ string CompilerMSL::compile()
for (auto &id : next_metal_resource_ids)
id = 0;
fixup_anonymous_struct_names();
fixup_type_alias();
replace_illegal_names();
sync_entry_point_aliases_and_names();
@ -3132,6 +3133,14 @@ void CompilerMSL::add_variable_to_interface_block(StorageClass storage, const st
return;
}
// If variable names alias, they will end up with wrong names in the interface struct, because
// there might be aliases in the member name cache and there would be a mismatch in fixup_in code.
// Make sure to register the variables as unique resource names ahead of time.
// This would normally conflict with the name cache when emitting local variables,
// but this happens in the setup stage, before we hit compilation loops.
// The name cache is cleared before we actually emit code, so this is safe.
add_resource_name(var.self);
if (var_type.basetype == SPIRType::Struct)
{
bool block_requires_flattening = variable_storage_requires_stage_io(storage) || is_block;
@ -3189,7 +3198,7 @@ void CompilerMSL::add_variable_to_interface_block(StorageClass storage, const st
if (storage == StorageClassOutput && is_stage_output_block_member_masked(var, mbr_idx, meta.strip_array))
{
location = UINT32_MAX; // Skip this member and resolve location again on next var member
location = UINT32_MAX; // Skip this member and resolve location again on next var member
if (is_block)
masked_block = true;
@ -3226,16 +3235,18 @@ void CompilerMSL::add_variable_to_interface_block(StorageClass storage, const st
{
bool is_composite_type = is_matrix(mbr_type) || is_array(mbr_type) || mbr_type.basetype == SPIRType::Struct;
bool attribute_load_store =
storage == StorageClassInput && get_execution_model() != ExecutionModelFragment;
storage == StorageClassInput && get_execution_model() != ExecutionModelFragment;
bool storage_is_stage_io = variable_storage_requires_stage_io(storage);
// Clip/CullDistance always need to be declared as user attributes.
if (builtin == BuiltInClipDistance || builtin == BuiltInCullDistance)
is_builtin = false;
string mbr_name_qual = to_name(var_type.self);
string var_chain_qual = to_name(var.self);
if (elem_cnt > 1) {
const string var_name = to_name(var.self);
string mbr_name_qual = var_name;
string var_chain_qual = var_name;
if (elem_cnt > 1)
{
mbr_name_qual += join("_", elem_idx);
var_chain_qual += join("[", elem_idx, "]");
}