summaryrefslogtreecommitdiff
path: root/src/mesa/swrast
diff options
context:
space:
mode:
authorBrian Paul <brian.paul@tungstengraphics.com>2003-03-15 17:33:25 +0000
committerBrian Paul <brian.paul@tungstengraphics.com>2003-03-15 17:33:25 +0000
commit350353adcd75f94fda63c787c86961716114e0bf (patch)
treed91f40c8a2d55f4f0e3e12d14dc075a8af83b92e /src/mesa/swrast
parentadd99d01ee7bf22e87c2c13b3476f6d70d0b3a7d (diff)
Fix up some fragment program texture enable issues.
Implemented TXD instruction.
Diffstat (limited to 'src/mesa/swrast')
-rw-r--r--src/mesa/swrast/s_context.c31
-rw-r--r--src/mesa/swrast/s_nvfragprog.c142
-rw-r--r--src/mesa/swrast/s_span.c30
-rw-r--r--src/mesa/swrast/s_span.h11
4 files changed, 104 insertions, 110 deletions
diff --git a/src/mesa/swrast/s_context.c b/src/mesa/swrast/s_context.c
index 6ed0c42e4d..29b73df365 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 c55080c0aa..b139b8cc55 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 2106b87c5b..cb02ab924d 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 be577ed6e5..d43aa1ae39 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);