glsl/types: Add support for function types

This commit is contained in:
Jason Ekstrand
2015-02-24 16:29:33 -08:00
parent 7b63b3de93
commit 053778c493
2 changed files with 122 additions and 1 deletions
+100
View File
@@ -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::function_types = NULL;
void *glsl_type::mem_ctx = NULL;
void
@@ -159,6 +160,39 @@ glsl_type::glsl_type(const glsl_struct_field *fields, unsigned num_fields,
mtx_unlock(&glsl_type::mutex);
}
glsl_type::glsl_type(const glsl_type *return_type,
const glsl_function_param *params, unsigned num_params) :
gl_type(0),
base_type(GLSL_TYPE_FUNCTION),
sampler_dimensionality(0), sampler_shadow(0), sampler_array(0),
sampler_type(0), interface_packing(0),
vector_elements(0), matrix_columns(0),
length(num_params)
{
unsigned int i;
mtx_lock(&glsl_type::mutex);
init_ralloc_type_ctx();
this->fields.parameters = rzalloc_array(this->mem_ctx,
glsl_function_param, num_params + 1);
/* We store the return type as the first parameter */
this->fields.parameters[0].type = return_type;
this->fields.parameters[0].in = false;
this->fields.parameters[0].out = true;
/* We store the i'th parameter in slot i+1 */
for (i = 0; i < length; i++) {
this->fields.parameters[i + 1].type = params[i].type;
this->fields.parameters[i + 1].in = params[i].in;
this->fields.parameters[i + 1].out = params[i].out;
}
mtx_unlock(&glsl_type::mutex);
}
bool
glsl_type::contains_sampler() const
@@ -827,6 +861,72 @@ glsl_type::get_interface_instance(const glsl_struct_field *fields,
}
static int
function_key_compare(const void *a, const void *b)
{
const glsl_type *const key1 = (glsl_type *) a;
const glsl_type *const key2 = (glsl_type *) b;
if (key1->length != key2->length)
return 1;
return memcmp(key1->fields.parameters, key2->fields.parameters,
(key1->length + 1) * sizeof(*key1->fields.parameters));
}
static unsigned
function_key_hash(const void *a)
{
const glsl_type *const key = (glsl_type *) a;
char hash_key[128];
unsigned size = 0;
size = snprintf(hash_key, sizeof(hash_key), "%08x", key->length);
for (unsigned i = 0; i < key->length; i++) {
if (size >= sizeof(hash_key))
break;
size += snprintf(& hash_key[size], sizeof(hash_key) - size,
"%p", (void *) key->fields.structure[i].type);
}
return hash_table_string_hash(& hash_key);
}
const glsl_type *
glsl_type::get_function_instance(const glsl_type *return_type,
const glsl_function_param *params,
unsigned num_params)
{
const glsl_type key(return_type, params, num_params);
mtx_lock(&glsl_type::mutex);
if (function_types == NULL) {
function_types = hash_table_ctor(64, function_key_hash,
function_key_compare);
}
const glsl_type *t = (glsl_type *) hash_table_find(function_types, &key);
if (t == NULL) {
mtx_unlock(&glsl_type::mutex);
t = new glsl_type(return_type, params, num_params);
mtx_lock(&glsl_type::mutex);
hash_table_insert(function_types, (void *) t, t);
}
assert(t->base_type == GLSL_TYPE_FUNCTION);
assert(t->length == num_params);
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)
{
+22 -1
View File
@@ -179,7 +179,7 @@ struct glsl_type {
*/
union {
const struct glsl_type *array; /**< Type of array elements. */
const struct glsl_type *parameters; /**< Parameters to function. */
struct glsl_function_param *parameters; /**< Parameters to function. */
struct glsl_struct_field *structure; /**< List of struct fields. */
} fields;
@@ -276,6 +276,13 @@ struct glsl_type {
enum glsl_interface_packing packing,
const char *block_name);
/**
* Get the instance of a function type
*/
static const glsl_type *get_function_instance(const struct glsl_type *return_type,
const glsl_function_param *parameters,
unsigned num_params);
/**
* Get the type resulting from a multiplication of \p type_a * \p type_b
*/
@@ -689,6 +696,10 @@ private:
glsl_type(const glsl_struct_field *fields, unsigned num_fields,
enum glsl_interface_packing packing, const char *name);
/** Constructor for interface types */
glsl_type(const glsl_type *return_type,
const glsl_function_param *params, unsigned num_params);
/** Constructor for array types */
glsl_type(const glsl_type *array, unsigned length);
@@ -701,6 +712,9 @@ private:
/** Hash table containing the known interface types. */
static struct hash_table *interface_types;
/** Hash table containing the known function types. */
static struct hash_table *function_types;
static int record_key_compare(const void *a, const void *b);
static unsigned record_key_hash(const void *key);
@@ -771,6 +785,13 @@ struct glsl_struct_field {
int stream;
};
struct glsl_function_param {
const struct glsl_type *type;
bool in;
bool out;
};
static inline unsigned int
glsl_align(unsigned int a, unsigned int align)
{