diff options
-rw-r--r-- | ast_to_hir.cpp | 61 | ||||
-rwxr-xr-x | builtin_types.sh | 2 | ||||
-rw-r--r-- | glsl_types.cpp | 50 | ||||
-rw-r--r-- | glsl_types.h | 57 | ||||
-rw-r--r-- | hir_field_selection.cpp | 5 | ||||
-rw-r--r-- | ir.cpp | 2 | ||||
-rw-r--r-- | ir_function.cpp | 20 |
7 files changed, 81 insertions, 116 deletions
diff --git a/ast_to_hir.cpp b/ast_to_hir.cpp index 1d9df36143..740adb9f43 100644 --- a/ast_to_hir.cpp +++ b/ast_to_hir.cpp @@ -151,10 +151,7 @@ arithmetic_result_type(const struct glsl_type *type_a, * vector." */ if (type_a->is_vector() && type_b->is_vector()) { - if (type_a->vector_elements == type_b->vector_elements) - return type_a; - else - return glsl_error_type; + return (type_a == type_b) ? type_a : glsl_error_type; } /* All of the combinations of <scalar, scalar>, <vector, scalar>, @@ -183,48 +180,42 @@ arithmetic_result_type(const struct glsl_type *type_a, * more detail how vectors and matrices are operated on." */ if (! multiply) { - if (type_a->is_matrix() && type_b->is_matrix() - && (type_a->vector_elements == type_b->vector_elements) - && (type_a->matrix_rows == type_b->matrix_rows)) - return type_a; - else - return glsl_error_type; + return (type_a == type_b) ? type_a : glsl_error_type; } else { if (type_a->is_matrix() && type_b->is_matrix()) { - if (type_a->vector_elements == type_b->matrix_rows) { - char type_name[7]; - const struct glsl_type *t; - - type_name[0] = 'm'; - type_name[1] = 'a'; - type_name[2] = 't'; - - if (type_a->matrix_rows == type_b->vector_elements) { - type_name[3] = '0' + type_a->matrix_rows; - type_name[4] = '\0'; - } else { - type_name[3] = '0' + type_a->matrix_rows; - type_name[4] = 'x'; - type_name[5] = '0' + type_b->vector_elements; - type_name[6] = '\0'; - } - - t = state->symbols->get_type(type_name); - return (t != NULL) ? t : glsl_error_type; + /* Matrix multiply. The columns of A must match the rows of B. Given + * the other previously tested constraints, this means the vector type + * of a row from A must be the same as the vector type of a column from + * B. + */ + if (type_a->row_type() == type_b->column_type()) { + /* The resulting matrix has the number of columns of matrix B and + * the number of rows of matrix A. We get the row count of A by + * looking at the size of a vector that makes up a column. The + * transpose (size of a row) is done for B. + */ + return + glsl_type::get_instance(type_a->base_type, + type_a->column_type()->vector_elements, + type_b->row_type()->vector_elements); } } else if (type_a->is_matrix()) { /* A is a matrix and B is a column vector. Columns of A must match - * rows of B. + * rows of B. Given the other previously tested constraints, this + * means the vector type of a row from A must be the same as the + * vector the type of B. */ - if (type_a->vector_elements == type_b->vector_elements) + if (type_a->row_type() == type_b) return type_b; } else { assert(type_b->is_matrix()); - /* A is a row vector and B is a matrix. Columns of A must match - * rows of B. + /* A is a row vector and B is a matrix. Columns of A must match rows + * of B. Given the other previously tested constraints, this means + * the type of A must be the same as the vector type of a column from + * B. */ - if (type_a->vector_elements == type_b->matrix_rows) + if (type_a == type_b->column_type()) return type_a; } } diff --git a/builtin_types.sh b/builtin_types.sh index 6dd0ea7403..299a4cef41 100755 --- a/builtin_types.sh +++ b/builtin_types.sh @@ -275,7 +275,7 @@ gen_header "120" for c in 2 3 4; do for r in 2 3 4; do if [ $c -ne $r ]; then - gen_integral_type "mat${c}x${r}" "GLSL_TYPE_FLOAT" $c $r + gen_integral_type "mat${c}x${r}" "GLSL_TYPE_FLOAT" $r $c fi done done diff --git a/glsl_types.cpp b/glsl_types.cpp index 6dcbba8e8c..b2631efef9 100644 --- a/glsl_types.cpp +++ b/glsl_types.cpp @@ -94,56 +94,6 @@ _mesa_glsl_initialize_types(struct _mesa_glsl_parse_state *state) } -const struct glsl_type * -_mesa_glsl_get_vector_type(unsigned base_type, unsigned vector_length) -{ - switch (base_type) { - case GLSL_TYPE_UINT: - switch (vector_length) { - case 1: - case 2: - case 3: - case 4: - return glsl_uint_type + (vector_length - 1); - default: - return glsl_error_type; - } - case GLSL_TYPE_INT: - switch (vector_length) { - case 1: - case 2: - case 3: - case 4: - return glsl_int_type + (vector_length - 1); - default: - return glsl_error_type; - } - case GLSL_TYPE_FLOAT: - switch (vector_length) { - case 1: - case 2: - case 3: - case 4: - return glsl_float_type + (vector_length - 1); - default: - return glsl_error_type; - } - case GLSL_TYPE_BOOL: - switch (vector_length) { - case 1: - case 2: - case 3: - case 4: - return glsl_bool_type + (vector_length - 1); - default: - return glsl_error_type; - } - default: - return glsl_error_type; - } -} - - const glsl_type *glsl_type::get_base_type() const { switch (base_type) { diff --git a/glsl_types.h b/glsl_types.h index a7897719fb..96c9a1b2a4 100644 --- a/glsl_types.h +++ b/glsl_types.h @@ -39,6 +39,12 @@ #define GLSL_TYPE_VOID 8 #define GLSL_TYPE_ERROR 9 +extern const struct glsl_type *const glsl_error_type; +extern const struct glsl_type *const glsl_int_type; +extern const struct glsl_type *const glsl_uint_type; +extern const struct glsl_type *const glsl_float_type; +extern const struct glsl_type *const glsl_bool_type; + #define is_numeric_base_type(b) \ (((b) >= GLSL_TYPE_UINT) && ((b) <= GLSL_TYPE_FLOAT)) @@ -69,7 +75,7 @@ struct glsl_type { */ unsigned vector_elements:3; /**< 0, 2, 3, or 4 vector elements. */ - unsigned matrix_rows:3; /**< 0, 2, 3, or 4 matrix rows. */ + unsigned matrix_columns:3; /**< 0, 2, 3, or 4 matrix columns. */ /** * Name of the data type @@ -102,11 +108,11 @@ struct glsl_type { glsl_type(unsigned base_type, unsigned vector_elements, - unsigned matrix_rows, const char *name) : + unsigned matrix_columns, const char *name) : base_type(base_type), sampler_dimensionality(0), sampler_shadow(0), sampler_array(0), sampler_type(0), - vector_elements(vector_elements), matrix_rows(matrix_rows), + vector_elements(vector_elements), matrix_columns(matrix_columns), name(name), length(0) { @@ -118,7 +124,7 @@ struct glsl_type { base_type(GLSL_TYPE_SAMPLER), sampler_dimensionality(dim), sampler_shadow(shadow), sampler_array(array), sampler_type(type), - vector_elements(0), matrix_rows(0), + vector_elements(0), matrix_columns(0), name(name), length(0) { @@ -130,7 +136,7 @@ struct glsl_type { base_type(GLSL_TYPE_STRUCT), sampler_dimensionality(0), sampler_shadow(0), sampler_array(0), sampler_type(0), - vector_elements(0), matrix_rows(0), + vector_elements(0), matrix_columns(0), name(name), length(num_fields) { @@ -169,7 +175,7 @@ struct glsl_type { bool is_vector() const { return (vector_elements > 0) - && (matrix_rows == 0) + && (matrix_columns == 0) && (base_type >= GLSL_TYPE_UINT) && (base_type <= GLSL_TYPE_BOOL); } @@ -180,7 +186,7 @@ struct glsl_type { bool is_matrix() const { /* GLSL only has float matrices. */ - return (matrix_rows > 0) && (base_type == GLSL_TYPE_FLOAT); + return (matrix_columns > 0) && (base_type == GLSL_TYPE_FLOAT); } /** @@ -223,6 +229,34 @@ struct glsl_type { return base_type == GLSL_TYPE_ERROR; } + /** + * Query the full type of a matrix row + * + * \return + * If the type is not a matrix, \c glsl_error_type is returned. Otherwise + * a type matching the rows of the matrix is returned. + */ + const glsl_type *row_type() const + { + return is_matrix() + ? get_instance(base_type, matrix_columns, 1) + : glsl_error_type; + } + + /** + * Query the full type of a matrix column + * + * \return + * If the type is not a matrix, \c glsl_error_type is returned. Otherwise + * a type matching the columns of the matrix is returned. + */ + const glsl_type *column_type() const + { + return is_matrix() + ? get_instance(base_type, vector_elements, 1) + : glsl_error_type; + } + private: /** * \name Pointers to various type singletons @@ -254,15 +288,6 @@ extern "C" { extern void _mesa_glsl_initialize_types(struct _mesa_glsl_parse_state *state); -extern const struct glsl_type * -_mesa_glsl_get_vector_type(unsigned base_type, unsigned vector_length); - -extern const struct glsl_type *const glsl_error_type; -extern const struct glsl_type *const glsl_int_type; -extern const struct glsl_type *const glsl_uint_type; -extern const struct glsl_type *const glsl_float_type; -extern const struct glsl_type *const glsl_bool_type; - #ifdef __cplusplus } #endif diff --git a/hir_field_selection.cpp b/hir_field_selection.cpp index aa53120dbd..5f548bfa0f 100644 --- a/hir_field_selection.cpp +++ b/hir_field_selection.cpp @@ -145,8 +145,9 @@ _mesa_ast_field_selection_to_hir(const ast_expression *expr, * generate the type of the resulting value. */ deref->type = - _mesa_glsl_get_vector_type(op->type->base_type, - deref->selector.swizzle.num_components); + glsl_type::get_instance(op->type->base_type, + deref->selector.swizzle.num_components, + 1); } else { /* FINISHME: Logging of error messages should be moved into * FINISHME: generate_swizzle. This allows the generation of more @@ -59,7 +59,7 @@ ir_constant::ir_constant(const struct glsl_type *type, const void *data) { const unsigned elements = ((type->vector_elements == 0) ? 1 : type->vector_elements) - * ((type->matrix_rows == 0) ? 1 : type->matrix_rows); + * ((type->matrix_columns == 0) ? 1 : type->matrix_columns); unsigned size = 0; this->type = type; diff --git a/ir_function.cpp b/ir_function.cpp index a14b546bc6..b6139c4a9f 100644 --- a/ir_function.cpp +++ b/ir_function.cpp @@ -27,18 +27,20 @@ int type_compare(const glsl_type *a, const glsl_type *b) { + /* If the types are the same, they trivially match. + */ + if (a == b) + return 0; + switch (a->base_type) { case GLSL_TYPE_UINT: case GLSL_TYPE_INT: case GLSL_TYPE_FLOAT: case GLSL_TYPE_BOOL: if ((a->vector_elements != b->vector_elements) - || (a->matrix_rows != b->matrix_rows)) + || (a->matrix_columns != b->matrix_columns)) return -1; - if (a->base_type == b->base_type) - return 0; - /* There is no implicit conversion to or from bool. */ if ((a->base_type == GLSL_TYPE_BOOL) @@ -48,14 +50,10 @@ type_compare(const glsl_type *a, const glsl_type *b) return 1; case GLSL_TYPE_SAMPLER: - return ((a->sampler_dimensionality == b->sampler_dimensionality) - && (a->sampler_shadow == b->sampler_shadow) - && (a->sampler_array == b->sampler_array) - && (a->sampler_type == b->sampler_type)) - ? 0 : -1; - case GLSL_TYPE_STRUCT: - return (strcmp(a->name, b->name) == 0) ? 0 : -1; + /* Samplers and structures must match exactly. + */ + return -1; case GLSL_TYPE_ARRAY: if ((b->base_type != GLSL_TYPE_ARRAY) |