On 09/11/2015 09:15 AM, Ilia Mirkin wrote:
On Fri, Sep 11, 2015 at 2:12 AM, Tapani Pälli <tapani.pa...@intel.com> wrote:
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 == ','))

So... in the case "ab,b" and you search for 'b', it'll find 'ab' and reject it.

Huh, this seems more complex that I thought .. almost a case for proper parser rather than a helper function.


+      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

Reply via email to