Add individual component negation.
authorJerome Glisse <glisse@freedesktop.org>
Sat, 21 Jan 2006 11:43:37 +0000 (11:43 +0000)
committerJerome Glisse <glisse@freedesktop.org>
Sat, 21 Jan 2006 11:43:37 +0000 (11:43 +0000)
src/mesa/drivers/dri/r300/r300_fragprog.c
src/mesa/drivers/dri/r300/r300_fragprog.h

index f1d27e9785cbc54826586f06ca2d74e002da6ae7..54839a197ea0f9a91194345d00111d0cb0811ddb 100644 (file)
@@ -174,7 +174,8 @@ static const pfs_reg_t undef = {
        index: 0,
        v_swz: SWIZZLE_XYZ,
        s_swz: SWIZZLE_W,
-       negate: 0,
+       negate_v: 0,
+       negate_s: 0,
        absolute: 0,
        no_use: GL_FALSE,
        valid: GL_FALSE
@@ -336,7 +337,8 @@ static pfs_reg_t emit_const4fv(struct r300_fragment_program *rp, GLfloat *cp)
 
 static __inline pfs_reg_t negate(pfs_reg_t r)
 {
-       r.negate = 1;
+       r.negate_v = 1;
+       r.negate_s = 1;
        return r;
 }
 
@@ -429,6 +431,7 @@ static pfs_reg_t do_swizzle(struct r300_fragment_program *rp,
 static pfs_reg_t t_src(struct r300_fragment_program *rp,
                                                struct prog_src_register fpsrc) {
        pfs_reg_t r = undef;
+       pfs_reg_t n = undef;
 
        switch (fpsrc.File) {
        case PROGRAM_TEMPORARY:
@@ -454,16 +457,42 @@ static pfs_reg_t t_src(struct r300_fragment_program *rp,
                ERROR("unknown SrcReg->File %x\n", fpsrc.File);
                return r;
        }
-       
+
        /* no point swizzling ONE/ZERO/HALF constants... */
        if (r.v_swz < SWIZZLE_111 && r.s_swz < SWIZZLE_ZERO)
                r = do_swizzle(rp, r, fpsrc.Swizzle);
-       
+#if 0
        /* WRONG! Need to be able to do individual component negation,
         * should probably handle this in the swizzling code unless
         * all components are negated, then we can do this natively */
        if ((fpsrc.NegateBase & 0xf) == 0xf)
                r.negate = GL_TRUE;
+#endif
+       r.negate_s = (fpsrc.NegateBase >> 3) & 1;
+
+       if ((fpsrc.NegateBase & 0x7) == 0x0) {
+               r.negate_v = 0;
+       } else if ((fpsrc.NegateBase & 0x7) == 0x7) {
+               r.negate_v = 1;
+       } else {
+               if (r.type != REG_TYPE_TEMP) {
+                       n = get_temp_reg(rp);
+                       emit_arith(rp, PFS_OP_MAD, n, 0x7 ^ fpsrc.NegateBase,
+                                  keep(r), pfs_one, pfs_zero, 0);
+                       r.negate_v = 1;
+                       emit_arith(rp, PFS_OP_MAD, n,
+                                  fpsrc.NegateBase & 0x7 | WRITEMASK_W,
+                                  keep(r), pfs_one, pfs_zero, 0);
+                       r.negate_v = 0;
+                       r = n;
+               } else {
+                       r.negate_v = 1;
+                       emit_arith(rp, PFS_OP_MAD, r,
+                                  fpsrc.NegateBase & 0x7 | WRITEMASK_W,
+                                  r, pfs_one, pfs_zero, 0);
+                       r.negate_v = 0;
+               }
+       }
 
        return r;
 }
@@ -824,14 +853,14 @@ static void emit_arith(struct r300_fragment_program *rp, int op,
                if (emit_vop && vop != R300_FPI0_OUTC_REPL_ALPHA) {
                        srcpos = add_src(rp, hwsrc[i], vpos, v_swiz[src[i].v_swz].flags);       
                        vswz[i] = (v_swiz[src[i].v_swz].base + (srcpos * v_swiz[src[i].v_swz].stride)) |
-                                               (src[i].negate   ? ARG_NEG : 0) |
+                                               (src[i].negate_v ? ARG_NEG : 0) |
                                                (src[i].absolute ? ARG_ABS : 0);
                } else vswz[i] = R300_FPI0_ARGC_ZERO;
                
                if (emit_sop) {
                        srcpos = add_src(rp, hwsrc[i], spos, s_swiz[src[i].s_swz].flags);
                        sswz[i] = (s_swiz[src[i].s_swz].base + (srcpos * s_swiz[src[i].s_swz].stride)) |
-                                               (src[i].negate   ? ARG_NEG : 0) |
+                                               (src[i].negate_s ? ARG_NEG : 0) |
                                                (src[i].absolute ? ARG_ABS : 0);        
                } else sswz[i] = R300_FPI2_ARGA_ZERO;
        }
index d841af98a8000a8db30a7a4132865353994c7850..f0aa0fc6c7ca01235a7b8bb9580fecc5869f09ca 100644 (file)
@@ -20,7 +20,8 @@ typedef struct _pfs_reg_t {
        GLuint index:6;
        GLuint v_swz:5;
        GLuint s_swz:5;
-       GLuint negate:1;    //XXX: we need to handle negate individually
+       GLuint negate_v:1;
+       GLuint negate_s:1;
        GLuint absolute:1;
        GLboolean no_use:1;
        GLboolean valid:1;