From: Brian Paul Date: Sat, 15 Mar 2003 17:33:25 +0000 (+0000) Subject: Fix up some fragment program texture enable issues. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=350353adcd75f94fda63c787c86961716114e0bf;p=mesa.git Fix up some fragment program texture enable issues. Implemented TXD instruction. --- diff --git a/src/mesa/main/enable.c b/src/mesa/main/enable.c index eb46976abb0..9192abd4aca 100644 --- a/src/mesa/main/enable.c +++ b/src/mesa/main/enable.c @@ -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 @@ -884,7 +884,7 @@ void _mesa_set_enable( GLcontext *ctx, GLenum cap, GLboolean state ) CHECK_EXTENSION(NV_fragment_program, cap); if (ctx->FragmentProgram.Enabled == state) return; - FLUSH_VERTICES(ctx, _NEW_PROGRAM); + FLUSH_VERTICES(ctx, _NEW_PROGRAM | _NEW_TEXTURE); ctx->FragmentProgram.Enabled = state; break; #endif /* FEATURE_NV_fragment_program */ diff --git a/src/mesa/main/nvfragparse.c b/src/mesa/main/nvfragparse.c index 60b15bcd06e..0f75d6c36f6 100644 --- a/src/mesa/main/nvfragparse.c +++ b/src/mesa/main/nvfragparse.c @@ -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 @@ -42,20 +42,6 @@ #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_2V 2 #define INPUT_3V 3 diff --git a/src/mesa/main/nvfragprog.h b/src/mesa/main/nvfragprog.h index d7e23627a42..8d1ed13f217 100644 --- a/src/mesa/main/nvfragprog.h +++ b/src/mesa/main/nvfragprog.h @@ -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 @@ -36,6 +36,21 @@ #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 */ #define FP_INPUT_REG_START 0 #define FP_INPUT_REG_END (FP_INPUT_REG_START + MAX_NV_FRAGMENT_PROGRAM_INPUTS - 1) diff --git a/src/mesa/main/state.c b/src/mesa/main/state.c index 1051bda11da..f4f6a1cb6ef 100644 --- a/src/mesa/main/state.c +++ b/src/mesa/main/state.c @@ -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 @@ -813,17 +813,26 @@ update_texture_state( GLcontext *ctx ) */ for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) { struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; + GLuint enableBits; texUnit->_ReallyEnabled = 0; texUnit->_GenFlags = 0; - if (!texUnit->Enabled) - continue; + /* Get the bitmask of texture enables */ + if (ctx->FragmentProgram.Enabled && ctx->FragmentProgram.Current) { + enableBits = ctx->FragmentProgram.Current->TexturesUsed[unit]; + } + else { + if (!texUnit->Enabled) + continue; + enableBits = texUnit->Enabled; + } /* 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; if (!texObj->Complete) { _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; if (!texObj->Complete) { _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; if (!texObj->Complete) { _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; if (!texObj->Complete) { _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; if (!texObj->Complete) { _mesa_test_texobj_completeness(ctx, texObj); diff --git a/src/mesa/swrast/s_context.c b/src/mesa/swrast/s_context.c index 6ed0c42e4d6..29b73df3657 100644 --- a/src/mesa/swrast/s_context.c +++ b/src/mesa/swrast/s_context.c @@ -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 @@ -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_choose_texture_sample_func( ctx, tObj ); diff --git a/src/mesa/swrast/s_nvfragprog.c b/src/mesa/swrast/s_nvfragprog.c index c55080c0aac..b139b8cc556 100644 --- a/src/mesa/swrast/s_nvfragprog.c +++ b/src/mesa/swrast/s_nvfragprog.c @@ -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 @@ -33,6 +33,7 @@ #include "macros.h" #include "s_nvfragprog.h" +#include "s_span.h" #include "s_texture.h" @@ -46,30 +47,9 @@ fetch_texel( GLcontext *ctx, const GLfloat texcoord[4], GLuint unit, const GLfloat *lambda = NULL; GLchan rgba[4]; SWcontext *swrast = SWRAST_CONTEXT(ctx); - const struct gl_texture_object *texObj = NULL; - - switch (targetBit) { - case TEXTURE_1D_BIT: - 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, + 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]); @@ -83,11 +63,30 @@ fetch_texel( GLcontext *ctx, const GLfloat texcoord[4], GLuint unit, */ static void 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] ) { - /* 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]; 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[1] = 0; result[2] = 0; @@ -701,6 +709,7 @@ execute_program(GLcontext *ctx, const struct fragment_program *program) { GLfloat texcoord[4], color[4]; fetch_vector4( &inst->SrcReg[0], machine, texcoord ); + /* XXX: Undo perspective divide from interpolate_texcoords() */ fetch_texel( ctx, texcoord, inst->TexSrcUnit, inst->TexSrcBit, color ); store_vector4( inst, machine, color ); @@ -723,9 +732,7 @@ execute_program(GLcontext *ctx, const struct fragment_program *program) { GLfloat texcoord[4], color[4]; fetch_vector4( &inst->SrcReg[0], machine, texcoord ); - texcoord[0] /= texcoord[3]; - texcoord[1] /= texcoord[3]; - texcoord[2] /= texcoord[3]; + /* Already did perspective divide in interpolate_texcoords() */ fetch_texel( ctx, texcoord, inst->TexSrcUnit, inst->TexSrcBit, color ); store_vector4( inst, machine, color ); @@ -807,56 +814,63 @@ execute_program(GLcontext *ctx, const struct fragment_program *program) void _swrast_exec_nv_fragment_program( GLcontext *ctx, struct sw_span *span ) { + const struct fragment_program *program = ctx->FragmentProgram.Current; GLuint i; for (i = 0; i < span->end; 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]; - GLuint j; + GLuint u; - /* Clear temporary registers XXX use memzero() */ + /* Clear temporary registers */ _mesa_bzero(ctx->FragmentProgram.Machine.Registers +FP_TEMP_REG_START, MAX_NV_FRAGMENT_PROGRAM_TEMPS * 4 * sizeof(GLfloat)); /* * Load input registers - yes this is all very inefficient for now. */ - wpos[0] = span->x + i; - wpos[1] = span->y + i; - wpos[2] = (GLfloat) span->array->z[i] / ctx->DepthMaxF; - wpos[3] = 1.0; /* XXX should be 1/w */ - - col0[0] = CHAN_TO_FLOAT(span->array->rgba[i][RCOMP]); - col0[1] = CHAN_TO_FLOAT(span->array->rgba[i][GCOMP]); - col0[2] = CHAN_TO_FLOAT(span->array->rgba[i][BCOMP]); - col0[3] = CHAN_TO_FLOAT(span->array->rgba[i][ACOMP]); - - col1[0] = CHAN_TO_FLOAT(span->array->spec[i][RCOMP]); - col1[1] = CHAN_TO_FLOAT(span->array->spec[i][GCOMP]); - col1[2] = CHAN_TO_FLOAT(span->array->spec[i][BCOMP]); - col1[3] = CHAN_TO_FLOAT(span->array->spec[i][ACOMP]); - - fogc[0] = span->array->fog[i]; - fogc[1] = 0.0F; - fogc[2] = 0.0F; - fogc[3] = 0.0F; - - for (j = 0; j < ctx->Const.MaxTextureCoordUnits; j++) { - if (ctx->Texture.Unit[j]._ReallyEnabled) { - COPY_4V(ctx->FragmentProgram.Machine.Registers[4 + j], - span->array->texcoords[j][i]); - } - else { - COPY_4V(ctx->FragmentProgram.Machine.Registers[4 + j], - ctx->Current.Attrib[VERT_ATTRIB_TEX0 + j]); + if (program->InputsRead & (1 << FRAG_ATTRIB_WPOS)) { + GLfloat *wpos = ctx->FragmentProgram.Machine.Registers[0]; + wpos[0] = span->x + i; + wpos[1] = span->y + i; + wpos[2] = (GLfloat) span->array->z[i] / ctx->DepthMaxF; + 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[1] = CHAN_TO_FLOAT(span->array->rgba[i][GCOMP]); + col0[2] = CHAN_TO_FLOAT(span->array->rgba[i][BCOMP]); + 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[1] = CHAN_TO_FLOAT(span->array->spec[i][GCOMP]); + col1[2] = CHAN_TO_FLOAT(span->array->spec[i][BCOMP]); + 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[1] = 0.0F; + fogc[2] = 0.0F; + fogc[3] = 0.0F; + } + for (u = 0; u < ctx->Const.MaxTextureCoordUnits; u++) { + if (program->InputsRead & (1 << (FRAG_ATTRIB_TEX0 + u))) { + if (ctx->Texture.Unit[u]._ReallyEnabled) { + COPY_4V(ctx->FragmentProgram.Machine.Registers[4 + u], + span->array->texcoords[u][i]); + } + else { + COPY_4V(ctx->FragmentProgram.Machine.Registers[4 + u], + 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 */ /* Store output registers */ diff --git a/src/mesa/swrast/s_span.c b/src/mesa/swrast/s_span.c index 2106b87c5b6..cb02ab924d6 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.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 @@ -321,10 +321,10 @@ compute_lambda(GLfloat dsdx, GLfloat dsdy, GLfloat dtdx, GLfloat dtdy, /* * This is a faster approximation */ -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) +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) { GLfloat dsdx2 = (s + dsdx) / (q + dqdx) - s * invQ; GLfloat dtdx2 = (t + dtdx) / (q + dqdx) - t * invQ; @@ -361,7 +361,8 @@ interpolate_texcoords(GLcontext *ctx, struct sw_span *span) 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); + const GLboolean needLambda = (obj->MinFilter != obj->MagFilter) + || ctx->FragmentProgram.Enabled; if (needLambda) { GLfloat (*texcoord)[4] = span->array->texcoords[u]; GLfloat *lambda = span->array->lambda[u]; @@ -384,9 +385,10 @@ interpolate_texcoords(GLcontext *ctx, struct sw_span *span) texcoord[i][0] = s * invQ; texcoord[i][1] = t * invQ; texcoord[i][2] = r * invQ; - lambda[i] = compute_lambda(dsdx, dsdy, dtdx, dtdy, - dqdx, dqdy, texW, texH, - s, t, q, invQ); + texcoord[i][3] = q; + lambda[i] = _mesa_compute_lambda(dsdx, dsdy, dtdx, dtdy, + dqdx, dqdy, texW, texH, + s, t, q, invQ); s += dsdx; t += dtdx; r += drdx; @@ -440,7 +442,8 @@ interpolate_texcoords(GLcontext *ctx, struct sw_span *span) /* 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); + const GLboolean needLambda = (obj->MinFilter != obj->MagFilter) + || ctx->FragmentProgram.Enabled; span->arrayMask |= SPAN_TEXTURE; if (needLambda) { /* just texture unit 0, with lambda */ @@ -462,12 +465,13 @@ interpolate_texcoords(GLcontext *ctx, struct sw_span *span) GLuint i; for (i = 0; i < span->end; i++) { const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q); - lambda[i] = compute_lambda(dsdx, dsdy, dtdx, dtdy, - dqdx, dqdy, texW, texH, - s, t, q, invQ); + lambda[i] = _mesa_compute_lambda(dsdx, dsdy, dtdx, dtdy, + dqdx, dqdy, texW, texH, + s, t, q, invQ); texcoord[i][0] = s * invQ; texcoord[i][1] = t * invQ; texcoord[i][2] = r * invQ; + texcoord[i][3] = q; s += dsdx; t += dtdx; r += drdx; diff --git a/src/mesa/swrast/s_span.h b/src/mesa/swrast/s_span.h index be577ed6e56..d43aa1ae394 100644 --- a/src/mesa/swrast/s_span.h +++ b/src/mesa/swrast/s_span.h @@ -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 - * 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 * 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 _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 _mesa_write_index_span( GLcontext *ctx, struct sw_span *span);