[Mesa-dev] [PATCH] softpipe: fix offset wrapping calculations

Roland Scheidegger sroland at vmware.com
Tue May 26 19:01:24 PDT 2015


Thanks for addressing this, some minor issues.

Am 27.05.2015 um 03:14 schrieb Dave Airlie:
> Roland pointed out my previous attempt was lacking, so I enhanced the
> texwrap piglit test, and tested them. This fixes the offset calculations
> in a number of areas by adding the offset first, it also fixes the fastpaths,
> which I forgot to address in the previous commit.
> 
> Signed-off-by: Dave Airlie <airlied at redhat.com>
> ---
>  src/gallium/drivers/softpipe/sp_tex_sample.c | 76 +++++++++++++---------------
>  1 file changed, 34 insertions(+), 42 deletions(-)
> 
> diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.c b/src/gallium/drivers/softpipe/sp_tex_sample.c
> index 4ac3498..59bbd86 100644
> --- a/src/gallium/drivers/softpipe/sp_tex_sample.c
> +++ b/src/gallium/drivers/softpipe/sp_tex_sample.c
> @@ -145,14 +145,13 @@ wrap_nearest_clamp(float s, unsigned size, int offset, int *icoord)
>  {
>     /* s limited to [0,1] */
>     /* i limited to [0,size-1] */
> +   s += (float)offset / size;
Ok softpipe isn't about performance, but an (unconditional) float div
here is imho stretching that "we don't care about performance" line...
Don't forget float divs are usually non-pipelined, 20+ cycles
operations, I think this could possibly make a very real performance
difference.
I think either doing it conditionally based on offset != 0 or something like
     s = s * (float)size;
     if (offset)
        s += (float)offset;
     if (s <= 0.0F)
        *icoord = 0;
     else if (s >= size)
        *icoord = size - 1;
     else
        *icoord = util_itrunc(s);
Would probably be much better...

(And the same for the other wrap modes)

(You could also fix the compute_lambda_lod issue where gather needs to
use lod_zero and not lod_none case while you're here though I guess it's
sort of an orthogonal issue.)

Roland



>     if (s <= 0.0F)
>        *icoord = 0;
>     else if (s >= 1.0F)
>        *icoord = size - 1;
>     else
>        *icoord = util_ifloor(s * size);
> -   if (offset)
> -      *icoord = CLAMP(*icoord + offset, 0, size - 1);
>  }
>  
>  
> @@ -164,14 +163,13 @@ wrap_nearest_clamp_to_edge(float s, unsigned size, int offset, int *icoord)
>     const float min = 1.0F / (2.0F * size);
>     const float max = 1.0F - min;
>  
> +   s += (float)offset / size;
>     if (s < min)
>        *icoord = 0;
>     else if (s > max)
>        *icoord = size - 1;
>     else
>        *icoord = util_ifloor(s * size);
> -   if (offset)
> -      *icoord = CLAMP(*icoord + offset, 0, size - 1);
>  }
>  
>  
> @@ -182,14 +180,14 @@ wrap_nearest_clamp_to_border(float s, unsigned size, int offset, int *icoord)
>     /* i limited to [-1, size] */
>     const float min = -1.0F / (2.0F * size);
>     const float max = 1.0F - min;
> +
> +   s += (float)offset / size;
>     if (s <= min)
>        *icoord = -1;
>     else if (s >= max)
>        *icoord = size;
>     else
>        *icoord = util_ifloor(s * size);
> -   if (offset)
> -      *icoord = CLAMP(*icoord + offset, 0, size - 1);
>  }
>  
>  
> @@ -198,8 +196,12 @@ wrap_nearest_mirror_repeat(float s, unsigned size, int offset, int *icoord)
>  {
>     const float min = 1.0F / (2.0F * size);
>     const float max = 1.0F - min;
> -   const int flr = util_ifloor(s);
> -   float u = frac(s);
> +   int flr;
> +   float u;
> +
> +   s += (float)offset / size;
> +   flr = util_ifloor(s);
> +   u = frac(s);
>     if (flr & 1)
>        u = 1.0F - u;
>     if (u < min)
> @@ -208,8 +210,6 @@ wrap_nearest_mirror_repeat(float s, unsigned size, int offset, int *icoord)
>        *icoord = size - 1;
>     else
>        *icoord = util_ifloor(u * size);
> -   if (offset)
> -      *icoord = CLAMP(*icoord + offset, 0, size - 1);
>  }
>  
>  
> @@ -218,15 +218,13 @@ wrap_nearest_mirror_clamp(float s, unsigned size, int offset, int *icoord)
>  {
>     /* s limited to [0,1] */
>     /* i limited to [0,size-1] */
> -   const float u = fabsf(s);
> +   const float u = fabsf(s + (float)offset / size);
>     if (u <= 0.0F)
>        *icoord = 0;
>     else if (u >= 1.0F)
>        *icoord = size - 1;
>     else
>        *icoord = util_ifloor(u * size);
> -   if (offset)
> -      *icoord = CLAMP(*icoord + offset, 0, size - 1);
>  }
>  
>  
> @@ -237,15 +235,14 @@ wrap_nearest_mirror_clamp_to_edge(float s, unsigned size, int offset, int *icoor
>     /* i limited to [0, size-1] */
>     const float min = 1.0F / (2.0F * size);
>     const float max = 1.0F - min;
> -   const float u = fabsf(s);
> +   const float u = fabsf(s + (float)offset / size);
> +
>     if (u < min)
>        *icoord = 0;
>     else if (u > max)
>        *icoord = size - 1;
>     else
>        *icoord = util_ifloor(u * size);
> -   if (offset)
> -      *icoord = CLAMP(*icoord + offset, 0, size - 1);
>  }
>  
>  
> @@ -256,15 +253,14 @@ wrap_nearest_mirror_clamp_to_border(float s, unsigned size, int offset, int *ico
>     /* i limited to [0, size-1] */
>     const float min = -1.0F / (2.0F * size);
>     const float max = 1.0F - min;
> -   const float u = fabsf(s);
> +   const float u = fabsf(s + (float)offset / size);
> +
>     if (u < min)
>        *icoord = -1;
>     else if (u > max)
>        *icoord = size;
>     else
>        *icoord = util_ifloor(u * size);
> -   if (offset)
> -      *icoord = CLAMP(*icoord + offset, 0, size - 1);
>  }
>  
>  
> @@ -293,14 +289,10 @@ static void
>  wrap_linear_clamp(float s, unsigned size, int offset,
>                    int *icoord0, int *icoord1, float *w)
>  {
> -   float u = CLAMP(s, 0.0F, 1.0F);
> +   float u = CLAMP(s + (float)offset / size, 0.0F, 1.0F);
>     u = u * size - 0.5f;
>     *icoord0 = util_ifloor(u);
>     *icoord1 = *icoord0 + 1;
> -   if (offset) {
> -      *icoord0 = CLAMP(*icoord0 + offset, 0, size - 1);
> -      *icoord1 = CLAMP(*icoord1 + offset, 0, size - 1);
> -   }
>     *w = frac(u);
>  }
>  
> @@ -309,7 +301,7 @@ static void
>  wrap_linear_clamp_to_edge(float s, unsigned size, int offset,
>                            int *icoord0, int *icoord1, float *w)
>  {
> -   float u = CLAMP(s, 0.0F, 1.0F);
> +   float u = CLAMP(s + (float)offset / size, 0.0F, 1.0F);
>     u = u * size - 0.5f;
>     *icoord0 = util_ifloor(u);
>     *icoord1 = *icoord0 + 1;
> @@ -317,10 +309,6 @@ wrap_linear_clamp_to_edge(float s, unsigned size, int offset,
>        *icoord0 = 0;
>     if (*icoord1 >= (int) size)
>        *icoord1 = size - 1;
> -   if (offset) {
> -      *icoord0 = CLAMP(*icoord0 + offset, 0, size - 1);
> -      *icoord1 = CLAMP(*icoord1 + offset, 0, size - 1);
> -   }
>     *w = frac(u);
>  }
>  
> @@ -331,7 +319,7 @@ wrap_linear_clamp_to_border(float s, unsigned size, int offset,
>  {
>     const float min = -1.0F / (2.0F * size);
>     const float max = 1.0F - min;
> -   float u = CLAMP(s, min, max);
> +   float u = CLAMP(s + (float)offset / size, min, max);
>     u = u * size - 0.5f;
>     *icoord0 = util_ifloor(u);
>     *icoord1 = *icoord0 + 1;
> @@ -343,8 +331,12 @@ static void
>  wrap_linear_mirror_repeat(float s, unsigned size, int offset,
>                            int *icoord0, int *icoord1, float *w)
>  {
> -   const int flr = util_ifloor(s);
> -   float u = frac(s);
> +   int flr;
> +   float u;
> +
> +   s += (float)offset / size;
> +   flr = util_ifloor(s);
> +   u = frac(s);
>     if (flr & 1)
>        u = 1.0F - u;
>     u = u * size - 0.5F;
> @@ -362,13 +354,13 @@ static void
>  wrap_linear_mirror_clamp(float s, unsigned size, int offset,
>                           int *icoord0, int *icoord1, float *w)
>  {
> -   float u = fabsf(s);
> +   float u = fabsf(s + (float)size / offset);
>     if (u >= 1.0F)
>        u = (float) size;
>     else
>        u *= size;
>     u -= 0.5F;
> -   *icoord0 = util_ifloor(u);
> +   *icoord0 = util_ifloor(u) + offset;
>     *icoord1 = *icoord0 + 1;
>     *w = frac(u);
>  }
> @@ -378,7 +370,7 @@ static void
>  wrap_linear_mirror_clamp_to_edge(float s, unsigned size, int offset,
>                                   int *icoord0, int *icoord1, float *w)
>  {
> -   float u = fabsf(s);
> +   float u = fabsf(s + (float)offset / size);
>     if (u >= 1.0F)
>        u = (float) size;
>     else
> @@ -400,7 +392,7 @@ wrap_linear_mirror_clamp_to_border(float s, unsigned size, int offset,
>  {
>     const float min = -1.0F / (2.0F * size);
>     const float max = 1.0F - min;
> -   float u = fabsf(s);
> +   float u = fabsf(s + (float)offset / size);
>     if (u <= min)
>        u = min * size;
>     else if (u >= max)
> @@ -1040,8 +1032,8 @@ img_filter_2d_linear_repeat_POT(struct sp_sampler_view *sp_sview,
>     union tex_tile_address addr;
>     int c;
>  
> -   float u = args->s * xpot - 0.5F;
> -   float v = args->t * ypot - 0.5F;
> +   float u = (args->s * xpot - 0.5F) + args->offset[0];
> +   float v = (args->t * ypot - 0.5F) + args->offset[1];
>  
>     int uflr = util_ifloor(u);
>     int vflr = util_ifloor(v);
> @@ -1093,8 +1085,8 @@ img_filter_2d_nearest_repeat_POT(struct sp_sampler_view *sp_sview,
>     union tex_tile_address addr;
>     int c;
>  
> -   float u = args->s * xpot;
> -   float v = args->t * ypot;
> +   float u = args->s * xpot + args->offset[0];
> +   float v = args->t * ypot + args->offset[1];
>  
>     int uflr = util_ifloor(u);
>     int vflr = util_ifloor(v);
> @@ -1126,8 +1118,8 @@ img_filter_2d_nearest_clamp_POT(struct sp_sampler_view *sp_sview,
>     union tex_tile_address addr;
>     int c;
>  
> -   float u = args->s * xpot;
> -   float v = args->t * ypot;
> +   float u = args->s * xpot + args->offset[0];
> +   float v = args->t * ypot + args->offset[1];
>  
>     int x0, y0;
>     const float *out;
> 



More information about the mesa-dev mailing list