diff options
author | Eric Anholt <[email protected]> | 2014-08-06 16:41:12 -0700 |
---|---|---|
committer | Eric Anholt <[email protected]> | 2014-08-08 18:59:47 -0700 |
commit | 663ffff0e747efebf434b57fe1e149619be0d228 (patch) | |
tree | 9224b911b379a36d1aadc0d81e6db57cf125e0f4 /src/gallium/drivers/vc4/vc4_program.c | |
parent | d815b2490b2da3c68aa4de951006d1c5f5470da2 (diff) |
vc4: Add support for the SIN instruction.
v2: Rebase on helpers.
Diffstat (limited to 'src/gallium/drivers/vc4/vc4_program.c')
-rw-r--r-- | src/gallium/drivers/vc4/vc4_program.c | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/src/gallium/drivers/vc4/vc4_program.c b/src/gallium/drivers/vc4/vc4_program.c index 4e991148c40..1d048206f8f 100644 --- a/src/gallium/drivers/vc4/vc4_program.c +++ b/src/gallium/drivers/vc4/vc4_program.c @@ -369,6 +369,40 @@ tgsi_to_qir_abs(struct tgsi_to_qir *trans, return qir_FMAXABS(c, arg, arg); } +/* Note that this instruction replicates its result from the x channel */ +static struct qreg +tgsi_to_qir_sin(struct tgsi_to_qir *trans, + struct tgsi_full_instruction *tgsi_inst, + enum qop op, struct qreg *src, int i) +{ + struct qcompile *c = trans->c; + 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), + }; + + struct qreg scaled_x = + qir_FMUL(c, + src[0 * 4 + 0], + qir_uniform_f(trans, 1.0f / (M_PI * 2.0f))); + + + struct qreg x = tgsi_to_qir_frc(trans, NULL, 0, &scaled_x, 0); + struct qreg x2 = qir_FMUL(c, x, x); + struct qreg sum = qir_FMUL(c, x, qir_uniform_f(trans, coeff[0])); + for (int i = 1; i < ARRAY_SIZE(coeff); i++) { + x = qir_FMUL(c, x, x2); + sum = qir_FADD(c, + sum, + qir_FMUL(c, + x, + qir_uniform_f(trans, coeff[i]))); + } + return sum; +} + static void emit_vertex_input(struct tgsi_to_qir *trans, int attr) { @@ -497,6 +531,7 @@ emit_tgsi_instruction(struct tgsi_to_qir *trans, [TGSI_OPCODE_POW] = { 0, tgsi_to_qir_pow }, [TGSI_OPCODE_TRUNC] = { 0, tgsi_to_qir_trunc }, [TGSI_OPCODE_FRC] = { 0, tgsi_to_qir_frc }, + [TGSI_OPCODE_SIN] = { 0, tgsi_to_qir_sin }, }; static int asdf = 0; uint32_t tgsi_op = tgsi_inst->Instruction.Opcode; |