i965/nir: Resolve source modifiers on Gen8+ logic operations.
authorKenneth Graunke <kenneth@whitecape.org>
Fri, 6 Mar 2015 04:39:49 +0000 (20:39 -0800)
committerKenneth Graunke <kenneth@whitecape.org>
Mon, 9 Mar 2015 03:03:35 +0000 (20:03 -0700)
On Gen8+, AND/OR/XOR/NOT don't support the abs() source modifier, and
negate changes meaning to bitwise-not (~, not -).  This isn't what NIR
expects, so we should resolve the source modifers via a MOV.

+30 Piglits (fs-op-bit{and,or,xor}-not-abs-*).

Signed-off-by: Kenneth Graunke <kenneth@whitecape.org>
Reviewed-by: Topi Pohjolainen <topi.pohjolainen@intel.com>
src/mesa/drivers/dri/i965/brw_fs.cpp
src/mesa/drivers/dri/i965/brw_fs.h
src/mesa/drivers/dri/i965/brw_fs_nir.cpp

index d6acc238a1a2f03886b247c07c2b0fbb6eddf43d..428234f7aecf38382dd308d77887746fd2cab346 100644 (file)
@@ -1561,6 +1561,17 @@ fs_visitor::emit_sampleid_setup()
    return reg;
 }
 
+void
+fs_visitor::resolve_source_modifiers(fs_reg *src)
+{
+   if (!src->abs && !src->negate)
+      return;
+
+   fs_reg temp = retype(vgrf(1), src->type);
+   emit(MOV(temp, *src));
+   *src = temp;
+}
+
 fs_reg
 fs_visitor::fix_math_operand(fs_reg src)
 {
index 70098d8451ad3113e62d6dd9e4bfe2457f41f302..ec77962dd3d70b25ba94c42e0863afe0a52618cd 100644 (file)
@@ -299,6 +299,7 @@ public:
                      int texunit);
    fs_reg emit_mcs_fetch(fs_reg coordinate, int components, fs_reg sampler);
    void emit_gen6_gather_wa(uint8_t wa, fs_reg dst);
+   void resolve_source_modifiers(fs_reg *src);
    fs_reg fix_math_operand(fs_reg src);
    fs_inst *emit_math(enum opcode op, fs_reg dst, fs_reg src0);
    fs_inst *emit_math(enum opcode op, fs_reg dst, fs_reg src0, fs_reg src1);
index 66f79187b69e803dd952aada3a73724d7a018842..a0300aa36d5d7370cc35e2785a9962c668448c8a 100644 (file)
@@ -935,15 +935,30 @@ fs_visitor::nir_emit_alu(nir_alu_instr *instr)
       break;
 
    case nir_op_inot:
+      if (brw->gen >= 8) {
+         resolve_source_modifiers(&op[0]);
+      }
       emit(NOT(result, op[0]));
       break;
    case nir_op_ixor:
+      if (brw->gen >= 8) {
+         resolve_source_modifiers(&op[0]);
+         resolve_source_modifiers(&op[1]);
+      }
       emit(XOR(result, op[0], op[1]));
       break;
    case nir_op_ior:
+      if (brw->gen >= 8) {
+         resolve_source_modifiers(&op[0]);
+         resolve_source_modifiers(&op[1]);
+      }
       emit(OR(result, op[0], op[1]));
       break;
    case nir_op_iand:
+      if (brw->gen >= 8) {
+         resolve_source_modifiers(&op[0]);
+         resolve_source_modifiers(&op[1]);
+      }
       emit(AND(result, op[0], op[1]));
       break;