[Mesa-dev] [PATCH 3/3] svga: implement TGSI_OPCODE_ROUND

Jose Fonseca jfonseca at vmware.com
Tue Jul 3 02:08:50 PDT 2012


Looks good AFAICT.

Reviewed-by: Jose Fonseca <jfonseca at vmware.com>


Jose

----- Original Message -----
> ROUND and TRUNC are implemented with one function to reduce code
> duplication.
> ---
>  src/gallium/drivers/svga/svga_tgsi_insn.c |   69
>  ++++++++++++++++++++++-------
>  1 files changed, 53 insertions(+), 16 deletions(-)
> 
> diff --git a/src/gallium/drivers/svga/svga_tgsi_insn.c
> b/src/gallium/drivers/svga/svga_tgsi_insn.c
> index a2d6b51..eec40c7 100644
> --- a/src/gallium/drivers/svga/svga_tgsi_insn.c
> +++ b/src/gallium/drivers/svga/svga_tgsi_insn.c
> @@ -632,11 +632,11 @@ create_zero_immediate( struct
> svga_shader_emitter *emit )
>  {
>     unsigned idx = emit->nr_hw_float_const++;
>  
> -   /* Emit the constant (0, 0, -1, 1) and use swizzling to generate
> +   /* Emit the constant (0, 0.5, -1, 1) and use swizzling to
> generate
>      * other useful vectors.
>      */
>     if (!emit_def_const( emit, SVGA3D_CONST_TYPE_FLOAT,
> -                        idx, 0, 0, -1, 1 ))
> +                        idx, 0, 0.5, -1, 1 ))
>        return FALSE;
>  
>     emit->zero_immediate_idx = idx;
> @@ -732,6 +732,16 @@ get_pos_neg_one_immediate( struct
> svga_shader_emitter *emit )
>                    3, 3, 3, 2);
>  }
>  
> +/* returns {0.5, 0.5, 0.5, 0.5} immediate */
> +static INLINE struct src_register
> +get_half_immediate( struct svga_shader_emitter *emit )
> +{
> +   assert(emit->created_zero_immediate);
> +   assert(emit->zero_immediate_idx >= 0);
> +   return swizzle(src_register(SVGA3DREG_CONST,
> emit->zero_immediate_idx),
> +                  1, 1, 1, 1);
> +}
> +
>  /* returns the loop const */
>  static INLINE struct src_register
>  get_loop_const( struct svga_shader_emitter *emit )
> @@ -2376,34 +2386,57 @@ static boolean emit_log(struct
> svga_shader_emitter *emit,
>  
>  
>  /**
> - * Translate TGSI TRUNC instruction.
> + * Translate TGSI TRUNC or ROUND 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)
> +emit_trunc_round(struct svga_shader_emitter *emit,
> +                 const struct tgsi_full_instruction *insn,
> +                 boolean round)
>  {
>     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;
> +   if (round) {
> +      SVGA3dShaderDestToken t0 = get_temp(emit);
> +      struct src_register half = get_half_immediate(emit);
>  
> -   /* t1 = abs(src0) - t1 */
> -   if (!submit_op2(emit, inst_token(SVGA3DOP_ADD), t1,
> absolute(src0),
> -                   negate(src(t1))))
> -      return FALSE;
> +      /* t0 = abs(src0) + 0.5 */
> +      if (!submit_op2(emit, inst_token(SVGA3DOP_ADD), t0,
> +                      absolute(src0), half))
> +         return FALSE;
> +
> +      /* t1 = fract(t0) */
> +      if (!submit_op1(emit, inst_token(SVGA3DOP_FRC), t1, src(t0)))
> +         return FALSE;
> +
> +      /* t1 = t0 - t1 */
> +      if (!submit_op2(emit, inst_token(SVGA3DOP_ADD), t1, src(t0),
> +                      negate(src(t1))))
> +         return FALSE;
> +   }
> +   else {
> +      /* trunc */
> +
> +      /* 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 */
> +      /* Need two extra/dummy registers: */
>        SVGA3dShaderDestToken t2 = get_temp(emit), t3 =
>        get_temp(emit),
>           t4 = get_temp(emit);
>  
> @@ -2519,7 +2552,12 @@ static boolean svga_emit_instruction( struct
> svga_shader_emitter *emit,
>        return emit_floor( emit, insn );
>  
>     case TGSI_OPCODE_TRUNC:
> -      return emit_trunc( emit, insn );
> +      return emit_trunc_round( emit, insn, FALSE );
> +
> +   case TGSI_OPCODE_ROUNDEVEN:
> +      /* Note: ROUNDEVEN not properly implemented yet */
> +   case TGSI_OPCODE_ROUND:
> +      return emit_trunc_round( emit, insn, TRUE );
>  
>     case TGSI_OPCODE_CEIL:
>        return emit_ceil( emit, insn );
> @@ -2612,8 +2650,6 @@ static boolean svga_emit_instruction( struct
> svga_shader_emitter *emit,
>         * about:
>         */
>     case TGSI_OPCODE_CLAMP:
> -   case TGSI_OPCODE_ROUND:
> -   case TGSI_OPCODE_ROUNDEVEN:
>     case TGSI_OPCODE_AND:
>     case TGSI_OPCODE_OR:
>     case TGSI_OPCODE_I2F:
> @@ -3102,6 +3138,7 @@ needs_to_create_zero( struct
> svga_shader_emitter *emit )
>         emit->info.opcode_count[TGSI_OPCODE_BGNLOOP] >= 1 ||
>         emit->info.opcode_count[TGSI_OPCODE_DDX] >= 1 ||
>         emit->info.opcode_count[TGSI_OPCODE_DDY] >= 1 ||
> +       emit->info.opcode_count[TGSI_OPCODE_ROUND] >= 1 ||
>         emit->info.opcode_count[TGSI_OPCODE_SGE] >= 1 ||
>         emit->info.opcode_count[TGSI_OPCODE_SGT] >= 1 ||
>         emit->info.opcode_count[TGSI_OPCODE_SLE] >= 1 ||
> --
> 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