i965: Split Gen4-5 and Gen6+ MATH instruction emitters.
authorKenneth Graunke <kenneth@whitecape.org>
Sat, 7 Jun 2014 08:56:12 +0000 (01:56 -0700)
committerKenneth Graunke <kenneth@whitecape.org>
Tue, 10 Jun 2014 23:38:26 +0000 (16:38 -0700)
Our existing functions, brw_math and brw_math2, had unclear roles:

Gen4-5 used brw_math for both unary and binary math functions; it never
used brw_math2.  Since operands are already in message registers, this
is reasonable.

Gen6+ used brw_math for unary math functions, and brw_math2 for binary
math functions, duplicating a lot of code.  The only real difference was
that brw_math used brw_null_reg() for src1.

This patch improves brw_math2's assertions to allow both unary and
binary operations, renames it to gen6_math(), and drops the Gen6+ code
out of brw_math().

Signed-off-by: Kenneth Graunke <kenneth@whitecape.org>
Reviewed-by: Matt Turner <mattst88@gmail.com>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
src/mesa/drivers/dri/i965/brw_eu.h
src/mesa/drivers/dri/i965/brw_eu_emit.c
src/mesa/drivers/dri/i965/brw_fs_generator.cpp
src/mesa/drivers/dri/i965/brw_vec4_generator.cpp

index 5aaaad43b6e60e54fe4c8bccac42ea8337739ee3..e495c2c6dfeb57d489ec91d9c2268a0db89b4eac 100644 (file)
@@ -285,7 +285,7 @@ void brw_math( struct brw_compile *p,
               unsigned data_type,
               unsigned precision );
 
