i965: Add support for LRP in VPs.
authorEric Anholt <eric@anholt.net>
Wed, 7 Jan 2009 20:37:58 +0000 (12:37 -0800)
committerEric Anholt <eric@anholt.net>
Wed, 7 Jan 2009 20:40:16 +0000 (12:40 -0800)
Bug #19226.

src/mesa/drivers/dri/i965/brw_vs_emit.c

index 71e2a95bfd91b1985856c6895e99e3f1f15c044c..2730162968484ae6ba64de9858e1c7c1a7adfbf4 100644 (file)
@@ -193,6 +193,7 @@ static void unalias1( struct brw_vs_compile *c,
       struct brw_reg tmp = brw_writemask(get_tmp(c), dst.dw1.bits.writemask);
       func(c, tmp, arg0);
       brw_MOV(p, dst, tmp);
+      release_tmp(c, tmp);
    }
    else {
       func(c, dst, arg0);
@@ -214,12 +215,38 @@ static void unalias2( struct brw_vs_compile *c,
       struct brw_reg tmp = brw_writemask(get_tmp(c), dst.dw1.bits.writemask);
       func(c, tmp, arg0, arg1);
       brw_MOV(p, dst, tmp);
+      release_tmp(c, tmp);
    }
    else {
       func(c, dst, arg0, arg1);
    }
 }
 
+static void unalias3( struct brw_vs_compile *c,
+                     struct brw_reg dst,
+                     struct brw_reg arg0,
+                     struct brw_reg arg1,
+                     struct brw_reg arg2,
+                     void (*func)( struct brw_vs_compile *,
+                                   struct brw_reg,
+                                   struct brw_reg,
+                                   struct brw_reg,
+                                   struct brw_reg ))
+{
+   if ((dst.file == arg0.file && dst.nr == arg0.nr) ||
+       (dst.file == arg1.file && dst.nr == arg1.nr) ||
+       (dst.file == arg2.file && dst.nr == arg2.nr)) {
+      struct brw_compile *p = &c->func;
+      struct brw_reg tmp = brw_writemask(get_tmp(c), dst.dw1.bits.writemask);
+      func(c, tmp, arg0, arg1, arg2);
+      brw_MOV(p, dst, tmp);
+      release_tmp(c, tmp);
+   }
+   else {
+      func(c, dst, arg0, arg1, arg2);
+   }
+}
+
 static void emit_sop( struct brw_compile *p,
                       struct brw_reg dst,
                       struct brw_reg arg0,
@@ -590,6 +617,18 @@ static void emit_lit_noalias( struct brw_vs_compile *c,
    brw_ENDIF(p, if_insn);
 }
 
+static void emit_lrp_noalias(struct brw_vs_compile *c,
+                            struct brw_reg dst,
+                            struct brw_reg arg0,
+                            struct brw_reg arg1,
+                            struct brw_reg arg2)
+{
+   struct brw_compile *p = &c->func;
+
+   brw_ADD(p, dst, negate(arg0), brw_imm_f(1.0));
+   brw_MUL(p, brw_null_reg(), dst, arg2);
+   brw_MAC(p, dst, arg0, arg1);
+}
 
 /** 3 or 4-component vector normalization */
 static void emit_nrm( struct brw_vs_compile *c, 
@@ -1077,6 +1116,9 @@ void brw_vs_emit(struct brw_vs_compile *c )
       case OPCODE_LIT:
         unalias1(c, dst, args[0], emit_lit_noalias);
         break;
+      case OPCODE_LRP:
+        unalias3(c, dst, args[0], args[1], args[2], emit_lrp_noalias);
+        break;
       case OPCODE_MAD:
         brw_MOV(p, brw_acc_reg(), args[2]);
         brw_MAC(p, dst, args[0], args[1]);