GLSL: Support I/O flattening with arrays as final type.

This commit is contained in:
Hans-Kristian Arntzen 2020-07-06 09:18:30 +02:00
parent 2d43103a55
commit 2ac8f51b06
4 changed files with 57 additions and 2 deletions

View File

@ -0,0 +1,17 @@
#version 100
struct Foo
{
float a[4];
};
varying float foo_a[4];
void main()
{
gl_Position = vec4(1.0);
for (int _46 = 0; _46 < 4; foo_a[_46] = float(_46 + 2), _46++)
{
}
}

View File

@ -0,0 +1,18 @@
#version 100
struct Foo
{
float a[4];
};
varying float foo_a[4];
void main()
{
gl_Position = vec4(1.0);
for (int i = 0; i < 4; i++)
{
foo_a[i] = float(i + 2);
}
}

View File

@ -0,0 +1,15 @@
#version 450
struct Foo
{
float a[4];
};
layout(location = 0) out Foo foo;
void main()
{
gl_Position = vec4(1.0);
for (int i = 0; i < 4; i++)
foo.a[i] = float(i + 2);
}

View File

@ -2127,6 +2127,7 @@ const char *CompilerGLSL::to_storage_qualifiers_glsl(const SPIRVariable &var)
void CompilerGLSL::emit_flattened_io_block_member(const std::string &basename, const SPIRType &type, const char *qual,
const SmallVector<uint32_t> &indices)
{
uint32_t member_type_id = type.self;
const SPIRType *member_type = &type;
const SPIRType *parent_type = nullptr;
auto flattened_name = basename;
@ -2135,7 +2136,8 @@ void CompilerGLSL::emit_flattened_io_block_member(const std::string &basename, c
flattened_name += "_";
flattened_name += to_member_name(*member_type, index);
parent_type = member_type;
member_type = &get<SPIRType>(member_type->member_types[index]);
member_type_id = member_type->member_types[index];
member_type = &get<SPIRType>(member_type_id);
}
assert(member_type->basetype != SPIRType::Struct);
@ -2151,7 +2153,7 @@ void CompilerGLSL::emit_flattened_io_block_member(const std::string &basename, c
auto backup_name = get_member_name(parent_type->self, last_index);
auto member_name = to_member_name(*parent_type, last_index);
set_member_name(parent_type->self, last_index, flattened_name);
emit_struct_member(*parent_type, member_type->self, last_index, qual);
emit_struct_member(*parent_type, member_type_id, last_index, qual);
// Restore member name.
set_member_name(parent_type->self, last_index, member_name);
}
@ -2168,6 +2170,9 @@ void CompilerGLSL::emit_flattened_io_block_struct(const std::string &basename, c
assert(member_type->basetype == SPIRType::Struct);
if (!member_type->array.empty())
SPIRV_CROSS_THROW("Cannot flatten array of structs in I/O blocks.");
for (uint32_t i = 0; i < uint32_t(member_type->member_types.size()); i++)
{
sub_indices.back() = i;