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

Chris Forbes chrisf at ijw.co.nz
Thu Jul 9 18:44:07 PDT 2015


7-12 inclusive are

Reviewed-by: Chris Forbes <chrisf at ijw.co.nz>

On Thu, Jul 9, 2015 at 7:17 PM, Dave Airlie <airlied at gmail.com> wrote:
> 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.
> v3: do subroutine to int with it's own IR
> operation to avoid hacking on asserts (Kayden)
>
> 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.h                          |  1 +
>  src/glsl/ir_builder.cpp                |  6 ++++
>  src/glsl/ir_builder.h                  |  1 +
>  src/glsl/ir_clone.cpp                  |  1 +
>  src/glsl/ir_validate.cpp               |  4 +++
>  src/glsl/link_uniform_initializers.cpp |  1 +
>  9 files changed, 98 insertions(+)
>
> diff --git a/src/glsl/glsl_types.cpp b/src/glsl/glsl_types.cpp
> index 281ff51..1e3ebb2 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;
>     }
> @@ -1331,6 +1393,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..38a5e2a 100644
> --- a/src/glsl/ir.cpp
> +++ b/src/glsl/ir.cpp
> @@ -260,6 +260,7 @@ ir_expression::ir_expression(int op, ir_rvalue *op0)
>     case ir_unop_bit_count:
>     case ir_unop_find_msb:
>     case ir_unop_find_lsb:
> +   case ir_unop_subroutine_to_int:
>        this->type = glsl_type::get_instance(GLSL_TYPE_INT,
>                                            op0->type->vector_elements, 1);
>        break;
> @@ -568,6 +569,7 @@ static const char *const operator_strs[] = {
>     "frexp_sig",
>     "frexp_exp",
>     "noise",
> +   "subroutine_to_int",
>     "interpolate_at_centroid",
>     "+",
>     "-",
> diff --git a/src/glsl/ir.h b/src/glsl/ir.h
> index f904555..092c96b 100644
> --- a/src/glsl/ir.h
> +++ b/src/glsl/ir.h
> @@ -1380,6 +1380,7 @@ enum ir_expression_operation {
>
>     ir_unop_noise,
>
> +   ir_unop_subroutine_to_int,
>     /**
>      * Interpolate fs input at centroid
>      *
> diff --git a/src/glsl/ir_builder.cpp b/src/glsl/ir_builder.cpp
> index e44b05c..cd03859 100644
> --- a/src/glsl/ir_builder.cpp
> +++ b/src/glsl/ir_builder.cpp
> @@ -338,6 +338,12 @@ sign(operand a)
>     return expr(ir_unop_sign, a);
>  }
>
> +ir_expression *
> +subr_to_int(operand a)
> +{
> +   return expr(ir_unop_subroutine_to_int, a);
> +}
> +
>  ir_expression*
>  equal(operand a, operand b)
>  {
> diff --git a/src/glsl/ir_builder.h b/src/glsl/ir_builder.h
> index 8702658..f76453f 100644
> --- a/src/glsl/ir_builder.h
> +++ b/src/glsl/ir_builder.h
> @@ -153,6 +153,7 @@ ir_expression *sqrt(operand a);
>  ir_expression *log(operand a);
>  ir_expression *sign(operand a);
>
> +ir_expression *subr_to_int(operand a);
>  ir_expression *equal(operand a, operand b);
>  ir_expression *nequal(operand a, operand b);
>  ir_expression *less(operand a, operand b);
> 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..49f4f70 100644
> --- a/src/glsl/ir_validate.cpp
> +++ b/src/glsl/ir_validate.cpp
> @@ -447,6 +447,10 @@ ir_validate::visit_leave(ir_expression *ir)
>               ir->operands[0]->type->base_type == GLSL_TYPE_DOUBLE);
>        assert(ir->type->base_type == GLSL_TYPE_INT);
>        break;
> +   case ir_unop_subroutine_to_int:
> +      assert(ir->operands[0]->type->base_type == GLSL_TYPE_SUBROUTINE);
> +      assert(ir->type->base_type == GLSL_TYPE_INT);
> +      break;
>     case ir_binop_add:
>     case ir_binop_sub:
>     case ir_binop_mul:
> diff --git a/src/glsl/link_uniform_initializers.cpp b/src/glsl/link_uniform_initializers.cpp
> index 204acfa..47d261c 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.4.3
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/mesa-dev


More information about the mesa-dev mailing list