Updated spirv-cross.
This commit is contained in:
parent
837eecfa16
commit
12e3ad2970
10
3rdparty/spirv-cross/spirv_cross_parsed_ir.cpp
vendored
10
3rdparty/spirv-cross/spirv_cross_parsed_ir.cpp
vendored
@ -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);
|
||||
|
||||
|
47
3rdparty/spirv-cross/spirv_glsl.cpp
vendored
47
3rdparty/spirv-cross/spirv_glsl.cpp
vendored
@ -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.
|
||||
|
2
3rdparty/spirv-cross/spirv_glsl.hpp
vendored
2
3rdparty/spirv-cross/spirv_glsl.hpp
vendored
@ -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);
|
||||
|
||||
|
1
3rdparty/spirv-cross/spirv_hlsl.cpp
vendored
1
3rdparty/spirv-cross/spirv_hlsl.cpp
vendored
@ -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();
|
||||
|
21
3rdparty/spirv-cross/spirv_msl.cpp
vendored
21
3rdparty/spirv-cross/spirv_msl.cpp
vendored
@ -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, "]");
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user