[Mesa-dev] [PATCH 3/6] softpipe: add textureOffset support.

Roland Scheidegger sroland at vmware.com
Wed May 20 04:15:42 PDT 2015


I've got some nitpicks for the actual math performed for the offsets in 
some of the cases, but otherwise looks good. If it's slightly slower 
that's ok (initially I think the idea was to special purpose all these 
things into separate functions but this got a bit out of control with 
more and more stuff added to handle).

At least it is my understanding the actual order of things for texcoord 
wrapping should always be (or at least give the same results) 1. size 
mul, 2. int conversion, 3. offset add, 4. wrap.
I'm not entirely sure that real hw actually does things like that 
however for the more complicated modes (mirror etc.)...

Roland

On 05/20/2015 12:48 AM, Dave Airlie wrote:
> From: Dave Airlie <airlied at redhat.com>
>
> This was an oversight when GLSL1.30 was enabled, I think my
> misunderstanding.
>
> This fixes a bunch of tex-miplevel-selection tests under softpipe,
> and is required for textureGather support.
>
> I'm not sure this won't make sampling slowering, but its softpipe,
> correctness first and all that.
>
> Signed-off-by: Dave Airlie <airlied at redhat.com>
> ---
>   src/gallium/drivers/softpipe/sp_tex_sample.c | 155 ++++++++++++++++-----------
>   src/gallium/drivers/softpipe/sp_tex_sample.h |   4 +
>   2 files changed, 97 insertions(+), 62 deletions(-)
>
> diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.c b/src/gallium/drivers/softpipe/sp_tex_sample.c
> index a40a273..1a413a3 100644
> --- a/src/gallium/drivers/softpipe/sp_tex_sample.c
> +++ b/src/gallium/drivers/softpipe/sp_tex_sample.c
> @@ -131,17 +131,17 @@ repeat(int coord, unsigned size)
>    * \param icoord  returns the integer texcoords
>    */
>   static void
> -wrap_nearest_repeat(float s, unsigned size, int *icoord)
> +wrap_nearest_repeat(float s, unsigned size, int offset, int *icoord)
>   {
>      /* s limited to [0,1) */
>      /* i limited to [0,size-1] */
>      int i = util_ifloor(s * size);
> -   *icoord = repeat(i, size);
> +   *icoord = repeat(i + offset, size);
>   }
>
>
>   static void
> -wrap_nearest_clamp(float s, unsigned size, int *icoord)
> +wrap_nearest_clamp(float s, unsigned size, int offset, int *icoord)
>   {
>      /* s limited to [0,1] */
>      /* i limited to [0,size-1] */
> @@ -151,27 +151,32 @@ wrap_nearest_clamp(float s, unsigned size, int *icoord)
>         *icoord = size - 1;
>      else
>         *icoord = util_ifloor(s * size);
> +   if (offset)
> +      *icoord = CLAMP(*icoord + offset, 0, size - 1);
>   }
>
>
>   static void
> -wrap_nearest_clamp_to_edge(float s, unsigned size, int *icoord)
> +wrap_nearest_clamp_to_edge(float s, unsigned size, int offset, int *icoord)
>   {
>      /* s limited to [min,max] */
>      /* i limited to [0, size-1] */
>      const float min = 1.0F / (2.0F * size);
>      const float max = 1.0F - min;
> +
>      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);
>   }
>
>
>   static void
> -wrap_nearest_clamp_to_border(float s, unsigned size, int *icoord)
> +wrap_nearest_clamp_to_border(float s, unsigned size, int offset, int *icoord)
>   {
>      /* s limited to [min,max] */
>      /* i limited to [-1, size] */
> @@ -183,11 +188,13 @@ wrap_nearest_clamp_to_border(float s, unsigned size, int *icoord)
>         *icoord = size;
>      else
>         *icoord = util_ifloor(s * size);
> +   if (offset)
> +      *icoord = CLAMP(*icoord + offset, 0, size - 1);
>   }

That's not quite right, that would never return a border texel anymore.
The offset probably just needs to be added before the if/else logic (as 
float). (I believe that logic is mostly there so the float->int 
conversion doesn't overflow, since otherwise it wouldn't really make a 
difference when doing the actual lookup with border, though I don't 
think we really ensure that for other modes so probably could actually 
ditch any clamping...)


