[Mesa-dev] [PATCH v3] glsl: add packed varyings to program resource list
Tapani Pälli
tapani.palli at intel.com
Fri Sep 11 00:19:40 PDT 2015
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)
v3: iterate over instances of name using strtok_r (Ilia Mirkin)
Signed-off-by: Tapani Pälli <tapani.palli at intel.com>
---
src/glsl/linker.cpp | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 76 insertions(+), 4 deletions(-)
diff --git a/src/glsl/linker.cpp b/src/glsl/linker.cpp
index 94f847e..de499e2 100644
--- a/src/glsl/linker.cpp
+++ b/src/glsl/linker.cpp
@@ -3114,6 +3114,35 @@ 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;
+
+ char *list = strdup(var->name + 7);
+ assert(list);
+
+ bool found = false;
+ char *saveptr;
+ char *token = strtok_r(list, ",", &saveptr);
+ while (token) {
+ if (strcmp(token, name) == 0) {
+ found = true;
+ break;
+ }
+ token = strtok_r(NULL, ",", &saveptr);
+ }
+ free(list);
+ return found;
+}
+
/**
* Function builds a stage reference bitmask from variable name.
*/
@@ -3141,6 +3170,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 +3200,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 +3237,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 +3251,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 +3310,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
More information about the mesa-dev
mailing list