diff options
author | Ian Romanick <ian.d.romanick@intel.com> | 2012-12-11 12:11:16 -0800 |
---|---|---|
committer | Ian Romanick <ian.d.romanick@intel.com> | 2013-01-25 09:07:33 -0500 |
commit | 491364e1f34ddb2c8ea439e871dd42aaa5cc9b28 (patch) | |
tree | 339b24932702a6421845c15c08fcba2bcc4104f8 /src/glsl/glsl_types.cpp | |
parent | 7f96a8471e8ddf2b49a644780f35ee493157782a (diff) |
glsl: Add GLSL_TYPE_INTERFACE
Interfaces are structurally identical to structures from the compiler's
point of view. They have some additional restrictions, and generally
GPUs use different instructions to access them. Using a different base
type should make this a bit easier.
This commit also adds the glsl_type::interface_packing fields. For
GLSL_TYPE_INTERFACE types, this will track the specified packing mode.
It is analogous to gl_uniform_buffer::_Packing.
v2: Add serveral missing GLSL_TYPE_INTERFACE cases in switch-statements.
v3: Add information about glsl_type::interface_packing. Move row_major
checking in glsl_type::record_key_compare from this patch to the
previous patch. Both suggested by Paul Berry.
Signed-off-by: Ian Romanick <ian.d.romanick@intel.com>
Reviewed-by: Paul Berry <stereotype441@gmail.com>
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
Diffstat (limited to 'src/glsl/glsl_types.cpp')
-rw-r--r-- | src/glsl/glsl_types.cpp | 70 |
1 files changed, 63 insertions, 7 deletions
diff --git a/src/glsl/glsl_types.cpp b/src/glsl/glsl_types.cpp index f2dd44acb62..40368ddd0f7 100644 --- a/src/glsl/glsl_types.cpp +++ b/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,29 @@ 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) +{ + 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; + } +} + +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) { @@ -430,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) { @@ -562,6 +585,9 @@ 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; @@ -625,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++) { @@ -642,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++) { @@ -664,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++) |