>
>
>   static void
> -wrap_nearest_mirror_repeat(float s, unsigned size, int *icoord)
> +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;
> @@ -201,11 +208,13 @@ wrap_nearest_mirror_repeat(float s, unsigned size, int *icoord)
>         *icoord = size - 1;
>      else
>         *icoord = util_ifloor(u * size);
> +   if (offset)
> +      *icoord = CLAMP(*icoord + offset, 0, size - 1);
>   }
>

This seems wrong too, offsets are added before doing wrap, so just 
clamping afterwards doesn't do the right thing.

>   static void
> -wrap_nearest_mirror_clamp(float s, unsigned size, int *icoord)
> +wrap_nearest_mirror_clamp(float s, unsigned size, int offset, int *icoord)
>   {
>      /* s limited to [0,1] */
>      /* i limited to [0,size-1] */
> @@ -216,11 +225,13 @@ wrap_nearest_mirror_clamp(float s, unsigned size, int *icoord)
>         *icoord = size - 1;
>      else
>         *icoord = util_ifloor(u * size);
> +   if (offset)
> +      *icoord = CLAMP(*icoord + offset, 0, size - 1);
>   }
>
Same here.


>   static void
> -wrap_nearest_mirror_clamp_to_edge(float s, unsigned size, int *icoord)
> +wrap_nearest_mirror_clamp_to_edge(float s, unsigned size, int offset, int *icoord)
>   {
>      /* s limited to [min,max] */
>      /* i limited to [0, size-1] */
> @@ -233,11 +244,13 @@ wrap_nearest_mirror_clamp_to_edge(float s, unsigned size, int *icoord)
>         *icoord = size - 1;
>      else
>         *icoord = util_ifloor(u * size);
> +   if (offset)
> +      *icoord = CLAMP(*icoord + offset, 0, size - 1);
>   }
>
Same here.


>   static void
> -wrap_nearest_mirror_clamp_to_border(float s, unsigned size, int *icoord)
> +wrap_nearest_mirror_clamp_to_border(float s, unsigned size, int offset, int *icoord)
>   {
>      /* s limited to [min,max] */
>      /* i limited to [0, size-1] */
> @@ -250,6 +263,8 @@ wrap_nearest_mirror_clamp_to_border(float s, unsigned size, int *icoord)
>         *icoord = size;
>      else
>         *icoord = util_ifloor(u * size);
> +   if (offset)
> +      *icoord = CLAMP(*icoord + offset, 0, size - 1);
>   }
>
And again (plus the border issue).


