[Mesa-dev] [PATCH 07/19] glsl/types: add new subroutine type (v2)

Dave Airlie airlied at gmail.com
Sun May 31 18:34:51 PDT 2015


From: Dave Airlie <airlied at redhat.com>

This type will be used to store the name of subroutine types

as in subroutine void myfunc(void);
will store myfunc into a subroutine type.

This is required to the parser can identify a subroutine
type in a uniform decleration as a valid type, and also for
looking up the type later.

Also add contains_subroutine method.

v2: handle subroutine to int comparisons, needed
for lowering pass.

Signed-off-by: Dave Airlie <airlied at redhat.com>
---
 src/glsl/glsl_types.cpp                | 63 ++++++++++++++++++++++++++++++++++
 src/glsl/glsl_types.h                  | 19 ++++++++++
 src/glsl/ir.cpp                        |  2 +-
 src/glsl/ir_clone.cpp                  |  1 +
 src/glsl/ir_validate.cpp               |  6 ++--
 src/glsl/link_uniform_initializers.cpp |  1 +
 6 files changed, 89 insertions(+), 3 deletions(-)

diff --git a/src/glsl/glsl_types.cpp b/src/glsl/glsl_types.cpp
index f675e90..f4e9ef0 100644
--- a/src/glsl/glsl_types.cpp
+++ b/src/glsl/glsl_types.cpp
@@ -32,6 +32,7 @@ mtx_t glsl_type::mutex = _MTX_INITIALIZER_NP;
 hash_table *glsl_type::array_types = NULL;
 hash_table *glsl_type::record_types = NULL;
 hash_table *glsl_type::interface_types = NULL;
+hash_table *glsl_type::subroutine_types = NULL;
 void *glsl_type::mem_ctx = NULL;
 
 void
@@ -159,6 +160,22 @@ glsl_type::glsl_type(const glsl_struct_field *fields, unsigned num_fields,
    mtx_unlock(&glsl_type::mutex);
 }
 
+glsl_type::glsl_type(const char *subroutine_name) :
+   gl_type(0),
+   base_type(GLSL_TYPE_SUBROUTINE),
+   sampler_dimensionality(0), sampler_shadow(0), sampler_array(0),
+   sampler_type(0), interface_packing(0),
+   vector_elements(0), matrix_columns(0),
+   length(0)
+{
+   mtx_lock(&glsl_type::mutex);
+
+   init_ralloc_type_ctx();
+   assert(subroutine_name != NULL);
+   this->name = ralloc_strdup(this->mem_ctx, subroutine_name);
+   this->vector_elements = 1;
+   mtx_unlock(&glsl_type::mutex);
+}
 
 bool
 glsl_type::contains_sampler() const
@@ -229,6 +246,22 @@ glsl_type::contains_opaque() const {
    }
 }
 
+bool
+glsl_type::contains_subroutine() const
+{
+   if (this->is_array()) {
+      return this->fields.array->contains_subroutine();
+   } else if (this->is_record()) {
+      for (unsigned int i = 0; i < this->length; i++) {
+	 if (this->fields.structure[i].type->contains_subroutine())
+	    return true;
+      }
+      return false;
+   } else {
+      return this->is_subroutine();
+   }
+}
+
 gl_texture_index
 glsl_type::sampler_index() const
 {
@@ -826,6 +859,34 @@ glsl_type::get_interface_instance(const glsl_struct_field *fields,
    return t;
 }
 
+const glsl_type *
+glsl_type::get_subroutine_instance(const char *subroutine_name)
+{
+   const glsl_type key(subroutine_name);
+
+   mtx_lock(&glsl_type::mutex);
+
+   if (subroutine_types == NULL) {
+      subroutine_types = hash_table_ctor(64, record_key_hash, record_key_compare);
+   }
+
+   const glsl_type *t = (glsl_type *) hash_table_find(subroutine_types, & key);
+   if (t == NULL) {
+      mtx_unlock(&glsl_type::mutex);
+      t = new glsl_type(subroutine_name);
+      mtx_lock(&glsl_type::mutex);
+
+      hash_table_insert(subroutine_types, (void *) t, t);
+   }
+
+   assert(t->base_type == GLSL_TYPE_SUBROUTINE);
+   assert(strcmp(t->name, subroutine_name) == 0);
+
+   mtx_unlock(&glsl_type::mutex);
+
+   return t;
+}
+
 
 const glsl_type *
 glsl_type::get_mul_type(const glsl_type *type_a, const glsl_type *type_b)
@@ -958,6 +1019,7 @@ glsl_type::component_slots() const
    case GLSL_TYPE_SAMPLER:
    case GLSL_TYPE_ATOMIC_UINT:
    case GLSL_TYPE_VOID:
+   case GLSL_TYPE_SUBROUTINE:
    case GLSL_TYPE_ERROR:
       break;
    }
@@ -1330,6 +1392,7 @@ glsl_type::count_attribute_slots() const
    case GLSL_TYPE_IMAGE:
    case GLSL_TYPE_ATOMIC_UINT:
    case GLSL_TYPE_VOID:
