i965/vec4: implement d2b
authorIago Toral Quiroga <itoral@igalia.com>
Wed, 17 Feb 2016 12:08:47 +0000 (13:08 +0100)
committerSamuel Iglesias Gonsálvez <siglesias@igalia.com>
Tue, 3 Jan 2017 10:26:50 +0000 (11:26 +0100)
v2 (Curro):
  - Generate the flag register with a MOV with conditional_mod instead of a CMP
    instruction, which has the benefit that we can skip loading a DF
    0.0 constant.
  - Avoid the PICK_LOW_32BIT + MOV by using the flag result and a
    SEL to set the boolean result.

v3:
  - Fix comment (Matt)

Reviewed-by: Matt Turner <mattst88@gmail.com>
src/mesa/drivers/dri/i965/brw_vec4_nir.cpp

index 778ebb55caaf31e3e5a7bcd18f90bd3c1ea68bcd..abd47cc4f5ce62f2486c00efb0b2aca171251735 100644 (file)
@@ -1543,6 +1543,24 @@ vec4_visitor::nir_emit_alu(nir_alu_instr *instr)
       emit(CMP(dst, op[0], brw_imm_f(0.0f), BRW_CONDITIONAL_NZ));
       break;
 
+   case nir_op_d2b: {
+      /* We use a MOV with conditional_mod to check if the provided value is
+       * 0.0. We want this to flush denormalized numbers to zero, so we set a
+       * source modifier on the source operand to trigger this, as source
+       * modifiers don't affect the result of the testing against 0.0.
+       */
+      src_reg value = op[0];
+      value.abs = true;
+      vec4_instruction *inst = emit(MOV(dst_null_df(), value));
+      inst->conditional_mod = BRW_CONDITIONAL_NZ;
+
+      src_reg one = src_reg(this, glsl_type::ivec4_type);
+      emit(MOV(dst_reg(one), brw_imm_d(~0)));
+      inst = emit(BRW_OPCODE_SEL, dst, one, brw_imm_d(0));
+      inst->predicate = BRW_PREDICATE_NORMAL;
+      break;
+   }
+
    case nir_op_i2b:
       emit(CMP(dst, op[0], brw_imm_d(0), BRW_CONDITIONAL_NZ));
       break;