summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Romanick <ian.d.romanick@intel.com>2010-03-30 16:58:19 -0700
committerIan Romanick <ian.d.romanick@intel.com>2010-03-30 16:58:19 -0700
commit548a1b5ab7304037a7cac8e6d647fb6b5ccbaf5d (patch)
tree270c86847c0cd76bbd4a765eb5f0f219e9e49177
parent066304679cdd8bad6bca7fb815087559cda75aaf (diff)
Implement array type handling
Since all glsl_type objects are flyweights, support is added to track all known array types. This accounts for most of the changes.
-rw-r--r--glsl_types.cpp49
-rw-r--r--glsl_types.h32
2 files changed, 81 insertions, 0 deletions
diff --git a/glsl_types.cpp b/glsl_types.cpp
index df9667f8dc..8d11196e93 100644
--- a/glsl_types.cpp
+++ b/glsl_types.cpp
@@ -26,8 +26,11 @@
#include "glsl_parser_extras.h"
#include "glsl_types.h"
#include "builtin_types.h"
+#include "hash_table.h"
+hash_table *glsl_type::array_types = NULL;
+
static void
add_types_to_symbol_table(glsl_symbol_table *symtab,
const struct glsl_type *types,
@@ -542,3 +545,49 @@ glsl_type::get_instance(unsigned base_type, unsigned rows, unsigned columns)
assert(!"Should not get here.");
return error_type;
}
+
+
+int
+glsl_type::array_key_compare(const void *a, const void *b)
+{
+ const array_hash_key *const key1 = (array_hash_key *) a;
+ const array_hash_key *const key2 = (array_hash_key *) b;
+
+ return ((key1->type == key2->type) && (key1->size == key2->size)) ? 0 : 1;
+}
+
+
+unsigned
+glsl_type::array_key_hash(const void *a)
+{
+ char buf[sizeof(array_hash_key) + 1];
+
+ memcpy(buf, a, sizeof(array_hash_key));
+ buf[sizeof(array_hash_key)] = '\0';
+
+ return hash_table_string_hash(buf);
+}
+
+
+const glsl_type *
+glsl_type::get_array_instance(const glsl_type *base, unsigned array_size)
+{
+ array_hash_key key = { base, array_size };
+
+ if (array_types == NULL) {
+ array_types = hash_table_ctor(64, array_key_hash, array_key_compare);
+ }
+
+ const glsl_type *t = (glsl_type *) hash_table_find(array_types, & key);
+ if (t == NULL) {
+ t = new glsl_type(base, array_size);
+
+ hash_table_insert(array_types, (void *) t, & key);
+ }
+
+ assert(t->base_type == GLSL_TYPE_ARRAY);
+ assert(t->length == array_size);
+ assert(t->fields.array == base);
+
+ return t;
+}
diff --git a/glsl_types.h b/glsl_types.h
index bb2d6f697b..6f3b512f28 100644
--- a/glsl_types.h
+++ b/glsl_types.h
@@ -170,6 +170,12 @@ struct glsl_type {
unsigned columns);
/**
+ * Get the instance of an array type
+ */
+ static const glsl_type *get_array_instance(const glsl_type *base,
+ unsigned elements);
+
+ /**
* Query the total number of scalars that make up a scalar, vector or matrix
*/
unsigned components() const
@@ -301,6 +307,20 @@ struct glsl_type {
private:
/**
+ * Constructor for array types
+ */
+ glsl_type(const glsl_type *array, unsigned length) :
+ base_type(GLSL_TYPE_ARRAY),
+ sampler_dimensionality(0), sampler_shadow(0), sampler_array(0),
+ sampler_type(0),
+ vector_elements(0), matrix_columns(0),
+ name(NULL), length(length)
+ {
+ this->fields.array = array;
+ this->name = "<array>";
+ }
+
+ /**
* \name Pointers to various private type singletons
*/
/*@{*/
@@ -314,6 +334,18 @@ private:
static const glsl_type *const mat4x3_type;
static const glsl_type *const mat4_type;
/*@}*/
+
+ /** Hash table containing the known array types. */
+ static struct hash_table *array_types;
+
+ /** Structure defining the key type used for array_types hash table. */
+ struct array_hash_key {
+ const glsl_type *type;
+ unsigned size;
+ };
+
+ static int array_key_compare(const void *a, const void *b);
+ static unsigned array_key_hash(const void *key);
};
struct glsl_struct_field {