diff options
Diffstat (limited to 'src/mesa')
-rw-r--r-- | src/mesa/drivers/dri/r300/r300_fragprog.c | 41 | ||||
-rw-r--r-- | src/mesa/drivers/dri/r300/r300_fragprog.h | 3 |
2 files changed, 37 insertions, 7 deletions
diff --git a/src/mesa/drivers/dri/r300/r300_fragprog.c b/src/mesa/drivers/dri/r300/r300_fragprog.c index f1d27e9785c..54839a197ea 100644 --- a/src/mesa/drivers/dri/r300/r300_fragprog.c +++ b/src/mesa/drivers/dri/r300/r300_fragprog.c @@ -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; } diff --git a/src/mesa/drivers/dri/r300/r300_fragprog.h b/src/mesa/drivers/dri/r300/r300_fragprog.h index d841af98a80..f0aa0fc6c7c 100644 --- a/src/mesa/drivers/dri/r300/r300_fragprog.h +++ b/src/mesa/drivers/dri/r300/r300_fragprog.h @@ -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; |