diff options
| author | Brian Paul <brian.paul@tungstengraphics.com> | 2002-03-16 18:02:07 +0000 | 
|---|---|---|
| committer | Brian Paul <brian.paul@tungstengraphics.com> | 2002-03-16 18:02:07 +0000 | 
| commit | 31f12f504e61cb2ad65b8890a68eb7154edcb64b (patch) | |
| tree | b053c091613eabf44359e7dfa4e542f3bc1ebaae /src | |
| parent | bc6b60c4ff81c4d677251e4c7262c0df26cda6a6 (diff) | |
New mipmap lambda calculation.  Previously, trilinear filtering could
result in _very_ blurry textures.  Still need to do some optimization
of the new code in s_span.c
Diffstat (limited to 'src')
| -rw-r--r-- | src/mesa/swrast/s_aatriangle.c | 46 | ||||
| -rw-r--r-- | src/mesa/swrast/s_aatritemp.h | 23 | ||||
| -rw-r--r-- | src/mesa/swrast/s_pointtemp.h | 12 | ||||
| -rw-r--r-- | src/mesa/swrast/s_span.c | 259 | ||||
| -rw-r--r-- | src/mesa/swrast/s_texture.c | 32 | ||||
| -rw-r--r-- | src/mesa/swrast/s_triangle.c | 71 | ||||
| -rw-r--r-- | src/mesa/swrast/s_tritemp.h | 149 | 
7 files changed, 265 insertions, 327 deletions
| diff --git a/src/mesa/swrast/s_aatriangle.c b/src/mesa/swrast/s_aatriangle.c index 0162319a66..ea939a5369 100644 --- a/src/mesa/swrast/s_aatriangle.c +++ b/src/mesa/swrast/s_aatriangle.c @@ -1,10 +1,10 @@ -/* $Id: s_aatriangle.c,v 1.22 2002/01/27 18:32:03 brianp Exp $ */ +/* $Id: s_aatriangle.c,v 1.23 2002/03/16 18:02:07 brianp Exp $ */  /*   * Mesa 3-D graphics library - * Version:  4.0.1 + * Version:  4.1   * - * Copyright (C) 1999-2001  Brian Paul   All Rights Reserved. + * Copyright (C) 1999-2002  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"), @@ -124,7 +124,6 @@ solve_plane_recip(GLfloat x, GLfloat y, const GLfloat plane[4])  } -  /*   * Solve plane and return clamped GLchan value.   */ @@ -352,23 +351,36 @@ index_aa_tri(GLcontext *ctx,  /*   * Compute mipmap level of detail. + * XXX we should really include the R coordinate in this computation + * in order to do 3-D texture mipmapping.   */  static INLINE GLfloat  compute_lambda(const GLfloat sPlane[4], const GLfloat tPlane[4], -               GLfloat invQ, GLfloat width, GLfloat height) +               const GLfloat qPlane[4], GLfloat cx, GLfloat cy, +               GLfloat invQ, GLfloat texWidth, GLfloat texHeight)  { -   GLfloat dudx = sPlane[0] / sPlane[2] * invQ * width; -   GLfloat dudy = sPlane[1] / sPlane[2] * invQ * width; -   GLfloat dvdx = tPlane[0] / tPlane[2] * invQ * height; -   GLfloat dvdy = tPlane[1] / tPlane[2] * invQ * height; -   GLfloat r1 = dudx * dudx + dudy * dudy; -   GLfloat r2 = dvdx * dvdx + dvdy * dvdy; -   GLfloat rho2 = r1 + r2; -   /* return log base 2 of rho */ -   if (rho2 == 0.0F) -      return 0.0; -   else -      return (GLfloat) (log(rho2) * 1.442695 * 0.5); /* 1.442695 = 1/log(2) */ +   const GLfloat s = solve_plane(cx, cy, sPlane); +   const GLfloat t = solve_plane(cx, cy, tPlane); +   const GLfloat invQ_x1 = solve_plane_recip(cx+1.0, cy, qPlane); +   const GLfloat invQ_y1 = solve_plane_recip(cx, cy+1.0, qPlane); +   const GLfloat s_x1 = s - sPlane[0] / sPlane[2]; +   const GLfloat s_y1 = s - sPlane[1] / sPlane[2]; +   const GLfloat t_x1 = t - tPlane[0] / tPlane[2]; +   const GLfloat t_y1 = t - tPlane[1] / tPlane[2]; +   GLfloat dsdx = s_x1 * invQ_x1 - s * invQ; +   GLfloat dsdy = s_y1 * invQ_y1 - s * invQ; +   GLfloat dtdx = t_x1 * invQ_x1 - t * invQ; +   GLfloat dtdy = t_y1 * invQ_y1 - t * invQ; +   GLfloat maxU, maxV, rho, lambda; +   dsdx = FABSF(dsdx); +   dsdy = FABSF(dsdy); +   dtdx = FABSF(dtdx); +   dtdy = FABSF(dtdy); +   maxU = MAX2(dsdx, dsdy) * texWidth; +   maxV = MAX2(dtdx, dtdy) * texHeight; +   rho = MAX2(maxU, maxV); +   lambda = LOG2(rho); +   return lambda;  } diff --git a/src/mesa/swrast/s_aatritemp.h b/src/mesa/swrast/s_aatritemp.h index 90b8fe74e3..2fd59b2323 100644 --- a/src/mesa/swrast/s_aatritemp.h +++ b/src/mesa/swrast/s_aatritemp.h @@ -1,4 +1,4 @@ -/* $Id: s_aatritemp.h,v 1.26 2002/01/28 03:42:28 brianp Exp $ */ +/* $Id: s_aatritemp.h,v 1.27 2002/03/16 18:02:07 brianp Exp $ */  /*   * Mesa 3-D graphics library @@ -76,10 +76,10 @@     GLfloat sPlane[4], tPlane[4], uPlane[4], vPlane[4];     GLfloat texWidth, texHeight;  #elif defined(DO_MULTITEX) -   GLfloat sPlane[MAX_TEXTURE_UNITS][4]; -   GLfloat tPlane[MAX_TEXTURE_UNITS][4]; -   GLfloat uPlane[MAX_TEXTURE_UNITS][4]; -   GLfloat vPlane[MAX_TEXTURE_UNITS][4]; +   GLfloat sPlane[MAX_TEXTURE_UNITS][4];  /* texture S */ +   GLfloat tPlane[MAX_TEXTURE_UNITS][4];  /* texture T */ +   GLfloat uPlane[MAX_TEXTURE_UNITS][4];  /* texture R */ +   GLfloat vPlane[MAX_TEXTURE_UNITS][4];  /* texture Q */     GLfloat texWidth[MAX_TEXTURE_UNITS], texHeight[MAX_TEXTURE_UNITS];  #endif     GLfloat bf = SWRAST_CONTEXT(ctx)->_backface_sign; @@ -316,7 +316,8 @@                 span.texcoords[0][count][0] = solve_plane(cx, cy, sPlane) * invQ;                 span.texcoords[0][count][1] = solve_plane(cx, cy, tPlane) * invQ;                 span.texcoords[0][count][2] = solve_plane(cx, cy, uPlane) * invQ; -               span.lambda[0][count] = compute_lambda(sPlane, tPlane, invQ, +               span.lambda[0][count] = compute_lambda(sPlane, tPlane, vPlane, +                                                      cx, cy, invQ,                                                        texWidth, texHeight);              }  #elif defined(DO_MULTITEX) @@ -329,7 +330,8 @@                       span.texcoords[unit][count][1] = solve_plane(cx, cy, tPlane[unit]) * invQ;                       span.texcoords[unit][count][2] = solve_plane(cx, cy, uPlane[unit]) * invQ;                       span.lambda[unit][count] = compute_lambda(sPlane[unit], -                                                               tPlane[unit], invQ, texWidth[unit], texHeight[unit]); +                                      tPlane[unit], vPlane[unit], cx, cy, invQ, +                                      texWidth[unit], texHeight[unit]);                    }                 }              } @@ -419,8 +421,8 @@                 span.texcoords[0][ix][0] = solve_plane(cx, cy, sPlane) * invQ;                 span.texcoords[0][ix][1] = solve_plane(cx, cy, tPlane) * invQ;                 span.texcoords[0][ix][2] = solve_plane(cx, cy, uPlane) * invQ; -               span.lambda[0][ix] = compute_lambda(sPlane, tPlane, invQ, -                                              texWidth, texHeight); +               span.lambda[0][ix] = compute_lambda(sPlane, tPlane, vPlane, +                                          cx, cy, invQ, texWidth, texHeight);              }  #elif defined(DO_MULTITEX)              { @@ -433,7 +435,8 @@                       span.texcoords[unit][ix][2] = solve_plane(cx, cy, uPlane[unit]) * invQ;                       span.lambda[unit][ix] = compute_lambda(sPlane[unit],                                                              tPlane[unit], -                                                            invQ, +                                                            vPlane[unit], +                                                            cx, cy, invQ,                                                              texWidth[unit],                                                              texHeight[unit]);                    } diff --git a/src/mesa/swrast/s_pointtemp.h b/src/mesa/swrast/s_pointtemp.h index 02dc9fee2c..8fa608f824 100644 --- a/src/mesa/swrast/s_pointtemp.h +++ b/src/mesa/swrast/s_pointtemp.h @@ -1,4 +1,4 @@ -/* $Id: s_pointtemp.h,v 1.12 2002/02/02 17:24:11 brianp Exp $ */ +/* $Id: s_pointtemp.h,v 1.13 2002/03/16 18:02:08 brianp Exp $ */  /*   * Mesa 3-D graphics library @@ -120,7 +120,6 @@ NAME ( GLcontext *ctx, const SWvertex *vert )  #endif  #if FLAGS & TEXTURE     span.interpMask |= SPAN_TEXTURE; -   span.arrayMask |= SPAN_LAMBDA;     for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {        if (ctx->Texture.Unit[u]._ReallyEnabled) {           const GLfloat q = vert->texcoord[u][3]; @@ -129,11 +128,10 @@ NAME ( GLcontext *ctx, const SWvertex *vert )           span.tex[u][1] = vert->texcoord[u][1] * invQ;           span.tex[u][2] = vert->texcoord[u][2] * invQ;           span.tex[u][3] = q; -         span.texStep[u][0] = 0.0; -         span.texStep[u][1] = 0.0; -         span.texStep[u][2] = 0.0; -         span.texStep[u][3] = 0.0; -         span.rho[u] = 0.0; +         span.texStepX[u][0] = span.texStepY[u][0] = 0.0; +         span.texStepX[u][1] = span.texStepY[u][1] = 0.0; +         span.texStepX[u][2] = span.texStepY[u][2] = 0.0; +         span.texStepX[u][3] = span.texStepY[u][3] = 0.0;        }     }  #endif diff --git a/src/mesa/swrast/s_span.c b/src/mesa/swrast/s_span.c index 90de11b86a..2ce8b76cf5 100644 --- a/src/mesa/swrast/s_span.c +++ b/src/mesa/swrast/s_span.c @@ -1,4 +1,4 @@ -/* $Id: s_span.c,v 1.36 2002/02/17 17:30:57 brianp Exp $ */ +/* $Id: s_span.c,v 1.37 2002/03/16 18:02:08 brianp Exp $ */  /*   * Mesa 3-D graphics library @@ -36,6 +36,7 @@  #include "colormac.h"  #include "context.h"  #include "macros.h" +#include "mmath.h"  #include "mem.h"  #include "s_alpha.h" @@ -263,52 +264,51 @@ _mesa_span_interpolate_z( const GLcontext *ctx, struct sw_span *span )  /* - * Return log_base_2(x) / 2. - * We divide by two here since we didn't square rho in the triangle function. + * This the ideal solution, as given in the OpenGL spec.   */ -#ifdef USE_IEEE -  #if 0 -/* This is pretty fast, but not accurate enough (only 2 fractional bits). - * Based on code from http://www.stereopsis.com/log2.html - */ -static INLINE GLfloat HALF_LOG2(GLfloat x) +static GLfloat +compute_lambda(GLfloat dsdx, GLfloat dsdy, GLfloat dtdx, GLfloat dtdy, +               GLfloat dqdx, GLfloat dqdy, GLfloat texW, GLfloat texH, +               GLfloat s, GLfloat t, GLfloat q, GLfloat invQ)  { -   const GLfloat y = x * x * x * x; -   const GLuint ix = *((GLuint *) &y); -   const GLuint exp = (ix >> 23) & 0xFF; -   const GLint log2 = ((GLint) exp) - 127; -   return (GLfloat) log2 * (0.5 / 4.0);  /* 4, because of x^4 above */ +   GLfloat dudx = texW * ((s + dsdx) / (q + dqdx) - s * invQ); +   GLfloat dvdx = texH * ((t + dtdx) / (q + dqdx) - t * invQ); +   GLfloat dudy = texW * ((s + dsdy) / (q + dqdy) - s * invQ); +   GLfloat dvdy = texH * ((t + dtdy) / (q + dqdy) - t * invQ); +   GLfloat x = sqrt(dudx * dudx + dvdx * dvdx); +   GLfloat y = sqrt(dudy * dudy + dvdy * dvdy); +   GLfloat rho = MAX2(x, y); +   GLfloat lambda = LOG2(rho); +   return lambda;  }  #endif -/* Pretty fast, and accurate. - * Based on code from http://www.flipcode.com/totd/ + +/* + * This is a faster approximation   */ -static INLINE GLfloat HALF_LOG2(GLfloat val) +static GLfloat +compute_lambda(GLfloat dsdx, GLfloat dsdy, GLfloat dtdx, GLfloat dtdy, +               GLfloat dqdx, GLfloat dqdy, GLfloat texW, GLfloat texH, +               GLfloat s, GLfloat t, GLfloat q, GLfloat invQ)  { -   GLint *exp_ptr = (GLint *) &val; -   GLint x = *exp_ptr; -   const GLint log_2 = ((x >> 23) & 255) - 128; -   x &= ~(255 << 23); -   x += 127 << 23; -   *exp_ptr = x; -   val = ((-1.0f/3) * val + 2) * val - 2.0f/3; -   return 0.5F * (val + log_2); +   GLfloat dsdx2 = (s + dsdx) / (q + dqdx) - s * invQ; +   GLfloat dtdx2 = (t + dtdx) / (q + dqdx) - t * invQ; +   GLfloat dsdy2 = (s + dsdy) / (q + dqdy) - s * invQ; +   GLfloat dtdy2 = (t + dtdy) / (q + dqdy) - t * invQ; +   GLfloat maxU, maxV, rho, lambda; +   dsdx2 = FABSF(dsdx2); +   dsdy2 = FABSF(dsdy2); +   dtdx2 = FABSF(dtdx2); +   dtdy2 = FABSF(dtdy2); +   maxU = MAX2(dsdx2, dsdy2) * texW; +   maxV = MAX2(dtdx2, dtdy2) * texH; +   rho = MAX2(maxU, maxV); +   lambda = LOG2(rho); +   return lambda;  } -#else /* USE_IEEE */ - -/* Slow, portable solution. - * NOTE: log_base_2(x) = log(x) / log(2) - * NOTE: 1.442695 = 1/log(2). - */ -#define HALF_LOG2(x)  ((GLfloat) (log(x) * (1.442695F * 0.5F))) - -#endif /* USE_IEEE */ - - -  /*   * Fill in the span.texcoords array from the interpolation values.   * XXX We could optimize here for the case when dq = 0.  That would @@ -320,76 +320,64 @@ interpolate_texcoords(GLcontext *ctx, struct sw_span *span)     ASSERT(span->interpMask & SPAN_TEXTURE);     if (ctx->Texture._ReallyEnabled & ~TEXTURE0_ANY) { -      if (span->interpMask & SPAN_LAMBDA) { -         /* multitexture, lambda */ -         GLuint u; -         for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { -            if (ctx->Texture.Unit[u]._ReallyEnabled) { -               const GLfloat rho = span->rho[u]; -               const GLfloat ds = span->texStep[u][0]; -               const GLfloat dt = span->texStep[u][1]; -               const GLfloat dr = span->texStep[u][2]; -               const GLfloat dq = span->texStep[u][3]; +      /* multitexture */ +      GLuint u; +      for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { +         if (ctx->Texture.Unit[u]._ReallyEnabled) { +            const struct gl_texture_object *obj =ctx->Texture.Unit[u]._Current; +            const struct gl_texture_image *img = obj->Image[obj->BaseLevel]; +            GLboolean needLambda = (obj->MinFilter != obj->MagFilter); +            if (needLambda) { +               const GLfloat texW = (GLfloat) img->Width; +               const GLfloat texH = (GLfloat) img->Height; +               const GLfloat dsdx = span->texStepX[u][0]; +               const GLfloat dsdy = span->texStepY[u][0]; +               const GLfloat dtdx = span->texStepX[u][1]; +               const GLfloat dtdy = span->texStepY[u][1]; +               const GLfloat drdx = span->texStepX[u][2]; +               const GLfloat dqdx = span->texStepX[u][3]; +               const GLfloat dqdy = span->texStepY[u][3];                 GLfloat s = span->tex[u][0];                 GLfloat t = span->tex[u][1];                 GLfloat r = span->tex[u][2];                 GLfloat q = span->tex[u][3];                 GLuint i; -               if (dq == 0.0) { -                  /* Ortho projection or polygon's parallel to window X axis */ +               for (i = 0; i < span->end; i++) {                    const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q); -                  const GLfloat lambda = HALF_LOG2(rho * invQ * invQ); -                  for (i = 0; i < span->end; i++) { -                     span->texcoords[u][i][0] = s * invQ; -                     span->texcoords[u][i][1] = t * invQ; -                     span->texcoords[u][i][2] = r * invQ; -                     span->lambda[u][i] = lambda; -                     s += ds; -                     t += dt; -                     r += dr; -                  } -               } -               else { -                  for (i = 0; i < span->end; i++) { -                     const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q); -                     span->texcoords[u][i][0] = s * invQ; -                     span->texcoords[u][i][1] = t * invQ; -                     span->texcoords[u][i][2] = r * invQ; -                     span->lambda[u][i] = HALF_LOG2(rho * invQ * invQ); -                     s += ds; -                     t += dt; -                     r += dr; -                     q += dq; -                  } +                  span->texcoords[u][i][0] = s * invQ; +                  span->texcoords[u][i][1] = t * invQ; +                  span->texcoords[u][i][2] = r * invQ; +                  span->lambda[u][i] = compute_lambda(dsdx, dsdy, dtdx, dtdy, +                                                      dqdx, dqdy, texW, texH, +                                                      s, t, q, invQ); +                  s += dsdx; +                  t += dtdx; +                  r += drdx; +                  q += dqdx;                 } +               span->arrayMask |= SPAN_LAMBDA;              } -         } -         span->arrayMask |= SPAN_LAMBDA; -      } -      else { -         /* multitexture, no lambda */ -         GLuint u; -         for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { -            if (ctx->Texture.Unit[u]._ReallyEnabled) { -               const GLfloat ds = span->texStep[u][0]; -               const GLfloat dt = span->texStep[u][1]; -               const GLfloat dr = span->texStep[u][2]; -               const GLfloat dq = span->texStep[u][3]; +            else { +               const GLfloat dsdx = span->texStepX[u][0]; +               const GLfloat dtdx = span->texStepX[u][1]; +               const GLfloat drdx = span->texStepX[u][2]; +               const GLfloat dqdx = span->texStepX[u][3];                 GLfloat s = span->tex[u][0];                 GLfloat t = span->tex[u][1];                 GLfloat r = span->tex[u][2];                 GLfloat q = span->tex[u][3];                 GLuint i; -               if (dq == 0.0) { +               if (dqdx == 0.0) {                    /* Ortho projection or polygon's parallel to window X axis */                    const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q);                    for (i = 0; i < span->end; i++) {                       span->texcoords[u][i][0] = s * invQ;                       span->texcoords[u][i][1] = t * invQ;                       span->texcoords[u][i][2] = r * invQ; -                     s += ds; -                     t += dt; -                     r += dr; +                     span->lambda[u][i] = 0.0; +                     s += dsdx; +                     t += dtdx; +                     r += drdx;                    }                 }                 else { @@ -398,79 +386,74 @@ interpolate_texcoords(GLcontext *ctx, struct sw_span *span)                       span->texcoords[u][i][0] = s * invQ;                       span->texcoords[u][i][1] = t * invQ;                       span->texcoords[u][i][2] = r * invQ; -                     s += ds; -                     t += dt; -                     r += dr; -                     q += dq; +                     span->lambda[u][i] = 0.0; +                     s += dsdx; +                     t += dtdx; +                     r += drdx; +                     q += dqdx;                    }                 } -            } -         } -      } +            } /* lambda */ +         } /* if */ +      } /* for */     }     else { -      if (span->interpMask & SPAN_LAMBDA) { +      /* single texture */ +      const struct gl_texture_object *obj = ctx->Texture.Unit[0]._Current; +      const struct gl_texture_image *img = obj->Image[obj->BaseLevel]; +      GLboolean needLambda = (obj->MinFilter != obj->MagFilter); +      if (needLambda) {           /* just texture unit 0, with lambda */ -         const GLfloat rho = span->rho[0]; -         const GLfloat ds = span->texStep[0][0]; -         const GLfloat dt = span->texStep[0][1]; -         const GLfloat dr = span->texStep[0][2]; -         const GLfloat dq = span->texStep[0][3]; +         const GLfloat texW = (GLfloat) img->Width; +         const GLfloat texH = (GLfloat) img->Height; +         const GLfloat dsdx = span->texStepX[0][0]; +         const GLfloat dsdy = span->texStepY[0][0]; +         const GLfloat dtdx = span->texStepX[0][1]; +         const GLfloat dtdy = span->texStepY[0][1]; +         const GLfloat drdx = span->texStepX[0][2]; +         const GLfloat dqdx = span->texStepX[0][3]; +         const GLfloat dqdy = span->texStepY[0][3];           GLfloat s = span->tex[0][0];           GLfloat t = span->tex[0][1];           GLfloat r = span->tex[0][2];           GLfloat q = span->tex[0][3];           GLuint i; -         if (dq == 0.0) { -            /* Ortho projection or polygon's parallel to window X axis */ +         for (i = 0; i < span->end; i++) {              const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q); -            const GLfloat lambda = HALF_LOG2(rho * invQ * invQ); -            for (i = 0; i < span->end; i++) { -               span->texcoords[0][i][0] = s * invQ; -               span->texcoords[0][i][1] = t * invQ; -               span->texcoords[0][i][2] = r * invQ; -               span->lambda[0][i] = lambda; -               s += ds; -               t += dt; -               r += dr; -            } -         } -         else { -            for (i = 0; i < span->end; i++) { -               const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q); -               span->texcoords[0][i][0] = s * invQ; -               span->texcoords[0][i][1] = t * invQ; -               span->texcoords[0][i][2] = r * invQ; -               span->lambda[0][i] = HALF_LOG2(rho * invQ * invQ); -               s += ds; -               t += dt; -               r += dr; -               q += dq; -            } +            span->lambda[0][i] = compute_lambda(dsdx, dsdy, dtdx, dtdy, +                                                dqdx, dqdy, texW, texH, +                                                s, t, q, invQ); +            span->texcoords[0][i][0] = s * invQ; +            span->texcoords[0][i][1] = t * invQ; +            span->texcoords[0][i][2] = r * invQ; +            s += dsdx; +            t += dtdx; +            r += drdx; +            q += dqdx;           }           span->arrayMask |= SPAN_LAMBDA;        }        else {           /* just texture 0, without lambda */ -         const GLfloat ds = span->texStep[0][0]; -         const GLfloat dt = span->texStep[0][1]; -         const GLfloat dr = span->texStep[0][2]; -         const GLfloat dq = span->texStep[0][3]; +         const GLfloat dsdx = span->texStepX[0][0]; +         const GLfloat dtdx = span->texStepX[0][1]; +         const GLfloat drdx = span->texStepX[0][2]; +         const GLfloat dqdx = span->texStepX[0][3];           GLfloat s = span->tex[0][0];           GLfloat t = span->tex[0][1];           GLfloat r = span->tex[0][2];           GLfloat q = span->tex[0][3];           GLuint i; -         if (dq == 0.0) { +         if (dqdx == 0.0) {              /* Ortho projection or polygon's parallel to window X axis */              const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q);              for (i = 0; i < span->end; i++) {                 span->texcoords[0][i][0] = s * invQ;                 span->texcoords[0][i][1] = t * invQ;                 span->texcoords[0][i][2] = r * invQ; -               s += ds; -               t += dt; -               r += dr; +               s += dsdx; +               t += dtdx; +               r += drdx;              }           }           else { @@ -479,10 +462,10 @@ interpolate_texcoords(GLcontext *ctx, struct sw_span *span)                 span->texcoords[0][i][0] = s * invQ;                 span->texcoords[0][i][1] = t * invQ;                 span->texcoords[0][i][2] = r * invQ; -               s += ds; -               t += dt; -               r += dr; -               q += dq; +               s += dsdx; +               t += dtdx; +               r += drdx; +               q += dqdx;              }           }        } diff --git a/src/mesa/swrast/s_texture.c b/src/mesa/swrast/s_texture.c index 4360429130..a487bd8970 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.55 2002/03/08 00:09:18 brianp Exp $ */ +/* $Id: s_texture.c,v 1.56 2002/03/16 18:02:08 brianp Exp $ */  /*   * Mesa 3-D graphics library @@ -310,18 +310,22 @@ compute_min_mag_ranges( GLfloat minMagThresh, GLuint n, const GLfloat lambda[],                          GLuint *magStart, GLuint *magEnd )  {     ASSERT(lambda != NULL); -#ifdef DEBUG -   /* verify that lambda[] is monotonous */ +#if 0 +   /* Verify that lambda[] is monotonous. +    * We can't really use this because the inaccuracy in the LOG2 function +    * causes this test to fail, yet the resulting texturing is correct. +    */     if (n > 1) {        GLuint i; +      printf("lambda delta = %g\n", lambda[0] - lambda[n-1]);        if (lambda[0] >= lambda[n-1]) { /* decreasing */           for (i = 0; i < n - 1; i++) { -            ASSERT((GLint) (lambda[i] * 100) >= (GLint) (lambda[i+1] * 100)); +            ASSERT((GLint) (lambda[i] * 10) >= (GLint) (lambda[i+1] * 10));           }        }        else { /* increasing */           for (i = 0; i < n - 1; i++) { -            ASSERT((GLint) (lambda[i] * 100) <= (GLint) (lambda[i+1] * 100)); +            ASSERT((GLint) (lambda[i] * 10) <= (GLint) (lambda[i+1] * 10));           }        }     } @@ -367,8 +371,10 @@ compute_min_mag_ranges( GLfloat minMagThresh, GLuint n, const GLfloat lambda[],        }     } -#ifdef DEBUG -   /* Verify the min/mag Start/End values */ +#if 0 +   /* Verify the min/mag Start/End values +    * We don't use this either (see above) +    */     {        GLint i;        for (i = 0; i < n; i++) { @@ -3280,6 +3286,18 @@ _swrast_texture_fragments( GLcontext *ctx, GLuint texUnit, GLuint n,           GLchan texel[MAX_WIDTH][4];           if (lambda) { +#if 0 +            float min, max; +            int i; +            min = max = lambda[0]; +            for (i = 1; i < n; i++) { +               if (lambda[i] > max) +                  max = lambda[i]; +               if (lambda[i] < min) +                  min = lambda[i]; +            } +            printf("min/max %g / %g\n", min, max); +#endif              if (textureUnit->LodBias != 0.0F) {                 /* apply LOD bias, but don't clamp yet */                 GLuint i; diff --git a/src/mesa/swrast/s_triangle.c b/src/mesa/swrast/s_triangle.c index 9bdc203524..1777552617 100644 --- a/src/mesa/swrast/s_triangle.c +++ b/src/mesa/swrast/s_triangle.c @@ -1,4 +1,4 @@ -/* $Id: s_triangle.c,v 1.54 2002/02/02 17:24:11 brianp Exp $ */ +/* $Id: s_triangle.c,v 1.55 2002/03/16 18:02:08 brianp Exp $ */  /*   * Mesa 3-D graphics library @@ -722,13 +722,13 @@ fast_persp_span(GLcontext *ctx, struct sw_span *span,     GLfloat tex_coord[3], tex_step[3];     GLchan *dest = span->color.rgba[0]; -   tex_coord[0] = span->tex[0][0]  * (info->smask + 1), -     tex_step[0] = span->texStep[0][0] * (info->smask + 1); -   tex_coord[1] = span->tex[0][1] * (info->tmask + 1), -     tex_step[1] = span->texStep[0][1] * (info->tmask + 1); +   tex_coord[0] = span->tex[0][0]  * (info->smask + 1); +   tex_step[0] = span->texStepX[0][0] * (info->smask + 1); +   tex_coord[1] = span->tex[0][1] * (info->tmask + 1); +   tex_step[1] = span->texStepX[0][1] * (info->tmask + 1);     /* span->tex[0][2] only if 3D-texturing, here only 2D */ -   tex_coord[2] = span->tex[0][3], -     tex_step[2] = span->texStep[0][3]; +   tex_coord[2] = span->tex[0][3]; +   tex_step[2] = span->texStepX[0][3];     switch (info->filter) {     case GL_NEAREST: @@ -935,43 +935,15 @@ static void general_textured_triangle( GLcontext *ctx,  /* - * Render a smooth-shaded, textured, RGBA triangle. - * Interpolate S,T,R with perspective correction and compute lambda for - * each fragment.  Lambda is used to determine whether to use the - * minification or magnification filter.  If minification and using - * mipmaps, lambda is also used to select the texture level of detail. - */ -static void lambda_textured_triangle( GLcontext *ctx, -				      const SWvertex *v0, -				      const SWvertex *v1, -				      const SWvertex *v2 ) -{ -#define INTERP_Z 1 -#define INTERP_FOG 1 -#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE -#define INTERP_RGB 1 -#define INTERP_SPEC 1 -#define INTERP_ALPHA 1 -#define INTERP_TEX 1 -#define INTERP_LAMBDA 1 - -#define RENDER_SPAN( span )   _mesa_write_texture_span(ctx, &span, GL_POLYGON); - -#include "s_tritemp.h" -} - - -/*   * This is the big one! - * Interpolate Z, RGB, Alpha, specular, fog, and N sets of texture coordinates - * with lambda (LOD). + * Interpolate Z, RGB, Alpha, specular, fog, and N sets of texture coordinates.   * Yup, it's slow.   */  static void -lambda_multitextured_triangle( GLcontext *ctx, -                               const SWvertex *v0, -                               const SWvertex *v1, -                               const SWvertex *v2 ) +multitextured_triangle( GLcontext *ctx, +                        const SWvertex *v0, +                        const SWvertex *v1, +                        const SWvertex *v2 )  {  #define INTERP_Z 1 @@ -981,7 +953,6 @@ lambda_multitextured_triangle( GLcontext *ctx,  #define INTERP_ALPHA 1  #define INTERP_SPEC 1  #define INTERP_MULTITEX 1 -#define INTERP_LAMBDA 1  #define RENDER_SPAN( span )   _mesa_write_texture_span(ctx, &span, GL_POLYGON); @@ -1201,24 +1172,12 @@ _swrast_choose_triangle( GLcontext *ctx )  	    }  	 }           else { -            /* More complicated textures (mipmap, multi-tex, sep specular) */ -            GLboolean needLambda; -            /* if mag filter != min filter we need to compute lambda */ -            const struct gl_texture_object *obj = ctx->Texture.Unit[0]._Current; -            if (obj && obj->MinFilter != obj->MagFilter) -               needLambda = GL_TRUE; -            else -               needLambda = GL_FALSE; +            /* general case textured triangles */              if (ctx->Texture._ReallyEnabled > TEXTURE0_ANY) { -               USE(lambda_multitextured_triangle); +               USE(multitextured_triangle);              }              else { -               if (needLambda) { -		  USE(lambda_textured_triangle); -	       } -               else { -                  USE(general_textured_triangle); -	       } +               USE(general_textured_triangle);              }           }        } diff --git a/src/mesa/swrast/s_tritemp.h b/src/mesa/swrast/s_tritemp.h index 4a602186d7..0c04db9393 100644 --- a/src/mesa/swrast/s_tritemp.h +++ b/src/mesa/swrast/s_tritemp.h @@ -1,4 +1,4 @@ -/* $Id: s_tritemp.h,v 1.34 2002/03/01 04:28:32 brianp Exp $ */ +/* $Id: s_tritemp.h,v 1.35 2002/03/16 18:02:08 brianp Exp $ */  /*   * Mesa 3-D graphics library @@ -43,8 +43,6 @@   *    INTERP_TEX      - if defined, interpolate set 0 float STRQ texcoords   *                         NOTE:  OpenGL STRQ = Mesa STUV (R was taken for red)   *    INTERP_MULTITEX - if defined, interpolate N units of STRQ texcoords - *    INTERP_LAMBDA   - if defined, compute lambda value (for mipmapping) - *                         a lambda value for every texture unit   *    INTERP_FLOAT_RGBA - if defined, interpolate RGBA with floating point   *    INTERP_FLOAT_SPEC - if defined, interpolate specular with floating point   * @@ -317,20 +315,16 @@        GLfloat dtdx, dtdy;  #endif  #ifdef INTERP_TEX -      GLfloat dsdy; -      GLfloat dtdy; -      GLfloat dudy; -      GLfloat dvdy; +      GLfloat dsdx, dsdy; +      GLfloat dtdx, dtdy; +      GLfloat dudx, dudy; +      GLfloat dvdx, dvdy;  #endif  #ifdef INTERP_MULTITEX -      GLfloat dsdy[MAX_TEXTURE_UNITS]; -      GLfloat dtdy[MAX_TEXTURE_UNITS]; -      GLfloat dudy[MAX_TEXTURE_UNITS]; -      GLfloat dvdy[MAX_TEXTURE_UNITS]; -#endif - -#if defined(INTERP_LAMBDA) && !defined(INTERP_TEX) && !defined(INTERP_MULTITEX) -#error "Mipmapping without texturing doesn't make sense." +      GLfloat dsdx[MAX_TEXTURE_UNITS], dsdy[MAX_TEXTURE_UNITS]; +      GLfloat dtdx[MAX_TEXTURE_UNITS], dtdy[MAX_TEXTURE_UNITS]; +      GLfloat dudx[MAX_TEXTURE_UNITS], dudy[MAX_TEXTURE_UNITS]; +      GLfloat dvdx[MAX_TEXTURE_UNITS], dvdy[MAX_TEXTURE_UNITS];  #endif        /* @@ -578,50 +572,35 @@           eMaj_ds = vMax->texcoord[0][0] * wMax - vMin->texcoord[0][0] * wMin;           eBot_ds = vMid->texcoord[0][0] * wMid - vMin->texcoord[0][0] * wMin; -         span.texStep[0][0] = oneOverArea * (eMaj_ds * eBot.dy -                                             - eMaj.dy * eBot_ds); +         dsdx = oneOverArea * (eMaj_ds * eBot.dy - eMaj.dy * eBot_ds);           dsdy = oneOverArea * (eMaj.dx * eBot_ds - eMaj_ds * eBot.dx); +         span.texStepX[0][0] = dsdx; +         span.texStepY[0][0] = dsdy;           eMaj_dt = vMax->texcoord[0][1] * wMax - vMin->texcoord[0][1] * wMin;           eBot_dt = vMid->texcoord[0][1] * wMid - vMin->texcoord[0][1] * wMin; -         span.texStep[0][1] = oneOverArea * (eMaj_dt * eBot.dy -                                             - eMaj.dy * eBot_dt); +         dtdx = oneOverArea * (eMaj_dt * eBot.dy - eMaj.dy * eBot_dt);           dtdy = oneOverArea * (eMaj.dx * eBot_dt - eMaj_dt * eBot.dx); +         span.texStepX[0][1] = dtdx; +         span.texStepY[0][1] = dtdy;           eMaj_du = vMax->texcoord[0][2] * wMax - vMin->texcoord[0][2] * wMin;           eBot_du = vMid->texcoord[0][2] * wMid - vMin->texcoord[0][2] * wMin; -         span.texStep[0][2] = oneOverArea * (eMaj_du * eBot.dy -                                             - eMaj.dy * eBot_du); +         dudx = oneOverArea * (eMaj_du * eBot.dy - eMaj.dy * eBot_du);           dudy = oneOverArea * (eMaj.dx * eBot_du - eMaj_du * eBot.dx); +         span.texStepX[0][2] = dudx; +         span.texStepY[0][2] = dudy;           eMaj_dv = vMax->texcoord[0][3] * wMax - vMin->texcoord[0][3] * wMin;           eBot_dv = vMid->texcoord[0][3] * wMid - vMin->texcoord[0][3] * wMin; -         span.texStep[0][3] = oneOverArea * (eMaj_dv * eBot.dy -                                             - eMaj.dy * eBot_dv); +         dvdx = oneOverArea * (eMaj_dv * eBot.dy - eMaj.dy * eBot_dv);           dvdy = oneOverArea * (eMaj.dx * eBot_dv - eMaj_dv * eBot.dx); +         span.texStepX[0][3] = dvdx; +         span.texStepY[0][3] = dvdy;        } -#  ifdef INTERP_LAMBDA -      { -         const struct gl_texture_object *obj = ctx->Texture.Unit[0]._Current; -         const struct gl_texture_image *texImage = obj->Image[obj->BaseLevel]; -         const GLfloat texWidth = (GLfloat) texImage->Width; -         const GLfloat texHeight = (GLfloat) texImage->Height; -         GLfloat dudx = span.texStep[0][0] * texWidth; -         GLfloat dudy = dsdy * texWidth; -         GLfloat dvdx = span.texStep[0][1] * texHeight; -         GLfloat dvdy = dtdy * texHeight; -         GLfloat r1 = dudx * dudx + dudy * dudy; -         GLfloat r2 = dvdx * dvdx + dvdy * dvdy; -         span.rho[0] = r1 + r2; /* was rho2 = MAX2(r1,r2) */ -         span.interpMask |= SPAN_LAMBDA; -      } -#  endif  #endif  #ifdef INTERP_MULTITEX        span.interpMask |= SPAN_TEXTURE; -#  ifdef INTERP_LAMBDA -      span.interpMask |= SPAN_LAMBDA; -#  endif        {           GLfloat wMax = vMax->win[3];           GLfloat wMin = vMin->win[3]; @@ -637,50 +616,37 @@                         - vMin->texcoord[u][0] * wMin;                 eBot_ds = vMid->texcoord[u][0] * wMid                         - vMin->texcoord[u][0] * wMin; -               span.texStep[u][0] = oneOverArea * (eMaj_ds * eBot.dy -                                                   - eMaj.dy * eBot_ds); +               dsdx[u] = oneOverArea * (eMaj_ds * eBot.dy - eMaj.dy * eBot_ds);                 dsdy[u] = oneOverArea * (eMaj.dx * eBot_ds - eMaj_ds * eBot.dx); +               span.texStepX[u][0] = dsdx[u]; +               span.texStepY[u][0] = dsdy[u];                 eMaj_dt = vMax->texcoord[u][1] * wMax                         - vMin->texcoord[u][1] * wMin;                 eBot_dt = vMid->texcoord[u][1] * wMid                         - vMin->texcoord[u][1] * wMin; -               span.texStep[u][1] = oneOverArea * (eMaj_dt * eBot.dy -                                                   - eMaj.dy * eBot_dt); +               dtdx[u] = oneOverArea * (eMaj_dt * eBot.dy - eMaj.dy * eBot_dt);                 dtdy[u] = oneOverArea * (eMaj.dx * eBot_dt - eMaj_dt * eBot.dx); +               span.texStepX[u][1] = dtdx[u]; +               span.texStepY[u][1] = dtdy[u];                 eMaj_du = vMax->texcoord[u][2] * wMax                         - vMin->texcoord[u][2] * wMin;                 eBot_du = vMid->texcoord[u][2] * wMid                         - vMin->texcoord[u][2] * wMin; -               span.texStep[u][2] = oneOverArea * (eMaj_du * eBot.dy -                                                   - eMaj.dy * eBot_du); +               dudx[u] = oneOverArea * (eMaj_du * eBot.dy - eMaj.dy * eBot_du);                 dudy[u] = oneOverArea * (eMaj.dx * eBot_du - eMaj_du * eBot.dx); +               span.texStepX[u][2] = dudx[u]; +               span.texStepY[u][2] = dudy[u];                 eMaj_dv = vMax->texcoord[u][3] * wMax                         - vMin->texcoord[u][3] * wMin;                 eBot_dv = vMid->texcoord[u][3] * wMid                         - vMin->texcoord[u][3] * wMin; -               span.texStep[u][3] = oneOverArea * (eMaj_dv * eBot.dy -                                                   - eMaj.dy * eBot_dv); +               dvdx[u] = oneOverArea * (eMaj_dv * eBot.dy - eMaj.dy * eBot_dv);                 dvdy[u] = oneOverArea * (eMaj.dx * eBot_dv - eMaj_dv * eBot.dx); -#  ifdef INTERP_LAMBDA -               { -                  const struct gl_texture_object *obj -                     = ctx->Texture.Unit[u]._Current; -                  const struct gl_texture_image *texImage -                     = obj->Image[obj->BaseLevel]; -                  const GLfloat texWidth = (GLfloat) texImage->Width; -                  const GLfloat texHeight = (GLfloat) texImage->Height; -                  GLfloat dudx = span.texStep[u][0] * texWidth; -                  GLfloat dudy = dsdy[u] * texWidth; -                  GLfloat dvdx = span.texStep[u][1] * texHeight; -                  GLfloat dvdy = dtdy[u] * texHeight; -                  GLfloat r1 = dudx * dudx + dudy * dudy; -                  GLfloat r2 = dvdx * dvdx + dvdy * dvdy; -                  span.rho[u] = r1 + r2; /* was rho2 = MAX2(r1,r2) */ -               } -#  endif +               span.texStepX[u][3] = dvdx[u]; +               span.texStepY[u][3] = dvdy[u];              }           }        } @@ -1040,21 +1006,21 @@                    GLfloat invW = vLower->win[3];                    GLfloat s0, t0, u0, v0;                    s0 = vLower->texcoord[0][0] * invW; -                  sLeft = s0 + (span.texStep[0][0] * adjx + dsdy * adjy) +                  sLeft = s0 + (span.texStepX[0][0] * adjx + dsdy * adjy)                       * (1.0F/FIXED_SCALE); -                  dsOuter = dsdy + dxOuter * span.texStep[0][0]; +                  dsOuter = dsdy + dxOuter * span.texStepX[0][0];                    t0 = vLower->texcoord[0][1] * invW; -                  tLeft = t0 + (span.texStep[0][1] * adjx + dtdy * adjy) +                  tLeft = t0 + (span.texStepX[0][1] * adjx + dtdy * adjy)                       * (1.0F/FIXED_SCALE); -                  dtOuter = dtdy + dxOuter * span.texStep[0][1]; +                  dtOuter = dtdy + dxOuter * span.texStepX[0][1];                    u0 = vLower->texcoord[0][2] * invW; -                  uLeft = u0 + (span.texStep[0][2] * adjx + dudy * adjy) +                  uLeft = u0 + (span.texStepX[0][2] * adjx + dudy * adjy)                       * (1.0F/FIXED_SCALE); -                  duOuter = dudy + dxOuter * span.texStep[0][2]; +                  duOuter = dudy + dxOuter * span.texStepX[0][2];                    v0 = vLower->texcoord[0][3] * invW; -                  vLeft = v0 + (span.texStep[0][3] * adjx + dvdy * adjy) +                  vLeft = v0 + (span.texStepX[0][3] * adjx + dvdy * adjy)                       * (1.0F/FIXED_SCALE); -                  dvOuter = dvdy + dxOuter * span.texStep[0][3]; +                  dvOuter = dvdy + dxOuter * span.texStepX[0][3];                 }  #endif  #ifdef INTERP_MULTITEX @@ -1065,21 +1031,21 @@                          GLfloat invW = vLower->win[3];                          GLfloat s0, t0, u0, v0;                          s0 = vLower->texcoord[u][0] * invW; -                        sLeft[u] = s0 + (span.texStep[u][0] * adjx + dsdy[u] +                        sLeft[u] = s0 + (span.texStepX[u][0] * adjx + dsdy[u]                                           * adjy) * (1.0F/FIXED_SCALE); -                        dsOuter[u] = dsdy[u] + dxOuter * span.texStep[u][0]; +                        dsOuter[u] = dsdy[u] + dxOuter * span.texStepX[u][0];                          t0 = vLower->texcoord[u][1] * invW; -                        tLeft[u] = t0 + (span.texStep[u][1] * adjx + dtdy[u] +                        tLeft[u] = t0 + (span.texStepX[u][1] * adjx + dtdy[u]                                           * adjy) * (1.0F/FIXED_SCALE); -                        dtOuter[u] = dtdy[u] + dxOuter * span.texStep[u][1]; +                        dtOuter[u] = dtdy[u] + dxOuter * span.texStepX[u][1];                          u0 = vLower->texcoord[u][2] * invW; -                        uLeft[u] = u0 + (span.texStep[u][2] * adjx + dudy[u] +                        uLeft[u] = u0 + (span.texStepX[u][2] * adjx + dudy[u]                                           * adjy) * (1.0F/FIXED_SCALE); -                        duOuter[u] = dudy[u] + dxOuter * span.texStep[u][2]; +                        duOuter[u] = dudy[u] + dxOuter * span.texStepX[u][2];                          v0 = vLower->texcoord[u][3] * invW; -                        vLeft[u] = v0 + (span.texStep[u][3] * adjx + dvdy[u] +                        vLeft[u] = v0 + (span.texStepX[u][3] * adjx + dvdy[u]                                           * adjy) * (1.0F/FIXED_SCALE); -                        dvOuter[u] = dvdy[u] + dxOuter * span.texStep[u][3]; +                        dvOuter[u] = dvdy[u] + dxOuter * span.texStepX[u][3];                       }                    }                 } @@ -1132,20 +1098,20 @@              fdtInner = fdtOuter + span.intTexStep[1];  #endif  #ifdef INTERP_TEX -            dsInner = dsOuter + span.texStep[0][0]; -            dtInner = dtOuter + span.texStep[0][1]; -            duInner = duOuter + span.texStep[0][2]; -            dvInner = dvOuter + span.texStep[0][3]; +            dsInner = dsOuter + span.texStepX[0][0]; +            dtInner = dtOuter + span.texStepX[0][1]; +            duInner = duOuter + span.texStepX[0][2]; +            dvInner = dvOuter + span.texStepX[0][3];  #endif  #ifdef INTERP_MULTITEX              {                 GLuint u;                 for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {                    if (ctx->Texture.Unit[u]._ReallyEnabled) { -                     dsInner[u] = dsOuter[u] + span.texStep[u][0]; -                     dtInner[u] = dtOuter[u] + span.texStep[u][1]; -                     duInner[u] = duOuter[u] + span.texStep[u][2]; -                     dvInner[u] = dvOuter[u] + span.texStep[u][3]; +                     dsInner[u] = dsOuter[u] + span.texStepX[u][0]; +                     dtInner[u] = dtOuter[u] + span.texStepX[u][1]; +                     duInner[u] = duOuter[u] + span.texStepX[u][2]; +                     dvInner[u] = dvOuter[u] + span.texStepX[u][3];                    }                 }              } @@ -1428,7 +1394,6 @@  #undef INTERP_INT_TEX  #undef INTERP_TEX  #undef INTERP_MULTITEX -#undef INTERP_LAMBDA  #undef INTERP_FLOAT_RGBA  #undef INTERP_FLOAT_SPEC | 
