X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fcompiler%2Fglsl_types.cpp;h=3cc5eb0495c8317b4e0275a11e8bcc681dac9ebb;hb=a34715ad9c84c4209de4c16fdf40655181350bd9;hp=c6a742e3aafd2500503b104cc0fde69b85182832;hpb=04d2f770c868537c2aa7329e923d526e7014d0b3;p=mesa.git diff --git a/src/compiler/glsl_types.cpp b/src/compiler/glsl_types.cpp index c6a742e3aaf..3cc5eb0495c 100644 --- a/src/compiler/glsl_types.cpp +++ b/src/compiler/glsl_types.cpp @@ -28,7 +28,8 @@ #include "util/hash_table.h" -mtx_t glsl_type::mutex = _MTX_INITIALIZER_NP; +mtx_t glsl_type::mem_mutex = _MTX_INITIALIZER_NP; +mtx_t glsl_type::hash_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; @@ -40,7 +41,7 @@ void glsl_type::init_ralloc_type_ctx(void) { if (glsl_type::mem_ctx == NULL) { - glsl_type::mem_ctx = ralloc_autofree_context(); + glsl_type::mem_ctx = ralloc_context(NULL); assert(glsl_type::mem_ctx != NULL); } } @@ -49,19 +50,26 @@ glsl_type::glsl_type(GLenum gl_type, glsl_base_type base_type, unsigned vector_elements, unsigned matrix_columns, const char *name) : gl_type(gl_type), - base_type(base_type), + base_type(base_type), sampled_type(GLSL_TYPE_VOID), sampler_dimensionality(0), sampler_shadow(0), sampler_array(0), - sampled_type(0), interface_packing(0), + interface_packing(0), interface_row_major(0), vector_elements(vector_elements), matrix_columns(matrix_columns), length(0) { - mtx_lock(&glsl_type::mutex); + /* Values of these types must fit in the two bits of + * glsl_type::sampled_type. + */ + STATIC_ASSERT((unsigned(GLSL_TYPE_UINT) & 3) == unsigned(GLSL_TYPE_UINT)); + STATIC_ASSERT((unsigned(GLSL_TYPE_INT) & 3) == unsigned(GLSL_TYPE_INT)); + STATIC_ASSERT((unsigned(GLSL_TYPE_FLOAT) & 3) == unsigned(GLSL_TYPE_FLOAT)); + + mtx_lock(&glsl_type::mem_mutex); init_ralloc_type_ctx(); assert(name != NULL); this->name = ralloc_strdup(this->mem_ctx, name); - mtx_unlock(&glsl_type::mutex); + mtx_unlock(&glsl_type::mem_mutex); /* Neither dimension is zero or both dimensions are zero. */ @@ -71,43 +79,38 @@ glsl_type::glsl_type(GLenum gl_type, glsl_type::glsl_type(GLenum gl_type, glsl_base_type base_type, enum glsl_sampler_dim dim, bool shadow, bool array, - unsigned type, const char *name) : + glsl_base_type type, const char *name) : gl_type(gl_type), - base_type(base_type), + base_type(base_type), sampled_type(type), sampler_dimensionality(dim), sampler_shadow(shadow), - sampler_array(array), sampled_type(type), interface_packing(0), - length(0) + sampler_array(array), interface_packing(0), + interface_row_major(0), length(0) { - mtx_lock(&glsl_type::mutex); + mtx_lock(&glsl_type::mem_mutex); init_ralloc_type_ctx(); assert(name != NULL); this->name = ralloc_strdup(this->mem_ctx, name); - mtx_unlock(&glsl_type::mutex); + mtx_unlock(&glsl_type::mem_mutex); memset(& fields, 0, sizeof(fields)); - if (base_type == GLSL_TYPE_SAMPLER) { - /* Samplers take no storage whatsoever. */ - matrix_columns = vector_elements = 0; - } else { - matrix_columns = vector_elements = 1; - } + matrix_columns = vector_elements = 1; } glsl_type::glsl_type(const glsl_struct_field *fields, unsigned num_fields, const char *name) : gl_type(0), - base_type(GLSL_TYPE_STRUCT), + base_type(GLSL_TYPE_STRUCT), sampled_type(GLSL_TYPE_VOID), sampler_dimensionality(0), sampler_shadow(0), sampler_array(0), - sampled_type(0), interface_packing(0), + interface_packing(0), interface_row_major(0), vector_elements(0), matrix_columns(0), length(num_fields) { unsigned int i; - mtx_lock(&glsl_type::mutex); + mtx_lock(&glsl_type::mem_mutex); init_ralloc_type_ctx(); assert(name != NULL); @@ -116,87 +119,55 @@ glsl_type::glsl_type(const glsl_struct_field *fields, unsigned num_fields, glsl_struct_field, length); for (i = 0; i < length; i++) { - this->fields.structure[i].type = fields[i].type; + this->fields.structure[i] = fields[i]; this->fields.structure[i].name = ralloc_strdup(this->fields.structure, fields[i].name); - this->fields.structure[i].location = fields[i].location; - this->fields.structure[i].offset = fields[i].offset; - this->fields.structure[i].interpolation = fields[i].interpolation; - this->fields.structure[i].centroid = fields[i].centroid; - this->fields.structure[i].sample = fields[i].sample; - this->fields.structure[i].matrix_layout = fields[i].matrix_layout; - this->fields.structure[i].patch = fields[i].patch; - this->fields.structure[i].image_read_only = fields[i].image_read_only; - this->fields.structure[i].image_write_only = fields[i].image_write_only; - this->fields.structure[i].image_coherent = fields[i].image_coherent; - this->fields.structure[i].image_volatile = fields[i].image_volatile; - this->fields.structure[i].image_restrict = fields[i].image_restrict; - this->fields.structure[i].precision = fields[i].precision; - this->fields.structure[i].explicit_xfb_buffer = - fields[i].explicit_xfb_buffer; - this->fields.structure[i].xfb_buffer = fields[i].xfb_buffer; - this->fields.structure[i].xfb_stride = fields[i].xfb_stride; - } - - mtx_unlock(&glsl_type::mutex); + } + + mtx_unlock(&glsl_type::mem_mutex); } glsl_type::glsl_type(const glsl_struct_field *fields, unsigned num_fields, - enum glsl_interface_packing packing, const char *name) : + enum glsl_interface_packing packing, + bool row_major, const char *name) : gl_type(0), - base_type(GLSL_TYPE_INTERFACE), + base_type(GLSL_TYPE_INTERFACE), sampled_type(GLSL_TYPE_VOID), sampler_dimensionality(0), sampler_shadow(0), sampler_array(0), - sampled_type(0), interface_packing((unsigned) packing), + interface_packing((unsigned) packing), + interface_row_major((unsigned) row_major), vector_elements(0), matrix_columns(0), length(num_fields) { unsigned int i; - mtx_lock(&glsl_type::mutex); + mtx_lock(&glsl_type::mem_mutex); init_ralloc_type_ctx(); assert(name != NULL); this->name = ralloc_strdup(this->mem_ctx, name); - this->fields.structure = ralloc_array(this->mem_ctx, - glsl_struct_field, length); + this->fields.structure = rzalloc_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] = fields[i]; this->fields.structure[i].name = ralloc_strdup(this->fields.structure, fields[i].name); - this->fields.structure[i].location = fields[i].location; - this->fields.structure[i].offset = fields[i].offset; - this->fields.structure[i].interpolation = fields[i].interpolation; - this->fields.structure[i].centroid = fields[i].centroid; - this->fields.structure[i].sample = fields[i].sample; - this->fields.structure[i].matrix_layout = fields[i].matrix_layout; - this->fields.structure[i].patch = fields[i].patch; - this->fields.structure[i].image_read_only = fields[i].image_read_only; - this->fields.structure[i].image_write_only = fields[i].image_write_only; - this->fields.structure[i].image_coherent = fields[i].image_coherent; - this->fields.structure[i].image_volatile = fields[i].image_volatile; - this->fields.structure[i].image_restrict = fields[i].image_restrict; - this->fields.structure[i].precision = fields[i].precision; - this->fields.structure[i].explicit_xfb_buffer = - fields[i].explicit_xfb_buffer; - this->fields.structure[i].xfb_buffer = fields[i].xfb_buffer; - this->fields.structure[i].xfb_stride = fields[i].xfb_stride; - } - - mtx_unlock(&glsl_type::mutex); + } + + mtx_unlock(&glsl_type::mem_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), + base_type(GLSL_TYPE_FUNCTION), sampled_type(GLSL_TYPE_VOID), sampler_dimensionality(0), sampler_shadow(0), sampler_array(0), - sampled_type(0), interface_packing(0), + interface_packing(0), interface_row_major(0), vector_elements(0), matrix_columns(0), length(num_params) { unsigned int i; - mtx_lock(&glsl_type::mutex); + mtx_lock(&glsl_type::mem_mutex); init_ralloc_type_ctx(); @@ -215,23 +186,23 @@ glsl_type::glsl_type(const glsl_type *return_type, this->fields.parameters[i + 1].out = params[i].out; } - mtx_unlock(&glsl_type::mutex); + mtx_unlock(&glsl_type::mem_mutex); } glsl_type::glsl_type(const char *subroutine_name) : gl_type(0), - base_type(GLSL_TYPE_SUBROUTINE), + base_type(GLSL_TYPE_SUBROUTINE), sampled_type(GLSL_TYPE_VOID), sampler_dimensionality(0), sampler_shadow(0), sampler_array(0), - sampled_type(0), interface_packing(0), + interface_packing(0), interface_row_major(0), vector_elements(1), matrix_columns(1), length(0) { - mtx_lock(&glsl_type::mutex); + mtx_lock(&glsl_type::mem_mutex); init_ralloc_type_ctx(); assert(subroutine_name != NULL); this->name = ralloc_strdup(this->mem_ctx, subroutine_name); - mtx_unlock(&glsl_type::mutex); + mtx_unlock(&glsl_type::mem_mutex); } bool @@ -239,7 +210,7 @@ glsl_type::contains_sampler() const { if (this->is_array()) { return this->fields.array->contains_sampler(); - } else if (this->is_record()) { + } else if (this->is_record() || this->is_interface()) { for (unsigned int i = 0; i < this->length; i++) { if (this->fields.structure[i].type->contains_sampler()) return true; @@ -250,13 +221,26 @@ glsl_type::contains_sampler() const } } +bool +glsl_type::contains_array() const +{ + if (this->is_record() || this->is_interface()) { + for (unsigned int i = 0; i < this->length; i++) { + if (this->fields.structure[i].type->contains_array()) + return true; + } + return false; + } else { + return this->is_array(); + } +} bool glsl_type::contains_integer() const { if (this->is_array()) { return this->fields.array->contains_integer(); - } else if (this->is_record()) { + } else if (this->is_record() || this->is_interface()) { for (unsigned int i = 0; i < this->length; i++) { if (this->fields.structure[i].type->contains_integer()) return true; @@ -272,7 +256,7 @@ glsl_type::contains_double() const { if (this->is_array()) { return this->fields.array->contains_double(); - } else if (this->is_record()) { + } else if (this->is_record() || this->is_interface()) { for (unsigned int i = 0; i < this->length; i++) { if (this->fields.structure[i].type->contains_double()) return true; @@ -293,6 +277,7 @@ glsl_type::contains_opaque() const { case GLSL_TYPE_ARRAY: return fields.array->contains_opaque(); case GLSL_TYPE_STRUCT: + case GLSL_TYPE_INTERFACE: for (unsigned int i = 0; i < length; i++) { if (fields.structure[i].type->contains_opaque()) return true; @@ -308,7 +293,7 @@ glsl_type::contains_subroutine() const { if (this->is_array()) { return this->fields.array->contains_subroutine(); - } else if (this->is_record()) { + } else if (this->is_record() || this->is_interface()) { for (unsigned int i = 0; i < this->length; i++) { if (this->fields.structure[i].type->contains_subroutine()) return true; @@ -324,7 +309,7 @@ glsl_type::sampler_index() const { const glsl_type *const t = (this->is_array()) ? this->fields.array : this; - assert(t->is_sampler()); + assert(t->is_sampler() || t->is_image()); switch (t->sampler_dimensionality) { case GLSL_SAMPLER_DIM_1D: @@ -354,7 +339,7 @@ glsl_type::contains_image() const { if (this->is_array()) { return this->fields.array->contains_image(); - } else if (this->is_record()) { + } else if (this->is_record() || this->is_interface()) { for (unsigned int i = 0; i < this->length; i++) { if (this->fields.structure[i].type->contains_image()) return true; @@ -370,14 +355,24 @@ const glsl_type *glsl_type::get_base_type() const switch (base_type) { case GLSL_TYPE_UINT: return uint_type; + case GLSL_TYPE_UINT16: + return uint16_t_type; case GLSL_TYPE_INT: return int_type; + case GLSL_TYPE_INT16: + return int16_t_type; case GLSL_TYPE_FLOAT: return float_type; + case GLSL_TYPE_FLOAT16: + return float16_t_type; case GLSL_TYPE_DOUBLE: return double_type; case GLSL_TYPE_BOOL: return bool_type; + case GLSL_TYPE_UINT64: + return uint64_t_type; + case GLSL_TYPE_INT64: + return int64_t_type; default: return error_type; } @@ -396,14 +391,24 @@ const glsl_type *glsl_type::get_scalar_type() const switch (type->base_type) { case GLSL_TYPE_UINT: return uint_type; + case GLSL_TYPE_UINT16: + return uint16_t_type; case GLSL_TYPE_INT: return int_type; + case GLSL_TYPE_INT16: + return int16_t_type; case GLSL_TYPE_FLOAT: return float_type; + case GLSL_TYPE_FLOAT16: + return float16_t_type; case GLSL_TYPE_DOUBLE: return double_type; case GLSL_TYPE_BOOL: return bool_type; + case GLSL_TYPE_UINT64: + return uint64_t_type; + case GLSL_TYPE_INT64: + return int64_t_type; default: /* Handle everything else */ return type; @@ -432,13 +437,26 @@ _mesa_glsl_release_types(void) _mesa_hash_table_destroy(glsl_type::interface_types, NULL); glsl_type::interface_types = NULL; } + + if (glsl_type::function_types != NULL) { + _mesa_hash_table_destroy(glsl_type::function_types, NULL); + glsl_type::function_types = NULL; + } + + if (glsl_type::subroutine_types != NULL) { + _mesa_hash_table_destroy(glsl_type::subroutine_types, NULL); + glsl_type::subroutine_types = NULL; + } + + ralloc_free(glsl_type::mem_ctx); + glsl_type::mem_ctx = NULL; } glsl_type::glsl_type(const glsl_type *array, unsigned length) : - base_type(GLSL_TYPE_ARRAY), + base_type(GLSL_TYPE_ARRAY), sampled_type(GLSL_TYPE_VOID), sampler_dimensionality(0), sampler_shadow(0), sampler_array(0), - sampled_type(0), interface_packing(0), + interface_packing(0), interface_row_major(0), vector_elements(0), matrix_columns(0), length(length), name(NULL) { @@ -455,9 +473,9 @@ glsl_type::glsl_type(const glsl_type *array, unsigned length) : */ const unsigned name_length = strlen(array->name) + 10 + 3; - mtx_lock(&glsl_type::mutex); + mtx_lock(&glsl_type::mem_mutex); char *const n = (char *) ralloc_size(this->mem_ctx, name_length); - mtx_unlock(&glsl_type::mutex); + mtx_unlock(&glsl_type::mem_mutex); if (length == 0) snprintf(n, name_length, "%s[]", array->name); @@ -492,6 +510,18 @@ glsl_type::vec(unsigned components) return ts[components - 1]; } +const glsl_type * +glsl_type::f16vec(unsigned components) +{ + if (components == 0 || components > 4) + return error_type; + + static const glsl_type *const ts[] = { + float16_t_type, f16vec2_type, f16vec3_type, f16vec4_type + }; + return ts[components - 1]; +} + const glsl_type * glsl_type::dvec(unsigned components) { @@ -543,6 +573,56 @@ glsl_type::bvec(unsigned components) } +const glsl_type * +glsl_type::i64vec(unsigned components) +{ + if (components == 0 || components > 4) + return error_type; + + static const glsl_type *const ts[] = { + int64_t_type, i64vec2_type, i64vec3_type, i64vec4_type + }; + return ts[components - 1]; +} + + +const glsl_type * +glsl_type::u64vec(unsigned components) +{ + if (components == 0 || components > 4) + return error_type; + + static const glsl_type *const ts[] = { + uint64_t_type, u64vec2_type, u64vec3_type, u64vec4_type + }; + return ts[components - 1]; +} + +const glsl_type * +glsl_type::i16vec(unsigned components) +{ + if (components == 0 || components > 4) + return error_type; + + static const glsl_type *const ts[] = { + int16_t_type, i16vec2_type, i16vec3_type, i16vec4_type + }; + return ts[components - 1]; +} + + +const glsl_type * +glsl_type::u16vec(unsigned components) +{ + if (components == 0 || components > 4) + return error_type; + + static const glsl_type *const ts[] = { + uint16_t_type, u16vec2_type, u16vec3_type, u16vec4_type + }; + return ts[components - 1]; +} + const glsl_type * glsl_type::get_instance(unsigned base_type, unsigned rows, unsigned columns) { @@ -562,15 +642,27 @@ glsl_type::get_instance(unsigned base_type, unsigned rows, unsigned columns) return ivec(rows); case GLSL_TYPE_FLOAT: return vec(rows); + case GLSL_TYPE_FLOAT16: + return f16vec(rows); case GLSL_TYPE_DOUBLE: return dvec(rows); case GLSL_TYPE_BOOL: return bvec(rows); + case GLSL_TYPE_UINT64: + return u64vec(rows); + case GLSL_TYPE_INT64: + return i64vec(rows); + case GLSL_TYPE_UINT16: + return u16vec(rows); + case GLSL_TYPE_INT16: + return i16vec(rows); default: return error_type; } } else { - if ((base_type != GLSL_TYPE_FLOAT && base_type != GLSL_TYPE_DOUBLE) || (rows == 1)) + if ((base_type != GLSL_TYPE_FLOAT && + base_type != GLSL_TYPE_DOUBLE && + base_type != GLSL_TYPE_FLOAT16) || (rows == 1)) return error_type; /* GLSL matrix types are named mat{COLUMNS}x{ROWS}. Only the following @@ -584,7 +676,8 @@ glsl_type::get_instance(unsigned base_type, unsigned rows, unsigned columns) */ #define IDX(c,r) (((c-1)*3) + (r-1)) - if (base_type == GLSL_TYPE_DOUBLE) { + switch (base_type) { + case GLSL_TYPE_DOUBLE: { switch (IDX(columns, rows)) { case IDX(2,2): return dmat2_type; case IDX(2,3): return dmat2x3_type; @@ -597,7 +690,8 @@ glsl_type::get_instance(unsigned base_type, unsigned rows, unsigned columns) case IDX(4,4): return dmat4_type; default: return error_type; } - } else { + } + case GLSL_TYPE_FLOAT: { switch (IDX(columns, rows)) { case IDX(2,2): return mat2_type; case IDX(2,3): return mat2x3_type; @@ -611,6 +705,22 @@ glsl_type::get_instance(unsigned base_type, unsigned rows, unsigned columns) default: return error_type; } } + case GLSL_TYPE_FLOAT16: { + switch (IDX(columns, rows)) { + case IDX(2,2): return f16mat2_type; + case IDX(2,3): return f16mat2x3_type; + case IDX(2,4): return f16mat2x4_type; + case IDX(3,2): return f16mat3x2_type; + case IDX(3,3): return f16mat3_type; + case IDX(3,4): return f16mat3x4_type; + case IDX(4,2): return f16mat4x2_type; + case IDX(4,3): return f16mat4x3_type; + case IDX(4,4): return f16mat4_type; + default: return error_type; + } + } + default: return error_type; + } } assert(!"Should not get here."); @@ -667,6 +777,9 @@ glsl_type::get_sampler_instance(enum glsl_sampler_dim dim, return error_type; else return samplerExternalOES_type; + case GLSL_SAMPLER_DIM_SUBPASS: + case GLSL_SAMPLER_DIM_SUBPASS_MS: + return error_type; } case GLSL_TYPE_INT: if (shadow) @@ -694,6 +807,9 @@ glsl_type::get_sampler_instance(enum glsl_sampler_dim dim, return (array ? isampler2DMSArray_type : isampler2DMS_type); case GLSL_SAMPLER_DIM_EXTERNAL: return error_type; + case GLSL_SAMPLER_DIM_SUBPASS: + case GLSL_SAMPLER_DIM_SUBPASS_MS: + return error_type; } case GLSL_TYPE_UINT: if (shadow) @@ -721,6 +837,9 @@ glsl_type::get_sampler_instance(enum glsl_sampler_dim dim, return (array ? usampler2DMSArray_type : usampler2DMS_type); case GLSL_SAMPLER_DIM_EXTERNAL: return error_type; + case GLSL_SAMPLER_DIM_SUBPASS: + case GLSL_SAMPLER_DIM_SUBPASS_MS: + return error_type; } default: return error_type; @@ -756,6 +875,10 @@ glsl_type::get_image_instance(enum glsl_sampler_dim dim, return imageBuffer_type; case GLSL_SAMPLER_DIM_MS: return (array ? image2DMSArray_type : image2DMS_type); + case GLSL_SAMPLER_DIM_SUBPASS: + return subpassInput_type; + case GLSL_SAMPLER_DIM_SUBPASS_MS: + return subpassInputMS_type; case GLSL_SAMPLER_DIM_EXTERNAL: return error_type; } @@ -781,6 +904,10 @@ glsl_type::get_image_instance(enum glsl_sampler_dim dim, return iimageBuffer_type; case GLSL_SAMPLER_DIM_MS: return (array ? iimage2DMSArray_type : iimage2DMS_type); + case GLSL_SAMPLER_DIM_SUBPASS: + return isubpassInput_type; + case GLSL_SAMPLER_DIM_SUBPASS_MS: + return isubpassInputMS_type; case GLSL_SAMPLER_DIM_EXTERNAL: return error_type; } @@ -806,6 +933,10 @@ glsl_type::get_image_instance(enum glsl_sampler_dim dim, return uimageBuffer_type; case GLSL_SAMPLER_DIM_MS: return (array ? uimage2DMSArray_type : uimage2DMS_type); + case GLSL_SAMPLER_DIM_SUBPASS: + return usubpassInput_type; + case GLSL_SAMPLER_DIM_SUBPASS_MS: + return usubpassInputMS_type; case GLSL_SAMPLER_DIM_EXTERNAL: return error_type; } @@ -827,7 +958,7 @@ glsl_type::get_array_instance(const glsl_type *base, unsigned array_size) char key[128]; snprintf(key, sizeof(key), "%p[%u]", (void *) base, array_size); - mtx_lock(&glsl_type::mutex); + mtx_lock(&glsl_type::hash_mutex); if (array_types == NULL) { array_types = _mesa_hash_table_create(NULL, _mesa_key_hash_string, @@ -836,9 +967,7 @@ glsl_type::get_array_instance(const glsl_type *base, unsigned array_size) const struct hash_entry *entry = _mesa_hash_table_search(array_types, key); if (entry == NULL) { - mtx_unlock(&glsl_type::mutex); const glsl_type *t = new glsl_type(base, array_size); - mtx_lock(&glsl_type::mutex); entry = _mesa_hash_table_insert(array_types, ralloc_strdup(mem_ctx, key), @@ -849,14 +978,14 @@ glsl_type::get_array_instance(const glsl_type *base, unsigned array_size) assert(((glsl_type *) entry->data)->length == array_size); assert(((glsl_type *) entry->data)->fields.array == base); - mtx_unlock(&glsl_type::mutex); + mtx_unlock(&glsl_type::hash_mutex); return (glsl_type *) entry->data; } bool -glsl_type::record_compare(const glsl_type *b) const +glsl_type::record_compare(const glsl_type *b, bool match_locations) const { if (this->length != b->length) return false; @@ -864,19 +993,18 @@ glsl_type::record_compare(const glsl_type *b) const if (this->interface_packing != b->interface_packing) return false; + if (this->interface_row_major != b->interface_row_major) + return false; + /* From the GLSL 4.20 specification (Sec 4.2): * * "Structures must have the same name, sequence of type names, and * type definitions, and field names to be considered the same type." * * GLSL ES behaves the same (Ver 1.00 Sec 4.2.4, Ver 3.00 Sec 4.2.5). - * - * Note that we cannot force type name check when comparing unnamed - * structure types, these have a unique name assigned during parsing. */ - if (!this->is_anonymous() && !b->is_anonymous()) - if (strcmp(this->name, b->name) != 0) - return false; + if (strcmp(this->name, b->name) != 0) + return false; for (unsigned i = 0; i < this->length; i++) { if (this->fields.structure[i].type != b->fields.structure[i].type) @@ -887,7 +1015,7 @@ glsl_type::record_compare(const glsl_type *b) const if (this->fields.structure[i].matrix_layout != b->fields.structure[i].matrix_layout) return false; - if (this->fields.structure[i].location + if (match_locations && this->fields.structure[i].location != b->fields.structure[i].location) return false; if (this->fields.structure[i].offset @@ -905,20 +1033,23 @@ glsl_type::record_compare(const glsl_type *b) const if (this->fields.structure[i].patch != b->fields.structure[i].patch) return false; - if (this->fields.structure[i].image_read_only - != b->fields.structure[i].image_read_only) + if (this->fields.structure[i].memory_read_only + != b->fields.structure[i].memory_read_only) return false; - if (this->fields.structure[i].image_write_only - != b->fields.structure[i].image_write_only) + if (this->fields.structure[i].memory_write_only + != b->fields.structure[i].memory_write_only) return false; - if (this->fields.structure[i].image_coherent - != b->fields.structure[i].image_coherent) + if (this->fields.structure[i].memory_coherent + != b->fields.structure[i].memory_coherent) return false; - if (this->fields.structure[i].image_volatile - != b->fields.structure[i].image_volatile) + if (this->fields.structure[i].memory_volatile + != b->fields.structure[i].memory_volatile) return false; - if (this->fields.structure[i].image_restrict - != b->fields.structure[i].image_restrict) + if (this->fields.structure[i].memory_restrict + != b->fields.structure[i].memory_restrict) + return false; + if (this->fields.structure[i].image_format + != b->fields.structure[i].image_format) return false; if (this->fields.structure[i].precision != b->fields.structure[i].precision) @@ -979,7 +1110,7 @@ glsl_type::get_record_instance(const glsl_struct_field *fields, { const glsl_type key(fields, num_fields, name); - mtx_lock(&glsl_type::mutex); + mtx_lock(&glsl_type::hash_mutex); if (record_types == NULL) { record_types = _mesa_hash_table_create(NULL, record_key_hash, @@ -989,9 +1120,7 @@ glsl_type::get_record_instance(const glsl_struct_field *fields, const struct hash_entry *entry = _mesa_hash_table_search(record_types, &key); if (entry == NULL) { - mtx_unlock(&glsl_type::mutex); const glsl_type *t = new glsl_type(fields, num_fields, name); - mtx_lock(&glsl_type::mutex); entry = _mesa_hash_table_insert(record_types, t, (void *) t); } @@ -1000,7 +1129,7 @@ glsl_type::get_record_instance(const glsl_struct_field *fields, assert(((glsl_type *) entry->data)->length == num_fields); assert(strcmp(((glsl_type *) entry->data)->name, name) == 0); - mtx_unlock(&glsl_type::mutex); + mtx_unlock(&glsl_type::hash_mutex); return (glsl_type *) entry->data; } @@ -1010,11 +1139,12 @@ const glsl_type * glsl_type::get_interface_instance(const glsl_struct_field *fields, unsigned num_fields, enum glsl_interface_packing packing, + bool row_major, const char *block_name) { - const glsl_type key(fields, num_fields, packing, block_name); + const glsl_type key(fields, num_fields, packing, row_major, block_name); - mtx_lock(&glsl_type::mutex); + mtx_lock(&glsl_type::hash_mutex); if (interface_types == NULL) { interface_types = _mesa_hash_table_create(NULL, record_key_hash, @@ -1024,10 +1154,8 @@ glsl_type::get_interface_instance(const glsl_struct_field *fields, const struct hash_entry *entry = _mesa_hash_table_search(interface_types, &key); if (entry == NULL) { - mtx_unlock(&glsl_type::mutex); const glsl_type *t = new glsl_type(fields, num_fields, - packing, block_name); - mtx_lock(&glsl_type::mutex); + packing, row_major, block_name); entry = _mesa_hash_table_insert(interface_types, t, (void *) t); } @@ -1036,7 +1164,7 @@ glsl_type::get_interface_instance(const glsl_struct_field *fields, assert(((glsl_type *) entry->data)->length == num_fields); assert(strcmp(((glsl_type *) entry->data)->name, block_name) == 0); - mtx_unlock(&glsl_type::mutex); + mtx_unlock(&glsl_type::hash_mutex); return (glsl_type *) entry->data; } @@ -1046,7 +1174,7 @@ glsl_type::get_subroutine_instance(const char *subroutine_name) { const glsl_type key(subroutine_name); - mtx_lock(&glsl_type::mutex); + mtx_lock(&glsl_type::hash_mutex); if (subroutine_types == NULL) { subroutine_types = _mesa_hash_table_create(NULL, record_key_hash, @@ -1056,9 +1184,7 @@ glsl_type::get_subroutine_instance(const char *subroutine_name) const struct hash_entry *entry = _mesa_hash_table_search(subroutine_types, &key); if (entry == NULL) { - mtx_unlock(&glsl_type::mutex); const glsl_type *t = new glsl_type(subroutine_name); - mtx_lock(&glsl_type::mutex); entry = _mesa_hash_table_insert(subroutine_types, t, (void *) t); } @@ -1066,7 +1192,7 @@ glsl_type::get_subroutine_instance(const char *subroutine_name) assert(((glsl_type *) entry->data)->base_type == GLSL_TYPE_SUBROUTINE); assert(strcmp(((glsl_type *) entry->data)->name, subroutine_name) == 0); - mtx_unlock(&glsl_type::mutex); + mtx_unlock(&glsl_type::hash_mutex); return (glsl_type *) entry->data; } @@ -1079,7 +1205,7 @@ function_key_compare(const void *a, const void *b) const glsl_type *const key2 = (glsl_type *) b; if (key1->length != key2->length) - return 1; + return false; return memcmp(key1->fields.parameters, key2->fields.parameters, (key1->length + 1) * sizeof(*key1->fields.parameters)) == 0; @@ -1090,20 +1216,8 @@ static uint32_t 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 _mesa_hash_string(hash_key); + return _mesa_hash_data(key->fields.parameters, + (key->length + 1) * sizeof(*key->fields.parameters)); } const glsl_type * @@ -1113,7 +1227,7 @@ glsl_type::get_function_instance(const glsl_type *return_type, { const glsl_type key(return_type, params, num_params); - mtx_lock(&glsl_type::mutex); + mtx_lock(&glsl_type::hash_mutex); if (function_types == NULL) { function_types = _mesa_hash_table_create(NULL, function_key_hash, @@ -1122,9 +1236,7 @@ glsl_type::get_function_instance(const glsl_type *return_type, struct hash_entry *entry = _mesa_hash_table_search(function_types, &key); if (entry == NULL) { - mtx_unlock(&glsl_type::mutex); const glsl_type *t = new glsl_type(return_type, params, num_params); - mtx_lock(&glsl_type::mutex); entry = _mesa_hash_table_insert(function_types, t, (void *) t); } @@ -1134,7 +1246,7 @@ glsl_type::get_function_instance(const glsl_type *return_type, assert(t->base_type == GLSL_TYPE_FUNCTION); assert(t->length == num_params); - mtx_unlock(&glsl_type::mutex); + mtx_unlock(&glsl_type::hash_mutex); return t; } @@ -1245,11 +1357,16 @@ glsl_type::component_slots() const switch (this->base_type) { case GLSL_TYPE_UINT: case GLSL_TYPE_INT: + case GLSL_TYPE_UINT16: + case GLSL_TYPE_INT16: case GLSL_TYPE_FLOAT: + case GLSL_TYPE_FLOAT16: case GLSL_TYPE_BOOL: return this->components(); case GLSL_TYPE_DOUBLE: + case GLSL_TYPE_UINT64: + case GLSL_TYPE_INT64: return 2 * this->components(); case GLSL_TYPE_STRUCT: @@ -1265,13 +1382,14 @@ glsl_type::component_slots() const case GLSL_TYPE_ARRAY: return this->length * this->fields.array->component_slots(); + case GLSL_TYPE_SAMPLER: case GLSL_TYPE_IMAGE: - return 1; + return 2; + case GLSL_TYPE_SUBROUTINE: - return 1; + return 1; case GLSL_TYPE_FUNCTION: - case GLSL_TYPE_SAMPLER: case GLSL_TYPE_ATOMIC_UINT: case GLSL_TYPE_VOID: case GLSL_TYPE_ERROR: @@ -1331,7 +1449,12 @@ glsl_type::uniform_locations() const case GLSL_TYPE_UINT: case GLSL_TYPE_INT: case GLSL_TYPE_FLOAT: + case GLSL_TYPE_FLOAT16: case GLSL_TYPE_DOUBLE: + case GLSL_TYPE_UINT16: + case GLSL_TYPE_INT16: + case GLSL_TYPE_UINT64: + case GLSL_TYPE_INT64: case GLSL_TYPE_BOOL: case GLSL_TYPE_SAMPLER: case GLSL_TYPE_IMAGE: @@ -1350,6 +1473,43 @@ glsl_type::uniform_locations() const } } +unsigned +glsl_type::varying_count() const +{ + unsigned size = 0; + + switch (this->base_type) { + case GLSL_TYPE_UINT: + case GLSL_TYPE_INT: + case GLSL_TYPE_FLOAT: + case GLSL_TYPE_FLOAT16: + case GLSL_TYPE_DOUBLE: + case GLSL_TYPE_BOOL: + case GLSL_TYPE_UINT16: + case GLSL_TYPE_INT16: + case GLSL_TYPE_UINT64: + case GLSL_TYPE_INT64: + return 1; + + case GLSL_TYPE_STRUCT: + case GLSL_TYPE_INTERFACE: + for (unsigned i = 0; i < this->length; i++) + size += this->fields.structure[i].type->varying_count(); + return size; + case GLSL_TYPE_ARRAY: + /* Don't count innermost array elements */ + if (this->without_array()->is_record() || + this->without_array()->is_interface() || + this->fields.array->is_array()) + return this->length * this->fields.array->varying_count(); + else + return this->fields.array->varying_count(); + default: + assert(!"unsupported varying type"); + return 0; + } +} + bool glsl_type::can_implicitly_convert_to(const glsl_type *desired, _mesa_glsl_parse_state *state) const @@ -1357,11 +1517,11 @@ glsl_type::can_implicitly_convert_to(const glsl_type *desired, if (this == desired) return true; - /* ESSL does not allow implicit conversions. If there is no state, we're - * doing intra-stage function linking where these checks have already been - * done. + /* GLSL 1.10 and ESSL do not allow implicit conversions. If there is no + * state, we're doing intra-stage function linking where these checks have + * already been done. */ - if (state && state->es_shader) + if (state && (state->es_shader || !state->is_version(120, 0))) return false; /* There is no conversion among matrix types. */ @@ -1376,11 +1536,14 @@ glsl_type::can_implicitly_convert_to(const glsl_type *desired, if (desired->is_float() && this->is_integer()) return true; - /* With GLSL 4.0 / ARB_gpu_shader5, int can be converted to uint. - * Note that state may be NULL here, when resolving function calls in the - * linker. By this time, all the state-dependent checks have already - * happened though, so allow anything that's allowed in any shader version. */ - if ((!state || state->is_version(400, 0) || state->ARB_gpu_shader5_enable) && + /* With GLSL 4.0, ARB_gpu_shader5, or MESA_shader_integer_functions, int + * can be converted to uint. Note that state may be NULL here, when + * resolving function calls in the linker. By this time, all the + * state-dependent checks have already happened though, so allow anything + * that's allowed in any shader version. + */ + if ((!state || state->is_version(400, 0) || state->ARB_gpu_shader5_enable || + state->MESA_shader_integer_functions_enable) && desired->base_type == GLSL_TYPE_UINT && this->base_type == GLSL_TYPE_INT) return true; @@ -1402,7 +1565,7 @@ glsl_type::can_implicitly_convert_to(const glsl_type *desired, unsigned glsl_type::std140_base_alignment(bool row_major) const { - unsigned N = is_double() ? 8 : 4; + unsigned N = is_64bit() ? 8 : 4; /* (1) If the member is a scalar consuming basic machine units, the * base alignment is . @@ -1520,7 +1683,7 @@ glsl_type::std140_base_alignment(bool row_major) const unsigned glsl_type::std140_size(bool row_major) const { - unsigned N = is_double() ? 8 : 4; + unsigned N = is_64bit() ? 8 : 4; /* (1) If the member is a scalar consuming basic machine units, the * base alignment is . @@ -1657,7 +1820,7 @@ unsigned glsl_type::std430_base_alignment(bool row_major) const { - unsigned N = is_double() ? 8 : 4; + unsigned N = is_64bit() ? 8 : 4; /* (1) If the member is a scalar consuming basic machine units, the * base alignment is . @@ -1766,7 +1929,7 @@ glsl_type::std430_base_alignment(bool row_major) const unsigned glsl_type::std430_array_stride(bool row_major) const { - unsigned N = is_double() ? 8 : 4; + unsigned N = is_64bit() ? 8 : 4; /* Notice that the array stride of a vec3 is not 3 * N but 4 * N. * See OpenGL 4.30 spec, section 7.6.2.2 "Standard Uniform Block Layout" @@ -1784,7 +1947,7 @@ glsl_type::std430_array_stride(bool row_major) const unsigned glsl_type::std430_size(bool row_major) const { - unsigned N = is_double() ? 8 : 4; + unsigned N = is_64bit() ? 8 : 4; /* OpenGL 4.30 spec, section 7.6.2.2 "Standard Uniform Block Layout": * @@ -1865,7 +2028,7 @@ glsl_type::std430_size(bool row_major) const } unsigned -glsl_type::count_attribute_slots(bool vertex_input_slots) const +glsl_type::count_attribute_slots(bool is_vertex_input) const { /* From page 31 (page 37 of the PDF) of the GLSL 1.50 spec: * @@ -1895,11 +2058,18 @@ glsl_type::count_attribute_slots(bool vertex_input_slots) const switch (this->base_type) { case GLSL_TYPE_UINT: case GLSL_TYPE_INT: + case GLSL_TYPE_UINT16: + case GLSL_TYPE_INT16: case GLSL_TYPE_FLOAT: + case GLSL_TYPE_FLOAT16: case GLSL_TYPE_BOOL: + case GLSL_TYPE_SAMPLER: + case GLSL_TYPE_IMAGE: return this->matrix_columns; case GLSL_TYPE_DOUBLE: - if (this->vector_elements > 2 && !vertex_input_slots) + case GLSL_TYPE_UINT64: + case GLSL_TYPE_INT64: + if (this->vector_elements > 2 && !is_vertex_input) return this->matrix_columns * 2; else return this->matrix_columns; @@ -1908,20 +2078,20 @@ glsl_type::count_attribute_slots(bool vertex_input_slots) const unsigned size = 0; for (unsigned i = 0; i < this->length; i++) - size += this->fields.structure[i].type->count_attribute_slots(vertex_input_slots); + size += this->fields.structure[i].type->count_attribute_slots(is_vertex_input); return size; } case GLSL_TYPE_ARRAY: - return this->length * this->fields.array->count_attribute_slots(vertex_input_slots); + return this->length * this->fields.array->count_attribute_slots(is_vertex_input); + + case GLSL_TYPE_SUBROUTINE: + return 1; case GLSL_TYPE_FUNCTION: - case GLSL_TYPE_SAMPLER: - case GLSL_TYPE_IMAGE: case GLSL_TYPE_ATOMIC_UINT: case GLSL_TYPE_VOID: - case GLSL_TYPE_SUBROUTINE: case GLSL_TYPE_ERROR: break; } @@ -1945,6 +2115,7 @@ glsl_type::coordinate_components() const case GLSL_SAMPLER_DIM_RECT: case GLSL_SAMPLER_DIM_MS: case GLSL_SAMPLER_DIM_EXTERNAL: + case GLSL_SAMPLER_DIM_SUBPASS: size = 2; break; case GLSL_SAMPLER_DIM_3D: @@ -1962,8 +2133,7 @@ glsl_type::coordinate_components() const * cubemap faces. */ if (sampler_array && - !(base_type == GLSL_TYPE_IMAGE && - sampler_dimensionality == GLSL_SAMPLER_DIM_CUBE)) + !(is_image() && sampler_dimensionality == GLSL_SAMPLER_DIM_CUBE)) size += 1; return size; @@ -1982,3 +2152,177 @@ glsl_type::coordinate_components() const #include "compiler/builtin_type_macros.h" /** @} */ + +static void +get_struct_type_field_and_pointer_sizes(size_t *s_field_size, + size_t *s_field_ptrs) +{ + *s_field_size = sizeof(glsl_struct_field); + *s_field_ptrs = + sizeof(((glsl_struct_field *)0)->type) + + sizeof(((glsl_struct_field *)0)->name); +} + +void +encode_type_to_blob(struct blob *blob, const glsl_type *type) +{ + uint32_t encoding; + + if (!type) { + blob_write_uint32(blob, 0); + return; + } + + switch (type->base_type) { + case GLSL_TYPE_UINT: + case GLSL_TYPE_INT: + case GLSL_TYPE_FLOAT: + case GLSL_TYPE_BOOL: + case GLSL_TYPE_DOUBLE: + case GLSL_TYPE_UINT64: + case GLSL_TYPE_INT64: + encoding = (type->base_type << 24) | + (type->vector_elements << 4) | + (type->matrix_columns); + break; + case GLSL_TYPE_SAMPLER: + encoding = (type->base_type) << 24 | + (type->sampler_dimensionality << 4) | + (type->sampler_shadow << 3) | + (type->sampler_array << 2) | + (type->sampled_type); + break; + case GLSL_TYPE_SUBROUTINE: + encoding = type->base_type << 24; + blob_write_uint32(blob, encoding); + blob_write_string(blob, type->name); + return; + case GLSL_TYPE_IMAGE: + encoding = (type->base_type) << 24 | + (type->sampler_dimensionality << 3) | + (type->sampler_array << 2) | + (type->sampled_type); + break; + case GLSL_TYPE_ATOMIC_UINT: + encoding = (type->base_type << 24); + break; + case GLSL_TYPE_ARRAY: + blob_write_uint32(blob, (type->base_type) << 24); + blob_write_uint32(blob, type->length); + encode_type_to_blob(blob, type->fields.array); + return; + case GLSL_TYPE_STRUCT: + case GLSL_TYPE_INTERFACE: + blob_write_uint32(blob, (type->base_type) << 24); + blob_write_string(blob, type->name); + blob_write_uint32(blob, type->length); + + size_t s_field_size, s_field_ptrs; + get_struct_type_field_and_pointer_sizes(&s_field_size, &s_field_ptrs); + + for (unsigned i = 0; i < type->length; i++) { + encode_type_to_blob(blob, type->fields.structure[i].type); + blob_write_string(blob, type->fields.structure[i].name); + + /* Write the struct field skipping the pointers */ + blob_write_bytes(blob, + ((char *)&type->fields.structure[i]) + s_field_ptrs, + s_field_size - s_field_ptrs); + } + + if (type->is_interface()) { + blob_write_uint32(blob, type->interface_packing); + blob_write_uint32(blob, type->interface_row_major); + } + return; + case GLSL_TYPE_VOID: + encoding = (type->base_type << 24); + break; + case GLSL_TYPE_ERROR: + default: + assert(!"Cannot encode type!"); + encoding = 0; + break; + } + + blob_write_uint32(blob, encoding); +} + +const glsl_type * +decode_type_from_blob(struct blob_reader *blob) +{ + uint32_t u = blob_read_uint32(blob); + + if (u == 0) { + return NULL; + } + + glsl_base_type base_type = (glsl_base_type) (u >> 24); + + switch (base_type) { + case GLSL_TYPE_UINT: + case GLSL_TYPE_INT: + case GLSL_TYPE_FLOAT: + case GLSL_TYPE_BOOL: + case GLSL_TYPE_DOUBLE: + case GLSL_TYPE_UINT64: + case GLSL_TYPE_INT64: + return glsl_type::get_instance(base_type, (u >> 4) & 0x0f, u & 0x0f); + case GLSL_TYPE_SAMPLER: + return glsl_type::get_sampler_instance((enum glsl_sampler_dim) ((u >> 4) & 0x07), + (u >> 3) & 0x01, + (u >> 2) & 0x01, + (glsl_base_type) ((u >> 0) & 0x03)); + case GLSL_TYPE_SUBROUTINE: + return glsl_type::get_subroutine_instance(blob_read_string(blob)); + case GLSL_TYPE_IMAGE: + return glsl_type::get_image_instance((enum glsl_sampler_dim) ((u >> 3) & 0x07), + (u >> 2) & 0x01, + (glsl_base_type) ((u >> 0) & 0x03)); + case GLSL_TYPE_ATOMIC_UINT: + return glsl_type::atomic_uint_type; + case GLSL_TYPE_ARRAY: { + unsigned length = blob_read_uint32(blob); + return glsl_type::get_array_instance(decode_type_from_blob(blob), + length); + } + case GLSL_TYPE_STRUCT: + case GLSL_TYPE_INTERFACE: { + char *name = blob_read_string(blob); + unsigned num_fields = blob_read_uint32(blob); + + size_t s_field_size, s_field_ptrs; + get_struct_type_field_and_pointer_sizes(&s_field_size, &s_field_ptrs); + + glsl_struct_field *fields = + (glsl_struct_field *) malloc(s_field_size * num_fields); + for (unsigned i = 0; i < num_fields; i++) { + fields[i].type = decode_type_from_blob(blob); + fields[i].name = blob_read_string(blob); + + blob_copy_bytes(blob, ((uint8_t *) &fields[i]) + s_field_ptrs, + s_field_size - s_field_ptrs); + } + + const glsl_type *t; + if (base_type == GLSL_TYPE_INTERFACE) { + enum glsl_interface_packing packing = + (glsl_interface_packing) blob_read_uint32(blob); + bool row_major = blob_read_uint32(blob); + t = glsl_type::get_interface_instance(fields, num_fields, packing, + row_major, name); + } else { + t = glsl_type::get_record_instance(fields, num_fields, name); + } + + free(fields); + return t; + } + case GLSL_TYPE_VOID: + return glsl_type::void_type; + case GLSL_TYPE_ERROR: + default: + assert(!"Cannot decode type!"); + return NULL; + } +}