summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ast_to_hir.cpp61
-rwxr-xr-xbuiltin_types.sh2
-rw-r--r--glsl_types.cpp50
-rw-r--r--glsl_types.h57
-rw-r--r--hir_field_selection.cpp5
-rw-r--r--ir.cpp2
-rw-r--r--ir_function.cpp20
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
diff --git a/ir.cpp b/ir.cpp
index 49df75425e..ad75cdad73 100644
--- a/ir.cpp
+++ b/ir.cpp
@@ -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)