glsl: Add support for the 'u' and 'U' unsigned integer suffixes.
[mesa.git] / src / glsl / ast_function.cpp
index 61012b850ae0b7fe3963a5f2abc19e168dbb636a..e9e8d250014216f023aa309936b67f816e54989b 100644 (file)
@@ -101,9 +101,6 @@ process_call(exec_list *instructions, ir_function *f,
 
    ir_function_signature *sig = f->matching_signature(actual_parameters);
 
-   /* The instructions param will be used when the FINISHMEs below are done */
-   (void) instructions;
-
    if (sig != NULL) {
       /* Verify that 'out' and 'inout' actual parameters are lvalues.  This
        * isn't done in ir_function::matching_signature because that function
@@ -504,8 +501,9 @@ emit_inline_vector_constructor(const glsl_type *type,
       instructions->push_tail(inst);
    } else {
       unsigned base_component = 0;
+      unsigned base_lhs_component = 0;
       ir_constant_data data;
-      unsigned constant_mask = 0;
+      unsigned constant_mask = 0, constant_components = 0;
 
       memset(&data, 0, sizeof(data));
 
@@ -515,8 +513,8 @@ emit_inline_vector_constructor(const glsl_type *type,
 
         /* Do not try to assign more components to the vector than it has!
          */
-        if ((rhs_components + base_component) > lhs_components) {
-           rhs_components = lhs_components - base_component;
+        if ((rhs_components + base_lhs_component) > lhs_components) {
+           rhs_components = lhs_components - base_lhs_component;
         }
 
         const ir_constant *const c = param->as_constant();
@@ -543,18 +541,23 @@ emit_inline_vector_constructor(const glsl_type *type,
 
            /* Mask of fields to be written in the assignment.
             */
-           constant_mask |= ((1U << rhs_components) - 1) << base_component;
-        }
+           constant_mask |= ((1U << rhs_components) - 1) << base_lhs_component;
+           constant_components += rhs_components;
 
-        /* Advance the component index by the number of components that were
-         * just assigned.
+           base_component += rhs_components;
+        }
+        /* Advance the component index by the number of components
+         * that were just assigned.
          */
-        base_component += rhs_components;
+        base_lhs_component += rhs_components;
       }
 
       if (constant_mask != 0) {
         ir_dereference *lhs = new(ctx) ir_dereference_variable(var);
-        ir_rvalue *rhs = new(ctx) ir_constant(var->type, &data);
+        const glsl_type *rhs_type = glsl_type::get_instance(var->type->base_type,
+                                                            constant_components,
+                                                            1);
+        ir_rvalue *rhs = new(ctx) ir_constant(rhs_type, &data);
 
         ir_instruction *inst =
            new(ctx) ir_assignment(lhs, rhs, NULL, constant_mask);
@@ -574,12 +577,10 @@ emit_inline_vector_constructor(const glsl_type *type,
 
         const ir_constant *const c = param->as_constant();
         if (c == NULL) {
-           /* Generate a swizzle that puts the first element of the source at
-            * the location of the first element of the destination.
-            */
+           /* Generate a swizzle in case rhs_components != rhs->type->vector_elements. */
            unsigned swiz[4] = { 0, 0, 0, 0 };
            for (unsigned i = 0; i < rhs_components; i++)
-              swiz[i + base_component] = i;
+              swiz[i] = i;
 
            /* Mask of fields to be written in the assignment.
             */
@@ -587,7 +588,7 @@ emit_inline_vector_constructor(const glsl_type *type,
               << base_component;
 
            ir_dereference *lhs = new(ctx) ir_dereference_variable(var);
-           ir_rvalue *rhs = new(ctx) ir_swizzle(param, swiz, lhs_components);
+           ir_rvalue *rhs = new(ctx) ir_swizzle(param, swiz, rhs_components);
 
            ir_instruction *inst =
               new(ctx) ir_assignment(lhs, rhs, NULL, write_mask);
@@ -632,10 +633,10 @@ assign_to_matrix_column(ir_variable *var, unsigned column, unsigned row_base,
     */
    unsigned swiz[4] = { src_base, src_base, src_base, src_base };
    for (unsigned i = 0; i < count; i++)
-      swiz[i + row_base] = src_base + i;
+      swiz[i + row_base] = i;
 
    ir_rvalue *const rhs =
-      new(mem_ctx) ir_swizzle(src, swiz, column_ref->type->components());
+      new(mem_ctx) ir_swizzle(src, swiz, count);
 
    /* Mask of fields to be written in the assignment.
     */
@@ -816,7 +817,7 @@ emit_inline_matrix_constructor(const glsl_type *type,
                                     var->type->matrix_columns);
 
       unsigned swiz[4] = { 0, 0, 0, 0 };
-      for (unsigned i = 1; i < src_matrix->type->vector_elements; i++)
+      for (unsigned i = 1; i < last_row; i++)
         swiz[i] = i;
 
       const unsigned write_mask = (1U << last_row) - 1;
@@ -837,14 +838,11 @@ emit_inline_matrix_constructor(const glsl_type *type,
          */
         ir_rvalue *rhs;
         if (lhs->type->vector_elements != rhs_col->type->vector_elements) {
-           rhs = new(ctx) ir_swizzle(rhs_col, swiz,
-                                     lhs->type->vector_elements);
+           rhs = new(ctx) ir_swizzle(rhs_col, swiz, last_row);
         } else {
            rhs = rhs_col;
         }
 
-        assert(lhs->type == rhs->type);
-
         ir_instruction *inst =
            new(ctx) ir_assignment(lhs, rhs, NULL, write_mask);
         instructions->push_tail(inst);
@@ -1063,7 +1061,7 @@ ast_function_expression::hir(exec_list *instructions,
        *    "It is an error to construct matrices from other matrices. This
        *    is reserved for future use."
        */
-      if ((state->language_version <= 110) && (matrix_parameters > 0)
+      if (state->language_version == 110 && matrix_parameters > 0
          && constructor_type->is_matrix()) {
         _mesa_glsl_error(& loc, state, "cannot construct `%s' from a "
                          "matrix in GLSL 1.10",