[Mesa-dev] [PATCH 09/32] glsl: Add GLSL_TYPE_INTERFACE

Ian Romanick idr at freedesktop.org
Tue Jan 22 00:52:00 PST 2013


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

Interfaces are structurally identical to structures from the compiler's
point of view.  They have some additional restrictions, and generally
GPUs use different instructions to access them.  Using a different base
type should make this a bit easier.

v2: Add serveral missing GLSL_TYPE_INTERFACE cases in switch-statements.

Signed-off-by: Ian Romanick <ian.d.romanick at intel.com>
---
 src/glsl/ast_to_hir.cpp                        |  1 +
 src/glsl/glsl_types.cpp                        | 73 +++++++++++++++++++++++---
 src/glsl/glsl_types.h                          | 36 ++++++++++++-
 src/glsl/ir_clone.cpp                          |  1 +
 src/glsl/link_uniform_initializers.cpp         |  1 +
 src/glsl/tests/uniform_initializer_utils.cpp   |  3 ++
 src/mesa/drivers/dri/i965/brw_fs.cpp           |  1 +
 src/mesa/drivers/dri/i965/brw_fs_visitor.cpp   |  1 +
 src/mesa/drivers/dri/i965/brw_shader.cpp       |  1 +
 src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp |  1 +
 src/mesa/program/ir_to_mesa.cpp                |  2 +
 11 files changed, 112 insertions(+), 9 deletions(-)

diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp
index bce3488..575dd84 100644
--- a/src/glsl/ast_to_hir.cpp
+++ b/src/glsl/ast_to_hir.cpp
@@ -857,6 +857,7 @@ do_comparison(void *mem_ctx, int operation, ir_rvalue *op0, ir_rvalue *op1)
    case GLSL_TYPE_ERROR:
    case GLSL_TYPE_VOID:
    case GLSL_TYPE_SAMPLER:
+   case GLSL_TYPE_INTERFACE:
       /* I assume a comparison of a struct containing a sampler just
        * ignores the sampler present in the type.
        */
