i965: Work around gen6 ignoring source modifiers on math instructions.
authorEric Anholt <eric@anholt.net>
Tue, 7 Dec 2010 22:50:50 +0000 (14:50 -0800)
committerEric Anholt <eric@anholt.net>
Tue, 7 Dec 2010 23:11:27 +0000 (15:11 -0800)
With the change of extended math from having the arguments moved into
mrfs and handed off through message passing to being directly hooked
up to the EU, it looks like the piece for doing source modifiers
(negate and abs) was left out.

Fixes:
fog-modes
glean/fp1-ARB_fog_exp test
glean/fp1-ARB_fog_exp2 test
glean/fp1-Computed fog exp test
glean/fp1-Computed fog exp2 test
ext_fog_coord-modes

src/mesa/drivers/dri/i965/brw_eu_emit.c
src/mesa/drivers/dri/i965/brw_fs.cpp
src/mesa/drivers/dri/i965/brw_wm_emit.c

index 96aa046b64f721691804bc7cbac19717d63595dd..f62fc7ebfb5eb7ad9023b77bfe6e417b6deb87b9 100644 (file)
@@ -1272,6 +1272,10 @@ void brw_math( struct brw_compile *p,
       assert(dest.hstride == BRW_HORIZONTAL_STRIDE_1);
       assert(src.hstride == BRW_HORIZONTAL_STRIDE_1);
 
+      /* Source modifiers are ignored for extended math instructions. */
+      assert(!src.negate);
+      assert(!src.abs);
+
       if (function != BRW_MATH_FUNCTION_INT_DIV_QUOTIENT &&
          function != BRW_MATH_FUNCTION_INT_DIV_QUOTIENT_AND_REMAINDER) {
         assert(src.type == BRW_REGISTER_TYPE_F);
@@ -1338,6 +1342,12 @@ void brw_math2(struct brw_compile *p,
       assert(src1.type == BRW_REGISTER_TYPE_F);
    }
 
+   /* Source modifiers are ignored for extended math instructions. */
+   assert(!src0.negate);
+   assert(!src0.abs);
+   assert(!src1.negate);
+   assert(!src1.abs);
+
    /* Math is the same ISA format as other opcodes, except that CondModifier
     * becomes FC[3:0] and ThreadCtrl becomes FC[5:4].
     */
@@ -1374,6 +1384,10 @@ void brw_math_16( struct brw_compile *p,
       insn->header.destreg__conditionalmod = function;
       insn->header.saturate = saturate;
 
+      /* Source modifiers are ignored for extended math instructions. */
+      assert(!src.negate);
+      assert(!src.abs);
+
       brw_set_dest(p, insn, dest);
       brw_set_src0(insn, src);
       brw_set_src1(insn, brw_null_reg());
index a956453dbf5ca6e3063eff90f213d8f0697611c0..8840b6d6f738486776f2b8d3172a9e16aa8397fc 100644 (file)
@@ -600,8 +600,13 @@ fs_visitor::emit_math(fs_opcodes opcode, fs_reg dst, fs_reg src)
     * might be able to do better by doing execsize = 1 math and then
     * expanding that result out, but we would need to be careful with
     * masking.
+    *
+    * The hardware ignores source modifiers (negate and abs) on math
+    * instructions, so we also move to a temp to set those up.
     */
-   if (intel->gen >= 6 && src.file == UNIFORM) {
+   if (intel->gen >= 6 && (src.file == UNIFORM ||
+                          src.abs ||
+                          src.negate)) {
       fs_reg expanded = fs_reg(this, glsl_type::float_type);
       emit(fs_inst(BRW_OPCODE_MOV, expanded, src));
       src = expanded;
index 6e8f08c14d84f79735625e532525c2a9a17a590e..24e10632aa0aad89510b54e23426627fa8cf56a8 100644 (file)
@@ -896,10 +896,14 @@ void emit_math1(struct brw_wm_compile *c,
                      BRW_MATH_SATURATE_NONE);
    struct brw_reg src;
 
-   if (intel->gen >= 6 && (arg0[0].hstride == BRW_HORIZONTAL_STRIDE_0 ||
-                          arg0[0].file != BRW_GENERAL_REGISTER_FILE)) {
+   if (intel->gen >= 6 && ((arg0[0].hstride == BRW_HORIZONTAL_STRIDE_0 ||
+                           arg0[0].file != BRW_GENERAL_REGISTER_FILE) ||
+                          arg0[0].negate || arg0[0].abs)) {
       /* Gen6 math requires that source and dst horizontal stride be 1,
        * and that the argument be in the GRF.
+       *
+       * The hardware ignores source modifiers (negate and abs) on math
+       * instructions, so we also move to a temp to set those up.
        */
       src = dst[dst_chan];
       brw_MOV(p, src, arg0[0]);