diff options
author | Kristian Høgsberg Kristensen <[email protected]> | 2016-04-11 14:28:18 -0700 |
---|---|---|
committer | Kristian Høgsberg Kristensen <[email protected]> | 2016-04-12 14:38:26 -0700 |
commit | 1af0f0151c6ae7d8634a642ad7a13713f395ca4d (patch) | |
tree | 0e0a763047626ee3d89068be2846d1e3bd2e2c49 /src/compiler/glsl | |
parent | 778fd46aa4df08f2dd5d5a9162e6dce062cc1cb6 (diff) |
glsl/linker: Recurse on struct fields when adding shader variables
ARB_program_interface_query requires that we add struct fields
recursively down to basic types.
Fixes 52 struct test cases in dEQP-GLES31.functional.program_interface_query.*
Signed-off-by: Kristian Høgsberg Kristensen <[email protected]>
Reviewed-by: Kenneth Graunke <[email protected]>
Diffstat (limited to 'src/compiler/glsl')
-rw-r--r-- | src/compiler/glsl/linker.cpp | 51 |
1 files changed, 45 insertions, 6 deletions
diff --git a/src/compiler/glsl/linker.cpp b/src/compiler/glsl/linker.cpp index c1bc6994f48..0773d4244b4 100644 --- a/src/compiler/glsl/linker.cpp +++ b/src/compiler/glsl/linker.cpp @@ -3575,13 +3575,52 @@ add_shader_variable(struct gl_shader_program *shProg, unsigned stage_mask, const char *name, const glsl_type *type, bool use_implicit_location, int location) { - gl_shader_variable *sha_v = - create_shader_variable(shProg, var, name, type, - use_implicit_location, location); - if (!sha_v) - return false; + const bool vertex_input_slots = + programInterface == GL_PROGRAM_INPUT && + stage_mask == MESA_SHADER_VERTEX; + + switch (type->base_type) { + case GLSL_TYPE_STRUCT: { + /* From the ARB_program_interface_query specification: + * + * "For an active variable declared as a structure, a separate entry + * will be generated for each active structure member. The name of + * each entry is formed by concatenating the name of the structure, + * the "." character, and the name of the structure member. If a + * structure member to enumerate is itself a structure or array, these + * enumeration rules are applied recursively." + */ + unsigned field_location = location; + for (unsigned i = 0; i < type->length; i++) { + const struct glsl_struct_field *field = &type->fields.structure[i]; + char *field_name = ralloc_asprintf(shProg, "%s.%s", name, field->name); + if (!add_shader_variable(shProg, stage_mask, programInterface, + var, field_name, field->type, + use_implicit_location, field_location)) + return false; + + field_location += + field->type->count_attribute_slots(vertex_input_slots); + } + return true; + } + + default: { + /* From the ARB_program_interface_query specification: + * + * "For an active variable declared as a single instance of a basic + * type, a single entry will be generated, using the variable name + * from the shader source." + */ + gl_shader_variable *sha_v = + create_shader_variable(shProg, var, name, type, + use_implicit_location, location); + if (!sha_v) + return false; - return add_program_resource(shProg, programInterface, sha_v, stage_mask); + return add_program_resource(shProg, programInterface, sha_v, stage_mask); + } + } } static bool |