Fix up some fragment program texture enable issues.

Implemented TXD instruction.
This commit is contained in:
Brian Paul
2003-03-15 17:33:25 +00:00
parent add99d01ee
commit 350353adcd
8 changed files with 141 additions and 137 deletions

View File

@@ -1,4 +1,4 @@
/* $Id: enable.c,v 1.75 2003/03/01 01:50:20 brianp Exp $ */ /* $Id: enable.c,v 1.76 2003/03/15 17:33:25 brianp Exp $ */
/* /*
* Mesa 3-D graphics library * Mesa 3-D graphics library
@@ -884,7 +884,7 @@ void _mesa_set_enable( GLcontext *ctx, GLenum cap, GLboolean state )
CHECK_EXTENSION(NV_fragment_program, cap); CHECK_EXTENSION(NV_fragment_program, cap);
if (ctx->FragmentProgram.Enabled == state) if (ctx->FragmentProgram.Enabled == state)
return; return;
FLUSH_VERTICES(ctx, _NEW_PROGRAM); FLUSH_VERTICES(ctx, _NEW_PROGRAM | _NEW_TEXTURE);
ctx->FragmentProgram.Enabled = state; ctx->FragmentProgram.Enabled = state;
break; break;
#endif /* FEATURE_NV_fragment_program */ #endif /* FEATURE_NV_fragment_program */

View File

@@ -1,4 +1,4 @@
/* $Id: nvfragparse.c,v 1.13 2003/03/14 15:40:59 brianp Exp $ */ /* $Id: nvfragparse.c,v 1.14 2003/03/15 17:33:26 brianp Exp $ */
/* /*
* Mesa 3-D graphics library * Mesa 3-D graphics library
@@ -42,20 +42,6 @@
#include "nvprogram.h" #include "nvprogram.h"
#define FRAG_ATTRIB_WPOS 0
#define FRAG_ATTRIB_COL0 1
#define FRAG_ATTRIB_COL1 2
#define FRAG_ATTRIB_FOGC 3
#define FRAG_ATTRIB_TEX0 4
#define FRAG_ATTRIB_TEX1 5
#define FRAG_ATTRIB_TEX2 6
#define FRAG_ATTRIB_TEX3 7
#define FRAG_ATTRIB_TEX4 8
#define FRAG_ATTRIB_TEX5 9
#define FRAG_ATTRIB_TEX6 10
#define FRAG_ATTRIB_TEX7 11
#define INPUT_1V 1 #define INPUT_1V 1
#define INPUT_2V 2 #define INPUT_2V 2
#define INPUT_3V 3 #define INPUT_3V 3

View File

@@ -1,4 +1,4 @@
/* $Id: nvfragprog.h,v 1.4 2003/03/14 15:40:59 brianp Exp $ */ /* $Id: nvfragprog.h,v 1.5 2003/03/15 17:33:26 brianp Exp $ */
/* /*
* Mesa 3-D graphics library * Mesa 3-D graphics library
@@ -36,6 +36,21 @@
#include "config.h" #include "config.h"
/* Fragment input registers / attributes */
#define FRAG_ATTRIB_WPOS 0
#define FRAG_ATTRIB_COL0 1
#define FRAG_ATTRIB_COL1 2
#define FRAG_ATTRIB_FOGC 3
#define FRAG_ATTRIB_TEX0 4
#define FRAG_ATTRIB_TEX1 5
#define FRAG_ATTRIB_TEX2 6
#define FRAG_ATTRIB_TEX3 7
#define FRAG_ATTRIB_TEX4 8
#define FRAG_ATTRIB_TEX5 9
#define FRAG_ATTRIB_TEX6 10
#define FRAG_ATTRIB_TEX7 11
/* Location of register sets within the whole register file */ /* Location of register sets within the whole register file */
#define FP_INPUT_REG_START 0 #define FP_INPUT_REG_START 0
#define FP_INPUT_REG_END (FP_INPUT_REG_START + MAX_NV_FRAGMENT_PROGRAM_INPUTS - 1) #define FP_INPUT_REG_END (FP_INPUT_REG_START + MAX_NV_FRAGMENT_PROGRAM_INPUTS - 1)

