Merge branch 'mesa_7_7_branch'
[mesa.git] / src / gallium / drivers / softpipe / sp_tex_sample.c
index f2d4f7eb8cce913db2b972ae86dd0f19071422ab..e26153b1d9096012ebf1a6a357efb867f82691eb 100644 (file)
 
 
 /*
- * Note, the FRAC macro has to work perfectly.  Otherwise you'll sometimes
- * see 1-pixel bands of improperly weighted linear-filtered textures.
+ * Return fractional part of 'f'.  Used for computing interpolation weights.
+ * Need to be careful with negative values.
+ * Note, if this function isn't perfect you'll sometimes see 1-pixel bands
+ * of improperly weighted linear-filtered textures.
  * The tests/texwrap.c demo is a good test.
- * Also note, FRAC(x) doesn't truly return the fractional part of x for x < 0.
- * Instead, if x < 0 then FRAC(x) = 1 - true_frac(x).
  */
-#define FRAC(f)  ((f) - util_ifloor(f))
+static INLINE float
+frac(float f)
+{
+   return f - util_ifloor(f);
+}
+
 
 
 /**
@@ -99,10 +104,16 @@ lerp_3d(float a, float b, float c,
 
 
 /**
- * If A is a signed integer, A % B doesn't give the right value for A < 0
- * (in terms of texture repeat).  Just casting to unsigned fixes that.
+ * Compute coord % size for repeat wrap modes.
+ * Note that if coord is a signed integer, coord % size doesn't give
+ * the right value for coord < 0 (in terms of texture repeat).  Just
+ * casting to unsigned fixes that.
  */
-#define REMAINDER(A, B) ((unsigned) (A) % (unsigned) (B))
+static INLINE int
+repeat(int coord, unsigned size)
+{
+   return (int) ((unsigned) coord % size);
+}
 
 
 /**
@@ -115,23 +126,20 @@ lerp_3d(float a, float b, float c,
  * \return  integer texture index
  */
 static void
-wrap_nearest_repeat(const float s[4], unsigned size,
-                        int icoord[4])
+wrap_nearest_repeat(const float s[4], unsigned size, int icoord[4])
 {
    uint ch;
-
    /* s limited to [0,1) */
    /* i limited to [0,size-1] */
    for (ch = 0; ch < 4; ch++) {
       int i = util_ifloor(s[ch] * size);
-      icoord[ch] = REMAINDER(i, size);
+      icoord[ch] = repeat(i, size);
    }
 }
 
 
 static void
-wrap_nearest_clamp(const float s[4], unsigned size,
-                   int icoord[4])
+wrap_nearest_clamp(const float s[4], unsigned size, int icoord[4])
 {
    uint ch;
    /* s limited to [0,1] */
@@ -148,8 +156,7 @@ wrap_nearest_clamp(const float s[4], unsigned size,
 
 
 static void
-wrap_nearest_clamp_to_edge(const float s[4], unsigned size,
-                           int icoord[4])
+wrap_nearest_clamp_to_edge(const float s[4], unsigned size, int icoord[4])
 {
    uint ch;
    /* s limited to [min,max] */
@@ -168,8 +175,7 @@ wrap_nearest_clamp_to_edge(const float s[4], unsigned size,
 
 
 static void
-wrap_nearest_clamp_to_border(const float s[4], unsigned size,
-                             int icoord[4])
+wrap_nearest_clamp_to_border(const float s[4], unsigned size, int icoord[4])
 {
    uint ch;
    /* s limited to [min,max] */
@@ -186,9 +192,9 @@ wrap_nearest_clamp_to_border(const float s[4], unsigned size,
    }
 }
 
+
 static void
-wrap_nearest_mirror_repeat(const float s[4], unsigned size,
-                           int icoord[4])
+wrap_nearest_mirror_repeat(const float s[4], unsigned size, int icoord[4])
 {
    uint ch;
    const float min = 1.0F / (2.0F * size);
@@ -209,9 +215,9 @@ wrap_nearest_mirror_repeat(const float s[4], unsigned size,
    }
 }
 
+
 static void
-wrap_nearest_mirror_clamp(const float s[4], unsigned size,
-                          int icoord[4])
+wrap_nearest_mirror_clamp(const float s[4], unsigned size, int icoord[4])
 {
    uint ch;
    for (ch = 0; ch < 4; ch++) {
@@ -227,9 +233,10 @@ wrap_nearest_mirror_clamp(const float s[4], unsigned size,
    }
 }
 
+
 static void
 wrap_nearest_mirror_clamp_to_edge(const float s[4], unsigned size,
-                           int icoord[4])
+                                  int icoord[4])
 {
    uint ch;
    /* s limited to [min,max] */
@@ -284,15 +291,15 @@ wrap_linear_repeat(const float s[4], unsigned size,
                    int icoord0[4], int icoord1[4], float w[4])
 {
    uint ch;
-
    for (ch = 0; ch < 4; ch++) {
       float u = s[ch] * size - 0.5F;
-      icoord0[ch] = REMAINDER(util_ifloor(u), size);
-      icoord1[ch] = REMAINDER(icoord0[ch] + 1, size);
-      w[ch] = FRAC(u);
+      icoord0[ch] = repeat(util_ifloor(u), size);
+      icoord1[ch] = repeat(icoord0[ch] + 1, size);
+      w[ch] = frac(u);
    }
 }
 
+
 static void
 wrap_linear_clamp(const float s[4], unsigned size,
                   int icoord0[4], int icoord1[4], float w[4])
@@ -303,10 +310,11 @@ wrap_linear_clamp(const float s[4], unsigned size,
       u = u * size - 0.5f;
       icoord0[ch] = util_ifloor(u);
       icoord1[ch] = icoord0[ch] + 1;
-      w[ch] = FRAC(u);
+      w[ch] = frac(u);
    }
 }
 
+
 static void
 wrap_linear_clamp_to_edge(const float s[4], unsigned size,
                           int icoord0[4], int icoord1[4], float w[4])
@@ -321,10 +329,11 @@ wrap_linear_clamp_to_edge(const float s[4], unsigned size,
          icoord0[ch] = 0;
       if (icoord1[ch] >= (int) size)
          icoord1[ch] = size - 1;
-      w[ch] = FRAC(u);
+      w[ch] = frac(u);
    }
 }
 
+
 static void
 wrap_linear_clamp_to_border(const float s[4], unsigned size,
                             int icoord0[4], int icoord1[4], float w[4])
@@ -337,7 +346,7 @@ wrap_linear_clamp_to_border(const float s[4], unsigned size,
       u = u * size - 0.5f;
       icoord0[ch] = util_ifloor(u);
       icoord1[ch] = icoord0[ch] + 1;
-      w[ch] = FRAC(u);
+      w[ch] = frac(u);
    }
 }
 
@@ -361,10 +370,11 @@ wrap_linear_mirror_repeat(const float s[4], unsigned size,
          icoord0[ch] = 0;
       if (icoord1[ch] >= (int) size)
          icoord1[ch] = size - 1;
-      w[ch] = FRAC(u);
+      w[ch] = frac(u);
    }
 }
 
+
 static void
 wrap_linear_mirror_clamp(const float s[4], unsigned size,
                          int icoord0[4], int icoord1[4], float w[4])
@@ -379,10 +389,11 @@ wrap_linear_mirror_clamp(const float s[4], unsigned size,
       u -= 0.5F;
       icoord0[ch] = util_ifloor(u);
       icoord1[ch] = icoord0[ch] + 1;
-      w[ch] = FRAC(u);
+      w[ch] = frac(u);
    }
 }
 
