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

Dave Airlie airlied at gmail.com
Tue May 26 18:14:47 PDT 2015


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;
    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;
-- 
2.1.0



More information about the mesa-dev mailing list