View File

@@ -1,4 +1,4 @@
/* $Id: state.c,v 1.99 2003/03/01 01:50:22 brianp Exp $ */ /* $Id: state.c,v 1.100 2003/03/15 17:33:26 brianp Exp $ */
/* /*
* Mesa 3-D graphics library * Mesa 3-D graphics library
@@ -813,17 +813,26 @@ update_texture_state( GLcontext *ctx )
*/ */
for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) { for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) {
struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
GLuint enableBits;
texUnit->_ReallyEnabled = 0; texUnit->_ReallyEnabled = 0;
texUnit->_GenFlags = 0; texUnit->_GenFlags = 0;
/* Get the bitmask of texture enables */
if (ctx->FragmentProgram.Enabled && ctx->FragmentProgram.Current) {
enableBits = ctx->FragmentProgram.Current->TexturesUsed[unit];
}
else {
if (!texUnit->Enabled) if (!texUnit->Enabled)
continue; continue;
enableBits = texUnit->Enabled;
}
/* Look for the highest-priority texture target that's enabled and /* Look for the highest-priority texture target that's enabled and
* complete. That's the one we'll use for texturing. * complete. That's the one we'll use for texturing. If we're using
* a fragment program we're guaranteed that bitcount(enabledBits) <= 1.
*/ */
if (texUnit->Enabled & TEXTURE_CUBE_BIT) { if (enableBits & TEXTURE_CUBE_BIT) {
struct gl_texture_object *texObj = texUnit->CurrentCubeMap; struct gl_texture_object *texObj = texUnit->CurrentCubeMap;
if (!texObj->Complete) { if (!texObj->Complete) {
_mesa_test_texobj_completeness(ctx, texObj); _mesa_test_texobj_completeness(ctx, texObj);
@@ -834,7 +843,7 @@ update_texture_state( GLcontext *ctx )
} }
} }
if (!texUnit->_ReallyEnabled && (texUnit->Enabled & TEXTURE_3D_BIT)) { if (!texUnit->_ReallyEnabled && (enableBits & TEXTURE_3D_BIT)) {
struct gl_texture_object *texObj = texUnit->Current3D; struct gl_texture_object *texObj = texUnit->Current3D;
if (!texObj->Complete) { if (!texObj->Complete) {
_mesa_test_texobj_completeness(ctx, texObj); _mesa_test_texobj_completeness(ctx, texObj);
@@ -845,7 +854,7 @@ update_texture_state( GLcontext *ctx )
} }
} }
if (!texUnit->_ReallyEnabled && (texUnit->Enabled & TEXTURE_RECT_BIT)) { if (!texUnit->_ReallyEnabled && (enableBits & TEXTURE_RECT_BIT)) {
struct gl_texture_object *texObj = texUnit->CurrentRect; struct gl_texture_object *texObj = texUnit->CurrentRect;
if (!texObj->Complete) { if (!texObj->Complete) {
_mesa_test_texobj_completeness(ctx, texObj); _mesa_test_texobj_completeness(ctx, texObj);
@@ -856,7 +865,7 @@ update_texture_state( GLcontext *ctx )
} }
} }
if (!texUnit->_ReallyEnabled && (texUnit->Enabled & TEXTURE_2D_BIT)) { if (!texUnit->_ReallyEnabled && (enableBits & TEXTURE_2D_BIT)) {
struct gl_texture_object *texObj = texUnit->Current2D; struct gl_texture_object *texObj = texUnit->Current2D;
if (!texObj->Complete) { if (!texObj->Complete) {
_mesa_test_texobj_completeness(ctx, texObj); _mesa_test_texobj_completeness(ctx, texObj);
@@ -867,7 +876,7 @@ update_texture_state( GLcontext *ctx )
} }
} }
if (!texUnit->_ReallyEnabled && (texUnit->Enabled & TEXTURE_1D_BIT)) { if (!texUnit->_ReallyEnabled && (enableBits & TEXTURE_1D_BIT)) {
struct gl_texture_object *texObj = texUnit->Current1D; struct gl_texture_object *texObj = texUnit->Current1D;
if (!texObj->Complete) { if (!texObj->Complete) {
_mesa_test_texobj_completeness(ctx, texObj); _mesa_test_texobj_completeness(ctx, texObj);

View File

@@ -1,4 +1,4 @@
/* $Id: s_context.c,v 1.46 2003/03/14 15:41:00 brianp Exp $ */ /* $Id: s_context.c,v 1.47 2003/03/15 17:33:27 brianp Exp $ */
/* /*
* Mesa 3-D graphics library * Mesa 3-D graphics library
@@ -306,35 +306,6 @@ _swrast_validate_texture_sample( GLcontext *ctx, GLuint texUnit,
} }
} }
if (ctx->FragmentProgram.Enabled) {
ASSERT(ctx->FragmentProgram.Current);
/* only one target can be referenced per unit per fragment program */
switch (ctx->FragmentProgram.Current->TexturesUsed[texUnit]) {
case TEXTURE_1D_BIT:
tObj = ctx->Texture.Unit[texUnit].Current1D;
break;
case TEXTURE_2D_BIT:
tObj = ctx->Texture.Unit[texUnit].Current2D;
break;
case TEXTURE_3D_BIT:
tObj = ctx->Texture.Unit[texUnit].Current3D;
break;
case TEXTURE_CUBE_BIT:
tObj = ctx->Texture.Unit[texUnit].CurrentCubeMap;
break;
case TEXTURE_RECT_BIT:
tObj = ctx->Texture.Unit[texUnit].CurrentRect;
break;
default:
_mesa_problem(ctx, "Bad texture in _swrast_validate_texture_sample");
return;
}
if (!tObj->Complete) {
_mesa_test_texobj_completeness(ctx,
(struct gl_texture_object *) tObj );
}
}
swrast->TextureSample[texUnit] = swrast->TextureSample[texUnit] =
_swrast_choose_texture_sample_func( ctx, tObj ); _swrast_choose_texture_sample_func( ctx, tObj );

View File

@@ -1,4 +1,4 @@
/* $Id: s_nvfragprog.c,v 1.7 2003/03/14 15:41:00 brianp Exp $ */ /* $Id: s_nvfragprog.c,v 1.8 2003/03/15 17:33:27 brianp Exp $ */
/* /*
* Mesa 3-D graphics library * Mesa 3-D graphics library
@@ -33,6 +33,7 @@
#include "macros.h" #include "macros.h"
#include "s_nvfragprog.h" #include "s_nvfragprog.h"
#include "s_span.h"
#include "s_texture.h" #include "s_texture.h"
@@ -46,30 +47,9 @@ fetch_texel( GLcontext *ctx, const GLfloat texcoord[4], GLuint unit,
const GLfloat *lambda = NULL; const GLfloat *lambda = NULL;
GLchan rgba[4]; GLchan rgba[4];
SWcontext *swrast = SWRAST_CONTEXT(ctx); SWcontext *swrast = SWRAST_CONTEXT(ctx);
const struct gl_texture_object *texObj = NULL;
switch (targetBit) { swrast->TextureSample[unit](ctx, unit, ctx->Texture.Unit[unit]._Current,
case TEXTURE_1D_BIT: 1, (const GLfloat (*)[4]) texcoord,
texObj = ctx->Texture.Unit[unit].Current1D;
break;
case TEXTURE_2D_BIT:
texObj = ctx->Texture.Unit[unit].Current2D;
break;
case TEXTURE_3D_BIT:
texObj = ctx->Texture.Unit[unit].Current3D;
break;
case TEXTURE_CUBE_BIT:
texObj = ctx->Texture.Unit[unit].CurrentCubeMap;
break;
case TEXTURE_RECT_BIT:
texObj = ctx->Texture.Unit[unit].CurrentRect;
break;
default:
_mesa_problem(ctx, "Invalid target in fetch_texel");
}
swrast->TextureSample[unit](ctx, unit, texObj, 1,
(const GLfloat (*)[4]) texcoord,
lambda, &rgba); lambda, &rgba);
color[0] = CHAN_TO_FLOAT(rgba[0]); color[0] = CHAN_TO_FLOAT(rgba[0]);
color[1] = CHAN_TO_FLOAT(rgba[1]); color[1] = CHAN_TO_FLOAT(rgba[1]);
@@ -83,11 +63,30 @@ fetch_texel( GLcontext *ctx, const GLfloat texcoord[4], GLuint unit,
*/ */
static void static void
fetch_texel_deriv( GLcontext *ctx, const GLfloat texcoord[4], fetch_texel_deriv( GLcontext *ctx, const GLfloat texcoord[4],
const GLfloat dtdx[4], const GLfloat dtdy[4], const GLfloat texdx[4], const GLfloat texdy[4],
GLuint unit, GLuint targetBit, GLfloat color[4] ) GLuint unit, GLuint targetBit, GLfloat color[4] )
{ {
/* XXX to do */ SWcontext *swrast = SWRAST_CONTEXT(ctx);
const struct gl_texture_object *texObj = ctx->Texture.Unit[unit]._Current;
const struct gl_texture_image *texImg = texObj->Image[texObj->BaseLevel];
const GLfloat texW = (GLfloat) texImg->WidthScale;
const GLfloat texH = (GLfloat) texImg->HeightScale;
GLchan rgba[4];
GLfloat lambda = _mesa_compute_lambda(texdx[0], texdy[0], /* ds/dx, ds/dy */
texdx[1], texdy[1], /* dt/dx, dt/dy */
texdx[3], texdy[2], /* dq/dx, dq/dy */
texW, texH,
texcoord[0], texcoord[1], texcoord[3],
1.0F / texcoord[3]);
swrast->TextureSample[unit](ctx, unit, ctx->Texture.Unit[unit]._Current,
1, (const GLfloat (*)[4]) texcoord,
&lambda, &rgba);
color[0] = CHAN_TO_FLOAT(rgba[0]);
color[1] = CHAN_TO_FLOAT(rgba[1]);
color[2] = CHAN_TO_FLOAT(rgba[2]);
color[3] = CHAN_TO_FLOAT(rgba[3]);
} }
@@ -300,6 +299,15 @@ execute_program(GLcontext *ctx, const struct fragment_program *program)
{ {
GLfloat a[4], result[4]; GLfloat a[4], result[4];
fetch_vector4( &inst->SrcReg[0], machine, a ); fetch_vector4( &inst->SrcReg[0], machine, a );
/* XXX - UGH! this is going to be a mess to implement!
* If we need the partial derivative of a texture coord
* or color, that's not too bad, but for an arbitrary register
* this will require a recursive solution. That is, we'll have
* to run another instance of this program with WPOS.x or .y
* incremented by one, stopping at the preceeding instruction.
* Then, read the register from that other instance and compute
* the difference. Yuck!
*/
result[0] = 0; /* XXX fix */ result[0] = 0; /* XXX fix */
result[1] = 0; result[1] = 0;
result[2] = 0; result[2] = 0;
@@ -701,6 +709,7 @@ execute_program(GLcontext *ctx, const struct fragment_program *program)
{ {
GLfloat texcoord[4], color[4]; GLfloat texcoord[4], color[4];
fetch_vector4( &inst->SrcReg[0], machine, texcoord ); fetch_vector4( &inst->SrcReg[0], machine, texcoord );
/* XXX: Undo perspective divide from interpolate_texcoords() */
fetch_texel( ctx, texcoord, inst->TexSrcUnit, fetch_texel( ctx, texcoord, inst->TexSrcUnit,
inst->TexSrcBit, color ); inst->TexSrcBit, color );
store_vector4( inst, machine, color ); store_vector4( inst, machine, color );
@@ -723,9 +732,7 @@ execute_program(GLcontext *ctx, const struct fragment_program *program)
{ {
GLfloat texcoord[4], color[4]; GLfloat texcoord[4], color[4];
fetch_vector4( &inst->SrcReg[0], machine, texcoord ); fetch_vector4( &inst->SrcReg[0], machine, texcoord );
texcoord[0] /= texcoord[3]; /* Already did perspective divide in interpolate_texcoords() */
texcoord[1] /= texcoord[3];
texcoord[2] /= texcoord[3];
fetch_texel( ctx, texcoord, inst->TexSrcUnit, fetch_texel( ctx, texcoord, inst->TexSrcUnit,
inst->TexSrcBit, color ); inst->TexSrcBit, color );
store_vector4( inst, machine, color ); store_vector4( inst, machine, color );
@@ -807,56 +814,63 @@ execute_program(GLcontext *ctx, const struct fragment_program *program)
void void
_swrast_exec_nv_fragment_program( GLcontext *ctx, struct sw_span *span ) _swrast_exec_nv_fragment_program( GLcontext *ctx, struct sw_span *span )
{ {
const struct fragment_program *program = ctx->FragmentProgram.Current;
GLuint i; GLuint i;
for (i = 0; i < span->end; i++) { for (i = 0; i < span->end; i++) {
if (span->array->mask[i]) { if (span->array->mask[i]) {
GLfloat *wpos = ctx->FragmentProgram.Machine.Registers[0];
GLfloat *col0 = ctx->FragmentProgram.Machine.Registers[1];
GLfloat *col1 = ctx->FragmentProgram.Machine.Registers[2];
GLfloat *fogc = ctx->FragmentProgram.Machine.Registers[3];
const GLfloat *colOut = ctx->FragmentProgram.Machine.Registers[FP_OUTPUT_REG_START]; const GLfloat *colOut = ctx->FragmentProgram.Machine.Registers[FP_OUTPUT_REG_START];
GLuint j; GLuint u;
/* Clear temporary registers XXX use memzero() */ /* Clear temporary registers */
_mesa_bzero(ctx->FragmentProgram.Machine.Registers +FP_TEMP_REG_START, _mesa_bzero(ctx->FragmentProgram.Machine.Registers +FP_TEMP_REG_START,
MAX_NV_FRAGMENT_PROGRAM_TEMPS * 4 * sizeof(GLfloat)); MAX_NV_FRAGMENT_PROGRAM_TEMPS * 4 * sizeof(GLfloat));
/* /*
* Load input registers - yes this is all very inefficient for now. * Load input registers - yes this is all very inefficient for now.
*/ */
if (program->InputsRead & (1 << FRAG_ATTRIB_WPOS)) {
GLfloat *wpos = ctx->FragmentProgram.Machine.Registers[0];
wpos[0] = span->x + i; wpos[0] = span->x + i;
wpos[1] = span->y + i; wpos[1] = span->y + i;
wpos[2] = (GLfloat) span->array->z[i] / ctx->DepthMaxF; wpos[2] = (GLfloat) span->array->z[i] / ctx->DepthMaxF;
wpos[3] = 1.0; /* XXX should be 1/w */ wpos[3] = 1.0; /* XXX should be 1/w */
}
if (program->InputsRead & (1 << FRAG_ATTRIB_COL0)) {
GLfloat *col0 = ctx->FragmentProgram.Machine.Registers[1];
col0[0] = CHAN_TO_FLOAT(span->array->rgba[i][RCOMP]); col0[0] = CHAN_TO_FLOAT(span->array->rgba[i][RCOMP]);
col0[1] = CHAN_TO_FLOAT(span->array->rgba[i][GCOMP]); col0[1] = CHAN_TO_FLOAT(span->array->rgba[i][GCOMP]);
col0[2] = CHAN_TO_FLOAT(span->array->rgba[i][BCOMP]); col0[2] = CHAN_TO_FLOAT(span->array->rgba[i][BCOMP]);
col0[3] = CHAN_TO_FLOAT(span->array->rgba[i][ACOMP]); col0[3] = CHAN_TO_FLOAT(span->array->rgba[i][ACOMP]);
}
if (program->InputsRead & (1 << FRAG_ATTRIB_COL1)) {
GLfloat *col1 = ctx->FragmentProgram.Machine.Registers[2];
col1[0] = CHAN_TO_FLOAT(span->array->spec[i][RCOMP]); col1[0] = CHAN_TO_FLOAT(span->array->spec[i][RCOMP]);
col1[1] = CHAN_TO_FLOAT(span->array->spec[i][GCOMP]); col1[1] = CHAN_TO_FLOAT(span->array->spec[i][GCOMP]);
col1[2] = CHAN_TO_FLOAT(span->array->spec[i][BCOMP]); col1[2] = CHAN_TO_FLOAT(span->array->spec[i][BCOMP]);
col1[3] = CHAN_TO_FLOAT(span->array->spec[i][ACOMP]); col1[3] = CHAN_TO_FLOAT(span->array->spec[i][ACOMP]);
}
if (program->InputsRead & (1 << FRAG_ATTRIB_FOGC)) {
GLfloat *fogc = ctx->FragmentProgram.Machine.Registers[3];
fogc[0] = span->array->fog[i]; fogc[0] = span->array->fog[i];
fogc[1] = 0.0F; fogc[1] = 0.0F;
fogc[2] = 0.0F; fogc[2] = 0.0F;
fogc[3] = 0.0F; fogc[3] = 0.0F;
}
for (j = 0; j < ctx->Const.MaxTextureCoordUnits; j++) { for (u = 0; u < ctx->Const.MaxTextureCoordUnits; u++) {
if (ctx->Texture.Unit[j]._ReallyEnabled) { if (program->InputsRead & (1 << (FRAG_ATTRIB_TEX0 + u))) {
COPY_4V(ctx->FragmentProgram.Machine.Registers[4 + j], if (ctx->Texture.Unit[u]._ReallyEnabled) {
span->array->texcoords[j][i]); COPY_4V(ctx->FragmentProgram.Machine.Registers[4 + u],
span->array->texcoords[u][i]);
} }
else { else {
COPY_4V(ctx->FragmentProgram.Machine.Registers[4 + j], COPY_4V(ctx->FragmentProgram.Machine.Registers[4 + u],
ctx->Current.Attrib[VERT_ATTRIB_TEX0 + j]); ctx->Current.Attrib[VERT_ATTRIB_TEX0 + u]);
}
} }
} }
if (!execute_program(ctx, ctx->FragmentProgram.Current)) if (!execute_program(ctx, program))
span->array->mask[i] = GL_FALSE; /* killed fragment */ span->array->mask[i] = GL_FALSE; /* killed fragment */
/* Store output registers */ /* Store output registers */

View File

@@ -1,4 +1,4 @@
/* $Id: s_span.c,v 1.57 2003/03/04 16:34:03 brianp Exp $ */ /* $Id: s_span.c,v 1.58 2003/03/15 17:33:27 brianp Exp $ */
/* /*
* Mesa 3-D graphics library * Mesa 3-D graphics library
@@ -321,8 +321,8 @@ compute_lambda(GLfloat dsdx, GLfloat dsdy, GLfloat dtdx, GLfloat dtdy,
/* /*
* This is a faster approximation * This is a faster approximation
*/ */
static GLfloat GLfloat
compute_lambda(GLfloat dsdx, GLfloat dsdy, GLfloat dtdx, GLfloat dtdy, _mesa_compute_lambda(GLfloat dsdx, GLfloat dsdy, GLfloat dtdx, GLfloat dtdy,
GLfloat dqdx, GLfloat dqdy, GLfloat texW, GLfloat texH, GLfloat dqdx, GLfloat dqdy, GLfloat texW, GLfloat texH,
GLfloat s, GLfloat t, GLfloat q, GLfloat invQ) GLfloat s, GLfloat t, GLfloat q, GLfloat invQ)
{ {
@@ -361,7 +361,8 @@ interpolate_texcoords(GLcontext *ctx, struct sw_span *span)
if (ctx->Texture.Unit[u]._ReallyEnabled) { if (ctx->Texture.Unit[u]._ReallyEnabled) {
const struct gl_texture_object *obj =ctx->Texture.Unit[u]._Current; const struct gl_texture_object *obj =ctx->Texture.Unit[u]._Current;
const struct gl_texture_image *img = obj->Image[obj->BaseLevel]; const struct gl_texture_image *img = obj->Image[obj->BaseLevel];
GLboolean needLambda = (obj->MinFilter != obj->MagFilter); const GLboolean needLambda = (obj->MinFilter != obj->MagFilter)
|| ctx->FragmentProgram.Enabled;
if (needLambda) { if (needLambda) {
GLfloat (*texcoord)[4] = span->array->texcoords[u]; GLfloat (*texcoord)[4] = span->array->texcoords[u];
GLfloat *lambda = span->array->lambda[u]; GLfloat *lambda = span->array->lambda[u];
@@ -384,7 +385,8 @@ interpolate_texcoords(GLcontext *ctx, struct sw_span *span)
texcoord[i][0] = s * invQ; texcoord[i][0] = s * invQ;
texcoord[i][1] = t * invQ; texcoord[i][1] = t * invQ;
texcoord[i][2] = r * invQ; texcoord[i][2] = r * invQ;
lambda[i] = compute_lambda(dsdx, dsdy, dtdx, dtdy, texcoord[i][3] = q;
lambda[i] = _mesa_compute_lambda(dsdx, dsdy, dtdx, dtdy,
dqdx, dqdy, texW, texH, dqdx, dqdy, texW, texH,
s, t, q, invQ); s, t, q, invQ);
s += dsdx; s += dsdx;
@@ -440,7 +442,8 @@ interpolate_texcoords(GLcontext *ctx, struct sw_span *span)
/* single texture */ /* single texture */
const struct gl_texture_object *obj = ctx->Texture.Unit[0]._Current; const struct gl_texture_object *obj = ctx->Texture.Unit[0]._Current;
const struct gl_texture_image *img = obj->Image[obj->BaseLevel]; const struct gl_texture_image *img = obj->Image[obj->BaseLevel];
GLboolean needLambda = (obj->MinFilter != obj->MagFilter); const GLboolean needLambda = (obj->MinFilter != obj->MagFilter)
|| ctx->FragmentProgram.Enabled;
span->arrayMask |= SPAN_TEXTURE; span->arrayMask |= SPAN_TEXTURE;
if (needLambda) { if (needLambda) {
/* just texture unit 0, with lambda */ /* just texture unit 0, with lambda */
@@ -462,12 +465,13 @@ interpolate_texcoords(GLcontext *ctx, struct sw_span *span)
GLuint i; GLuint i;
for (i = 0; i < span->end; i++) { for (i = 0; i < span->end; i++) {
const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q); const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q);
lambda[i] = compute_lambda(dsdx, dsdy, dtdx, dtdy, lambda[i] = _mesa_compute_lambda(dsdx, dsdy, dtdx, dtdy,
dqdx, dqdy, texW, texH, dqdx, dqdy, texW, texH,
s, t, q, invQ); s, t, q, invQ);
texcoord[i][0] = s * invQ; texcoord[i][0] = s * invQ;
texcoord[i][1] = t * invQ; texcoord[i][1] = t * invQ;
texcoord[i][2] = r * invQ; texcoord[i][2] = r * invQ;
texcoord[i][3] = q;
s += dsdx; s += dsdx;
t += dtdx; t += dtdx;
r += drdx; r += drdx;

View File

@@ -1,10 +1,10 @@
/* $Id: s_span.h,v 1.17 2002/06/15 02:38:17 brianp Exp $ */ /* $Id: s_span.h,v 1.18 2003/03/15 17:33:28 brianp Exp $ */
/* /*
* Mesa 3-D graphics library * Mesa 3-D graphics library
* Version: 4.1 * Version: 5.1
* *
* Copyright (C) 1999-2002 Brian Paul All Rights Reserved. * Copyright (C) 1999-2003 Brian Paul All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a * Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"), * copy of this software and associated documentation files (the "Software"),
@@ -48,6 +48,11 @@ _mesa_span_default_color( GLcontext *ctx, struct sw_span *span );
extern void extern void
_mesa_span_default_texcoords( GLcontext *ctx, struct sw_span *span ); _mesa_span_default_texcoords( GLcontext *ctx, struct sw_span *span );
extern GLfloat
_mesa_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);
extern void extern void
_mesa_write_index_span( GLcontext *ctx, struct sw_span *span); _mesa_write_index_span( GLcontext *ctx, struct sw_span *span);