i965: Fix bitcast operations with negate (ceil)
authorIago Toral Quiroga <itoral@igalia.com>
Wed, 17 Dec 2014 13:19:01 +0000 (14:19 +0100)
committerIago Toral Quiroga <itoral@igalia.com>
Tue, 13 Jan 2015 11:19:32 +0000 (12:19 +0100)
Commit 0ae9ca12a8 put source modifiers out of the bitcast operations
by adding a MOV operation that would handle them separately. It missed
the case of ceil though: the implementation negates both its source and
destination operands. The source operand will be used for RNDD, which
we can handle normally, but we need to fix the modifier for the
negated result.

v2:
  - RNDD can handle the source modifier so no need to put that one
    in a separate MOV.

Fixes the following 42 dEQP tests:
dEQP-GLES3.functional.shaders.builtin_functions.common.ceil.*_vertex
dEQP-GLES3.functional.shaders.builtin_functions.common.ceil.*_fragment
dEQP-GLES3.functional.shaders.builtin_functions.precision.ceil._*vertex.*
dEQP-GLES3.functional.shaders.builtin_functions.precision.ceil._*fragment.*

Reviewed-by: Matt Turner <mattst88@gmail.com>
Reviewed-by: Jason Ekstrand <jason.ekstrand@intel.com>
src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp

index bd9345ebef24542ec78ff4361234f686fcb32be2..1e7fdf5b4f20014286de7f27e77f03da1e524ed4 100644 (file)
@@ -954,10 +954,13 @@ fs_visitor::visit(ir_expression *ir)
    case ir_unop_trunc:
       emit(RNDZ(this->result, op[0]));
       break;
-   case ir_unop_ceil:
-      op[0].negate = !op[0].negate;
-      emit(RNDD(this->result, op[0]));
-      this->result.negate = true;
+   case ir_unop_ceil: {
+         fs_reg tmp = fs_reg(this, ir->type);
+         op[0].negate = !op[0].negate;
+         emit(RNDD(tmp, op[0]));
+         tmp.negate = true;
+         emit(MOV(this->result, tmp));
+      }
       break;
    case ir_unop_floor:
       emit(RNDD(this->result, op[0]));
index a81c66a861fcb56533681aa18452780654480864..8b8b27f8e7b43659dcdbcafb15040ab99e2b62de 100644 (file)
@@ -1647,10 +1647,13 @@ vec4_visitor::visit(ir_expression *ir)
    case ir_unop_trunc:
       emit(RNDZ(result_dst, op[0]));
       break;
-   case ir_unop_ceil:
-      op[0].negate = !op[0].negate;
-      inst = emit(RNDD(result_dst, op[0]));
-      this->result.negate = true;
+   case ir_unop_ceil: {
+         src_reg tmp = src_reg(this, ir->type);
+         op[0].negate = !op[0].negate;
+         emit(RNDD(dst_reg(tmp), op[0]));
+         tmp.negate = true;
+         emit(MOV(result_dst, tmp));
+      }
       break;
    case ir_unop_floor:
       inst = emit(RNDD(result_dst, op[0]));