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. v3: do subroutine to int with it's own IR operation to avoid hacking on asserts (Kayden) 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.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@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev