ir_to_mesa: Fix implementation of ir_binop_equal, ir_binop_notequal.
authorEric Anholt <eric@anholt.net>
Wed, 18 Aug 2010 00:24:42 +0000 (17:24 -0700)
committerEric Anholt <eric@anholt.net>
Wed, 18 Aug 2010 00:27:44 +0000 (17:27 -0700)
These binops are the vector-to-bool comparisons, not vec-to-bvec.  We
likely want both operations avilable as expression, since 915 and 965
FS naturally does the vector version, while 965 VS can also naturally
do the scalar version.  However, we can save that until later.

Fixes:
glsl-fs-vec4-operator-equal.shader_test
glsl-fs-vec4-operator-notequal.shader_test
glsl-vs-vec4-operator-equal.shader_test
glsl-vs-vec4-operator-notequal.shader_test

src/mesa/program/ir_to_mesa.cpp

index 7fff66c78b1655251ffa9b423832604483fc899d..7b65fa4203b27a989f6fa8a85030c9e5b2890edb 100644 (file)
@@ -813,10 +813,34 @@ ir_to_mesa_visitor::visit(ir_expression *ir)
       ir_to_mesa_emit_op2(ir, OPCODE_SGE, result_dst, op[0], op[1]);
       break;
    case ir_binop_equal:
-      ir_to_mesa_emit_op2(ir, OPCODE_SEQ, result_dst, op[0], op[1]);
+      /* "==" operator producing a scalar boolean. */
+      if (ir->operands[0]->type->is_vector() ||
+         ir->operands[1]->type->is_vector()) {
+        ir_to_mesa_src_reg temp = get_temp(glsl_type::vec4_type);
+        ir_to_mesa_emit_op2(ir, OPCODE_SNE,
+                            ir_to_mesa_dst_reg_from_src(temp), op[0], op[1]);
+        ir_to_mesa_emit_op2(ir, OPCODE_DP4, result_dst, temp, temp);
+        ir_to_mesa_emit_op2(ir, OPCODE_SEQ,
+                            result_dst, result_src, src_reg_for_float(0.0));
+      } else {
+        ir_to_mesa_emit_op2(ir, OPCODE_SEQ, result_dst, op[0], op[1]);
+      }
       break;
-   case ir_binop_logic_xor:
    case ir_binop_nequal:
+      /* "!=" operator producing a scalar boolean. */
+      if (ir->operands[0]->type->is_vector() ||
+         ir->operands[1]->type->is_vector()) {
+        ir_to_mesa_src_reg temp = get_temp(glsl_type::vec4_type);
+        ir_to_mesa_emit_op2(ir, OPCODE_SNE,
+                            ir_to_mesa_dst_reg_from_src(temp), op[0], op[1]);
+        ir_to_mesa_emit_op2(ir, OPCODE_DP4, result_dst, temp, temp);
+        ir_to_mesa_emit_op2(ir, OPCODE_SNE,
+                            result_dst, result_src, src_reg_for_float(0.0));
+      } else {
+        ir_to_mesa_emit_op2(ir, OPCODE_SNE, result_dst, op[0], op[1]);
+      }
+      break;
+   case ir_binop_logic_xor:
       ir_to_mesa_emit_op2(ir, OPCODE_SNE, result_dst, op[0], op[1]);
       break;