From: Eric Anholt Date: Wed, 6 Aug 2014 23:41:12 +0000 (-0700) Subject: vc4: Add support for the SIN instruction. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=663ffff0e747efebf434b57fe1e149619be0d228;p=mesa.git vc4: Add support for the SIN instruction. v2: Rebase on helpers. --- 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;