> @@ -264,30 +279,34 @@ wrap_nearest_mirror_clamp_to_border(float s, unsigned size, int *icoord)
>    * \param icoord  returns the computed integer texture coord
>    */
>   static void
> -wrap_linear_repeat(float s, unsigned size,
> +wrap_linear_repeat(float s, unsigned size, int offset,
>                      int *icoord0, int *icoord1, float *w)
>   {
>      float u = s * size - 0.5F;
> -   *icoord0 = repeat(util_ifloor(u), size);
> +   *icoord0 = repeat(util_ifloor(u) + offset, size);
>      *icoord1 = repeat(*icoord0 + 1, size);
>      *w = frac(u);
>   }
>
>
>   static void
> -wrap_linear_clamp(float s, unsigned size,
> +wrap_linear_clamp(float s, unsigned size, int offset,
>                     int *icoord0, int *icoord1, float *w)
>   {
>      float u = CLAMP(s, 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);
>   }
>

Similar to the nearest modes, this won't give border texels - the offset 
add needs to be done earlier, before the float clamp (but after the size 
mul).

>   static void
> -wrap_linear_clamp_to_edge(float s, unsigned size,
> +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);
> @@ -298,12 +317,16 @@ wrap_linear_clamp_to_edge(float s, unsigned size,
>         *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);
>   }
>

This is not quite ok to get correct mip weights you need to do it 
earlier and change things a bit (e.g. float size mul, add offsets, clamp).

>   static void
> -wrap_linear_clamp_to_border(float s, unsigned size,
> +wrap_linear_clamp_to_border(float s, unsigned size, int offset,
>                               int *icoord0, int *icoord1, float *w)
>   {
>      const float min = -1.0F / (2.0F * size);
> @@ -317,7 +340,7 @@ wrap_linear_clamp_to_border(float s, unsigned size,
>
>
>   static void
> -wrap_linear_mirror_repeat(float s, unsigned size,
> +wrap_linear_mirror_repeat(float s, unsigned size, int offset,
>                             int *icoord0, int *icoord1, float *w)
>   {
>      const int flr = util_ifloor(s);
> @@ -336,7 +359,7 @@ wrap_linear_mirror_repeat(float s, unsigned size,
>
>
>   static void
> -wrap_linear_mirror_clamp(float s, unsigned size,
> +wrap_linear_mirror_clamp(float s, unsigned size, int offset,
>                            int *icoord0, int *icoord1, float *w)
>   {
>      float u = fabsf(s);
> @@ -352,7 +375,7 @@ wrap_linear_mirror_clamp(float s, unsigned size,
>
>
>   static void
> -wrap_linear_mirror_clamp_to_edge(float s, unsigned size,
> +wrap_linear_mirror_clamp_to_edge(float s, unsigned size, int offset,
>                                    int *icoord0, int *icoord1, float *w)
>   {
>      float u = fabsf(s);
> @@ -372,7 +395,7 @@ wrap_linear_mirror_clamp_to_edge(float s, unsigned size,
>
>
>   static void
> -wrap_linear_mirror_clamp_to_border(float s, unsigned size,
> +wrap_linear_mirror_clamp_to_border(float s, unsigned size, int offset,
>                                      int *icoord0, int *icoord1, float *w)
>   {
>      const float min = -1.0F / (2.0F * size);
> @@ -395,10 +418,10 @@ wrap_linear_mirror_clamp_to_border(float s, unsigned size,
>    * PIPE_TEX_WRAP_CLAMP for nearest sampling, unnormalized coords.
>    */

What's with those modes? Ignored because noone uses them?

>   static void
> -wrap_nearest_unorm_clamp(float s, unsigned size, int *icoord)
> +wrap_nearest_unorm_clamp(float s, unsigned size, int offset, int *icoord)
>   {
>      int i = util_ifloor(s);
> -   *icoord = CLAMP(i, 0, (int) size-1);
> +   *icoord = CLAMP(i + offset, 0, (int) size-1);
>   }
>
>
> @@ -406,9 +429,9 @@ wrap_nearest_unorm_clamp(float s, unsigned size, int *icoord)
>    * PIPE_TEX_WRAP_CLAMP_TO_BORDER for nearest sampling, unnormalized coords.
>    */
>   static void
> -wrap_nearest_unorm_clamp_to_border(float s, unsigned size, int *icoord)
> +wrap_nearest_unorm_clamp_to_border(float s, unsigned size, int offset, int *icoord)
>   {
> -   *icoord = util_ifloor( CLAMP(s, -0.5F, (float) size + 0.5F) );
> +   *icoord = util_ifloor( CLAMP(s + offset, -0.5F, (float) size + 0.5F) );
>   }
>
>
> @@ -416,9 +439,9 @@ wrap_nearest_unorm_clamp_to_border(float s, unsigned size, int *icoord)
>    * PIPE_TEX_WRAP_CLAMP_TO_EDGE for nearest sampling, unnormalized coords.
>    */
>   static void
> -wrap_nearest_unorm_clamp_to_edge(float s, unsigned size, int *icoord)
> +wrap_nearest_unorm_clamp_to_edge(float s, unsigned size, int offset, int *icoord)
>   {
> -   *icoord = util_ifloor( CLAMP(s, 0.5F, (float) size - 0.5F) );
> +   *icoord = util_ifloor( CLAMP(s + offset, 0.5F, (float) size - 0.5F) );
>   }

(This is not your fault but I just realize we shouldn't use ifloor here 
and in similar places if the result can't be negative anyway - and the 
clamp should probably just use 0 instead of 0.5F since it may be easier 
and should give the same results...)

>
>
> @@ -426,11 +449,11 @@ wrap_nearest_unorm_clamp_to_edge(float s, unsigned size, int *icoord)
>    * PIPE_TEX_WRAP_CLAMP for linear sampling, unnormalized coords.
>    */
>   static void
> -wrap_linear_unorm_clamp(float s, unsigned size,
> +wrap_linear_unorm_clamp(float s, unsigned size, int offset,
>                           int *icoord0, int *icoord1, float *w)
>   {
>      /* Not exactly what the spec says, but it matches NVIDIA output */
> -   float u = CLAMP(s - 0.5F, 0.0f, (float) size - 1.0f);
> +   float u = CLAMP(s + offset - 0.5F, 0.0f, (float) size - 1.0f);
>      *icoord0 = util_ifloor(u);
>      *icoord1 = *icoord0 + 1;
>      *w = frac(u);
> @@ -441,10 +464,10 @@ wrap_linear_unorm_clamp(float s, unsigned size,
>    * PIPE_TEX_WRAP_CLAMP_TO_BORDER for linear sampling, unnormalized coords.
>    */
>   static void
> -wrap_linear_unorm_clamp_to_border(float s, unsigned size,
> +wrap_linear_unorm_clamp_to_border(float s, unsigned size, int offset,
>                                     int *icoord0, int *icoord1, float *w)
>   {
> -   float u = CLAMP(s, -0.5F, (float) size + 0.5F);
> +   float u = CLAMP(s + offset, -0.5F, (float) size + 0.5F);
>      u -= 0.5F;
>      *icoord0 = util_ifloor(u);
>      *icoord1 = *icoord0 + 1;
> @@ -458,10 +481,10 @@ wrap_linear_unorm_clamp_to_border(float s, unsigned size,
>    * PIPE_TEX_WRAP_CLAMP_TO_EDGE for linear sampling, unnormalized coords.
>    */
>   static void
> -wrap_linear_unorm_clamp_to_edge(float s, unsigned size,
> +wrap_linear_unorm_clamp_to_edge(float s, unsigned size, int offset,
>                                   int *icoord0, int *icoord1, float *w)
>   {
> -   float u = CLAMP(s, +0.5F, (float) size - 0.5F);
> +   float u = CLAMP(s + offset, +0.5F, (float) size - 0.5F);
>      u -= 0.5F;
>      *icoord0 = util_ifloor(u);
>      *icoord1 = *icoord0 + 1;
> @@ -1154,7 +1177,7 @@ img_filter_1d_nearest(struct sp_sampler_view *sp_sview,
>      addr.value = 0;
>      addr.bits.level = args->level;
>
> -   sp_samp->nearest_texcoord_s(args->s, width, &x);
> +   sp_samp->nearest_texcoord_s(args->s, width, args->offset[0], &x);
>
>      out = get_texel_2d(sp_sview, sp_samp, addr, x, 0);
>      for (c = 0; c < TGSI_QUAD_SIZE; c++)
> @@ -1186,7 +1209,7 @@ img_filter_1d_array_nearest(struct sp_sampler_view *sp_sview,
>      addr.value = 0;
>      addr.bits.level = args->level;
>
> -   sp_samp->nearest_texcoord_s(args->s, width, &x);
> +   sp_samp->nearest_texcoord_s(args->s, width, args->offset[0], &x);
>      layer = coord_to_layer(args->t, sp_sview->base.u.tex.first_layer,
>                             sp_sview->base.u.tex.last_layer);
>
> @@ -1222,8 +1245,8 @@ img_filter_2d_nearest(struct sp_sampler_view *sp_sview,
>      addr.value = 0;
>      addr.bits.level = args->level;
>
> -   sp_samp->nearest_texcoord_s(args->s, width, &x);
> -   sp_samp->nearest_texcoord_t(args->t, height, &y);
> +   sp_samp->nearest_texcoord_s(args->s, width, args->offset[0], &x);
> +   sp_samp->nearest_texcoord_t(args->t, height, args->offset[1], &y);
>
>      out = get_texel_2d(sp_sview, sp_samp, addr, x, y);
>      for (c = 0; c < TGSI_QUAD_SIZE; c++)
> @@ -1257,8 +1280,8 @@ img_filter_2d_array_nearest(struct sp_sampler_view *sp_sview,
>      addr.value = 0;
>      addr.bits.level = args->level;
>
> -   sp_samp->nearest_texcoord_s(args->s, width, &x);
> -   sp_samp->nearest_texcoord_t(args->t, height, &y);
> +   sp_samp->nearest_texcoord_s(args->s, width, args->offset[0], &x);
> +   sp_samp->nearest_texcoord_t(args->t, height, args->offset[1], &y);
>      layer = coord_to_layer(args->p, sp_sview->base.u.tex.first_layer,
>                             sp_sview->base.u.tex.last_layer);
>
> @@ -1299,12 +1322,12 @@ img_filter_cube_nearest(struct sp_sampler_view *sp_sview,
>       * mode CLAMP_TO_EDGE.
>       */
>      if (sp_samp->base.seamless_cube_map) {
> -      wrap_nearest_clamp_to_edge(args->s, width, &x);
> -      wrap_nearest_clamp_to_edge(args->t, height, &y);
> +      wrap_nearest_clamp_to_edge(args->s, width, args->offset[0], &x);
> +      wrap_nearest_clamp_to_edge(args->t, height, args->offset[1], &y);
>      } else {
>         /* Would probably make sense to ignore mode and just do edge clamp */
> -      sp_samp->nearest_texcoord_s(args->s, width, &x);
> -      sp_samp->nearest_texcoord_t(args->t, height, &y);
> +      sp_samp->nearest_texcoord_s(args->s, width, args->offset[0], &x);
> +      sp_samp->nearest_texcoord_t(args->t, height, args->offset[1], &y);
>      }
>
>      layerface = args->face_id + sp_sview->base.u.tex.first_layer;
> @@ -1339,8 +1362,8 @@ img_filter_cube_array_nearest(struct sp_sampler_view *sp_sview,
>      addr.value = 0;
>      addr.bits.level = args->level;
>
> -   sp_samp->nearest_texcoord_s(args->s, width, &x);
> -   sp_samp->nearest_texcoord_t(args->t, height, &y);
> +   sp_samp->nearest_texcoord_s(args->s, width, args->offset[0], &x);
> +   sp_samp->nearest_texcoord_t(args->t, height, args->offset[1], &y);
>      layerface = coord_to_layer(6 * args->p + sp_sview->base.u.tex.first_layer,
>                                 sp_sview->base.u.tex.first_layer,
>                                 sp_sview->base.u.tex.last_layer - 5) + args->face_id;
> @@ -1375,9 +1398,9 @@ img_filter_3d_nearest(struct sp_sampler_view *sp_sview,
>      assert(height > 0);
>      assert(depth > 0);
>
> -   sp_samp->nearest_texcoord_s(args->s, width,  &x);
> -   sp_samp->nearest_texcoord_t(args->t, height, &y);
> -   sp_samp->nearest_texcoord_p(args->p, depth,  &z);
> +   sp_samp->nearest_texcoord_s(args->s, width,  args->offset[0], &x);
> +   sp_samp->nearest_texcoord_t(args->t, height, args->offset[1], &y);
> +   sp_samp->nearest_texcoord_p(args->p, depth,  args->offset[2], &z);
>
>      addr.value = 0;
>      addr.bits.level = args->level;
> @@ -1409,7 +1432,7 @@ img_filter_1d_linear(struct sp_sampler_view *sp_sview,
>      addr.value = 0;
>      addr.bits.level = args->level;
>
> -   sp_samp->linear_texcoord_s(args->s, width, &x0, &x1, &xw);
> +   sp_samp->linear_texcoord_s(args->s, width, args->offset[0], &x0, &x1, &xw);
>
>      tx0 = get_texel_2d(sp_sview, sp_samp, addr, x0, 0);
>      tx1 = get_texel_2d(sp_sview, sp_samp, addr, x1, 0);
> @@ -1441,7 +1464,7 @@ img_filter_1d_array_linear(struct sp_sampler_view *sp_sview,
>      addr.value = 0;
>      addr.bits.level = args->level;
>
> -   sp_samp->linear_texcoord_s(args->s, width, &x0, &x1, &xw);
> +   sp_samp->linear_texcoord_s(args->s, width, args->offset[0], &x0, &x1, &xw);
>      layer = coord_to_layer(args->t, sp_sview->base.u.tex.first_layer,
>                             sp_sview->base.u.tex.last_layer);
>
> @@ -1477,8 +1500,8 @@ img_filter_2d_linear(struct sp_sampler_view *sp_sview,
>      addr.value = 0;
>      addr.bits.level = args->level;
>
> -   sp_samp->linear_texcoord_s(args->s, width,  &x0, &x1, &xw);
> -   sp_samp->linear_texcoord_t(args->t, height, &y0, &y1, &yw);
> +   sp_samp->linear_texcoord_s(args->s, width,  args->offset[0], &x0, &x1, &xw);
> +   sp_samp->linear_texcoord_t(args->t, height, args->offset[1], &y0, &y1, &yw);
>
>      tx0 = get_texel_2d(sp_sview, sp_samp, addr, x0, y0);
>      tx1 = get_texel_2d(sp_sview, sp_samp, addr, x1, y0);
> @@ -1516,8 +1539,8 @@ img_filter_2d_array_linear(struct sp_sampler_view *sp_sview,
>      addr.value = 0;
>      addr.bits.level = args->level;
>
> -   sp_samp->linear_texcoord_s(args->s, width,  &x0, &x1, &xw);
> -   sp_samp->linear_texcoord_t(args->t, height, &y0, &y1, &yw);
> +   sp_samp->linear_texcoord_s(args->s, width,  args->offset[0], &x0, &x1, &xw);
> +   sp_samp->linear_texcoord_t(args->t, height, args->offset[1], &y0, &y1, &yw);
>      layer = coord_to_layer(args->p, sp_sview->base.u.tex.first_layer,
>                             sp_sview->base.u.tex.last_layer);
>
> @@ -1565,12 +1588,12 @@ img_filter_cube_linear(struct sp_sampler_view *sp_sview,
>       */
>      if (sp_samp->base.seamless_cube_map) {
>         /* Note this is a bit overkill, actual clamping is not required */
> -      wrap_linear_clamp_to_border(args->s, width, &x0, &x1, &xw);
> -      wrap_linear_clamp_to_border(args->t, height, &y0, &y1, &yw);
> +      wrap_linear_clamp_to_border(args->s, width, args->offset[0], &x0, &x1, &xw);
> +      wrap_linear_clamp_to_border(args->t, height, args->offset[1], &y0, &y1, &yw);
>      } else {
>         /* Would probably make sense to ignore mode and just do edge clamp */
> -      sp_samp->linear_texcoord_s(args->s, width,  &x0, &x1, &xw);
> -      sp_samp->linear_texcoord_t(args->t, height, &y0, &y1, &yw);
> +      sp_samp->linear_texcoord_s(args->s, width,  args->offset[0], &x0, &x1, &xw);
> +      sp_samp->linear_texcoord_t(args->t, height, args->offset[1], &y0, &y1, &yw);
>      }
>
>      layer = sp_sview->base.u.tex.first_layer;
> @@ -1626,12 +1649,12 @@ img_filter_cube_array_linear(struct sp_sampler_view *sp_sview,
>       */
>      if (sp_samp->base.seamless_cube_map) {
>         /* Note this is a bit overkill, actual clamping is not required */
> -      wrap_linear_clamp_to_border(args->s, width, &x0, &x1, &xw);
> -      wrap_linear_clamp_to_border(args->t, height, &y0, &y1, &yw);
> +      wrap_linear_clamp_to_border(args->s, width, args->offset[0], &x0, &x1, &xw);
> +      wrap_linear_clamp_to_border(args->t, height, args->offset[1], &y0, &y1, &yw);
>      } else {
>         /* Would probably make sense to ignore mode and just do edge clamp */
> -      sp_samp->linear_texcoord_s(args->s, width,  &x0, &x1, &xw);
> -      sp_samp->linear_texcoord_t(args->t, height, &y0, &y1, &yw);
> +      sp_samp->linear_texcoord_s(args->s, width,  args->offset[0], &x0, &x1, &xw);
> +      sp_samp->linear_texcoord_t(args->t, height, args->offset[1], &y0, &y1, &yw);
>      }
>
>      layer = coord_to_layer(6 * args->p + sp_sview->base.u.tex.first_layer,
> @@ -1682,9 +1705,9 @@ img_filter_3d_linear(struct sp_sampler_view *sp_sview,
>      assert(height > 0);
>      assert(depth > 0);
>
> -   sp_samp->linear_texcoord_s(args->s, width,  &x0, &x1, &xw);
> -   sp_samp->linear_texcoord_t(args->t, height, &y0, &y1, &yw);
> -   sp_samp->linear_texcoord_p(args->p, depth,  &z0, &z1, &zw);
> +   sp_samp->linear_texcoord_s(args->s, width,  args->offset[0], &x0, &x1, &xw);
> +   sp_samp->linear_texcoord_t(args->t, height, args->offset[1], &y0, &y1, &yw);
> +   sp_samp->linear_texcoord_p(args->p, depth,  args->offset[2], &z0, &z1, &zw);
>
>      tx00 = get_texel_3d(sp_sview, sp_samp, addr, x0, y0, z0);
>      tx01 = get_texel_3d(sp_sview, sp_samp, addr, x1, y0, z0);
> @@ -1820,6 +1843,8 @@ mip_filter_linear(struct sp_sampler_view *sp_sview,
>
>      compute_lambda_lod(sp_sview, sp_samp, s, t, p, lod_in, filt_args->control, lod);
>
> +   args.offset = filt_args->offset;
> +
>      for (j = 0; j < TGSI_QUAD_SIZE; j++) {
>         int level0 = psview->u.tex.first_level + (int)lod[j];
>
> @@ -1880,6 +1905,8 @@ mip_filter_nearest(struct sp_sampler_view *sp_sview,
>      float lod[TGSI_QUAD_SIZE];
>      int j;
>      struct img_filter_args args;
> +
> +   args.offset = filt_args->offset;
>      compute_lambda_lod(sp_sview, sp_samp, s, t, p, lod_in, filt_args->control, lod);
>
>      for (j = 0; j < TGSI_QUAD_SIZE; j++) {
> @@ -1922,6 +1949,8 @@ mip_filter_none(struct sp_sampler_view *sp_sview,
>      struct img_filter_args args;
>
>      args.level = sp_sview->base.u.tex.first_level;
> +   args.offset = filt_args->offset;
> +
>      compute_lambda_lod(sp_sview, sp_samp, s, t, p, lod_in, filt_args->control, lod);
>
>      for (j = 0; j < TGSI_QUAD_SIZE; j++) {
> @@ -1955,6 +1984,7 @@ mip_filter_none_no_filter_select(struct sp_sampler_view *sp_sview,
>      int j;
>      struct img_filter_args args;
>      args.level = sp_sview->base.u.tex.first_level;
> +   args.offset = filt_args->offset;
>      for (j = 0; j < TGSI_QUAD_SIZE; j++) {
>         args.s = s[j];
>         args.t = t[j];
> @@ -3265,6 +3295,7 @@ sp_tgsi_get_samples(struct tgsi_sampler *tgsi_sampler,
>      }
>
>      filt_args.control = control;
> +   filt_args.offset = offset;
>      sp_samp->sp_sview[sview_index].get_samples(&sp_samp->sp_sview[sview_index],
>                                                 sp_samp->sp_sampler[sampler_index],
>                                                 s, t, p, c0, lod, &filt_args, rgba);
> diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.h b/src/gallium/drivers/softpipe/sp_tex_sample.h
> index 9890b19..2eca3fb 100644
> --- a/src/gallium/drivers/softpipe/sp_tex_sample.h
> +++ b/src/gallium/drivers/softpipe/sp_tex_sample.h
> @@ -38,10 +38,12 @@ struct sp_sampler;
>
>   typedef void (*wrap_nearest_func)(float s,
>                                     unsigned size,
> +                                  int offset,
>                                     int *icoord);
>
>   typedef void (*wrap_linear_func)(float s,
>                                    unsigned size,
> +                                 int offset,
>                                    int *icoord0,
>                                    int *icoord1,
>                                    float *w);
> @@ -57,6 +59,7 @@ struct img_filter_args {
>      float p;
>      unsigned level;
>      unsigned face_id;
> +   const int8_t *offset;
>   };
>
>   typedef void (*img_filter_func)(struct sp_sampler_view *sp_sview,
> @@ -66,6 +69,7 @@ typedef void (*img_filter_func)(struct sp_sampler_view *sp_sview,
>
>   struct filter_args {
>      enum tgsi_sampler_control control;
> +   const int8_t *offset;
>   };
>
>   typedef void (*mip_filter_func)(struct sp_sampler_view *sp_sview,
>




More information about the mesa-dev mailing list