summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Oliveira <igor.oliveira@openbossa.org>2010-01-19 19:21:47 -0400
committerIgor Oliveira <igor.oliveira@openbossa.org>2010-09-29 23:07:26 -0400
commit2274bbcd34fb45c88c81772d2da2749c47decb09 (patch)
tree9b2bfbd8220137395f2b135b3ccdff3580282e51
parent26a7edf37a98eca6ac788d052360e1dc8fee437c (diff)
tgsi: implement DFRACEXP
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_exec.c40
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_info.c3
2 files changed, 42 insertions, 1 deletions
diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.c b/src/gallium/auxiliary/tgsi/tgsi_exec.c
index c933f5df45..e29dead8cb 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_exec.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_exec.c
@@ -346,6 +346,17 @@ micro_dldexp(union tgsi_double_channel *dst,
}
static void
+micro_dfracexp(union tgsi_double_channel *dst,
+ union tgsi_exec_channel *dst_exp,
+ const union tgsi_double_channel *src)
+{
+ dst->d[0] = frexp(src->d[0], &dst_exp->i[0]);
+ dst->d[1] = frexp(src->d[1], &dst_exp->i[1]);
+ dst->d[2] = frexp(src->d[2], &dst_exp->i[2]);
+ dst->d[3] = frexp(src->d[3], &dst_exp->i[3]);
+}
+
+static void
micro_exp2(union tgsi_exec_channel *dst,
const union tgsi_exec_channel *src)
{
@@ -2734,6 +2745,31 @@ exec_d2f(struct tgsi_exec_machine *mach,
}
static void
+exec_dfracexp(struct tgsi_exec_machine *mach,
+ const struct tgsi_full_instruction *inst)
+{
+ union tgsi_double_channel src;
+ union tgsi_double_channel dst;
+ union tgsi_exec_channel dst_exp;
+
+ if (((inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_XY) == TGSI_WRITEMASK_XY) &&
+ ((inst->Dst[1].Register.WriteMask & TGSI_WRITEMASK_X) == TGSI_WRITEMASK_X)) {
+ fetch_double_channel(mach, &src, &inst->Src[0], CHAN_X, CHAN_Y);
+ micro_dfracexp(&dst, &dst_exp, &src);
+ store_double_channel(mach, &dst, &inst->Dst[0], inst, CHAN_X, CHAN_Y);
+ store_dest(mach, &dst_exp, &inst->Dst[1], inst, CHAN_X, TGSI_EXEC_DATA_INT);
+ }
+ if (((inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_ZW) == TGSI_WRITEMASK_ZW) &&
+ ((inst->Dst[1].Register.WriteMask & TGSI_WRITEMASK_Y) == TGSI_WRITEMASK_Y)) {
+ fetch_double_channel(mach, &src, &inst->Src[0], CHAN_Z, CHAN_W);
+ micro_dfracexp(&dst, &dst_exp, &src);
+ store_double_channel(mach, &dst, &inst->Dst[0], inst, CHAN_Z, CHAN_W);
+ store_dest(mach, &dst_exp, &inst->Dst[1], inst, CHAN_Y, TGSI_EXEC_DATA_INT);
+ }
+}
+
+
+static void
micro_i2f(union tgsi_exec_channel *dst,
const union tgsi_exec_channel *src)
{
@@ -4040,6 +4076,10 @@ exec_instruction(
exec_double_binary(mach, inst, micro_dldexp);
break;
+ case TGSI_OPCODE_DFRACEXP:
+ exec_dfracexp(mach, inst);
+ break;
+
default:
printf("%d", inst->Instruction.Opcode);
assert( 0 );
diff --git a/src/gallium/auxiliary/tgsi/tgsi_info.c b/src/gallium/auxiliary/tgsi/tgsi_info.c
index 86f4b8eb5a..6de9e29a1f 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_info.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_info.c
@@ -192,7 +192,8 @@ static const struct tgsi_opcode_info opcode_info[TGSI_OPCODE_LAST] =
{ 1, 1, 0, 0 ,0, 0, "DSQRT", TGSI_OPCODE_DSQRT },
{ 1, 3, 0, 0 ,0, 0, "DMAD", TGSI_OPCODE_DMAD },
{ 1, 1, 0, 0, 0, 0, "DFRAC", TGSI_OPCODE_DFRAC},
- { 1, 2, 0, 0, 0, 0, "DLDEXP", TGSI_OPCODE_DLDEXP}
+ { 1, 2, 0, 0, 0, 0, "DLDEXP", TGSI_OPCODE_DLDEXP},
+ { 2, 1, 0, 0, 0, 0, "DFRACEXP", TGSI_OPCODE_DFRACEXP}
};
const struct tgsi_opcode_info *