+   case GLSL_TYPE_SUBROUTINE:
    case GLSL_TYPE_ERROR:
       break;
    }
diff --git a/src/glsl/glsl_types.h b/src/glsl/glsl_types.h
index f54a939..0f4dc80 100644
--- a/src/glsl/glsl_types.h
+++ b/src/glsl/glsl_types.h
@@ -59,6 +59,7 @@ enum glsl_base_type {
    GLSL_TYPE_INTERFACE,
    GLSL_TYPE_ARRAY,
    GLSL_TYPE_VOID,
+   GLSL_TYPE_SUBROUTINE,
    GLSL_TYPE_ERROR
 };
 
@@ -264,6 +265,11 @@ struct glsl_type {
 						  const char *block_name);
 
    /**
+    * Get the instance of an subroutine type
+    */
+   static const glsl_type *get_subroutine_instance(const char *subroutine_name);
+
+   /**
     * Get the type resulting from a multiplication of \p type_a * \p type_b
     */
    static const glsl_type *get_mul_type(const glsl_type *type_a,
@@ -514,6 +520,13 @@ struct glsl_type {
    /**
     * Query if a type is unnamed/anonymous (named by the parser)
     */
+
+   bool is_subroutine() const
+   {
+      return base_type == GLSL_TYPE_SUBROUTINE;
+   }
+   bool contains_subroutine() const;
+
    bool is_anonymous() const
    {
       return !strncmp(name, "#anon", 5);
@@ -679,6 +692,9 @@ private:
    /** Constructor for array types */
    glsl_type(const glsl_type *array, unsigned length);
 
+   /** Constructor for subroutine types */
+   glsl_type(const char *name);
+
    /** Hash table containing the known array types. */
    static struct hash_table *array_types;
 
@@ -688,6 +704,9 @@ private:
    /** Hash table containing the known interface types. */
    static struct hash_table *interface_types;
 
+   /** Hash table containing the known subroutine types. */
+   static struct hash_table *subroutine_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.cpp b/src/glsl/ir.cpp
index dbd064f..55d1877 100644
--- a/src/glsl/ir.cpp
+++ b/src/glsl/ir.cpp
@@ -411,7 +411,7 @@ ir_expression::ir_expression(int op, ir_rvalue *op0, ir_rvalue *op1)
    case ir_binop_gequal:
    case ir_binop_less:
    case ir_binop_greater:
-      assert(op0->type == op1->type);
+      assert(op0->type->is_subroutine() || op0->type == op1->type);
       this->type = glsl_type::get_instance(GLSL_TYPE_BOOL,
 					   op0->type->vector_elements, 1);
       break;
diff --git a/src/glsl/ir_clone.cpp b/src/glsl/ir_clone.cpp
index 914e0e4..49834ff 100644
--- a/src/glsl/ir_clone.cpp
+++ b/src/glsl/ir_clone.cpp
@@ -362,6 +362,7 @@ ir_constant::clone(void *mem_ctx, struct hash_table *ht) const
    case GLSL_TYPE_ATOMIC_UINT:
    case GLSL_TYPE_VOID:
    case GLSL_TYPE_ERROR:
+   case GLSL_TYPE_SUBROUTINE:
    case GLSL_TYPE_INTERFACE:
       assert(!"Should not get here.");
       break;
diff --git a/src/glsl/ir_validate.cpp b/src/glsl/ir_validate.cpp
index cfe0df3..ec288d4 100644
--- a/src/glsl/ir_validate.cpp
+++ b/src/glsl/ir_validate.cpp
@@ -494,9 +494,11 @@ ir_validate::visit_leave(ir_expression *ir)
        * vector type of the same size.
        */
       assert(ir->type->base_type == GLSL_TYPE_BOOL);
-      assert(ir->operands[0]->type == ir->operands[1]->type);
+      assert(ir->operands[0]->type->is_subroutine()
+	     || ir->operands[0]->type == ir->operands[1]->type);
       assert(ir->operands[0]->type->is_vector()
-	     || ir->operands[0]->type->is_scalar());
+	     || ir->operands[0]->type->is_scalar()
+	     || ir->operands[0]->type->is_subroutine());
       assert(ir->operands[0]->type->vector_elements
 	     == ir->type->vector_elements);
       break;
diff --git a/src/glsl/link_uniform_initializers.cpp b/src/glsl/link_uniform_initializers.cpp
index 6907384..3d232a8 100644
--- a/src/glsl/link_uniform_initializers.cpp
+++ b/src/glsl/link_uniform_initializers.cpp
@@ -89,6 +89,7 @@ copy_constant_to_storage(union gl_constant_value *storage,
       case GLSL_TYPE_ATOMIC_UINT:
       case GLSL_TYPE_INTERFACE:
       case GLSL_TYPE_VOID:
+      case GLSL_TYPE_SUBROUTINE:
       case GLSL_TYPE_ERROR:
 	 /* All other types should have already been filtered by other
 	  * paths in the caller.
-- 
2.1.0



More information about the mesa-dev mailing list