This makes sure that user is still able to query properties about variables that have gotten packed by lower_packed_varyings pass.
Fixes following OpenGL ES 3.1 test: ES31-CTS.program_interface_query.separate-programs-vertex v2: fix 'name included in packed list' check (Ilia Mirkin) Signed-off-by: Tapani Pälli <tapani.pa...@intel.com> --- src/glsl/linker.cpp | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 70 insertions(+), 4 deletions(-) diff --git a/src/glsl/linker.cpp b/src/glsl/linker.cpp index 94f847e..d8afb26 100644 --- a/src/glsl/linker.cpp +++ b/src/glsl/linker.cpp @@ -3114,6 +3114,29 @@ add_program_resource(struct gl_shader_program *prog, GLenum type, return true; } +/* Function checks if a variable var is a packed varying and + * if given name is part of packed varying's list. + * + * If a variable is a packed varying, it has a name like + * 'packed:a,b,c' where a, b and c are separate variables. + */ +static bool +included_in_packed_varying(ir_variable *var, const char *name) +{ + if (strncmp(var->name, "packed:", 7) != 0) + return false; + + const char *name_in_list = strstr(var->name, name); + const char *head = name_in_list - 1; + const char *tail = name_in_list + strlen(name); + + if (name_in_list && + (*head == ':' || *head == ',') && + (*tail == '\0' || *tail == ',')) + return true; + return false; +} + /** * Function builds a stage reference bitmask from variable name. */ @@ -3141,6 +3164,11 @@ build_stageref(struct gl_shader_program *shProg, const char *name, if (var) { unsigned baselen = strlen(var->name); + if (included_in_packed_varying(var, name)) { + stages |= (1 << i); + break; + } + /* Type needs to match if specified, otherwise we might * pick a variable with same name but different interface. */ @@ -3166,9 +3194,9 @@ build_stageref(struct gl_shader_program *shProg, const char *name, static bool add_interface_variables(struct gl_shader_program *shProg, - struct gl_shader *sh, GLenum programInterface) + exec_list *ir, GLenum programInterface) { - foreach_in_list(ir_instruction, node, sh->ir) { + foreach_in_list(ir_instruction, node, ir) { ir_variable *var = node->as_variable(); uint8_t mask = 0; @@ -3203,6 +3231,12 @@ add_interface_variables(struct gl_shader_program *shProg, continue; }; + /* Skip packed varyings, packed varyings are handled separately + * by add_packed_varyings. + */ + if (strncmp(var->name, "packed:", 7) == 0) + continue; + if (!add_program_resource(shProg, programInterface, var, build_stageref(shProg, var->name, var->data.mode) | mask)) @@ -3211,6 +3245,33 @@ add_interface_variables(struct gl_shader_program *shProg, return true; } +static bool +add_packed_varyings(struct gl_shader_program *shProg, int stage) +{ + struct gl_shader *sh = shProg->_LinkedShaders[stage]; + GLenum iface; + + if (!sh || !sh->packed_varyings) + return true; + + foreach_in_list(ir_instruction, node, sh->packed_varyings) { + ir_variable *var = node->as_variable(); + if (var) { + switch (var->data.mode) { + case ir_var_shader_in: + iface = GL_PROGRAM_INPUT; + case ir_var_shader_out: + iface = GL_PROGRAM_OUTPUT; + } + if (!add_program_resource(shProg, iface, var, + build_stageref(shProg, var->name, + var->data.mode))) + return false; + } + } + return true; +} + /** * Builds up a list of program resources that point to existing * resource data. @@ -3243,12 +3304,17 @@ build_program_resource_list(struct gl_shader_program *shProg) if (input_stage == MESA_SHADER_STAGES && output_stage == 0) return; + if (!add_packed_varyings(shProg, input_stage)) + return; + if (!add_packed_varyings(shProg, output_stage)) + return; + /* Add inputs and outputs to the resource list. */ - if (!add_interface_variables(shProg, shProg->_LinkedShaders[input_stage], + if (!add_interface_variables(shProg, shProg->_LinkedShaders[input_stage]->ir, GL_PROGRAM_INPUT)) return; - if (!add_interface_variables(shProg, shProg->_LinkedShaders[output_stage], + if (!add_interface_variables(shProg, shProg->_LinkedShaders[output_stage]->ir, GL_PROGRAM_OUTPUT)) return; -- 2.4.3 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev