X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fcompiler%2Fglsl_types.cpp;h=2213055021d9b3fbbb9714f7c9cacf543f54d84f;hb=2ade1c5cf790ab8df62e4ff9d67e360ac870ff1f;hp=2e84d6ea72c5f57334c10a5aef30811a859da011;hpb=f0920e266c152044cb05892f3aea5a17a163cc02;p=mesa.git diff --git a/src/compiler/glsl_types.cpp b/src/compiler/glsl_types.cpp index 2e84d6ea72c..2213055021d 100644 --- a/src/compiler/glsl_types.cpp +++ b/src/compiler/glsl_types.cpp @@ -246,7 +246,7 @@ glsl_type::contains_integer() const } return false; } else { - return glsl_base_type_is_integer(this->base_type); + return this->is_integer(); } } @@ -486,7 +486,6 @@ void glsl_type_singleton_decref() { mtx_lock(&glsl_type::hash_mutex); - assert(glsl_type_users > 0); /* Do not release glsl_types if they are still used. */ @@ -557,7 +556,7 @@ glsl_type::glsl_type(const glsl_type *array, unsigned length, char *const n = (char *) ralloc_size(this->mem_ctx, name_length); if (length == 0) - util_snprintf(n, name_length, "%s[]", array->name); + snprintf(n, name_length, "%s[]", array->name); else { /* insert outermost dimensions in the correct spot * otherwise the dimension order will be backwards @@ -565,11 +564,11 @@ glsl_type::glsl_type(const glsl_type *array, unsigned length, const char *pos = strchr(array->name, '['); if (pos) { int idx = pos - array->name; - util_snprintf(n, idx+1, "%s", array->name); - util_snprintf(n + idx, name_length - idx, "[%u]%s", + snprintf(n, idx+1, "%s", array->name); + snprintf(n + idx, name_length - idx, "[%u]%s", length, array->name + idx); } else { - util_snprintf(n, name_length, "%s[%u]", array->name, length); + snprintf(n, name_length, "%s[%u]", array->name, length); } } @@ -635,10 +634,11 @@ glsl_type::get_instance(unsigned base_type, unsigned rows, unsigned columns, assert(columns > 1 || !row_major); char name[128]; - util_snprintf(name, sizeof(name), "%sx%uB%s", bare_type->name, - explicit_stride, row_major ? "RM" : ""); + snprintf(name, sizeof(name), "%sx%uB%s", bare_type->name, + explicit_stride, row_major ? "RM" : ""); mtx_lock(&glsl_type::hash_mutex); + assert(glsl_type_users > 0); if (explicit_matrix_types == NULL) { explicit_matrix_types = @@ -1000,10 +1000,11 @@ glsl_type::get_array_instance(const glsl_type *base, * named 'foo'. */ char key[128]; - util_snprintf(key, sizeof(key), "%p[%u]x%uB", (void *) base, array_size, - explicit_stride); + snprintf(key, sizeof(key), "%p[%u]x%uB", (void *) base, array_size, + explicit_stride); mtx_lock(&glsl_type::hash_mutex); + assert(glsl_type_users > 0); if (array_types == NULL) { array_types = _mesa_hash_table_create(NULL, _mesa_key_hash_string, @@ -1204,6 +1205,7 @@ glsl_type::get_struct_instance(const glsl_struct_field *fields, const glsl_type key(fields, num_fields, name, packed); mtx_lock(&glsl_type::hash_mutex); + assert(glsl_type_users > 0); if (struct_types == NULL) { struct_types = _mesa_hash_table_create(NULL, record_key_hash, @@ -1239,6 +1241,7 @@ glsl_type::get_interface_instance(const glsl_struct_field *fields, const glsl_type key(fields, num_fields, packing, row_major, block_name); mtx_lock(&glsl_type::hash_mutex); + assert(glsl_type_users > 0); if (interface_types == NULL) { interface_types = _mesa_hash_table_create(NULL, record_key_hash, @@ -1269,6 +1272,7 @@ glsl_type::get_subroutine_instance(const char *subroutine_name) const glsl_type key(subroutine_name); mtx_lock(&glsl_type::hash_mutex); + assert(glsl_type_users > 0); if (subroutine_types == NULL) { subroutine_types = _mesa_hash_table_create(NULL, record_key_hash, @@ -1322,6 +1326,7 @@ glsl_type::get_function_instance(const glsl_type *return_type, const glsl_type key(return_type, params, num_params); mtx_lock(&glsl_type::hash_mutex); + assert(glsl_type_users > 0); if (function_types == NULL) { function_types = _mesa_hash_table_create(NULL, function_key_hash, @@ -2124,6 +2129,74 @@ glsl_type::std430_array_stride(bool row_major) const return stride; } +/* Note that the value returned by this method is only correct if the + * explit offset, and stride values are set, so only with SPIR-V shaders. + * Should not be used with GLSL shaders. + */ + +unsigned +glsl_type::explicit_size(bool align_to_stride) const +{ + if (this->is_struct() || this->is_interface()) { + if (this->length > 0) { + unsigned size = 0; + + for (unsigned i = 0; i < this->length; i++) { + assert(this->fields.structure[i].offset >= 0); + unsigned last_byte = this->fields.structure[i].offset + + this->fields.structure[i].type->explicit_size(); + size = MAX2(size, last_byte); + } + + return size; + } else { + return 0; + } + } else if (this->is_array()) { + /* From ARB_program_interface_query spec: + * + * "For the property of BUFFER_DATA_SIZE, then the implementation-dependent + * minimum total buffer object size, in basic machine units, required to + * hold all active variables associated with an active uniform block, shader + * storage block, or atomic counter buffer is written to . If the + * final member of an active shader storage block is array with no declared + * size, the minimum buffer size is computed assuming the array was declared + * as an array with one element." + * + */ + if (this->is_unsized_array()) + return this->explicit_stride; + + assert(this->length > 0); + unsigned elem_size = align_to_stride ? this->explicit_stride : this->fields.array->explicit_size(); + assert(this->explicit_stride >= elem_size); + + return this->explicit_stride * (this->length - 1) + elem_size; + } else if (this->is_matrix()) { + const struct glsl_type *elem_type; + unsigned length; + + if (this->interface_row_major) { + elem_type = get_instance(this->base_type, + this->matrix_columns, 1); + length = this->vector_elements; + } else { + elem_type = get_instance(this->base_type, + this->vector_elements, 1); + length = this->matrix_columns; + } + + unsigned elem_size = align_to_stride ? this->explicit_stride : elem_type->explicit_size(); + + assert(this->explicit_stride); + return this->explicit_stride * (length - 1) + elem_size; + } + + unsigned N = this->bit_size() / 8; + + return this->vector_elements * N; +} + unsigned glsl_type::std430_size(bool row_major) const { @@ -2297,6 +2370,67 @@ glsl_type::get_explicit_interface_type(bool supports_std430) const } } +/* This differs from get_explicit_std430_type() in that it: + * - can size arrays slightly smaller ("stride * (len - 1) + elem_size" instead + * of "stride * len") + * - consumes a glsl_type_size_align_func which allows 8 and 16-bit values to be + * packed more tightly + * - overrides any struct field offsets but get_explicit_std430_type() tries to + * respect any existing ones + */ +const glsl_type * +glsl_type::get_explicit_type_for_size_align(glsl_type_size_align_func type_info, + unsigned *size, unsigned *alignment) const +{ + if (this->is_scalar() || this->is_vector()) { + type_info(this, size, alignment); + return this; + } else if (this->is_array()) { + unsigned elem_size, elem_align; + const struct glsl_type *explicit_element = + this->fields.array->get_explicit_type_for_size_align(type_info, &elem_size, &elem_align); + + unsigned stride = align(elem_size, elem_align); + + *size = stride * (this->length - 1) + elem_size; + *alignment = elem_align; + return glsl_type::get_array_instance(explicit_element, this->length, stride); + } else if (this->is_struct()) { + struct glsl_struct_field *fields = (struct glsl_struct_field *) + malloc(sizeof(struct glsl_struct_field) * this->length); + + *size = 0; + *alignment = 0; + for (unsigned i = 0; i < this->length; i++) { + fields[i] = this->fields.structure[i]; + assert(fields[i].matrix_layout != GLSL_MATRIX_LAYOUT_ROW_MAJOR); + + unsigned field_size, field_align; + fields[i].type = + fields[i].type->get_explicit_type_for_size_align(type_info, &field_size, &field_align); + fields[i].offset = align(*size, field_align); + + *size = fields[i].offset + field_size; + *alignment = MAX2(*alignment, field_align); + } + + const glsl_type *type = glsl_type::get_struct_instance(fields, this->length, this->name, false); + free(fields); + return type; + } else if (this->is_matrix()) { + unsigned col_size, col_align; + type_info(this->column_type(), &col_size, &col_align); + unsigned stride = align(col_size, col_align); + + *size = this->matrix_columns * stride; + *alignment = col_align; + return glsl_type::get_instance(this->base_type, this->vector_elements, + this->matrix_columns, stride, false); + } else { + unreachable("Unhandled type."); + } +} + unsigned glsl_type::count_attribute_slots(bool is_gl_vertex_input) const {