From: Dave Airlie <airl...@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 <airl...@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 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev