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/mesa/swrast | |
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/mesa/swrast')
-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 |