diff options
author | Eric Anholt <[email protected]> | 2014-10-13 14:11:28 +0100 |
---|---|---|
committer | Eric Anholt <[email protected]> | 2014-10-13 17:15:47 +0100 |
commit | 5bc91b6e322354d0964c07375c9a3a28b0083a38 (patch) | |
tree | afa3d54e4c2f0e4efb52e76855ed2b120493cbd7 /src | |
parent | 02ca66fbc3e2b272afcb9bae66348d3b1900e2c3 (diff) |
vc4: Improve the accuracy of SIN and COS.
This gets them to pass glsl-sin/cos. There was an obvious problem that I
was using the FRC code on the scaled input value, which means that we had
a range in [0, 1], while our taylor is most accurate across [-0.5, 0.5].
We can just slide things over, but that means flipping the sign of the
coefficients. After that, it was just a matter of stuffing more
coefficients in.
Diffstat (limited to 'src')
-rw-r--r-- | src/gallium/drivers/vc4/vc4_program.c | 28 |
1 files changed, 17 insertions, 11 deletions
diff --git a/src/gallium/drivers/vc4/vc4_program.c b/src/gallium/drivers/vc4/vc4_program.c index 455b5d7f117..1bbdba5e7c9 100644 --- a/src/gallium/drivers/vc4/vc4_program.c +++ b/src/gallium/drivers/vc4/vc4_program.c @@ -766,10 +766,11 @@ tgsi_to_qir_sin(struct vc4_compile *c, enum qop op, struct qreg *src, int i) { float coeff[] = { - 2.0 * M_PI, - -pow(2.0 * M_PI, 3) / (3 * 2 * 1), - pow(2.0 * M_PI, 5) / (5 * 4 * 3 * 2 * 1), - -pow(2.0 * M_PI, 7) / (7 * 6 * 5 * 4 * 3 * 2 * 1), + -2.0 * M_PI, + pow(2.0 * M_PI, 3) / (3 * 2 * 1), + -pow(2.0 * M_PI, 5) / (5 * 4 * 3 * 2 * 1), + pow(2.0 * M_PI, 7) / (7 * 6 * 5 * 4 * 3 * 2 * 1), + -pow(2.0 * M_PI, 9) / (9 * 8 * 7 * 6 * 5 * 4 * 3 * 2 * 1), }; struct qreg scaled_x = @@ -777,8 +778,9 @@ tgsi_to_qir_sin(struct vc4_compile *c, src[0 * 4 + 0], qir_uniform_f(c, 1.0f / (M_PI * 2.0f))); - - struct qreg x = tgsi_to_qir_frc(c, NULL, 0, &scaled_x, 0); + struct qreg x = qir_FADD(c, + tgsi_to_qir_frc(c, NULL, 0, &scaled_x, 0), + qir_uniform_f(c, -0.5)); struct qreg x2 = qir_FMUL(c, x, x); struct qreg sum = qir_FMUL(c, x, qir_uniform_f(c, coeff[0])); for (int i = 1; i < ARRAY_SIZE(coeff); i++) { @@ -799,16 +801,20 @@ tgsi_to_qir_cos(struct vc4_compile *c, enum qop op, struct qreg *src, int i) { float coeff[] = { - 1.0f, - -pow(2.0 * M_PI, 2) / (2 * 1), - pow(2.0 * M_PI, 4) / (4 * 3 * 2 * 1), - -pow(2.0 * M_PI, 6) / (6 * 5 * 4 * 3 * 2 * 1), + -1.0f, + pow(2.0 * M_PI, 2) / (2 * 1), + -pow(2.0 * M_PI, 4) / (4 * 3 * 2 * 1), + pow(2.0 * M_PI, 6) / (6 * 5 * 4 * 3 * 2 * 1), + -pow(2.0 * M_PI, 8) / (8 * 7 * 6 * 5 * 4 * 3 * 2 * 1), + pow(2.0 * M_PI, 10) / (10 * 9 * 8 * 7 * 6 * 5 * 4 * 3 * 2 * 1), }; struct qreg scaled_x = qir_FMUL(c, src[0 * 4 + 0], qir_uniform_f(c, 1.0f / (M_PI * 2.0f))); - struct qreg x_frac = tgsi_to_qir_frc(c, NULL, 0, &scaled_x, 0); + struct qreg x_frac = qir_FADD(c, + tgsi_to_qir_frc(c, NULL, 0, &scaled_x, 0), + qir_uniform_f(c, -0.5)); struct qreg sum = qir_uniform_f(c, coeff[0]); struct qreg x2 = qir_FMUL(c, x_frac, x_frac); |