summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJerome Glisse <glisse@freedesktop.org>2006-11-05 00:47:27 +0000
committerJerome Glisse <glisse@freedesktop.org>2006-11-05 00:47:27 +0000
commite330a69ee509b4fc16b93ae554ca2e378c929e63 (patch)
tree632268872281808a3fe7cebb46a5e4d04d2b9e7a
parent0056ea5417d6d3c3ca875cf86a085611c83f8afb (diff)
Add sin instruction to fragment program.
There is a bug somewhere in fragment program. tri-cos and tri-sin show the bug. Also we should not emit multiple time the same constant. for sin,cos,lit have to fix that.
-rw-r--r--src/mesa/drivers/dri/r300/r300_fragprog.c66
1 files changed, 64 insertions, 2 deletions
diff --git a/src/mesa/drivers/dri/r300/r300_fragprog.c b/src/mesa/drivers/dri/r300/r300_fragprog.c
index 60f5db62fa..7793c5eb2e 100644
--- a/src/mesa/drivers/dri/r300/r300_fragprog.c
+++ b/src/mesa/drivers/dri/r300/r300_fragprog.c
@@ -1063,7 +1063,6 @@ static GLboolean parse_program(struct r300_fragment_program *rp)
* cos using taylor serie:
* cos(x) = 1 - x^2/2! + x^4/4! - x^6/6!
*/
-// printf("swz %d\n", src[0].v_swz);
temp = get_temp_reg(rp);
cnstv[0] = 0.5;
cnstv[1] = 0.041666667;
@@ -1374,7 +1373,70 @@ static GLboolean parse_program(struct r300_fragment_program *rp)
free_temp(rp, temp);
break;
case OPCODE_SIN:
- ERROR("SIN not implemented\n");
+ /*
+ * sin using taylor serie:
+ * sin(x) = x - x^3/3! + x^5/5! - x^7/7!
+ */
+ temp = get_temp_reg(rp);
+ cnstv[0] = 0.333333333;
+ cnstv[1] = 0.008333333;
+ cnstv[2] = 0.000198413;
+ cnstv[4] = 0.0;
+ cnst = emit_const4fv(rp, cnstv);
+ src[0] = t_scalar_src(rp, fpi->SrcReg[0]);
+
+ emit_arith(rp, PFS_OP_MAD, temp,
+ WRITEMASK_XYZ,
+ src[0],
+ src[0],
+ pfs_zero,
+ flags);
+ emit_arith(rp, PFS_OP_MAD, temp,
+ WRITEMASK_Y | WRITEMASK_Z,
+ temp, temp,
+ pfs_zero,
+ flags);
+ emit_arith(rp, PFS_OP_MAD, temp,
+ WRITEMASK_Z,
+ temp,
+ swizzle(temp, X, X, X, W),
+ pfs_zero,
+ flags);
+ emit_arith(rp, PFS_OP_MAD, temp,
+ WRITEMASK_XYZ,
+ src[0],
+ temp,
+ pfs_zero,
+ flags);
+ emit_arith(rp, PFS_OP_MAD, temp,
+ WRITEMASK_XYZ,
+ temp, cnst,
+ pfs_zero,
+ flags);
+ emit_arith(rp, PFS_OP_MAD, temp,
+ WRITEMASK_X,
+ src[0],
+ pfs_one,
+ negate(temp),
+ flags);
+ emit_arith(rp, PFS_OP_MAD, temp,
+ WRITEMASK_X,
+ temp,
+ pfs_one,
+ swizzle(temp, Y, Y, Y, W),
+ flags);
+ emit_arith(rp, PFS_OP_MAD, temp,
+ WRITEMASK_X,
+ temp,
+ pfs_one,
+ negate(swizzle(temp, Z, Z, Z, W)),
+ flags);
+ emit_arith(rp, PFS_OP_MAD, dest, mask,
+ swizzle(temp, X, X, X, X),
+ pfs_one,
+ pfs_zero,
+ flags);
+ free_temp(rp, temp);
break;
case OPCODE_SLT:
src[0] = t_src(rp, fpi->SrcReg[0]);