i965/vec4_nir: Do boolean source modifier resolves on BDW+
authorJason Ekstrand <jason.ekstrand@intel.com>
Mon, 3 Aug 2015 21:37:41 +0000 (14:37 -0700)
committerJason Ekstrand <jason.ekstrand@intel.com>
Mon, 10 Aug 2015 18:45:43 +0000 (11:45 -0700)
On BDW+, the negation source modifier on NOT, AND, OR, and XOR, is actually
a boolean negate and not an integer negate.  However, NIR's soruce
modifiers are the integer version.  We have to resolve it with a MOV prior
to emitting the actual instruction.  This is basically the same thing we do
in the FS backend.

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

index 985886d702490d9e22b1a7a3d592161bc8ffecd1..0c13d43a7d3db404272d27d90fd904d4caaca45d 100644 (file)
@@ -320,6 +320,7 @@ public:
                    dst_reg dst, src_reg src0, src_reg src1);
 
    src_reg fix_3src_operand(src_reg src);
+   src_reg resolve_source_modifiers(const src_reg& src);
 
    vec4_instruction *emit_math(enum opcode opcode, const dst_reg &dst, const src_reg &src0,
                                const src_reg &src1 = src_reg());
index 3056d0982149f5270d9ba0b5536ed87ebabfbcab..f04c5e1b5b5b27670ba08a8638276bff87e7a09a 100644 (file)
@@ -1020,18 +1020,33 @@ vec4_visitor::nir_emit_alu(nir_alu_instr *instr)
    }
 
    case nir_op_inot:
+      if (devinfo->gen >= 8) {
+         op[0] = resolve_source_modifiers(op[0]);
+      }
       emit(NOT(dst, op[0]));
       break;
 
    case nir_op_ixor:
+      if (devinfo->gen >= 8) {
+         op[0] = resolve_source_modifiers(op[0]);
+         op[1] = resolve_source_modifiers(op[1]);
+      }
       emit(XOR(dst, op[0], op[1]));
       break;
 
    case nir_op_ior:
+      if (devinfo->gen >= 8) {
+         op[0] = resolve_source_modifiers(op[0]);
+         op[1] = resolve_source_modifiers(op[1]);
+      }
       emit(OR(dst, op[0], op[1]));
       break;
 
    case nir_op_iand:
+      if (devinfo->gen >= 8) {
+         op[0] = resolve_source_modifiers(op[0]);
+         op[1] = resolve_source_modifiers(op[1]);
+      }
       emit(AND(dst, op[0], op[1]));
       break;
 
index ba352be3ad5863ef58e127913ea861b8533b3e3a..57d98c9b6b3daa775011d784e568a67ced9a8372 100644 (file)
@@ -312,6 +312,19 @@ vec4_visitor::fix_3src_operand(src_reg src)
    return src_reg(expanded);
 }
 
+src_reg
+vec4_visitor::resolve_source_modifiers(const src_reg& src)
+{
+   if (!src.abs && !src.negate)
+      return src;
+
+   dst_reg resolved = dst_reg(this, glsl_type::ivec4_type);
+   resolved.type = src.type;
+   emit(MOV(resolved, src));
+
+   return src_reg(resolved);
+}
+
 src_reg
 vec4_visitor::fix_math_operand(src_reg src)
 {