diff options
| author | Brian Paul <brian.paul@tungstengraphics.com> | 2002-02-17 01:58:59 +0000 | 
|---|---|---|
| committer | Brian Paul <brian.paul@tungstengraphics.com> | 2002-02-17 01:58:59 +0000 | 
| commit | 4f252bd98048736a489b07f973c8e7f39d713877 (patch) | |
| tree | ee1efc40a3452a00bec05afdf856a11f5c1770c6 /src | |
| parent | c14a5a6c6285b29860a722359faa11a16da4eac9 (diff) | |
Lots of improvements in the 2D texture sampling code.  Fewer function calls
and no more switches inside loops.  To do: give the 1D/3D/cube routines the
same treatment.
Diffstat (limited to 'src')
| -rw-r--r-- | src/mesa/swrast/s_texture.c | 427 | 
1 files changed, 315 insertions, 112 deletions
| diff --git a/src/mesa/swrast/s_texture.c b/src/mesa/swrast/s_texture.c index 07e005b150..1e881a3e0c 100644 --- a/src/mesa/swrast/s_texture.c +++ b/src/mesa/swrast/s_texture.c @@ -1,4 +1,4 @@ -/* $Id: s_texture.c,v 1.52 2002/02/16 23:44:46 brianp Exp $ */ +/* $Id: s_texture.c,v 1.53 2002/02/17 01:58:59 brianp Exp $ */  /*   * Mesa 3-D graphics library @@ -184,16 +184,25 @@  } +#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);						\ +} + +  /*   * Compute linear mipmap levels for given lambda.   */  #define COMPUTE_LINEAR_MIPMAP_LEVEL(tObj, lambda, level)	\  {								\     if (lambda < 0.0F)						\ -      lambda = 0.0F;						\ +      level = tObj->BaseLevel;					\     else if (lambda > tObj->_MaxLambda)				\ -      lambda = tObj->_MaxLambda;				\ -   level = (GLint) (tObj->BaseLevel + lambda);			\ +      level = (GLint) (tObj->BaseLevel + tObj->_MaxLambda);	\ +   else								\ +      level = (GLint) (tObj->BaseLevel + lambda);		\  } @@ -202,11 +211,14 @@   */  #define COMPUTE_NEAREST_MIPMAP_LEVEL(tObj, lambda, level)	\  {								\ +   GLfloat l;							\     if (lambda <= 0.5F)						\ -      lambda = 0.0F;						\ +      l = 0.0F;							\     else if (lambda > tObj->_MaxLambda + 0.4999F)		\ -      lambda = tObj->_MaxLambda + 0.4999F;			\ -   level = (GLint) (tObj->BaseLevel + lambda + 0.5F);		\ +      l = tObj->_MaxLambda + 0.4999F;				\ +   else								\ +      l = lambda;						\ +   level = (GLint) (tObj->BaseLevel + l + 0.5F);		\     if (level > tObj->_MaxLevel)					\        level = tObj->_MaxLevel;					\  } @@ -752,16 +764,98 @@ sample_2d_linear(GLcontext *ctx,  } +/* + * As above, but we know WRAP_S == REPEAT and WRAP_T == REPEAT + * and we're not using a paletted texture. + */ +static void +sample_2d_linear_repeat(GLcontext *ctx, +                        const struct gl_texture_object *tObj, +                        const struct gl_texture_image *img, +                        const GLfloat texcoord[4], +                        GLchan rgba[]) +{ +   const GLint width = img->Width2; +   const GLint height = img->Height2; +   GLint i0, j0, i1, j1; +   GLfloat u, v; + +   ASSERT(tObj->WrapS == GL_REPEAT); +   ASSERT(tObj->WrapT == GL_REPEAT); +   ASSERT(img->Format != GL_COLOR_INDEX); + +   COMPUTE_LINEAR_REPEAT_TEXEL_LOCATION(texcoord[0], u, width,  i0, i1); +   COMPUTE_LINEAR_REPEAT_TEXEL_LOCATION(texcoord[1], v, height, j0, j1); + +   { +      const GLfloat a = FRAC(u); +      const GLfloat b = FRAC(v); + +#if CHAN_TYPE == GL_FLOAT || CHAN_TYPE == GL_UNSIGNED_SHORT +      const GLfloat w00 = (1.0F-a) * (1.0F-b); +      const GLfloat w10 =       a  * (1.0F-b); +      const GLfloat w01 = (1.0F-a) *       b ; +      const GLfloat w11 =       a  *       b ; +#else /* CHAN_BITS == 8 */ +      /* compute sample weights in fixed point in [0,WEIGHT_SCALE] */ +      const GLint w00 = IROUND_POS((1.0F-a) * (1.0F-b) * WEIGHT_SCALE); +      const GLint w10 = IROUND_POS(      a  * (1.0F-b) * WEIGHT_SCALE); +      const GLint w01 = IROUND_POS((1.0F-a) *       b  * WEIGHT_SCALE); +      const GLint w11 = IROUND_POS(      a  *       b  * WEIGHT_SCALE); +#endif +      GLchan t00[4]; +      GLchan t10[4]; +      GLchan t01[4]; +      GLchan t11[4]; + +      (*img->FetchTexel)(img, i0, j0, 0, (GLvoid *) t00); +      (*img->FetchTexel)(img, i1, j0, 0, (GLvoid *) t10); +      (*img->FetchTexel)(img, i0, j1, 0, (GLvoid *) t01); +      (*img->FetchTexel)(img, i1, j1, 0, (GLvoid *) t11); + +#if CHAN_TYPE == GL_FLOAT +      rgba[0] = w00 * t00[0] + w10 * t10[0] + w01 * t01[0] + w11 * t11[0]; +      rgba[1] = w00 * t00[1] + w10 * t10[1] + w01 * t01[1] + w11 * t11[1]; +      rgba[2] = w00 * t00[2] + w10 * t10[2] + w01 * t01[2] + w11 * t11[2]; +      rgba[3] = w00 * t00[3] + w10 * t10[3] + w01 * t01[3] + w11 * t11[3]; +#elif CHAN_TYPE == GL_UNSIGNED_SHORT +      rgba[0] = (GLchan) (w00 * t00[0] + w10 * t10[0] + +                          w01 * t01[0] + w11 * t11[0] + 0.5); +      rgba[1] = (GLchan) (w00 * t00[1] + w10 * t10[1] + +                          w01 * t01[1] + w11 * t11[1] + 0.5); +      rgba[2] = (GLchan) (w00 * t00[2] + w10 * t10[2] + +                          w01 * t01[2] + w11 * t11[2] + 0.5); +      rgba[3] = (GLchan) (w00 * t00[3] + w10 * t10[3] + +                          w01 * t01[3] + w11 * t11[3] + 0.5); +#else /* CHAN_BITS == 8 */ +      rgba[0] = (GLchan) ((w00 * t00[0] + w10 * t10[0] + +                           w01 * t01[0] + w11 * t11[0]) >> WEIGHT_SHIFT); +      rgba[1] = (GLchan) ((w00 * t00[1] + w10 * t10[1] + +                           w01 * t01[1] + w11 * t11[1]) >> WEIGHT_SHIFT); +      rgba[2] = (GLchan) ((w00 * t00[2] + w10 * t10[2] + +                           w01 * t01[2] + w11 * t11[2]) >> WEIGHT_SHIFT); +      rgba[3] = (GLchan) ((w00 * t00[3] + w10 * t10[3] + +                           w01 * t01[3] + w11 * t11[3]) >> WEIGHT_SHIFT); +#endif + +   } + +} + +  static void  sample_2d_nearest_mipmap_nearest(GLcontext *ctx,                                   const struct gl_texture_object *tObj, -                                 const GLfloat texcoord[4], GLfloat lambda, -                                 GLchan rgba[4]) +                                 GLuint n, GLfloat texcoord[][4], +                                 const GLfloat lambda[], GLchan rgba[][4])  { -   GLint level; -   COMPUTE_NEAREST_MIPMAP_LEVEL(tObj, lambda, level); -   sample_2d_nearest(ctx, tObj, tObj->Image[level], texcoord, rgba); +   GLuint i; +   for (i = 0; i < n; i++) { +      GLint level; +      COMPUTE_NEAREST_MIPMAP_LEVEL(tObj, lambda[i], level); +      sample_2d_nearest(ctx, tObj, tObj->Image[level], texcoord[i], rgba[i]); +   }  } @@ -769,12 +863,15 @@ sample_2d_nearest_mipmap_nearest(GLcontext *ctx,  static void  sample_2d_linear_mipmap_nearest(GLcontext *ctx,                                  const struct gl_texture_object *tObj, -                                const GLfloat texcoord[4], GLfloat lambda, -                                GLchan rgba[4]) +                                GLuint n, GLfloat texcoord[][4], +                                const GLfloat lambda[], GLchan rgba[][4])  { -   GLint level; -   COMPUTE_NEAREST_MIPMAP_LEVEL(tObj, lambda, level); -   sample_2d_linear(ctx, tObj, tObj->Image[level], texcoord, rgba); +   GLuint i; +   for (i = 0; i < n; i++) { +      GLint level; +      COMPUTE_NEAREST_MIPMAP_LEVEL(tObj, lambda[i], level); +      sample_2d_linear(ctx, tObj, tObj->Image[level], texcoord[i], rgba[i]); +   }  } @@ -782,57 +879,91 @@ sample_2d_linear_mipmap_nearest(GLcontext *ctx,  static void  sample_2d_nearest_mipmap_linear(GLcontext *ctx,                                  const struct gl_texture_object *tObj, -                                const GLfloat texcoord[4], GLfloat lambda, -                                GLchan rgba[4]) +                                GLuint n, GLfloat texcoord[][4], +                                const GLfloat lambda[], GLchan rgba[][4])  { -   GLint level; - -   COMPUTE_LINEAR_MIPMAP_LEVEL(tObj, lambda, level); - -   if (level >= tObj->_MaxLevel) { -      sample_2d_nearest(ctx, tObj, tObj->Image[tObj->_MaxLevel], texcoord, rgba); -   } -   else { -      GLchan t0[4], t1[4];  /* texels */ -      const GLfloat f = FRAC(lambda); -      sample_2d_nearest(ctx, tObj, tObj->Image[level  ], texcoord, t0); -      sample_2d_nearest(ctx, tObj, tObj->Image[level+1], texcoord, t1); -      rgba[RCOMP] = (GLchan) INTCAST ((1.0F-f) * t0[RCOMP] + f * t1[RCOMP]); -      rgba[GCOMP] = (GLchan) INTCAST ((1.0F-f) * t0[GCOMP] + f * t1[GCOMP]); -      rgba[BCOMP] = (GLchan) INTCAST ((1.0F-f) * t0[BCOMP] + f * t1[BCOMP]); -      rgba[ACOMP] = (GLchan) INTCAST ((1.0F-f) * t0[ACOMP] + f * t1[ACOMP]); +   GLuint i; +   for (i = 0; i < n; i++) { +      GLint level; +      COMPUTE_LINEAR_MIPMAP_LEVEL(tObj, lambda[i], level); +      if (level >= tObj->_MaxLevel) { +         sample_2d_nearest(ctx, tObj, tObj->Image[tObj->_MaxLevel], +                           texcoord[i], rgba[i]); +      } +      else { +         GLchan t0[4], t1[4];  /* texels */ +         const GLfloat f = FRAC(lambda[i]); +         sample_2d_nearest(ctx, tObj, tObj->Image[level  ], texcoord[i], t0); +         sample_2d_nearest(ctx, tObj, tObj->Image[level+1], texcoord[i], t1); +         rgba[i][RCOMP] = (GLchan) INTCAST ((1.0F-f) * t0[RCOMP] + f * t1[RCOMP]); +         rgba[i][GCOMP] = (GLchan) INTCAST ((1.0F-f) * t0[GCOMP] + f * t1[GCOMP]); +         rgba[i][BCOMP] = (GLchan) INTCAST ((1.0F-f) * t0[BCOMP] + f * t1[BCOMP]); +         rgba[i][ACOMP] = (GLchan) INTCAST ((1.0F-f) * t0[ACOMP] + f * t1[ACOMP]); +      }     }  } +/* Trilinear filtering */  static void -sample_2d_linear_mipmap_linear(GLcontext *ctx, -                               const struct gl_texture_object *tObj, -                               const GLfloat texcoord[4], GLfloat lambda, -                               GLchan rgba[4]) +sample_2d_linear_mipmap_linear( GLcontext *ctx, +                                const struct gl_texture_object *tObj, +                                GLuint n, GLfloat texcoord[][4], +                                const GLfloat lambda[], GLchan rgba[][4] )  { -   GLint level; +   GLuint i; +   for (i = 0; i < n; i++) { +      GLint level; +      COMPUTE_LINEAR_MIPMAP_LEVEL(tObj, lambda[i], level); +      if (level >= tObj->_MaxLevel) { +         sample_2d_linear(ctx, tObj, tObj->Image[tObj->_MaxLevel], +                          texcoord[i], rgba[i]); +      } +      else { +         GLchan t0[4], t1[4];  /* texels */ +         const GLfloat f = FRAC(lambda[i]); +         sample_2d_linear(ctx, tObj, tObj->Image[level  ], texcoord[i], t0); +         sample_2d_linear(ctx, tObj, tObj->Image[level+1], texcoord[i], t1); +         rgba[i][RCOMP] = (GLchan) INTCAST ((1.0F-f) * t0[RCOMP] + f * t1[RCOMP]); +         rgba[i][GCOMP] = (GLchan) INTCAST ((1.0F-f) * t0[GCOMP] + f * t1[GCOMP]); +         rgba[i][BCOMP] = (GLchan) INTCAST ((1.0F-f) * t0[BCOMP] + f * t1[BCOMP]); +         rgba[i][ACOMP] = (GLchan) INTCAST ((1.0F-f) * t0[ACOMP] + f * t1[ACOMP]); +      } +   } +} -   COMPUTE_LINEAR_MIPMAP_LEVEL(tObj, lambda, level); -   if (level >= tObj->_MaxLevel) { -      sample_2d_linear(ctx, tObj, tObj->Image[tObj->_MaxLevel], texcoord, rgba); -   } -   else { -      GLchan t0[4], t1[4];  /* texels */ -      const GLfloat f = FRAC(lambda); -      sample_2d_linear(ctx, tObj, tObj->Image[level  ], texcoord, t0); -      sample_2d_linear(ctx, tObj, tObj->Image[level+1], texcoord, t1); -      rgba[RCOMP] = (GLchan) INTCAST ((1.0F-f) * t0[RCOMP] + f * t1[RCOMP]); -      rgba[GCOMP] = (GLchan) INTCAST ((1.0F-f) * t0[GCOMP] + f * t1[GCOMP]); -      rgba[BCOMP] = (GLchan) INTCAST ((1.0F-f) * t0[BCOMP] + f * t1[BCOMP]); -      rgba[ACOMP] = (GLchan) INTCAST ((1.0F-f) * t0[ACOMP] + f * t1[ACOMP]); +static void +sample_2d_linear_mipmap_linear_repeat( GLcontext *ctx, +                                       const struct gl_texture_object *tObj, +                                       GLuint n, GLfloat texcoord[][4], +                                       const GLfloat lambda[], GLchan rgba[][4] ) +{ +   GLuint i; +   ASSERT(tObj->WrapS == GL_REPEAT); +   ASSERT(tObj->WrapT == GL_REPEAT); +   for (i = 0; i < n; i++) { +      GLint level; +      COMPUTE_LINEAR_MIPMAP_LEVEL(tObj, lambda[i], level); +      if (level >= tObj->_MaxLevel) { +         sample_2d_linear_repeat(ctx, tObj, tObj->Image[tObj->_MaxLevel], +                                 texcoord[i], rgba[i]); +      } +      else { +         GLchan t0[4], t1[4];  /* texels */ +         const GLfloat f = FRAC(lambda[i]); +         sample_2d_linear_repeat(ctx, tObj, tObj->Image[level  ], texcoord[i], t0); +         sample_2d_linear_repeat(ctx, tObj, tObj->Image[level+1], texcoord[i], t1); +         rgba[i][RCOMP] = (GLchan) INTCAST ((1.0F-f) * t0[RCOMP] + f * t1[RCOMP]); +         rgba[i][GCOMP] = (GLchan) INTCAST ((1.0F-f) * t0[GCOMP] + f * t1[GCOMP]); +         rgba[i][BCOMP] = (GLchan) INTCAST ((1.0F-f) * t0[BCOMP] + f * t1[BCOMP]); +         rgba[i][ACOMP] = (GLchan) INTCAST ((1.0F-f) * t0[ACOMP] + f * t1[ACOMP]); +      }     }  } -  static void  sample_nearest_2d( GLcontext *ctx, GLuint texUnit,                     const struct gl_texture_object *tObj, GLuint n, @@ -970,8 +1101,16 @@ sample_lambda_2d( GLcontext *ctx, GLuint texUnit,                    GLuint n, GLfloat texcoords[][4],                    const GLfloat lambda[], GLchan rgba[][4] )  { +   const struct gl_texture_image *tImg = tObj->Image[tObj->BaseLevel];     const GLfloat minMagThresh = SWRAST_CONTEXT(ctx)->_MinMagThresh[texUnit];     GLuint i; +   GLint minStart, minEnd;  /* texels with minification */ +   GLint magStart, magEnd;  /* texels with magnification */ + +   const GLboolean repeatNoBorder = (tObj->WrapS == GL_REPEAT) +      && (tObj->WrapT == GL_REPEAT) +      && (tImg->Border == 0) +      && (tImg->Format != GL_COLOR_INDEX);  #ifdef DEBUG     ASSERT (span_is_monotonous(n, lambda) == GL_TRUE); @@ -980,84 +1119,148 @@ sample_lambda_2d( GLcontext *ctx, GLuint texUnit,     /* since lambda is monotonous-array use this check first */     if (lambda[0] <= minMagThresh && lambda[n-1] <= minMagThresh) {        /* magnification for whole span */ -      const struct gl_texture_image *img = tObj->Image[tObj->BaseLevel]; -      switch (tObj->MagFilter) { +      magStart = 0; +      magEnd = n; +      minStart = minEnd = 0; +   } +   else if (lambda[0] > minMagThresh && lambda[n-1] > minMagThresh) { +      /* minification for whole span */ +      minStart = 0; +      minEnd = n; +      magStart = magEnd = 0; +   } +   else { +      /* a mix of minification and magnification */ +      if (lambda[0] > minMagThresh) { +         /* start with minification */ +         for (i = 1; i < n; i++) { +            if (lambda[i] <= minMagThresh) +               break; +         } +         minStart = 0; +         minEnd = i; +         magStart = i; +         magEnd = n; +      } +      else { +         /* start with magnification */ +         for (i = 1; i < n; i++) { +            if (lambda[i] <= minMagThresh) +               break; +         } +         magStart = 0; +         magEnd = i; +         minStart = i; +         minEnd = n; +      } +   } + +#ifdef DEBUG +   /* Verify the min/mag Start/End values */ +   { +      GLint i; +      for (i = 0; i < n; i++) { +         if (lambda[i] > minMagThresh) { +            /* minification */ +            assert(i >= minStart); +            assert(i < minEnd); +         } +         else { +            /* magnification */ +            assert(i >= magStart); +            assert(i < magEnd); +         } +      } +   } +#endif + +   if (minStart < minEnd) { +      /* do the minified texels */ +      const GLuint m = (GLuint) (minEnd - minStart); +      switch (tObj->MinFilter) {        case GL_NEAREST: -         if (tObj->WrapS == GL_REPEAT && tObj->WrapT == GL_REPEAT && -             img->Border == 0) { -            switch (img->Format) { +         if (repeatNoBorder) { +            switch (tImg->Format) {              case GL_RGB: -               opt_sample_rgb_2d(ctx, texUnit, tObj, n, texcoords, -                                 NULL, rgba); +               opt_sample_rgb_2d(ctx, texUnit, tObj, m, texcoords + minStart, +                                 NULL, rgba + minStart);                 break;              case GL_RGBA: -	       opt_sample_rgba_2d(ctx, texUnit, tObj, n, texcoords, -                                  NULL, rgba); +	       opt_sample_rgba_2d(ctx, texUnit, tObj, m, texcoords + minStart, +                                  NULL, rgba + minStart);                 break;              default: -               sample_nearest_2d(ctx, texUnit, tObj, n, texcoords, -                                 NULL, rgba); +               sample_nearest_2d(ctx, texUnit, tObj, m, texcoords + minStart, +                                 NULL, rgba + minStart );              }           }           else { -            sample_nearest_2d(ctx, texUnit, tObj, n, texcoords, -                              NULL, rgba); +            sample_nearest_2d(ctx, texUnit, tObj, m, texcoords + minStart, +                              NULL, rgba + minStart);           }           break;        case GL_LINEAR: -	 sample_linear_2d(ctx, texUnit, tObj, n, texcoords, -			  NULL, rgba); +	 sample_linear_2d(ctx, texUnit, tObj, m, texcoords + minStart, +			  NULL, rgba + minStart); +         break; +      case GL_NEAREST_MIPMAP_NEAREST: +         sample_2d_nearest_mipmap_nearest(ctx, tObj, m, texcoords + minStart, +                                          lambda + minStart, rgba + minStart); +         break; +      case GL_LINEAR_MIPMAP_NEAREST: +         sample_2d_linear_mipmap_nearest(ctx, tObj, m, texcoords + minStart, +                                         lambda + minStart, rgba + minStart); +         break; +      case GL_NEAREST_MIPMAP_LINEAR: +         sample_2d_nearest_mipmap_linear(ctx, tObj, m, texcoords + minStart, +                                         lambda + minStart, rgba + minStart); +         break; +      case GL_LINEAR_MIPMAP_LINEAR: +         if (repeatNoBorder) +            sample_2d_linear_mipmap_linear_repeat(ctx, tObj, m, +                  texcoords + minStart, lambda + minStart, rgba + minStart); +         else +            sample_2d_linear_mipmap_linear(ctx, tObj, m, texcoords + minStart, +                                        lambda + minStart, rgba + minStart);           break;        default: -         _mesa_problem(NULL, "Bad mag filter in sample_lambda_2d"); +         _mesa_problem(NULL, "Bad min filter in sample_2d_texture"); +         return;        }     } -   else { -      const struct gl_texture_image *tImg = tObj->Image[tObj->BaseLevel]; -      for (i = 0; i < n; i++) { -         if (lambda[i] > minMagThresh) { -            /* minification */ -            switch (tObj->MinFilter) { -               case GL_NEAREST: -                  sample_2d_nearest(ctx, tObj, tImg, texcoords[i], rgba[i]); -                  break; -               case GL_LINEAR: -                  sample_2d_linear(ctx, tObj, tImg, texcoords[i], rgba[i]); -                  break; -               case GL_NEAREST_MIPMAP_NEAREST: -                  sample_2d_nearest_mipmap_nearest(ctx, tObj, texcoords[i], -                                                   lambda[i], rgba[i]); -                  break; -               case GL_LINEAR_MIPMAP_NEAREST: -                  sample_2d_linear_mipmap_nearest(ctx, tObj, texcoords[i], -                                                  lambda[i], rgba[i]); -                  break; -               case GL_NEAREST_MIPMAP_LINEAR: -                  sample_2d_nearest_mipmap_linear(ctx, tObj, texcoords[i], -                                                  lambda[i], rgba[i]); -                  break; -               case GL_LINEAR_MIPMAP_LINEAR: -                  sample_2d_linear_mipmap_linear(ctx, tObj, texcoords[i], -                                                 lambda[i], rgba[i] ); -                  break; -               default: -                  _mesa_problem(NULL, "Bad min filter in sample_2d_texture"); -                  return; + +   if (magStart < magEnd) { +      /* do the magnified texels */ +      const GLuint m = (GLuint) (magEnd - magStart); + +      switch (tObj->MagFilter) { +      case GL_NEAREST: +         if (repeatNoBorder) { +            switch (tImg->Format) { +            case GL_RGB: +               opt_sample_rgb_2d(ctx, texUnit, tObj, m, texcoords + magStart, +                                 NULL, rgba + magStart); +               break; +            case GL_RGBA: +	       opt_sample_rgba_2d(ctx, texUnit, tObj, m, texcoords + magStart, +                                  NULL, rgba + magStart); +               break; +            default: +               sample_nearest_2d(ctx, texUnit, tObj, m, texcoords + magStart, +                                 NULL, rgba + magStart );              }           }           else { -            /* magnification */ -            switch (tObj->MagFilter) { -               case GL_NEAREST: -                  sample_2d_nearest(ctx, tObj, tImg, texcoords[i], rgba[i]); -                  break; -               case GL_LINEAR: -                  sample_2d_linear(ctx, tObj, tImg, texcoords[i], rgba[i] ); -                  break; -               default: -                  _mesa_problem(NULL, "Bad mag filter in sample_2d_texture"); -            } +            sample_nearest_2d(ctx, texUnit, tObj, m, texcoords + magStart, +                              NULL, rgba + magStart);           } +         break; +      case GL_LINEAR: +	 sample_linear_2d(ctx, texUnit, tObj, m, texcoords + magStart, +			  NULL, rgba + magStart); +         break; +      default: +         _mesa_problem(NULL, "Bad mag filter in sample_lambda_2d");        }     }  } | 
