Fix some naming issues for stripped and flattened structs.

This commit is contained in:
Hans-Kristian Arntzen 2017-10-10 17:32:26 +02:00
parent 1ec1bec296
commit 94ff355812
7 changed files with 36 additions and 39 deletions

View File

@ -7,7 +7,7 @@ struct CBO_1
};
ConstantBuffer<CBO_1> cbo[2][4] : register(b4);
cbuffer PushMe
cbuffer push
{
float4 PushMe_a : packoffset(c0);
float4 PushMe_b : packoffset(c1);

View File

@ -4,7 +4,7 @@ struct B
float b;
};
cbuffer UBO : register(b0)
cbuffer _42 : register(b0)
{
int UBO_some_value : packoffset(c0);
};

View File

@ -1,8 +1,8 @@
cbuffer CBuffer : register(b3)
cbuffer cbuf : register(b3)
{
float4 CBuffer_a : packoffset(c0);
};
cbuffer PushMe
cbuffer registers
{
float4 PushMe_d : packoffset(c0);
};

View File

@ -1,4 +1,4 @@
cbuffer UBO
cbuffer _16
{
row_major float4x4 UBO_uMVP : packoffset(c0);
};

View File

@ -27,7 +27,7 @@ using namespace spirv_cross;
#define log(...) fprintf(stderr, __VA_ARGS__)
static string ensure_valid_identifier(const string &name)
static string ensure_valid_identifier(const string &name, bool member)
{
// Functions in glslangValidator are mangled with name(<mangled> stuff.
// Normally, we would never see '(' in any legal identifiers, so just strip them out.
@ -37,12 +37,26 @@ static string ensure_valid_identifier(const string &name)
{
auto &c = str[i];
// _<num> variables are reserved by the internal implementation,
// otherwise, make sure the name is a valid identifier.
if (i == 0 || (str[0] == '_' && i == 1))
c = isalpha(c) ? c : '_';
if (member)
{
// _m<num> variables are reserved by the internal implementation,
// otherwise, make sure the name is a valid identifier.
if (i == 0)
c = isalpha(c) ? c : '_';
else if (i == 2 && str[0] == '_' && str[1] == 'm')
c = isalpha(c) ? c : '_';
else
c = isalnum(c) ? c : '_';
}
else
c = isalnum(c) ? c : '_';
{
// _<num> variables are reserved by the internal implementation,
// otherwise, make sure the name is a valid identifier.
if (i == 0 || (str[0] == '_' && i == 1))
c = isalpha(c) ? c : '_';
else
c = isalnum(c) ? c : '_';
}
}
return str;
}
@ -899,7 +913,7 @@ void Compiler::set_name(uint32_t id, const std::string &name)
if (name[0] == '_' && name.size() >= 2 && isdigit(name[1]))
return;
str = ensure_valid_identifier(name);
str = ensure_valid_identifier(name, false);
}
const SPIRType &Compiler::get_type(uint32_t id) const
@ -960,10 +974,10 @@ void Compiler::set_member_name(uint32_t id, uint32_t index, const std::string &n
return;
// Reserved for unnamed members.
if (name[0] == '_' && name.size() >= 2 && isdigit(name[1]))
if (name[0] == '_' && name.size() >= 3 && name[1] == 'm' && isdigit(name[2]))
return;
str = ensure_valid_identifier(name);
str = ensure_valid_identifier(name, true);
}
const std::string &Compiler::get_member_name(uint32_t id, uint32_t index) const

View File

@ -1447,16 +1447,6 @@ void CompilerGLSL::emit_flattened_io_block(const SPIRVariable &var, const char *
if (!type.array.empty())
SPIRV_CROSS_THROW("Array of varying structs cannot be flattened to legacy-compatible varyings.");
// Block names should never alias.
auto block_name = to_name(type.self, false);
// Shaders never use the block by interface name, so we don't
// have to track this other than updating name caches.
if (resource_names.find(block_name) != end(resource_names))
block_name = get_fallback_name(type.self);
else
resource_names.insert(block_name);
auto old_flags = meta[type.self].decoration.decoration_flags;
// Emit the members as if they are part of a block to get all qualifiers.
meta[type.self].decoration.decoration_flags |= 1ull << DecorationBlock;
@ -1474,7 +1464,8 @@ void CompilerGLSL::emit_flattened_io_block(const SPIRVariable &var, const char *
// Replace member name while emitting it so it encodes both struct name and member name.
// Sanitize underscores because joining the two identifiers might create more than 1 underscore in a row,
// which is not allowed.
auto member_name = get_member_name(type.self, i);
auto backup_name = get_member_name(type.self, i);
auto member_name = to_member_name(type, i);
set_member_name(type.self, i, sanitize_underscores(join(to_name(type.self), "_", member_name)));
emit_struct_member(type, member, i, qual);
// Restore member name.

View File

@ -1094,9 +1094,6 @@ void CompilerHLSL::emit_buffer_block(const SPIRVariable &var)
}
else
{
// Block names should never alias.
auto block_name = to_name(type.self, false);
if (type.array.empty())
{
if (buffer_is_packing_standard(type, BufferPackingHLSLCbufferPackOffset))
@ -1104,29 +1101,24 @@ void CompilerHLSL::emit_buffer_block(const SPIRVariable &var)
else
SPIRV_CROSS_THROW("cbuffer cannot be expressed with either HLSL packing layout or packoffset.");
// Shaders never use the block by interface name, so we don't
// have to track this other than updating name caches.
if (resource_names.find(block_name) != end(resource_names))
block_name = get_fallback_name(type.self);
else
resource_names.insert(block_name);
// Flatten the top-level struct so we can use packoffset,
// this restriction is similar to GLSL where layout(offset) is not possible on sub-structs.
flattened_structs.insert(var.self);
type.member_name_cache.clear();
statement("cbuffer ", block_name, to_resource_binding(var));
add_resource_name(var.self);
statement("cbuffer ", to_name(var.self), to_resource_binding(var));
begin_scope();
uint32_t i = 0;
for (auto &member : type.member_types)
{
add_member_name(type, i);
auto member_name = get_member_name(type.self, i);
set_member_name(type.self, i, sanitize_underscores(join(block_name, "_", member_name)));
auto backup_name = get_member_name(type.self, i);
auto member_name = to_member_name(type, i);
set_member_name(type.self, i, sanitize_underscores(join(to_name(type.self), "_", member_name)));
emit_struct_member(type, member, i, "");
set_member_name(type.self, i, member_name);
set_member_name(type.self, i, backup_name);
i++;
}