[Mesa-dev] [PATCH 1/2] gallivm: add support for texel offsets for ordinary texturing.

Jose Fonseca jfonseca at vmware.com
Fri Mar 1 04:09:44 PST 2013


Looks great to me.

Bumping GLSL support to 140 also sounds great.

Jose

----- Original Message -----
> From: Roland Scheidegger <sroland at vmware.com>
> 
> This was previously only handled for texelFetch (much easier).
> Depending on the wrap mode this works slightly differently (for somewhat
> efficient implementation), hence have to do that separately in all roughly
> 137 places - it is easy if we use fixed point coords for wrapping, however
> some wrapping modes are near impossible with fixed point (the repeat stuff)
> hence we have to normalize the offsets if we can't do the wrapping in
> unnormalized space (which is a division which is slow but should still be
> much better than the alternative, which would be integer modulo for wrapping
> which is just unusable). This should still give accurate results in all
> cases that really matter, though it might be not quite conformant behavior
> for some apis (but we have much worse problems there anyway even without
> using offsets).
> (Untested, no piglit test.)
> ---
>  src/gallium/auxiliary/gallivm/lp_bld_sample_aos.c |  130
>  +++++++++++++++-----
>  src/gallium/auxiliary/gallivm/lp_bld_sample_aos.h |    1 +
>  src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c |  132
>  +++++++++++++++++----
>  3 files changed, 210 insertions(+), 53 deletions(-)
> 
> diff --git a/src/gallium/auxiliary/gallivm/lp_bld_sample_aos.c
> b/src/gallium/auxiliary/gallivm/lp_bld_sample_aos.c
> index bddff2c..16d5718 100644
> --- a/src/gallium/auxiliary/gallivm/lp_bld_sample_aos.c
> +++ b/src/gallium/auxiliary/gallivm/lp_bld_sample_aos.c
> @@ -64,9 +64,11 @@
>   * for scaled integer texcoords.
>   * \param block_length  is the length of the pixel block along the
>   *                      coordinate axis
> - * \param coord  the incoming texcoord (s,t,r or q) scaled to the texture
> size
> + * \param coord  the incoming texcoord (s,t or r) scaled to the texture size
> + * \param coord_f  the incoming texcoord (s,t or r) as float vec
>   * \param length  the texture size along one dimension
>   * \param stride  pixel stride along the coordinate axis (in bytes)
> + * \param offset  the texel offset along the coord axis
>   * \param is_pot  if TRUE, length is a power of two
>   * \param wrap_mode  one of PIPE_TEX_WRAP_x
>   * \param out_offset  byte offset for the wrapped coordinate
> @@ -79,6 +81,7 @@ lp_build_sample_wrap_nearest_int(struct
> lp_build_sample_context *bld,
>                                   LLVMValueRef coord_f,
>                                   LLVMValueRef length,
>                                   LLVMValueRef stride,
> +                                 LLVMValueRef offset,
>                                   boolean is_pot,
>                                   unsigned wrap_mode,
>                                   LLVMValueRef *out_offset,
> @@ -97,6 +100,11 @@ lp_build_sample_wrap_nearest_int(struct
> lp_build_sample_context *bld,
>        else {
>           struct lp_build_context *coord_bld = &bld->coord_bld;
>           LLVMValueRef length_f = lp_build_int_to_float(coord_bld, length);
> +         if (offset) {
> +            offset = lp_build_int_to_float(coord_bld, offset);
> +            offset = lp_build_div(coord_bld, offset, length_f);
> +            coord_f = lp_build_add(coord_bld, coord_f, offset);
> +         }
>           coord = lp_build_fract_safe(coord_bld, coord_f);
>           coord = lp_build_mul(coord_bld, coord, length_f);
>           coord = lp_build_itrunc(coord_bld, coord);
> @@ -126,8 +134,9 @@ lp_build_sample_wrap_nearest_int(struct
> lp_build_sample_context *bld,
>  /**
>   * Build LLVM code for texture coord wrapping, for nearest filtering,
>   * for float texcoords.
> - * \param coord  the incoming texcoord (s,t,r or q)
> + * \param coord  the incoming texcoord (s,t or r)
>   * \param length  the texture size along one dimension
> + * \param offset  the texel offset along the coord axis
>   * \param is_pot  if TRUE, length is a power of two
>   * \param wrap_mode  one of PIPE_TEX_WRAP_x
>   * \param icoord  the texcoord after wrapping, as int
> @@ -136,6 +145,7 @@ static void
>  lp_build_sample_wrap_nearest_float(struct lp_build_sample_context *bld,
>                                     LLVMValueRef coord,
>                                     LLVMValueRef length,
> +                                   LLVMValueRef offset,
>                                     boolean is_pot,
>                                     unsigned wrap_mode,
>                                     LLVMValueRef *icoord)
> @@ -145,6 +155,12 @@ lp_build_sample_wrap_nearest_float(struct
> lp_build_sample_context *bld,
>  
>     switch(wrap_mode) {
>     case PIPE_TEX_WRAP_REPEAT:
> +      if (offset) {
> +         /* this is definitely not ideal for POT case */
> +         offset = lp_build_int_to_float(coord_bld, offset);
> +         offset = lp_build_div(coord_bld, offset, length);
> +         coord = lp_build_add(coord_bld, coord, offset);
> +      }
>        /* take fraction, unnormalize */
>        coord = lp_build_fract_safe(coord_bld, coord);
>        coord = lp_build_mul(coord_bld, coord, length);
> @@ -156,6 +172,10 @@ lp_build_sample_wrap_nearest_float(struct
> lp_build_sample_context *bld,
>           /* scale coord to length */
>           coord = lp_build_mul(coord_bld, coord, length);
>        }
> +      if (offset) {
> +         offset = lp_build_int_to_float(coord_bld, offset);
> +         coord = lp_build_add(coord_bld, coord, offset);
> +      }
>        coord = lp_build_clamp(coord_bld, coord, coord_bld->zero,
>                               length_minus_one);
>        *icoord = lp_build_itrunc(coord_bld, coord);
> @@ -178,9 +198,11 @@ lp_build_sample_wrap_nearest_float(struct
> lp_build_sample_context *bld,
>   * for scaled integer texcoords.
>   * \param block_length  is the length of the pixel block along the
>   *                      coordinate axis
> - * \param coord0  the incoming texcoord (s,t,r or q) scaled to the texture
> size
> + * \param coord0  the incoming texcoord (s,t or r) scaled to the texture
> size
> + * \param coord_f  the incoming texcoord (s,t or r) as float vec
>   * \param length  the texture size along one dimension
>   * \param stride  pixel stride along the coordinate axis (in bytes)
> + * \param offset  the texel offset along the coord axis
>   * \param is_pot  if TRUE, length is a power of two
>   * \param wrap_mode  one of PIPE_TEX_WRAP_x
>   * \param offset0  resulting relative offset for coord0
> @@ -196,6 +218,7 @@ lp_build_sample_wrap_linear_int(struct
> lp_build_sample_context *bld,
>                                  LLVMValueRef coord_f,
>                                  LLVMValueRef length,
>                                  LLVMValueRef stride,
> +                                LLVMValueRef offset,
>                                  boolean is_pot,
>                                  unsigned wrap_mode,
>                                  LLVMValueRef *offset0,
> @@ -230,6 +253,11 @@ lp_build_sample_wrap_linear_int(struct
> lp_build_sample_context *bld,
>              LLVMValueRef mask;
>              LLVMValueRef weight;
>              LLVMValueRef length_f = lp_build_int_to_float(&bld->coord_bld,
>              length);
> +            if (offset) {
> +               offset = lp_build_int_to_float(&bld->coord_bld, offset);
> +               offset = lp_build_div(&bld->coord_bld, offset, length_f);
> +               coord_f = lp_build_add(&bld->coord_bld, coord_f, offset);
> +            }
>              lp_build_coord_repeat_npot_linear(bld, coord_f,
>                                                length, length_f,
>                                                &coord0, &weight);
> @@ -282,6 +310,11 @@ lp_build_sample_wrap_linear_int(struct
> lp_build_sample_context *bld,
>        else {
>           LLVMValueRef weight;
>           LLVMValueRef length_f = lp_build_int_to_float(&bld->coord_bld,
>           length);
> +         if (offset) {
> +            offset = lp_build_int_to_float(&bld->coord_bld, offset);
> +            offset = lp_build_div(&bld->coord_bld, offset, length_f);
> +            coord_f = lp_build_add(&bld->coord_bld, coord_f, offset);
> +         }
>           lp_build_coord_repeat_npot_linear(bld, coord_f,
>                                             length, length_f,
>                                             &coord0, &weight);
> @@ -340,8 +373,9 @@ lp_build_sample_wrap_linear_int(struct
> lp_build_sample_context *bld,
>   * for float texcoords.
>   * \param block_length  is the length of the pixel block along the
>   *                      coordinate axis
> - * \param coord  the incoming texcoord (s,t,r or q)
> + * \param coord  the incoming texcoord (s,t or r)
>   * \param length  the texture size along one dimension
> + * \param offset  the texel offset along the coord axis
>   * \param is_pot  if TRUE, length is a power of two
>   * \param wrap_mode  one of PIPE_TEX_WRAP_x
>   * \param coord0  the first texcoord after wrapping, as int
> @@ -354,6 +388,7 @@ lp_build_sample_wrap_linear_float(struct
> lp_build_sample_context *bld,
>                                    unsigned block_length,
>                                    LLVMValueRef coord,
>                                    LLVMValueRef length,
> +                                  LLVMValueRef offset,
>                                    boolean is_pot,
>                                    unsigned wrap_mode,
>                                    LLVMValueRef *coord0,
> @@ -372,6 +407,10 @@ lp_build_sample_wrap_linear_float(struct
> lp_build_sample_context *bld,
>        if (is_pot) {
>           /* mul by size and subtract 0.5 */
>           coord = lp_build_mul(coord_bld, coord, length);
> +         if (offset) {
> +            offset = lp_build_int_to_float(coord_bld, offset);
> +            coord = lp_build_add(coord_bld, coord, offset);
> +         }
>           if (!force_nearest)
>              coord = lp_build_sub(coord_bld, coord, half);
>           *coord1 = lp_build_add(coord_bld, coord, coord_bld->one);
> @@ -385,6 +424,11 @@ lp_build_sample_wrap_linear_float(struct
> lp_build_sample_context *bld,
>        }
>        else {
>           LLVMValueRef mask;
> +         if (offset) {
> +            offset = lp_build_int_to_float(coord_bld, offset);
> +            offset = lp_build_div(coord_bld, offset, length);
> +            coord = lp_build_add(coord_bld, coord, offset);
> +         }
>           /* wrap with normalized floats is just fract */
>           coord = lp_build_fract(coord_bld, coord);
>           /* unnormalize */
> @@ -411,6 +455,10 @@ lp_build_sample_wrap_linear_float(struct
> lp_build_sample_context *bld,
>           /* mul by tex size */
>           coord = lp_build_mul(coord_bld, coord, length);
>        }
> +      if (offset) {
> +         offset = lp_build_int_to_float(coord_bld, offset);
> +         coord = lp_build_add(coord_bld, coord, offset);
> +      }
>        /* subtract 0.5 */
>        if (!force_nearest) {
>           coord = lp_build_sub(coord_bld, coord, half);
> @@ -520,6 +568,7 @@ lp_build_sample_image_nearest(struct
> lp_build_sample_context *bld,
>                                LLVMValueRef s,
>                                LLVMValueRef t,
>                                LLVMValueRef r,
> +                              const LLVMValueRef *offsets,
>                                LLVMValueRef *colors_lo,
>                                LLVMValueRef *colors_hi)
>  {
> @@ -584,6 +633,17 @@ lp_build_sample_image_nearest(struct
> lp_build_sample_context *bld,
>     if (dims >= 3)
>        r_ipart = LLVMBuildAShr(builder, r, i32_c8, "");
>  
> +   /* add texel offsets */
> +   if (offsets[0]) {
> +      s_ipart = lp_build_add(&i32, s_ipart, offsets[0]);
> +      if (dims >= 2) {
> +         t_ipart = lp_build_add(&i32, t_ipart, offsets[1]);
> +         if (dims >= 3) {
> +            r_ipart = lp_build_add(&i32, r_ipart, offsets[2]);
> +         }
> +      }
> +   }
> +
>     /* get pixel, row, image strides */
>     x_stride = lp_build_const_vec(bld->gallivm,
>                                   bld->int_coord_bld.type,
> @@ -593,7 +653,7 @@ lp_build_sample_image_nearest(struct
> lp_build_sample_context *bld,
>     lp_build_sample_wrap_nearest_int(bld,
>                                      bld->format_desc->block.width,
>                                      s_ipart, s_float,
> -                                    width_vec, x_stride,
> +                                    width_vec, x_stride, offsets[0],
>                                      bld->static_texture_state->pot_width,
>                                      bld->static_sampler_state->wrap_s,
>                                      &x_offset, &x_subcoord);
> @@ -603,7 +663,7 @@ lp_build_sample_image_nearest(struct
> lp_build_sample_context *bld,
>        lp_build_sample_wrap_nearest_int(bld,
>                                         bld->format_desc->block.height,
>                                         t_ipart, t_float,
> -                                       height_vec, row_stride_vec,
> +                                       height_vec, row_stride_vec,
> offsets[1],
>                                         bld->static_texture_state->pot_height,
>                                         bld->static_sampler_state->wrap_t,
>                                         &y_offset, &y_subcoord);
> @@ -613,7 +673,7 @@ lp_build_sample_image_nearest(struct
> lp_build_sample_context *bld,
>           lp_build_sample_wrap_nearest_int(bld,
>                                            1, /* block length (depth) */
>                                            r_ipart, r_float,
> -                                          depth_vec, img_stride_vec,
> +                                          depth_vec, img_stride_vec,
> offsets[2],
>                                            bld->static_texture_state->pot_depth,
>                                            bld->static_sampler_state->wrap_r,
>                                            &z_offset, &z_subcoord);
> @@ -655,6 +715,7 @@ lp_build_sample_image_nearest_afloat(struct
> lp_build_sample_context *bld,
>                                       LLVMValueRef s,
>                                       LLVMValueRef t,
>                                       LLVMValueRef r,
> +                                     const LLVMValueRef *offsets,
>                                       LLVMValueRef *colors_lo,
>                                       LLVMValueRef *colors_hi)
>     {
> @@ -677,21 +738,21 @@ lp_build_sample_image_nearest_afloat(struct
> lp_build_sample_context *bld,
>  
>     /* Do texcoord wrapping */
>     lp_build_sample_wrap_nearest_float(bld,
> -                                      s, width_vec,
> +                                      s, width_vec, offsets[0],
>                                        bld->static_texture_state->pot_width,
>                                        bld->static_sampler_state->wrap_s,
>                                        &x_icoord);
>  
>     if (dims >= 2) {
>        lp_build_sample_wrap_nearest_float(bld,
> -                                         t, height_vec,
> +                                         t, height_vec, offsets[1],
>                                           bld->static_texture_state->pot_height,
>                                           bld->static_sampler_state->wrap_t,
>                                           &y_icoord);
>  
>        if (dims >= 3) {
>           lp_build_sample_wrap_nearest_float(bld,
> -                                            r, depth_vec,
> +                                            r, depth_vec, offsets[2],
>                                              bld->static_texture_state->pot_depth,
>                                              bld->static_sampler_state->wrap_r,
>                                              &z_icoord);
> @@ -982,6 +1043,7 @@ lp_build_sample_image_linear(struct
> lp_build_sample_context *bld,
>                               LLVMValueRef s,
>                               LLVMValueRef t,
>                               LLVMValueRef r,
> +                             const LLVMValueRef *offsets,
>                               LLVMValueRef *colors_lo,
>                               LLVMValueRef *colors_hi)
>  {
> @@ -1063,6 +1125,17 @@ lp_build_sample_image_linear(struct
> lp_build_sample_context *bld,
>     if (dims >= 3)
>        r_ipart = LLVMBuildAShr(builder, r, i32_c8, "");
>  
> +   /* add texel offsets */
> +   if (offsets[0]) {
> +      s_ipart = lp_build_add(&i32, s_ipart, offsets[0]);
> +      if (dims >= 2) {
> +         t_ipart = lp_build_add(&i32, t_ipart, offsets[1]);
> +         if (dims >= 3) {
> +            r_ipart = lp_build_add(&i32, r_ipart, offsets[2]);
> +         }
> +      }
> +   }
> +
>     /* compute fractional part (AND with 0xff) */
>     i32_c255 = lp_build_const_int_vec(bld->gallivm, i32.type, 255);
>     s_fpart = LLVMBuildAnd(builder, s, i32_c255, "");
> @@ -1081,7 +1154,7 @@ lp_build_sample_image_linear(struct
> lp_build_sample_context *bld,
>     lp_build_sample_wrap_linear_int(bld,
>                                     bld->format_desc->block.width,
>                                     s_ipart, &s_fpart, s_float,
> -                                   width_vec, x_stride,
> +                                   width_vec, x_stride, offsets[0],
>                                     bld->static_texture_state->pot_width,
>                                     bld->static_sampler_state->wrap_s,
>                                     &x_offset0, &x_offset1,
> @@ -1113,7 +1186,7 @@ lp_build_sample_image_linear(struct
> lp_build_sample_context *bld,
>        lp_build_sample_wrap_linear_int(bld,
>                                        bld->format_desc->block.height,
>                                        t_ipart, &t_fpart, t_float,
> -                                      height_vec, y_stride,
> +                                      height_vec, y_stride, offsets[1],
>                                        bld->static_texture_state->pot_height,
>                                        bld->static_sampler_state->wrap_t,
>                                        &y_offset0, &y_offset1,
> @@ -1133,7 +1206,7 @@ lp_build_sample_image_linear(struct
> lp_build_sample_context *bld,
>        lp_build_sample_wrap_linear_int(bld,
>                                        bld->format_desc->block.height,
>                                        r_ipart, &r_fpart, r_float,
> -                                      depth_vec, z_stride,
> +                                      depth_vec, z_stride, offsets[2],
>                                        bld->static_texture_state->pot_depth,
>                                        bld->static_sampler_state->wrap_r,
>                                        &z_offset0, &z_offset1,
> @@ -1171,6 +1244,7 @@ lp_build_sample_image_linear_afloat(struct
> lp_build_sample_context *bld,
>                                      LLVMValueRef s,
>                                      LLVMValueRef t,
>                                      LLVMValueRef r,
> +                                    const LLVMValueRef *offsets,
>                                      LLVMValueRef *colors_lo,
>                                      LLVMValueRef *colors_hi)
>  {
> @@ -1204,7 +1278,7 @@ lp_build_sample_image_linear_afloat(struct
> lp_build_sample_context *bld,
>     /* do texcoord wrapping and compute texel offsets */
>     lp_build_sample_wrap_linear_float(bld,
>                                       bld->format_desc->block.width,
> -                                     s, width_vec,
> +                                     s, width_vec, offsets[0],
>                                       bld->static_texture_state->pot_width,
>                                       bld->static_sampler_state->wrap_s,
>                                       &x_icoord0, &x_icoord1,
> @@ -1214,7 +1288,7 @@ lp_build_sample_image_linear_afloat(struct
> lp_build_sample_context *bld,
>     if (dims >= 2) {
>        lp_build_sample_wrap_linear_float(bld,
>                                          bld->format_desc->block.height,
> -                                        t, height_vec,
> +                                        t, height_vec, offsets[1],
>                                          bld->static_texture_state->pot_height,
>                                          bld->static_sampler_state->wrap_t,
>                                          &y_icoord0, &y_icoord1,
> @@ -1224,7 +1298,7 @@ lp_build_sample_image_linear_afloat(struct
> lp_build_sample_context *bld,
>        if (dims >= 3) {
>           lp_build_sample_wrap_linear_float(bld,
>                                             bld->format_desc->block.height,
> -                                           r, depth_vec,
> +                                           r, depth_vec, offsets[2],
>                                             bld->static_texture_state->pot_depth,
>                                             bld->static_sampler_state->wrap_r,
>                                             &z_icoord0, &z_icoord1,
> @@ -1339,6 +1413,7 @@ lp_build_sample_mipmap(struct lp_build_sample_context
> *bld,
>                         LLVMValueRef s,
>                         LLVMValueRef t,
>                         LLVMValueRef r,
> +                       const LLVMValueRef *offsets,
>                         LLVMValueRef ilevel0,
>                         LLVMValueRef ilevel1,
>                         LLVMValueRef lod_fpart,
> @@ -1377,7 +1452,7 @@ lp_build_sample_mipmap(struct lp_build_sample_context
> *bld,
>           lp_build_sample_image_nearest_afloat(bld,
>                                                size0,
>                                                row_stride0_vec,
>                                                img_stride0_vec,
> -                                              data_ptr0, mipoff0, s, t, r,
> +                                              data_ptr0, mipoff0, s, t, r,
> offsets,
>                                                &colors0_lo, &colors0_hi);
>        }
>        else {
> @@ -1385,7 +1460,7 @@ lp_build_sample_mipmap(struct lp_build_sample_context
> *bld,
>           lp_build_sample_image_linear_afloat(bld,
>                                               size0,
>                                               row_stride0_vec,
>                                               img_stride0_vec,
> -                                             data_ptr0, mipoff0, s, t, r,
> +                                             data_ptr0, mipoff0, s, t, r,
> offsets,
>                                               &colors0_lo, &colors0_hi);
>        }
>     }
> @@ -1394,7 +1469,7 @@ lp_build_sample_mipmap(struct lp_build_sample_context
> *bld,
>           lp_build_sample_image_nearest(bld,
>                                         size0,
>                                         row_stride0_vec, img_stride0_vec,
> -                                       data_ptr0, mipoff0, s, t, r,
> +                                       data_ptr0, mipoff0, s, t, r, offsets,
>                                         &colors0_lo, &colors0_hi);
>        }
>        else {
> @@ -1402,7 +1477,7 @@ lp_build_sample_mipmap(struct lp_build_sample_context
> *bld,
>           lp_build_sample_image_linear(bld,
>                                        size0,
>                                        row_stride0_vec, img_stride0_vec,
> -                                      data_ptr0, mipoff0, s, t, r,
> +                                      data_ptr0, mipoff0, s, t, r, offsets,
>                                        &colors0_lo, &colors0_hi);
>        }
>     }
> @@ -1472,14 +1547,14 @@ lp_build_sample_mipmap(struct lp_build_sample_context
> *bld,
>                 lp_build_sample_image_nearest_afloat(bld,
>                                                      size1,
>                                                      row_stride1_vec,
>                                                      img_stride1_vec,
> -                                                    data_ptr1, mipoff1, s,
> t, r,
> +                                                    data_ptr1, mipoff1, s,
> t, r, offsets,
>                                                      &colors1_lo,
>                                                      &colors1_hi);
>              }
>              else {
>                 lp_build_sample_image_linear_afloat(bld,
>                                                     size1,
>                                                     row_stride1_vec,
>                                                     img_stride1_vec,
> -                                                   data_ptr1, mipoff1, s, t,
> r,
> +                                                   data_ptr1, mipoff1, s, t,
> r, offsets,
>                                                     &colors1_lo,
>                                                     &colors1_hi);
>              }
>           }
> @@ -1488,14 +1563,14 @@ lp_build_sample_mipmap(struct lp_build_sample_context
> *bld,
>                 lp_build_sample_image_nearest(bld,
>                                               size1,
>                                               row_stride1_vec,
>                                               img_stride1_vec,
> -                                             data_ptr1, mipoff1, s, t, r,
> +                                             data_ptr1, mipoff1, s, t, r,
> offsets,
>                                               &colors1_lo, &colors1_hi);
>              }
>              else {
>                 lp_build_sample_image_linear(bld,
>                                              size1,
>                                              row_stride1_vec,
>                                              img_stride1_vec,
> -                                            data_ptr1, mipoff1, s, t, r,
> +                                            data_ptr1, mipoff1, s, t, r,
> offsets,
>                                              &colors1_lo, &colors1_hi);
>              }
>           }
> @@ -1574,6 +1649,7 @@ lp_build_sample_aos(struct lp_build_sample_context
> *bld,
>                      LLVMValueRef s,
>                      LLVMValueRef t,
>                      LLVMValueRef r,
> +                    const LLVMValueRef *offsets,
>                      LLVMValueRef lod_ipart,
>                      LLVMValueRef lod_fpart,
>                      LLVMValueRef ilevel0,
> @@ -1612,7 +1688,7 @@ lp_build_sample_aos(struct lp_build_sample_context
> *bld,
>        /* no need to distinguish between minification and magnification */
>        lp_build_sample_mipmap(bld,
>                               min_filter, mip_filter,
> -                             s, t, r,
> +                             s, t, r, offsets,
>                               ilevel0, ilevel1, lod_fpart,
>                               packed_lo, packed_hi);
>     }
> @@ -1645,7 +1721,7 @@ lp_build_sample_aos(struct lp_build_sample_context
> *bld,
>           /* Use the minification filter */
>           lp_build_sample_mipmap(bld,
>                                  min_filter, mip_filter,
> -                                s, t, r,
> +                                s, t, r, offsets,
>                                  ilevel0, ilevel1, lod_fpart,
>                                  packed_lo, packed_hi);
>        }
> @@ -1654,7 +1730,7 @@ lp_build_sample_aos(struct lp_build_sample_context
> *bld,
>           /* Use the magnification filter */
>           lp_build_sample_mipmap(bld,
>                                  mag_filter, PIPE_TEX_MIPFILTER_NONE,
> -                                s, t, r,
> +                                s, t, r, offsets,
>                                  ilevel0, NULL, NULL,
>                                  packed_lo, packed_hi);
>        }
> diff --git a/src/gallium/auxiliary/gallivm/lp_bld_sample_aos.h
> b/src/gallium/auxiliary/gallivm/lp_bld_sample_aos.h
> index 6590e8c..6fce971 100644
> --- a/src/gallium/auxiliary/gallivm/lp_bld_sample_aos.h
> +++ b/src/gallium/auxiliary/gallivm/lp_bld_sample_aos.h
> @@ -46,6 +46,7 @@ lp_build_sample_aos(struct lp_build_sample_context *bld,
>                      LLVMValueRef s,
>                      LLVMValueRef t,
>                      LLVMValueRef r,
> +                    const LLVMValueRef *offsets,
>                      LLVMValueRef lod_ipart,
>                      LLVMValueRef lod_fpart,
>                      LLVMValueRef ilevel0,
> diff --git a/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c
> b/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c
> index 50ccd2a..8aa4166 100644
> --- a/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c
> +++ b/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c
> @@ -277,6 +277,7 @@ lp_build_sample_wrap_linear(struct
> lp_build_sample_context *bld,
>                              LLVMValueRef coord,
>                              LLVMValueRef length,
>                              LLVMValueRef length_f,
> +                            LLVMValueRef offset,
>                              boolean is_pot,
>                              unsigned wrap_mode,
>                              LLVMValueRef *x0_out,
> @@ -296,6 +297,10 @@ lp_build_sample_wrap_linear(struct
> lp_build_sample_context *bld,
>           /* mul by size and subtract 0.5 */
>           coord = lp_build_mul(coord_bld, coord, length_f);
>           coord = lp_build_sub(coord_bld, coord, half);
> +         if (offset) {
> +            offset = lp_build_int_to_float(coord_bld, offset);
> +            coord = lp_build_add(coord_bld, coord, offset);
> +         }
>           /* convert to int, compute lerp weight */
>           lp_build_ifloor_fract(coord_bld, coord, &coord0, &weight);
>           coord1 = lp_build_add(int_coord_bld, coord0, int_coord_bld->one);
> @@ -305,6 +310,11 @@ lp_build_sample_wrap_linear(struct
> lp_build_sample_context *bld,
>        }
>        else {
>           LLVMValueRef mask;
> +         if (offset) {
> +            offset = lp_build_int_to_float(coord_bld, offset);
> +            offset = lp_build_div(coord_bld, offset, length_f);
> +            coord = lp_build_add(coord_bld, coord, offset);
> +         }
>           lp_build_coord_repeat_npot_linear(bld, coord,
>                                             length, length_f,
>                                             &coord0, &weight);
> @@ -321,6 +331,10 @@ lp_build_sample_wrap_linear(struct
> lp_build_sample_context *bld,
>           /* scale coord to length */
>           coord = lp_build_mul(coord_bld, coord, length_f);
>        }
> +      if (offset) {
> +         offset = lp_build_int_to_float(coord_bld, offset);
> +         coord = lp_build_add(coord_bld, coord, offset);
> +      }
>  
>        /* clamp to [0, length] */
>        coord = lp_build_clamp(coord_bld, coord, coord_bld->zero, length_f);
> @@ -341,6 +355,11 @@ lp_build_sample_wrap_linear(struct
> lp_build_sample_context *bld,
>              /* mul by tex size */
>              coord = lp_build_mul(coord_bld, coord, length_f);
>           }
> +         if (offset) {
> +            offset = lp_build_int_to_float(coord_bld, offset);
> +            coord = lp_build_add(coord_bld, coord, offset);
> +         }
> +
>           /* clamp to length max */
>           coord = lp_build_min(coord_bld, coord, length_f);
>           /* subtract 0.5 */
> @@ -360,6 +379,10 @@ lp_build_sample_wrap_linear(struct
> lp_build_sample_context *bld,
>           /* scale coord to length */
>           coord = lp_build_mul(coord_bld, coord, length_f);
>        }
> +      if (offset) {
> +         offset = lp_build_int_to_float(coord_bld, offset);
> +         coord = lp_build_add(coord_bld, coord, offset);
> +      }
>        /* was: clamp to [-0.5, length + 0.5], then sub 0.5 */
>        /* can skip clamp (though might not work for very large coord values
>        */
>        coord = lp_build_sub(coord_bld, coord, half);
> @@ -375,6 +398,10 @@ lp_build_sample_wrap_linear(struct
> lp_build_sample_context *bld,
>        /* scale coord to length */
>        coord = lp_build_mul(coord_bld, coord, length_f);
>        coord = lp_build_sub(coord_bld, coord, half);
> +      if (offset) {
> +         offset = lp_build_int_to_float(coord_bld, offset);
> +         coord = lp_build_add(coord_bld, coord, offset);
> +      }
>  
>        /* convert to int, compute lerp weight */
>        lp_build_ifloor_fract(coord_bld, coord, &coord0, &weight);
> @@ -387,12 +414,15 @@ lp_build_sample_wrap_linear(struct
> lp_build_sample_context *bld,
>        break;
>  
>     case PIPE_TEX_WRAP_MIRROR_CLAMP:
> -      coord = lp_build_abs(coord_bld, coord);
> -
>        if (bld->static_sampler_state->normalized_coords) {
>           /* scale coord to length */
>           coord = lp_build_mul(coord_bld, coord, length_f);
>        }
> +      if (offset) {
> +         offset = lp_build_int_to_float(coord_bld, offset);
> +         coord = lp_build_add(coord_bld, coord, offset);
> +      }
> +      coord = lp_build_abs(coord_bld, coord);
>  
>        /* clamp to [0, length] */
>        coord = lp_build_min(coord_bld, coord, length_f);
> @@ -409,12 +439,16 @@ lp_build_sample_wrap_linear(struct
> lp_build_sample_context *bld,
>           LLVMValueRef min, max;
>           struct lp_build_context abs_coord_bld = bld->coord_bld;
>           abs_coord_bld.type.sign = FALSE;
> -         coord = lp_build_abs(coord_bld, coord);
>  
>           if (bld->static_sampler_state->normalized_coords) {
>              /* scale coord to length */
>              coord = lp_build_mul(coord_bld, coord, length_f);
>           }
> +         if (offset) {
> +            offset = lp_build_int_to_float(coord_bld, offset);
> +            coord = lp_build_add(coord_bld, coord, offset);
> +         }
> +         coord = lp_build_abs(coord_bld, coord);
>  
>           /* clamp to [0.5, length - 0.5] */
>           min = half;
> @@ -431,12 +465,15 @@ lp_build_sample_wrap_linear(struct
> lp_build_sample_context *bld,
>  
>     case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER:
>        {
> -         coord = lp_build_abs(coord_bld, coord);
> -
>           if (bld->static_sampler_state->normalized_coords) {
>              /* scale coord to length */
>              coord = lp_build_mul(coord_bld, coord, length_f);
>           }
> +         if (offset) {
> +            offset = lp_build_int_to_float(coord_bld, offset);
> +            coord = lp_build_add(coord_bld, coord, offset);
> +         }
> +         coord = lp_build_abs(coord_bld, coord);
>  
>           /* was: clamp to [-0.5, length + 0.5] then sub 0.5 */
>           /* skip clamp - always positive, and other side
> @@ -466,6 +503,8 @@ lp_build_sample_wrap_linear(struct
> lp_build_sample_context *bld,
>   * Build LLVM code for texture wrap mode for nearest filtering.
>   * \param coord  the incoming texcoord (nominally in [0,1])
>   * \param length  the texture size along one dimension, as int vector
> + * \param length_f  the texture size along one dimension, as float vector
> + * \param offset  texel offset along one dimension (as int vector)
>   * \param is_pot  if TRUE, length is a power of two
>   * \param wrap_mode  one of PIPE_TEX_WRAP_x
>   */
> @@ -474,6 +513,7 @@ lp_build_sample_wrap_nearest(struct
> lp_build_sample_context *bld,
>                               LLVMValueRef coord,
>                               LLVMValueRef length,
>                               LLVMValueRef length_f,
> +                             LLVMValueRef offset,
>                               boolean is_pot,
>                               unsigned wrap_mode)
>  {
> @@ -488,9 +528,17 @@ lp_build_sample_wrap_nearest(struct
> lp_build_sample_context *bld,
>        if (is_pot) {
>           coord = lp_build_mul(coord_bld, coord, length_f);
>           icoord = lp_build_ifloor(coord_bld, coord);
> +         if (offset) {
> +            icoord = lp_build_add(int_coord_bld, icoord, offset);
> +         }
>           icoord = LLVMBuildAnd(builder, icoord, length_minus_one, "");
>        }
>        else {
> +          if (offset) {
> +             offset = lp_build_int_to_float(coord_bld, offset);
> +             offset = lp_build_div(coord_bld, offset, length_f);
> +             coord = lp_build_add(coord_bld, coord, offset);
> +          }
>            /* take fraction, unnormalize */
>            coord = lp_build_fract_safe(coord_bld, coord);
>            coord = lp_build_mul(coord_bld, coord, length_f);
> @@ -508,6 +556,9 @@ lp_build_sample_wrap_nearest(struct
> lp_build_sample_context *bld,
>        /* floor */
>        /* use itrunc instead since we clamp to 0 anyway */
>        icoord = lp_build_itrunc(coord_bld, coord);
> +      if (offset) {
> +         icoord = lp_build_add(int_coord_bld, icoord, offset);
> +      }
>  
>        /* clamp to [0, length - 1]. */
>        icoord = lp_build_clamp(int_coord_bld, icoord, int_coord_bld->zero,
> @@ -521,9 +572,17 @@ lp_build_sample_wrap_nearest(struct
> lp_build_sample_context *bld,
>        }
>        /* no clamp necessary, border masking will handle this */
>        icoord = lp_build_ifloor(coord_bld, coord);
> +      if (offset) {
> +         icoord = lp_build_add(int_coord_bld, icoord, offset);
> +      }
>        break;
>  
>     case PIPE_TEX_WRAP_MIRROR_REPEAT:
> +      if (offset) {
> +         offset = lp_build_int_to_float(coord_bld, offset);
> +         offset = lp_build_div(coord_bld, offset, length_f);
> +         coord = lp_build_add(coord_bld, coord, offset);
> +      }
>        /* compute mirror function */
>        coord = lp_build_coord_mirror(bld, coord);
>  
> @@ -540,12 +599,15 @@ lp_build_sample_wrap_nearest(struct
> lp_build_sample_context *bld,
>  
>     case PIPE_TEX_WRAP_MIRROR_CLAMP:
>     case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE:
> -      coord = lp_build_abs(coord_bld, coord);
> -
>        if (bld->static_sampler_state->normalized_coords) {
>           /* scale coord to length */
>           coord = lp_build_mul(coord_bld, coord, length_f);
>        }
> +      if (offset) {
> +         offset = lp_build_int_to_float(coord_bld, offset);
> +         coord = lp_build_add(coord_bld, coord, offset);
> +      }
> +      coord = lp_build_abs(coord_bld, coord);
>  
>        /* itrunc == ifloor here */
>        icoord = lp_build_itrunc(coord_bld, coord);
> @@ -555,12 +617,15 @@ lp_build_sample_wrap_nearest(struct
> lp_build_sample_context *bld,
>        break;
>  
>     case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER:
> -      coord = lp_build_abs(coord_bld, coord);
> -
>        if (bld->static_sampler_state->normalized_coords) {
>           /* scale coord to length */
>           coord = lp_build_mul(coord_bld, coord, length_f);
>        }
> +      if (offset) {
> +         offset = lp_build_int_to_float(coord_bld, offset);
> +         coord = lp_build_add(coord_bld, coord, offset);
> +      }
> +      coord = lp_build_abs(coord_bld, coord);
>  
>        /* itrunc == ifloor here */
>        icoord = lp_build_itrunc(coord_bld, coord);
> @@ -590,6 +655,7 @@ lp_build_sample_image_nearest(struct
> lp_build_sample_context *bld,
>                                LLVMValueRef s,
>                                LLVMValueRef t,
>                                LLVMValueRef r,
> +                              const LLVMValueRef *offsets,
>                                LLVMValueRef colors_out[4])
>  {
>     const unsigned dims = bld->dims;
> @@ -619,19 +685,19 @@ lp_build_sample_image_nearest(struct
> lp_build_sample_context *bld,
>     /*
>      * Compute integer texcoords.
>      */
> -   x = lp_build_sample_wrap_nearest(bld, s, width_vec, flt_width_vec,
> +   x = lp_build_sample_wrap_nearest(bld, s, width_vec, flt_width_vec,
> offsets[0],
>                                      bld->static_texture_state->pot_width,
>                                      bld->static_sampler_state->wrap_s);
>     lp_build_name(x, "tex.x.wrapped");
>  
>     if (dims >= 2) {
> -      y = lp_build_sample_wrap_nearest(bld, t, height_vec, flt_height_vec,
> +      y = lp_build_sample_wrap_nearest(bld, t, height_vec, flt_height_vec,
> offsets[1],
>                                         bld->static_texture_state->pot_height,
>                                         bld->static_sampler_state->wrap_t);
>        lp_build_name(y, "tex.y.wrapped");
>  
>        if (dims == 3) {
> -         z = lp_build_sample_wrap_nearest(bld, r, depth_vec, flt_depth_vec,
> +         z = lp_build_sample_wrap_nearest(bld, r, depth_vec, flt_depth_vec,
> offsets[2],
>                                            bld->static_texture_state->pot_depth,
>                                            bld->static_sampler_state->wrap_r);
>           lp_build_name(z, "tex.z.wrapped");
> @@ -670,6 +736,7 @@ lp_build_sample_image_linear(struct
> lp_build_sample_context *bld,
>                               LLVMValueRef s,
>                               LLVMValueRef t,
>                               LLVMValueRef r,
> +                             const LLVMValueRef *offsets,
>                               LLVMValueRef colors_out[4])
>  {
>     const unsigned dims = bld->dims;
> @@ -702,7 +769,7 @@ lp_build_sample_image_linear(struct
> lp_build_sample_context *bld,
>     /*
>      * Compute integer texcoords.
>      */
> -   lp_build_sample_wrap_linear(bld, s, width_vec, flt_width_vec,
> +   lp_build_sample_wrap_linear(bld, s, width_vec, flt_width_vec, offsets[0],
>                                 bld->static_texture_state->pot_width,
>                                 bld->static_sampler_state->wrap_s,
>                                 &x0, &x1, &s_fpart);
> @@ -710,7 +777,7 @@ lp_build_sample_image_linear(struct
> lp_build_sample_context *bld,
>     lp_build_name(x1, "tex.x1.wrapped");
>  
>     if (dims >= 2) {
> -      lp_build_sample_wrap_linear(bld, t, height_vec, flt_height_vec,
> +      lp_build_sample_wrap_linear(bld, t, height_vec, flt_height_vec,
> offsets[1],
>                                    bld->static_texture_state->pot_height,
>                                    bld->static_sampler_state->wrap_t,
>                                    &y0, &y1, &t_fpart);
> @@ -718,7 +785,7 @@ lp_build_sample_image_linear(struct
> lp_build_sample_context *bld,
>        lp_build_name(y1, "tex.y1.wrapped");
>  
>        if (dims == 3) {
> -         lp_build_sample_wrap_linear(bld, r, depth_vec, flt_depth_vec,
> +         lp_build_sample_wrap_linear(bld, r, depth_vec, flt_depth_vec,
> offsets[2],
>                                       bld->static_texture_state->pot_depth,
>                                       bld->static_sampler_state->wrap_r,
>                                       &z0, &z1, &r_fpart);
> @@ -851,6 +918,7 @@ lp_build_sample_mipmap(struct lp_build_sample_context
> *bld,
>                         LLVMValueRef s,
>                         LLVMValueRef t,
>                         LLVMValueRef r,
> +                       const LLVMValueRef *offsets,
>                         LLVMValueRef ilevel0,
>                         LLVMValueRef ilevel1,
>                         LLVMValueRef lod_fpart,
> @@ -886,7 +954,7 @@ lp_build_sample_mipmap(struct lp_build_sample_context
> *bld,
>        lp_build_sample_image_nearest(bld, sampler_unit,
>                                      size0,
>                                      row_stride0_vec, img_stride0_vec,
> -                                    data_ptr0, mipoff0, s, t, r,
> +                                    data_ptr0, mipoff0, s, t, r, offsets,
>                                      colors0);
>     }
>     else {
> @@ -894,7 +962,7 @@ lp_build_sample_mipmap(struct lp_build_sample_context
> *bld,
>        lp_build_sample_image_linear(bld, sampler_unit,
>                                     size0,
>                                     row_stride0_vec, img_stride0_vec,
> -                                   data_ptr0, mipoff0, s, t, r,
> +                                   data_ptr0, mipoff0, s, t, r, offsets,
>                                     colors0);
>     }
>  
> @@ -950,14 +1018,14 @@ lp_build_sample_mipmap(struct lp_build_sample_context
> *bld,
>              lp_build_sample_image_nearest(bld, sampler_unit,
>                                            size1,
>                                            row_stride1_vec, img_stride1_vec,
> -                                          data_ptr1, mipoff1, s, t, r,
> +                                          data_ptr1, mipoff1, s, t, r,
> offsets,
>                                            colors1);
>           }
>           else {
>              lp_build_sample_image_linear(bld, sampler_unit,
>                                           size1,
>                                           row_stride1_vec, img_stride1_vec,
> -                                         data_ptr1, mipoff1, s, t, r,
> +                                         data_ptr1, mipoff1, s, t, r,
> offsets,
>                                           colors1);
>           }
>  
> @@ -1120,6 +1188,7 @@ lp_build_sample_general(struct lp_build_sample_context
> *bld,
>                          LLVMValueRef s,
>                          LLVMValueRef t,
>                          LLVMValueRef r,
> +                        const LLVMValueRef *offsets,
>                          LLVMValueRef lod_ipart,
>                          LLVMValueRef lod_fpart,
>                          LLVMValueRef ilevel0,
> @@ -1147,7 +1216,7 @@ lp_build_sample_general(struct lp_build_sample_context
> *bld,
>        /* no need to distinguish between minification and magnification */
>        lp_build_sample_mipmap(bld, sampler_unit,
>                               min_filter, mip_filter,
> -                             s, t, r,
> +                             s, t, r, offsets,
>                               ilevel0, ilevel1, lod_fpart,
>                               texels);
>     }
> @@ -1180,7 +1249,7 @@ lp_build_sample_general(struct lp_build_sample_context
> *bld,
>           /* Use the minification filter */
>           lp_build_sample_mipmap(bld, sampler_unit,
>                                  min_filter, mip_filter,
> -                                s, t, r,
> +                                s, t, r, offsets,
>                                  ilevel0, ilevel1, lod_fpart,
>                                  texels);
>        }
> @@ -1189,7 +1258,7 @@ lp_build_sample_general(struct lp_build_sample_context
> *bld,
>           /* Use the magnification filter */
>           lp_build_sample_mipmap(bld, sampler_unit,
>                                  mag_filter, PIPE_TEX_MIPFILTER_NONE,
> -                                s, t, r,
> +                                s, t, r, offsets,
>                                  ilevel0, NULL, NULL,
>                                  texels);
>        }
> @@ -1605,7 +1674,7 @@ lp_build_sample_soa(struct gallivm_state *gallivm,
>           if (use_aos) {
>              /* do sampling/filtering with fixed pt arithmetic */
>              lp_build_sample_aos(&bld, sampler_index,
> -                                s, t, r,
> +                                s, t, r, offsets,
>                                  lod_ipart, lod_fpart,
>                                  ilevel0, ilevel1,
>                                  texel_out);
> @@ -1613,7 +1682,7 @@ lp_build_sample_soa(struct gallivm_state *gallivm,
>  
>           else {
>              lp_build_sample_general(&bld, sampler_index,
> -                                    s, t, r,
> +                                    s, t, r, offsets,
>                                      lod_ipart, lod_fpart,
>                                      ilevel0, ilevel1,
>                                      texel_out);
> @@ -1681,10 +1750,21 @@ lp_build_sample_soa(struct gallivm_state *gallivm,
>              LLVMValueRef lod_iparts, lod_fparts = NULL;
>              LLVMValueRef ilevel0s, ilevel1s = NULL;
>              LLVMValueRef indexi = lp_build_const_int32(gallivm, i);
> +            LLVMValueRef offsets4[4] = { NULL };
>  
>              s4 = lp_build_extract_range(gallivm, s, 4*i, 4);
>              t4 = lp_build_extract_range(gallivm, t, 4*i, 4);
>              r4 = lp_build_extract_range(gallivm, r, 4*i, 4);
> +
> +            if (offsets[0]) {
> +               offsets4[0] = lp_build_extract_range(gallivm, offsets[0],
> 4*i, 4);
> +               if (dims > 1) {
> +                  offsets4[1] = lp_build_extract_range(gallivm, offsets[1],
> 4*i, 4);
> +                  if (dims > 2) {
> +                     offsets4[2] = lp_build_extract_range(gallivm,
> offsets[2], 4*i, 4);
> +                  }
> +               }
> +            }
>              lod_iparts = LLVMBuildExtractElement(builder, lod_ipart, indexi,
>              "");
>              ilevel0s = LLVMBuildExtractElement(builder, ilevel0, indexi,
>              "");
>              if (mip_filter == PIPE_TEX_MIPFILTER_LINEAR) {
> @@ -1695,7 +1775,7 @@ lp_build_sample_soa(struct gallivm_state *gallivm,
>              if (use_aos) {
>                 /* do sampling/filtering with fixed pt arithmetic */
>                 lp_build_sample_aos(&bld4, sampler_index,
> -                                   s4, t4, r4,
> +                                   s4, t4, r4, offsets4,
>                                     lod_iparts, lod_fparts,
>                                     ilevel0s, ilevel1s,
>                                     texelout4);
> @@ -1703,7 +1783,7 @@ lp_build_sample_soa(struct gallivm_state *gallivm,
>  
>              else {
>                 lp_build_sample_general(&bld4, sampler_index,
> -                                       s4, t4, r4,
> +                                       s4, t4, r4, offsets4,
>                                         lod_iparts, lod_fparts,
>                                         ilevel0s, ilevel1s,
>                                         texelout4);
> --
> 1.7.9.5
> 


More information about the mesa-dev mailing list