[Mesa-dev] [PATCH 3/3] tgsi: implement ROUND and ROUNDEVEN instructions in exec module

Ian Romanick idr at freedesktop.org
Mon Jul 2 17:33:17 PDT 2012


On 07/02/2012 04:00 PM, Brian Paul wrote:

Won't this cause a constant and a non-constant to generate a different 
value?  The implementation of round() used in constant folding really 
needs to be the same as the one used by the code generator.  Right?

> ---
>   src/gallium/auxiliary/tgsi/tgsi_exec.c |   29 ++++++++++++++++++++++++-----
>   1 files changed, 24 insertions(+), 5 deletions(-)
>
> diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.c b/src/gallium/auxiliary/tgsi/tgsi_exec.c
> index 4c5e9d1..c4413e7 100644
> --- a/src/gallium/auxiliary/tgsi/tgsi_exec.c
> +++ b/src/gallium/auxiliary/tgsi/tgsi_exec.c
> @@ -320,10 +320,28 @@ static void
>   micro_rnd(union tgsi_exec_channel *dst,
>             const union tgsi_exec_channel *src)
>   {
> -   dst->f[0] = floorf(src->f[0] + 0.5f);
> -   dst->f[1] = floorf(src->f[1] + 0.5f);
> -   dst->f[2] = floorf(src->f[2] + 0.5f);
> -   dst->f[3] = floorf(src->f[3] + 0.5f);
> +   dst->f[0] = roundf(src->f[0]);
> +   dst->f[1] = roundf(src->f[1]);
> +   dst->f[2] = roundf(src->f[2]);
> +   dst->f[3] = roundf(src->f[3]);
> +}
> +
> +static void
> +micro_rnde(union tgsi_exec_channel *dst,
> +           const union tgsi_exec_channel *src)
> +{
> +   /* GLSL spec:
> +    * [roundEven] Returns a value equal to the nearest integer to x.
> +    * A fractional part of 0.5 will round toward the nearest even integer.
> +    * (Both 3.5 and 4.5 for x will return 4.0.)
> +    */
> +   unsigned i;
> +   for (i = 0; i<  4; i++) {
> +      float x = src->f[i];
> +      /* if x is odd, half = 0.5, else half = 0.49999 */
> +      float half = (((int) x)&  1) ? 0.5f : 0.499999f;
> +      dst->f[i] = (x>= 0.0f) ? floorf(x + half) : ceilf(x - half);
> +   }
>   }
>
>   static void
> @@ -3550,8 +3568,9 @@ exec_instruction(
>         break;
>
>      case TGSI_OPCODE_ROUND:
> -   case TGSI_OPCODE_ROUNDEVEN:
>         exec_vector_unary(mach, inst, micro_rnd, TGSI_EXEC_DATA_FLOAT, TGSI_EXEC_DATA_FLOAT);
> +   case TGSI_OPCODE_ROUNDEVEN:
> +      exec_vector_unary(mach, inst, micro_rnde, TGSI_EXEC_DATA_FLOAT, TGSI_EXEC_DATA_FLOAT);
>         break;
>
>      case TGSI_OPCODE_EX2:



More information about the mesa-dev mailing list