glsl: Convert ir_binop_vector_extract in the LHS to ir_triop_vector_insert 69/6569/1
authorIan Romanick <ian.d.romanick@intel.com>
Sat, 16 Mar 2013 01:06:11 +0000 (18:06 -0700)
committerIan Romanick <ian.d.romanick@intel.com>
Mon, 13 May 2013 19:05:19 +0000 (12:05 -0700)
The ast_array_index code can't know whether to generate an
ir_binop_vector_extract or an ir_triop_vector_insert.  Instead it will
always generate ir_binop_vector_extract, and the LHS and RHS have to be
re-written.

v2: Convert tabs to spaces.  Suggested by Eric.

Signed-off-by: Ian Romanick <ian.d.romanick@intel.com>
Reviewed-by: Eric Anholt <eric@anholt.net>
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
src/glsl/ast_to_hir.cpp

index e595110..b206380 100644 (file)
@@ -672,6 +672,30 @@ do_assignment(exec_list *instructions, struct _mesa_glsl_parse_state *state,
    void *ctx = state;
    bool error_emitted = (lhs->type->is_error() || rhs->type->is_error());
 
+   /* If the assignment LHS comes back as an ir_binop_vector_extract
+    * expression, move it to the RHS as an ir_triop_vector_insert.
+    */
+   if (lhs->ir_type == ir_type_expression) {
+      ir_expression *const expr = lhs->as_expression();
+
+      if (unlikely(expr->operation == ir_binop_vector_extract)) {
+         ir_rvalue *new_rhs =
+            validate_assignment(state, lhs->type, rhs, is_initializer);
+
+         if (new_rhs == NULL) {
+            _mesa_glsl_error(& lhs_loc, state, "type mismatch");
+            return lhs;
+         } else {
+            rhs = new(ctx) ir_expression(ir_triop_vector_insert,
+                                         expr->operands[0]->type,
+                                         expr->operands[0],
+                                         new_rhs,
+                                         expr->operands[1]);
+            lhs = expr->operands[0]->clone(ctx, NULL);
+         }
+      }
+   }
+
    ir_variable *lhs_var = lhs->variable_referenced();
    if (lhs_var)
       lhs_var->assigned = true;