glsl: Factor out a get_mul_type() function.

Reviewed-by: Chris Forbes <chrisf@ijw.co.nz>
This commit is contained in:
Matt Turner 2015-03-27 10:43:05 -07:00
parent f9e2295560
commit 73f6f9b9be
3 changed files with 78 additions and 57 deletions

View File

@ -375,66 +375,14 @@ arithmetic_result_type(ir_rvalue * &value_a, ir_rvalue * &value_b,
if (type_a == type_b)
return type_a;
} else {
if (type_a->is_matrix() && type_b->is_matrix()) {
/* 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.
*/
const glsl_type *const type =
glsl_type::get_instance(type_a->base_type,
type_a->column_type()->vector_elements,
type_b->row_type()->vector_elements);
assert(type != glsl_type::error_type);
const glsl_type *type = glsl_type::get_mul_type(type_a, type_b);
return type;
}
} else if (type_a->is_matrix()) {
/* A is a matrix and B is a column vector. Columns of A must match
* 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->row_type() == type_b) {
/* The resulting vector has a number of elements equal to
* the number of rows of matrix A. */
const glsl_type *const type =
glsl_type::get_instance(type_a->base_type,
type_a->column_type()->vector_elements,
1);
assert(type != glsl_type::error_type);
return type;
}
} else {
assert(type_b->is_matrix());
/* 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 == type_b->column_type()) {
/* The resulting vector has a number of elements equal to
* the number of columns of matrix B. */
const glsl_type *const type =
glsl_type::get_instance(type_a->base_type,
type_b->row_type()->vector_elements,
1);
assert(type != glsl_type::error_type);
return type;
}
if (type == glsl_type::error_type) {
_mesa_glsl_error(loc, state,
"size mismatch for matrix multiplication");
}
_mesa_glsl_error(loc, state, "size mismatch for matrix multiplication");
return glsl_type::error_type;
return type;
}

View File

@ -824,6 +824,73 @@ glsl_type::get_interface_instance(const glsl_struct_field *fields,
}
const glsl_type *
glsl_type::get_mul_type(const glsl_type *type_a, const glsl_type *type_b)
{
if (type_a == type_b) {
return type_a;
} else if (type_a->is_matrix() && type_b->is_matrix()) {
/* 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.
*/
const glsl_type *const type =
get_instance(type_a->base_type,
type_a->column_type()->vector_elements,
type_b->row_type()->vector_elements);
assert(type != error_type);
return type;
}
} else if (type_a->is_matrix()) {
/* A is a matrix and B is a column vector. Columns of A must match
* 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->row_type() == type_b) {
/* The resulting vector has a number of elements equal to
* the number of rows of matrix A. */
const glsl_type *const type =
get_instance(type_a->base_type,
type_a->column_type()->vector_elements,
1);
assert(type != error_type);
return type;
}
} else {
assert(type_b->is_matrix());
/* 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 == type_b->column_type()) {
/* The resulting vector has a number of elements equal to
* the number of columns of matrix B. */
const glsl_type *const type =
get_instance(type_a->base_type,
type_b->row_type()->vector_elements,
1);
assert(type != error_type);
return type;
}
}
return error_type;
}
const glsl_type *
glsl_type::field_type(const char *name) const
{

View File

@ -275,6 +275,12 @@ struct glsl_type {
enum glsl_interface_packing packing,
const char *block_name);
/**
* Get the type resulting from a multiplication of \p type_a * \p type_b
*/
static const glsl_type *get_mul_type(const glsl_type *type_a,
const glsl_type *type_b);
/**
* Query the total number of scalars that make up a scalar, vector or matrix
*/