+
 static void
 wrap_linear_mirror_clamp_to_edge(const float s[4], unsigned size,
                                  int icoord0[4], int icoord1[4], float w[4])
@@ -401,10 +412,11 @@ wrap_linear_mirror_clamp_to_edge(const float s[4], unsigned size,
          icoord0[ch] = 0;
       if (icoord1[ch] >= (int) size)
          icoord1[ch] = size - 1;
-      w[ch] = FRAC(u);
+      w[ch] = frac(u);
    }
 }
 
+
 static void
 wrap_linear_mirror_clamp_to_border(const float s[4], unsigned size,
                                    int icoord0[4], int icoord1[4], float w[4])
@@ -423,7 +435,7 @@ wrap_linear_mirror_clamp_to_border(const float s[4], unsigned size,
       u -= 0.5F;
       icoord0[ch] = util_ifloor(u);
       icoord1[ch] = icoord0[ch] + 1;
-      w[ch] = FRAC(u);
+      w[ch] = frac(u);
    }
 }
 
@@ -433,8 +445,7 @@ wrap_linear_mirror_clamp_to_border(const float s[4], unsigned size,
  * Only a subset of wrap modes supported.
  */
 static void
-wrap_nearest_unorm_clamp(const float s[4], unsigned size,
-                          int icoord[4])
+wrap_nearest_unorm_clamp(const float s[4], unsigned size, int icoord[4])
 {
    uint ch;
    for (ch = 0; ch < 4; ch++) {
@@ -443,11 +454,13 @@ wrap_nearest_unorm_clamp(const float s[4], unsigned size,
    }
 }
 
-/* Handles clamp_to_edge and clamp_to_border:
+
+/**
+ * Handles clamp_to_edge and clamp_to_border:
  */
 static void
 wrap_nearest_unorm_clamp_to_border(const float s[4], unsigned size,
-                               int icoord[4])
+                                   int icoord[4])
 {
    uint ch;
    for (ch = 0; ch < 4; ch++) {
@@ -462,7 +475,7 @@ wrap_nearest_unorm_clamp_to_border(const float s[4], unsigned size,
  */
 static void
 wrap_linear_unorm_clamp(const float s[4], unsigned size,
-                         int icoord0[4], int icoord1[4], float w[4])
+                        int icoord0[4], int icoord1[4], float w[4])
 {
    uint ch;
    for (ch = 0; ch < 4; ch++) {
@@ -470,13 +483,14 @@ wrap_linear_unorm_clamp(const float s[4], unsigned size,
       float u = CLAMP(s[ch] - 0.5F, 0.0f, (float) size - 1.0f);
       icoord0[ch] = util_ifloor(u);
       icoord1[ch] = icoord0[ch] + 1;
-      w[ch] = FRAC(u);
+      w[ch] = frac(u);
    }
 }
 
+
 static void
-wrap_linear_unorm_clamp_to_border( const float s[4], unsigned size,
-                                   int icoord0[4], int icoord1[4], float w[4])
+wrap_linear_unorm_clamp_to_border(const float s[4], unsigned size,
+                                  int icoord0[4], int icoord1[4], float w[4])
 {
    uint ch;
    for (ch = 0; ch < 4; ch++) {
@@ -486,14 +500,12 @@ wrap_linear_unorm_clamp_to_border( const float s[4], unsigned size,
       icoord1[ch] = icoord0[ch] + 1;
       if (icoord1[ch] > (int) size - 1)
          icoord1[ch] = size - 1;
-      w[ch] = FRAC(u);
+      w[ch] = frac(u);
    }
 }
 
 
 
-
-
 /**
  * Examine the quad's texture coordinates to compute the partial
  * derivatives w.r.t X and Y, then compute lambda (level of detail).
@@ -509,7 +521,7 @@ compute_lambda_1d(const struct sp_sampler_varient *samp,
    const struct pipe_sampler_state *sampler = samp->sampler;
    float dsdx = fabsf(s[QUAD_BOTTOM_RIGHT] - s[QUAD_BOTTOM_LEFT]);
    float dsdy = fabsf(s[QUAD_TOP_LEFT]     - s[QUAD_BOTTOM_LEFT]);
-   float rho = MAX2(dsdx, dsdy) * texture->width[0];
+   float rho = MAX2(dsdx, dsdy) * texture->width0;
    float lambda;
 
    lambda = util_fast_log2(rho);
@@ -519,6 +531,7 @@ compute_lambda_1d(const struct sp_sampler_varient *samp,
    return lambda;
 }
 
+
 static float
 compute_lambda_2d(const struct sp_sampler_varient *samp,
                   const float s[QUAD_SIZE],
@@ -532,8 +545,8 @@ compute_lambda_2d(const struct sp_sampler_varient *samp,
    float dsdy = fabsf(s[QUAD_TOP_LEFT]     - s[QUAD_BOTTOM_LEFT]);
    float dtdx = fabsf(t[QUAD_BOTTOM_RIGHT] - t[QUAD_BOTTOM_LEFT]);
    float dtdy = fabsf(t[QUAD_TOP_LEFT]     - t[QUAD_BOTTOM_LEFT]);
-   float maxx = MAX2(dsdx, dsdy) * texture->width[0];
-   float maxy = MAX2(dtdx, dtdy) * texture->height[0];
+   float maxx = MAX2(dsdx, dsdy) * texture->width0;
+   float maxy = MAX2(dtdx, dtdy) * texture->height0;
    float rho  = MAX2(maxx, maxy);
    float lambda;
 
@@ -560,9 +573,9 @@ compute_lambda_3d(const struct sp_sampler_varient *samp,
    float dtdy = fabsf(t[QUAD_TOP_LEFT]     - t[QUAD_BOTTOM_LEFT]);
    float dpdx = fabsf(p[QUAD_BOTTOM_RIGHT] - p[QUAD_BOTTOM_LEFT]);
    float dpdy = fabsf(p[QUAD_TOP_LEFT]     - p[QUAD_BOTTOM_LEFT]);
-   float maxx = MAX2(dsdx, dsdy) * texture->width[0];
-   float maxy = MAX2(dtdx, dtdy) * texture->height[0];
-   float maxz = MAX2(dpdx, dpdy) * texture->depth[0];
+   float maxx = MAX2(dsdx, dsdy) * texture->width0;
+   float maxy = MAX2(dtdx, dtdy) * texture->height0;
+   float maxz = MAX2(dpdx, dpdy) * texture->depth0;
    float rho, lambda;
 
    rho = MAX2(maxx, maxy);
@@ -576,7 +589,10 @@ compute_lambda_3d(const struct sp_sampler_varient *samp,
 }
 
 
-
+/**
+ * Compute lambda for a vertex texture sampler.
+ * Since there aren't derivatives to use, just return the LOD bias.
+ */
 static float
 compute_lambda_vert(const struct sp_sampler_varient *samp,
                     const float s[QUAD_SIZE],
@@ -592,30 +608,68 @@ compute_lambda_vert(const struct sp_sampler_varient *samp,
 /**
  * Get a texel from a texture, using the texture tile cache.
  *
- * \param face  the cube face in 0..5
- * \param level  the mipmap level
+ * \param addr  the template tex address containing cube, z, face info.
  * \param x  the x coord of texel within 2D image
  * \param y  the y coord of texel within 2D image
- * \param z  which slice of a 3D texture
  * \param rgba  the quad to put the texel/color into
- * \param j  which element of the rgba quad to write to
  *
  * XXX maybe move this into sp_tex_tile_cache.c and merge with the
  * sp_get_cached_tile_tex() function.  Also, get 4 texels instead of 1...
  */
-static INLINE void
-get_texel_quad_2d(const struct tgsi_sampler *tgsi_sampler,
-                  union tex_tile_address addr, 
-                 unsigned x, unsigned y, 
-                  const float *out[4])
+
+
+
+
+static INLINE const float *
+get_texel_2d_no_border(const struct sp_sampler_varient *samp,
+                      union tex_tile_address addr, int x, int y)
 {
-   const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler);
+   const struct softpipe_tex_cached_tile *tile;
+
+   addr.bits.x = x / TILE_SIZE;
+   addr.bits.y = y / TILE_SIZE;
+   y %= TILE_SIZE;
+   x %= TILE_SIZE;
+
+   tile = sp_get_cached_tile_tex(samp->cache, addr);
+
+   return &tile->data.color[y][x][0];
+}
+
+
+static INLINE const float *
+get_texel_2d(const struct sp_sampler_varient *samp,
+            union tex_tile_address addr, int x, int y)
+{
+   const struct pipe_texture *texture = samp->texture;
+   unsigned level = addr.bits.level;
+
+   if (x < 0 || x >= (int) u_minify(texture->width0, level) ||
+       y < 0 || y >= (int) u_minify(texture->height0, level)) {
+      return samp->sampler->border_color;
+   }
+   else {
+      return get_texel_2d_no_border( samp, addr, x, y );
+   }
+}
+
 
-   const struct softpipe_tex_cached_tile *tile
-      = sp_get_cached_tile_tex(samp->cache, addr);
+/* Gather a quad of adjacent texels within a tile:
+ */
+static INLINE void
+get_texel_quad_2d_no_border_single_tile(const struct sp_sampler_varient *samp,
+                                       union tex_tile_address addr, 
+                                       unsigned x, unsigned y, 
+                                       const float *out[4])
+{
+   const struct softpipe_tex_cached_tile *tile;
 
+   addr.bits.x = x / TILE_SIZE;
+   addr.bits.y = y / TILE_SIZE;
    y %= TILE_SIZE;
    x %= TILE_SIZE;
+
+   tile = sp_get_cached_tile_tex(samp->cache, addr);
       
    out[0] = &tile->data.color[y  ][x  ][0];
    out[1] = &tile->data.color[y  ][x+1][0];
@@ -623,15 +677,50 @@ get_texel_quad_2d(const struct tgsi_sampler *tgsi_sampler,
    out[3] = &tile->data.color[y+1][x+1][0];
 }
 
+
+/* Gather a quad of potentially non-adjacent texels:
+ */
+static INLINE void
+get_texel_quad_2d_no_border(const struct sp_sampler_varient *samp,
+                           union tex_tile_address addr,
+                           int x0, int y0, 
+                           int x1, int y1,
+                           const float *out[4])
+{
+   out[0] = get_texel_2d_no_border( samp, addr, x0, y0 );
+   out[1] = get_texel_2d_no_border( samp, addr, x1, y0 );
+   out[2] = get_texel_2d_no_border( samp, addr, x0, y1 );
+   out[3] = get_texel_2d_no_border( samp, addr, x1, y1 );
+}
+
+/* Can involve a lot of unnecessary checks for border color:
+ */
+static INLINE void
+get_texel_quad_2d(const struct sp_sampler_varient *samp,
+                 union tex_tile_address addr,
+                 int x0, int y0, 
+                 int x1, int y1,
+                 const float *out[4])
+{
+   out[0] = get_texel_2d( samp, addr, x0, y0 );
+   out[1] = get_texel_2d( samp, addr, x1, y0 );
+   out[3] = get_texel_2d( samp, addr, x1, y1 );
+   out[2] = get_texel_2d( samp, addr, x0, y1 );
+}
+
+
+
+/* 3d varients:
+ */
 static INLINE const float *
-get_texel_2d_ptr(const struct tgsi_sampler *tgsi_sampler,
-                 union tex_tile_address addr, int x, int y)
+get_texel_3d_no_border(const struct sp_sampler_varient *samp,
+                       union tex_tile_address addr, int x, int y, int z)
 {
-   const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler);
    const struct softpipe_tex_cached_tile *tile;
 
    addr.bits.x = x / TILE_SIZE;
    addr.bits.y = y / TILE_SIZE;
+   addr.bits.z = z;
    y %= TILE_SIZE;
    x %= TILE_SIZE;
 
@@ -641,74 +730,53 @@ get_texel_2d_ptr(const struct tgsi_sampler *tgsi_sampler,
 }
 
 
-static INLINE void
-get_texel_quad_2d_mt(const struct tgsi_sampler *tgsi_sampler,
-                    union tex_tile_address addr,
-                     int x0, int y0, 
-                     int x1, int y1,
-                     const float *out[4])
-{
-   out[0] = get_texel_2d_ptr( tgsi_sampler, addr, x0, y0 );
-   out[1] = get_texel_2d_ptr( tgsi_sampler, addr, x1, y0 );
-   out[2] = get_texel_2d_ptr( tgsi_sampler, addr, x0, y1 );
-   out[3] = get_texel_2d_ptr( tgsi_sampler, addr, x1, y1 );
-}
-
-static INLINE void
-get_texel(const struct tgsi_sampler *tgsi_sampler,
-                 unsigned face, unsigned level, int x, int y, int z,
-                 float rgba[NUM_CHANNELS][QUAD_SIZE], unsigned j)
+static INLINE const float *
+get_texel_3d(const struct sp_sampler_varient *samp,
+            union tex_tile_address addr, int x, int y, int z)
 {
-   const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler);
    const struct pipe_texture *texture = samp->texture;
-   const struct pipe_sampler_state *sampler = samp->sampler;
+   unsigned level = addr.bits.level;
 
-   if (x < 0 || x >= (int) texture->width[level] ||
-       y < 0 || y >= (int) texture->height[level] ||
-       z < 0 || z >= (int) texture->depth[level]) {
-      rgba[0][j] = sampler->border_color[0];
-      rgba[1][j] = sampler->border_color[1];
-      rgba[2][j] = sampler->border_color[2];
-      rgba[3][j] = sampler->border_color[3];
+   if (x < 0 || x >= (int) u_minify(texture->width0, level) ||
+       y < 0 || y >= (int) u_minify(texture->height0, level) ||
+       z < 0 || z >= (int) u_minify(texture->depth0, level)) {
+      return samp->sampler->border_color;
    }
    else {
-      const unsigned tx = x % TILE_SIZE;
-      const unsigned ty = y % TILE_SIZE;
-      const struct softpipe_tex_cached_tile *tile;
-
-      tile = sp_get_cached_tile_tex(samp->cache, 
-                                    tex_tile_address(x, y, z, face, level));
-
-      rgba[0][j] = tile->data.color[ty][tx][0];
-      rgba[1][j] = tile->data.color[ty][tx][1];
-      rgba[2][j] = tile->data.color[ty][tx][2];
-      rgba[3][j] = tile->data.color[ty][tx][3];
-      if (0)
-      {
-         debug_printf("Get texel %f %f %f %f from %s\n",
-                      rgba[0][j], rgba[1][j], rgba[2][j], rgba[3][j],
-                      pf_name(texture->format));
-      }
+      return get_texel_3d_no_border( samp, addr, x, y, z );
    }
 }
 
 
+/**
+ * Given the logbase2 of a mipmap's base level size and a mipmap level,
+ * return the size (in texels) of that mipmap level.
+ * For example, if level[0].width = 256 then base_pot will be 8.
+ * If level = 2, then we'll return 64 (the width at level=2).
+ * Return 1 if level > base_pot.
+ */
+static INLINE unsigned
+pot_level_size(unsigned base_pot, unsigned level)
+{
+   return (base_pot >= level) ? (1 << (base_pot - level)) : 1;
+}
 
 
-
+/* Some image-filter fastpaths:
+ */
 static INLINE void
 img_filter_2d_linear_repeat_POT(struct tgsi_sampler *tgsi_sampler,
-                                  const float s[QUAD_SIZE],
-                                  const float t[QUAD_SIZE],
-                                  const float p[QUAD_SIZE],
-                                  float lodbias,
-                                  float rgba[NUM_CHANNELS][QUAD_SIZE])
+                                const float s[QUAD_SIZE],
+                                const float t[QUAD_SIZE],
+                                const float p[QUAD_SIZE],
+                                float lodbias,
+                                float rgba[NUM_CHANNELS][QUAD_SIZE])
 {
    const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler);
    unsigned  j;
    unsigned level = samp->level;
-   unsigned xpot = 1 << (samp->xpot - level);
-   unsigned ypot = 1 << (samp->ypot - level);
+   unsigned xpot = pot_level_size(samp->xpot, level);
+   unsigned ypot = pot_level_size(samp->ypot, level);
    unsigned xmax = (xpot - 1) & (TILE_SIZE - 1); /* MIN2(TILE_SIZE, xpot) - 1; */
    unsigned ymax = (ypot - 1) & (TILE_SIZE - 1); /* MIN2(TILE_SIZE, ypot) - 1; */
    union tex_tile_address addr;
@@ -716,7 +784,6 @@ img_filter_2d_linear_repeat_POT(struct tgsi_sampler *tgsi_sampler,
    addr.value = 0;
    addr.bits.level = samp->level;
 
-
    for (j = 0; j < QUAD_SIZE; j++) {
       int c;
 
@@ -736,20 +803,15 @@ img_filter_2d_linear_repeat_POT(struct tgsi_sampler *tgsi_sampler,
       
       /* Can we fetch all four at once:
        */
-      if (x0 < xmax && y0 < ymax)
-      {
-        addr.bits.x = x0 / TILE_SIZE;
-        addr.bits.y = y0 / TILE_SIZE;
-         get_texel_quad_2d(tgsi_sampler, addr, x0, y0, tx);
+      if (x0 < xmax && y0 < ymax) {
+         get_texel_quad_2d_no_border_single_tile(samp, addr, x0, y0, tx);
       }
-      else 
-      {
+      else {
          unsigned x1 = (x0 + 1) & (xpot - 1);
          unsigned y1 = (y0 + 1) & (ypot - 1);
-         get_texel_quad_2d_mt(tgsi_sampler, addr, x0, y0, x1, y1, tx);
+         get_texel_quad_2d_no_border(samp, addr, x0, y0, x1, y1, tx);
       }
 
-
       /* interpolate R, G, B, A */
       for (c = 0; c < 4; c++) {
          rgba[c][j] = lerp_2d(xw, yw, 
@@ -771,8 +833,8 @@ img_filter_2d_nearest_repeat_POT(struct tgsi_sampler *tgsi_sampler,
    const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler);
    unsigned  j;
    unsigned level = samp->level;
-   unsigned xpot = 1 << (samp->xpot - level);
-   unsigned ypot = 1 << (samp->ypot - level);
+   unsigned xpot = pot_level_size(samp->xpot, level);
+   unsigned ypot = pot_level_size(samp->ypot, level);
    union tex_tile_address addr;
 
    addr.value = 0;
@@ -790,7 +852,7 @@ img_filter_2d_nearest_repeat_POT(struct tgsi_sampler *tgsi_sampler,
       int x0 = uflr & (xpot - 1);
       int y0 = vflr & (ypot - 1);
 
-      const float *out = get_texel_2d_ptr(tgsi_sampler, addr, x0, y0);
+      const float *out = get_texel_2d_no_border(samp, addr, x0, y0);
 
       for (c = 0; c < 4; c++) {
          rgba[c][j] = out[c];
@@ -810,8 +872,8 @@ img_filter_2d_nearest_clamp_POT(struct tgsi_sampler *tgsi_sampler,
    const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler);
    unsigned  j;
    unsigned level = samp->level;
-   unsigned xpot = 1 << (samp->xpot - level);
-   unsigned ypot = 1 << (samp->ypot - level);
+   unsigned xpot = pot_level_size(samp->xpot, level);
+   unsigned ypot = pot_level_size(samp->ypot, level);
    union tex_tile_address addr;
 
    addr.value = 0;
@@ -838,7 +900,7 @@ img_filter_2d_nearest_clamp_POT(struct tgsi_sampler *tgsi_sampler,
       else if (y0 > ypot - 1)
          y0 = ypot - 1;
       
-      out = get_texel_2d_ptr(tgsi_sampler, addr, x0, y0);
+      out = get_texel_2d_no_border(samp, addr, x0, y0);
 
       for (c = 0; c < 4; c++) {
          rgba[c][j] = out[c];
@@ -846,6 +908,7 @@ img_filter_2d_nearest_clamp_POT(struct tgsi_sampler *tgsi_sampler,
    }
 }
 
+
 static void
 img_filter_1d_nearest(struct tgsi_sampler *tgsi_sampler,
                         const float s[QUAD_SIZE],
@@ -859,16 +922,24 @@ img_filter_1d_nearest(struct tgsi_sampler *tgsi_sampler,
    unsigned level0, j;
    int width;
    int x[4];
+   union tex_tile_address addr;
 
    level0 = samp->level;
-   width = texture->width[level0];
+   width = u_minify(texture->width0, level0);
 
    assert(width > 0);
 
+   addr.value = 0;
+   addr.bits.level = samp->level;
+
    samp->nearest_texcoord_s(s, width, x);
 
    for (j = 0; j < QUAD_SIZE; j++) {
-      get_texel(tgsi_sampler, 0, level0, x[j], 0, 0, rgba, j);
+      const float *out = get_texel_2d(samp, addr, x[j], 0);
+      int c;
+      for (c = 0; c < 4; c++) {
+         rgba[c][j] = out[c];
+      }
    }
 }
 
@@ -880,6 +951,53 @@ img_filter_2d_nearest(struct tgsi_sampler *tgsi_sampler,
                       const float p[QUAD_SIZE],
                       float lodbias,
                       float rgba[NUM_CHANNELS][QUAD_SIZE])
+{
+   const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler);
+   const struct pipe_texture *texture = samp->texture;
+   unsigned level0, j;
+   int width, height;
+   int x[4], y[4];
+   union tex_tile_address addr;
+
+
+   level0 = samp->level;
+   width = u_minify(texture->width0, level0);
+   height = u_minify(texture->height0, level0);
+
+   assert(width > 0);
+   assert(height > 0);
+   addr.value = 0;
+   addr.bits.level = samp->level;
+
+   samp->nearest_texcoord_s(s, width, x);
+   samp->nearest_texcoord_t(t, height, y);
+
+   for (j = 0; j < QUAD_SIZE; j++) {
+      const float *out = get_texel_2d(samp, addr, x[j], y[j]);
+      int c;
+      for (c = 0; c < 4; c++) {
+         rgba[c][j] = out[c];
+      }
+   }
+}
+
+
+static INLINE union tex_tile_address
+face(union tex_tile_address addr, unsigned face )
+{
+   addr.bits.face = face;
+   return addr;
+}
+
+
+static void
+img_filter_cube_nearest(struct tgsi_sampler *tgsi_sampler,
+                        const float s[QUAD_SIZE],
+                        const float t[QUAD_SIZE],
+                        const float p[QUAD_SIZE],
+                        float lodbias,
+                        float rgba[NUM_CHANNELS][QUAD_SIZE])
 {
    const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler);
    const struct pipe_texture *texture = samp->texture;
@@ -887,18 +1005,27 @@ img_filter_2d_nearest(struct tgsi_sampler *tgsi_sampler,
    unsigned level0, j;
    int width, height;
    int x[4], y[4];
+   union tex_tile_address addr;
 
    level0 = samp->level;
-   width = texture->width[level0];
-   height = texture->height[level0];
+   width = u_minify(texture->width0, level0);
+   height = u_minify(texture->height0, level0);
 
    assert(width > 0);
+   assert(height > 0);
+   addr.value = 0;
+   addr.bits.level = samp->level;
 
    samp->nearest_texcoord_s(s, width, x);
    samp->nearest_texcoord_t(t, height, y);
 
    for (j = 0; j < QUAD_SIZE; j++) {
-      get_texel(tgsi_sampler, faces[j], level0, x[j], y[j], 0, rgba, j);
+      const float *out = get_texel_2d(samp, face(addr, faces[j]), x[j], y[j]);
+      int c;
+      for (c = 0; c < 4; c++) {
+         rgba[c][j] = out[c];
+      }
    }
 }
 
@@ -916,11 +1043,12 @@ img_filter_3d_nearest(struct tgsi_sampler *tgsi_sampler,
    unsigned level0, j;
    int width, height, depth;
    int x[4], y[4], z[4];
+   union tex_tile_address addr;
 
    level0 = samp->level;
-   width = texture->width[level0];
-   height = texture->height[level0];
-   depth = texture->depth[level0];
+   width = u_minify(texture->width0, level0);
+   height = u_minify(texture->height0, level0);
+   depth = u_minify(texture->depth0, level0);
 
    assert(width > 0);
    assert(height > 0);
@@ -930,8 +1058,15 @@ img_filter_3d_nearest(struct tgsi_sampler *tgsi_sampler,
    samp->nearest_texcoord_t(t, height, y);
    samp->nearest_texcoord_p(p, depth,  z);
 
+   addr.value = 0;
+   addr.bits.level = samp->level;
+
    for (j = 0; j < QUAD_SIZE; j++) {
-      get_texel(tgsi_sampler, 0, level0, x[j], y[j], z[j], rgba, j);
+      const float *out = get_texel_3d(samp, addr, x[j], y[j], z[j]);
+      int c;
+      for (c = 0; c < 4; c++) {
+         rgba[c][j] = out[c];
+      }      
    }
 }
 
@@ -950,29 +1085,31 @@ img_filter_1d_linear(struct tgsi_sampler *tgsi_sampler,
    int width;
    int x0[4], x1[4];
    float xw[4]; /* weights */
-
+   union tex_tile_address addr;
 
    level0 = samp->level;
-   width = texture->width[level0];
+   width = u_minify(texture->width0, level0);
 
    assert(width > 0);
 
-   samp->linear_texcoord_s(s, width, x0, x1, xw);
+   addr.value = 0;
+   addr.bits.level = samp->level;
 
+   samp->linear_texcoord_s(s, width, x0, x1, xw);
 
    for (j = 0; j < QUAD_SIZE; j++) {
-      float tx[4][4]; /* texels */
+      const float *tx0 = get_texel_2d(samp, addr, x0[j], 0);
+      const float *tx1 = get_texel_2d(samp, addr, x1[j], 0);
       int c;
-      get_texel(tgsi_sampler, 0, level0, x0[j], 0, 0, tx, 0);
-      get_texel(tgsi_sampler, 0, level0, x1[j], 0, 0, tx, 1);
 
       /* interpolate R, G, B, A */
       for (c = 0; c < 4; c++) {
-         rgba[c][j] = lerp(xw[j], tx[c][0], tx[c][1]);
+         rgba[c][j] = lerp(xw[j], tx0[c], tx1[c]);
       }
    }
 }
 
+
 static void
 img_filter_2d_linear(struct tgsi_sampler *tgsi_sampler,
                      const float s[QUAD_SIZE],
@@ -983,35 +1120,85 @@ img_filter_2d_linear(struct tgsi_sampler *tgsi_sampler,
 {
    const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler);
    const struct pipe_texture *texture = samp->texture;
-   const unsigned *faces = samp->faces; /* zero when not cube-mapping */
    unsigned level0, j;
    int width, height;
    int x0[4], y0[4], x1[4], y1[4];
    float xw[4], yw[4]; /* weights */
+   union tex_tile_address addr;
+
+   level0 = samp->level;
+   width = u_minify(texture->width0, level0);
+   height = u_minify(texture->height0, level0);
+
+   assert(width > 0);
+   assert(height > 0);
+
+   addr.value = 0;
+   addr.bits.level = samp->level;
+
+   samp->linear_texcoord_s(s, width,  x0, x1, xw);
+   samp->linear_texcoord_t(t, height, y0, y1, yw);
 
+   for (j = 0; j < QUAD_SIZE; j++) {
+      const float *tx0 = get_texel_2d(samp, addr, x0[j], y0[j]);
+      const float *tx1 = get_texel_2d(samp, addr, x1[j], y0[j]);
+      const float *tx2 = get_texel_2d(samp, addr, x0[j], y1[j]);
+      const float *tx3 = get_texel_2d(samp, addr, x1[j], y1[j]);
+      int c;
+
+      /* interpolate R, G, B, A */
+      for (c = 0; c < 4; c++) {
+         rgba[c][j] = lerp_2d(xw[j], yw[j],
+                              tx0[c], tx1[c],
+                              tx2[c], tx3[c]);
+      }
+   }
+}
+
+
+static void
+img_filter_cube_linear(struct tgsi_sampler *tgsi_sampler,
+                       const float s[QUAD_SIZE],
+                       const float t[QUAD_SIZE],
+                       const float p[QUAD_SIZE],
+                       float lodbias,
+                       float rgba[NUM_CHANNELS][QUAD_SIZE])
+{
+   const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler);
+   const struct pipe_texture *texture = samp->texture;
+   const unsigned *faces = samp->faces; /* zero when not cube-mapping */
+   unsigned level0, j;
+   int width, height;
+   int x0[4], y0[4], x1[4], y1[4];
+   float xw[4], yw[4]; /* weights */
+   union tex_tile_address addr;
 
    level0 = samp->level;
-   width = texture->width[level0];
-   height = texture->height[level0];
+   width = u_minify(texture->width0, level0);
+   height = u_minify(texture->height0, level0);
 
    assert(width > 0);
+   assert(height > 0);
+
+   addr.value = 0;
+   addr.bits.level = samp->level;
 
    samp->linear_texcoord_s(s, width,  x0, x1, xw);
    samp->linear_texcoord_t(t, height, y0, y1, yw);
 
    for (j = 0; j < QUAD_SIZE; j++) {
-      float tx[4][4]; /* texels */
+      union tex_tile_address addrj = face(addr, faces[j]);
+      const float *tx0 = get_texel_2d(samp, addrj, x0[j], y0[j]);
+      const float *tx1 = get_texel_2d(samp, addrj, x1[j], y0[j]);
+      const float *tx2 = get_texel_2d(samp, addrj, x0[j], y1[j]);
+      const float *tx3 = get_texel_2d(samp, addrj, x1[j], y1[j]);
       int c;
-      get_texel(tgsi_sampler, faces[j], level0, x0[j], y0[j], 0, tx, 0);
-      get_texel(tgsi_sampler, faces[j], level0, x1[j], y0[j], 0, tx, 1);
-      get_texel(tgsi_sampler, faces[j], level0, x0[j], y1[j], 0, tx, 2);
-      get_texel(tgsi_sampler, faces[j], level0, x1[j], y1[j], 0, tx, 3);
 
       /* interpolate R, G, B, A */
       for (c = 0; c < 4; c++) {
          rgba[c][j] = lerp_2d(xw[j], yw[j],
-                              tx[c][0], tx[c][1],
-                              tx[c][2], tx[c][3]);
+                              tx0[c], tx1[c],
+                              tx2[c], tx3[c]);
       }
    }
 }
@@ -1031,11 +1218,15 @@ img_filter_3d_linear(struct tgsi_sampler *tgsi_sampler,
    int width, height, depth;
    int x0[4], x1[4], y0[4], y1[4], z0[4], z1[4];
    float xw[4], yw[4], zw[4]; /* interpolation weights */
+   union tex_tile_address addr;
 
    level0 = samp->level;
-   width = texture->width[level0];
-   height = texture->height[level0];
-   depth = texture->depth[level0];
+   width = u_minify(texture->width0, level0);
+   height = u_minify(texture->height0, level0);
+   depth = u_minify(texture->depth0, level0);
+
+   addr.value = 0;
+   addr.bits.level = level0;
 
    assert(width > 0);
    assert(height > 0);
@@ -1046,42 +1237,37 @@ img_filter_3d_linear(struct tgsi_sampler *tgsi_sampler,
    samp->linear_texcoord_p(p, depth,  z0, z1, zw);
 
    for (j = 0; j < QUAD_SIZE; j++) {
-      float tx0[4][4], tx1[4][4];
       int c;
-      
-      get_texel(tgsi_sampler, 0, level0, x0[j], y0[j], z0[j], tx0, 0);
-      get_texel(tgsi_sampler, 0, level0, x1[j], y0[j], z0[j], tx0, 1);
-      get_texel(tgsi_sampler, 0, level0, x0[j], y1[j], z0[j], tx0, 2);
-      get_texel(tgsi_sampler, 0, level0, x1[j], y1[j], z0[j], tx0, 3);
-      get_texel(tgsi_sampler, 0, level0, x0[j], y0[j], z1[j], tx1, 0);
-      get_texel(tgsi_sampler, 0, level0, x1[j], y0[j], z1[j], tx1, 1);
-      get_texel(tgsi_sampler, 0, level0, x0[j], y1[j], z1[j], tx1, 2);
-      get_texel(tgsi_sampler, 0, level0, x1[j], y1[j], z1[j], tx1, 3);
 
+      const float *tx00 = get_texel_3d(samp, addr, x0[j], y0[j], z0[j]);
+      const float *tx01 = get_texel_3d(samp, addr, x1[j], y0[j], z0[j]);
+      const float *tx02 = get_texel_3d(samp, addr, x0[j], y1[j], z0[j]);
+      const float *tx03 = get_texel_3d(samp, addr, x1[j], y1[j], z0[j]);
+      
+      const float *tx10 = get_texel_3d(samp, addr, x0[j], y0[j], z1[j]);
+      const float *tx11 = get_texel_3d(samp, addr, x1[j], y0[j], z1[j]);
+      const float *tx12 = get_texel_3d(samp, addr, x0[j], y1[j], z1[j]);
+      const float *tx13 = get_texel_3d(samp, addr, x1[j], y1[j], z1[j]);
+      
       /* interpolate R, G, B, A */
       for (c = 0; c < 4; c++) {
          rgba[c][j] = lerp_3d(xw[j], yw[j], zw[j],
-                              tx0[c][0], tx0[c][1],
-                              tx0[c][2], tx0[c][3],
-                              tx1[c][0], tx1[c][1],
-                              tx1[c][2], tx1[c][3]);
+                              tx00[c], tx01[c],
+                              tx02[c], tx03[c],
+                              tx10[c], tx11[c],
+                              tx12[c], tx13[c]);
       }
    }
 }
 
 
-
-
-
-
-
 static void
 mip_filter_linear(struct tgsi_sampler *tgsi_sampler,
-                     const float s[QUAD_SIZE],
-                     const float t[QUAD_SIZE],
-                     const float p[QUAD_SIZE],
-                     float lodbias,
-                     float rgba[NUM_CHANNELS][QUAD_SIZE])
+                  const float s[QUAD_SIZE],
+                  const float t[QUAD_SIZE],
+                  const float p[QUAD_SIZE],
+                  float lodbias,
+                  float rgba[NUM_CHANNELS][QUAD_SIZE])
 {
    struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler);
    const struct pipe_texture *texture = samp->texture;
@@ -1120,7 +1306,6 @@ mip_filter_linear(struct tgsi_sampler *tgsi_sampler,
 }
 
 
-
 static void
 mip_filter_nearest(struct tgsi_sampler *tgsi_sampler,
                    const float s[QUAD_SIZE],
@@ -1144,6 +1329,14 @@ mip_filter_nearest(struct tgsi_sampler *tgsi_sampler,
       samp->level = MIN2(samp->level, (int)texture->last_level);
       samp->min_img_filter( tgsi_sampler, s, t, p, 0, rgba );
    }
+
+#if 0
+   printf("RGBA %g %g %g %g, %g %g %g %g, %g %g %g %g, %g %g %g %g\n",
+          rgba[0][0], rgba[1][0], rgba[2][0], rgba[3][0],
+          rgba[0][1], rgba[1][1], rgba[2][1], rgba[3][1],
+          rgba[0][2], rgba[1][2], rgba[2][2], rgba[3][2],
+          rgba[0][3], rgba[1][3], rgba[2][3], rgba[3][3]);
+#endif
 }
 
 
@@ -1168,7 +1361,8 @@ mip_filter_none(struct tgsi_sampler *tgsi_sampler,
 
 
 
-/* Specialized version of mip_filter_linear with hard-wired calls to
+/**
+ * Specialized version of mip_filter_linear with hard-wired calls to
  * 2d lambda calculation and 2d_linear_repeat_POT img filters.
  */
 static void
@@ -1220,7 +1414,8 @@ mip_filter_linear_2d_linear_repeat_POT(
 
 
 
-/* Compare stage in the little sampling pipeline.
+/**
+ * Do shadow/depth comparisons.
  */
 static void
 sample_compare(struct tgsi_sampler *tgsi_sampler,
@@ -1237,7 +1432,6 @@ sample_compare(struct tgsi_sampler *tgsi_sampler,
 
    samp->mip_filter( tgsi_sampler, s, t, p, lodbias, rgba );
 
-
    /**
     * Compare texcoord 'p' (aka R) against texture value 'rgba[0]'
     * When we sampled the depth texture, the depth value was put into all
@@ -1304,7 +1498,10 @@ sample_compare(struct tgsi_sampler *tgsi_sampler,
    }
 }
 
-/* Calculate cube faces.
+
+/**
+ * Compute which cube face is referenced by each texcoord and put that
+ * info into the sampler faces[] array.  Then sample the cube faces
  */
 static void
 sample_cube(struct tgsi_sampler *tgsi_sampler,
@@ -1337,7 +1534,7 @@ sample_cube(struct tgsi_sampler *tgsi_sampler,
       unsigned face;
       float sc, tc, ma;
 
-      if (arx > ary && arx > arz) {
+      if (arx >= ary && arx >= arz) {
          if (rx >= 0.0F) {
             face = PIPE_TEX_FACE_POS_X;
             sc = -rz;
@@ -1351,7 +1548,7 @@ sample_cube(struct tgsi_sampler *tgsi_sampler,
             ma = arx;
          }
       }
-      else if (ary > arx && ary > arz) {
+      else if (ary >= arx && ary >= arz) {
          if (ry >= 0.0F) {
             face = PIPE_TEX_FACE_POS_Y;
             sc = rx;
@@ -1380,9 +1577,12 @@ sample_cube(struct tgsi_sampler *tgsi_sampler,
          }
       }
 
-      ssss[j] = ( sc / ma + 1.0F ) * 0.5F;
-      tttt[j] = ( tc / ma + 1.0F ) * 0.5F;
-      samp->faces[j] = face;
+      {
+        const float ima = 1.0 / ma;
+        ssss[j] = ( sc * ima + 1.0F ) * 0.5F;
+        tttt[j] = ( tc * ima + 1.0F ) * 0.5F;
+        samp->faces[j] = face;
+      }
    }
 
    /* In our little pipeline, the compare stage is next.  If compare
@@ -1394,8 +1594,8 @@ sample_cube(struct tgsi_sampler *tgsi_sampler,
 
 
 
-
-static wrap_nearest_func get_nearest_unorm_wrap( unsigned mode )
+static wrap_nearest_func
+get_nearest_unorm_wrap(unsigned mode)
 {
    switch (mode) {
    case PIPE_TEX_WRAP_CLAMP:
@@ -1410,7 +1610,8 @@ static wrap_nearest_func get_nearest_unorm_wrap( unsigned mode )
 }
 
 
-static wrap_nearest_func get_nearest_wrap( unsigned mode )
+static wrap_nearest_func
+get_nearest_wrap(unsigned mode)
 {
    switch (mode) {
    case PIPE_TEX_WRAP_REPEAT:
@@ -1435,7 +1636,9 @@ static wrap_nearest_func get_nearest_wrap( unsigned mode )
    }
 }
 
-static wrap_linear_func get_linear_unorm_wrap( unsigned mode )
+
+static wrap_linear_func
+get_linear_unorm_wrap(unsigned mode)
 {
    switch (mode) {
    case PIPE_TEX_WRAP_CLAMP:
@@ -1449,7 +1652,9 @@ static wrap_linear_func get_linear_unorm_wrap( unsigned mode )
    }
 }
 
-static wrap_linear_func get_linear_wrap( unsigned mode )
+
+static wrap_linear_func
+get_linear_wrap(unsigned mode)
 {
    switch (mode) {
    case PIPE_TEX_WRAP_REPEAT:
@@ -1474,7 +1679,9 @@ static wrap_linear_func get_linear_wrap( unsigned mode )
    }
 }
 
-static compute_lambda_func get_lambda_func( const union sp_sampler_key key )
+
+static compute_lambda_func
+get_lambda_func(const union sp_sampler_key key)
 {
    if (key.bits.processor == TGSI_PROCESSOR_VERTEX)
       return compute_lambda_vert;
@@ -1493,9 +1700,11 @@ static compute_lambda_func get_lambda_func( const union sp_sampler_key key )
    }
 }
 
-static filter_func get_img_filter( const union sp_sampler_key key,
-                                   unsigned filter,
-                                   const struct pipe_sampler_state *sampler )
+
+static filter_func
+get_img_filter(const union sp_sampler_key key,
+               unsigned filter,
+               const struct pipe_sampler_state *sampler)
 {
    switch (key.bits.target) {
    case PIPE_TEXTURE_1D:
@@ -1531,14 +1740,19 @@ static filter_func get_img_filter( const union sp_sampler_key key,
             }
          }
       }
-      /* Fallthrough to default versions:
+      /* Otherwise use default versions:
        */
-   case PIPE_TEXTURE_CUBE:
       if (filter == PIPE_TEX_FILTER_NEAREST) 
          return img_filter_2d_nearest;
       else
          return img_filter_2d_linear;
       break;
+   case PIPE_TEXTURE_CUBE:
+      if (filter == PIPE_TEX_FILTER_NEAREST) 
+         return img_filter_cube_nearest;
+      else
+         return img_filter_cube_linear;
+      break;
    case PIPE_TEXTURE_3D:
       if (filter == PIPE_TEX_FILTER_NEAREST) 
          return img_filter_3d_nearest;
@@ -1564,8 +1778,8 @@ sp_sampler_varient_bind_texture( struct sp_sampler_varient *samp,
 
    samp->texture = texture;
    samp->cache = tex_cache;
-   samp->xpot = util_unsigned_logbase2( texture->width[0] );
-   samp->ypot = util_unsigned_logbase2( texture->height[0] );
+   samp->xpot = util_unsigned_logbase2( texture->width0 );
+   samp->ypot = util_unsigned_logbase2( texture->height0 );
    samp->level = CLAMP((int) sampler->min_lod, 0, (int) texture->last_level);
 }
 
@@ -1577,7 +1791,8 @@ sp_sampler_varient_destroy( struct sp_sampler_varient *samp )
 }
 
 
-/* Create a sampler varient for a given set of non-orthogonal state.  Currently the 
+/**
+ * Create a sampler varient for a given set of non-orthogonal state.
  */
 struct sp_sampler_varient *
 sp_create_sampler_varient( const struct pipe_sampler_state *sampler,
@@ -1674,9 +1889,3 @@ sp_create_sampler_varient( const struct pipe_sampler_state *sampler,
 
    return samp;
 }
-
-
-
-
-
-