[Mesa-dev] [PATCH 1/3] svga: properly implement TRUNC instruction
Jose Fonseca
jfonseca at vmware.com
Tue Jul 3 02:04:12 PDT 2012
Reviewed-by: Jose Fonseca <jfonseca at vmware.com>
----- Original Message -----
> Was previously implemented with FLOOR.
> Fixes quite a few piglit tests of float->int conversion, integer
> division, etc.
>
> v2: clean up left over debug/devel code, per Jose
> ---
> src/gallium/drivers/svga/svga_tgsi_insn.c | 55
> ++++++++++++++++++++++++++++-
> 1 files changed, 54 insertions(+), 1 deletions(-)
>
> diff --git a/src/gallium/drivers/svga/svga_tgsi_insn.c
> b/src/gallium/drivers/svga/svga_tgsi_insn.c
> index 75853aa..595b06d 100644
> --- a/src/gallium/drivers/svga/svga_tgsi_insn.c
> +++ b/src/gallium/drivers/svga/svga_tgsi_insn.c
> @@ -2374,6 +2374,57 @@ static boolean emit_log(struct
> svga_shader_emitter *emit,
> }
>
>
> +/**
> + * Translate TGSI TRUNC instruction.
> + * We need to truncate toward zero. Ex: trunc(-1.9) = -1
> + * Different approaches are needed for VS versus PS.
> + */
> +static boolean
> +emit_trunc(struct svga_shader_emitter *emit,
> + const struct tgsi_full_instruction *insn)
> +{
> + SVGA3dShaderDestToken dst = translate_dst_register(emit, insn,
> 0);
> + const struct src_register src0 =
> + translate_src_register(emit, &insn->Src[0] );
> + SVGA3dShaderDestToken t1 = get_temp(emit);
> +
> + /* t1 = fract(abs(src0)) */
> + if (!submit_op1(emit, inst_token(SVGA3DOP_FRC), t1,
> absolute(src0)))
> + return FALSE;
> +
> + /* t1 = abs(src0) - t1 */
> + if (!submit_op2(emit, inst_token(SVGA3DOP_ADD), t1,
> absolute(src0),
> + negate(src(t1))))
> + return FALSE;
> +
> + /*
> + * Now we need to multiply t1 by the sign of the original value.
> + */
> + if (emit->unit == PIPE_SHADER_VERTEX) {
> + /* For VS: use SGN instruction */
> + /* Need another temp plus two extra/dummy registers */
> + SVGA3dShaderDestToken t2 = get_temp(emit), t3 =
> get_temp(emit),
> + t4 = get_temp(emit);
> +
> + /* t2 = sign(src0) */
> + if (!submit_op3(emit, inst_token(SVGA3DOP_SGN), t2, src0,
> + src(t3), src(t4)))
> + return FALSE;
> +
> + /* dst = t1 * t2 */
> + if (!submit_op2(emit, inst_token(SVGA3DOP_MUL), dst, src(t1),
> src(t2)))
> + return FALSE;
> + }
> + else {
> + /* For FS: Use CMP instruction */
> + return submit_op3(emit, inst_token( SVGA3DOP_CMP ), dst,
> + src0, src(t1), negate(src(t1)));
> + }
> +
> + return TRUE;
> +}
> +
> +
> static boolean emit_bgnsub( struct svga_shader_emitter *emit,
> unsigned position,
> const struct tgsi_full_instruction *insn
> )
> @@ -2464,9 +2515,11 @@ static boolean svga_emit_instruction( struct
> svga_shader_emitter *emit,
> return emit_call( emit, insn );
>
> case TGSI_OPCODE_FLR:
> - case TGSI_OPCODE_TRUNC: /* should be TRUNC, not FLR */
> return emit_floor( emit, insn );
>
> + case TGSI_OPCODE_TRUNC:
> + return emit_trunc( emit, insn );
> +
> case TGSI_OPCODE_CEIL:
> return emit_ceil( emit, insn );
>
> --
> 1.7.3.4
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/mesa-dev
>
More information about the mesa-dev
mailing list