aboutsummaryrefslogtreecommitdiff
path: root/mesalib/src/glsl/glsl_types.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'mesalib/src/glsl/glsl_types.cpp')
-rw-r--r--mesalib/src/glsl/glsl_types.cpp94
1 files changed, 76 insertions, 18 deletions
diff --git a/mesalib/src/glsl/glsl_types.cpp b/mesalib/src/glsl/glsl_types.cpp
index 71b185027..4a2c87907 100644
--- a/mesalib/src/glsl/glsl_types.cpp
+++ b/mesalib/src/glsl/glsl_types.cpp
@@ -34,6 +34,7 @@ extern "C" {
hash_table *glsl_type::array_types = NULL;
hash_table *glsl_type::record_types = NULL;
+hash_table *glsl_type::interface_types = NULL;
void *glsl_type::mem_ctx = NULL;
void
@@ -51,7 +52,7 @@ glsl_type::glsl_type(GLenum gl_type,
gl_type(gl_type),
base_type(base_type),
sampler_dimensionality(0), sampler_shadow(0), sampler_array(0),
- sampler_type(0),
+ sampler_type(0), interface_packing(0),
vector_elements(vector_elements), matrix_columns(matrix_columns),
length(0)
{
@@ -69,7 +70,7 @@ glsl_type::glsl_type(GLenum gl_type,
gl_type(gl_type),
base_type(GLSL_TYPE_SAMPLER),
sampler_dimensionality(dim), sampler_shadow(shadow),
- sampler_array(array), sampler_type(type),
+ sampler_array(array), sampler_type(type), interface_packing(0),
vector_elements(0), matrix_columns(0),
length(0)
{
@@ -82,7 +83,7 @@ glsl_type::glsl_type(const glsl_struct_field *fields, unsigned num_fields,
const char *name) :
base_type(GLSL_TYPE_STRUCT),
sampler_dimensionality(0), sampler_shadow(0), sampler_array(0),
- sampler_type(0),
+ sampler_type(0), interface_packing(0),
vector_elements(0), matrix_columns(0),
length(num_fields)
{
@@ -96,6 +97,29 @@ glsl_type::glsl_type(const glsl_struct_field *fields, unsigned num_fields,
this->fields.structure[i].type = fields[i].type;
this->fields.structure[i].name = ralloc_strdup(this->fields.structure,
fields[i].name);
+ this->fields.structure[i].row_major = fields[i].row_major;
+ }
+}
+
+glsl_type::glsl_type(const glsl_struct_field *fields, unsigned num_fields,
+ enum glsl_interface_packing packing, const char *name) :
+ base_type(GLSL_TYPE_INTERFACE),
+ sampler_dimensionality(0), sampler_shadow(0), sampler_array(0),
+ sampler_type(0), interface_packing((unsigned) packing),
+ vector_elements(0), matrix_columns(0),
+ length(num_fields)
+{
+ unsigned int i;
+
+ init_ralloc_type_ctx();
+ this->name = ralloc_strdup(this->mem_ctx, name);
+ this->fields.structure = ralloc_array(this->mem_ctx,
+ glsl_struct_field, length);
+ for (i = 0; i < length; i++) {
+ this->fields.structure[i].type = fields[i].type;
+ this->fields.structure[i].name = ralloc_strdup(this->fields.structure,
+ fields[i].name);
+ this->fields.structure[i].row_major = fields[i].row_major;
}
}
@@ -429,7 +453,7 @@ _mesa_glsl_release_types(void)
glsl_type::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),
+ sampler_type(0), interface_packing(0),
vector_elements(0), matrix_columns(0),
name(NULL), length(length)
{
@@ -561,12 +585,18 @@ glsl_type::record_key_compare(const void *a, const void *b)
if (key1->length != key2->length)
return 1;
+ if (key1->interface_packing != key2->interface_packing)
+ return 1;
+
for (unsigned i = 0; i < key1->length; i++) {
if (key1->fields.structure[i].type != key2->fields.structure[i].type)
return 1;
if (strcmp(key1->fields.structure[i].name,
key2->fields.structure[i].name) != 0)
return 1;
+ if (key1->fields.structure[i].row_major
+ != key2->fields.structure[i].row_major)
+ return 1;
}
return 0;
@@ -621,9 +651,37 @@ glsl_type::get_record_instance(const glsl_struct_field *fields,
const glsl_type *
+glsl_type::get_interface_instance(const glsl_struct_field *fields,
+ unsigned num_fields,
+ enum glsl_interface_packing packing,
+ const char *name)
+{
+ const glsl_type key(fields, num_fields, packing, name);
+
+ if (interface_types == NULL) {
+ interface_types = hash_table_ctor(64, record_key_hash, record_key_compare);
+ }
+
+ const glsl_type *t = (glsl_type *) hash_table_find(interface_types, & key);
+ if (t == NULL) {
+ t = new glsl_type(fields, num_fields, packing, name);
+
+ hash_table_insert(interface_types, (void *) t, t);
+ }
+
+ assert(t->base_type == GLSL_TYPE_INTERFACE);
+ assert(t->length == num_fields);
+ assert(strcmp(t->name, name) == 0);
+
+ return t;
+}
+
+
+const glsl_type *
glsl_type::field_type(const char *name) const
{
- if (this->base_type != GLSL_TYPE_STRUCT)
+ if (this->base_type != GLSL_TYPE_STRUCT
+ && this->base_type != GLSL_TYPE_INTERFACE)
return error_type;
for (unsigned i = 0; i < this->length; i++) {
@@ -638,7 +696,8 @@ glsl_type::field_type(const char *name) const
int
glsl_type::field_index(const char *name) const
{
- if (this->base_type != GLSL_TYPE_STRUCT)
+ if (this->base_type != GLSL_TYPE_STRUCT
+ && this->base_type != GLSL_TYPE_INTERFACE)
return -1;
for (unsigned i = 0; i < this->length; i++) {
@@ -660,7 +719,8 @@ glsl_type::component_slots() const
case GLSL_TYPE_BOOL:
return this->components();
- case GLSL_TYPE_STRUCT: {
+ case GLSL_TYPE_STRUCT:
+ case GLSL_TYPE_INTERFACE: {
unsigned size = 0;
for (unsigned i = 0; i < this->length; i++)
@@ -672,9 +732,13 @@ glsl_type::component_slots() const
case GLSL_TYPE_ARRAY:
return this->length * this->fields.array->component_slots();
- default:
- return 0;
+ case GLSL_TYPE_SAMPLER:
+ case GLSL_TYPE_VOID:
+ case GLSL_TYPE_ERROR:
+ break;
}
+
+ return 0;
}
bool
@@ -799,12 +863,6 @@ glsl_type::std140_base_alignment(bool row_major) const
return -1;
}
-static unsigned
-align(unsigned val, unsigned align)
-{
- return (val + align - 1) / align * align;
-}
-
unsigned
glsl_type::std140_size(bool row_major) const
{
@@ -906,11 +964,11 @@ glsl_type::std140_size(bool row_major) const
for (unsigned i = 0; i < this->length; i++) {
const struct glsl_type *field_type = this->fields.structure[i].type;
unsigned align = field_type->std140_base_alignment(row_major);
- size = (size + align - 1) / align * align;
+ size = glsl_align(size, align);
size += field_type->std140_size(row_major);
}
- size = align(size,
- this->fields.structure[0].type->std140_base_alignment(row_major));
+ size = glsl_align(size,
+ this->fields.structure[0].type->std140_base_alignment(row_major));
return size;
}