diff --git a/src/glsl/glsl_types.cpp b/src/glsl/glsl_types.cpp
index 46cc96e..0075550 100644
--- a/src/glsl/glsl_types.cpp
+++ b/src/glsl/glsl_types.cpp
@@ -34,6 +34,7 @@ extern "C" {
 
 hash_table *glsl_type::array_types = NULL;
 hash_table *glsl_type::record_types = NULL;
+hash_table *glsl_type::interface_types = NULL;
 void *glsl_type::mem_ctx = NULL;
 
 void
@@ -51,7 +52,7 @@ glsl_type::glsl_type(GLenum gl_type,
    gl_type(gl_type),
    base_type(base_type),
    sampler_dimensionality(0), sampler_shadow(0), sampler_array(0),
-   sampler_type(0),
+   sampler_type(0), interface_packing(0),
    vector_elements(vector_elements), matrix_columns(matrix_columns),
    length(0)
 {
@@ -69,7 +70,7 @@ glsl_type::glsl_type(GLenum gl_type,
    gl_type(gl_type),
    base_type(GLSL_TYPE_SAMPLER),
    sampler_dimensionality(dim), sampler_shadow(shadow),
-   sampler_array(array), sampler_type(type),
+   sampler_array(array), sampler_type(type), interface_packing(0),
    vector_elements(0), matrix_columns(0),
    length(0)
 {
@@ -82,7 +83,29 @@ glsl_type::glsl_type(const glsl_struct_field *fields, unsigned num_fields,
 		     const char *name) :
    base_type(GLSL_TYPE_STRUCT),
    sampler_dimensionality(0), sampler_shadow(0), sampler_array(0),
-   sampler_type(0),
+   sampler_type(0), interface_packing(0),
+   vector_elements(0), matrix_columns(0),
+   length(num_fields)
+{
+   unsigned int i;
+
+   init_ralloc_type_ctx();
+   this->name = ralloc_strdup(this->mem_ctx, name);
+   this->fields.structure = ralloc_array(this->mem_ctx,
+					 glsl_struct_field, length);
+   for (i = 0; i < length; i++) {
+      this->fields.structure[i].type = fields[i].type;
+      this->fields.structure[i].name = ralloc_strdup(this->fields.structure,
+						     fields[i].name);
+      this->fields.structure[i].row_major = fields[i].row_major;
+   }
+}
+
+glsl_type::glsl_type(const glsl_struct_field *fields, unsigned num_fields,
+		     enum glsl_interface_packing packing, const char *name) :
+   base_type(GLSL_TYPE_INTERFACE),
+   sampler_dimensionality(0), sampler_shadow(0), sampler_array(0),
+   sampler_type(0), interface_packing((unsigned) packing),
    vector_elements(0), matrix_columns(0),
    length(num_fields)
 {
@@ -430,7 +453,7 @@ _mesa_glsl_release_types(void)
 glsl_type::glsl_type(const glsl_type *array, unsigned length) :
    base_type(GLSL_TYPE_ARRAY),
    sampler_dimensionality(0), sampler_shadow(0), sampler_array(0),
-   sampler_type(0),
+   sampler_type(0), interface_packing(0),
    vector_elements(0), matrix_columns(0),
    name(NULL), length(length)
 {
@@ -562,12 +585,18 @@ glsl_type::record_key_compare(const void *a, const void *b)
    if (key1->length != key2->length)
       return 1;
 
+   if (key1->interface_packing != key2->interface_packing)
+      return 1;
+
    for (unsigned i = 0; i < key1->length; i++) {
       if (key1->fields.structure[i].type != key2->fields.structure[i].type)
 	 return 1;
       if (strcmp(key1->fields.structure[i].name,
 		 key2->fields.structure[i].name) != 0)
 	 return 1;
+      if (key1->fields.structure[i].row_major
+	  != key2->fields.structure[i].row_major)
+	 return 1;
    }
 
    return 0;
@@ -622,9 +651,37 @@ glsl_type::get_record_instance(const glsl_struct_field *fields,
 
 
 const glsl_type *
+glsl_type::get_interface_instance(const glsl_struct_field *fields,
+				  unsigned num_fields,
+				  enum glsl_interface_packing packing,
+				  const char *name)
+{
+   const glsl_type key(fields, num_fields, packing, name);
+
+   if (interface_types == NULL) {
+      interface_types = hash_table_ctor(64, record_key_hash, record_key_compare);
+   }
+
+   const glsl_type *t = (glsl_type *) hash_table_find(interface_types, & key);
+   if (t == NULL) {
+      t = new glsl_type(fields, num_fields, packing, name);
+
+      hash_table_insert(interface_types, (void *) t, t);
+   }
+
+   assert(t->base_type == GLSL_TYPE_INTERFACE);
+   assert(t->length == num_fields);
+   assert(strcmp(t->name, name) == 0);
+
+   return t;
+}
+
+
+const glsl_type *
 glsl_type::field_type(const char *name) const
 {
-   if (this->base_type != GLSL_TYPE_STRUCT)
+   if (this->base_type != GLSL_TYPE_STRUCT
+       && this->base_type != GLSL_TYPE_INTERFACE)
       return error_type;
 
    for (unsigned i = 0; i < this->length; i++) {
@@ -639,7 +696,8 @@ glsl_type::field_type(const char *name) const
 int
 glsl_type::field_index(const char *name) const
 {
-   if (this->base_type != GLSL_TYPE_STRUCT)
+   if (this->base_type != GLSL_TYPE_STRUCT
+       && this->base_type != GLSL_TYPE_INTERFACE)
       return -1;
 
    for (unsigned i = 0; i < this->length; i++) {
@@ -661,7 +719,8 @@ glsl_type::component_slots() const
    case GLSL_TYPE_BOOL:
       return this->components();
 
-   case GLSL_TYPE_STRUCT: {
+   case GLSL_TYPE_STRUCT:
+   case GLSL_TYPE_INTERFACE: {
       unsigned size = 0;
 
       for (unsigned i = 0; i < this->length; i++)
diff --git a/src/glsl/glsl_types.h b/src/glsl/glsl_types.h
index 24ad844..8588685 100644
--- a/src/glsl/glsl_types.h
+++ b/src/glsl/glsl_types.h
@@ -54,6 +54,7 @@ enum glsl_base_type {
    GLSL_TYPE_BOOL,
    GLSL_TYPE_SAMPLER,
    GLSL_TYPE_STRUCT,
+   GLSL_TYPE_INTERFACE,
    GLSL_TYPE_ARRAY,
    GLSL_TYPE_VOID,
    GLSL_TYPE_ERROR
@@ -69,6 +70,12 @@ enum glsl_sampler_dim {
    GLSL_SAMPLER_DIM_EXTERNAL
 };
 
+enum glsl_interface_packing {
+   GLSL_INTERFACE_PACKING_STD140,
+   GLSL_INTERFACE_PACKING_SHARED,
+   GLSL_INTERFACE_PACKING_PACKED
+};
+
 #ifdef __cplusplus
 #include "GL/gl.h"
 #include "ralloc.h"
@@ -84,6 +91,7 @@ struct glsl_type {
 				* only \c GLSL_TYPE_FLOAT, \c GLSL_TYPE_INT,
 				* and \c GLSL_TYPE_UINT are valid.
 				*/
+   unsigned interface_packing:2;
 
    /* Callers of this ralloc-based new need not call delete. It's
     * easier to just ralloc_free 'mem_ctx' (or any of its ancestors). */
@@ -130,8 +138,9 @@ struct glsl_type {
 
    /**
     * For \c GLSL_TYPE_ARRAY, this is the length of the array.  For
-    * \c GLSL_TYPE_STRUCT, it is the number of elements in the structure and
-    * the number of values pointed to by \c fields.structure (below).
+    * \c GLSL_TYPE_STRUCT or \c GLSL_TYPE_INTERFACE, it is the number of
+    * elements in the structure and the number of values pointed to by
+    * \c fields.structure (below).
     */
    unsigned length;
 
@@ -232,6 +241,14 @@ struct glsl_type {
 					       const char *name);
 
    /**
+    * Get the instance of an interface block type
+    */
+   static const glsl_type *get_interface_instance(const glsl_struct_field *fields,
+						  unsigned num_fields,
+						  enum glsl_interface_packing packing,
+						  const char *name);
+
+   /**
     * Query the total number of scalars that make up a scalar, vector or matrix
     */
    unsigned components() const
@@ -394,6 +411,14 @@ struct glsl_type {
    }
 
    /**
+    * Query whether or not a type is an interface
+    */
+   bool is_interface() const
+   {
+      return base_type == GLSL_TYPE_INTERFACE;
+   }
+
+   /**
     * Query whether or not a type is the void type singleton.
     */
    bool is_void() const
@@ -491,6 +516,10 @@ private:
    glsl_type(const glsl_struct_field *fields, unsigned num_fields,
 	     const char *name);
 
+   /** Constructor for interface types */
+   glsl_type(const glsl_struct_field *fields, unsigned num_fields,
+	     enum glsl_interface_packing packing, const char *name);
+
    /** Constructor for array types */
    glsl_type(const glsl_type *array, unsigned length);
 
@@ -500,6 +529,9 @@ private:
    /** Hash table containing the known record types. */
    static struct hash_table *record_types;
 
+   /** Hash table containing the known interface types. */
+   static struct hash_table *interface_types;
+
    static int record_key_compare(const void *a, const void *b);
    static unsigned record_key_hash(const void *key);
 
diff --git a/src/glsl/ir_clone.cpp b/src/glsl/ir_clone.cpp
index 9b7981b..3e22f2d 100644
--- a/src/glsl/ir_clone.cpp
+++ b/src/glsl/ir_clone.cpp
@@ -378,6 +378,7 @@ ir_constant::clone(void *mem_ctx, struct hash_table *ht) const
    case GLSL_TYPE_SAMPLER:
    case GLSL_TYPE_VOID:
    case GLSL_TYPE_ERROR:
+   case GLSL_TYPE_INTERFACE:
       assert(!"Should not get here.");
       break;
    }
diff --git a/src/glsl/link_uniform_initializers.cpp b/src/glsl/link_uniform_initializers.cpp
index 933df29..836a360 100644
--- a/src/glsl/link_uniform_initializers.cpp
+++ b/src/glsl/link_uniform_initializers.cpp
@@ -69,6 +69,7 @@ copy_constant_to_storage(union gl_constant_value *storage,
 	 break;
       case GLSL_TYPE_ARRAY:
       case GLSL_TYPE_STRUCT:
+      case GLSL_TYPE_INTERFACE:
       case GLSL_TYPE_VOID:
       case GLSL_TYPE_ERROR:
 	 /* All other types should have already been filtered by other
diff --git a/src/glsl/tests/uniform_initializer_utils.cpp b/src/glsl/tests/uniform_initializer_utils.cpp
index e7d274e..a04f5dd 100644
--- a/src/glsl/tests/uniform_initializer_utils.cpp
+++ b/src/glsl/tests/uniform_initializer_utils.cpp
@@ -96,6 +96,7 @@ generate_data_element(void *mem_ctx, const glsl_type *type,
       case GLSL_TYPE_ARRAY:
       case GLSL_TYPE_VOID:
       case GLSL_TYPE_ERROR:
+      case GLSL_TYPE_INTERFACE:
 	 ASSERT_TRUE(false);
 	 break;
       }
@@ -122,6 +123,7 @@ generate_data_element(void *mem_ctx, const glsl_type *type,
       case GLSL_TYPE_ARRAY:
       case GLSL_TYPE_VOID:
       case GLSL_TYPE_ERROR:
+      case GLSL_TYPE_INTERFACE:
 	 ASSERT_TRUE(false);
 	 break;
       }
@@ -219,6 +221,7 @@ verify_data(gl_constant_value *storage, unsigned storage_array_size,
 	 case GLSL_TYPE_ARRAY:
 	 case GLSL_TYPE_VOID:
 	 case GLSL_TYPE_ERROR:
+	 case GLSL_TYPE_INTERFACE:
 	    ASSERT_TRUE(false);
 	    break;
 	 }
diff --git a/src/mesa/drivers/dri/i965/brw_fs.cpp b/src/mesa/drivers/dri/i965/brw_fs.cpp
index 03b0630..8e57eb0 100644
--- a/src/mesa/drivers/dri/i965/brw_fs.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs.cpp
@@ -457,6 +457,7 @@ fs_visitor::type_size(const struct glsl_type *type)
       return 0;
    case GLSL_TYPE_VOID:
    case GLSL_TYPE_ERROR:
+   case GLSL_TYPE_INTERFACE:
       assert(!"not reached");
       break;
    }
diff --git a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
index 07df1a8..1186291 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
@@ -685,6 +685,7 @@ fs_visitor::emit_assignment_writes(fs_reg &l, fs_reg &r,
 
    case GLSL_TYPE_VOID:
    case GLSL_TYPE_ERROR:
+   case GLSL_TYPE_INTERFACE:
       assert(!"not reached");
       break;
    }
diff --git a/src/mesa/drivers/dri/i965/brw_shader.cpp b/src/mesa/drivers/dri/i965/brw_shader.cpp
index 49e24d2..039c26c 100644
--- a/src/mesa/drivers/dri/i965/brw_shader.cpp
+++ b/src/mesa/drivers/dri/i965/brw_shader.cpp
@@ -255,6 +255,7 @@ brw_type_for_base_type(const struct glsl_type *type)
       return BRW_REGISTER_TYPE_UD;
    case GLSL_TYPE_VOID:
    case GLSL_TYPE_ERROR:
+   case GLSL_TYPE_INTERFACE:
       assert(!"not reached");
       break;
    }
diff --git a/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp b/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp
index 7eda0fb..8aa67c2 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp
+++ b/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp
@@ -396,6 +396,7 @@ type_size(const struct glsl_type *type)
       return 1;
    case GLSL_TYPE_VOID:
    case GLSL_TYPE_ERROR:
+   case GLSL_TYPE_INTERFACE:
       assert(0);
       break;
    }
diff --git a/src/mesa/program/ir_to_mesa.cpp b/src/mesa/program/ir_to_mesa.cpp
index 18527e6..637ab07 100644
--- a/src/mesa/program/ir_to_mesa.cpp
+++ b/src/mesa/program/ir_to_mesa.cpp
@@ -625,6 +625,7 @@ type_size(const struct glsl_type *type)
       return 1;
    case GLSL_TYPE_VOID:
    case GLSL_TYPE_ERROR:
+   case GLSL_TYPE_INTERFACE:
       assert(!"Invalid type in type_size");
       break;
    }
@@ -2529,6 +2530,7 @@ _mesa_associate_uniform_storage(struct gl_context *ctx,
          case GLSL_TYPE_VOID:
          case GLSL_TYPE_STRUCT:
          case GLSL_TYPE_ERROR:
+         case GLSL_TYPE_INTERFACE:
 	    assert(!"Should not get here.");
 	    break;
 	 }
-- 
1.7.11.7



More information about the mesa-dev mailing list