diff options
Diffstat (limited to 'src/mesa/swrast')
-rw-r--r-- | src/mesa/swrast/s_texfilter.c | 1018 |
1 files changed, 477 insertions, 541 deletions
diff --git a/src/mesa/swrast/s_texfilter.c b/src/mesa/swrast/s_texfilter.c index 9e44fba3da..6b1dfd5d50 100644 --- a/src/mesa/swrast/s_texfilter.c +++ b/src/mesa/swrast/s_texfilter.c @@ -1,8 +1,8 @@ /* * Mesa 3-D graphics library - * Version: 7.0.3 + * Version: 7.3 * - * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. + * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -33,6 +33,16 @@ #include "s_texfilter.h" +/* + * Note, the FRAC macro has to work perfectly. Otherwise 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) - IFLOOR(f)) + + /** * Constants for integer linear interpolation. */ @@ -223,257 +233,271 @@ lerp_rgba_3d(GLchan result[4], GLfloat a, GLfloat b, GLfloat c, * Used to compute texel locations for linear sampling. * Input: * wrapMode = GL_REPEAT, GL_CLAMP, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_BORDER - * S = texcoord in [0,1] - * SIZE = width (or height or depth) of texture + * s = texcoord in [0,1] + * size = width (or height or depth) of texture * Output: - * U = texcoord in [0, width] - * I0, I1 = two nearest texel indexes + * i0, i1 = returns two nearest texel indexes + * weight = returns blend factor between texels */ -#define COMPUTE_LINEAR_TEXEL_LOCATIONS(wrapMode, S, U, SIZE, I0, I1) \ -{ \ - switch (wrapMode) { \ - case GL_REPEAT: \ - U = S * SIZE - 0.5F; \ - if (img->_IsPowerOfTwo) { \ - I0 = IFLOOR(U) & (SIZE - 1); \ - I1 = (I0 + 1) & (SIZE - 1); \ - } \ - else { \ - I0 = REMAINDER(IFLOOR(U), SIZE); \ - I1 = REMAINDER(I0 + 1, SIZE); \ - } \ - break; \ - case GL_CLAMP_TO_EDGE: \ - if (S <= 0.0F) \ - U = 0.0F; \ - else if (S >= 1.0F) \ - U = (GLfloat) SIZE; \ - else \ - U = S * SIZE; \ - U -= 0.5F; \ - I0 = IFLOOR(U); \ - I1 = I0 + 1; \ - if (I0 < 0) \ - I0 = 0; \ - if (I1 >= (GLint) SIZE) \ - I1 = SIZE - 1; \ - break; \ - case GL_CLAMP_TO_BORDER: \ - { \ - const GLfloat min = -1.0F / (2.0F * SIZE); \ - const GLfloat max = 1.0F - min; \ - if (S <= min) \ - U = min * SIZE; \ - else if (S >= max) \ - U = max * SIZE; \ - else \ - U = S * SIZE; \ - U -= 0.5F; \ - I0 = IFLOOR(U); \ - I1 = I0 + 1; \ - } \ - break; \ - case GL_MIRRORED_REPEAT: \ - { \ - const GLint flr = IFLOOR(S); \ - if (flr & 1) \ - U = 1.0F - (S - (GLfloat) flr); /* flr is odd */ \ - else \ - U = S - (GLfloat) flr; /* flr is even */ \ - U = (U * SIZE) - 0.5F; \ - I0 = IFLOOR(U); \ - I1 = I0 + 1; \ - if (I0 < 0) \ - I0 = 0; \ - if (I1 >= (GLint) SIZE) \ - I1 = SIZE - 1; \ - } \ - break; \ - case GL_MIRROR_CLAMP_EXT: \ - U = FABSF(S); \ - if (U >= 1.0F) \ - U = (GLfloat) SIZE; \ - else \ - U *= SIZE; \ - U -= 0.5F; \ - I0 = IFLOOR(U); \ - I1 = I0 + 1; \ - break; \ - case GL_MIRROR_CLAMP_TO_EDGE_EXT: \ - U = FABSF(S); \ - if (U >= 1.0F) \ - U = (GLfloat) SIZE; \ - else \ - U *= SIZE; \ - U -= 0.5F; \ - I0 = IFLOOR(U); \ - I1 = I0 + 1; \ - if (I0 < 0) \ - I0 = 0; \ - if (I1 >= (GLint) SIZE) \ - I1 = SIZE - 1; \ - break; \ - case GL_MIRROR_CLAMP_TO_BORDER_EXT: \ - { \ - const GLfloat min = -1.0F / (2.0F * SIZE); \ - const GLfloat max = 1.0F - min; \ - U = FABSF(S); \ - if (U <= min) \ - U = min * SIZE; \ - else if (U >= max) \ - U = max * SIZE; \ - else \ - U *= SIZE; \ - U -= 0.5F; \ - I0 = IFLOOR(U); \ - I1 = I0 + 1; \ - } \ - break; \ - case GL_CLAMP: \ - if (S <= 0.0F) \ - U = 0.0F; \ - else if (S >= 1.0F) \ - U = (GLfloat) SIZE; \ - else \ - U = S * SIZE; \ - U -= 0.5F; \ - I0 = IFLOOR(U); \ - I1 = I0 + 1; \ - break; \ - default: \ - _mesa_problem(ctx, "Bad wrap mode"); \ - return; \ - } \ +static INLINE void +linear_texel_locations(GLenum wrapMode, + const struct gl_texture_image *img, + GLint size, GLfloat s, + GLint *i0, GLint *i1, GLfloat *weight) +{ + GLfloat u; + switch (wrapMode) { + case GL_REPEAT: + u = s * size - 0.5F; + if (img->_IsPowerOfTwo) { + *i0 = IFLOOR(u) & (size - 1); + *i1 = (*i0 + 1) & (size - 1); + } + else { + *i0 = REMAINDER(IFLOOR(u), size); + *i1 = REMAINDER(*i0 + 1, size); + } + break; + case GL_CLAMP_TO_EDGE: + if (s <= 0.0F) + u = 0.0F; + else if (s >= 1.0F) + u = (GLfloat) size; + else + u = s * size; + u -= 0.5F; + *i0 = IFLOOR(u); + *i1 = *i0 + 1; + if (*i0 < 0) + *i0 = 0; + if (*i1 >= (GLint) size) + *i1 = size - 1; + break; + case GL_CLAMP_TO_BORDER: + { + const GLfloat min = -1.0F / (2.0F * size); + const GLfloat max = 1.0F - min; + if (s <= min) + u = min * size; + else if (s >= max) + u = max * size; + else + u = s * size; + u -= 0.5F; + *i0 = IFLOOR(u); + *i1 = *i0 + 1; + } + break; + case GL_MIRRORED_REPEAT: + { + const GLint flr = IFLOOR(s); + if (flr & 1) + u = 1.0F - (s - (GLfloat) flr); + else + u = s - (GLfloat) flr; + u = (u * size) - 0.5F; + *i0 = IFLOOR(u); + *i1 = *i0 + 1; + if (*i0 < 0) + *i0 = 0; + if (*i1 >= (GLint) size) + *i1 = size - 1; + } + break; + case GL_MIRROR_CLAMP_EXT: + u = FABSF(s); + if (u >= 1.0F) + u = (GLfloat) size; + else + u *= size; + u -= 0.5F; + *i0 = IFLOOR(u); + *i1 = *i0 + 1; + break; + case GL_MIRROR_CLAMP_TO_EDGE_EXT: + u = FABSF(s); + if (u >= 1.0F) + u = (GLfloat) size; + else + u *= size; + u -= 0.5F; + *i0 = IFLOOR(u); + *i1 = *i0 + 1; + if (*i0 < 0) + *i0 = 0; + if (*i1 >= (GLint) size) + *i1 = size - 1; + break; + case GL_MIRROR_CLAMP_TO_BORDER_EXT: + { + const GLfloat min = -1.0F / (2.0F * size); + const GLfloat max = 1.0F - min; + u = FABSF(s); + if (u <= min) + u = min * size; + else if (u >= max) + u = max * size; + else + u *= size; + u -= 0.5F; + *i0 = IFLOOR(u); + *i1 = *i0 + 1; + } + break; + case GL_CLAMP: + if (s <= 0.0F) + u = 0.0F; + else if (s >= 1.0F) + u = (GLfloat) size; + else + u = s * size; + u -= 0.5F; + *i0 = IFLOOR(u); + *i1 = *i0 + 1; + break; + default: + _mesa_problem(NULL, "Bad wrap mode"); + u = 0.0F; + } + *weight = FRAC(u); } /** * Used to compute texel location for nearest sampling. */ -#define COMPUTE_NEAREST_TEXEL_LOCATION(wrapMode, S, SIZE, I) \ -{ \ - switch (wrapMode) { \ - case GL_REPEAT: \ - /* s limited to [0,1) */ \ - /* i limited to [0,size-1] */ \ - I = IFLOOR(S * SIZE); \ - if (img->_IsPowerOfTwo) \ - I &= (SIZE - 1); \ - else \ - I = REMAINDER(I, SIZE); \ - break; \ - case GL_CLAMP_TO_EDGE: \ - { \ - /* s limited to [min,max] */ \ - /* i limited to [0, size-1] */ \ - const GLfloat min = 1.0F / (2.0F * SIZE); \ - const GLfloat max = 1.0F - min; \ - if (S < min) \ - I = 0; \ - else if (S > max) \ - I = SIZE - 1; \ - else \ - I = IFLOOR(S * SIZE); \ - } \ - break; \ - case GL_CLAMP_TO_BORDER: \ - { \ - /* s limited to [min,max] */ \ - /* i limited to [-1, size] */ \ - const GLfloat min = -1.0F / (2.0F * SIZE); \ - const GLfloat max = 1.0F - min; \ - if (S <= min) \ - I = -1; \ - else if (S >= max) \ - I = SIZE; \ - else \ - I = IFLOOR(S * SIZE); \ - } \ - break; \ - case GL_MIRRORED_REPEAT: \ - { \ - const GLfloat min = 1.0F / (2.0F * SIZE); \ - const GLfloat max = 1.0F - min; \ - const GLint flr = IFLOOR(S); \ - GLfloat u; \ - if (flr & 1) \ - u = 1.0F - (S - (GLfloat) flr); /* flr is odd */ \ - else \ - u = S - (GLfloat) flr; /* flr is even */ \ - if (u < min) \ - I = 0; \ - else if (u > max) \ - I = SIZE - 1; \ - else \ - I = IFLOOR(u * SIZE); \ - } \ - break; \ - case GL_MIRROR_CLAMP_EXT: \ - { \ - /* s limited to [0,1] */ \ - /* i limited to [0,size-1] */ \ - const GLfloat u = FABSF(S); \ - if (u <= 0.0F) \ - I = 0; \ - else if (u >= 1.0F) \ - I = SIZE - 1; \ - else \ - I = IFLOOR(u * SIZE); \ - } \ - break; \ - case GL_MIRROR_CLAMP_TO_EDGE_EXT: \ - { \ - /* s limited to [min,max] */ \ - /* i limited to [0, size-1] */ \ - const GLfloat min = 1.0F / (2.0F * SIZE); \ - const GLfloat max = 1.0F - min; \ - const GLfloat u = FABSF(S); \ - if (u < min) \ - I = 0; \ - else if (u > max) \ - I = SIZE - 1; \ - else \ - I = IFLOOR(u * SIZE); \ - } \ - break; \ - case GL_MIRROR_CLAMP_TO_BORDER_EXT: \ - { \ - /* s limited to [min,max] */ \ - /* i limited to [0, size-1] */ \ - const GLfloat min = -1.0F / (2.0F * SIZE); \ - const GLfloat max = 1.0F - min; \ - const GLfloat u = FABSF(S); \ - if (u < min) \ - I = -1; \ - else if (u > max) \ - I = SIZE; \ - else \ - I = IFLOOR(u * SIZE); \ - } \ - break; \ - case GL_CLAMP: \ - /* s limited to [0,1] */ \ - /* i limited to [0,size-1] */ \ - if (S <= 0.0F) \ - I = 0; \ - else if (S >= 1.0F) \ - I = SIZE - 1; \ - else \ - I = IFLOOR(S * SIZE); \ - break; \ - default: \ - _mesa_problem(ctx, "Bad wrap mode"); \ - return; \ - } \ +static INLINE GLint +nearest_texel_location(GLenum wrapMode, + const struct gl_texture_image *img, + GLint size, GLfloat s) +{ + GLint i; + + switch (wrapMode) { + case GL_REPEAT: + /* s limited to [0,1) */ + /* i limited to [0,size-1] */ + i = IFLOOR(s * size); + if (img->_IsPowerOfTwo) + i &= (size - 1); + else + i = REMAINDER(i, size); + return i; + case GL_CLAMP_TO_EDGE: + { + /* s limited to [min,max] */ + /* i limited to [0, size-1] */ + const GLfloat min = 1.0F / (2.0F * size); + const GLfloat max = 1.0F - min; + if (s < min) + i = 0; + else if (s > max) + i = size - 1; + else + i = IFLOOR(s * size); + } + return i; + case GL_CLAMP_TO_BORDER: + { + /* s limited to [min,max] */ + /* i limited to [-1, size] */ + const GLfloat min = -1.0F / (2.0F * size); + const GLfloat max = 1.0F - min; + if (s <= min) + i = -1; + else if (s >= max) + i = size; + else + i = IFLOOR(s * size); + } + return i; + case GL_MIRRORED_REPEAT: + { + const GLfloat min = 1.0F / (2.0F * size); + const GLfloat max = 1.0F - min; + const GLint flr = IFLOOR(s); + GLfloat u; + if (flr & 1) + u = 1.0F - (s - (GLfloat) flr); + else + u = s - (GLfloat) flr; + if (u < min) + i = 0; + else if (u > max) + i = size - 1; + else + i = IFLOOR(u * size); + } + return i; + case GL_MIRROR_CLAMP_EXT: + { + /* s limited to [0,1] */ + /* i limited to [0,size-1] */ + const GLfloat u = FABSF(s); + if (u <= 0.0F) + i = 0; + else if (u >= 1.0F) + i = size - 1; + else + i = IFLOOR(u * size); + } + return i; + case GL_MIRROR_CLAMP_TO_EDGE_EXT: + { + /* s limited to [min,max] */ + /* i limited to [0, size-1] */ + const GLfloat min = 1.0F / (2.0F * size); + const GLfloat max = 1.0F - min; + const GLfloat u = FABSF(s); + if (u < min) + i = 0; + else if (u > max) + i = size - 1; + else + i = IFLOOR(u * size); + } + return i; + case GL_MIRROR_CLAMP_TO_BORDER_EXT: + { + /* s limited to [min,max] */ + /* i limited to [0, size-1] */ + const GLfloat min = -1.0F / (2.0F * size); + const GLfloat max = 1.0F - min; + const GLfloat u = FABSF(s); + if (u < min) + i = -1; + else if (u > max) + i = size; + else + i = IFLOOR(u * size); + } + return i; + case GL_CLAMP: + /* s limited to [0,1] */ + /* i limited to [0,size-1] */ + if (s <= 0.0F) + i = 0; + else if (s >= 1.0F) + i = size - 1; + else + i = IFLOOR(s * size); + return i; + default: + _mesa_problem(NULL, "Bad wrap mode"); + return 0; + } } /* Power of two image sizes only */ -#define COMPUTE_LINEAR_REPEAT_TEXEL_LOCATION(S, U, SIZE, I0, I1) \ -{ \ - U = S * SIZE - 0.5F; \ - I0 = IFLOOR(U) & (SIZE - 1); \ - I1 = (I0 + 1) & (SIZE - 1); \ +static INLINE void +linear_repeat_texel_location(GLuint size, GLfloat s, + GLint *i0, GLint *i1, GLfloat *weight) +{ + GLfloat u = s * size - 0.5F; + *i0 = IFLOOR(u) & (size - 1); + *i1 = (*i0 + 1) & (size - 1); + *weight = FRAC(u); } @@ -516,17 +540,6 @@ nearest_mipmap_level(const struct gl_texture_object *tObj, GLfloat lambda) /* - * Note, the FRAC macro has to work perfectly. Otherwise 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) - IFLOOR(f)) - - - -/* * Bitflags for texture border color sampling. */ #define I0BIT 1 @@ -538,7 +551,7 @@ nearest_mipmap_level(const struct gl_texture_object *tObj, GLfloat lambda) -/* +/** * The lambda[] array values are always monotonic. Either the whole span * will be minified, magnified, or split between the two. This function * determines the subranges in [0, n-1] that are to be minified or magnified. @@ -651,10 +664,10 @@ compute_min_mag_ranges(const struct gl_texture_object *tObj, /* 1-D Texture Sampling Functions */ /**********************************************************************/ -/* +/** * Return the texture sample for coordinate (s) using GL_NEAREST filter. */ -static void +static INLINE void sample_1d_nearest(GLcontext *ctx, const struct gl_texture_object *tObj, const struct gl_texture_image *img, @@ -662,7 +675,7 @@ sample_1d_nearest(GLcontext *ctx, { const GLint width = img->Width2; /* without border, power of two */ GLint i; - COMPUTE_NEAREST_TEXEL_LOCATION(tObj->WrapS, texcoord[0], width, i); + i = nearest_texel_location(tObj->WrapS, img, width, texcoord[0]); /* skip over the border, if any */ i += img->Border; if (i < 0 || i >= (GLint) img->Width) { @@ -675,10 +688,10 @@ sample_1d_nearest(GLcontext *ctx, } -/* +/** * Return the texture sample for coordinate (s) using GL_LINEAR filter. */ -static void +static INLINE void sample_1d_linear(GLcontext *ctx, const struct gl_texture_object *tObj, const struct gl_texture_image *img, @@ -686,12 +699,11 @@ sample_1d_linear(GLcontext *ctx, { const GLint width = img->Width2; GLint i0, i1; - GLfloat u; GLbitfield useBorderColor = 0x0; GLfloat a; GLchan t0[4], t1[4]; /* texels */ - COMPUTE_LINEAR_TEXEL_LOCATIONS(tObj->WrapS, texcoord[0], u, width, i0, i1); + linear_texel_locations(tObj->WrapS, img, width, texcoord[0], &i0, &i1, &a); if (img->Border) { i0 += img->Border; @@ -716,7 +728,6 @@ sample_1d_linear(GLcontext *ctx, img->FetchTexelc(img, i1, 0, 0, t1); } - a = FRAC(u); lerp_rgba(rgba, a, t0, t1); } @@ -776,7 +787,6 @@ sample_1d_nearest_mipmap_linear(GLcontext *ctx, } - static void sample_1d_linear_mipmap_linear(GLcontext *ctx, const struct gl_texture_object *tObj, @@ -802,7 +812,7 @@ sample_1d_linear_mipmap_linear(GLcontext *ctx, } - +/** Sample 1D texture, nearest filtering for both min/magnification */ static void sample_nearest_1d( GLcontext *ctx, const struct gl_texture_object *tObj, GLuint n, @@ -812,13 +822,13 @@ sample_nearest_1d( GLcontext *ctx, GLuint i; struct gl_texture_image *image = tObj->Image[0][tObj->BaseLevel]; (void) lambda; - for (i=0;i<n;i++) { + for (i = 0; i < n; i++) { sample_1d_nearest(ctx, tObj, image, texcoords[i], rgba[i]); } } - +/** Sample 1D texture, linear filtering for both min/magnification */ static void sample_linear_1d( GLcontext *ctx, const struct gl_texture_object *tObj, GLuint n, @@ -828,17 +838,13 @@ sample_linear_1d( GLcontext *ctx, GLuint i; struct gl_texture_image *image = tObj->Image[0][tObj->BaseLevel]; (void) lambda; - for (i=0;i<n;i++) { + for (i = 0; i < n; i++) { sample_1d_linear(ctx, tObj, image, texcoords[i], rgba[i]); } } -/* - * Given an (s) texture coordinate and lambda (level of detail) value, - * return a texture sample. - * - */ +/** Sample 1D texture, using lambda to choose between min/magnification */ static void sample_lambda_1d( GLcontext *ctx, const struct gl_texture_object *tObj, GLuint n, @@ -915,7 +921,7 @@ sample_lambda_1d( GLcontext *ctx, /**********************************************************************/ -/* +/** * Return the texture sample for coordinate (s,t) using GL_NEAREST filter. */ static INLINE void @@ -930,8 +936,8 @@ sample_2d_nearest(GLcontext *ctx, GLint i, j; (void) ctx; - COMPUTE_NEAREST_TEXEL_LOCATION(tObj->WrapS, texcoord[0], width, i); - COMPUTE_NEAREST_TEXEL_LOCATION(tObj->WrapT, texcoord[1], height, j); + i = nearest_texel_location(tObj->WrapS, img, width, texcoord[0]); + j = nearest_texel_location(tObj->WrapT, img, height, texcoord[1]); /* skip over the border, if any */ i += img->Border; @@ -947,7 +953,6 @@ sample_2d_nearest(GLcontext *ctx, } - /** * Return the texture sample for coordinate (s,t) using GL_LINEAR filter. * New sampling code contributed by Lynn Quam <quam@ai.sri.com>. @@ -963,12 +968,11 @@ sample_2d_linear(GLcontext *ctx, const GLint height = img->Height2; GLint i0, j0, i1, j1; GLbitfield useBorderColor = 0x0; - GLfloat u, v; GLfloat a, b; GLchan t00[4], t10[4], t01[4], t11[4]; /* sampled texel colors */ - COMPUTE_LINEAR_TEXEL_LOCATIONS(tObj->WrapS, texcoord[0], u, width, i0, i1); - COMPUTE_LINEAR_TEXEL_LOCATIONS(tObj->WrapT, texcoord[1], v, height, j0, j1); + linear_texel_locations(tObj->WrapS, img, width, texcoord[0], &i0, &i1, &a); + linear_texel_locations(tObj->WrapT, img, height, texcoord[1], &j0, &j1, &b); if (img->Border) { i0 += img->Border; @@ -1009,13 +1013,11 @@ sample_2d_linear(GLcontext *ctx, img->FetchTexelc(img, i1, j1, 0, t11); } - a = FRAC(u); - b = FRAC(v); lerp_rgba_2d(rgba, a, b, t00, t10, t01, t11); } -/* +/** * As above, but we know WRAP_S == REPEAT and WRAP_T == REPEAT. * We don't have to worry about the texture border. */ @@ -1029,8 +1031,7 @@ sample_2d_linear_repeat(GLcontext *ctx, const GLint width = img->Width2; const GLint height = img->Height2; GLint i0, j0, i1, j1; - GLfloat u, v; - GLfloat a, b; + GLfloat wi, wj; GLchan t00[4], t10[4], t01[4], t11[4]; /* sampled texel colors */ (void) ctx; @@ -1041,21 +1042,18 @@ sample_2d_linear_repeat(GLcontext *ctx, ASSERT(img->TexFormat->BaseFormat != GL_COLOR_INDEX); ASSERT(img->_IsPowerOfTwo); - COMPUTE_LINEAR_REPEAT_TEXEL_LOCATION(texcoord[0], u, width, i0, i1); - COMPUTE_LINEAR_REPEAT_TEXEL_LOCATION(texcoord[1], v, height, j0, j1); + linear_repeat_texel_location(width, texcoord[0], &i0, &i1, &wi); + linear_repeat_texel_location(height, texcoord[1], &j0, &j1, &wj); img->FetchTexelc(img, i0, j0, 0, t00); img->FetchTexelc(img, i1, j0, 0, t10); img->FetchTexelc(img, i0, j1, 0, t01); img->FetchTexelc(img, i1, j1, 0, t11); - a = FRAC(u); - b = FRAC(v); - lerp_rgba_2d(rgba, a, b, t00, t10, t01, t11); + lerp_rgba_2d(rgba, wi, wj, t00, t10, t01, t11); } - static void sample_2d_nearest_mipmap_nearest(GLcontext *ctx, const struct gl_texture_object *tObj, @@ -1070,7 +1068,6 @@ sample_2d_nearest_mipmap_nearest(GLcontext *ctx, } - static void sample_2d_linear_mipmap_nearest(GLcontext *ctx, const struct gl_texture_object *tObj, @@ -1086,7 +1083,6 @@ sample_2d_linear_mipmap_nearest(GLcontext *ctx, } - static void sample_2d_nearest_mipmap_linear(GLcontext *ctx, const struct gl_texture_object *tObj, @@ -1112,8 +1108,6 @@ sample_2d_nearest_mipmap_linear(GLcontext *ctx, } - -/* Trilinear filtering */ static void sample_2d_linear_mipmap_linear( GLcontext *ctx, const struct gl_texture_object *tObj, @@ -1140,10 +1134,10 @@ sample_2d_linear_mipmap_linear( GLcontext *ctx, static void -sample_2d_linear_mipmap_linear_repeat( GLcontext *ctx, - const struct gl_texture_object *tObj, - GLuint n, const GLfloat texcoord[][4], - const GLfloat lambda[], GLchan rgba[][4] ) +sample_2d_linear_mipmap_linear_repeat(GLcontext *ctx, + const struct gl_texture_object *tObj, + GLuint n, const GLfloat texcoord[][4], + const GLfloat lambda[], GLchan rgba[][4]) { GLuint i; ASSERT(lambda != NULL); @@ -1158,35 +1152,38 @@ sample_2d_linear_mipmap_linear_repeat( GLcontext *ctx, else { GLchan t0[4], t1[4]; /* texels */ const GLfloat f = FRAC(lambda[i]); - sample_2d_linear_repeat(ctx, tObj, tObj->Image[0][level ], texcoord[i], t0); - sample_2d_linear_repeat(ctx, tObj, tObj->Image[0][level+1], texcoord[i], t1); + sample_2d_linear_repeat(ctx, tObj, tObj->Image[0][level ], + texcoord[i], t0); + sample_2d_linear_repeat(ctx, tObj, tObj->Image[0][level+1], + texcoord[i], t1); lerp_rgba(rgba[i], f, t0, t1); } } } +/** Sample 2D texture, nearest filtering for both min/magnification */ static void -sample_nearest_2d( GLcontext *ctx, - const struct gl_texture_object *tObj, GLuint n, - const GLfloat texcoords[][4], - const GLfloat lambda[], GLchan rgba[][4] ) +sample_nearest_2d(GLcontext *ctx, + const struct gl_texture_object *tObj, GLuint n, + const GLfloat texcoords[][4], + const GLfloat lambda[], GLchan rgba[][4]) { GLuint i; struct gl_texture_image *image = tObj->Image[0][tObj->BaseLevel]; (void) lambda; - for (i=0;i<n;i++) { + for (i = 0; i < n; i++) { sample_2d_nearest(ctx, tObj, image, texcoords[i], rgba[i]); } } - +/** Sample 2D texture, linear filtering for both min/magnification */ static void -sample_linear_2d( GLcontext *ctx, - const struct gl_texture_object *tObj, GLuint n, - const GLfloat texcoords[][4], - const GLfloat lambda[], GLchan rgba[][4] ) +sample_linear_2d(GLcontext *ctx, + const struct gl_texture_object *tObj, GLuint n, + const GLfloat texcoords[][4], + const GLfloat lambda[], GLchan rgba[][4]) { GLuint i; struct gl_texture_image *image = tObj->Image[0][tObj->BaseLevel]; @@ -1195,19 +1192,19 @@ sample_linear_2d( GLcontext *ctx, tObj->WrapT == GL_REPEAT && image->_IsPowerOfTwo && image->Border == 0) { - for (i=0;i<n;i++) { + for (i = 0; i < n; i++) { sample_2d_linear_repeat(ctx, tObj, image, texcoords[i], rgba[i]); } } else { - for (i=0;i<n;i++) { + for (i = 0; i < n; i++) { sample_2d_linear(ctx, tObj, image, texcoords[i], rgba[i]); } } } -/* +/** * Optimized 2-D texture sampling: * S and T wrap mode == GL_REPEAT * GL_NEAREST min/mag filter @@ -1216,10 +1213,10 @@ sample_linear_2d( GLcontext *ctx, * Format = GL_RGB */ static void -opt_sample_rgb_2d( GLcontext *ctx, - const struct gl_texture_object *tObj, - GLuint n, const GLfloat texcoords[][4], - const GLfloat lambda[], GLchan rgba[][4] ) +opt_sample_rgb_2d(GLcontext *ctx, + const struct gl_texture_object *tObj, + GLuint n, const GLfloat texcoords[][4], + const GLfloat lambda[], GLchan rgba[][4]) { const struct gl_texture_image *img = tObj->Image[0][tObj->BaseLevel]; const GLfloat width = (GLfloat) img->Width; @@ -1248,7 +1245,7 @@ opt_sample_rgb_2d( GLcontext *ctx, } -/* +/** * Optimized 2-D texture sampling: * S and T wrap mode == GL_REPEAT * GL_NEAREST min/mag filter @@ -1257,10 +1254,10 @@ opt_sample_rgb_2d( GLcontext *ctx, * Format = GL_RGBA */ static void -opt_sample_rgba_2d( GLcontext *ctx, - const struct gl_texture_object *tObj, - GLuint n, const GLfloat texcoords[][4], - const GLfloat lambda[], GLchan rgba[][4] ) +opt_sample_rgba_2d(GLcontext *ctx, + const struct gl_texture_object *tObj, + GLuint n, const GLfloat texcoords[][4], + const GLfloat lambda[], GLchan rgba[][4]) { const struct gl_texture_image *img = tObj->Image[0][tObj->BaseLevel]; const GLfloat width = (GLfloat) img->Width; @@ -1287,15 +1284,12 @@ opt_sample_rgba_2d( GLcontext *ctx, } -/* - * Given an array of texture coordinate and lambda (level of detail) - * values, return an array of texture sample. - */ +/** Sample 2D texture, using lambda to choose between min/magnification */ static void -sample_lambda_2d( GLcontext *ctx, - const struct gl_texture_object *tObj, - GLuint n, const GLfloat texcoords[][4], - const GLfloat lambda[], GLchan rgba[][4] ) +sample_lambda_2d(GLcontext *ctx, + const struct gl_texture_object *tObj, + GLuint n, const GLfloat texcoords[][4], + const GLfloat lambda[], GLchan rgba[][4]) { const struct gl_texture_image *tImg = tObj->Image[0][tObj->BaseLevel]; GLuint minStart, minEnd; /* texels with minification */ @@ -1409,10 +1403,10 @@ sample_lambda_2d( GLcontext *ctx, /* 3-D Texture Sampling Functions */ /**********************************************************************/ -/* +/** * Return the texture sample for coordinate (s,t,r) using GL_NEAREST filter. */ -static void +static INLINE void sample_3d_nearest(GLcontext *ctx, const struct gl_texture_object *tObj, const struct gl_texture_image *img, @@ -1425,9 +1419,9 @@ sample_3d_nearest(GLcontext *ctx, GLint i, j, k; (void) ctx; - COMPUTE_NEAREST_TEXEL_LOCATION(tObj->WrapS, texcoord[0], width, i); - COMPUTE_NEAREST_TEXEL_LOCATION(tObj->WrapT, texcoord[1], height, j); - COMPUTE_NEAREST_TEXEL_LOCATION(tObj->WrapR, texcoord[2], depth, k); + i = nearest_texel_location(tObj->WrapS, img, width, texcoord[0]); + j = nearest_texel_location(tObj->WrapT, img, height, texcoord[1]); + k = nearest_texel_location(tObj->WrapR, img, depth, texcoord[2]); if (i < 0 || i >= (GLint) img->Width || j < 0 || j >= (GLint) img->Height || @@ -1441,8 +1435,7 @@ sample_3d_nearest(GLcontext *ctx, } - -/* +/** * Return the texture sample for coordinate (s,t,r) using GL_LINEAR filter. */ static void @@ -1457,14 +1450,13 @@ sample_3d_linear(GLcontext *ctx, const GLint depth = img->Depth2; GLint i0, j0, k0, i1, j1, k1; GLbitfield useBorderColor = 0x0; - GLfloat u, v, w; GLfloat a, b, c; GLchan t000[4], t010[4], t001[4], t011[4]; GLchan t100[4], t110[4], t101[4], t111[4]; - COMPUTE_LINEAR_TEXEL_LOCATIONS(tObj->WrapS, texcoord[0], u, width, i0, i1); - COMPUTE_LINEAR_TEXEL_LOCATIONS(tObj->WrapT, texcoord[1], v, height, j0, j1); - COMPUTE_LINEAR_TEXEL_LOCATIONS(tObj->WrapR, texcoord[2], w, depth, k0, k1); + linear_texel_locations(tObj->WrapS, img, width, texcoord[0], &i0, &i1, &a); + linear_texel_locations(tObj->WrapT, img, height, texcoord[1], &j0, &j1, &b); + linear_texel_locations(tObj->WrapR, img, depth, texcoord[2], &k0, &k1, &c); if (img->Border) { i0 += img->Border; @@ -1536,14 +1528,10 @@ sample_3d_linear(GLcontext *ctx, } /* trilinear interpolation of samples */ - a = FRAC(u); - b = FRAC(v); - c = FRAC(w); lerp_rgba_3d(rgba, a, b, c, t000, t100, t010, t110, t001, t101, t011, t111); } - static void sample_3d_nearest_mipmap_nearest(GLcontext *ctx, const struct gl_texture_object *tObj, @@ -1623,6 +1611,7 @@ sample_3d_linear_mipmap_linear(GLcontext *ctx, } +/** Sample 3D texture, nearest filtering for both min/magnification */ static void sample_nearest_3d(GLcontext *ctx, const struct gl_texture_object *tObj, GLuint n, @@ -1632,37 +1621,34 @@ sample_nearest_3d(GLcontext *ctx, GLuint i; struct gl_texture_image *image = tObj->Image[0][tObj->BaseLevel]; (void) lambda; - for (i=0;i<n;i++) { + for (i = 0; i < n; i++) { sample_3d_nearest(ctx, tObj, image, texcoords[i], rgba[i]); } } - +/** Sample 3D texture, linear filtering for both min/magnification */ static void -sample_linear_3d( GLcontext *ctx, - const struct gl_texture_object *tObj, GLuint n, - const GLfloat texcoords[][4], - const GLfloat lambda[], GLchan rgba[][4] ) +sample_linear_3d(GLcontext *ctx, + const struct gl_texture_object *tObj, GLuint n, + const GLfloat texcoords[][4], + const GLfloat lambda[], GLchan rgba[][4]) { GLuint i; struct gl_texture_image *image = tObj->Image[0][tObj->BaseLevel]; (void) lambda; - for (i=0;i<n;i++) { + for (i = 0; i < n; i++) { sample_3d_linear(ctx, tObj, image, texcoords[i], rgba[i]); } } -/* - * Given an (s,t,r) texture coordinate and lambda (level of detail) value, - * return a texture sample. - */ +/** Sample 3D texture, using lambda to choose between min/magnification */ static void -sample_lambda_3d( GLcontext *ctx, - const struct gl_texture_object *tObj, GLuint n, - const GLfloat texcoords[][4], const GLfloat lambda[], - GLchan rgba[][4] ) +sample_lambda_3d(GLcontext *ctx, + const struct gl_texture_object *tObj, GLuint n, + const GLfloat texcoords[][4], const GLfloat lambda[], + GLchan rgba[][4]) { GLuint minStart, minEnd; /* texels with minification */ GLuint magStart, magEnd; /* texels with magnification */ @@ -1951,11 +1937,12 @@ sample_cube_linear_mipmap_linear(GLcontext *ctx, } +/** Sample cube texture, using lambda to choose between min/magnification */ static void -sample_lambda_cube( GLcontext *ctx, - const struct gl_texture_object *tObj, GLuint n, - const GLfloat texcoords[][4], const GLfloat lambda[], - GLchan rgba[][4]) +sample_lambda_cube(GLcontext *ctx, + const struct gl_texture_object *tObj, GLuint n, + const GLfloat texcoords[][4], const GLfloat lambda[], + GLchan rgba[][4]) { GLuint minStart, minEnd; /* texels with minification */ GLuint magStart, magEnd; /* texels with magnification */ @@ -2031,50 +2018,56 @@ sample_lambda_cube( GLcontext *ctx, static INLINE GLint clamp_rect_coord_nearest(GLenum wrapMode, GLfloat coord, GLint max) { - if (wrapMode == GL_CLAMP) { + switch (wrapMode) { + case GL_CLAMP: return IFLOOR( CLAMP(coord, 0.0F, max - 1) ); - } - else if (wrapMode == GL_CLAMP_TO_EDGE) { + case GL_CLAMP_TO_EDGE: return IFLOOR( CLAMP(coord, 0.5F, max - 0.5F) ); - } - else { + case GL_CLAMP_TO_BORDER: return IFLOOR( CLAMP(coord, -0.5F, max + 0.5F) ); + default: + _mesa_problem(NULL, "bad wrapMode in clamp_rect_coord_nearest"); + return 0; } } -/* +/** * As above, but GL_LINEAR filtering. */ static INLINE void clamp_rect_coord_linear(GLenum wrapMode, GLfloat coord, GLint max, - GLint *i0out, GLint *i1out) + GLint *i0out, GLint *i1out, GLfloat *weight) { GLfloat fcol; GLint i0, i1; - if (wrapMode == GL_CLAMP) { + switch (wrapMode) { + case GL_CLAMP: /* Not exactly what the spec says, but it matches NVIDIA output */ fcol = CLAMP(coord - 0.5F, 0.0, max-1); i0 = IFLOOR(fcol); i1 = i0 + 1; - } - else if (wrapMode == GL_CLAMP_TO_EDGE) { + break; + case GL_CLAMP_TO_EDGE: fcol = CLAMP(coord, 0.5F, max - 0.5F); fcol -= 0.5F; i0 = IFLOOR(fcol); i1 = i0 + 1; if (i1 > max - 1) i1 = max - 1; - } - else { - ASSERT(wrapMode == GL_CLAMP_TO_BORDER); + break; + case GL_CLAMP_TO_BORDER: fcol = CLAMP(coord, -0.5F, max + 0.5F); fcol -= 0.5F; i0 = IFLOOR(fcol); i1 = i0 + 1; + default: + _mesa_problem(NULL, "bad wrapMode in clamp_rect_coord_linear"); + i0 = i1 = 0; } *i0out = i0; *i1out = i1; + *weight = FRAC(fcol); } @@ -2085,10 +2078,8 @@ sample_nearest_rect(GLcontext *ctx, GLchan rgba[][4]) { const struct gl_texture_image *img = tObj->Image[0][0]; - const GLfloat width = (GLfloat) img->Width; - const GLfloat height = (GLfloat) img->Height; - const GLint width_minus_1 = img->Width - 1; - const GLint height_minus_1 = img->Height - 1; + const GLint width = img->Width; + const GLint height = img->Height; GLuint i; (void) ctx; @@ -2106,7 +2097,7 @@ sample_nearest_rect(GLcontext *ctx, GLint row, col; col = clamp_rect_coord_nearest(tObj->WrapS, texcoords[i][0], width); row = clamp_rect_coord_nearest(tObj->WrapT, texcoords[i][1], height); - if (col < 0 || col > width_minus_1 || row < 0 || row > height_minus_1) + if (col < 0 || col >= width || row < 0 || row >= height) COPY_CHAN4(rgba[i], tObj->_BorderChan); else img->FetchTexelc(img, col, row, 0, rgba[i]); @@ -2121,10 +2112,8 @@ sample_linear_rect(GLcontext *ctx, const GLfloat lambda[], GLchan rgba[][4]) { const struct gl_texture_image *img = tObj->Image[0][0]; - const GLfloat width = (GLfloat) img->Width; - const GLfloat height = (GLfloat) img->Height; - const GLint width_minus_1 = img->Width - 1; - const GLint height_minus_1 = img->Height - 1; + const GLint width = img->Width; + const GLint height = img->Height; GLuint i; (void) ctx; @@ -2138,64 +2127,22 @@ sample_linear_rect(GLcontext *ctx, tObj->WrapT == GL_CLAMP_TO_BORDER); ASSERT(img->TexFormat->BaseFormat != GL_COLOR_INDEX); - /* XXX lots of opportunity for optimization in this loop */ for (i = 0; i < n; i++) { - GLfloat frow, fcol; GLint i0, j0, i1, j1; GLchan t00[4], t01[4], t10[4], t11[4]; GLfloat a, b; GLbitfield useBorderColor = 0x0; - /* NOTE: we DO NOT use [0, 1] texture coordinates! */ - if (tObj->WrapS == GL_CLAMP) { - /* Not exactly what the spec says, but it matches NVIDIA output */ - fcol = CLAMP(texcoords[i][0] - 0.5F, 0.0, width_minus_1); - i0 = IFLOOR(fcol); - i1 = i0 + 1; - } - else if (tObj->WrapS == GL_CLAMP_TO_EDGE) { - fcol = CLAMP(texcoords[i][0], 0.5F, width - 0.5F); - fcol -= 0.5F; - i0 = IFLOOR(fcol); - i1 = i0 + 1; - if (i1 > width_minus_1) - i1 = width_minus_1; - } - else { - ASSERT(tObj->WrapS == GL_CLAMP_TO_BORDER); - fcol = CLAMP(texcoords[i][0], -0.5F, width + 0.5F); - fcol -= 0.5F; - i0 = IFLOOR(fcol); - i1 = i0 + 1; - } - - if (tObj->WrapT == GL_CLAMP) { - /* Not exactly what the spec says, but it matches NVIDIA output */ - frow = CLAMP(texcoords[i][1] - 0.5F, 0.0, width_minus_1); - j0 = IFLOOR(frow); - j1 = j0 + 1; - } - else if (tObj->WrapT == GL_CLAMP_TO_EDGE) { - frow = CLAMP(texcoords[i][1], 0.5F, height - 0.5F); - frow -= 0.5F; - j0 = IFLOOR(frow); - j1 = j0 + 1; - if (j1 > height_minus_1) - j1 = height_minus_1; - } - else { - ASSERT(tObj->WrapT == GL_CLAMP_TO_BORDER); - frow = CLAMP(texcoords[i][1], -0.5F, height + 0.5F); - frow -= 0.5F; - j0 = IFLOOR(frow); - j1 = j0 + 1; - } + clamp_rect_coord_linear(tObj->WrapS, texcoords[i][0], width, + &i0, &i1, &a); + clamp_rect_coord_linear(tObj->WrapT, texcoords[i][1], height, + &j0, &j1, &b); /* compute integer rows/columns */ - if (i0 < 0 || i0 > width_minus_1) useBorderColor |= I0BIT; - if (i1 < 0 || i1 > width_minus_1) useBorderColor |= I1BIT; - if (j0 < 0 || j0 > height_minus_1) useBorderColor |= J0BIT; - if (j1 < 0 || j1 > height_minus_1) useBorderColor |= J1BIT; + if (i0 < 0 || i0 >= width) useBorderColor |= I0BIT; + if (i1 < 0 || i1 >= width) useBorderColor |= I1BIT; + if (j0 < 0 || j0 >= height) useBorderColor |= J0BIT; + if (j1 < 0 || j1 >= height) useBorderColor |= J1BIT; /* get four texel samples */ if (useBorderColor & (I0BIT | J0BIT)) @@ -2218,20 +2165,17 @@ sample_linear_rect(GLcontext *ctx, else img->FetchTexelc(img, i1, j1, 0, t11); - /* compute interpolants */ - a = FRAC(fcol); - b = FRAC(frow); - lerp_rgba_2d(rgba[i], a, b, t00, t10, t01, t11); } } +/** Sample Rect texture, using lambda to choose between min/magnification */ static void -sample_lambda_rect( GLcontext *ctx, - const struct gl_texture_object *tObj, GLuint n, - const GLfloat texcoords[][4], const GLfloat lambda[], - GLchan rgba[][4]) +sample_lambda_rect(GLcontext *ctx, + const struct gl_texture_object *tObj, GLuint n, + const GLfloat texcoords[][4], const GLfloat lambda[], + GLchan rgba[][4]) { GLuint minStart, minEnd, magStart, magEnd; @@ -2243,22 +2187,22 @@ sample_lambda_rect( GLcontext *ctx, if (minStart < minEnd) { if (tObj->MinFilter == GL_NEAREST) { - sample_nearest_rect( ctx, tObj, minEnd - minStart, - texcoords + minStart, NULL, rgba + minStart); + sample_nearest_rect(ctx, tObj, minEnd - minStart, + texcoords + minStart, NULL, rgba + minStart); } else { - sample_linear_rect( ctx, tObj, minEnd - minStart, - texcoords + minStart, NULL, rgba + minStart); + sample_linear_rect(ctx, tObj, minEnd - minStart, + texcoords + minStart, NULL, rgba + minStart); } } if (magStart < magEnd) { if (tObj->MagFilter == GL_NEAREST) { - sample_nearest_rect( ctx, tObj, magEnd - magStart, - texcoords + magStart, NULL, rgba + magStart); + sample_nearest_rect(ctx, tObj, magEnd - magStart, + texcoords + magStart, NULL, rgba + magStart); } else { - sample_linear_rect( ctx, tObj, magEnd - magStart, - texcoords + magStart, NULL, rgba + magStart); + sample_linear_rect(ctx, tObj, magEnd - magStart, + texcoords + magStart, NULL, rgba + magStart); } } } @@ -2269,7 +2213,7 @@ sample_lambda_rect( GLcontext *ctx, /* 2D Texture Array Sampling Functions */ /**********************************************************************/ -/* +/** * Return the texture sample for coordinate (s,t,r) using GL_NEAREST filter. */ static void @@ -2286,8 +2230,8 @@ sample_2d_array_nearest(GLcontext *ctx, GLint array; (void) ctx; - COMPUTE_NEAREST_TEXEL_LOCATION(tObj->WrapS, texcoord[0], width, i); - COMPUTE_NEAREST_TEXEL_LOCATION(tObj->WrapT, texcoord[1], height, j); + i = nearest_texel_location(tObj->WrapS, img, width, texcoord[0]); + j = nearest_texel_location(tObj->WrapT, img, height, texcoord[1]); array = clamp_rect_coord_nearest(tObj->WrapR, texcoord[2], depth); if (i < 0 || i >= (GLint) img->Width || @@ -2302,8 +2246,7 @@ sample_2d_array_nearest(GLcontext *ctx, } - -/* +/** * Return the texture sample for coordinate (s,t,r) using GL_LINEAR filter. */ static void @@ -2319,12 +2262,11 @@ sample_2d_array_linear(GLcontext *ctx, GLint i0, j0, i1, j1; GLint array; GLbitfield useBorderColor = 0x0; - GLfloat u, v; GLfloat a, b; GLchan t00[4], t01[4], t10[4], t11[4]; - COMPUTE_LINEAR_TEXEL_LOCATIONS(tObj->WrapS, texcoord[0], u, width, i0, i1); - COMPUTE_LINEAR_TEXEL_LOCATIONS(tObj->WrapT, texcoord[1], v, height, j0, j1); + linear_texel_locations(tObj->WrapS, img, width, texcoord[0], &i0, &i1, &a); + linear_texel_locations(tObj->WrapT, img, height, texcoord[1], &j0, &j1, &b); array = clamp_rect_coord_nearest(tObj->WrapR, texcoord[2], depth); if (array < 0 || array >= depth) { @@ -2372,19 +2314,16 @@ sample_2d_array_linear(GLcontext *ctx, } /* trilinear interpolation of samples */ - a = FRAC(u); - b = FRAC(v); lerp_rgba_2d(rgba, a, b, t00, t10, t01, t11); } } - static void sample_2d_array_nearest_mipmap_nearest(GLcontext *ctx, const struct gl_texture_object *tObj, GLuint n, const GLfloat texcoord[][4], - const GLfloat lambda[], GLchan rgba[][4] ) + const GLfloat lambda[], GLchan rgba[][4]) { GLuint i; for (i = 0; i < n; i++) { @@ -2428,8 +2367,10 @@ sample_2d_array_nearest_mipmap_linear(GLcontext *ctx, else { GLchan t0[4], t1[4]; /* texels */ const GLfloat f = FRAC(lambda[i]); - sample_2d_array_nearest(ctx, tObj, tObj->Image[0][level ], texcoord[i], t0); - sample_2d_array_nearest(ctx, tObj, tObj->Image[0][level+1], texcoord[i], t1); + sample_2d_array_nearest(ctx, tObj, tObj->Image[0][level ], + texcoord[i], t0); + sample_2d_array_nearest(ctx, tObj, tObj->Image[0][level+1], + texcoord[i], t1); lerp_rgba(rgba[i], f, t0, t1); } } @@ -2438,9 +2379,9 @@ sample_2d_array_nearest_mipmap_linear(GLcontext *ctx, static void sample_2d_array_linear_mipmap_linear(GLcontext *ctx, - const struct gl_texture_object *tObj, - GLuint n, const GLfloat texcoord[][4], - const GLfloat lambda[], GLchan rgba[][4]) + const struct gl_texture_object *tObj, + GLuint n, const GLfloat texcoord[][4], + const GLfloat lambda[], GLchan rgba[][4]) { GLuint i; ASSERT(lambda != NULL); @@ -2453,30 +2394,34 @@ sample_2d_array_linear_mipmap_linear(GLcontext *ctx, else { GLchan t0[4], t1[4]; /* texels */ const GLfloat f = FRAC(lambda[i]); - sample_2d_array_linear(ctx, tObj, tObj->Image[0][level ], texcoord[i], t0); - sample_2d_array_linear(ctx, tObj, tObj->Image[0][level+1], texcoord[i], t1); + sample_2d_array_linear(ctx, tObj, tObj->Image[0][level ], + texcoord[i], t0); + sample_2d_array_linear(ctx, tObj, tObj->Image[0][level+1], + texcoord[i], t1); lerp_rgba(rgba[i], f, t0, t1); } } } +/** Sample 2D Array texture, nearest filtering for both min/magnification */ static void sample_nearest_2d_array(GLcontext *ctx, - const struct gl_texture_object *tObj, GLuint n, - const GLfloat texcoords[][4], const GLfloat lambda[], - GLchan rgba[][4]) + const struct gl_texture_object *tObj, GLuint n, + const GLfloat texcoords[][4], const GLfloat lambda[], + GLchan rgba[][4]) { GLuint i; struct gl_texture_image *image = tObj->Image[0][tObj->BaseLevel]; (void) lambda; - for (i=0;i<n;i++) { + for (i = 0; i < n; i++) { sample_2d_array_nearest(ctx, tObj, image, texcoords[i], rgba[i]); } } +/** Sample 2D Array texture, linear filtering for both min/magnification */ static void sample_linear_2d_array(GLcontext *ctx, const struct gl_texture_object *tObj, GLuint n, @@ -2486,16 +2431,13 @@ sample_linear_2d_array(GLcontext *ctx, GLuint i; struct gl_texture_image *image = tObj->Image[0][tObj->BaseLevel]; (void) lambda; - for (i=0;i<n;i++) { + for (i = 0; i < n; i++) { sample_2d_array_linear(ctx, tObj, image, texcoords[i], rgba[i]); } } -/* - * Given an (s,t,r) texture coordinate and lambda (level of detail) value, - * return a texture sample. - */ +/** Sample 2D Array texture, using lambda to choose between min/magnification */ static void sample_lambda_2d_array(GLcontext *ctx, const struct gl_texture_object *tObj, GLuint n, @@ -2525,8 +2467,10 @@ sample_lambda_2d_array(GLcontext *ctx, texcoords[i], rgba[i]); break; case GL_NEAREST_MIPMAP_NEAREST: - sample_2d_array_nearest_mipmap_nearest(ctx, tObj, m, texcoords + minStart, - lambda + minStart, rgba + minStart); + sample_2d_array_nearest_mipmap_nearest(ctx, tObj, m, + texcoords + minStart, + lambda + minStart, + rgba + minStart); break; case GL_LINEAR_MIPMAP_NEAREST: sample_2d_array_linear_mipmap_nearest(ctx, tObj, m, @@ -2535,8 +2479,10 @@ sample_lambda_2d_array(GLcontext *ctx, rgba + minStart); break; case GL_NEAREST_MIPMAP_LINEAR: - sample_2d_array_nearest_mipmap_linear(ctx, tObj, m, texcoords + minStart, - lambda + minStart, rgba + minStart); + sample_2d_array_nearest_mipmap_linear(ctx, tObj, m, + texcoords + minStart, + lambda + minStart, + rgba + minStart); break; case GL_LINEAR_MIPMAP_LINEAR: sample_2d_array_linear_mipmap_linear(ctx, tObj, m, @@ -2577,7 +2523,7 @@ sample_lambda_2d_array(GLcontext *ctx, /* 1D Texture Array Sampling Functions */ /**********************************************************************/ -/* +/** * Return the texture sample for coordinate (s,t,r) using GL_NEAREST filter. */ static void @@ -2593,7 +2539,7 @@ sample_1d_array_nearest(GLcontext *ctx, GLint array; (void) ctx; - COMPUTE_NEAREST_TEXEL_LOCATION(tObj->WrapS, texcoord[0], width, i); + i = nearest_texel_location(tObj->WrapS, img, width, texcoord[0]); array = clamp_rect_coord_nearest(tObj->WrapT, texcoord[1], height); if (i < 0 || i >= (GLint) img->Width || @@ -2607,8 +2553,7 @@ sample_1d_array_nearest(GLcontext *ctx, } - -/* +/** * Return the texture sample for coordinate (s,t,r) using GL_LINEAR filter. */ static void @@ -2623,11 +2568,10 @@ sample_1d_array_linear(GLcontext *ctx, GLint i0, i1; GLint array; GLbitfield useBorderColor = 0x0; - GLfloat u; GLfloat a; GLchan t0[4], t1[4]; - COMPUTE_LINEAR_TEXEL_LOCATIONS(tObj->WrapS, texcoord[0], u, width, i0, i1); + linear_texel_locations(tObj->WrapS, img, width, texcoord[0], &i0, &i1, &a); array = clamp_rect_coord_nearest(tObj->WrapT, texcoord[1], height); if (img->Border) { @@ -2657,17 +2601,15 @@ sample_1d_array_linear(GLcontext *ctx, } /* bilinear interpolation of samples */ - a = FRAC(u); lerp_rgba(rgba, a, t0, t1); } - static void sample_1d_array_nearest_mipmap_nearest(GLcontext *ctx, const struct gl_texture_object *tObj, GLuint n, const GLfloat texcoord[][4], - const GLfloat lambda[], GLchan rgba[][4] ) + const GLfloat lambda[], GLchan rgba[][4]) { GLuint i; for (i = 0; i < n; i++) { @@ -2721,9 +2663,9 @@ sample_1d_array_nearest_mipmap_linear(GLcontext *ctx, static void sample_1d_array_linear_mipmap_linear(GLcontext *ctx, - const struct gl_texture_object *tObj, - GLuint n, const GLfloat texcoord[][4], - const GLfloat lambda[], GLchan rgba[][4]) + const struct gl_texture_object *tObj, + GLuint n, const GLfloat texcoord[][4], + const GLfloat lambda[], GLchan rgba[][4]) { GLuint i; ASSERT(lambda != NULL); @@ -2744,22 +2686,23 @@ 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, - const struct gl_texture_object *tObj, GLuint n, - const GLfloat texcoords[][4], const GLfloat lambda[], - GLchan rgba[][4]) + const struct gl_texture_object *tObj, GLuint n, + const GLfloat texcoords[][4], const GLfloat lambda[], + GLchan rgba[][4]) { GLuint i; struct gl_texture_image *image = tObj->Image[0][tObj->BaseLevel]; (void) lambda; - for (i=0;i<n;i++) { + for (i = 0; i < n; i++) { sample_1d_array_nearest(ctx, tObj, image, texcoords[i], rgba[i]); } } - +/** Sample 1D Array texture, linear filtering for both min/magnification */ static void sample_linear_1d_array(GLcontext *ctx, const struct gl_texture_object *tObj, GLuint n, @@ -2769,16 +2712,13 @@ sample_linear_1d_array(GLcontext *ctx, GLuint i; struct gl_texture_image *image = tObj->Image[0][tObj->BaseLevel]; (void) lambda; - for (i=0;i<n;i++) { + for (i = 0; i < n; i++) { sample_1d_array_linear(ctx, tObj, image, texcoords[i], rgba[i]); } } -/* - * Given an (s,t,r) texture coordinate and lambda (level of detail) value, - * return a texture sample. - */ +/** Sample 1D Array texture, using lambda to choose between min/magnification */ static void sample_lambda_1d_array(GLcontext *ctx, const struct gl_texture_object *tObj, GLuint n, @@ -2854,9 +2794,7 @@ sample_lambda_1d_array(GLcontext *ctx, } - - -/* +/** * Sample a shadow/depth texture. */ static void @@ -2906,31 +2844,32 @@ sample_depth_texture( GLcontext *ctx, break; case GL_TEXTURE_1D: - COMPUTE_NEAREST_TEXEL_LOCATION(tObj->WrapS, texcoords[i][0], - width, col); + col = nearest_texel_location(tObj->WrapS, img, width, + texcoords[i][0]); row = 0; slice = 0; break; case GL_TEXTURE_2D: - COMPUTE_NEAREST_TEXEL_LOCATION(tObj->WrapS, texcoords[i][0], - width, col); - COMPUTE_NEAREST_TEXEL_LOCATION(tObj->WrapT, texcoords[i][1], - height, row); + col = nearest_texel_location(tObj->WrapS, img, width, + texcoords[i][0]); + row = nearest_texel_location(tObj->WrapT, img, height, + texcoords[i][1]); slice = 0; break; case GL_TEXTURE_1D_ARRAY_EXT: - COMPUTE_NEAREST_TEXEL_LOCATION(tObj->WrapS, texcoords[i][0], - width, col); + col = nearest_texel_location(tObj->WrapS, img, width, + texcoords[i][0]); row = clamp_rect_coord_nearest(tObj->WrapT, texcoords[i][1], height); slice = 0; + break; case GL_TEXTURE_2D_ARRAY_EXT: - COMPUTE_NEAREST_TEXEL_LOCATION(tObj->WrapS, texcoords[i][0], - width, col); - COMPUTE_NEAREST_TEXEL_LOCATION(tObj->WrapT, texcoords[i][1], - height, row); + col = nearest_texel_location(tObj->WrapS, img, width, + texcoords[i][0]); + row = nearest_texel_location(tObj->WrapT, img, height, + texcoords[i][1]); slice = clamp_rect_coord_nearest(tObj->WrapR, texcoords[i][2], depth); break; } @@ -3007,39 +2946,40 @@ sample_depth_texture( GLcontext *ctx, GLfloat depth00, depth01, depth10, depth11; GLint i0, i1, j0, j1; GLint slice; - GLfloat u, v; + GLfloat a, b; GLuint useBorderTexel; switch (tObj->Target) { case GL_TEXTURE_RECTANGLE_ARB: clamp_rect_coord_linear(tObj->WrapS, texcoords[i][0], - width, &i0, &i1); + width, &i0, &i1, &a); clamp_rect_coord_linear(tObj->WrapT, texcoords[i][1], - height, &j0, &j1); + height, &j0, &j1, &b); slice = 0; break; case GL_TEXTURE_1D: case GL_TEXTURE_2D: - COMPUTE_LINEAR_TEXEL_LOCATIONS(tObj->WrapS, texcoords[i][0], - u, width, i0, i1); - COMPUTE_LINEAR_TEXEL_LOCATIONS(tObj->WrapT, texcoords[i][1], - v, height,j0, j1); + linear_texel_locations(tObj->WrapS, img, width, + texcoords[i][0], &i0, &i1, &a); + linear_texel_locations(tObj->WrapT, img, height, + texcoords[i][1], &j0, &j1, &b); slice = 0; break; case GL_TEXTURE_1D_ARRAY_EXT: - COMPUTE_LINEAR_TEXEL_LOCATIONS(tObj->WrapS, texcoords[i][0], - u, width, i0, i1); + linear_texel_locations(tObj->WrapS, img, width, + texcoords[i][0], &i0, &i1, &a); j0 = clamp_rect_coord_nearest(tObj->WrapT, texcoords[i][1], height); j1 = j0; slice = 0; + break; case GL_TEXTURE_2D_ARRAY_EXT: - COMPUTE_LINEAR_TEXEL_LOCATIONS(tObj->WrapS, texcoords[i][0], - u, width, i0, i1); - COMPUTE_LINEAR_TEXEL_LOCATIONS(tObj->WrapT, texcoords[i][1], - v, height,j0, j1); + linear_texel_locations(tObj->WrapS, img, width, + texcoords[i][0], &i0, &i1, &a); + linear_texel_locations(tObj->WrapT, img, height, + texcoords[i][1], &j0, &j1, &b); slice = clamp_rect_coord_nearest(tObj->WrapR, texcoords[i][2], depth); break; } @@ -3103,8 +3043,6 @@ sample_depth_texture( GLcontext *ctx, if (0) { /* compute a single weighted depth sample and do one comparison */ - const GLfloat a = FRAC(u + 1.0F); - const GLfloat b = FRAC(v + 1.0F); const GLfloat depthSample = lerp_2d(a, b, depth00, depth10, depth01, depth11); if ((depthSample <= texcoords[i][compare_coord] && function == GL_LEQUAL) || @@ -3175,8 +3113,6 @@ sample_depth_texture( GLcontext *ctx, case GL_NONE: /* ordinary bilinear filtering */ { - const GLfloat a = FRAC(u + 1.0F); - const GLfloat b = FRAC(v + 1.0F); const GLfloat depthSample = lerp_2d(a, b, depth00, depth10, depth01, depth11); CLAMPED_FLOAT_TO_CHAN(result, depthSample); @@ -3270,10 +3206,10 @@ sample_depth_texture2(const GLcontext *ctx, GLint col, row, ii, jj, imin, imax, jmin, jmax, samples, count; GLfloat w; GLchan lum; - COMPUTE_NEAREST_TEXEL_LOCATION(texObj->WrapS, texcoords[i][0], - width, col); - COMPUTE_NEAREST_TEXEL_LOCATION(texObj->WrapT, texcoords[i][1], - height, row); + col = nearest_texel_location(texObj->WrapS, img, width, + texcoords[i][0]); + row = nearest_texel_location(texObj->WrapT, img, height, + texcoords[i][1]); imin = col - K; imax = col + K; |