From: Jason Ekstrand Date: Wed, 12 Dec 2018 20:32:19 +0000 (-0600) Subject: glsl_type: Add support for explicitly laid out matrices and arrays X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=6cebeb4f71918aded1ddade5727f79fae83780fd;p=mesa.git glsl_type: Add support for explicitly laid out matrices and arrays SPIR-V allows for matrix and array types to be decorated with explicit byte stride decorations and matrix types to be decorated row- or column-major. This commit adds support to glsl_type to encode this information. Because this doesn't work nicely with std430 and std140 alignments, we add asserts to ensure that we don't use any of the std430 or std140 layout functions with explicitly laid out types. In SPIR-V, the layout information for matrices is applied to the parent struct member instead of to the matrix type itself. However, this is gets rather clumsy when you're walking derefs trying to compute offsets because, the moment you hit a matrix, you have to crawl back the deref chain and find the struct. Instead, we take the same path here as we've taken in spirv_to_nir and put the decorations on the matrix type itself. This also subtly adds support for strided vector types. These don't come up in SPIR-V directly but you can get one as the result of taking a column from a row-major matrix or a row from a column-major matrix. Reviewed-by: Alejandro PiƱeiro --- diff --git a/src/compiler/glsl/gl_nir_lower_samplers_as_deref.c b/src/compiler/glsl/gl_nir_lower_samplers_as_deref.c index f3f2dd22df2..96c751a1284 100644 --- a/src/compiler/glsl/gl_nir_lower_samplers_as_deref.c +++ b/src/compiler/glsl/gl_nir_lower_samplers_as_deref.c @@ -99,7 +99,7 @@ remove_struct_derefs_prep(nir_deref_instr **p, char **name, remove_struct_derefs_prep(&p[1], name, location, type); - *type = glsl_array_type(*type, length); + *type = glsl_array_type(*type, length, glsl_get_explicit_stride(cur->type)); break; } diff --git a/src/compiler/glsl_types.cpp b/src/compiler/glsl_types.cpp index 67f3967d0c1..00be0e00a9e 100644 --- a/src/compiler/glsl_types.cpp +++ b/src/compiler/glsl_types.cpp @@ -30,6 +30,7 @@ mtx_t glsl_type::hash_mutex = _MTX_INITIALIZER_NP; +hash_table *glsl_type::explicit_matrix_types = NULL; hash_table *glsl_type::array_types = NULL; hash_table *glsl_type::record_types = NULL; hash_table *glsl_type::interface_types = NULL; @@ -38,13 +39,14 @@ hash_table *glsl_type::subroutine_types = NULL; glsl_type::glsl_type(GLenum gl_type, glsl_base_type base_type, unsigned vector_elements, - unsigned matrix_columns, const char *name) : + unsigned matrix_columns, const char *name, + unsigned explicit_stride, bool row_major) : gl_type(gl_type), base_type(base_type), sampled_type(GLSL_TYPE_VOID), sampler_dimensionality(0), sampler_shadow(0), sampler_array(0), - interface_packing(0), interface_row_major(0), + interface_packing(0), interface_row_major(row_major), vector_elements(vector_elements), matrix_columns(matrix_columns), - length(0) + length(0), explicit_stride(explicit_stride) { /* Values of these types must fit in the two bits of * glsl_type::sampled_type. @@ -77,7 +79,8 @@ glsl_type::glsl_type(GLenum gl_type, glsl_base_type base_type, base_type(base_type), sampled_type(type), sampler_dimensionality(dim), sampler_shadow(shadow), sampler_array(array), interface_packing(0), - interface_row_major(0), length(0) + interface_row_major(0), + length(0), explicit_stride(0) { this->mem_ctx = ralloc_context(NULL); assert(this->mem_ctx != NULL); @@ -97,7 +100,7 @@ glsl_type::glsl_type(const glsl_struct_field *fields, unsigned num_fields, sampler_dimensionality(0), sampler_shadow(0), sampler_array(0), interface_packing(0), interface_row_major(0), vector_elements(0), matrix_columns(0), - length(num_fields) + length(num_fields), explicit_stride(0) { unsigned int i; @@ -127,7 +130,7 @@ glsl_type::glsl_type(const glsl_struct_field *fields, unsigned num_fields, interface_packing((unsigned) packing), interface_row_major((unsigned) row_major), vector_elements(0), matrix_columns(0), - length(num_fields) + length(num_fields), explicit_stride(0) { unsigned int i; @@ -152,7 +155,7 @@ glsl_type::glsl_type(const glsl_type *return_type, sampler_dimensionality(0), sampler_shadow(0), sampler_array(0), interface_packing(0), interface_row_major(0), vector_elements(0), matrix_columns(0), - length(num_params) + length(num_params), explicit_stride(0) { unsigned int i; @@ -181,7 +184,7 @@ glsl_type::glsl_type(const char *subroutine_name) : sampler_dimensionality(0), sampler_shadow(0), sampler_array(0), interface_packing(0), interface_row_major(0), vector_elements(1), matrix_columns(1), - length(0) + length(0), explicit_stride(0) { this->mem_ctx = ralloc_context(NULL); assert(this->mem_ctx != NULL); @@ -389,6 +392,55 @@ const glsl_type *glsl_type::get_scalar_type() const } +const glsl_type *glsl_type::get_bare_type() const +{ + switch (this->base_type) { + case GLSL_TYPE_UINT8: + case GLSL_TYPE_INT8: + case GLSL_TYPE_UINT16: + case GLSL_TYPE_INT16: + case GLSL_TYPE_FLOAT16: + 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 get_instance(this->base_type, this->vector_elements, + this->matrix_columns); + + case GLSL_TYPE_STRUCT: + case GLSL_TYPE_INTERFACE: { + glsl_struct_field *bare_fields = new glsl_struct_field[this->length]; + for (unsigned i = 0; i < this->length; i++) { + bare_fields[i].type = this->fields.structure[i].type->get_bare_type(); + bare_fields[i].name = this->fields.structure[i].name; + } + const glsl_type *bare_type = + get_record_instance(bare_fields, this->length, this->name); + delete[] bare_fields; + return bare_type; + } + + case GLSL_TYPE_ARRAY: + return get_array_instance(this->fields.array->get_bare_type(), + this->length); + + case GLSL_TYPE_SAMPLER: + case GLSL_TYPE_IMAGE: + case GLSL_TYPE_ATOMIC_UINT: + case GLSL_TYPE_VOID: + case GLSL_TYPE_SUBROUTINE: + case GLSL_TYPE_FUNCTION: + case GLSL_TYPE_ERROR: + return this; + } + + unreachable("Invalid base type"); +} + + static void hash_free_type_function(struct hash_entry *entry) { @@ -407,6 +459,12 @@ _mesa_glsl_release_types(void) * object, or if process terminates), so no mutex-locking should be * necessary. */ + if (glsl_type::explicit_matrix_types != NULL) { + _mesa_hash_table_destroy(glsl_type::explicit_matrix_types, + hash_free_type_function); + glsl_type::explicit_matrix_types = NULL; + } + if (glsl_type::array_types != NULL) { _mesa_hash_table_destroy(glsl_type::array_types, hash_free_type_function); glsl_type::array_types = NULL; @@ -434,12 +492,13 @@ _mesa_glsl_release_types(void) } -glsl_type::glsl_type(const glsl_type *array, unsigned length) : +glsl_type::glsl_type(const glsl_type *array, unsigned length, + unsigned explicit_stride) : base_type(GLSL_TYPE_ARRAY), sampled_type(GLSL_TYPE_VOID), sampler_dimensionality(0), sampler_shadow(0), sampler_array(0), interface_packing(0), interface_row_major(0), vector_elements(0), matrix_columns(0), - length(length), name(NULL) + length(length), name(NULL), explicit_stride(explicit_stride) { this->fields.array = array; /* Inherit the gl type of the base. The GL type is used for @@ -521,10 +580,57 @@ VECN(components, int8_t, i8vec) VECN(components, uint8_t, u8vec) const glsl_type * -glsl_type::get_instance(unsigned base_type, unsigned rows, unsigned columns) +glsl_type::get_instance(unsigned base_type, unsigned rows, unsigned columns, + unsigned explicit_stride, bool row_major) { - if (base_type == GLSL_TYPE_VOID) + if (base_type == GLSL_TYPE_VOID) { + assert(explicit_stride == 0 && !row_major); return void_type; + } + + /* Matrix and vector types with explicit strides have to be looked up in a + * table so they're handled separately. + */ + if (explicit_stride > 0) { + const glsl_type *bare_type = get_instance(base_type, rows, 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" : ""); + + mtx_lock(&glsl_type::hash_mutex); + + if (explicit_matrix_types == NULL) { + explicit_matrix_types = + _mesa_hash_table_create(NULL, _mesa_key_hash_string, + _mesa_key_string_equal); + } + + const struct hash_entry *entry = + _mesa_hash_table_search(explicit_matrix_types, name); + if (entry == NULL) { + const glsl_type *t = new glsl_type(bare_type->gl_type, + (glsl_base_type)base_type, + rows, columns, name, + explicit_stride, row_major); + + entry = _mesa_hash_table_insert(explicit_matrix_types, + t->name, (void *)t); + } + + assert(((glsl_type *) entry->data)->base_type == base_type); + assert(((glsl_type *) entry->data)->vector_elements == rows); + assert(((glsl_type *) entry->data)->matrix_columns == columns); + assert(((glsl_type *) entry->data)->explicit_stride == explicit_stride); + + mtx_unlock(&glsl_type::hash_mutex); + + return (const glsl_type *) entry->data; + } + + assert(!row_major); /* Treat GLSL vectors as Nx1 matrices. */ @@ -846,7 +952,9 @@ glsl_type::get_image_instance(enum glsl_sampler_dim dim, } const glsl_type * -glsl_type::get_array_instance(const glsl_type *base, unsigned array_size) +glsl_type::get_array_instance(const glsl_type *base, + unsigned array_size, + unsigned explicit_stride) { /* Generate a name using the base type pointer in the key. This is * done because the name of the base type may not be unique across @@ -854,7 +962,8 @@ glsl_type::get_array_instance(const glsl_type *base, unsigned array_size) * named 'foo'. */ char key[128]; - util_snprintf(key, sizeof(key), "%p[%u]", (void *) base, array_size); + util_snprintf(key, sizeof(key), "%p[%u]x%uB", (void *) base, array_size, + explicit_stride); mtx_lock(&glsl_type::hash_mutex); @@ -865,7 +974,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) { - const glsl_type *t = new glsl_type(base, array_size); + const glsl_type *t = new glsl_type(base, array_size, explicit_stride); entry = _mesa_hash_table_insert(array_types, strdup(key), @@ -1599,6 +1708,7 @@ glsl_type::std140_size(bool row_major) const * basic machine units, the base alignment is 4. */ if (this->is_scalar() || this->is_vector()) { + assert(this->explicit_stride == 0); return this->vector_elements * N; } @@ -1633,6 +1743,8 @@ glsl_type::std140_size(bool row_major) const array_len = 1; } + assert(element_type->explicit_stride == 0); + if (row_major) { vec_type = get_instance(element_type->base_type, element_type->matrix_columns, 1); @@ -1660,6 +1772,7 @@ glsl_type::std140_size(bool row_major) const * the array are laid out in order, according to rule (9). */ if (this->is_array()) { + assert(this->explicit_stride == 0); if (this->without_array()->is_record()) { return this->arrays_of_arrays_size() * this->without_array()->std140_size(row_major); @@ -1834,6 +1947,8 @@ glsl_type::std430_array_stride(bool row_major) const { unsigned N = is_64bit() ? 8 : 4; + assert(explicit_stride == 0); + /* 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" * @@ -1860,8 +1975,10 @@ glsl_type::std430_size(bool row_major) const * stride of arrays of scalars and vectors in rule 4 and of structures * in rule 9 are not rounded up a multiple of the base alignment of a vec4. */ - if (this->is_scalar() || this->is_vector()) - return this->vector_elements * N; + if (this->is_scalar() || this->is_vector()) { + assert(this->explicit_stride == 0); + return this->vector_elements * N; + } if (this->without_array()->is_matrix()) { const struct glsl_type *element_type; @@ -1876,6 +1993,8 @@ glsl_type::std430_size(bool row_major) const array_len = 1; } + assert(element_type->explicit_stride == 0); + if (row_major) { vec_type = get_instance(element_type->base_type, element_type->matrix_columns, 1); @@ -1893,6 +2012,7 @@ glsl_type::std430_size(bool row_major) const } if (this->is_array()) { + assert(this->explicit_stride == 0); if (this->without_array()->is_record()) return this->arrays_of_arrays_size() * this->without_array()->std430_size(row_major); @@ -2092,9 +2212,12 @@ encode_type_to_blob(struct blob *blob, const glsl_type *type) case GLSL_TYPE_INT64: case GLSL_TYPE_BOOL: encoding = (type->base_type << 24) | + (type->interface_row_major << 10) | (type->vector_elements << 4) | (type->matrix_columns); - break; + blob_write_uint32(blob, encoding); + blob_write_uint32(blob, type->explicit_stride); + return; case GLSL_TYPE_SAMPLER: encoding = (type->base_type) << 24 | (type->sampler_dimensionality << 4) | @@ -2119,6 +2242,7 @@ encode_type_to_blob(struct blob *blob, const glsl_type *type) case GLSL_TYPE_ARRAY: blob_write_uint32(blob, (type->base_type) << 24); blob_write_uint32(blob, type->length); + blob_write_uint32(blob, type->explicit_stride); encode_type_to_blob(blob, type->fields.array); return; case GLSL_TYPE_STRUCT: @@ -2181,8 +2305,11 @@ decode_type_from_blob(struct blob_reader *blob) case GLSL_TYPE_INT16: case GLSL_TYPE_UINT64: case GLSL_TYPE_INT64: - case GLSL_TYPE_BOOL: - return glsl_type::get_instance(base_type, (u >> 4) & 0x0f, u & 0x0f); + case GLSL_TYPE_BOOL: { + unsigned explicit_stride = blob_read_uint32(blob); + return glsl_type::get_instance(base_type, (u >> 4) & 0x0f, u & 0x0f, + explicit_stride, (u >> 10) & 0x1); + } case GLSL_TYPE_SAMPLER: return glsl_type::get_sampler_instance((enum glsl_sampler_dim) ((u >> 4) & 0x07), (u >> 3) & 0x01, @@ -2198,8 +2325,9 @@ decode_type_from_blob(struct blob_reader *blob) return glsl_type::atomic_uint_type; case GLSL_TYPE_ARRAY: { unsigned length = blob_read_uint32(blob); + unsigned explicit_stride = blob_read_uint32(blob); return glsl_type::get_array_instance(decode_type_from_blob(blob), - length); + length, explicit_stride); } case GLSL_TYPE_STRUCT: case GLSL_TYPE_INTERFACE: { diff --git a/src/compiler/glsl_types.h b/src/compiler/glsl_types.h index d32b580acc1..4d205fad141 100644 --- a/src/compiler/glsl_types.h +++ b/src/compiler/glsl_types.h @@ -209,6 +209,13 @@ public: */ const char *name; + /** + * Explicit array, matrix, or vector stride. This is used to communicate + * explicit array layouts from SPIR-V. Should be 0 if the type has no + * explicit stride. + */ + unsigned explicit_stride; + /** * Subtype of composite data types. */ @@ -271,11 +278,18 @@ public: */ const glsl_type *get_scalar_type() const; + /** + * Gets the "bare" type without any decorations or layout information. + */ + const glsl_type *get_bare_type() const; + /** * Get the instance of a built-in scalar, vector, or matrix type */ static const glsl_type *get_instance(unsigned base_type, unsigned rows, - unsigned columns); + unsigned columns, + unsigned explicit_stride = 0, + bool row_major = false); /** * Get the instance of a sampler type @@ -292,7 +306,8 @@ public: * Get the instance of an array type */ static const glsl_type *get_array_instance(const glsl_type *base, - unsigned elements); + unsigned elements, + unsigned explicit_stride = 0); /** * Get the instance of a record type @@ -752,9 +767,13 @@ public: */ const glsl_type *row_type() const { - return is_matrix() - ? get_instance(base_type, matrix_columns, 1) - : error_type; + if (!is_matrix()) + return error_type; + + if (explicit_stride && !interface_row_major) + return get_instance(base_type, matrix_columns, 1, explicit_stride); + else + return get_instance(base_type, matrix_columns, 1); } /** @@ -766,9 +785,13 @@ public: */ const glsl_type *column_type() const { - return is_matrix() - ? get_instance(base_type, vector_elements, 1) - : error_type; + if (!is_matrix()) + return error_type; + + if (explicit_stride && interface_row_major) + return get_instance(base_type, vector_elements, 1, explicit_stride); + else + return get_instance(base_type, vector_elements, 1); } /** @@ -878,8 +901,9 @@ private: /** Constructor for vector and matrix types */ glsl_type(GLenum gl_type, - glsl_base_type base_type, unsigned vector_elements, - unsigned matrix_columns, const char *name); + glsl_base_type base_type, unsigned vector_elements, + unsigned matrix_columns, const char *name, + unsigned explicit_stride = 0, bool row_major = false); /** Constructor for sampler or image types */ glsl_type(GLenum gl_type, glsl_base_type base_type, @@ -899,12 +923,15 @@ private: 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); + /** Constructors for array types */ + glsl_type(const glsl_type *array, unsigned length, unsigned explicit_stride); /** Constructor for subroutine types */ glsl_type(const char *name); + /** Hash table containing the known explicit matrix and vector types. */ + static struct hash_table *explicit_matrix_types; + /** Hash table containing the known array types. */ static struct hash_table *array_types; diff --git a/src/compiler/nir/nir_lower_atomics_to_ssbo.c b/src/compiler/nir/nir_lower_atomics_to_ssbo.c index d9acc5c3a79..ffa03dc27f8 100644 --- a/src/compiler/nir/nir_lower_atomics_to_ssbo.c +++ b/src/compiler/nir/nir_lower_atomics_to_ssbo.c @@ -219,7 +219,7 @@ nir_lower_atomics_to_ssbo(nir_shader *shader, unsigned ssbo_offset) char name[16]; /* A length of 0 is used to denote unsized arrays */ - const struct glsl_type *type = glsl_array_type(glsl_uint_type(), 0); + const struct glsl_type *type = glsl_array_type(glsl_uint_type(), 0, 0); snprintf(name, sizeof(name), "counter%d", var->data.binding); diff --git a/src/compiler/nir/nir_lower_clip_cull_distance_arrays.c b/src/compiler/nir/nir_lower_clip_cull_distance_arrays.c index 2afbf9285c0..6e1557ef40d 100644 --- a/src/compiler/nir/nir_lower_clip_cull_distance_arrays.c +++ b/src/compiler/nir/nir_lower_clip_cull_distance_arrays.c @@ -62,10 +62,10 @@ get_unwrapped_array_length(nir_shader *nir, nir_variable *var) static void update_type(nir_variable *var, gl_shader_stage stage, unsigned length) { - const struct glsl_type *type = glsl_array_type(glsl_float_type(), length); + const struct glsl_type *type = glsl_array_type(glsl_float_type(), length, 0); if (nir_is_per_vertex_io(var, stage)) - type = glsl_array_type(type, glsl_get_length(var->type)); + type = glsl_array_type(type, glsl_get_length(var->type), 0); var->type = type; } diff --git a/src/compiler/nir/nir_lower_io_arrays_to_elements.c b/src/compiler/nir/nir_lower_io_arrays_to_elements.c index 30d53f156ff..34020249199 100644 --- a/src/compiler/nir/nir_lower_io_arrays_to_elements.c +++ b/src/compiler/nir/nir_lower_io_arrays_to_elements.c @@ -127,13 +127,12 @@ lower_array(nir_builder *b, nir_intrinsic_instr *intr, nir_variable *var, const struct glsl_type *type = glsl_without_array(element->type); /* This pass also splits matrices so we need give them a new type. */ - if (glsl_type_is_matrix(type)) { - type = glsl_vector_type(glsl_get_base_type(type), - glsl_get_vector_elements(type)); - } + if (glsl_type_is_matrix(type)) + type = glsl_get_column_type(type); if (nir_is_per_vertex_io(var, b->shader->info.stage)) { - type = glsl_array_type(type, glsl_get_length(element->type)); + type = glsl_array_type(type, glsl_get_length(element->type), + glsl_get_explicit_stride(element->type)); } element->type = type; diff --git a/src/compiler/nir/nir_split_per_member_structs.c b/src/compiler/nir/nir_split_per_member_structs.c index f649c8f474b..c1234c2e92a 100644 --- a/src/compiler/nir/nir_split_per_member_structs.c +++ b/src/compiler/nir/nir_split_per_member_structs.c @@ -50,7 +50,8 @@ member_type(const struct glsl_type *type, unsigned index) if (glsl_type_is_array(type)) { const struct glsl_type *elem = member_type(glsl_get_array_element(type), index); - return glsl_array_type(elem, glsl_get_length(type)); + assert(glsl_get_explicit_stride(type) == 0); + return glsl_array_type(elem, glsl_get_length(type), 0); } else { assert(glsl_type_is_struct(type)); assert(index < glsl_get_length(type)); diff --git a/src/compiler/nir/nir_split_vars.c b/src/compiler/nir/nir_split_vars.c index bf9205c5150..e738ee3f385 100644 --- a/src/compiler/nir/nir_split_vars.c +++ b/src/compiler/nir/nir_split_vars.c @@ -58,7 +58,8 @@ wrap_type_in_array(const struct glsl_type *type, const struct glsl_type *elem_type = wrap_type_in_array(type, glsl_get_array_element(array_type)); - return glsl_array_type(elem_type, glsl_get_length(array_type)); + assert(glsl_get_explicit_stride(array_type) == 0); + return glsl_array_type(elem_type, glsl_get_length(array_type), 0); } static int @@ -341,6 +342,7 @@ init_var_list_array_infos(struct exec_list *vars, const struct glsl_type *type = var->type; for (int i = 0; i < num_levels; i++) { + assert(glsl_get_explicit_stride(type) == 0); info->levels[i].array_len = glsl_get_length(type); type = glsl_get_array_element(type); @@ -506,7 +508,7 @@ split_var_list_arrays(nir_shader *shader, glsl_get_components(split_type), info->levels[i].array_len); } else { - split_type = glsl_array_type(split_type, info->levels[i].array_len); + split_type = glsl_array_type(split_type, info->levels[i].array_len, 0); } } @@ -918,6 +920,7 @@ get_vec_var_usage(nir_variable *var, const struct glsl_type *type = var->type; for (unsigned i = 0; i < num_levels; i++) { usage->levels[i].array_len = glsl_get_length(type); + assert(glsl_get_explicit_stride(type) == 0); type = glsl_get_array_element(type); } assert(glsl_type_is_vector_or_scalar(type)); @@ -1290,7 +1293,7 @@ shrink_vec_var_list(struct exec_list *vars, new_num_comps, usage->levels[i].array_len); } else { - new_type = glsl_array_type(new_type, usage->levels[i].array_len); + new_type = glsl_array_type(new_type, usage->levels[i].array_len, 0); } } var->type = new_type; diff --git a/src/compiler/nir_types.cpp b/src/compiler/nir_types.cpp index 2b4ff0702f2..356252276b4 100644 --- a/src/compiler/nir_types.cpp +++ b/src/compiler/nir_types.cpp @@ -59,6 +59,12 @@ glsl_without_array_or_matrix(const glsl_type *type) return type; } +const glsl_type * +glsl_get_bare_type(const glsl_type *type) +{ + return type->get_bare_type(); +} + const glsl_type * glsl_get_struct_field(const glsl_type *type, unsigned index) { @@ -72,6 +78,12 @@ glsl_get_struct_field_offset(const struct glsl_type *type, return type->fields.structure[index].offset; } +const unsigned +glsl_get_explicit_stride(const struct glsl_type *type) +{ + return type->explicit_stride; +} + const glsl_type * glsl_get_function_return_type(const glsl_type *type) { @@ -234,6 +246,13 @@ glsl_type_is_matrix(const struct glsl_type *type) return type->is_matrix(); } +bool +glsl_matrix_type_is_row_major(const struct glsl_type *type) +{ + assert(type->is_matrix() && type->explicit_stride); + return type->interface_row_major; +} + bool glsl_type_is_array(const struct glsl_type *type) { @@ -432,9 +451,23 @@ glsl_matrix_type(enum glsl_base_type base_type, unsigned rows, unsigned columns) } const glsl_type * -glsl_array_type(const glsl_type *base, unsigned elements) +glsl_explicit_matrix_type(const glsl_type *mat, + unsigned stride, bool row_major) +{ + assert(stride > 0); + const glsl_type *t = glsl_type::get_instance(mat->base_type, + mat->vector_elements, + mat->matrix_columns, + stride, row_major); + assert(t != glsl_type::error_type); + return t; +} + +const glsl_type * +glsl_array_type(const glsl_type *base, unsigned elements, + unsigned explicit_stride) { - return glsl_type::get_array_instance(base, elements); + return glsl_type::get_array_instance(base, elements, explicit_stride); } const glsl_type * @@ -495,7 +528,8 @@ glsl_channel_type(const glsl_type *t) { switch (t->base_type) { case GLSL_TYPE_ARRAY: - return glsl_array_type(glsl_channel_type(t->fields.array), t->length); + return glsl_array_type(glsl_channel_type(t->fields.array), t->length, + t->explicit_stride); case GLSL_TYPE_UINT: case GLSL_TYPE_INT: case GLSL_TYPE_FLOAT: diff --git a/src/compiler/nir_types.h b/src/compiler/nir_types.h index 6e671b4cc71..d17671b9400 100644 --- a/src/compiler/nir_types.h +++ b/src/compiler/nir_types.h @@ -49,9 +49,11 @@ const struct glsl_type *glsl_get_struct_field(const struct glsl_type *type, const int glsl_get_struct_field_offset(const struct glsl_type *type, unsigned index); +const unsigned glsl_get_explicit_stride(const struct glsl_type *type); const struct glsl_type *glsl_get_array_element(const struct glsl_type *type); const struct glsl_type *glsl_without_array(const struct glsl_type *type); const struct glsl_type *glsl_without_array_or_matrix(const struct glsl_type *type); +const struct glsl_type *glsl_get_bare_type(const struct glsl_type *type); const struct glsl_type *glsl_get_column_type(const struct glsl_type *type); @@ -136,6 +138,7 @@ bool glsl_type_is_vector(const struct glsl_type *type); bool glsl_type_is_scalar(const struct glsl_type *type); bool glsl_type_is_vector_or_scalar(const struct glsl_type *type); bool glsl_type_is_matrix(const struct glsl_type *type); +bool glsl_matrix_type_is_row_major(const struct glsl_type *type); bool glsl_type_is_array(const struct glsl_type *type); bool glsl_type_is_array_of_arrays(const struct glsl_type *type); bool glsl_type_is_array_or_matrix(const struct glsl_type *type); @@ -173,8 +176,14 @@ const struct glsl_type *glsl_vector_type(enum glsl_base_type base_type, unsigned components); const struct glsl_type *glsl_matrix_type(enum glsl_base_type base_type, unsigned rows, unsigned columns); +const struct glsl_type *glsl_explicit_matrix_type(const struct glsl_type *mat, + unsigned stride, + bool row_major); + const struct glsl_type *glsl_array_type(const struct glsl_type *base, - unsigned elements); + unsigned elements, + unsigned explicit_stride); + const struct glsl_type *glsl_struct_type(const struct glsl_struct_field *fields, unsigned num_fields, const char *name); const struct glsl_type *glsl_interface_type(const struct glsl_struct_field *fields, diff --git a/src/compiler/spirv/spirv_to_nir.c b/src/compiler/spirv/spirv_to_nir.c index 341a1cb17ce..a9fd543e12f 100644 --- a/src/compiler/spirv/spirv_to_nir.c +++ b/src/compiler/spirv/spirv_to_nir.c @@ -1145,7 +1145,7 @@ vtn_handle_type(struct vtn_builder *b, SpvOp opcode, } val->type->base_type = vtn_base_type_array; - val->type->type = glsl_array_type(array_element->type, val->type->length); + val->type->type = glsl_array_type(array_element->type, val->type->length, 0); val->type->array_element = array_element; val->type->stride = 0; break; diff --git a/src/compiler/spirv/vtn_variables.c b/src/compiler/spirv/vtn_variables.c index f33eb5509a0..fb497fc2d06 100644 --- a/src/compiler/spirv/vtn_variables.c +++ b/src/compiler/spirv/vtn_variables.c @@ -389,7 +389,8 @@ repair_atomic_type(const struct glsl_type *type) const struct glsl_type *atomic = repair_atomic_type(glsl_get_array_element(type)); - return glsl_array_type(atomic, glsl_get_length(type)); + return glsl_array_type(atomic, glsl_get_length(type), + glsl_get_explicit_stride(type)); } else { return glsl_atomic_uint_type(); } diff --git a/src/gallium/auxiliary/nir/tgsi_to_nir.c b/src/gallium/auxiliary/nir/tgsi_to_nir.c index e1ef7bca7cc..0f365d9ebe0 100644 --- a/src/gallium/auxiliary/nir/tgsi_to_nir.c +++ b/src/gallium/auxiliary/nir/tgsi_to_nir.c @@ -181,7 +181,7 @@ ttn_emit_declaration(struct ttn_compile *c) /* for arrays, we create variables instead of registers: */ nir_variable *var = rzalloc(b->shader, nir_variable); - var->type = glsl_array_type(glsl_vec4_type(), array_size); + var->type = glsl_array_type(glsl_vec4_type(), array_size, 0); var->data.mode = nir_var_global; var->name = ralloc_asprintf(var, "arr_%d", decl->Array.ArrayID); @@ -265,7 +265,7 @@ ttn_emit_declaration(struct ttn_compile *c) var->type = glsl_vec4_type(); if (is_array) - var->type = glsl_array_type(var->type, array_size); + var->type = glsl_array_type(var->type, array_size, 0); switch (file) { case TGSI_FILE_INPUT: diff --git a/src/intel/vulkan/anv_nir_lower_multiview.c b/src/intel/vulkan/anv_nir_lower_multiview.c index 498be05b7ba..c42d9c2dfa2 100644 --- a/src/intel/vulkan/anv_nir_lower_multiview.c +++ b/src/intel/vulkan/anv_nir_lower_multiview.c @@ -125,7 +125,7 @@ build_view_index(struct lower_multiview_state *state) const struct glsl_type *type = glsl_int_type(); if (b->shader->info.stage == MESA_SHADER_TESS_CTRL || b->shader->info.stage == MESA_SHADER_GEOMETRY) - type = glsl_array_type(type, 1); + type = glsl_array_type(type, 1, 0); nir_variable *idx_var = nir_variable_create(b->shader, nir_var_shader_in, diff --git a/src/mesa/program/prog_to_nir.c b/src/mesa/program/prog_to_nir.c index ee7d7d8f6d2..10ba037d428 100644 --- a/src/mesa/program/prog_to_nir.c +++ b/src/mesa/program/prog_to_nir.c @@ -983,7 +983,7 @@ prog_to_nir(const struct gl_program *prog, if (prog->Parameters->NumParameters > 0) { c->parameters = rzalloc(s, nir_variable); c->parameters->type = - glsl_array_type(glsl_vec4_type(), prog->Parameters->NumParameters); + glsl_array_type(glsl_vec4_type(), prog->Parameters->NumParameters, 0); c->parameters->name = "parameters"; c->parameters->data.read_only = true; c->parameters->data.mode = nir_var_uniform;