Fix a few typos
[mesa.git] / src / glsl / ast_function.cpp
index 36a0d193d9ea0fd43c1e4d2823ab383120683f94..758361324e3673db47b6133748c5c22612bada32 100644 (file)
@@ -1191,7 +1191,7 @@ emit_inline_matrix_constructor(const glsl_type *type,
     *
     *  - Construct a matrix from an arbirary combination of vectors and
     *    scalars.  The components of the constructor parameters are assigned
-    *    to the matrix in colum-major order until the matrix is full.
+    *    to the matrix in column-major order until the matrix is full.
     *
     *  - Construct a matrix from a single matrix.  The source matrix is copied
     *    to the upper left portion of the constructed matrix, and the remaining
@@ -1370,71 +1370,59 @@ emit_inline_matrix_constructor(const glsl_type *type,
    } else {
       const unsigned cols = type->matrix_columns;
       const unsigned rows = type->vector_elements;
+      unsigned remaining_slots = rows * cols;
       unsigned col_idx = 0;
       unsigned row_idx = 0;
 
       foreach_in_list(ir_rvalue, rhs, parameters) {
-        const unsigned components_remaining_this_column = rows - row_idx;
-        unsigned rhs_components = rhs->type->components();
-        unsigned rhs_base = 0;
-
-        /* Since the parameter might be used in the RHS of two assignments,
-         * generate a temporary and copy the paramter there.
-         */
-        ir_variable *rhs_var =
-           new(ctx) ir_variable(rhs->type, "mat_ctor_vec", ir_var_temporary);
-        instructions->push_tail(rhs_var);
-
-        ir_dereference *rhs_var_ref =
-           new(ctx) ir_dereference_variable(rhs_var);
-        ir_instruction *inst = new(ctx) ir_assignment(rhs_var_ref, rhs, NULL);
-        instructions->push_tail(inst);
-
-        /* Assign the current parameter to as many components of the matrix
-         * as it will fill.
-         *
-         * NOTE: A single vector parameter can span two matrix columns.  A
-         * single vec4, for example, can completely fill a mat2.
-         */
-        if (rhs_components >= components_remaining_this_column) {
-           const unsigned count = MIN2(rhs_components,
-                                       components_remaining_this_column);
-
-           rhs_var_ref = new(ctx) ir_dereference_variable(rhs_var);
-
-           ir_instruction *inst = assign_to_matrix_column(var, col_idx,
-                                                          row_idx,
-                                                          rhs_var_ref, 0,
-                                                          count, ctx);
-           instructions->push_tail(inst);
-
-           rhs_base = count;
-
-           col_idx++;
-           row_idx = 0;
-        }
-
-        /* If there is data left in the parameter and components left to be
-         * set in the destination, emit another assignment.  It is possible
-         * that the assignment could be of a vec4 to the last element of the
-         * matrix.  In this case col_idx==cols, but there is still data
-         * left in the source parameter.  Obviously, don't emit an assignment
-         * to data outside the destination matrix.
-         */
-        if ((col_idx < cols) && (rhs_base < rhs_components)) {
-           const unsigned count = rhs_components - rhs_base;
-
-           rhs_var_ref = new(ctx) ir_dereference_variable(rhs_var);
-
-           ir_instruction *inst = assign_to_matrix_column(var, col_idx,
-                                                          row_idx,
-                                                          rhs_var_ref,
-                                                          rhs_base,
-                                                          count, ctx);
-           instructions->push_tail(inst);
-
-           row_idx += count;
-        }
+         unsigned rhs_components = rhs->type->components();
+         unsigned rhs_base = 0;
+
+         if (remaining_slots == 0)
+            break;
+
+         /* Since the parameter might be used in the RHS of two assignments,
+          * generate a temporary and copy the paramter there.
+          */
+         ir_variable *rhs_var =
+            new(ctx) ir_variable(rhs->type, "mat_ctor_vec", ir_var_temporary);
+         instructions->push_tail(rhs_var);
+
+         ir_dereference *rhs_var_ref =
+            new(ctx) ir_dereference_variable(rhs_var);
+         ir_instruction *inst = new(ctx) ir_assignment(rhs_var_ref, rhs, NULL);
+         instructions->push_tail(inst);
+
+         do {
+            /* Assign the current parameter to as many components of the matrix
+             * as it will fill.
+             *
+             * NOTE: A single vector parameter can span two matrix columns.  A
+             * single vec4, for example, can completely fill a mat2.
+             */
+            unsigned count = MIN2(rows - row_idx,
+                                  rhs_components - rhs_base);
+
+            rhs_var_ref = new(ctx) ir_dereference_variable(rhs_var);
+            ir_instruction *inst = assign_to_matrix_column(var, col_idx,
+                                                         row_idx,
+                                                         rhs_var_ref,
+                                                         rhs_base,
+                                                         count, ctx);
+            instructions->push_tail(inst);
+            rhs_base += count;
+            row_idx += count;
+            remaining_slots -= count;
+
+            /* Sometimes, there is still data left in the parameters and
+             * components left to be set in the destination but in other
+             * column.
+             */
+            if (row_idx >= rows) {
+               row_idx = 0;
+               col_idx++;
+            }
+         } while(remaining_slots > 0 && rhs_base < rhs_components);
       }
    }