[Mesa-dev] [PATCH 11/23] glsl/types: add new subroutine type
Dave Airlie
airlied at gmail.com
Thu Apr 23 18:42:47 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.
Signed-off-by: Dave Airlie <airlied at redhat.com>
---
src/glsl/glsl_types.cpp | 63 ++++++++++++++++++++++++++++++++++
src/glsl/glsl_types.h | 19 ++++++++++
src/glsl/ir_clone.cpp | 1 +
src/glsl/link_uniform_initializers.cpp | 1 +
4 files changed, 84 insertions(+)
diff --git a/src/glsl/glsl_types.cpp b/src/glsl/glsl_types.cpp
index 9c9b7ef..37b5c62 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 d383dd5..078adaf 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
};
@@ -276,6 +277,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,
@@ -526,6 +532,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);
@@ -686,6 +699,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;
@@ -695,6 +711,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_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/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