Merge branch 'llvm-cliptest-viewport'
[mesa.git] / src / mesa / swrast / s_texfilter.c
index 997c2f4bb79c5c443ed008be194f640c056a1414..ec281776d0d1f998fffc9a36bd8d7cdf464fa7ac 100644 (file)
@@ -135,8 +135,11 @@ lerp_rgba_3d(GLfloat result[4], GLfloat a, GLfloat b, GLfloat 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.
+ * Used for GL_REPEAT wrap mode.  Using A % B doesn't produce the
+ * right results for A<0.  Casting to A to be unsigned only works if B
+ * is a power of two.  Adding a bias to A (which is a multiple of B)
+ * avoids the problems with A < 0 (for reasonable A) without using a
+ * conditional.
  */
 #define REMAINDER(A, B) (((A) + (B) * 1024) % (B))
 
@@ -488,14 +491,15 @@ tex_array_slice(GLfloat coord, GLsizei size)
 
 /**
  * Compute nearest integer texcoords for given texobj and coordinate.
+ * NOTE: only used for depth texture sampling.
  */
 static INLINE void
 nearest_texcoord(const struct gl_texture_object *texObj,
+                 GLuint level,
                  const GLfloat texcoord[4],
                  GLint *i, GLint *j, GLint *k)
 {
-   const GLint baseLevel = texObj->BaseLevel;
-   const struct gl_texture_image *img = texObj->Image[0][baseLevel];
+   const struct gl_texture_image *img = texObj->Image[0][level];
    const GLint width = img->Width;
    const GLint height = img->Height;
    const GLint depth = img->Depth;
@@ -534,15 +538,16 @@ nearest_texcoord(const struct gl_texture_object *texObj,
 
 /**
  * Compute linear integer texcoords for given texobj and coordinate.
+ * NOTE: only used for depth texture sampling.
  */
 static INLINE void
 linear_texcoord(const struct gl_texture_object *texObj,
+                GLuint level,
                 const GLfloat texcoord[4],
                 GLint *i0, GLint *i1, GLint *j0, GLint *j1, GLint *slice,
                 GLfloat *wi, GLfloat *wj)
 {
-   const GLint baseLevel = texObj->BaseLevel;
-   const struct gl_texture_image *img = texObj->Image[0][baseLevel];
+   const struct gl_texture_image *img = texObj->Image[0][level];
    const GLint width = img->Width;
    const GLint height = img->Height;
    const GLint depth = img->Depth;
@@ -793,7 +798,7 @@ get_border_color(const struct gl_texture_object *tObj,
  * Return the texture sample for coordinate (s) using GL_NEAREST filter.
  */
 static INLINE void
-sample_1d_nearest(GLcontext *ctx,
+sample_1d_nearest(struct gl_context *ctx,
                   const struct gl_texture_object *tObj,
                   const struct gl_texture_image *img,
                   const GLfloat texcoord[4], GLfloat rgba[4])
@@ -817,7 +822,7 @@ sample_1d_nearest(GLcontext *ctx,
  * Return the texture sample for coordinate (s) using GL_LINEAR filter.
  */
 static INLINE void
-sample_1d_linear(GLcontext *ctx,
+sample_1d_linear(struct gl_context *ctx,
                  const struct gl_texture_object *tObj,
                  const struct gl_texture_image *img,
                  const GLfloat texcoord[4], GLfloat rgba[4])
@@ -858,7 +863,7 @@ sample_1d_linear(GLcontext *ctx,
 
 
 static void
-sample_1d_nearest_mipmap_nearest(GLcontext *ctx,
+sample_1d_nearest_mipmap_nearest(struct gl_context *ctx,
                                  const struct gl_texture_object *tObj,
                                  GLuint n, const GLfloat texcoord[][4],
                                  const GLfloat lambda[], GLfloat rgba[][4])
@@ -873,7 +878,7 @@ sample_1d_nearest_mipmap_nearest(GLcontext *ctx,
 
 
 static void
-sample_1d_linear_mipmap_nearest(GLcontext *ctx,
+sample_1d_linear_mipmap_nearest(struct gl_context *ctx,
                                 const struct gl_texture_object *tObj,
                                 GLuint n, const GLfloat texcoord[][4],
                                 const GLfloat lambda[], GLfloat rgba[][4])
@@ -888,7 +893,7 @@ sample_1d_linear_mipmap_nearest(GLcontext *ctx,
 
 
 static void
-sample_1d_nearest_mipmap_linear(GLcontext *ctx,
+sample_1d_nearest_mipmap_linear(struct gl_context *ctx,
                                 const struct gl_texture_object *tObj,
                                 GLuint n, const GLfloat texcoord[][4],
                                 const GLfloat lambda[], GLfloat rgba[][4])
@@ -913,7 +918,7 @@ sample_1d_nearest_mipmap_linear(GLcontext *ctx,
 
 
 static void
-sample_1d_linear_mipmap_linear(GLcontext *ctx,
+sample_1d_linear_mipmap_linear(struct gl_context *ctx,
                                const struct gl_texture_object *tObj,
                                GLuint n, const GLfloat texcoord[][4],
                                const GLfloat lambda[], GLfloat rgba[][4])
@@ -939,7 +944,7 @@ sample_1d_linear_mipmap_linear(GLcontext *ctx,
 
 /** Sample 1D texture, nearest filtering for both min/magnification */
 static void
-sample_nearest_1d( GLcontext *ctx,
+sample_nearest_1d( struct gl_context *ctx,
                    const struct gl_texture_object *tObj, GLuint n,
                    const GLfloat texcoords[][4], const GLfloat lambda[],
                    GLfloat rgba[][4] )
@@ -955,7 +960,7 @@ sample_nearest_1d( GLcontext *ctx,
 
 /** Sample 1D texture, linear filtering for both min/magnification */
 static void
-sample_linear_1d( GLcontext *ctx,
+sample_linear_1d( struct gl_context *ctx,
                   const struct gl_texture_object *tObj, GLuint n,
                   const GLfloat texcoords[][4], const GLfloat lambda[],
                   GLfloat rgba[][4] )
@@ -971,7 +976,7 @@ sample_linear_1d( GLcontext *ctx,
 
 /** Sample 1D texture, using lambda to choose between min/magnification */
 static void
-sample_lambda_1d( GLcontext *ctx,
+sample_lambda_1d( struct gl_context *ctx,
                   const struct gl_texture_object *tObj, GLuint n,
                   const GLfloat texcoords[][4],
                   const GLfloat lambda[], GLfloat rgba[][4] )
@@ -1050,7 +1055,7 @@ sample_lambda_1d( GLcontext *ctx,
  * Return the texture sample for coordinate (s,t) using GL_NEAREST filter.
  */
 static INLINE void
-sample_2d_nearest(GLcontext *ctx,
+sample_2d_nearest(struct gl_context *ctx,
                   const struct gl_texture_object *tObj,
                   const struct gl_texture_image *img,
                   const GLfloat texcoord[4],
@@ -1083,7 +1088,7 @@ sample_2d_nearest(GLcontext *ctx,
  * New sampling code contributed by Lynn Quam <quam@ai.sri.com>.
  */
 static INLINE void
-sample_2d_linear(GLcontext *ctx,
+sample_2d_linear(struct gl_context *ctx,
                  const struct gl_texture_object *tObj,
                  const struct gl_texture_image *img,
                  const GLfloat texcoord[4],
@@ -1147,7 +1152,7 @@ sample_2d_linear(GLcontext *ctx,
  * We don't have to worry about the texture border.
  */
 static INLINE void
-sample_2d_linear_repeat(GLcontext *ctx,
+sample_2d_linear_repeat(struct gl_context *ctx,
                         const struct gl_texture_object *tObj,
                         const struct gl_texture_image *img,
                         const GLfloat texcoord[4],
@@ -1180,7 +1185,7 @@ sample_2d_linear_repeat(GLcontext *ctx,
 
 
 static void
-sample_2d_nearest_mipmap_nearest(GLcontext *ctx,
+sample_2d_nearest_mipmap_nearest(struct gl_context *ctx,
                                  const struct gl_texture_object *tObj,
                                  GLuint n, const GLfloat texcoord[][4],
                                  const GLfloat lambda[], GLfloat rgba[][4])
@@ -1194,7 +1199,7 @@ sample_2d_nearest_mipmap_nearest(GLcontext *ctx,
 
 
 static void
-sample_2d_linear_mipmap_nearest(GLcontext *ctx,
+sample_2d_linear_mipmap_nearest(struct gl_context *ctx,
                                 const struct gl_texture_object *tObj,
                                 GLuint n, const GLfloat texcoord[][4],
                                 const GLfloat lambda[], GLfloat rgba[][4])
@@ -1209,7 +1214,7 @@ sample_2d_linear_mipmap_nearest(GLcontext *ctx,
 
 
 static void
-sample_2d_nearest_mipmap_linear(GLcontext *ctx,
+sample_2d_nearest_mipmap_linear(struct gl_context *ctx,
                                 const struct gl_texture_object *tObj,
                                 GLuint n, const GLfloat texcoord[][4],
                                 const GLfloat lambda[], GLfloat rgba[][4])
@@ -1234,7 +1239,7 @@ sample_2d_nearest_mipmap_linear(GLcontext *ctx,
 
 
 static void
-sample_2d_linear_mipmap_linear( GLcontext *ctx,
+sample_2d_linear_mipmap_linear( struct gl_context *ctx,
                                 const struct gl_texture_object *tObj,
                                 GLuint n, const GLfloat texcoord[][4],
                                 const GLfloat lambda[], GLfloat rgba[][4] )
@@ -1259,7 +1264,7 @@ sample_2d_linear_mipmap_linear( GLcontext *ctx,
 
 
 static void
-sample_2d_linear_mipmap_linear_repeat(GLcontext *ctx,
+sample_2d_linear_mipmap_linear_repeat(struct gl_context *ctx,
                                       const struct gl_texture_object *tObj,
                                       GLuint n, const GLfloat texcoord[][4],
                                       const GLfloat lambda[], GLfloat rgba[][4])
@@ -1289,7 +1294,7 @@ sample_2d_linear_mipmap_linear_repeat(GLcontext *ctx,
 
 /** Sample 2D texture, nearest filtering for both min/magnification */
 static void
-sample_nearest_2d(GLcontext *ctx,
+sample_nearest_2d(struct gl_context *ctx,
                   const struct gl_texture_object *tObj, GLuint n,
                   const GLfloat texcoords[][4],
                   const GLfloat lambda[], GLfloat rgba[][4])
@@ -1305,7 +1310,7 @@ sample_nearest_2d(GLcontext *ctx,
 
 /** Sample 2D texture, linear filtering for both min/magnification */
 static void
-sample_linear_2d(GLcontext *ctx,
+sample_linear_2d(struct gl_context *ctx,
                  const struct gl_texture_object *tObj, GLuint n,
                  const GLfloat texcoords[][4],
                  const GLfloat lambda[], GLfloat rgba[][4])
@@ -1338,7 +1343,7 @@ sample_linear_2d(GLcontext *ctx,
  *    Format = GL_RGB
  */
 static void
-opt_sample_rgb_2d(GLcontext *ctx,
+opt_sample_rgb_2d(struct gl_context *ctx,
                   const struct gl_texture_object *tObj,
                   GLuint n, const GLfloat texcoords[][4],
                   const GLfloat lambda[], GLfloat rgba[][4])
@@ -1379,7 +1384,7 @@ opt_sample_rgb_2d(GLcontext *ctx,
  *    Format = GL_RGBA
  */
 static void
-opt_sample_rgba_2d(GLcontext *ctx,
+opt_sample_rgba_2d(struct gl_context *ctx,
                    const struct gl_texture_object *tObj,
                    GLuint n, const GLfloat texcoords[][4],
                    const GLfloat lambda[], GLfloat rgba[][4])
@@ -1414,7 +1419,7 @@ opt_sample_rgba_2d(GLcontext *ctx,
 
 /** Sample 2D texture, using lambda to choose between min/magnification */
 static void
-sample_lambda_2d(GLcontext *ctx,
+sample_lambda_2d(struct gl_context *ctx,
                  const struct gl_texture_object *tObj,
                  GLuint n, const GLfloat texcoords[][4],
                  const GLfloat lambda[], GLfloat rgba[][4])
@@ -1535,7 +1540,7 @@ sample_lambda_2d(GLcontext *ctx,
  * Return the texture sample for coordinate (s,t,r) using GL_NEAREST filter.
  */
 static INLINE void
-sample_3d_nearest(GLcontext *ctx,
+sample_3d_nearest(struct gl_context *ctx,
                   const struct gl_texture_object *tObj,
                   const struct gl_texture_image *img,
                   const GLfloat texcoord[4],
@@ -1567,7 +1572,7 @@ sample_3d_nearest(GLcontext *ctx,
  * Return the texture sample for coordinate (s,t,r) using GL_LINEAR filter.
  */
 static void
-sample_3d_linear(GLcontext *ctx,
+sample_3d_linear(struct gl_context *ctx,
                  const struct gl_texture_object *tObj,
                  const struct gl_texture_image *img,
                  const GLfloat texcoord[4],
@@ -1661,7 +1666,7 @@ sample_3d_linear(GLcontext *ctx,
 
 
 static void
-sample_3d_nearest_mipmap_nearest(GLcontext *ctx,
+sample_3d_nearest_mipmap_nearest(struct gl_context *ctx,
                                  const struct gl_texture_object *tObj,
                                  GLuint n, const GLfloat texcoord[][4],
                                  const GLfloat lambda[], GLfloat rgba[][4] )
@@ -1675,7 +1680,7 @@ sample_3d_nearest_mipmap_nearest(GLcontext *ctx,
 
 
 static void
-sample_3d_linear_mipmap_nearest(GLcontext *ctx,
+sample_3d_linear_mipmap_nearest(struct gl_context *ctx,
                                 const struct gl_texture_object *tObj,
                                 GLuint n, const GLfloat texcoord[][4],
                                 const GLfloat lambda[], GLfloat rgba[][4])
@@ -1690,7 +1695,7 @@ sample_3d_linear_mipmap_nearest(GLcontext *ctx,
 
 
 static void
-sample_3d_nearest_mipmap_linear(GLcontext *ctx,
+sample_3d_nearest_mipmap_linear(struct gl_context *ctx,
                                 const struct gl_texture_object *tObj,
                                 GLuint n, const GLfloat texcoord[][4],
                                 const GLfloat lambda[], GLfloat rgba[][4])
@@ -1715,7 +1720,7 @@ sample_3d_nearest_mipmap_linear(GLcontext *ctx,
 
 
 static void
-sample_3d_linear_mipmap_linear(GLcontext *ctx,
+sample_3d_linear_mipmap_linear(struct gl_context *ctx,
                                const struct gl_texture_object *tObj,
                                GLuint n, const GLfloat texcoord[][4],
                                const GLfloat lambda[], GLfloat rgba[][4])
@@ -1741,7 +1746,7 @@ sample_3d_linear_mipmap_linear(GLcontext *ctx,
 
 /** Sample 3D texture, nearest filtering for both min/magnification */
 static void
-sample_nearest_3d(GLcontext *ctx,
+sample_nearest_3d(struct gl_context *ctx,
                   const struct gl_texture_object *tObj, GLuint n,
                   const GLfloat texcoords[][4], const GLfloat lambda[],
                   GLfloat rgba[][4])
@@ -1757,7 +1762,7 @@ sample_nearest_3d(GLcontext *ctx,
 
 /** Sample 3D texture, linear filtering for both min/magnification */
 static void
-sample_linear_3d(GLcontext *ctx,
+sample_linear_3d(struct gl_context *ctx,
                  const struct gl_texture_object *tObj, GLuint n,
                  const GLfloat texcoords[][4],
                 const GLfloat lambda[], GLfloat rgba[][4])
@@ -1773,7 +1778,7 @@ sample_linear_3d(GLcontext *ctx,
 
 /** Sample 3D texture, using lambda to choose between min/magnification */
 static void
-sample_lambda_3d(GLcontext *ctx,
+sample_lambda_3d(struct gl_context *ctx,
                  const struct gl_texture_object *tObj, GLuint n,
                  const GLfloat texcoords[][4], const GLfloat lambda[],
                  GLfloat rgba[][4])
@@ -1928,7 +1933,7 @@ choose_cube_face(const struct gl_texture_object *texObj,
 
 
 static void
-sample_nearest_cube(GLcontext *ctx,
+sample_nearest_cube(struct gl_context *ctx,
                    const struct gl_texture_object *tObj, GLuint n,
                     const GLfloat texcoords[][4], const GLfloat lambda[],
                     GLfloat rgba[][4])
@@ -1946,7 +1951,7 @@ sample_nearest_cube(GLcontext *ctx,
 
 
 static void
-sample_linear_cube(GLcontext *ctx,
+sample_linear_cube(struct gl_context *ctx,
                   const struct gl_texture_object *tObj, GLuint n,
                    const GLfloat texcoords[][4],
                   const GLfloat lambda[], GLfloat rgba[][4])
@@ -1964,7 +1969,7 @@ sample_linear_cube(GLcontext *ctx,
 
 
 static void
-sample_cube_nearest_mipmap_nearest(GLcontext *ctx,
+sample_cube_nearest_mipmap_nearest(struct gl_context *ctx,
                                    const struct gl_texture_object *tObj,
                                    GLuint n, const GLfloat texcoord[][4],
                                    const GLfloat lambda[], GLfloat rgba[][4])
@@ -1993,7 +1998,7 @@ sample_cube_nearest_mipmap_nearest(GLcontext *ctx,
 
 
 static void
-sample_cube_linear_mipmap_nearest(GLcontext *ctx,
+sample_cube_linear_mipmap_nearest(struct gl_context *ctx,
                                   const struct gl_texture_object *tObj,
                                   GLuint n, const GLfloat texcoord[][4],
                                   const GLfloat lambda[], GLfloat rgba[][4])
@@ -2012,7 +2017,7 @@ sample_cube_linear_mipmap_nearest(GLcontext *ctx,
 
 
 static void
-sample_cube_nearest_mipmap_linear(GLcontext *ctx,
+sample_cube_nearest_mipmap_linear(struct gl_context *ctx,
                                   const struct gl_texture_object *tObj,
                                   GLuint n, const GLfloat texcoord[][4],
                                   const GLfloat lambda[], GLfloat rgba[][4])
@@ -2041,7 +2046,7 @@ sample_cube_nearest_mipmap_linear(GLcontext *ctx,
 
 
 static void
-sample_cube_linear_mipmap_linear(GLcontext *ctx,
+sample_cube_linear_mipmap_linear(struct gl_context *ctx,
                                  const struct gl_texture_object *tObj,
                                  GLuint n, const GLfloat texcoord[][4],
                                  const GLfloat lambda[], GLfloat rgba[][4])
@@ -2071,7 +2076,7 @@ sample_cube_linear_mipmap_linear(GLcontext *ctx,
 
 /** Sample cube texture, using lambda to choose between min/magnification */
 static void
-sample_lambda_cube(GLcontext *ctx,
+sample_lambda_cube(struct gl_context *ctx,
                   const struct gl_texture_object *tObj, GLuint n,
                   const GLfloat texcoords[][4], const GLfloat lambda[],
                   GLfloat rgba[][4])
@@ -2145,7 +2150,7 @@ sample_lambda_cube(GLcontext *ctx,
 
 
 static void
-sample_nearest_rect(GLcontext *ctx,
+sample_nearest_rect(struct gl_context *ctx,
                    const struct gl_texture_object *tObj, GLuint n,
                     const GLfloat texcoords[][4], const GLfloat lambda[],
                     GLfloat rgba[][4])
@@ -2179,7 +2184,7 @@ sample_nearest_rect(GLcontext *ctx,
 
 
 static void
-sample_linear_rect(GLcontext *ctx,
+sample_linear_rect(struct gl_context *ctx,
                   const struct gl_texture_object *tObj, GLuint n,
                    const GLfloat texcoords[][4],
                   const GLfloat lambda[], GLfloat rgba[][4])
@@ -2245,7 +2250,7 @@ sample_linear_rect(GLcontext *ctx,
 
 /** Sample Rect texture, using lambda to choose between min/magnification */
 static void
-sample_lambda_rect(GLcontext *ctx,
+sample_lambda_rect(struct gl_context *ctx,
                   const struct gl_texture_object *tObj, GLuint n,
                   const GLfloat texcoords[][4], const GLfloat lambda[],
                   GLfloat rgba[][4])
@@ -2289,7 +2294,7 @@ sample_lambda_rect(GLcontext *ctx,
  * Return the texture sample for coordinate (s,t,r) using GL_NEAREST filter.
  */
 static void
-sample_2d_array_nearest(GLcontext *ctx,
+sample_2d_array_nearest(struct gl_context *ctx,
                         const struct gl_texture_object *tObj,
                         const struct gl_texture_image *img,
                         const GLfloat texcoord[4],
@@ -2322,7 +2327,7 @@ sample_2d_array_nearest(GLcontext *ctx,
  * Return the texture sample for coordinate (s,t,r) using GL_LINEAR filter.
  */
 static void
-sample_2d_array_linear(GLcontext *ctx,
+sample_2d_array_linear(struct gl_context *ctx,
                        const struct gl_texture_object *tObj,
                        const struct gl_texture_image *img,
                        const GLfloat texcoord[4],
@@ -2392,7 +2397,7 @@ sample_2d_array_linear(GLcontext *ctx,
 
 
 static void
-sample_2d_array_nearest_mipmap_nearest(GLcontext *ctx,
+sample_2d_array_nearest_mipmap_nearest(struct gl_context *ctx,
                                        const struct gl_texture_object *tObj,
                                        GLuint n, const GLfloat texcoord[][4],
                                        const GLfloat lambda[], GLfloat rgba[][4])
@@ -2407,7 +2412,7 @@ sample_2d_array_nearest_mipmap_nearest(GLcontext *ctx,
 
 
 static void
-sample_2d_array_linear_mipmap_nearest(GLcontext *ctx,
+sample_2d_array_linear_mipmap_nearest(struct gl_context *ctx,
                                       const struct gl_texture_object *tObj,
                                       GLuint n, const GLfloat texcoord[][4],
                                       const GLfloat lambda[], GLfloat rgba[][4])
@@ -2423,7 +2428,7 @@ sample_2d_array_linear_mipmap_nearest(GLcontext *ctx,
 
 
 static void
-sample_2d_array_nearest_mipmap_linear(GLcontext *ctx,
+sample_2d_array_nearest_mipmap_linear(struct gl_context *ctx,
                                       const struct gl_texture_object *tObj,
                                       GLuint n, const GLfloat texcoord[][4],
                                       const GLfloat lambda[], GLfloat rgba[][4])
@@ -2450,7 +2455,7 @@ sample_2d_array_nearest_mipmap_linear(GLcontext *ctx,
 
 
 static void
-sample_2d_array_linear_mipmap_linear(GLcontext *ctx,
+sample_2d_array_linear_mipmap_linear(struct gl_context *ctx,
                                      const struct gl_texture_object *tObj,
                                      GLuint n, const GLfloat texcoord[][4],
                                      const GLfloat lambda[], GLfloat rgba[][4])
@@ -2478,7 +2483,7 @@ sample_2d_array_linear_mipmap_linear(GLcontext *ctx,
 
 /** Sample 2D Array texture, nearest filtering for both min/magnification */
 static void
-sample_nearest_2d_array(GLcontext *ctx,
+sample_nearest_2d_array(struct gl_context *ctx,
                         const struct gl_texture_object *tObj, GLuint n,
                         const GLfloat texcoords[][4], const GLfloat lambda[],
                         GLfloat rgba[][4])
@@ -2495,7 +2500,7 @@ sample_nearest_2d_array(GLcontext *ctx,
 
 /** Sample 2D Array texture, linear filtering for both min/magnification */
 static void
-sample_linear_2d_array(GLcontext *ctx,
+sample_linear_2d_array(struct gl_context *ctx,
                        const struct gl_texture_object *tObj, GLuint n,
                        const GLfloat texcoords[][4],
                        const GLfloat lambda[], GLfloat rgba[][4])
@@ -2511,7 +2516,7 @@ sample_linear_2d_array(GLcontext *ctx,
 
 /** Sample 2D Array texture, using lambda to choose between min/magnification */
 static void
-sample_lambda_2d_array(GLcontext *ctx,
+sample_lambda_2d_array(struct gl_context *ctx,
                        const struct gl_texture_object *tObj, GLuint n,
                        const GLfloat texcoords[][4], const GLfloat lambda[],
                        GLfloat rgba[][4])
@@ -2599,7 +2604,7 @@ sample_lambda_2d_array(GLcontext *ctx,
  * Return the texture sample for coordinate (s,t,r) using GL_NEAREST filter.
  */
 static void
-sample_1d_array_nearest(GLcontext *ctx,
+sample_1d_array_nearest(struct gl_context *ctx,
                         const struct gl_texture_object *tObj,
                         const struct gl_texture_image *img,
                         const GLfloat texcoord[4],
@@ -2629,7 +2634,7 @@ sample_1d_array_nearest(GLcontext *ctx,
  * Return the texture sample for coordinate (s,t,r) using GL_LINEAR filter.
  */
 static void
-sample_1d_array_linear(GLcontext *ctx,
+sample_1d_array_linear(struct gl_context *ctx,
                        const struct gl_texture_object *tObj,
                        const struct gl_texture_image *img,
                        const GLfloat texcoord[4],
@@ -2678,7 +2683,7 @@ sample_1d_array_linear(GLcontext *ctx,
 
 
 static void
-sample_1d_array_nearest_mipmap_nearest(GLcontext *ctx,
+sample_1d_array_nearest_mipmap_nearest(struct gl_context *ctx,
                                        const struct gl_texture_object *tObj,
                                        GLuint n, const GLfloat texcoord[][4],
                                        const GLfloat lambda[], GLfloat rgba[][4])
@@ -2693,7 +2698,7 @@ sample_1d_array_nearest_mipmap_nearest(GLcontext *ctx,
 
 
 static void
-sample_1d_array_linear_mipmap_nearest(GLcontext *ctx,
+sample_1d_array_linear_mipmap_nearest(struct gl_context *ctx,
                                       const struct gl_texture_object *tObj,
                                       GLuint n, const GLfloat texcoord[][4],
                                       const GLfloat lambda[], GLfloat rgba[][4])
@@ -2709,7 +2714,7 @@ sample_1d_array_linear_mipmap_nearest(GLcontext *ctx,
 
 
 static void
-sample_1d_array_nearest_mipmap_linear(GLcontext *ctx,
+sample_1d_array_nearest_mipmap_linear(struct gl_context *ctx,
                                       const struct gl_texture_object *tObj,
                                       GLuint n, const GLfloat texcoord[][4],
                                       const GLfloat lambda[], GLfloat rgba[][4])
@@ -2734,7 +2739,7 @@ sample_1d_array_nearest_mipmap_linear(GLcontext *ctx,
 
 
 static void
-sample_1d_array_linear_mipmap_linear(GLcontext *ctx,
+sample_1d_array_linear_mipmap_linear(struct gl_context *ctx,
                                      const struct gl_texture_object *tObj,
                                      GLuint n, const GLfloat texcoord[][4],
                                      const GLfloat lambda[], GLfloat rgba[][4])
@@ -2760,7 +2765,7 @@ sample_1d_array_linear_mipmap_linear(GLcontext *ctx,
 
 /** Sample 1D Array texture, nearest filtering for both min/magnification */
 static void
-sample_nearest_1d_array(GLcontext *ctx,
+sample_nearest_1d_array(struct gl_context *ctx,
                         const struct gl_texture_object *tObj, GLuint n,
                         const GLfloat texcoords[][4], const GLfloat lambda[],
                         GLfloat rgba[][4])
@@ -2776,7 +2781,7 @@ sample_nearest_1d_array(GLcontext *ctx,
 
 /** Sample 1D Array texture, linear filtering for both min/magnification */
 static void
-sample_linear_1d_array(GLcontext *ctx,
+sample_linear_1d_array(struct gl_context *ctx,
                        const struct gl_texture_object *tObj, GLuint n,
                        const GLfloat texcoords[][4],
                        const GLfloat lambda[], GLfloat rgba[][4])
@@ -2792,7 +2797,7 @@ sample_linear_1d_array(GLcontext *ctx,
 
 /** Sample 1D Array texture, using lambda to choose between min/magnification */
 static void
-sample_lambda_1d_array(GLcontext *ctx,
+sample_lambda_1d_array(struct gl_context *ctx,
                        const struct gl_texture_object *tObj, GLuint n,
                        const GLfloat texcoords[][4], const GLfloat lambda[],
                        GLfloat rgba[][4])
@@ -2963,16 +2968,40 @@ shadow_compare4(GLenum function, GLfloat coord,
 
 
 /**
- * Sample a shadow/depth texture.
+ * Choose the mipmap level to use when sampling from a depth texture.
+ */
+static int
+choose_depth_texture_level(const struct gl_texture_object *tObj, GLfloat lambda)
+{
+   GLint level;
+
+   if (tObj->MinFilter == GL_NEAREST || tObj->MinFilter == GL_LINEAR) {
+      /* no mipmapping - use base level */
+      level = tObj->BaseLevel;
+   }
+   else {
+      /* choose mipmap level */
+      lambda = CLAMP(lambda, tObj->MinLod, tObj->MaxLod);
+      level = (GLint) lambda;
+      level = CLAMP(level, tObj->BaseLevel, tObj->_MaxLevel);
+   }
+
+   return level;
+}
+
+
+/**
+ * Sample a shadow/depth texture.  This function is incomplete.  It doesn't
+ * check for minification vs. magnification, etc.
  */
 static void
-sample_depth_texture( GLcontext *ctx,
+sample_depth_texture( struct gl_context *ctx,
                       const struct gl_texture_object *tObj, GLuint n,
                       const GLfloat texcoords[][4], const GLfloat lambda[],
                       GLfloat texel[][4] )
 {
-   const GLint baseLevel = tObj->BaseLevel;
-   const struct gl_texture_image *img = tObj->Image[0][baseLevel];
+   const GLint level = choose_depth_texture_level(tObj, lambda[0]);
+   const struct gl_texture_image *img = tObj->Image[0][level];
    const GLint width = img->Width;
    const GLint height = img->Height;
    const GLint depth = img->Depth;
@@ -2982,8 +3011,6 @@ sample_depth_texture( GLcontext *ctx,
    GLenum function;
    GLfloat result;
 
-   (void) lambda;
-
    ASSERT(img->_BaseFormat == GL_DEPTH_COMPONENT ||
           img->_BaseFormat == GL_DEPTH_STENCIL_EXT);
 
@@ -3006,7 +3033,7 @@ sample_depth_texture( GLcontext *ctx,
          GLfloat depthSample;
          GLint col, row, slice;
 
-         nearest_texcoord(tObj, texcoords[i], &col, &row, &slice);
+         nearest_texcoord(tObj, level, texcoords[i], &col, &row, &slice);
 
          if (col >= 0 && row >= 0 && col < width && row < height && 
              slice >= 0 && slice < depth) {
@@ -3029,6 +3056,9 @@ sample_depth_texture( GLcontext *ctx,
          case GL_ALPHA:
             ASSIGN_4V(texel[i], 0.0F, 0.0F, 0.0F, result);
             break;
+         case GL_RED:
+            ASSIGN_4V(texel[i], result, 0.0F, 0.0F, 1.0F);
+            break;
          default:
             _mesa_problem(ctx, "Bad depth texture mode");
          }
@@ -3044,7 +3074,7 @@ sample_depth_texture( GLcontext *ctx,
          GLfloat wi, wj;
          GLuint useBorderTexel;
 
-         linear_texcoord(tObj, texcoords[i], &i0, &i1, &j0, &j1, &slice,
+         linear_texcoord(tObj, level, texcoords[i], &i0, &i1, &j0, &j1, &slice,
                          &wi, &wj);
 
          useBorderTexel = 0;
@@ -3134,7 +3164,7 @@ sample_depth_texture( GLcontext *ctx,
  * Note: fragment programs don't observe the texture enable/disable flags.
  */
 static void
-null_sample_func( GLcontext *ctx,
+null_sample_func( struct gl_context *ctx,
                  const struct gl_texture_object *tObj, GLuint n,
                  const GLfloat texcoords[][4], const GLfloat lambda[],
                  GLfloat rgba[][4])
@@ -3157,7 +3187,7 @@ null_sample_func( GLcontext *ctx,
  * Choose the texture sampling function for the given texture object.
  */
 texture_sample_func
-_swrast_choose_texture_sample_func( GLcontext *ctx,
+_swrast_choose_texture_sample_func( struct gl_context *ctx,
                                    const struct gl_texture_object *t )
 {
    if (!t || !t->_Complete) {