i965: Add support for OPCODE_SSG.
authorEric Anholt <eric@anholt.net>
Thu, 1 Jul 2010 00:05:11 +0000 (17:05 -0700)
committerEric Anholt <eric@anholt.net>
Thu, 1 Jul 2010 00:29:09 +0000 (17:29 -0700)
The old compiler didn't use SSG, and instead emitted SGT/SGT/SUB.  We
can do a little better for SSG than we do for the SGT series.

src/mesa/drivers/dri/i965/brw_vs_emit.c
src/mesa/drivers/dri/i965/brw_wm.h
src/mesa/drivers/dri/i965/brw_wm_emit.c
src/mesa/drivers/dri/i965/brw_wm_glsl.c
src/mesa/drivers/dri/i965/brw_wm_pass1.c

index 0b44deeb634f2beb37e21c92aa7de5c454f66b64..128987d78a6688204605967d6270ecf176e0b9e2 100644 (file)
@@ -485,6 +485,23 @@ static void emit_cmp( struct brw_compile *p,
    brw_set_predicate_control(p, BRW_PREDICATE_NONE);
 }
 
+static void emit_sign(struct brw_vs_compile *c,
+                     struct brw_reg dst,
+                     struct brw_reg arg0)
+{
+   struct brw_compile *p = &c->func;
+
+   brw_MOV(p, dst, brw_imm_f(0));
+
+   brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_L, arg0, brw_imm_f(0));
+   brw_MOV(p, dst, brw_imm_f(-1.0));
+   brw_set_predicate_control(p, BRW_PREDICATE_NONE);
+
+   brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_G, arg0, brw_imm_f(0));
+   brw_MOV(p, dst, brw_imm_f(1.0));
+   brw_set_predicate_control(p, BRW_PREDICATE_NONE);
+}
+
 static void emit_max( struct brw_compile *p, 
                      struct brw_reg dst,
                      struct brw_reg arg0,
@@ -1719,6 +1736,9 @@ void brw_vs_emit(struct brw_vs_compile *c )
       case OPCODE_SLE:
          unalias2(c, dst, args[0], args[1], emit_sle);
          break;
+      case OPCODE_SSG:
+         unalias1(c, dst, args[0], emit_sign);
+         break;
       case OPCODE_SUB:
         brw_ADD(p, dst, args[0], negate(args[1]));
         break;
index 277b6de44250851320d51cf580704054005ebb79..938557ff3699e67249dbfd5a516d635dc9e9d264 100644 (file)
@@ -425,6 +425,10 @@ void emit_sop(struct brw_compile *p,
              GLuint cond,
              const struct brw_reg *arg0,
              const struct brw_reg *arg1);
+void emit_sign(struct brw_compile *p,
+              const struct brw_reg *dst,
+              GLuint mask,
+              const struct brw_reg *arg0);
 void emit_tex(struct brw_wm_compile *c,
              struct brw_reg *dst,
              GLuint dst_flags,
index 323cfac8fa7851872a6888cf744775dd427c5f08..11f482bddf20c7b5557a2948dc7fba1bc353b3d8 100644 (file)
@@ -668,6 +668,28 @@ void emit_cmp(struct brw_compile *p,
    }
 }
 
+void emit_sign(struct brw_compile *p,
+              const struct brw_reg *dst,
+              GLuint mask,
+              const struct brw_reg *arg0)
+{
+   GLuint i;
+
+   for (i = 0; i < 4; i++) {
+      if (mask & (1<<i)) {
+        brw_MOV(p, dst[i], brw_imm_f(0.0));
+
+        brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_L, arg0[i], brw_imm_f(0));
+        brw_MOV(p, dst[i], brw_imm_f(-1.0));
+        brw_set_predicate_control(p, BRW_PREDICATE_NONE);
+
+        brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_G, arg0[i], brw_imm_f(0));
+        brw_MOV(p, dst[i], brw_imm_f(1.0));
+        brw_set_predicate_control(p, BRW_PREDICATE_NONE);
+      }
+   }
+}
+
 void emit_max(struct brw_compile *p,
              const struct brw_reg *dst,
              GLuint mask,
@@ -1673,6 +1695,10 @@ void brw_wm_emit( struct brw_wm_compile *c )
         emit_sne(p, dst, dst_flags, args[0], args[1]);
        break;
 
+      case OPCODE_SSG:
+        emit_sign(p, dst, dst_flags, args[0]);
+        break;
+
       case OPCODE_LIT:
         emit_lit(c, dst, dst_flags, args[0]);
         break;
index fe3c89b7212c82617c1ecb130540dab660c5a7c1..e23ce7ad7a588bd58e4532d33613ecfc45a2d8fc 100644 (file)
@@ -1971,6 +1971,9 @@ static void brw_wm_emit_glsl(struct brw_context *brw, struct brw_wm_compile *c)
                emit_sop(p, dst, dst_flags,
                         BRW_CONDITIONAL_NEQ, args[0], args[1]);
                break;
+           case OPCODE_SSG:
+               emit_sign(p, dst, dst_flags, args[0]);
+               break;
            case OPCODE_MUL:
                emit_alu2(p, brw_MUL, dst, dst_flags, args[0], args[1]);
                break;
index b44939402920083e2df8984e95268d7ea9100ccf..8ee1f153b1fc3566ca2c26339ee123b4d6f16070 100644 (file)
@@ -158,6 +158,7 @@ void brw_wm_pass1( struct brw_wm_compile *c )
       case OPCODE_FLR:
       case OPCODE_FRC:
       case OPCODE_MOV:
+      case OPCODE_SSG:
       case OPCODE_SWZ:
       case OPCODE_TRUNC:
         read0 = writemask;