[Mesa-dev] [PATCH 08/16] linker: Add a last_field parameter to various program_resource_visitor methods

Ian Romanick idr at freedesktop.org
Mon Jul 21 14:04:24 PDT 2014


From: Ian Romanick <ian.d.romanick at intel.com>

I also considered renaming visit_field(const glsl_struct_field *) to
entry_record and adding an exit_record method.  This would be more
similar to the hierarchical visitor.

Signed-off-by: Ian Romanick <ian.d.romanick at intel.com>
---
 src/glsl/link_uniform_blocks.cpp |  3 ++-
 src/glsl/link_uniforms.cpp       | 31 ++++++++++++++++++-------------
 src/glsl/linker.h                | 12 ++++++++++--
 3 files changed, 30 insertions(+), 16 deletions(-)

diff --git a/src/glsl/link_uniform_blocks.cpp b/src/glsl/link_uniform_blocks.cpp
index fef3626..d1c7da4 100644
--- a/src/glsl/link_uniform_blocks.cpp
+++ b/src/glsl/link_uniform_blocks.cpp
@@ -68,7 +68,8 @@ private:
    }
 
    virtual void visit_field(const glsl_type *type, const char *name,
-                            bool row_major, const glsl_type *record_type)
+                            bool row_major, const glsl_type *record_type,
+                            bool last_field)
    {
       assert(this->index < this->num_variables);
 
diff --git a/src/glsl/link_uniforms.cpp b/src/glsl/link_uniforms.cpp
index bbfd326..6dd8de4 100644
--- a/src/glsl/link_uniforms.cpp
+++ b/src/glsl/link_uniforms.cpp
@@ -62,7 +62,7 @@ program_resource_visitor::process(const glsl_type *type, const char *name)
    assert(type->is_record_or_array_of() || type->is_interface_or_array_of());
 
    char *name_copy = ralloc_strdup(NULL, name);
-   recursion(type, &name_copy, strlen(name), false, NULL);
+   recursion(type, &name_copy, strlen(name), false, NULL, false);
    ralloc_free(name_copy);
 }
 
@@ -107,7 +107,7 @@ program_resource_visitor::process(ir_variable *var)
           * lowering is only applied to non-uniform interface blocks, so we
           * can safely pass false for row_major.
           */
-         recursion(var->type, &name, new_length, false, NULL);
+         recursion(var->type, &name, new_length, false, NULL, false);
       }
       ralloc_free(name);
    } else if (var->data.from_named_ifc_block_nonarray) {
@@ -131,29 +131,30 @@ program_resource_visitor::process(ir_variable *var)
        * is only applied to non-uniform interface blocks, so we can safely
        * pass false for row_major.
        */
-      recursion(var->type, &name, strlen(name), false, NULL);
+      recursion(var->type, &name, strlen(name), false, NULL, false);
       ralloc_free(name);
    } else if (t->is_record_or_array_of()) {
       char *name = ralloc_strdup(NULL, var->name);
-      recursion(var->type, &name, strlen(name), false, NULL);
+      recursion(var->type, &name, strlen(name), false, NULL, false);
       ralloc_free(name);
    } else if (t->is_interface()) {
       char *name = ralloc_strdup(NULL, var->type->name);
-      recursion(var->type, &name, strlen(name), false, NULL);
+      recursion(var->type, &name, strlen(name), false, NULL, false);
       ralloc_free(name);
    } else if (t->is_array() && t->fields.array->is_interface()) {
       char *name = ralloc_strdup(NULL, var->type->fields.array->name);
-      recursion(var->type, &name, strlen(name), false, NULL);
+      recursion(var->type, &name, strlen(name), false, NULL, false);
       ralloc_free(name);
    } else {
-      this->visit_field(t, var->name, false, NULL);
+      this->visit_field(t, var->name, false, NULL, false);
    }
 }
 
 void
 program_resource_visitor::recursion(const glsl_type *t, char **name,
                                     size_t name_length, bool row_major,
-                                    const glsl_type *record_type)
+                                    const glsl_type *record_type,
+                                    bool last_field)
 {
    /* Records need to have each field processed individually.
     *
@@ -180,7 +181,8 @@ program_resource_visitor::recursion(const glsl_type *t, char **name,
          }
 
          recursion(t->fields.structure[i].type, name, new_length,
-                   t->fields.structure[i].row_major, record_type);
+                   t->fields.structure[i].row_major, record_type,
+                   (i + 1) == t->length);
 
          /* Only the first leaf-field of the record gets called with the
           * record type pointer.
@@ -199,7 +201,8 @@ program_resource_visitor::recursion(const glsl_type *t, char **name,
 	 ralloc_asprintf_rewrite_tail(name, &new_length, "[%u]", i);
 
          recursion(t->fields.array, name, new_length, row_major,
-                   record_type);
+                   record_type,
+                   (i + 1) == t->length);
 
          /* Only the first leaf-field of the record gets called with the
           * record type pointer.
@@ -207,14 +210,15 @@ program_resource_visitor::recursion(const glsl_type *t, char **name,
          record_type = NULL;
       }
    } else {
-      this->visit_field(t, *name, row_major, record_type);
+      this->visit_field(t, *name, row_major, record_type, last_field);
    }
 }
 
 void
 program_resource_visitor::visit_field(const glsl_type *type, const char *name,
                                       bool row_major,
-                                      const glsl_type *)
+                                      const glsl_type *,
+                                      bool /* last_field */)
 {
    visit_field(type, name, row_major);
 }
@@ -507,7 +511,8 @@ private:
    }
 
    virtual void visit_field(const glsl_type *type, const char *name,
-                            bool row_major, const glsl_type *record_type)
+                            bool row_major, const glsl_type *record_type,
+                            bool /* last_field */)
    {
       assert(!type->is_record_or_array_of());
       assert(!type->is_interface_or_array_of());
diff --git a/src/glsl/linker.h b/src/glsl/linker.h
index 130915d..8851da6 100644
--- a/src/glsl/linker.h
+++ b/src/glsl/linker.h
@@ -138,11 +138,15 @@ protected:
     * \param name  Fully qualified name of the field.
     * \param row_major  For a matrix type, is it stored row-major.
     * \param record_type  Type of the record containing the field.
+    * \param last_field   Set if \c name is the last field of the structure
+    *                     containing it.  This will always be false for items
+    *                     not contained in a structure or interface block.
     *
     * The default implementation just calls the other \c visit_field method.
     */
    virtual void visit_field(const glsl_type *type, const char *name,
-                            bool row_major, const glsl_type *record_type);
+                            bool row_major, const glsl_type *record_type,
+                            bool last_field);
 
    /**
     * Method invoked for each leaf of the variable
@@ -168,9 +172,13 @@ private:
    /**
     * \param name_length  Length of the current name \b not including the
     *                     terminating \c NUL character.
+    * \param last_field   Set if \c name is the last field of the structure
+    *                     containing it.  This will always be false for items
+    *                     not contained in a structure or interface block.
     */
    void recursion(const glsl_type *t, char **name, size_t name_length,
-                  bool row_major, const glsl_type *record_type);
+                  bool row_major, const glsl_type *record_type,
+                  bool last_field);
 };
 
 void
-- 
1.8.1.4



More information about the mesa-dev mailing list