[Mesa-dev] [PATCH 07/19] glsl/types: add new subroutine type (v2)
Kenneth Graunke
kenneth at whitecape.org
Sun May 31 20:35:57 PDT 2015
On Monday, June 01, 2015 11:34:51 AM Dave Airlie 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.
>
> 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);
As is, this allows a lot of things that you probably don't want.
For example, (subroutine != float), and (subroutine < sampler).
While it allows (subroutine == int), it doesn't appear to allow
(int == subroutine), which is a bit odd.
If we're going to go this route, I'd be in favor of specifying /exactly/
what's allowed.
Alternatively...another approach would be to create an
ir_unop_subroutine_to_int expression opcode that "unwraps" a subroutine,
producing an integer that can be compared as normal. I think that could
be a lot cleaner than munging equality rules. Thoughts?
> 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.
>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: This is a digitally signed message part.
URL: <http://lists.freedesktop.org/archives/mesa-dev/attachments/20150531/a639d618/attachment.sig>
More information about the mesa-dev
mailing list