Mesa (master): linker: Add a last_field parameter to various program_resource_visitor methods

Ian Romanick idr at kemper.freedesktop.org
Mon Aug 4 21:40:44 UTC 2014


Module: Mesa
Branch: master
Commit: 47c6fc5b04774737404b55b01cbab5c3baf1c183
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=47c6fc5b04774737404b55b01cbab5c3baf1c183

Author: Ian Romanick <ian.d.romanick at intel.com>
Date:   Wed Jul 16 15:37:10 2014 -0700

linker: Add a last_field parameter to various program_resource_visitor methods

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>
Reviewed-by: Matt Turner <mattst88 at gmail.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 0b1291d..ddd134a 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 7489536..8014a3d 100644
--- a/src/glsl/link_uniforms.cpp
+++ b/src/glsl/link_uniforms.cpp
@@ -63,7 +63,7 @@ program_resource_visitor::process(const glsl_type *type, const char *name)
           || type->without_array()->is_interface());
 
    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);
 }
 
@@ -108,7 +108,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) {
@@ -132,29 +132,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->without_array()->is_record()) {
       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.
     *
@@ -181,7 +182,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.
@@ -200,7 +202,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.
@@ -208,14 +211,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);
 }
@@ -508,7 +512,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->without_array()->is_record());
       assert(!type->without_array()->is_interface());
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




More information about the mesa-commit mailing list