/**
- * 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))
/**
* 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;
/**
* 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;
* 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])
* 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])
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])
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])
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])
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])
/** 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] )
/** 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] )
/** 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] )
* 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],
* 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],
* 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],
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])
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])
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])
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] )
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])
/** 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])
/** 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])
* 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])
* 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])
/** 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])
* 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],
* 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],
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] )
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])
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])
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])
/** 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])
/** 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])
/** 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])
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])
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])
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])
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])
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])
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])
/** 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])
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])
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])
/** 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])
* 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],
* 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],
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])
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])
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])
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])
/** 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])
/** 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])
/** 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])
* 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],
* 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],
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])
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])
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])
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])
/** 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])
/** 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])
/** 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])
/**
- * 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;
GLenum function;
GLfloat result;
- (void) lambda;
-
ASSERT(img->_BaseFormat == GL_DEPTH_COMPONENT ||
img->_BaseFormat == GL_DEPTH_STENCIL_EXT);
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) {
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");
}
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;
* 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])
* 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) {