glsl: Fix aggregates with dynamic initializers.
authorCody Northrop <cody@lunarg.com>
Thu, 10 Jul 2014 15:55:31 +0000 (09:55 -0600)
committerKenneth Graunke <kenneth@whitecape.org>
Mon, 14 Jul 2014 15:36:36 +0000 (08:36 -0700)
Vectors are falling in to the ir_dereference_array() path.

Without this change, the following glsl aborts the debug driver,
or gets the wrong answer in release:

mat2x2 a = mat2( vec2( 1.0, vertex.x ), vec2( 0.0, 1.0 ) );

Also submitting piglit tests, will reference in bug.

v2: Rebase on Mesa master.

v3: Remove unneeded check for arrays, which are covered by
    process_array_constructor(), recommended by Timothy Arceri.

Signed-off-by: Cody Northrop <cody@lunarg.com>
Reviewed-by: Courtney Goeltzenleuchter <courtney@lunarg.com>
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=79373

src/glsl/ast_function.cpp

index 631b793c8303f3b6b1aeb11b6d5a274f3bbc0cdb..4981fe1745852d39366d3a23f450e672624dfe2e 100644 (file)
@@ -760,11 +760,22 @@ process_vec_mat_constructor(exec_list *instructions,
    instructions->push_tail(var);
 
    int i = 0;
+
    foreach_in_list(ir_rvalue, rhs, &actual_parameters) {
-      ir_rvalue *lhs = new(ctx) ir_dereference_array(var,
-                                                     new(ctx) ir_constant(i));
+      ir_instruction *assignment = NULL;
+
+      if (var->type->is_matrix()) {
+         ir_rvalue *lhs = new(ctx) ir_dereference_array(var,
+                                             new(ctx) ir_constant(i));
+         assignment = new(ctx) ir_assignment(lhs, rhs, NULL);
+      } else {
+         /* use writemask rather than index for vector */
+         assert(var->type->is_vector());
+         assert(i < 4);
+         ir_dereference *lhs = new(ctx) ir_dereference_variable(var);
+         assignment = new(ctx) ir_assignment(lhs, rhs, NULL, (unsigned)(1 << i));
+      }
 
-      ir_instruction *assignment = new(ctx) ir_assignment(lhs, rhs, NULL);
       instructions->push_tail(assignment);
 
       i++;