-void brw_math2(struct brw_compile *p,
+void gen6_math(struct brw_compile *p,
               struct brw_reg dest,
               unsigned function,
               struct brw_reg src0,
index 6b2117d260003d04e03b8b59b0ca46eed84b8e03..63e7bdeb206c9af985f4dd10602dc8e0a06abd75 100644 (file)
@@ -1837,63 +1837,27 @@ void brw_math( struct brw_compile *p,
               unsigned precision )
 {
    struct brw_context *brw = p->brw;
+   struct brw_instruction *insn = next_insn(p, BRW_OPCODE_SEND);
 
-   if (brw->gen >= 6) {
-      struct brw_instruction *insn = next_insn(p, BRW_OPCODE_MATH);
-
-      assert(dest.file == BRW_GENERAL_REGISTER_FILE ||
-             (brw->gen >= 7 && dest.file == BRW_MESSAGE_REGISTER_FILE));
-      assert(src.file == BRW_GENERAL_REGISTER_FILE);
-
-      assert(dest.hstride == BRW_HORIZONTAL_STRIDE_1);
-      if (brw->gen == 6)
-        assert(src.hstride == BRW_HORIZONTAL_STRIDE_1);
-
-      /* Source modifiers are ignored for extended math instructions on Gen6. */
-      if (brw->gen == 6) {
-        assert(!src.negate);
-        assert(!src.abs);
-      }
-
-      if (function == BRW_MATH_FUNCTION_INT_DIV_QUOTIENT ||
-         function == BRW_MATH_FUNCTION_INT_DIV_REMAINDER ||
-         function == BRW_MATH_FUNCTION_INT_DIV_QUOTIENT_AND_REMAINDER) {
-        assert(src.type != BRW_REGISTER_TYPE_F);
-      } else {
-        assert(src.type == BRW_REGISTER_TYPE_F);
-      }
-
-      /* Math is the same ISA format as other opcodes, except that CondModifier
-       * becomes FC[3:0] and ThreadCtrl becomes FC[5:4].
-       */
-      insn->header.destreg__conditionalmod = function;
-
-      brw_set_dest(p, insn, dest);
-      brw_set_src0(p, insn, src);
-      brw_set_src1(p, insn, brw_null_reg());
-   } else {
-      struct brw_instruction *insn = next_insn(p, BRW_OPCODE_SEND);
+   assert(brw->gen < 6);
 
-      /* Example code doesn't set predicate_control for send
-       * instructions.
-       */
-      insn->header.predicate_control = 0;
-      insn->header.destreg__conditionalmod = msg_reg_nr;
+   /* Example code doesn't set predicate_control for send
+    * instructions.
+    */
+   insn->header.predicate_control = 0;
+   insn->header.destreg__conditionalmod = msg_reg_nr;
 
-      brw_set_dest(p, insn, dest);
-      brw_set_src0(p, insn, src);
-      brw_set_math_message(p,
-                          insn,
-                          function,
-                          src.type == BRW_REGISTER_TYPE_D,
-                          precision,
-                          data_type);
-   }
+   brw_set_dest(p, insn, dest);
+   brw_set_src0(p, insn, src);
+   brw_set_math_message(p,
+                        insn,
+                        function,
+                        src.type == BRW_REGISTER_TYPE_D,
+                        precision,
+                        data_type);
 }
 
-/** Extended math function, float[8].
- */
-void brw_math2(struct brw_compile *p,
+void gen6_math(struct brw_compile *p,
               struct brw_reg dest,
               unsigned function,
               struct brw_reg src0,
@@ -1902,10 +1866,11 @@ void brw_math2(struct brw_compile *p,
    struct brw_context *brw = p->brw;
    struct brw_instruction *insn = next_insn(p, BRW_OPCODE_MATH);
 
+   assert(brw->gen >= 6);
+
    assert(dest.file == BRW_GENERAL_REGISTER_FILE ||
           (brw->gen >= 7 && dest.file == BRW_MESSAGE_REGISTER_FILE));
    assert(src0.file == BRW_GENERAL_REGISTER_FILE);
-   assert(src1.file == BRW_GENERAL_REGISTER_FILE);
 
    assert(dest.hstride == BRW_HORIZONTAL_STRIDE_1);
    if (brw->gen == 6) {
@@ -1918,9 +1883,16 @@ void brw_math2(struct brw_compile *p,
        function == BRW_MATH_FUNCTION_INT_DIV_QUOTIENT_AND_REMAINDER) {
       assert(src0.type != BRW_REGISTER_TYPE_F);
       assert(src1.type != BRW_REGISTER_TYPE_F);
+      assert(src1.file == BRW_GENERAL_REGISTER_FILE);
    } else {
       assert(src0.type == BRW_REGISTER_TYPE_F);
       assert(src1.type == BRW_REGISTER_TYPE_F);
+      if (function == BRW_MATH_FUNCTION_POW) {
+         assert(src1.file == BRW_GENERAL_REGISTER_FILE);
+      } else {
+         assert(src1.file == BRW_ARCHITECTURE_REGISTER_FILE &&
+                src1.nr == BRW_ARF_NULL);
+      }
    }
 
    /* Source modifiers are ignored for extended math instructions on Gen6. */
index df1d20f906138ecbe04785ef3c64516a24cdb065..e900967a356af68fe2e1cda01281d31be83a7500 100644 (file)
@@ -298,11 +298,7 @@ fs_generator::generate_math1_gen7(fs_inst *inst,
                                struct brw_reg src0)
 {
    assert(inst->mlen == 0);
-   brw_math(p, dst,
-           brw_math_function(inst->opcode),
-           0, src0,
-           BRW_MATH_DATA_VECTOR,
-           BRW_MATH_PRECISION_FULL);
+   gen6_math(p, dst, brw_math_function(inst->opcode), src0, brw_null_reg());
 }
 
 void
@@ -312,7 +308,7 @@ fs_generator::generate_math2_gen7(fs_inst *inst,
                                struct brw_reg src1)
 {
    assert(inst->mlen == 0);
-   brw_math2(p, dst, brw_math_function(inst->opcode), src0, src1);
+   gen6_math(p, dst, brw_math_function(inst->opcode), src0, src1);
 }
 
 void
@@ -325,19 +321,11 @@ fs_generator::generate_math1_gen6(fs_inst *inst,
    assert(inst->mlen == 0);
 
    brw_set_default_compression_control(p, BRW_COMPRESSION_NONE);
-   brw_math(p, dst,
-           op,
-           0, src0,
-           BRW_MATH_DATA_VECTOR,
-           BRW_MATH_PRECISION_FULL);
+   gen6_math(p, dst, op, src0, brw_null_reg());
 
    if (dispatch_width == 16) {
       brw_set_default_compression_control(p, BRW_COMPRESSION_2NDHALF);
-      brw_math(p, sechalf(dst),
-              op,
-              0, sechalf(src0),
-              BRW_MATH_DATA_VECTOR,
-              BRW_MATH_PRECISION_FULL);
+      gen6_math(p, sechalf(dst), op, sechalf(src0), brw_null_reg());
       brw_set_default_compression_control(p, BRW_COMPRESSION_COMPRESSED);
    }
 }
@@ -353,11 +341,11 @@ fs_generator::generate_math2_gen6(fs_inst *inst,
    assert(inst->mlen == 0);
 
    brw_set_default_compression_control(p, BRW_COMPRESSION_NONE);
-   brw_math2(p, dst, op, src0, src1);
+   gen6_math(p, dst, op, src0, src1);
 
    if (dispatch_width == 16) {
       brw_set_default_compression_control(p, BRW_COMPRESSION_2NDHALF);
-      brw_math2(p, sechalf(dst), op, sechalf(src0), sechalf(src1));
+      gen6_math(p, sechalf(dst), op, sechalf(src0), sechalf(src1));
       brw_set_default_compression_control(p, BRW_COMPRESSION_COMPRESSED);
    }
 }
index e95e6d9ba44aac3dd944ea19605e921304cacbca..931741faa2b64931b8453253c67d91f401bfb305 100644 (file)
@@ -186,13 +186,7 @@ vec4_generator::generate_math1_gen6(vec4_instruction *inst,
    check_gen6_math_src_arg(src);
 
    brw_set_default_access_mode(p, BRW_ALIGN_1);
-   brw_math(p,
-           dst,
-           brw_math_function(inst->opcode),
-           inst->base_mrf,
-           src,
-           BRW_MATH_DATA_SCALAR,
-           BRW_MATH_PRECISION_FULL);
+   gen6_math(p, dst, brw_math_function(inst->opcode), src, brw_null_reg());
    brw_set_default_access_mode(p, BRW_ALIGN_16);
 }
 
@@ -202,10 +196,7 @@ vec4_generator::generate_math2_gen7(vec4_instruction *inst,
                                     struct brw_reg src0,
                                     struct brw_reg src1)
 {
-   brw_math2(p,
-            dst,
-            brw_math_function(inst->opcode),
-            src0, src1);
+   gen6_math(p, dst, brw_math_function(inst->opcode), src0, src1);
 }
 
 void
@@ -221,10 +212,7 @@ vec4_generator::generate_math2_gen6(vec4_instruction *inst,
    check_gen6_math_src_arg(src1);
 
    brw_set_default_access_mode(p, BRW_ALIGN_1);
-   brw_math2(p,
-            dst,
-            brw_math_function(inst->opcode),
-            src0, src1);
+   gen6_math(p, dst, brw_math_function(inst->opcode), src0, src1);
    brw_set_default_access_mode(p, BRW_ALIGN_16);
 }
 
@@ -1146,10 +1134,12 @@ vec4_generator::generate_vec4_instruction(vec4_instruction *instruction,
    case SHADER_OPCODE_LOG2:
    case SHADER_OPCODE_SIN:
    case SHADER_OPCODE_COS:
-      if (brw->gen == 6) {
+      if (brw->gen >= 7) {
+         gen6_math(p, dst, brw_math_function(inst->opcode), src[0],
+                   brw_null_reg());
+      } else if (brw->gen == 6) {
         generate_math1_gen6(inst, dst, src[0]);
       } else {
-        /* Also works for Gen7. */
         generate_math1_gen4(inst, dst, src[0]);
       }
       break;