glsl: Factor out a get_mul_type() function.
authorMatt Turner <mattst88@gmail.com>
Fri, 27 Mar 2015 17:43:05 +0000 (10:43 -0700)
committerMatt Turner <mattst88@gmail.com>
Tue, 31 Mar 2015 21:01:15 +0000 (14:01 -0700)
Reviewed-by: Chris Forbes <chrisf@ijw.co.nz>
src/glsl/ast_to_hir.cpp
src/glsl/glsl_types.cpp
src/glsl/glsl_types.h

index 036ec17dee7e285da0963915c1ca2213e1499fbd..78369360f19a6c504f88cc38d170ce32c3f3f3e8 100644 (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;
    }
 
 
index be87b0a2d24140d57110433a0beb091fe9e7f3d7..4aa36a79490246294ba5ecb1ec6ab9ba70ee0f08 100644 (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
 {
index 7359e94764c14fbd1e3cf4642b63f00671c73bab..d383dd5bef17e18f7e71937a6df66bbf70ec2bc3 100644 (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
     */