summaryrefslogtreecommitdiffstats
path: root/src/mesa/swrast
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/swrast')
-rw-r--r--src/mesa/swrast/s_aaline.c51
-rw-r--r--src/mesa/swrast/s_aalinetemp.h125
-rw-r--r--src/mesa/swrast/s_aatriangle.c52
-rw-r--r--src/mesa/swrast/s_aatritemp.h224
-rw-r--r--src/mesa/swrast/s_alpha.c2
-rw-r--r--src/mesa/swrast/s_arbshader.c126
-rw-r--r--src/mesa/swrast/s_arbshader.h38
-rw-r--r--src/mesa/swrast/s_atifragshader.c11
-rw-r--r--src/mesa/swrast/s_context.c164
-rw-r--r--src/mesa/swrast/s_context.h213
-rw-r--r--src/mesa/swrast/s_copypix.c2
-rw-r--r--src/mesa/swrast/s_drawpix.c2
-rw-r--r--src/mesa/swrast/s_feedback.c17
-rw-r--r--src/mesa/swrast/s_fog.c58
-rw-r--r--src/mesa/swrast/s_fragprog.c224
-rw-r--r--src/mesa/swrast/s_fragprog.h (renamed from src/mesa/swrast/s_nvfragprog.h)13
-rw-r--r--src/mesa/swrast/s_lines.c7
-rw-r--r--src/mesa/swrast/s_linetemp.h92
-rw-r--r--src/mesa/swrast/s_logic.c2
-rw-r--r--src/mesa/swrast/s_masking.c2
-rw-r--r--src/mesa/swrast/s_nvfragprog.c1665
-rw-r--r--src/mesa/swrast/s_pointtemp.h72
-rw-r--r--src/mesa/swrast/s_readpix.c2
-rw-r--r--src/mesa/swrast/s_span.c770
-rw-r--r--src/mesa/swrast/s_span.h179
-rw-r--r--src/mesa/swrast/s_texcombine.c6
-rw-r--r--src/mesa/swrast/s_triangle.c52
-rw-r--r--src/mesa/swrast/s_tritemp.h434
-rw-r--r--src/mesa/swrast/s_zoom.c19
-rw-r--r--src/mesa/swrast/swrast.h3
30 files changed, 1420 insertions, 3207 deletions
diff --git a/src/mesa/swrast/s_aaline.c b/src/mesa/swrast/s_aaline.c
index b3a209923fd..c81095163b0 100644
--- a/src/mesa/swrast/s_aaline.c
+++ b/src/mesa/swrast/s_aaline.c
@@ -1,8 +1,8 @@
/*
* Mesa 3-D graphics library
- * Version: 6.1
+ * Version: 6.5.3
*
- * Copyright (C) 1999-2004 Brian Paul All Rights Reserved.
+ * Copyright (C) 1999-2007 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"),
@@ -67,14 +67,14 @@ struct LineInfo
GLfloat iPlane[4];
/* DO_SPEC */
GLfloat srPlane[4], sgPlane[4], sbPlane[4];
- /* DO_TEX or DO_MULTITEX */
- GLfloat sPlane[MAX_TEXTURE_COORD_UNITS][4];
- GLfloat tPlane[MAX_TEXTURE_COORD_UNITS][4];
- GLfloat uPlane[MAX_TEXTURE_COORD_UNITS][4];
- GLfloat vPlane[MAX_TEXTURE_COORD_UNITS][4];
- GLfloat lambda[MAX_TEXTURE_COORD_UNITS];
- GLfloat texWidth[MAX_TEXTURE_COORD_UNITS];
- GLfloat texHeight[MAX_TEXTURE_COORD_UNITS];
+ /* DO_TEXVAR */
+ GLfloat sPlane[FRAG_ATTRIB_MAX][4];
+ GLfloat tPlane[FRAG_ATTRIB_MAX][4];
+ GLfloat uPlane[FRAG_ATTRIB_MAX][4];
+ GLfloat vPlane[FRAG_ATTRIB_MAX][4];
+ GLfloat lambda[FRAG_ATTRIB_MAX];
+ GLfloat texWidth[FRAG_ATTRIB_MAX];
+ GLfloat texHeight[FRAG_ATTRIB_MAX];
SWspan span;
};
@@ -499,15 +499,7 @@ segment(GLcontext *ctx,
#define DO_Z
#define DO_FOG
#define DO_RGBA
-#define DO_TEX
-#include "s_aalinetemp.h"
-
-
-#define NAME(x) aa_multitex_rgba_##x
-#define DO_Z
-#define DO_FOG
-#define DO_RGBA
-#define DO_MULTITEX
+#define DO_TEXVAR
#include "s_aalinetemp.h"
@@ -515,7 +507,7 @@ segment(GLcontext *ctx,
#define DO_Z
#define DO_FOG
#define DO_RGBA
-#define DO_MULTITEX
+#define DO_TEXVAR
#define DO_SPEC
#include "s_aalinetemp.h"
@@ -530,18 +522,15 @@ _swrast_choose_aa_line_function(GLcontext *ctx)
if (ctx->Visual.rgbMode) {
/* RGBA */
- if (ctx->Texture._EnabledCoordUnits != 0) {
- if (ctx->Texture._EnabledCoordUnits > 1) {
- /* Multitextured! */
- if (ctx->Light.Model.ColorControl==GL_SEPARATE_SPECULAR_COLOR ||
- ctx->Fog.ColorSumEnabled)
- swrast->Line = aa_multitex_spec_line;
- else
- swrast->Line = aa_multitex_rgba_line;
- }
- else {
+ if (ctx->Texture._EnabledCoordUnits != 0
+ || ctx->FragmentProgram._Current) {
+
+ if (ctx->Light.Model.ColorControl==GL_SEPARATE_SPECULAR_COLOR ||
+ ctx->Fog.ColorSumEnabled)
+ swrast->Line = aa_multitex_spec_line;
+ else
swrast->Line = aa_tex_rgba_line;
- }
+
}
else {
swrast->Line = aa_rgba_line;
diff --git a/src/mesa/swrast/s_aalinetemp.h b/src/mesa/swrast/s_aalinetemp.h
index 34c95fc34ec..4d33b7dff7e 100644
--- a/src/mesa/swrast/s_aalinetemp.h
+++ b/src/mesa/swrast/s_aalinetemp.h
@@ -1,8 +1,8 @@
/*
* Mesa 3-D graphics library
- * Version: 6.5
+ * Version: 6.5.3
*
- * Copyright (C) 1999-2005 Brian Paul All Rights Reserved.
+ * Copyright (C) 1999-2007 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"),
@@ -36,6 +36,7 @@
static void
NAME(plot)(GLcontext *ctx, struct LineInfo *line, int ix, int iy)
{
+ const SWcontext *swrast = SWRAST_CONTEXT(ctx);
const GLfloat fx = (GLfloat) ix;
const GLfloat fy = (GLfloat) iy;
#ifdef DO_INDEX
@@ -45,6 +46,8 @@ NAME(plot)(GLcontext *ctx, struct LineInfo *line, int ix, int iy)
#endif
const GLuint i = line->span.end;
+ (void) swrast;
+
if (coverage == 0.0)
return;
@@ -61,7 +64,7 @@ NAME(plot)(GLcontext *ctx, struct LineInfo *line, int ix, int iy)
line->span.array->z[i] = (GLuint) solve_plane(fx, fy, line->zPlane);
#endif
#ifdef DO_FOG
- line->span.array->fog[i] = solve_plane(fx, fy, line->fPlane);
+ line->span.array->attribs[FRAG_ATTRIB_FOGC][i][0] = solve_plane(fx, fy, line->fPlane);
#endif
#ifdef DO_RGBA
line->span.array->rgba[i][RCOMP] = solve_plane_chan(fx, fy, line->rPlane);
@@ -77,41 +80,29 @@ NAME(plot)(GLcontext *ctx, struct LineInfo *line, int ix, int iy)
line->span.array->spec[i][GCOMP] = solve_plane_chan(fx, fy, line->sgPlane);
line->span.array->spec[i][BCOMP] = solve_plane_chan(fx, fy, line->sbPlane);
#endif
-#ifdef DO_TEX
- {
- GLfloat invQ;
- if (ctx->FragmentProgram._Active) {
- invQ = 1.0F;
- }
- else {
- invQ = solve_plane_recip(fx, fy, line->vPlane[0]);
- }
- line->span.array->texcoords[0][i][0] = solve_plane(fx, fy, line->sPlane[0]) * invQ;
- line->span.array->texcoords[0][i][1] = solve_plane(fx, fy, line->tPlane[0]) * invQ;
- line->span.array->texcoords[0][i][2] = solve_plane(fx, fy, line->uPlane[0]) * invQ;
- line->span.array->lambda[0][i] = compute_lambda(line->sPlane[0],
- line->tPlane[0], invQ,
- line->texWidth[0],
- line->texHeight[0]);
- }
-#elif defined(DO_MULTITEX)
+#if defined(DO_TEXVAR)
{
- GLuint unit;
- for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) {
- if (ctx->Texture.Unit[unit]._ReallyEnabled) {
+ GLuint attr;
+ for (attr = swrast->_MinFragmentAttrib; attr < swrast->_MaxFragmentAttrib; attr++) {
+ if (swrast->_FragmentAttribs & (1 << attr)) {
+ GLfloat (*attribArray)[4] = line->span.array->attribs[attr];
GLfloat invQ;
- if (ctx->FragmentProgram._Active) {
+ if (ctx->FragmentProgram._Current) {
invQ = 1.0F;
}
else {
- invQ = solve_plane_recip(fx, fy, line->vPlane[unit]);
+ invQ = solve_plane_recip(fx, fy, line->vPlane[attr]);
+ }
+ attribArray[i][0] = solve_plane(fx, fy, line->sPlane[attr]) * invQ;
+ attribArray[i][1] = solve_plane(fx, fy, line->tPlane[attr]) * invQ;
+ attribArray[i][2] = solve_plane(fx, fy, line->uPlane[attr]) * invQ;
+ if (attr < FRAG_ATTRIB_VAR0) {
+ const GLuint unit = attr - FRAG_ATTRIB_TEX0;
+ line->span.array->lambda[unit][i]
+ = compute_lambda(line->sPlane[attr],
+ line->tPlane[attr], invQ,
+ line->texWidth[attr], line->texHeight[attr]);
}
- line->span.array->texcoords[unit][i][0] = solve_plane(fx, fy, line->sPlane[unit]) * invQ;
- line->span.array->texcoords[unit][i][1] = solve_plane(fx, fy, line->tPlane[unit]) * invQ;
- line->span.array->texcoords[unit][i][2] = solve_plane(fx, fy, line->uPlane[unit]) * invQ;
- line->span.array->lambda[unit][i] = compute_lambda(line->sPlane[unit],
- line->tPlane[unit], invQ,
- line->texWidth[unit], line->texHeight[unit]);
}
}
}
@@ -214,52 +205,33 @@ NAME(line)(GLcontext *ctx, const SWvertex *v0, const SWvertex *v1)
constant_plane(v1->index, line.iPlane);
}
#endif
-#ifdef DO_TEX
+#if defined(DO_TEXVAR)
{
- const struct gl_texture_object *obj = ctx->Texture.Unit[0]._Current;
- const struct gl_texture_image *texImage = obj->Image[0][obj->BaseLevel];
+ GLuint attr;
const GLfloat invW0 = v0->win[3];
const GLfloat invW1 = v1->win[3];
- const GLfloat s0 = v0->texcoord[0][0] * invW0;
- const GLfloat s1 = v1->texcoord[0][0] * invW1;
- const GLfloat t0 = v0->texcoord[0][1] * invW0;
- const GLfloat t1 = v1->texcoord[0][1] * invW1;
- const GLfloat r0 = v0->texcoord[0][2] * invW0;
- const GLfloat r1 = v1->texcoord[0][2] * invW1;
- const GLfloat q0 = v0->texcoord[0][3] * invW0;
- const GLfloat q1 = v1->texcoord[0][3] * invW1;
- line.span.arrayMask |= (SPAN_TEXTURE | SPAN_LAMBDA);
- compute_plane(line.x0, line.y0, line.x1, line.y1, s0, s1, line.sPlane[0]);
- compute_plane(line.x0, line.y0, line.x1, line.y1, t0, t1, line.tPlane[0]);
- compute_plane(line.x0, line.y0, line.x1, line.y1, r0, r1, line.uPlane[0]);
- compute_plane(line.x0, line.y0, line.x1, line.y1, q0, q1, line.vPlane[0]);
- line.texWidth[0] = (GLfloat) texImage->Width;
- line.texHeight[0] = (GLfloat) texImage->Height;
- }
-#elif defined(DO_MULTITEX)
- {
- GLuint u;
- line.span.arrayMask |= (SPAN_TEXTURE | SPAN_LAMBDA);
- 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 *texImage = obj->Image[0][obj->BaseLevel];
- const GLfloat invW0 = v0->win[3];
- const GLfloat invW1 = v1->win[3];
- const GLfloat s0 = v0->texcoord[u][0] * invW0;
- const GLfloat s1 = v1->texcoord[u][0] * invW1;
- const GLfloat t0 = v0->texcoord[u][1] * invW0;
- const GLfloat t1 = v1->texcoord[u][1] * invW1;
- const GLfloat r0 = v0->texcoord[u][2] * invW0;
- const GLfloat r1 = v1->texcoord[u][2] * invW1;
- const GLfloat q0 = v0->texcoord[u][3] * invW0;
- const GLfloat q1 = v1->texcoord[u][3] * invW1;
- compute_plane(line.x0, line.y0, line.x1, line.y1, s0, s1, line.sPlane[u]);
- compute_plane(line.x0, line.y0, line.x1, line.y1, t0, t1, line.tPlane[u]);
- compute_plane(line.x0, line.y0, line.x1, line.y1, r0, r1, line.uPlane[u]);
- compute_plane(line.x0, line.y0, line.x1, line.y1, q0, q1, line.vPlane[u]);
- line.texWidth[u] = (GLfloat) texImage->Width;
- line.texHeight[u] = (GLfloat) texImage->Height;
+ line.span.arrayMask |= (SPAN_TEXTURE | SPAN_LAMBDA | SPAN_VARYING);
+ for (attr = swrast->_MinFragmentAttrib; attr < swrast->_MaxFragmentAttrib; attr++) {
+ if (swrast->_FragmentAttribs & (1 << attr)) {
+ const GLfloat s0 = v0->attrib[attr][0] * invW0;
+ const GLfloat s1 = v1->attrib[attr][0] * invW1;
+ const GLfloat t0 = v0->attrib[attr][1] * invW0;
+ const GLfloat t1 = v1->attrib[attr][1] * invW1;
+ const GLfloat r0 = v0->attrib[attr][2] * invW0;
+ const GLfloat r1 = v1->attrib[attr][2] * invW1;
+ const GLfloat q0 = v0->attrib[attr][3] * invW0;
+ const GLfloat q1 = v1->attrib[attr][3] * invW1;
+ compute_plane(line.x0, line.y0, line.x1, line.y1, s0, s1, line.sPlane[attr]);
+ compute_plane(line.x0, line.y0, line.x1, line.y1, t0, t1, line.tPlane[attr]);
+ compute_plane(line.x0, line.y0, line.x1, line.y1, r0, r1, line.uPlane[attr]);
+ compute_plane(line.x0, line.y0, line.x1, line.y1, q0, q1, line.vPlane[attr]);
+ if (attr < FRAG_ATTRIB_VAR0) {
+ const GLuint u = attr - FRAG_ATTRIB_TEX0;
+ const struct gl_texture_object *obj = ctx->Texture.Unit[u]._Current;
+ const struct gl_texture_image *texImage = obj->Image[0][obj->BaseLevel];
+ line.texWidth[attr] = (GLfloat) texImage->Width;
+ line.texHeight[attr] = (GLfloat) texImage->Height;
+ }
}
}
}
@@ -324,6 +296,5 @@ NAME(line)(GLcontext *ctx, const SWvertex *v0, const SWvertex *v1)
#undef DO_RGBA
#undef DO_INDEX
#undef DO_SPEC
-#undef DO_TEX
-#undef DO_MULTITEX
+#undef DO_TEXVAR
#undef NAME
diff --git a/src/mesa/swrast/s_aatriangle.c b/src/mesa/swrast/s_aatriangle.c
index 63a13cf3fba..5e3059af93b 100644
--- a/src/mesa/swrast/s_aatriangle.c
+++ b/src/mesa/swrast/s_aatriangle.c
@@ -1,8 +1,8 @@
/*
* Mesa 3-D graphics library
- * Version: 6.3
+ * Version: 6.5.3
*
- * Copyright (C) 1999-2004 Brian Paul All Rights Reserved.
+ * Copyright (C) 1999-2007 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"),
@@ -408,7 +408,7 @@ tex_aa_tri(GLcontext *ctx,
#define DO_Z
#define DO_FOG
#define DO_RGBA
-#define DO_TEX
+#define DO_TEXVAR
#include "s_aatritemp.h"
}
@@ -422,39 +422,12 @@ spec_tex_aa_tri(GLcontext *ctx,
#define DO_Z
#define DO_FOG
#define DO_RGBA
-#define DO_TEX
+#define DO_TEXVAR
#define DO_SPEC
#include "s_aatritemp.h"
}
-static void
-multitex_aa_tri(GLcontext *ctx,
- const SWvertex *v0,
- const SWvertex *v1,
- const SWvertex *v2)
-{
-#define DO_Z
-#define DO_FOG
-#define DO_RGBA
-#define DO_MULTITEX
-#include "s_aatritemp.h"
-}
-
-static void
-spec_multitex_aa_tri(GLcontext *ctx,
- const SWvertex *v0,
- const SWvertex *v1,
- const SWvertex *v2)
-{
-#define DO_Z
-#define DO_FOG
-#define DO_RGBA
-#define DO_MULTITEX
-#define DO_SPEC
-#include "s_aatritemp.h"
-}
-
/*
* Examine GL state and set swrast->Triangle to an
@@ -465,22 +438,13 @@ _swrast_set_aa_triangle_function(GLcontext *ctx)
{
ASSERT(ctx->Polygon.SmoothFlag);
- if (ctx->Texture._EnabledCoordUnits != 0) {
+ if (ctx->Texture._EnabledCoordUnits != 0
+ || ctx->FragmentProgram._Current) {
if (NEED_SECONDARY_COLOR(ctx)) {
- if (ctx->Texture._EnabledCoordUnits > 1) {
- SWRAST_CONTEXT(ctx)->Triangle = spec_multitex_aa_tri;
- }
- else {
- SWRAST_CONTEXT(ctx)->Triangle = spec_tex_aa_tri;
- }
+ SWRAST_CONTEXT(ctx)->Triangle = spec_tex_aa_tri;
}
else {
- if (ctx->Texture._EnabledCoordUnits > 1) {
- SWRAST_CONTEXT(ctx)->Triangle = multitex_aa_tri;
- }
- else {
- SWRAST_CONTEXT(ctx)->Triangle = tex_aa_tri;
- }
+ SWRAST_CONTEXT(ctx)->Triangle = tex_aa_tri;
}
}
else if (ctx->Visual.rgbMode) {
diff --git a/src/mesa/swrast/s_aatritemp.h b/src/mesa/swrast/s_aatritemp.h
index b5470a02980..bbf9cc611d8 100644
--- a/src/mesa/swrast/s_aatritemp.h
+++ b/src/mesa/swrast/s_aatritemp.h
@@ -1,8 +1,8 @@
/*
* Mesa 3-D graphics library
- * Version: 6.5
+ * Version: 6.5.3
*
- * Copyright (C) 1999-2005 Brian Paul All Rights Reserved.
+ * Copyright (C) 1999-2007 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"),
@@ -36,12 +36,12 @@
* DO_RGBA - if defined, compute RGBA values
* DO_INDEX - if defined, compute color index values
* DO_SPEC - if defined, compute specular RGB values
- * DO_TEX - if defined, compute unit 0 STRQ texcoords
- * DO_MULTITEX - if defined, compute all unit's STRQ texcoords
+ * DO_TEXVAR - if defined, compute texcoords, varying
*/
/*void triangle( GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2, GLuint pv )*/
{
+ const SWcontext *swrast = SWRAST_CONTEXT(ctx);
const GLfloat *p0 = v0->win;
const GLfloat *p1 = v1->win;
const GLfloat *p2 = v2->win;
@@ -70,20 +70,18 @@
#ifdef DO_SPEC
GLfloat srPlane[4], sgPlane[4], sbPlane[4];
#endif
-#ifdef DO_TEX
- GLfloat sPlane[4], tPlane[4], uPlane[4], vPlane[4];
- GLfloat texWidth, texHeight;
-#elif defined(DO_MULTITEX)
- GLfloat sPlane[MAX_TEXTURE_COORD_UNITS][4]; /* texture S */
- GLfloat tPlane[MAX_TEXTURE_COORD_UNITS][4]; /* texture T */
- GLfloat uPlane[MAX_TEXTURE_COORD_UNITS][4]; /* texture R */
- GLfloat vPlane[MAX_TEXTURE_COORD_UNITS][4]; /* texture Q */
- GLfloat texWidth[MAX_TEXTURE_COORD_UNITS];
- GLfloat texHeight[MAX_TEXTURE_COORD_UNITS];
+#if defined(DO_TEXVAR)
+ GLfloat sPlane[FRAG_ATTRIB_MAX][4]; /* texture S */
+ GLfloat tPlane[FRAG_ATTRIB_MAX][4]; /* texture T */
+ GLfloat uPlane[FRAG_ATTRIB_MAX][4]; /* texture R */
+ GLfloat vPlane[FRAG_ATTRIB_MAX][4]; /* texture Q */
+ GLfloat texWidth[FRAG_ATTRIB_MAX];
+ GLfloat texHeight[FRAG_ATTRIB_MAX];
#endif
GLfloat bf = SWRAST_CONTEXT(ctx)->_BackfaceSign;
-
+ (void) swrast;
+
INIT_SPAN(span, GL_POLYGON, 0, 0, SPAN_COVERAGE);
/* determine bottom to top order of vertices */
@@ -179,65 +177,44 @@
}
span.arrayMask |= SPAN_SPEC;
#endif
-#ifdef DO_TEX
+#if defined(DO_TEXVAR)
{
- const struct gl_texture_object *obj = ctx->Texture.Unit[0]._Current;
- const struct gl_texture_image *texImage = obj->Image[0][obj->BaseLevel];
+ GLuint attr;
const GLfloat invW0 = v0->win[3];
const GLfloat invW1 = v1->win[3];
const GLfloat invW2 = v2->win[3];
- const GLfloat s0 = v0->texcoord[0][0] * invW0;
- const GLfloat s1 = v1->texcoord[0][0] * invW1;
- const GLfloat s2 = v2->texcoord[0][0] * invW2;
- const GLfloat t0 = v0->texcoord[0][1] * invW0;
- const GLfloat t1 = v1->texcoord[0][1] * invW1;
- const GLfloat t2 = v2->texcoord[0][1] * invW2;
- const GLfloat r0 = v0->texcoord[0][2] * invW0;
- const GLfloat r1 = v1->texcoord[0][2] * invW1;
- const GLfloat r2 = v2->texcoord[0][2] * invW2;
- const GLfloat q0 = v0->texcoord[0][3] * invW0;
- const GLfloat q1 = v1->texcoord[0][3] * invW1;
- const GLfloat q2 = v2->texcoord[0][3] * invW2;
- compute_plane(p0, p1, p2, s0, s1, s2, sPlane);
- compute_plane(p0, p1, p2, t0, t1, t2, tPlane);
- compute_plane(p0, p1, p2, r0, r1, r2, uPlane);
- compute_plane(p0, p1, p2, q0, q1, q2, vPlane);
- texWidth = (GLfloat) texImage->Width;
- texHeight = (GLfloat) texImage->Height;
- }
- span.arrayMask |= (SPAN_TEXTURE | SPAN_LAMBDA);
-#elif defined(DO_MULTITEX)
- {
- 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 *texImage = obj->Image[0][obj->BaseLevel];
- const GLfloat invW0 = v0->win[3];
- const GLfloat invW1 = v1->win[3];
- const GLfloat invW2 = v2->win[3];
- const GLfloat s0 = v0->texcoord[u][0] * invW0;
- const GLfloat s1 = v1->texcoord[u][0] * invW1;
- const GLfloat s2 = v2->texcoord[u][0] * invW2;
- const GLfloat t0 = v0->texcoord[u][1] * invW0;
- const GLfloat t1 = v1->texcoord[u][1] * invW1;
- const GLfloat t2 = v2->texcoord[u][1] * invW2;
- const GLfloat r0 = v0->texcoord[u][2] * invW0;
- const GLfloat r1 = v1->texcoord[u][2] * invW1;
- const GLfloat r2 = v2->texcoord[u][2] * invW2;
- const GLfloat q0 = v0->texcoord[u][3] * invW0;
- const GLfloat q1 = v1->texcoord[u][3] * invW1;
- const GLfloat q2 = v2->texcoord[u][3] * invW2;
- compute_plane(p0, p1, p2, s0, s1, s2, sPlane[u]);
- compute_plane(p0, p1, p2, t0, t1, t2, tPlane[u]);
- compute_plane(p0, p1, p2, r0, r1, r2, uPlane[u]);
- compute_plane(p0, p1, p2, q0, q1, q2, vPlane[u]);
- texWidth[u] = (GLfloat) texImage->Width;
- texHeight[u] = (GLfloat) texImage->Height;
+ for (attr = swrast->_MinFragmentAttrib; attr < swrast->_MaxFragmentAttrib; attr++) {
+ if (swrast->_FragmentAttribs & (1 << attr)) {
+ const GLfloat s0 = v0->attrib[attr][0] * invW0;
+ const GLfloat s1 = v1->attrib[attr][0] * invW1;
+ const GLfloat s2 = v2->attrib[attr][0] * invW2;
+ const GLfloat t0 = v0->attrib[attr][1] * invW0;
+ const GLfloat t1 = v1->attrib[attr][1] * invW1;
+ const GLfloat t2 = v2->attrib[attr][1] * invW2;
+ const GLfloat r0 = v0->attrib[attr][2] * invW0;
+ const GLfloat r1 = v1->attrib[attr][2] * invW1;
+ const GLfloat r2 = v2->attrib[attr][2] * invW2;
+ const GLfloat q0 = v0->attrib[attr][3] * invW0;
+ const GLfloat q1 = v1->attrib[attr][3] * invW1;
+ const GLfloat q2 = v2->attrib[attr][3] * invW2;
+ compute_plane(p0, p1, p2, s0, s1, s2, sPlane[attr]);
+ compute_plane(p0, p1, p2, t0, t1, t2, tPlane[attr]);
+ compute_plane(p0, p1, p2, r0, r1, r2, uPlane[attr]);
+ compute_plane(p0, p1, p2, q0, q1, q2, vPlane[attr]);
+ if (attr < FRAG_ATTRIB_VAR0) {
+ const GLuint u = attr - FRAG_ATTRIB_TEX0;
+ const struct gl_texture_object *obj = ctx->Texture.Unit[u]._Current;
+ const struct gl_texture_image *texImage = obj->Image[0][obj->BaseLevel];
+ texWidth[attr] = (GLfloat) texImage->Width;
+ texHeight[attr] = (GLfloat) texImage->Height;
+ }
+ else {
+ texWidth[attr] = texHeight[attr] = 1.0;
+ }
}
}
}
- span.arrayMask |= (SPAN_TEXTURE | SPAN_LAMBDA);
+ span.arrayMask |= (SPAN_TEXTURE | SPAN_LAMBDA | SPAN_VARYING);
#endif
/* Begin bottom-to-top scan over the triangle.
@@ -289,7 +266,7 @@
array->z[count] = (GLuint) solve_plane(cx, cy, zPlane);
#endif
#ifdef DO_FOG
- array->fog[count] = solve_plane(cx, cy, fogPlane);
+ array->attribs[FRAG_ATTRIB_FOGC][count][0] = solve_plane(cx, cy, fogPlane);
#endif
#ifdef DO_RGBA
array->rgba[count][RCOMP] = solve_plane_chan(cx, cy, rPlane);
@@ -305,28 +282,21 @@
array->spec[count][GCOMP] = solve_plane_chan(cx, cy, sgPlane);
array->spec[count][BCOMP] = solve_plane_chan(cx, cy, sbPlane);
#endif
-#ifdef DO_TEX
+#if defined(DO_TEXVAR)
{
- const GLfloat invQ = solve_plane_recip(cx, cy, vPlane);
- array->texcoords[0][count][0] = solve_plane(cx, cy, sPlane) * invQ;
- array->texcoords[0][count][1] = solve_plane(cx, cy, tPlane) * invQ;
- array->texcoords[0][count][2] = solve_plane(cx, cy, uPlane) * invQ;
- array->lambda[0][count] = compute_lambda(sPlane, tPlane, vPlane,
- cx, cy, invQ,
- texWidth, texHeight);
- }
-#elif defined(DO_MULTITEX)
- {
- GLuint unit;
- for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) {
- if (ctx->Texture.Unit[unit]._ReallyEnabled) {
- GLfloat invQ = solve_plane_recip(cx, cy, vPlane[unit]);
- array->texcoords[unit][count][0] = solve_plane(cx, cy, sPlane[unit]) * invQ;
- array->texcoords[unit][count][1] = solve_plane(cx, cy, tPlane[unit]) * invQ;
- array->texcoords[unit][count][2] = solve_plane(cx, cy, uPlane[unit]) * invQ;
- array->lambda[unit][count] = compute_lambda(sPlane[unit],
- tPlane[unit], vPlane[unit], cx, cy, invQ,
- texWidth[unit], texHeight[unit]);
+ GLuint attr;
+ for (attr = swrast->_MinFragmentAttrib; attr < swrast->_MaxFragmentAttrib; attr++) {
+ if (swrast->_FragmentAttribs & (1 << attr)) {
+ GLfloat invQ = solve_plane_recip(cx, cy, vPlane[attr]);
+ array->attribs[attr][count][0] = solve_plane(cx, cy, sPlane[attr]) * invQ;
+ array->attribs[attr][count][1] = solve_plane(cx, cy, tPlane[attr]) * invQ;
+ array->attribs[attr][count][2] = solve_plane(cx, cy, uPlane[attr]) * invQ;
+ if (attr < FRAG_ATTRIB_VAR0) {
+ const GLuint unit = attr - FRAG_ATTRIB_TEX0;
+ array->lambda[unit][count] = compute_lambda(sPlane[attr], tPlane[attr],
+ vPlane[attr], cx, cy, invQ,
+ texWidth[attr], texHeight[attr]);
+ }
}
}
}
@@ -393,7 +363,7 @@
array->z[ix] = (GLuint) solve_plane(cx, cy, zPlane);
#endif
#ifdef DO_FOG
- array->fog[ix] = solve_plane(cx, cy, fogPlane);
+ array->attribs[FRAG_ATTRIB_FOGC][ix][0] = solve_plane(cx, cy, fogPlane);
#endif
#ifdef DO_RGBA
array->rgba[ix][RCOMP] = solve_plane_chan(cx, cy, rPlane);
@@ -409,30 +379,24 @@
array->spec[ix][GCOMP] = solve_plane_chan(cx, cy, sgPlane);
array->spec[ix][BCOMP] = solve_plane_chan(cx, cy, sbPlane);
#endif
-#ifdef DO_TEX
- {
- const GLfloat invQ = solve_plane_recip(cx, cy, vPlane);
- array->texcoords[0][ix][0] = solve_plane(cx, cy, sPlane) * invQ;
- array->texcoords[0][ix][1] = solve_plane(cx, cy, tPlane) * invQ;
- array->texcoords[0][ix][2] = solve_plane(cx, cy, uPlane) * invQ;
- array->lambda[0][ix] = compute_lambda(sPlane, tPlane, vPlane,
- cx, cy, invQ, texWidth, texHeight);
- }
-#elif defined(DO_MULTITEX)
+#if defined(DO_TEXVAR)
{
- GLuint unit;
- for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) {
- if (ctx->Texture.Unit[unit]._ReallyEnabled) {
- GLfloat invQ = solve_plane_recip(cx, cy, vPlane[unit]);
- array->texcoords[unit][ix][0] = solve_plane(cx, cy, sPlane[unit]) * invQ;
- array->texcoords[unit][ix][1] = solve_plane(cx, cy, tPlane[unit]) * invQ;
- array->texcoords[unit][ix][2] = solve_plane(cx, cy, uPlane[unit]) * invQ;
- array->lambda[unit][ix] = compute_lambda(sPlane[unit],
- tPlane[unit],
- vPlane[unit],
- cx, cy, invQ,
- texWidth[unit],
- texHeight[unit]);
+ GLuint attr;
+ for (attr = swrast->_MinFragmentAttrib; attr < swrast->_MaxFragmentAttrib; attr++) {
+ if (swrast->_FragmentAttribs & (1 << attr)) {
+ GLfloat invQ = solve_plane_recip(cx, cy, vPlane[attr]);
+ array->attribs[attr][ix][0] = solve_plane(cx, cy, sPlane[attr]) * invQ;
+ array->attribs[attr][ix][1] = solve_plane(cx, cy, tPlane[attr]) * invQ;
+ array->attribs[attr][ix][2] = solve_plane(cx, cy, uPlane[attr]) * invQ;
+ if (attr < FRAG_ATTRIB_VAR0) {
+ const GLuint unit = attr - FRAG_ATTRIB_TEX0;
+ array->lambda[unit][ix] = compute_lambda(sPlane[attr],
+ tPlane[attr],
+ vPlane[attr],
+ cx, cy, invQ,
+ texWidth[attr],
+ texHeight[attr]);
+ }
}
}
}
@@ -468,30 +432,28 @@
array->z[j] = array->z[j + left];
#endif
#ifdef DO_FOG
- array->fog[j] = array->fog[j + left];
+ array->attribs[FRAG_ATTRIB_FOGC][j][0]
+ = array->attribs[FRAG_ATTRIB_FOGC][j + left][0];
#endif
-#ifdef DO_TEX
- COPY_4V(array->texcoords[0][j], array->texcoords[0][j + left]);
-#endif
-#if defined(DO_MULTITEX) || defined(DO_TEX)
+#if defined(DO_TEXVAR)
array->lambda[0][j] = array->lambda[0][j + left];
#endif
array->coverage[j] = array->coverage[j + left];
}
}
-#ifdef DO_MULTITEX
- /* shift texcoords */
+#ifdef DO_TEXVAR
+ /* shift texcoords, varying */
{
SWspanarrays *array = span.array;
- GLuint unit;
- for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) {
- if (ctx->Texture.Unit[unit]._ReallyEnabled) {
+ GLuint attr;
+ for (attr = swrast->_MinFragmentAttrib; attr < swrast->_MaxFragmentAttrib; attr++) {
+ if (swrast->_FragmentAttribs & (1 << attr)) {
GLint j;
for (j = 0; j < (GLint) n; j++) {
- array->texcoords[unit][j][0] = array->texcoords[unit][j + left][0];
- array->texcoords[unit][j][1] = array->texcoords[unit][j + left][1];
- array->texcoords[unit][j][2] = array->texcoords[unit][j + left][2];
- array->lambda[unit][j] = array->lambda[unit][j + left];
+ array->attribs[attr][j][0] = array->attribs[attr][j + left][0];
+ array->attribs[attr][j][1] = array->attribs[attr][j + left][1];
+ array->attribs[attr][j][2] = array->attribs[attr][j + left][2];
+ /*array->lambda[unit][j] = array->lambda[unit][j + left];*/
}
}
}
@@ -532,12 +494,8 @@
#undef DO_SPEC
#endif
-#ifdef DO_TEX
-#undef DO_TEX
-#endif
-
-#ifdef DO_MULTITEX
-#undef DO_MULTITEX
+#ifdef DO_TEXVAR
+#undef DO_TEXVAR
#endif
#ifdef DO_OCCLUSION_TEST
diff --git a/src/mesa/swrast/s_alpha.c b/src/mesa/swrast/s_alpha.c
index 87a016512cd..af8a6baddc2 100644
--- a/src/mesa/swrast/s_alpha.c
+++ b/src/mesa/swrast/s_alpha.c
@@ -123,7 +123,7 @@ _swrast_alpha_test(const GLcontext *ctx, SWspan *span)
ALPHA_TEST(rgba[i][ACOMP], ;);
}
else {
- GLfloat (*rgba)[4] = span->array->color.sz4.rgba;
+ GLfloat (*rgba)[4] = span->array->attribs[FRAG_ATTRIB_COL0];
const GLfloat ref = ctx->Color.AlphaRef;
ALPHA_TEST(rgba[i][ACOMP], ;);
}
diff --git a/src/mesa/swrast/s_arbshader.c b/src/mesa/swrast/s_arbshader.c
deleted file mode 100644
index 356e43c8198..00000000000
--- a/src/mesa/swrast/s_arbshader.c
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version: 6.5.3
- *
- * Copyright (C) 2006 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"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- * Michal Krol
- */
-
-#include "glheader.h"
-#include "context.h"
-#include "colormac.h"
-#include "s_arbshader.h"
-#include "s_context.h"
-#include "shaderobjects.h"
-#include "shaderobjects_3dlabs.h"
-#include "slang_utility.h"
-#include "slang_link.h"
-
-#if FEATURE_ARB_fragment_shader
-
-void
-_swrast_exec_arbshader(GLcontext *ctx, SWspan *span)
-{
- struct gl2_program_intf **pro;
- GLuint i;
-
- ASSERT(span->array->ChanType == GL_FLOAT);
-
- if (!ctx->ShaderObjects._FragmentShaderPresent)
- return;
-
- pro = ctx->ShaderObjects.CurrentProgram;
- if (!ctx->ShaderObjects._VertexShaderPresent)
- (**pro).UpdateFixedUniforms(pro);
-
- for (i = span->start; i < span->end; i++) {
- /* only run shader on active fragments */
- if (span->array->mask[i]) {
- GLfloat vec[4];
- GLuint j;
- GLboolean discard;
-
- /*
- * Load input attributes
- */
- vec[0] = (GLfloat) span->x + i;
- vec[1] = (GLfloat) span->y;
- vec[2] = (GLfloat) span->array->z[i] / ctx->DrawBuffer->_DepthMaxF;
- vec[3] = span->w + span->dwdx * i;
- (**pro).UpdateFixedVarying(pro, SLANG_FRAGMENT_FIXED_FRAGCOORD, vec,
- 0, 4 * sizeof(GLfloat), GL_TRUE);
-
- (**pro).UpdateFixedVarying(pro, SLANG_FRAGMENT_FIXED_COLOR,
- span->array->color.sz4.rgba[i],
- 0, 4 * sizeof(GLfloat), GL_TRUE);
-
- (**pro).UpdateFixedVarying(pro, SLANG_FRAGMENT_FIXED_SECONDARYCOLOR,
- span->array->color.sz4.spec[i],
- 0, 4 * sizeof(GLfloat), GL_TRUE);
-
- for (j = 0; j < ctx->Const.MaxTextureCoordUnits; j++) {
- (**pro).UpdateFixedVarying(pro, SLANG_FRAGMENT_FIXED_TEXCOORD,
- span->array->texcoords[j][i],
- j, 4 * sizeof(GLfloat), GL_TRUE);
- }
-
- for (j = 0; j < MAX_VARYING_VECTORS; j++) {
- GLuint k;
- for (k = 0; k < VARYINGS_PER_VECTOR; k++) {
- (**pro).UpdateVarying(pro, j * VARYINGS_PER_VECTOR + k,
- &span->array->varying[i][j][k],
- GL_FALSE);
- }
- }
-
- _slang_exec_fragment_shader(pro);
-
- /*
- * Store results
- */
- _slang_fetch_discard(pro, &discard);
- if (discard) {
- span->array->mask[i] = GL_FALSE;
- span->writeAll = GL_FALSE;
- }
- else {
- GLboolean zWritten = GL_FALSE; /* temp hack (bug 9345) */
- (**pro).UpdateFixedVarying(pro, SLANG_FRAGMENT_FIXED_FRAGCOLOR,
- vec, 0, 4 * sizeof(GLfloat), GL_FALSE);
- COPY_4V(span->array->color.sz4.rgba[i], vec);
- if (zWritten) {
- (**pro).UpdateFixedVarying(pro, SLANG_FRAGMENT_FIXED_FRAGDEPTH,
- vec, 0, sizeof (GLfloat), GL_FALSE);
- if (vec[0] <= 0.0f)
- span->array->z[i] = 0;
- else if (vec[0] >= 1.0f)
- span->array->z[i] = ctx->DrawBuffer->_DepthMax;
- else
- span->array->z[i] = IROUND(vec[0] * ctx->DrawBuffer->_DepthMaxF);
- }
- }
- }
- }
-}
-
-#endif /* FEATURE_ARB_fragment_shader */
-
diff --git a/src/mesa/swrast/s_arbshader.h b/src/mesa/swrast/s_arbshader.h
deleted file mode 100644
index 5df80c870b0..00000000000
--- a/src/mesa/swrast/s_arbshader.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version: 6.5
- *
- * Copyright (C) 2006 David Airlie 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"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * DAVID AIRLIE BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-
-#ifndef S_ARBSHADER_H
-#define S_ARBSHADER_H
-
-#include "s_context.h"
-
-#if FEATURE_ARB_fragment_shader
-
-extern void _swrast_exec_arbshader (GLcontext *ctx, SWspan *span);
-
-#endif /* FEATURE_ARB_fragment_shader */
-
-#endif
-
diff --git a/src/mesa/swrast/s_atifragshader.c b/src/mesa/swrast/s_atifragshader.c
index 467b8652d81..947054faa30 100644
--- a/src/mesa/swrast/s_atifragshader.c
+++ b/src/mesa/swrast/s_atifragshader.c
@@ -268,7 +268,7 @@ handle_pass_op(struct atifs_machine *machine, struct atifs_setupinst *texinst,
if (pass_tex >= GL_TEXTURE0_ARB && pass_tex <= GL_TEXTURE7_ARB) {
pass_tex -= GL_TEXTURE0_ARB;
COPY_4V(machine->Registers[idx],
- span->array->texcoords[pass_tex][column]);
+ span->array->attribs[FRAG_ATTRIB_TEX0 + pass_tex][column]);
}
else if (pass_tex >= GL_REG_0_ATI && pass_tex <= GL_REG_5_ATI) {
pass_tex -= GL_REG_0_ATI;
@@ -290,7 +290,8 @@ handle_sample_op(GLcontext * ctx, struct atifs_machine *machine,
if (coord_source >= GL_TEXTURE0_ARB && coord_source <= GL_TEXTURE7_ARB) {
coord_source -= GL_TEXTURE0_ARB;
- COPY_4V(tex_coords, span->array->texcoords[coord_source][column]);
+ COPY_4V(tex_coords,
+ span->array->attribs[FRAG_ATTRIB_TEX0 + coord_source][column]);
}
else if (coord_source >= GL_REG_0_ATI && coord_source <= GL_REG_5_ATI) {
coord_source -= GL_REG_0_ATI;
@@ -573,8 +574,8 @@ init_machine(GLcontext * ctx, struct atifs_machine *machine,
machine->Registers[i][j] = 0.0;
}
- COPY_4V(inputs[ATI_FS_INPUT_PRIMARY], span->array->color.sz4.rgba[col]);
- COPY_4V(inputs[ATI_FS_INPUT_SECONDARY], span->array->color.sz4.spec[col]);
+ COPY_4V(inputs[ATI_FS_INPUT_PRIMARY], span->array->attribs[FRAG_ATTRIB_COL0][col]);
+ COPY_4V(inputs[ATI_FS_INPUT_SECONDARY], span->array->attribs[FRAG_ATTRIB_COL1][col]);
}
@@ -605,7 +606,7 @@ _swrast_exec_fragment_shader(GLcontext * ctx, SWspan *span)
const GLfloat *colOut = machine.Registers[0];
/*fprintf(stderr,"outputs %f %f %f %f\n",
colOut[0], colOut[1], colOut[2], colOut[3]); */
- COPY_4V(span->array->color.sz4.rgba[i], colOut);
+ COPY_4V(span->array->attribs[FRAG_ATTRIB_COL0][i], colOut);
}
}
}
diff --git a/src/mesa/swrast/s_context.c b/src/mesa/swrast/s_context.c
index 1c9a098a2d5..00702b43013 100644
--- a/src/mesa/swrast/s_context.c
+++ b/src/mesa/swrast/s_context.c
@@ -2,7 +2,7 @@
* Mesa 3-D graphics library
* Version: 6.5.3
*
- * Copyright (C) 1999-2006 Brian Paul All Rights Reserved.
+ * Copyright (C) 1999-2007 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"),
@@ -31,7 +31,7 @@
#include "context.h"
#include "colormac.h"
#include "mtypes.h"
-#include "program.h"
+#include "prog_statevars.h"
#include "teximage.h"
#include "swrast.h"
#include "s_blend.h"
@@ -98,11 +98,7 @@ _swrast_update_rasterflags( GLcontext *ctx )
rasterMask |= MULTI_DRAW_BIT; /* all color index bits disabled */
}
- if (ctx->FragmentProgram._Enabled) {
- rasterMask |= FRAGPROG_BIT;
- }
-
- if (ctx->ShaderObjects._FragmentShaderPresent) {
+ if (ctx->FragmentProgram._Current) {
rasterMask |= FRAGPROG_BIT;
}
@@ -129,27 +125,28 @@ _swrast_update_rasterflags( GLcontext *ctx )
static void
_swrast_update_polygon( GLcontext *ctx )
{
- GLfloat backface_sign = 1;
+ GLfloat backface_sign;
if (ctx->Polygon.CullFlag) {
- backface_sign = 1;
- switch(ctx->Polygon.CullFaceMode) {
+ backface_sign = 1.0;
+ switch (ctx->Polygon.CullFaceMode) {
case GL_BACK:
- if(ctx->Polygon.FrontFace==GL_CCW)
- backface_sign = -1;
+ if (ctx->Polygon.FrontFace == GL_CCW)
+ backface_sign = -1.0;
break;
case GL_FRONT:
- if(ctx->Polygon.FrontFace!=GL_CCW)
- backface_sign = -1;
+ if (ctx->Polygon.FrontFace != GL_CCW)
+ backface_sign = -1.0;
break;
- default:
case GL_FRONT_AND_BACK:
- backface_sign = 0;
+ /* fallthrough */
+ default:
+ backface_sign = 0.0;
break;
}
}
else {
- backface_sign = 0;
+ backface_sign = 0.0;
}
SWRAST_CONTEXT(ctx)->_BackfaceSign = backface_sign;
@@ -165,7 +162,7 @@ _swrast_update_fog_hint( GLcontext *ctx )
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
swrast->_PreferPixelFog = (!swrast->AllowVertexFog ||
- ctx->FragmentProgram._Enabled || /* not _Active! */
+ ctx->FragmentProgram._Current ||
(ctx->Hint.Fog == GL_NICEST &&
swrast->AllowPixelFog));
}
@@ -198,20 +195,14 @@ static void
_swrast_update_fog_state( GLcontext *ctx )
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
+ const struct gl_fragment_program *fp = ctx->FragmentProgram._Current;
/* determine if fog is needed, and if so, which fog mode */
swrast->_FogEnabled = GL_FALSE;
- if (ctx->ShaderObjects._FragmentShaderPresent) {
- swrast->_FogEnabled = GL_FALSE;
- }
- else if (ctx->FragmentProgram._Enabled) {
- if (ctx->FragmentProgram._Current->Base.Target==GL_FRAGMENT_PROGRAM_ARB) {
- const struct gl_fragment_program *fp
- = ctx->FragmentProgram._Current;
- if (fp->FogOption != GL_NONE) {
- swrast->_FogEnabled = GL_TRUE;
- swrast->_FogMode = fp->FogOption;
- }
+ if (fp && fp->Base.Target == GL_FRAGMENT_PROGRAM_ARB) {
+ if (fp->FogOption != GL_NONE) {
+ swrast->_FogEnabled = GL_TRUE;
+ swrast->_FogMode = fp->FogOption;
}
}
else if (ctx->Fog.Enabled) {
@@ -228,8 +219,8 @@ _swrast_update_fog_state( GLcontext *ctx )
static void
_swrast_update_fragment_program(GLcontext *ctx, GLbitfield newState)
{
- if (ctx->FragmentProgram._Enabled) {
- const struct gl_fragment_program *fp = ctx->FragmentProgram._Current;
+ const struct gl_fragment_program *fp = ctx->FragmentProgram._Current;
+ if (fp) {
#if 0
/* XXX Need a way to trigger the initial loading of parameters
* even when there's no recent state changes.
@@ -304,7 +295,7 @@ _swrast_validate_triangle( GLcontext *ctx,
if (ctx->Texture._EnabledUnits == 0
&& NEED_SECONDARY_COLOR(ctx)
- && !ctx->FragmentProgram._Enabled) {
+ && !ctx->FragmentProgram._Current) {
/* separate specular color, but no texture */
swrast->SpecTriangle = swrast->Triangle;
swrast->Triangle = _swrast_add_spec_terms_triangle;
@@ -328,7 +319,7 @@ _swrast_validate_line( GLcontext *ctx, const SWvertex *v0, const SWvertex *v1 )
if (ctx->Texture._EnabledUnits == 0
&& NEED_SECONDARY_COLOR(ctx)
- && !ctx->FragmentProgram._Enabled) {
+ && !ctx->FragmentProgram._Current) {
swrast->SpecLine = swrast->Line;
swrast->Line = _swrast_add_spec_terms_line;
}
@@ -351,7 +342,7 @@ _swrast_validate_point( GLcontext *ctx, const SWvertex *v0 )
if (ctx->Texture._EnabledUnits == 0
&& NEED_SECONDARY_COLOR(ctx)
- && !ctx->FragmentProgram._Enabled) {
+ && !ctx->FragmentProgram._Current) {
swrast->SpecPoint = swrast->Point;
swrast->Point = _swrast_add_spec_terms_point;
}
@@ -505,9 +496,92 @@ _swrast_update_texture_samplers(GLcontext *ctx)
for (u = 0; u < ctx->Const.MaxTextureImageUnits; u++) {
const struct gl_texture_object *tObj = ctx->Texture.Unit[u]._Current;
- if (tObj)
- swrast->TextureSample[u] =
- _swrast_choose_texture_sample_func(ctx, tObj);
+ /* Note: If tObj is NULL, the sample function will be a simple
+ * function that just returns opaque black (0,0,0,1).
+ */
+ swrast->TextureSample[u] = _swrast_choose_texture_sample_func(ctx, tObj);
+ }
+}
+
+
+/**
+ * Update the swrast->_FragmentAttribs field.
+ */
+static void
+_swrast_update_fragment_attribs(GLcontext *ctx)
+{
+ SWcontext *swrast = SWRAST_CONTEXT(ctx);
+
+ if (ctx->FragmentProgram._Current) {
+ swrast->_FragmentAttribs
+ = ctx->FragmentProgram._Current->Base.InputsRead;
+ }
+ else {
+ GLuint u;
+ swrast->_FragmentAttribs = 0x0;
+
+ if (ctx->Depth.Test)
+ swrast->_FragmentAttribs |= FRAG_BIT_WPOS;
+ if (NEED_SECONDARY_COLOR(ctx))
+ swrast->_FragmentAttribs |= FRAG_BIT_COL1;
+ if (swrast->_FogEnabled)
+ swrast->_FragmentAttribs |= FRAG_BIT_FOGC;
+
+ for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
+ if (ctx->Texture.Unit[u]._ReallyEnabled) {
+ swrast->_FragmentAttribs |= FRAG_BIT_TEX(u);
+ }
+ }
+ }
+
+ /* Find lowest, highest bit set in _FragmentAttribs */
+ {
+ GLuint bits = swrast->_FragmentAttribs;
+ GLuint i = 0;;
+ while (bits) {
+ i++;
+ bits = bits >> 1;
+ }
+ swrast->_MaxFragmentAttrib = i;
+ swrast->_MinFragmentAttrib = FRAG_ATTRIB_TEX0; /* XXX temporary */
+ }
+}
+
+
+/**
+ * Update the swrast->_ColorOutputsMask which indicates which color
+ * renderbuffers (aka rendertargets) are being written to by the current
+ * fragment program.
+ * We also take glDrawBuffers() into account to skip outputs that are
+ * set to GL_NONE.
+ */
+static void
+_swrast_update_color_outputs(GLcontext *ctx)
+{
+ SWcontext *swrast = SWRAST_CONTEXT(ctx);
+ const struct gl_framebuffer *fb = ctx->DrawBuffer;
+
+ swrast->_ColorOutputsMask = 0;
+ swrast->_NumColorOutputs = 0;
+
+ if (ctx->FragmentProgram._Current) {
+ const GLbitfield outputsWritten
+ = ctx->FragmentProgram._Current->Base.OutputsWritten;
+ GLuint output;
+ for (output = 0; output < ctx->Const.MaxDrawBuffers; output++) {
+ if ((outputsWritten & (1 << (FRAG_RESULT_DATA0 + output)))
+ && (fb->_NumColorDrawBuffers[output] > 0)) {
+ swrast->_ColorOutputsMask |= (1 << output);
+ swrast->_NumColorOutputs = output + 1;
+ }
+ }
+ }
+ if (swrast->_ColorOutputsMask == 0x0) {
+ /* no fragment program, or frag prog didn't write to gl_FragData[] */
+ if (fb->_NumColorDrawBuffers[0] > 0) {
+ swrast->_ColorOutputsMask = 0x1;
+ swrast->_NumColorOutputs = 1;
+ }
}
}
@@ -552,6 +626,15 @@ _swrast_validate_derived( GLcontext *ctx )
if (swrast->NewState & _SWRAST_NEW_RASTERMASK)
_swrast_update_rasterflags( ctx );
+ if (swrast->NewState & (_NEW_DEPTH |
+ _NEW_FOG |
+ _NEW_PROGRAM |
+ _NEW_TEXTURE))
+ _swrast_update_fragment_attribs(ctx);
+
+ if (swrast->NewState & (_NEW_PROGRAM | _NEW_BUFFERS))
+ _swrast_update_color_outputs(ctx);
+
swrast->NewState = 0;
swrast->StateChanges = 0;
swrast->InvalidateState = _swrast_invalidate_state;
@@ -709,7 +792,6 @@ _swrast_CreateContext( GLcontext *ctx )
/* init point span buffer */
swrast->PointSpan.primitive = GL_POINT;
- swrast->PointSpan.start = 0;
swrast->PointSpan.end = 0;
swrast->PointSpan.facing = 0;
swrast->PointSpan.array = swrast->SpanArrays;
@@ -812,8 +894,10 @@ _swrast_print_vertex( GLcontext *ctx, const SWvertex *v )
for (i = 0 ; i < ctx->Const.MaxTextureCoordUnits ; i++)
if (ctx->Texture.Unit[i]._ReallyEnabled)
_mesa_debug(ctx, "texcoord[%d] %f %f %f %f\n", i,
- v->texcoord[i][0], v->texcoord[i][1],
- v->texcoord[i][2], v->texcoord[i][3]);
+ v->attrib[FRAG_ATTRIB_TEX0 + i][0],
+ v->attrib[FRAG_ATTRIB_TEX0 + i][1],
+ v->attrib[FRAG_ATTRIB_TEX0 + i][2],
+ v->attrib[FRAG_ATTRIB_TEX0 + i][3]);
#if CHAN_TYPE == GL_FLOAT
_mesa_debug(ctx, "color %f %f %f %f\n",
diff --git a/src/mesa/swrast/s_context.h b/src/mesa/swrast/s_context.h
index 37d7081d4d6..3a9a48922ef 100644
--- a/src/mesa/swrast/s_context.h
+++ b/src/mesa/swrast/s_context.h
@@ -45,204 +45,7 @@
#include "mtypes.h"
#include "swrast.h"
-
-
-/**
- * \defgroup SpanFlags SPAN_XXX-flags
- * Bitmasks to indicate which sw_span_arrays need to be computed
- * (sw_span::interpMask) or have already been filled in (sw_span::arrayMask)
- */
-/*@{*/
-#define SPAN_RGBA 0x001
-#define SPAN_SPEC 0x002
-#define SPAN_INDEX 0x004
-#define SPAN_Z 0x008
-#define SPAN_W 0x010
-#define SPAN_FOG 0x020
-#define SPAN_TEXTURE 0x040
-#define SPAN_INT_TEXTURE 0x080
-#define SPAN_LAMBDA 0x100
-#define SPAN_COVERAGE 0x200
-#define SPAN_FLAT 0x400 /**< flat shading? */
-#define SPAN_XY 0x800
-#define SPAN_MASK 0x1000
-#define SPAN_VARYING 0x2000
-/*@}*/
-
-#if 0
-/* alternate arrangement for code below */
-struct arrays2 {
- union {
- GLubyte sz1[MAX_WIDTH][4]; /* primary color */
- GLushort sz2[MAX_WIDTH][4];
- GLfloat sz4[MAX_WIDTH][4];
- } rgba;
- union {
- GLubyte sz1[MAX_WIDTH][4]; /* specular color and temp storage */
- GLushort sz2[MAX_WIDTH][4];
- GLfloat sz4[MAX_WIDTH][4];
- } spec;
-};
-#endif
-
-
-/**
- * \sw_span_arrays
- * \brief Arrays of fragment values.
- *
- * These will either be computed from the x/xStep values above or
- * filled in by glDraw/CopyPixels, etc.
- * These arrays are separated out of sw_span to conserve memory.
- */
-typedef struct sw_span_arrays {
- GLenum ChanType; /**< Color channel type, GL_UNSIGNED_BYTE, GL_FLOAT */
- union {
- struct {
- GLubyte rgba[MAX_WIDTH][4]; /**< primary color */
- GLubyte spec[MAX_WIDTH][4]; /**< specular color and temp storage */
- } sz1;
- struct {
- GLushort rgba[MAX_WIDTH][4];
- GLushort spec[MAX_WIDTH][4];
- } sz2;
- struct {
- GLfloat rgba[MAX_WIDTH][4];
- GLfloat spec[MAX_WIDTH][4];
- } sz4;
- } color;
- /** XXX these are temporary fields, pointing into above color arrays */
- GLchan (*rgba)[4];
- GLchan (*spec)[4];
-
- GLuint index[MAX_WIDTH];
- GLint x[MAX_WIDTH]; /**< X/Y used for point/line rendering only */
- GLint y[MAX_WIDTH]; /**< X/Y used for point/line rendering only */
- GLuint z[MAX_WIDTH];
- GLfloat fog[MAX_WIDTH];
- GLfloat texcoords[MAX_TEXTURE_COORD_UNITS][MAX_WIDTH][4];
- GLfloat lambda[MAX_TEXTURE_COORD_UNITS][MAX_WIDTH];
- GLfloat coverage[MAX_WIDTH];
- GLfloat varying[MAX_WIDTH][MAX_VARYING_VECTORS][VARYINGS_PER_VECTOR];
-
- /** This mask indicates which fragments are alive or culled */
- GLubyte mask[MAX_WIDTH];
-} SWspanarrays;
-
-
-/**
- * \SWspan
- * \brief Contains data for either a horizontal line or a set of
- * pixels that are passed through a pipeline of functions before being
- * drawn.
- *
- * The sw_span structure describes the colors, Z, fogcoord, texcoords,
- * etc for either a horizontal run or an array of independent pixels.
- * We can either specify a base/step to indicate interpolated values, or
- * fill in arrays of values. The interpMask and arrayMask bitfields
- * indicate which are active.
- *
- * With this structure it's easy to hand-off span rasterization to
- * subroutines instead of doing it all inline in the triangle functions
- * like we used to do.
- * It also cleans up the local variable namespace a great deal.
- *
- * It would be interesting to experiment with multiprocessor rasterization
- * with this structure. The triangle rasterizer could simply emit a
- * stream of these structures which would be consumed by one or more
- * span-processing threads which could run in parallel.
- */
-typedef struct sw_span {
- GLint x, y;
-
- /** Only need to process pixels between start <= i < end */
- /** At this time, start is always zero. */
- GLuint start, end;
-
- /** This flag indicates that mask[] array is effectively filled with ones */
- GLboolean writeAll;
-
- /** either GL_POLYGON, GL_LINE, GL_POLYGON, GL_BITMAP */
- GLenum primitive;
-
- /** 0 = front-facing span, 1 = back-facing span (for two-sided stencil) */
- GLuint facing;
-
- /**
- * This bitmask (of \link SpanFlags SPAN_* flags\endlink) indicates
- * which of the x/xStep variables are relevant.
- */
- GLbitfield interpMask;
-
- /* For horizontal spans, step is the partial derivative wrt X.
- * For lines, step is the delta from one fragment to the next.
- */
-#if CHAN_TYPE == GL_FLOAT
- GLfloat red, redStep;
- GLfloat green, greenStep;
- GLfloat blue, blueStep;
- GLfloat alpha, alphaStep;
- GLfloat specRed, specRedStep;
- GLfloat specGreen, specGreenStep;
- GLfloat specBlue, specBlueStep;
-#else /* CHAN_TYPE == GL_UNSIGNED_BYTE or GL_UNSIGNED_SHORT */
- GLfixed red, redStep;
- GLfixed green, greenStep;
- GLfixed blue, blueStep;
- GLfixed alpha, alphaStep;
- GLfixed specRed, specRedStep;
- GLfixed specGreen, specGreenStep;
- GLfixed specBlue, specBlueStep;
-#endif
- GLfixed index, indexStep;
- GLfixed z, zStep; /* XXX z should probably be GLuint */
- GLfloat fog, fogStep;
- GLfloat tex[MAX_TEXTURE_COORD_UNITS][4]; /* s, t, r, q */
- GLfloat texStepX[MAX_TEXTURE_COORD_UNITS][4];
- GLfloat texStepY[MAX_TEXTURE_COORD_UNITS][4];
- GLfixed intTex[2], intTexStep[2]; /* s, t only */
- GLfloat var[MAX_VARYING_VECTORS][VARYINGS_PER_VECTOR];
- GLfloat varStepX[MAX_VARYING_VECTORS][VARYINGS_PER_VECTOR];
- GLfloat varStepY[MAX_VARYING_VECTORS][VARYINGS_PER_VECTOR];
-
- /* partial derivatives wrt X and Y. */
- GLfloat dzdx, dzdy;
- GLfloat w, dwdx, dwdy;
- GLfloat drdx, drdy;
- GLfloat dgdx, dgdy;
- GLfloat dbdx, dbdy;
- GLfloat dadx, dady;
- GLfloat dsrdx, dsrdy;
- GLfloat dsgdx, dsgdy;
- GLfloat dsbdx, dsbdy;
- GLfloat dfogdx, dfogdy;
-
- /**
- * This bitmask (of \link SpanFlags SPAN_* flags\endlink) indicates
- * which of the fragment arrays in the span_arrays struct are relevant.
- */
- GLbitfield arrayMask;
-
- /**
- * We store the arrays of fragment values in a separate struct so
- * that we can allocate sw_span structs on the stack without using
- * a lot of memory. The span_arrays struct is about 400KB while the
- * sw_span struct is only about 512 bytes.
- */
- SWspanarrays *array;
-} SWspan;
-
-
-
-#define INIT_SPAN(S, PRIMITIVE, END, INTERP_MASK, ARRAY_MASK) \
-do { \
- (S).primitive = (PRIMITIVE); \
- (S).interpMask = (INTERP_MASK); \
- (S).arrayMask = (ARRAY_MASK); \
- (S).start = 0; \
- (S).end = (END); \
- (S).facing = 0; \
- (S).array = SWRAST_CONTEXT(ctx)->SpanArrays; \
-} while (0)
+#include "s_span.h"
typedef void (*texture_sample_func)(GLcontext *ctx,
@@ -269,7 +72,8 @@ typedef void (*validate_texture_image_func)(GLcontext *ctx,
GLuint face, GLuint level);
-/** \defgroup Bitmasks
+/**
+ * \defgroup Bitmasks
* Bitmasks to indicate which rasterization options are enabled
* (RasterMask)
*/
@@ -329,6 +133,17 @@ typedef struct
GLboolean _FogEnabled;
GLenum _FogMode; /* either GL_FOG_MODE or fragment program's fog mode */
+ /** Multiple render targets */
+ GLbitfield _ColorOutputsMask;
+ GLuint _NumColorOutputs;
+
+ /** Fragment attributes to compute during rasterization.
+ * Mask of FRAG_BIT_* flags.
+ */
+ GLbitfield _FragmentAttribs;
+ GLuint _MinFragmentAttrib; /**< Lowest bit set in _FragmentAttribs */
+ GLuint _MaxFragmentAttrib; /**< Highest bit set in _FragmentAttribs + 1 */
+
/* Accum buffer temporaries.
*/
GLboolean _IntegerAccumMode; /**< Storing unscaled integers? */
diff --git a/src/mesa/swrast/s_copypix.c b/src/mesa/swrast/s_copypix.c
index b318777072a..2051e1f3b73 100644
--- a/src/mesa/swrast/s_copypix.c
+++ b/src/mesa/swrast/s_copypix.c
@@ -268,7 +268,7 @@ copy_rgba_pixels(GLcontext *ctx, GLint srcx, GLint srcy,
ASSERT(width < MAX_WIDTH);
for (row = 0; row < height; row++, sy += stepy, dy += stepy) {
- GLvoid *rgba = span.array->color.sz4.rgba;
+ GLvoid *rgba = span.array->attribs[FRAG_ATTRIB_COL0];
/* Get row/span of source pixels */
if (overlapping) {
diff --git a/src/mesa/swrast/s_drawpix.c b/src/mesa/swrast/s_drawpix.c
index 99ad71143e0..50147f329f6 100644
--- a/src/mesa/swrast/s_drawpix.c
+++ b/src/mesa/swrast/s_drawpix.c
@@ -644,7 +644,7 @@ draw_rgba_pixels( GLcontext *ctx, GLint x, GLint y,
= _mesa_image_row_stride(unpack, width, format, type);
GLint skipPixels = 0;
/* use span array for temp color storage */
- GLfloat *rgba = (GLfloat *) span.array->color.sz4.rgba;
+ GLfloat *rgba = (GLfloat *) span.array->attribs[FRAG_ATTRIB_COL0];
/* if the span is wider than MAX_WIDTH we have to do it in chunks */
while (skipPixels < width) {
diff --git a/src/mesa/swrast/s_feedback.c b/src/mesa/swrast/s_feedback.c
index 26cb05cd560..5d3fbdfeb6e 100644
--- a/src/mesa/swrast/s_feedback.c
+++ b/src/mesa/swrast/s_feedback.c
@@ -46,10 +46,10 @@
static void feedback_vertex( GLcontext *ctx,
const SWvertex *v, const SWvertex *pv )
{
- const GLuint texUnit = 0; /* See section 5.3 of 1.2.1 spec */
GLfloat win[4];
GLfloat color[4];
GLfloat tc[4];
+ const GLfloat *vtc = v->attrib[FRAG_ATTRIB_TEX0];
win[0] = v->win[0];
win[1] = v->win[1];
@@ -61,16 +61,15 @@ static void feedback_vertex( GLcontext *ctx,
color[2] = CHAN_TO_FLOAT(pv->color[2]);
color[3] = CHAN_TO_FLOAT(pv->color[3]);
- if (v->texcoord[texUnit][3] != 1.0 &&
- v->texcoord[texUnit][3] != 0.0) {
- GLfloat invq = 1.0F / v->texcoord[texUnit][3];
- tc[0] = v->texcoord[texUnit][0] * invq;
- tc[1] = v->texcoord[texUnit][1] * invq;
- tc[2] = v->texcoord[texUnit][2] * invq;
- tc[3] = v->texcoord[texUnit][3];
+ if (vtc[3] != 1.0 && vtc[3] != 0.0) {
+ GLfloat invq = 1.0F / vtc[3];
+ tc[0] = vtc[0] * invq;
+ tc[1] = vtc[1] * invq;
+ tc[2] = vtc[2] * invq;
+ tc[3] = vtc[3];
}
else {
- COPY_4V(tc, v->texcoord[texUnit]);
+ COPY_4V(tc, vtc);
}
_mesa_feedback_vertex( ctx, win, color, (GLfloat) v->index, tc );
diff --git a/src/mesa/swrast/s_fog.c b/src/mesa/swrast/s_fog.c
index f4c3fe4f2dc..433fc4a4d0c 100644
--- a/src/mesa/swrast/s_fog.c
+++ b/src/mesa/swrast/s_fog.c
@@ -72,10 +72,10 @@ _swrast_z_to_fogfactor(GLcontext *ctx, GLfloat z)
*/
#define FOG_LOOP(TYPE, COMPUTE_F) \
do { \
- const GLfloat fogStep = span->fogStep; \
- GLfloat fogCoord = span->fog; \
- const GLfloat wStep = haveW ? span->dwdx : 0.0F; \
- GLfloat w = haveW ? span->w : 1.0F; \
+ const GLfloat fogStep = span->attrStepX[FRAG_ATTRIB_FOGC][0]; \
+ GLfloat fogCoord = span->attrStart[FRAG_ATTRIB_FOGC][0]; \
+ const GLfloat wStep = haveW ? span->attrStepX[FRAG_ATTRIB_WPOS][3] : 0.0F;\
+ GLfloat w = haveW ? span->attrStart[FRAG_ATTRIB_WPOS][3] : 1.0F; \
GLuint i; \
for (i = 0; i < span->end; i++) { \
GLfloat f, oneMinusF; \
@@ -154,7 +154,7 @@ _swrast_fog_rgba_span( const GLcontext *ctx, SWspan *span )
FOG_LOOP(GLushort, COMPUTE_F);
}
else {
- GLfloat (*rgba)[4] = span->array->color.sz4.rgba;
+ GLfloat (*rgba)[4] = span->array->attribs[FRAG_ATTRIB_COL0];
ASSERT(span->array->ChanType == GL_FLOAT);
FOG_LOOP(GLfloat, COMPUTE_F);
}
@@ -172,7 +172,7 @@ _swrast_fog_rgba_span( const GLcontext *ctx, SWspan *span )
FOG_LOOP(GLushort, COMPUTE_F);
}
else {
- GLfloat (*rgba)[4] = span->array->color.sz4.rgba;
+ GLfloat (*rgba)[4] = span->array->attribs[FRAG_ATTRIB_COL0];
ASSERT(span->array->ChanType == GL_FLOAT);
FOG_LOOP(GLfloat, COMPUTE_F);
}
@@ -194,7 +194,7 @@ _swrast_fog_rgba_span( const GLcontext *ctx, SWspan *span )
FOG_LOOP(GLushort, COMPUTE_F);
}
else {
- GLfloat (*rgba)[4] = span->array->color.sz4.rgba;
+ GLfloat (*rgba)[4] = span->array->attribs[FRAG_ATTRIB_COL0];
ASSERT(span->array->ChanType == GL_FLOAT);
FOG_LOOP(GLfloat, COMPUTE_F);
}
@@ -214,7 +214,7 @@ _swrast_fog_rgba_span( const GLcontext *ctx, SWspan *span )
if (span->array->ChanType == GL_UNSIGNED_BYTE) {
GLubyte (*rgba)[4] = span->array->color.sz1.rgba;
for (i = 0; i < span->end; i++) {
- const GLfloat f = span->array->fog[i];
+ const GLfloat f = span->array->attribs[FRAG_ATTRIB_FOGC][i][0];
const GLfloat oneMinusF = 1.0F - f;
rgba[i][RCOMP] = (GLubyte) (f * rgba[i][RCOMP] + oneMinusF * rFog);
rgba[i][GCOMP] = (GLubyte) (f * rgba[i][GCOMP] + oneMinusF * gFog);
@@ -224,7 +224,7 @@ _swrast_fog_rgba_span( const GLcontext *ctx, SWspan *span )
else if (span->array->ChanType == GL_UNSIGNED_SHORT) {
GLushort (*rgba)[4] = span->array->color.sz2.rgba;
for (i = 0; i < span->end; i++) {
- const GLfloat f = span->array->fog[i];
+ const GLfloat f = span->array->attribs[FRAG_ATTRIB_FOGC][i][0];
const GLfloat oneMinusF = 1.0F - f;
rgba[i][RCOMP] = (GLushort) (f * rgba[i][RCOMP] + oneMinusF * rFog);
rgba[i][GCOMP] = (GLushort) (f * rgba[i][GCOMP] + oneMinusF * gFog);
@@ -232,10 +232,10 @@ _swrast_fog_rgba_span( const GLcontext *ctx, SWspan *span )
}
}
else {
- GLfloat (*rgba)[4] = span->array->color.sz4.rgba;
+ GLfloat (*rgba)[4] = span->array->attribs[FRAG_ATTRIB_COL0];
ASSERT(span->array->ChanType == GL_FLOAT);
for (i = 0; i < span->end; i++) {
- const GLfloat f = span->array->fog[i];
+ const GLfloat f = span->array->attribs[FRAG_ATTRIB_FOGC][i][0];
const GLfloat oneMinusF = 1.0F - f;
rgba[i][RCOMP] = f * rgba[i][RCOMP] + oneMinusF * rFog;
rgba[i][GCOMP] = f * rgba[i][GCOMP] + oneMinusF * gFog;
@@ -258,7 +258,7 @@ _swrast_fog_rgba_span( const GLcontext *ctx, SWspan *span )
FOG_LOOP(GLushort, COMPUTE_F);
}
else {
- GLfloat (*rgba)[4] = span->array->color.sz4.rgba;
+ GLfloat (*rgba)[4] = span->array->attribs[FRAG_ATTRIB_COL0];
ASSERT(span->array->ChanType == GL_FLOAT);
FOG_LOOP(GLfloat, COMPUTE_F);
}
@@ -293,10 +293,10 @@ _swrast_fog_ci_span( const GLcontext *ctx, SWspan *span )
const GLfloat fogEnd = ctx->Fog.End;
const GLfloat fogScale = (ctx->Fog.Start == ctx->Fog.End)
? 1.0F : 1.0F / (ctx->Fog.End - ctx->Fog.Start);
- const GLfloat fogStep = span->fogStep;
- GLfloat fogCoord = span->fog;
- const GLfloat wStep = haveW ? span->dwdx : 0.0F;
- GLfloat w = haveW ? span->w : 1.0F;
+ const GLfloat fogStep = span->attrStepX[FRAG_ATTRIB_FOGC][0];
+ GLfloat fogCoord = span->attrStart[FRAG_ATTRIB_FOGC][0];
+ const GLfloat wStep = haveW ? span->attrStepX[FRAG_ATTRIB_WPOS][3] : 0.0F;
+ GLfloat w = haveW ? span->attrStart[FRAG_ATTRIB_WPOS][3] : 1.0F;
GLuint i;
for (i = 0; i < span->end; i++) {
GLfloat f = (fogEnd - fogCoord / w) * fogScale;
@@ -310,10 +310,10 @@ _swrast_fog_ci_span( const GLcontext *ctx, SWspan *span )
case GL_EXP:
{
const GLfloat density = -ctx->Fog.Density;
- const GLfloat fogStep = span->fogStep;
- GLfloat fogCoord = span->fog;
- const GLfloat wStep = haveW ? span->dwdx : 0.0F;
- GLfloat w = haveW ? span->w : 1.0F;
+ const GLfloat fogStep = span->attrStepX[FRAG_ATTRIB_FOGC][0];
+ GLfloat fogCoord = span->attrStart[FRAG_ATTRIB_FOGC][0];
+ const GLfloat wStep = haveW ? span->attrStepX[FRAG_ATTRIB_WPOS][3] : 0.0F;
+ GLfloat w = haveW ? span->attrStart[FRAG_ATTRIB_WPOS][3] : 1.0F;
GLuint i;
for (i = 0; i < span->end; i++) {
GLfloat f = EXPF(density * fogCoord / w);
@@ -327,10 +327,10 @@ _swrast_fog_ci_span( const GLcontext *ctx, SWspan *span )
case GL_EXP2:
{
const GLfloat negDensitySquared = -ctx->Fog.Density * ctx->Fog.Density;
- const GLfloat fogStep = span->fogStep;
- GLfloat fogCoord = span->fog;
- const GLfloat wStep = haveW ? span->dwdx : 0.0F;
- GLfloat w = haveW ? span->w : 1.0F;
+ const GLfloat fogStep = span->attrStepX[FRAG_ATTRIB_FOGC][0];
+ GLfloat fogCoord = span->attrStart[FRAG_ATTRIB_FOGC][0];
+ const GLfloat wStep = haveW ? span->attrStepX[FRAG_ATTRIB_WPOS][3] : 0.0F;
+ GLfloat w = haveW ? span->attrStart[FRAG_ATTRIB_WPOS][3] : 1.0F;
GLuint i;
for (i = 0; i < span->end; i++) {
const GLfloat coord = fogCoord / w;
@@ -360,7 +360,7 @@ _swrast_fog_ci_span( const GLcontext *ctx, SWspan *span )
*/
GLuint i;
for (i = 0; i < span->end; i++) {
- const GLfloat f = span->array->fog[i];
+ const GLfloat f = span->array->attribs[FRAG_ATTRIB_FOGC][i][0];
index[i] = (GLuint) ((GLfloat) index[i] + (1.0F - f) * fogIndex);
}
}
@@ -368,10 +368,10 @@ _swrast_fog_ci_span( const GLcontext *ctx, SWspan *span )
/* The span's fog start/step values are blend factors.
* They were previously computed per-vertex.
*/
- const GLfloat fogStep = span->fogStep;
- GLfloat fog = span->fog;
- const GLfloat wStep = haveW ? span->dwdx : 0.0F;
- GLfloat w = haveW ? span->w : 1.0F;
+ const GLfloat fogStep = span->attrStepX[FRAG_ATTRIB_FOGC][0];
+ GLfloat fog = span->attrStart[FRAG_ATTRIB_FOGC][0];
+ const GLfloat wStep = haveW ? span->attrStepX[FRAG_ATTRIB_WPOS][3] : 0.0F;
+ GLfloat w = haveW ? span->attrStart[FRAG_ATTRIB_WPOS][3] : 1.0F;
GLuint i;
ASSERT(span->interpMask & SPAN_FOG);
for (i = 0; i < span->end; i++) {
diff --git a/src/mesa/swrast/s_fragprog.c b/src/mesa/swrast/s_fragprog.c
new file mode 100644
index 00000000000..7f7c0d6db52
--- /dev/null
+++ b/src/mesa/swrast/s_fragprog.c
@@ -0,0 +1,224 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 6.5.2
+ *
+ * Copyright (C) 1999-2006 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"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "glheader.h"
+#include "colormac.h"
+#include "context.h"
+#include "prog_execute.h"
+#include "prog_instruction.h"
+
+#include "s_fragprog.h"
+#include "s_span.h"
+
+
+/**
+ * Fetch a texel.
+ */
+static void
+fetch_texel( GLcontext *ctx, const GLfloat texcoord[4], GLfloat lambda,
+ GLuint unit, GLfloat color[4] )
+{
+ GLchan rgba[4];
+ SWcontext *swrast = SWRAST_CONTEXT(ctx);
+
+ /* XXX use a float-valued TextureSample routine here!!! */
+ swrast->TextureSample[unit](ctx, 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]);
+}
+
+
+/**
+ * Fetch a texel with the given partial derivatives to compute a level
+ * of detail in the mipmap.
+ */
+static void
+fetch_texel_deriv( GLcontext *ctx, const GLfloat texcoord[4],
+ const GLfloat texdx[4], const GLfloat texdy[4],
+ GLuint unit, GLfloat color[4] )
+{
+ SWcontext *swrast = SWRAST_CONTEXT(ctx);
+ const struct gl_texture_object *texObj = ctx->Texture.Unit[unit]._Current;
+ const struct gl_texture_image *texImg = texObj->Image[0][texObj->BaseLevel];
+ const GLfloat texW = (GLfloat) texImg->WidthScale;
+ const GLfloat texH = (GLfloat) texImg->HeightScale;
+ GLchan rgba[4];
+
+ GLfloat lambda = _swrast_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, 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]);
+}
+
+
+/**
+ * Initialize the virtual fragment program machine state prior to running
+ * fragment program on a fragment. This involves initializing the input
+ * registers, condition codes, etc.
+ * \param machine the virtual machine state to init
+ * \param program the fragment program we're about to run
+ * \param span the span of pixels we'll operate on
+ * \param col which element (column) of the span we'll operate on
+ */
+static void
+init_machine(GLcontext *ctx, struct gl_program_machine *machine,
+ const struct gl_fragment_program *program,
+ const SWspan *span, GLuint col)
+{
+ GLuint inputsRead = program->Base.InputsRead;
+
+ if (ctx->FragmentProgram.CallbackEnabled)
+ inputsRead = ~0;
+
+ if (program->Base.Target == GL_FRAGMENT_PROGRAM_NV) {
+ /* Clear temporary registers (undefined for ARB_f_p) */
+ _mesa_bzero(machine->Temporaries,
+ MAX_PROGRAM_TEMPS * 4 * sizeof(GLfloat));
+ }
+
+ /* Setup pointer to input attributes */
+ machine->Attribs = span->array->attribs;
+
+ /* Store front/back facing value in register FOGC.Y */
+ machine->Attribs[FRAG_ATTRIB_FOGC][col][1] = (GLfloat) ctx->_Facing;
+
+ machine->CurElement = col;
+
+ /* init condition codes */
+ machine->CondCodes[0] = COND_EQ;
+ machine->CondCodes[1] = COND_EQ;
+ machine->CondCodes[2] = COND_EQ;
+ machine->CondCodes[3] = COND_EQ;
+
+ /* init call stack */
+ machine->StackDepth = 0;
+
+ machine->FetchTexelLod = fetch_texel;
+ machine->FetchTexelDeriv = fetch_texel_deriv;
+}
+
+
+/**
+ * Run fragment program on the pixels in span from 'start' to 'end' - 1.
+ */
+static void
+run_program(GLcontext *ctx, SWspan *span, GLuint start, GLuint end)
+{
+ SWcontext *swrast = SWRAST_CONTEXT(ctx);
+ const struct gl_fragment_program *program = ctx->FragmentProgram._Current;
+ const GLbitfield outputsWritten = program->Base.OutputsWritten;
+ struct gl_program_machine machine;
+ GLuint i;
+
+ for (i = start; i < end; i++) {
+ if (span->array->mask[i]) {
+ init_machine(ctx, &machine, program, span, i);
+
+ if (_mesa_execute_program(ctx, &program->Base, &machine)) {
+
+ /* Store result color */
+ if (outputsWritten & (1 << FRAG_RESULT_COLR)) {
+ COPY_4V(span->array->attribs[FRAG_ATTRIB_COL0][i],
+ machine.Outputs[FRAG_RESULT_COLR]);
+ }
+ else {
+ /* Multiple drawbuffers / render targets
+ * Note that colors beyond 0 and 1 will overwrite other
+ * attributes, such as FOGC, TEX0, TEX1, etc. That's OK.
+ */
+ GLuint output;
+ for (output = 0; output < swrast->_NumColorOutputs; output++) {
+ if (outputsWritten & (1 << (FRAG_RESULT_DATA0 + output))) {
+ COPY_4V(span->array->attribs[FRAG_ATTRIB_COL0+output][i],
+ machine.Outputs[FRAG_RESULT_DATA0 + output]);
+ }
+ }
+ }
+
+ /* Store result depth/z */
+ if (outputsWritten & (1 << FRAG_RESULT_DEPR)) {
+ const GLfloat depth = machine.Outputs[FRAG_RESULT_DEPR][2];
+ if (depth <= 0.0)
+ span->array->z[i] = 0;
+ else if (depth >= 1.0)
+ span->array->z[i] = ctx->DrawBuffer->_DepthMax;
+ else
+ span->array->z[i] = IROUND(depth * ctx->DrawBuffer->_DepthMaxF);
+ }
+ }
+ else {
+ /* killed fragment */
+ span->array->mask[i] = GL_FALSE;
+ span->writeAll = GL_FALSE;
+ }
+ }
+ }
+}
+
+
+/**
+ * Execute the current fragment program for all the fragments
+ * in the given span.
+ */
+void
+_swrast_exec_fragment_program( GLcontext *ctx, SWspan *span )
+{
+ const struct gl_fragment_program *program = ctx->FragmentProgram._Current;
+
+ /* incoming colors should be floats */
+ if (program->Base.InputsRead & FRAG_BIT_COL0) {
+ ASSERT(span->array->ChanType == GL_FLOAT);
+ }
+
+ ctx->_CurrentProgram = GL_FRAGMENT_PROGRAM_ARB; /* or NV, doesn't matter */
+
+ run_program(ctx, span, 0, span->end);
+
+ if (program->Base.OutputsWritten & (1 << FRAG_RESULT_COLR)) {
+ span->interpMask &= ~SPAN_RGBA;
+ span->arrayMask |= SPAN_RGBA;
+ }
+
+ if (program->Base.OutputsWritten & (1 << FRAG_RESULT_DEPR)) {
+ span->interpMask &= ~SPAN_Z;
+ span->arrayMask |= SPAN_Z;
+ }
+
+ ctx->_CurrentProgram = 0;
+}
+
diff --git a/src/mesa/swrast/s_nvfragprog.h b/src/mesa/swrast/s_fragprog.h
index 188bacc3d89..e1b7e679185 100644
--- a/src/mesa/swrast/s_nvfragprog.h
+++ b/src/mesa/swrast/s_fragprog.h
@@ -1,8 +1,8 @@
/*
* Mesa 3-D graphics library
- * Version: 6.1
+ * Version: 6.5.3
*
- * Copyright (C) 1999-2003 Brian Paul All Rights Reserved.
+ * Copyright (C) 1999-2006 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"),
@@ -23,15 +23,16 @@
*/
-#ifndef S_NVFRAGPROG_H
-#define S_NVFRAGPROG_H
+#ifndef S_FRAGPROG_H
+#define S_FRAGPROG_H
#include "s_context.h"
extern void
-_swrast_exec_fragment_program( GLcontext *ctx, SWspan *span );
+_swrast_exec_fragment_program(GLcontext *ctx, SWspan *span);
-#endif
+#endif /* S_FRAGPROG_H */
+
diff --git a/src/mesa/swrast/s_lines.c b/src/mesa/swrast/s_lines.c
index ff507249b08..7b2a52b4ffa 100644
--- a/src/mesa/swrast/s_lines.c
+++ b/src/mesa/swrast/s_lines.c
@@ -198,6 +198,7 @@ draw_wide_line( GLcontext *ctx, SWspan *span, GLboolean xMajor )
#define INTERP_Z
#define INTERP_FOG
#define INTERP_MULTITEX
+#define INTERP_VARYING
#define RENDER_SPAN(span) \
if (ctx->Line.StippleFlag) { \
span.arrayMask |= SPAN_MASK; \
@@ -298,10 +299,12 @@ _swrast_choose_line( GLcontext *ctx )
_swrast_choose_aa_line_function(ctx);
ASSERT(swrast->Line);
}
- else if (ctx->Texture._EnabledCoordUnits) {
+ else if (ctx->Texture._EnabledCoordUnits
+ || ctx->FragmentProgram._Current) {
/* textured lines */
if (ctx->Texture._EnabledCoordUnits > 0x1
- || NEED_SECONDARY_COLOR(ctx)) {
+ || NEED_SECONDARY_COLOR(ctx)
+ || ctx->FragmentProgram._Current) {
/* multi-texture and/or separate specular color */
USE(multitextured_line);
}
diff --git a/src/mesa/swrast/s_linetemp.h b/src/mesa/swrast/s_linetemp.h
index 8b3918511d1..7b66291eb5e 100644
--- a/src/mesa/swrast/s_linetemp.h
+++ b/src/mesa/swrast/s_linetemp.h
@@ -37,6 +37,7 @@
* INTERP_INDEX - if defined, interpolate color index values
* INTERP_TEX - if defined, interpolate unit 0 texcoords
* INTERP_MULTITEX - if defined, interpolate multi-texcoords
+ * INTERP_VARYING - if defined, interpolate GLSL varyings
*
* When one can directly address pixels in the color buffer the following
* macros can be defined and used to directly compute pixel addresses during
@@ -70,6 +71,7 @@
static void
NAME( GLcontext *ctx, const SWvertex *vert0, const SWvertex *vert1 )
{
+ const SWcontext *swrast = SWRAST_CONTEXT(ctx);
SWspan span;
GLuint interpFlags = 0;
GLint x0 = (GLint) vert0->win[0];
@@ -99,6 +101,8 @@ NAME( GLcontext *ctx, const SWvertex *vert0, const SWvertex *vert1 )
SETUP_CODE
#endif
+ (void) swrast;
+
/* Cull primitives with malformed coordinates.
*/
{
@@ -276,8 +280,8 @@ NAME( GLcontext *ctx, const SWvertex *vert0, const SWvertex *vert1 )
#endif
#ifdef INTERP_FOG
interpFlags |= SPAN_FOG;
- span.fog = vert0->fog;
- span.fogStep = (vert1->fog - vert0->fog) / numPixels;
+ span.attrStart[FRAG_ATTRIB_FOGC][0] = vert0->fog;
+ span.attrStepX[FRAG_ATTRIB_FOGC][0] = (vert1->fog - vert0->fog) / numPixels;
#endif
#ifdef INTERP_TEX
interpFlags |= SPAN_TEXTURE;
@@ -286,50 +290,50 @@ NAME( GLcontext *ctx, const SWvertex *vert0, const SWvertex *vert1 )
const GLfloat invw1 = vert1->win[3];
const GLfloat invLen = 1.0F / numPixels;
GLfloat ds, dt, dr, dq;
- span.tex[0][0] = invw0 * vert0->texcoord[0][0];
- span.tex[0][1] = invw0 * vert0->texcoord[0][1];
- span.tex[0][2] = invw0 * vert0->texcoord[0][2];
- span.tex[0][3] = invw0 * vert0->texcoord[0][3];
- ds = (invw1 * vert1->texcoord[0][0]) - span.tex[0][0];
- dt = (invw1 * vert1->texcoord[0][1]) - span.tex[0][1];
- dr = (invw1 * vert1->texcoord[0][2]) - span.tex[0][2];
- dq = (invw1 * vert1->texcoord[0][3]) - span.tex[0][3];
- span.texStepX[0][0] = ds * invLen;
- span.texStepX[0][1] = dt * invLen;
- span.texStepX[0][2] = dr * invLen;
- span.texStepX[0][3] = dq * invLen;
- span.texStepY[0][0] = 0.0F;
- span.texStepY[0][1] = 0.0F;
- span.texStepY[0][2] = 0.0F;
- span.texStepY[0][3] = 0.0F;
+ span.attrStart[FRAG_ATTRIB_TEX0][0] = invw0 * vert0->attrib[FRAG_ATTRIB_TEX0][0];
+ span.attrStart[FRAG_ATTRIB_TEX0][1] = invw0 * vert0->attrib[FRAG_ATTRIB_TEX0][1];
+ span.attrStart[FRAG_ATTRIB_TEX0][2] = invw0 * vert0->attrib[FRAG_ATTRIB_TEX0][2];
+ span.attrStart[FRAG_ATTRIB_TEX0][3] = invw0 * vert0->attrib[FRAG_ATTRIB_TEX0][3];
+ ds = (invw1 * vert1->attrib[FRAG_ATTRIB_TEX0][0]) - span.attrStart[FRAG_ATTRIB_TEX0][0];
+ dt = (invw1 * vert1->attrib[FRAG_ATTRIB_TEX0][1]) - span.attrStart[FRAG_ATTRIB_TEX0][1];
+ dr = (invw1 * vert1->attrib[FRAG_ATTRIB_TEX0][2]) - span.attrStart[FRAG_ATTRIB_TEX0][2];
+ dq = (invw1 * vert1->attrib[FRAG_ATTRIB_TEX0][3]) - span.attrStart[FRAG_ATTRIB_TEX0][3];
+ span.attrStepX[FRAG_ATTRIB_TEX0][0] = ds * invLen;
+ span.attrStepX[FRAG_ATTRIB_TEX0][1] = dt * invLen;
+ span.attrStepX[FRAG_ATTRIB_TEX0][2] = dr * invLen;
+ span.attrStepX[FRAG_ATTRIB_TEX0][3] = dq * invLen;
+ span.attrStepY[FRAG_ATTRIB_TEX0][0] = 0.0F;
+ span.attrStepY[FRAG_ATTRIB_TEX0][1] = 0.0F;
+ span.attrStepY[FRAG_ATTRIB_TEX0][2] = 0.0F;
+ span.attrStepY[FRAG_ATTRIB_TEX0][3] = 0.0F;
}
#endif
-#ifdef INTERP_MULTITEX
- interpFlags |= SPAN_TEXTURE;
+#if defined(INTERP_MULTITEX) || defined(INTERP_VARYING)
+ interpFlags |= (SPAN_TEXTURE | SPAN_VARYING);
{
const GLfloat invLen = 1.0F / numPixels;
- GLuint u;
- for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
- if (ctx->Texture.Unit[u]._ReallyEnabled) {
- const GLfloat invw0 = vert0->win[3];
- const GLfloat invw1 = vert1->win[3];
+ const GLfloat invw0 = vert0->win[3];
+ const GLfloat invw1 = vert1->win[3];
+ GLuint attr;
+ for (attr = swrast->_MinFragmentAttrib; attr < swrast->_MaxFragmentAttrib; attr++) {
+ if (swrast->_FragmentAttribs & (1 << attr)) {
GLfloat ds, dt, dr, dq;
- span.tex[u][0] = invw0 * vert0->texcoord[u][0];
- span.tex[u][1] = invw0 * vert0->texcoord[u][1];
- span.tex[u][2] = invw0 * vert0->texcoord[u][2];
- span.tex[u][3] = invw0 * vert0->texcoord[u][3];
- ds = (invw1 * vert1->texcoord[u][0]) - span.tex[u][0];
- dt = (invw1 * vert1->texcoord[u][1]) - span.tex[u][1];
- dr = (invw1 * vert1->texcoord[u][2]) - span.tex[u][2];
- dq = (invw1 * vert1->texcoord[u][3]) - span.tex[u][3];
- span.texStepX[u][0] = ds * invLen;
- span.texStepX[u][1] = dt * invLen;
- span.texStepX[u][2] = dr * invLen;
- span.texStepX[u][3] = dq * invLen;
- span.texStepY[u][0] = 0.0F;
- span.texStepY[u][1] = 0.0F;
- span.texStepY[u][2] = 0.0F;
- span.texStepY[u][3] = 0.0F;
+ span.attrStart[attr][0] = invw0 * vert0->attrib[attr][0];
+ span.attrStart[attr][1] = invw0 * vert0->attrib[attr][1];
+ span.attrStart[attr][2] = invw0 * vert0->attrib[attr][2];
+ span.attrStart[attr][3] = invw0 * vert0->attrib[attr][3];
+ ds = (invw1 * vert1->attrib[attr][0]) - span.attrStart[attr][0];
+ dt = (invw1 * vert1->attrib[attr][1]) - span.attrStart[attr][1];
+ dr = (invw1 * vert1->attrib[attr][2]) - span.attrStart[attr][2];
+ dq = (invw1 * vert1->attrib[attr][3]) - span.attrStart[attr][3];
+ span.attrStepX[attr][0] = ds * invLen;
+ span.attrStepX[attr][1] = dt * invLen;
+ span.attrStepX[attr][2] = dr * invLen;
+ span.attrStepX[attr][3] = dq * invLen;
+ span.attrStepY[attr][0] = 0.0F;
+ span.attrStepY[attr][1] = 0.0F;
+ span.attrStepY[attr][2] = 0.0F;
+ span.attrStepY[attr][3] = 0.0F;
}
}
}
@@ -338,9 +342,9 @@ NAME( GLcontext *ctx, const SWvertex *vert0, const SWvertex *vert1 )
INIT_SPAN(span, GL_LINE, numPixels, interpFlags, SPAN_XY);
/* Need these for fragment prog texcoord interpolation */
- span.w = 1.0F;
- span.dwdx = 0.0F;
- span.dwdy = 0.0F;
+ span.attrStart[FRAG_ATTRIB_WPOS][3] = 1.0F;
+ span.attrStepX[FRAG_ATTRIB_WPOS][3] = 0.0F;
+ span.attrStepY[FRAG_ATTRIB_WPOS][3] = 0.0F;
/*
* Draw
diff --git a/src/mesa/swrast/s_logic.c b/src/mesa/swrast/s_logic.c
index 719b17962d4..e680732beed 100644
--- a/src/mesa/swrast/s_logic.c
+++ b/src/mesa/swrast/s_logic.c
@@ -240,7 +240,7 @@ _swrast_logicop_rgba_span(GLcontext *ctx, struct gl_renderbuffer *rb,
}
else {
logicop_uint4(ctx, 4 * span->end,
- (GLuint *) span->array->color.sz4.rgba,
+ (GLuint *) span->array->attribs[FRAG_ATTRIB_COL0],
(const GLuint *) rbPixels, span->array->mask);
}
}
diff --git a/src/mesa/swrast/s_masking.c b/src/mesa/swrast/s_masking.c
index 65c984dd3e3..8800f7d8e34 100644
--- a/src/mesa/swrast/s_masking.c
+++ b/src/mesa/swrast/s_masking.c
@@ -91,7 +91,7 @@ _swrast_mask_rgba_span(GLcontext *ctx, struct gl_renderbuffer *rb,
const GLuint bMask = ctx->Color.ColorMask[BCOMP] ? ~0x0 : 0x0;
const GLuint aMask = ctx->Color.ColorMask[ACOMP] ? ~0x0 : 0x0;
const GLuint (*dst)[4] = (const GLuint (*)[4]) rbPixels;
- GLuint (*src)[4] = (GLuint (*)[4]) span->array->color.sz4.rgba;
+ GLuint (*src)[4] = (GLuint (*)[4]) span->array->attribs[FRAG_ATTRIB_COL0];
GLuint i;
for (i = 0; i < n; i++) {
src[i][RCOMP] = (src[i][RCOMP] & rMask) | (dst[i][RCOMP] & ~rMask);
diff --git a/src/mesa/swrast/s_nvfragprog.c b/src/mesa/swrast/s_nvfragprog.c
deleted file mode 100644
index 028ddc0090d..00000000000
--- a/src/mesa/swrast/s_nvfragprog.c
+++ /dev/null
@@ -1,1665 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version: 6.5.2
- *
- * Copyright (C) 1999-2006 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"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-/*
- * Regarding GL_NV_fragment_program:
- *
- * Portions of this software may use or implement intellectual
- * property owned and licensed by NVIDIA Corporation. NVIDIA disclaims
- * any and all warranties with respect to such intellectual property,
- * including any use thereof or modifications thereto.
- */
-
-#include "glheader.h"
-#include "colormac.h"
-#include "context.h"
-#include "program_instruction.h"
-#include "program.h"
-
-#include "s_nvfragprog.h"
-#include "s_span.h"
-
-
-/* See comments below for info about this */
-#define LAMBDA_ZERO 1
-
-/* debug predicate */
-#define DEBUG_FRAG 0
-
-
-/**
- * Virtual machine state used during execution of a fragment programs.
- */
-struct fp_machine
-{
- GLfloat Temporaries[MAX_NV_FRAGMENT_PROGRAM_TEMPS][4];
- GLfloat Inputs[MAX_NV_FRAGMENT_PROGRAM_INPUTS][4];
- GLfloat Outputs[MAX_NV_FRAGMENT_PROGRAM_OUTPUTS][4];
- GLuint CondCodes[4]; /**< COND_* value for x/y/z/w */
-
- GLuint CallStack[MAX_PROGRAM_CALL_DEPTH]; /**< For CAL/RET instructions */
- GLuint StackDepth; /**< Index/ptr to top of CallStack[] */
-};
-
-
-#if FEATURE_MESA_program_debug
-static struct fp_machine *CurrentMachine = NULL;
-
-/**
- * For GL_MESA_program_debug.
- * Return current value (4*GLfloat) of a fragment program register.
- * Called via ctx->Driver.GetFragmentProgramRegister().
- */
-void
-_swrast_get_program_register(GLcontext *ctx, enum register_file file,
- GLuint index, GLfloat val[4])
-{
- if (CurrentMachine) {
- switch (file) {
- case PROGRAM_INPUT:
- COPY_4V(val, CurrentMachine->Inputs[index]);
- break;
- case PROGRAM_OUTPUT:
- COPY_4V(val, CurrentMachine->Outputs[index]);
- break;
- case PROGRAM_TEMPORARY:
- COPY_4V(val, CurrentMachine->Temporaries[index]);
- break;
- default:
- _mesa_problem(NULL,
- "bad register file in _swrast_get_program_register");
- }
- }
-}
-#endif /* FEATURE_MESA_program_debug */
-
-
-/**
- * Fetch a texel.
- */
-static void
-fetch_texel( GLcontext *ctx, const GLfloat texcoord[4], GLfloat lambda,
- GLuint unit, GLfloat color[4] )
-{
- GLchan rgba[4];
- SWcontext *swrast = SWRAST_CONTEXT(ctx);
-
- /* XXX use a float-valued TextureSample routine here!!! */
- swrast->TextureSample[unit](ctx, 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]);
-}
-
-
-/**
- * Fetch a texel with the given partial derivatives to compute a level
- * of detail in the mipmap.
- */
-static void
-fetch_texel_deriv( GLcontext *ctx, const GLfloat texcoord[4],
- const GLfloat texdx[4], const GLfloat texdy[4],
- GLuint unit, GLfloat color[4] )
-{
- SWcontext *swrast = SWRAST_CONTEXT(ctx);
- const struct gl_texture_object *texObj = ctx->Texture.Unit[unit]._Current;
- const struct gl_texture_image *texImg = texObj->Image[0][texObj->BaseLevel];
- const GLfloat texW = (GLfloat) texImg->WidthScale;
- const GLfloat texH = (GLfloat) texImg->HeightScale;
- GLchan rgba[4];
-
- GLfloat lambda = _swrast_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, 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]);
-}
-
-
-/**
- * Return a pointer to the 4-element float vector specified by the given
- * source register.
- */
-static INLINE const GLfloat *
-get_register_pointer( GLcontext *ctx,
- const struct prog_src_register *source,
- const struct fp_machine *machine,
- const struct gl_fragment_program *program )
-{
- switch (source->File) {
- case PROGRAM_TEMPORARY:
- ASSERT(source->Index < MAX_NV_FRAGMENT_PROGRAM_TEMPS);
- return machine->Temporaries[source->Index];
- case PROGRAM_INPUT:
- ASSERT(source->Index < MAX_NV_FRAGMENT_PROGRAM_INPUTS);
- return machine->Inputs[source->Index];
- case PROGRAM_OUTPUT:
- /* This is only for PRINT */
- ASSERT(source->Index < MAX_NV_FRAGMENT_PROGRAM_OUTPUTS);
- return machine->Outputs[source->Index];
- case PROGRAM_LOCAL_PARAM:
- ASSERT(source->Index < MAX_PROGRAM_LOCAL_PARAMS);
- return program->Base.LocalParams[source->Index];
- case PROGRAM_ENV_PARAM:
- ASSERT(source->Index < MAX_NV_FRAGMENT_PROGRAM_PARAMS);
- return ctx->FragmentProgram.Parameters[source->Index];
- case PROGRAM_STATE_VAR:
- /* Fallthrough */
- case PROGRAM_CONSTANT:
- /* Fallthrough */
- case PROGRAM_NAMED_PARAM:
- ASSERT(source->Index < (GLint) program->Base.Parameters->NumParameters);
- return program->Base.Parameters->ParameterValues[source->Index];
- default:
- _mesa_problem(ctx, "Invalid input register file %d in fp "
- "get_register_pointer", source->File);
- return NULL;
- }
-}
-
-
-/**
- * Fetch a 4-element float vector from the given source register.
- * Apply swizzling and negating as needed.
- */
-static void
-fetch_vector4( GLcontext *ctx,
- const struct prog_src_register *source,
- const struct fp_machine *machine,
- const struct gl_fragment_program *program,
- GLfloat result[4] )
-{
- const GLfloat *src = get_register_pointer(ctx, source, machine, program);
- ASSERT(src);
-
- if (source->Swizzle == MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y,
- SWIZZLE_Z, SWIZZLE_W)) {
- /* no swizzling */
- COPY_4V(result, src);
- }
- else {
- result[0] = src[GET_SWZ(source->Swizzle, 0)];
- result[1] = src[GET_SWZ(source->Swizzle, 1)];
- result[2] = src[GET_SWZ(source->Swizzle, 2)];
- result[3] = src[GET_SWZ(source->Swizzle, 3)];
- }
-
- if (source->NegateBase) {
- result[0] = -result[0];
- result[1] = -result[1];
- result[2] = -result[2];
- result[3] = -result[3];
- }
- if (source->Abs) {
- result[0] = FABSF(result[0]);
- result[1] = FABSF(result[1]);
- result[2] = FABSF(result[2]);
- result[3] = FABSF(result[3]);
- }
- if (source->NegateAbs) {
- result[0] = -result[0];
- result[1] = -result[1];
- result[2] = -result[2];
- result[3] = -result[3];
- }
-}
-
-
-/**
- * Fetch the derivative with respect to X for the given register.
- * \return GL_TRUE if it was easily computed or GL_FALSE if we
- * need to execute another instance of the program (ugh)!
- */
-static GLboolean
-fetch_vector4_deriv( GLcontext *ctx,
- const struct prog_src_register *source,
- const SWspan *span,
- char xOrY, GLint column, GLfloat result[4] )
-{
- GLfloat src[4];
-
- ASSERT(xOrY == 'X' || xOrY == 'Y');
-
- switch (source->Index) {
- case FRAG_ATTRIB_WPOS:
- if (xOrY == 'X') {
- src[0] = 1.0;
- src[1] = 0.0;
- src[2] = span->dzdx / ctx->DrawBuffer->_DepthMaxF;
- src[3] = span->dwdx;
- }
- else {
- src[0] = 0.0;
- src[1] = 1.0;
- src[2] = span->dzdy / ctx->DrawBuffer->_DepthMaxF;
- src[3] = span->dwdy;
- }
- break;
- case FRAG_ATTRIB_COL0:
- if (xOrY == 'X') {
- src[0] = span->drdx * (1.0F / CHAN_MAXF);
- src[1] = span->dgdx * (1.0F / CHAN_MAXF);
- src[2] = span->dbdx * (1.0F / CHAN_MAXF);
- src[3] = span->dadx * (1.0F / CHAN_MAXF);
- }
- else {
- src[0] = span->drdy * (1.0F / CHAN_MAXF);
- src[1] = span->dgdy * (1.0F / CHAN_MAXF);
- src[2] = span->dbdy * (1.0F / CHAN_MAXF);
- src[3] = span->dady * (1.0F / CHAN_MAXF);
- }
- break;
- case FRAG_ATTRIB_COL1:
- if (xOrY == 'X') {
- src[0] = span->dsrdx * (1.0F / CHAN_MAXF);
- src[1] = span->dsgdx * (1.0F / CHAN_MAXF);
- src[2] = span->dsbdx * (1.0F / CHAN_MAXF);
- src[3] = 0.0; /* XXX need this */
- }
- else {
- src[0] = span->dsrdy * (1.0F / CHAN_MAXF);
- src[1] = span->dsgdy * (1.0F / CHAN_MAXF);
- src[2] = span->dsbdy * (1.0F / CHAN_MAXF);
- src[3] = 0.0; /* XXX need this */
- }
- break;
- case FRAG_ATTRIB_FOGC:
- if (xOrY == 'X') {
- src[0] = span->dfogdx;
- src[1] = 0.0;
- src[2] = 0.0;
- src[3] = 0.0;
- }
- else {
- src[0] = span->dfogdy;
- src[1] = 0.0;
- src[2] = 0.0;
- src[3] = 0.0;
- }
- break;
- case FRAG_ATTRIB_TEX0:
- case FRAG_ATTRIB_TEX1:
- case FRAG_ATTRIB_TEX2:
- case FRAG_ATTRIB_TEX3:
- case FRAG_ATTRIB_TEX4:
- case FRAG_ATTRIB_TEX5:
- case FRAG_ATTRIB_TEX6:
- case FRAG_ATTRIB_TEX7:
- if (xOrY == 'X') {
- const GLuint u = source->Index - FRAG_ATTRIB_TEX0;
- /* this is a little tricky - I think I've got it right */
- const GLfloat invQ = 1.0f / (span->tex[u][3]
- + span->texStepX[u][3] * column);
- src[0] = span->texStepX[u][0] * invQ;
- src[1] = span->texStepX[u][1] * invQ;
- src[2] = span->texStepX[u][2] * invQ;
- src[3] = span->texStepX[u][3] * invQ;
- }
- else {
- const GLuint u = source->Index - FRAG_ATTRIB_TEX0;
- /* Tricky, as above, but in Y direction */
- const GLfloat invQ = 1.0f / (span->tex[u][3] + span->texStepY[u][3]);
- src[0] = span->texStepY[u][0] * invQ;
- src[1] = span->texStepY[u][1] * invQ;
- src[2] = span->texStepY[u][2] * invQ;
- src[3] = span->texStepY[u][3] * invQ;
- }
- break;
- default:
- return GL_FALSE;
- }
-
- result[0] = src[GET_SWZ(source->Swizzle, 0)];
- result[1] = src[GET_SWZ(source->Swizzle, 1)];
- result[2] = src[GET_SWZ(source->Swizzle, 2)];
- result[3] = src[GET_SWZ(source->Swizzle, 3)];
-
- if (source->NegateBase) {
- result[0] = -result[0];
- result[1] = -result[1];
- result[2] = -result[2];
- result[3] = -result[3];
- }
- if (source->Abs) {
- result[0] = FABSF(result[0]);
- result[1] = FABSF(result[1]);
- result[2] = FABSF(result[2]);
- result[3] = FABSF(result[3]);
- }
- if (source->NegateAbs) {
- result[0] = -result[0];
- result[1] = -result[1];
- result[2] = -result[2];
- result[3] = -result[3];
- }
- return GL_TRUE;
-}
-
-
-/**
- * As above, but only return result[0] element.
- */
-static void
-fetch_vector1( GLcontext *ctx,
- const struct prog_src_register *source,
- const struct fp_machine *machine,
- const struct gl_fragment_program *program,
- GLfloat result[4] )
-{
- const GLfloat *src = get_register_pointer(ctx, source, machine, program);
- ASSERT(src);
-
- result[0] = src[GET_SWZ(source->Swizzle, 0)];
-
- if (source->NegateBase) {
- result[0] = -result[0];
- }
- if (source->Abs) {
- result[0] = FABSF(result[0]);
- }
- if (source->NegateAbs) {
- result[0] = -result[0];
- }
-}
-
-
-/**
- * Test value against zero and return GT, LT, EQ or UN if NaN.
- */
-static INLINE GLuint
-generate_cc( float value )
-{
- if (value != value)
- return COND_UN; /* NaN */
- if (value > 0.0F)
- return COND_GT;
- if (value < 0.0F)
- return COND_LT;
- return COND_EQ;
-}
-
-
-/**
- * Test if the ccMaskRule is satisfied by the given condition code.
- * Used to mask destination writes according to the current condition code.
- */
-static INLINE GLboolean
-test_cc(GLuint condCode, GLuint ccMaskRule)
-{
- switch (ccMaskRule) {
- case COND_EQ: return (condCode == COND_EQ);
- case COND_NE: return (condCode != COND_EQ);
- case COND_LT: return (condCode == COND_LT);
- case COND_GE: return (condCode == COND_GT || condCode == COND_EQ);
- case COND_LE: return (condCode == COND_LT || condCode == COND_EQ);
- case COND_GT: return (condCode == COND_GT);
- case COND_TR: return GL_TRUE;
- case COND_FL: return GL_FALSE;
- default: return GL_TRUE;
- }
-}
-
-
-/**
- * Store 4 floats into a register. Observe the instructions saturate and
- * set-condition-code flags.
- */
-static void
-store_vector4( const struct prog_instruction *inst,
- struct fp_machine *machine,
- const GLfloat value[4] )
-{
- const struct prog_dst_register *dest = &(inst->DstReg);
- const GLboolean clamp = inst->SaturateMode == SATURATE_ZERO_ONE;
- GLfloat *dstReg;
- GLfloat dummyReg[4];
- GLfloat clampedValue[4];
- GLuint writeMask = dest->WriteMask;
-
- switch (dest->File) {
- case PROGRAM_OUTPUT:
- dstReg = machine->Outputs[dest->Index];
- break;
- case PROGRAM_TEMPORARY:
- dstReg = machine->Temporaries[dest->Index];
- break;
- case PROGRAM_WRITE_ONLY:
- dstReg = dummyReg;
- return;
- default:
- _mesa_problem(NULL, "bad register file in store_vector4(fp)");
- return;
- }
-
-#if 0
- if (value[0] > 1.0e10 ||
- IS_INF_OR_NAN(value[0]) ||
- IS_INF_OR_NAN(value[1]) ||
- IS_INF_OR_NAN(value[2]) ||
- IS_INF_OR_NAN(value[3]) )
- printf("store %g %g %g %g\n", value[0], value[1], value[2], value[3]);
-#endif
-
- if (clamp) {
- clampedValue[0] = CLAMP(value[0], 0.0F, 1.0F);
- clampedValue[1] = CLAMP(value[1], 0.0F, 1.0F);
- clampedValue[2] = CLAMP(value[2], 0.0F, 1.0F);
- clampedValue[3] = CLAMP(value[3], 0.0F, 1.0F);
- value = clampedValue;
- }
-
- if (dest->CondMask != COND_TR) {
- /* condition codes may turn off some writes */
- if (writeMask & WRITEMASK_X) {
- if (!test_cc(machine->CondCodes[GET_SWZ(dest->CondSwizzle, 0)],
- dest->CondMask))
- writeMask &= ~WRITEMASK_X;
- }
- if (writeMask & WRITEMASK_Y) {
- if (!test_cc(machine->CondCodes[GET_SWZ(dest->CondSwizzle, 1)],
- dest->CondMask))
- writeMask &= ~WRITEMASK_Y;
- }
- if (writeMask & WRITEMASK_Z) {
- if (!test_cc(machine->CondCodes[GET_SWZ(dest->CondSwizzle, 2)],
- dest->CondMask))
- writeMask &= ~WRITEMASK_Z;
- }
- if (writeMask & WRITEMASK_W) {
- if (!test_cc(machine->CondCodes[GET_SWZ(dest->CondSwizzle, 3)],
- dest->CondMask))
- writeMask &= ~WRITEMASK_W;
- }
- }
-
- if (writeMask & WRITEMASK_X)
- dstReg[0] = value[0];
- if (writeMask & WRITEMASK_Y)
- dstReg[1] = value[1];
- if (writeMask & WRITEMASK_Z)
- dstReg[2] = value[2];
- if (writeMask & WRITEMASK_W)
- dstReg[3] = value[3];
-
- if (inst->CondUpdate) {
- if (writeMask & WRITEMASK_X)
- machine->CondCodes[0] = generate_cc(value[0]);
- if (writeMask & WRITEMASK_Y)
- machine->CondCodes[1] = generate_cc(value[1]);
- if (writeMask & WRITEMASK_Z)
- machine->CondCodes[2] = generate_cc(value[2]);
- if (writeMask & WRITEMASK_W)
- machine->CondCodes[3] = generate_cc(value[3]);
- }
-}
-
-
-/**
- * Initialize a new machine state instance from an existing one, adding
- * the partial derivatives onto the input registers.
- * Used to implement DDX and DDY instructions in non-trivial cases.
- */
-static void
-init_machine_deriv( GLcontext *ctx,
- const struct fp_machine *machine,
- const struct gl_fragment_program *program,
- const SWspan *span, char xOrY,
- struct fp_machine *dMachine )
-{
- GLuint u;
-
- ASSERT(xOrY == 'X' || xOrY == 'Y');
-
- /* copy existing machine */
- _mesa_memcpy(dMachine, machine, sizeof(struct fp_machine));
-
- if (program->Base.Target == GL_FRAGMENT_PROGRAM_NV) {
- /* Clear temporary registers (undefined for ARB_f_p) */
- _mesa_bzero( (void*) machine->Temporaries,
- MAX_NV_FRAGMENT_PROGRAM_TEMPS * 4 * sizeof(GLfloat));
- }
-
- /* Add derivatives */
- if (program->Base.InputsRead & (1 << FRAG_ATTRIB_WPOS)) {
- GLfloat *wpos = (GLfloat*) machine->Inputs[FRAG_ATTRIB_WPOS];
- if (xOrY == 'X') {
- wpos[0] += 1.0F;
- wpos[1] += 0.0F;
- wpos[2] += span->dzdx;
- wpos[3] += span->dwdx;
- }
- else {
- wpos[0] += 0.0F;
- wpos[1] += 1.0F;
- wpos[2] += span->dzdy;
- wpos[3] += span->dwdy;
- }
- }
- if (program->Base.InputsRead & (1 << FRAG_ATTRIB_COL0)) {
- GLfloat *col0 = (GLfloat*) machine->Inputs[FRAG_ATTRIB_COL0];
- if (xOrY == 'X') {
- col0[0] += span->drdx * (1.0F / CHAN_MAXF);
- col0[1] += span->dgdx * (1.0F / CHAN_MAXF);
- col0[2] += span->dbdx * (1.0F / CHAN_MAXF);
- col0[3] += span->dadx * (1.0F / CHAN_MAXF);
- }
- else {
- col0[0] += span->drdy * (1.0F / CHAN_MAXF);
- col0[1] += span->dgdy * (1.0F / CHAN_MAXF);
- col0[2] += span->dbdy * (1.0F / CHAN_MAXF);
- col0[3] += span->dady * (1.0F / CHAN_MAXF);
- }
- }
- if (program->Base.InputsRead & (1 << FRAG_ATTRIB_COL1)) {
- GLfloat *col1 = (GLfloat*) machine->Inputs[FRAG_ATTRIB_COL1];
- if (xOrY == 'X') {
- col1[0] += span->dsrdx * (1.0F / CHAN_MAXF);
- col1[1] += span->dsgdx * (1.0F / CHAN_MAXF);
- col1[2] += span->dsbdx * (1.0F / CHAN_MAXF);
- col1[3] += 0.0; /*XXX fix */
- }
- else {
- col1[0] += span->dsrdy * (1.0F / CHAN_MAXF);
- col1[1] += span->dsgdy * (1.0F / CHAN_MAXF);
- col1[2] += span->dsbdy * (1.0F / CHAN_MAXF);
- col1[3] += 0.0; /*XXX fix */
- }
- }
- if (program->Base.InputsRead & (1 << FRAG_ATTRIB_FOGC)) {
- GLfloat *fogc = (GLfloat*) machine->Inputs[FRAG_ATTRIB_FOGC];
- if (xOrY == 'X') {
- fogc[0] += span->dfogdx;
- }
- else {
- fogc[0] += span->dfogdy;
- }
- }
- for (u = 0; u < ctx->Const.MaxTextureCoordUnits; u++) {
- if (program->Base.InputsRead & (1 << (FRAG_ATTRIB_TEX0 + u))) {
- GLfloat *tex = (GLfloat*) machine->Inputs[FRAG_ATTRIB_TEX0 + u];
- /* XXX perspective-correct interpolation */
- if (xOrY == 'X') {
- tex[0] += span->texStepX[u][0];
- tex[1] += span->texStepX[u][1];
- tex[2] += span->texStepX[u][2];
- tex[3] += span->texStepX[u][3];
- }
- else {
- tex[0] += span->texStepY[u][0];
- tex[1] += span->texStepY[u][1];
- tex[2] += span->texStepY[u][2];
- tex[3] += span->texStepY[u][3];
- }
- }
- }
-
- /* init condition codes */
- dMachine->CondCodes[0] = COND_EQ;
- dMachine->CondCodes[1] = COND_EQ;
- dMachine->CondCodes[2] = COND_EQ;
- dMachine->CondCodes[3] = COND_EQ;
-}
-
-
-/**
- * Execute the given vertex program.
- * NOTE: we do everything in single-precision floating point; we don't
- * currently observe the single/half/fixed-precision qualifiers.
- * \param ctx - rendering context
- * \param program - the fragment program to execute
- * \param machine - machine state (register file)
- * \param maxInst - max number of instructions to execute
- * \return GL_TRUE if program completed or GL_FALSE if program executed KIL.
- */
-static GLboolean
-execute_program( GLcontext *ctx,
- const struct gl_fragment_program *program, GLuint maxInst,
- struct fp_machine *machine, const SWspan *span,
- GLuint column )
-{
- GLuint pc;
-
- if (DEBUG_FRAG) {
- printf("execute fragment program --------------------\n");
- }
-
- for (pc = 0; pc < maxInst; pc++) {
- const struct prog_instruction *inst = program->Base.Instructions + pc;
-
- if (ctx->FragmentProgram.CallbackEnabled &&
- ctx->FragmentProgram.Callback) {
- ctx->FragmentProgram.CurrentPosition = inst->StringPos;
- ctx->FragmentProgram.Callback(program->Base.Target,
- ctx->FragmentProgram.CallbackData);
- }
-
- if (DEBUG_FRAG) {
- _mesa_print_instruction(inst);
- }
-
- switch (inst->Opcode) {
- case OPCODE_ABS:
- {
- GLfloat a[4], result[4];
- fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a );
- result[0] = FABSF(a[0]);
- result[1] = FABSF(a[1]);
- result[2] = FABSF(a[2]);
- result[3] = FABSF(a[3]);
- store_vector4( inst, machine, result );
- }
- break;
- case OPCODE_ADD:
- {
- GLfloat a[4], b[4], result[4];
- fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a );
- fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b );
- result[0] = a[0] + b[0];
- result[1] = a[1] + b[1];
- result[2] = a[2] + b[2];
- result[3] = a[3] + b[3];
- store_vector4( inst, machine, result );
- if (DEBUG_FRAG) {
- printf("ADD (%g %g %g %g) = (%g %g %g %g) + (%g %g %g %g)\n",
- result[0], result[1], result[2], result[3],
- a[0], a[1], a[2], a[3],
- b[0], b[1], b[2], b[3]);
- }
- }
- break;
- case OPCODE_BRA: /* conditional branch */
- {
- /* NOTE: The return is conditional! */
- const GLuint swizzle = inst->DstReg.CondSwizzle;
- const GLuint condMask = inst->DstReg.CondMask;
- if (test_cc(machine->CondCodes[GET_SWZ(swizzle, 0)], condMask) ||
- test_cc(machine->CondCodes[GET_SWZ(swizzle, 1)], condMask) ||
- test_cc(machine->CondCodes[GET_SWZ(swizzle, 2)], condMask) ||
- test_cc(machine->CondCodes[GET_SWZ(swizzle, 3)], condMask)) {
- /* take branch */
- pc = inst->BranchTarget;
- }
- }
- break;
- case OPCODE_CAL: /* Call subroutine */
- {
- /* NOTE: The call is conditional! */
- const GLuint swizzle = inst->DstReg.CondSwizzle;
- const GLuint condMask = inst->DstReg.CondMask;
- if (test_cc(machine->CondCodes[GET_SWZ(swizzle, 0)], condMask) ||
- test_cc(machine->CondCodes[GET_SWZ(swizzle, 1)], condMask) ||
- test_cc(machine->CondCodes[GET_SWZ(swizzle, 2)], condMask) ||
- test_cc(machine->CondCodes[GET_SWZ(swizzle, 3)], condMask)) {
- if (machine->StackDepth >= MAX_PROGRAM_CALL_DEPTH) {
- return GL_TRUE; /* Per GL_NV_vertex_program2 spec */
- }
- machine->CallStack[machine->StackDepth++] = pc + 1;
- pc = inst->BranchTarget;
- }
- }
- break;
- case OPCODE_CMP:
- {
- GLfloat a[4], b[4], c[4], result[4];
- fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a );
- fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b );
- fetch_vector4( ctx, &inst->SrcReg[2], machine, program, c );
- result[0] = a[0] < 0.0F ? b[0] : c[0];
- result[1] = a[1] < 0.0F ? b[1] : c[1];
- result[2] = a[2] < 0.0F ? b[2] : c[2];
- result[3] = a[3] < 0.0F ? b[3] : c[3];
- store_vector4( inst, machine, result );
- }
- break;
- case OPCODE_COS:
- {
- GLfloat a[4], result[4];
- fetch_vector1( ctx, &inst->SrcReg[0], machine, program, a );
- result[0] = result[1] = result[2] = result[3]
- = (GLfloat) _mesa_cos(a[0]);
- store_vector4( inst, machine, result );
- }
- break;
- case OPCODE_DDX: /* Partial derivative with respect to X */
- {
- GLfloat a[4], aNext[4], result[4];
- struct fp_machine dMachine;
- if (!fetch_vector4_deriv(ctx, &inst->SrcReg[0], span, 'X',
- column, result)) {
- /* This is tricky. Make a copy of the current machine state,
- * increment the input registers by the dx or dy partial
- * derivatives, then re-execute the program up to the
- * preceeding instruction, then fetch the source register.
- * Finally, find the difference in the register values for
- * the original and derivative runs.
- */
- fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a);
- init_machine_deriv(ctx, machine, program, span,
- 'X', &dMachine);
- execute_program(ctx, program, pc, &dMachine, span, column);
- fetch_vector4( ctx, &inst->SrcReg[0], &dMachine, program, aNext );
- result[0] = aNext[0] - a[0];
- result[1] = aNext[1] - a[1];
- result[2] = aNext[2] - a[2];
- result[3] = aNext[3] - a[3];
- }
- store_vector4( inst, machine, result );
- }
- break;
- case OPCODE_DDY: /* Partial derivative with respect to Y */
- {
- GLfloat a[4], aNext[4], result[4];
- struct fp_machine dMachine;
- if (!fetch_vector4_deriv(ctx, &inst->SrcReg[0], span, 'Y',
- column, result)) {
- init_machine_deriv(ctx, machine, program, span,
- 'Y', &dMachine);
- fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a);
- execute_program(ctx, program, pc, &dMachine, span, column);
- fetch_vector4( ctx, &inst->SrcReg[0], &dMachine, program, aNext );
- result[0] = aNext[0] - a[0];
- result[1] = aNext[1] - a[1];
- result[2] = aNext[2] - a[2];
- result[3] = aNext[3] - a[3];
- }
- store_vector4( inst, machine, result );
- }
- break;
- case OPCODE_DP3:
- {
- GLfloat a[4], b[4], result[4];
- fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a );
- fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b );
- result[0] = result[1] = result[2] = result[3] = DOT3(a, b);
- store_vector4( inst, machine, result );
- if (DEBUG_FRAG) {
- printf("DP3 %g = (%g %g %g) . (%g %g %g)\n",
- result[0], a[0], a[1], a[2], b[0], b[1], b[2]);
- }
- }
- break;
- case OPCODE_DP4:
- {
- GLfloat a[4], b[4], result[4];
- fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a );
- fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b );
- result[0] = result[1] = result[2] = result[3] = DOT4(a,b);
- store_vector4( inst, machine, result );
- if (DEBUG_FRAG) {
- printf("DP4 %g = (%g, %g %g %g) . (%g, %g %g %g)\n",
- result[0], a[0], a[1], a[2], a[3],
- b[0], b[1], b[2], b[3]);
- }
- }
- break;
- case OPCODE_DPH:
- {
- GLfloat a[4], b[4], result[4];
- fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a );
- fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b );
- result[0] = result[1] = result[2] = result[3] =
- a[0] * b[0] + a[1] * b[1] + a[2] * b[2] + b[3];
- store_vector4( inst, machine, result );
- }
- break;
- case OPCODE_DST: /* Distance vector */
- {
- GLfloat a[4], b[4], result[4];
- fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a );
- fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b );
- result[0] = 1.0F;
- result[1] = a[1] * b[1];
- result[2] = a[2];
- result[3] = b[3];
- store_vector4( inst, machine, result );
- }
- break;
- case OPCODE_EX2: /* Exponential base 2 */
- {
- GLfloat a[4], result[4];
- fetch_vector1( ctx, &inst->SrcReg[0], machine, program, a );
- result[0] = result[1] = result[2] = result[3] =
- (GLfloat) _mesa_pow(2.0, a[0]);
- store_vector4( inst, machine, result );
- }
- break;
- case OPCODE_FLR:
- {
- GLfloat a[4], result[4];
- fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a );
- result[0] = FLOORF(a[0]);
- result[1] = FLOORF(a[1]);
- result[2] = FLOORF(a[2]);
- result[3] = FLOORF(a[3]);
- store_vector4( inst, machine, result );
- }
- break;
- case OPCODE_FRC:
- {
- GLfloat a[4], result[4];
- fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a );
- result[0] = a[0] - FLOORF(a[0]);
- result[1] = a[1] - FLOORF(a[1]);
- result[2] = a[2] - FLOORF(a[2]);
- result[3] = a[3] - FLOORF(a[3]);
- store_vector4( inst, machine, result );
- }
- break;
- case OPCODE_KIL_NV: /* NV_f_p only */
- {
- const GLuint swizzle = inst->DstReg.CondSwizzle;
- const GLuint condMask = inst->DstReg.CondMask;
- if (test_cc(machine->CondCodes[GET_SWZ(swizzle, 0)], condMask) ||
- test_cc(machine->CondCodes[GET_SWZ(swizzle, 1)], condMask) ||
- test_cc(machine->CondCodes[GET_SWZ(swizzle, 2)], condMask) ||
- test_cc(machine->CondCodes[GET_SWZ(swizzle, 3)], condMask)) {
- return GL_FALSE;
- }
- }
- break;
- case OPCODE_KIL: /* ARB_f_p only */
- {
- GLfloat a[4];
- fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a );
- if (a[0] < 0.0F || a[1] < 0.0F || a[2] < 0.0F || a[3] < 0.0F) {
- return GL_FALSE;
- }
- }
- break;
- case OPCODE_LG2: /* log base 2 */
- {
- GLfloat a[4], result[4];
- fetch_vector1( ctx, &inst->SrcReg[0], machine, program, a );
- result[0] = result[1] = result[2] = result[3] = LOG2(a[0]);
- store_vector4( inst, machine, result );
- }
- break;
- case OPCODE_LIT:
- {
- const GLfloat epsilon = 1.0F / 256.0F; /* from NV VP spec */
- GLfloat a[4], result[4];
- fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a );
- a[0] = MAX2(a[0], 0.0F);
- a[1] = MAX2(a[1], 0.0F);
- /* XXX ARB version clamps a[3], NV version doesn't */
- a[3] = CLAMP(a[3], -(128.0F - epsilon), (128.0F - epsilon));
- result[0] = 1.0F;
- result[1] = a[0];
- /* XXX we could probably just use pow() here */
- if (a[0] > 0.0F) {
- if (a[1] == 0.0 && a[3] == 0.0)
- result[2] = 1.0;
- else
- result[2] = EXPF(a[3] * LOGF(a[1]));
- }
- else {
- result[2] = 0.0;
- }
- result[3] = 1.0F;
- store_vector4( inst, machine, result );
- if (DEBUG_FRAG) {
- printf("LIT (%g %g %g %g) : (%g %g %g %g)\n",
- result[0], result[1], result[2], result[3],
- a[0], a[1], a[2], a[3]);
- }
- }
- break;
- case OPCODE_LRP:
- {
- GLfloat a[4], b[4], c[4], result[4];
- fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a );
- fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b );
- fetch_vector4( ctx, &inst->SrcReg[2], machine, program, c );
- result[0] = a[0] * b[0] + (1.0F - a[0]) * c[0];
- result[1] = a[1] * b[1] + (1.0F - a[1]) * c[1];
- result[2] = a[2] * b[2] + (1.0F - a[2]) * c[2];
- result[3] = a[3] * b[3] + (1.0F - a[3]) * c[3];
- store_vector4( inst, machine, result );
- if (DEBUG_FRAG) {
- printf("LRP (%g %g %g %g) = (%g %g %g %g), "
- "(%g %g %g %g), (%g %g %g %g)\n",
- result[0], result[1], result[2], result[3],
- a[0], a[1], a[2], a[3],
- b[0], b[1], b[2], b[3],
- c[0], c[1], c[2], c[3]);
- }
- }
- break;
- case OPCODE_MAD:
- {
- GLfloat a[4], b[4], c[4], result[4];
- fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a );
- fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b );
- fetch_vector4( ctx, &inst->SrcReg[2], machine, program, c );
- result[0] = a[0] * b[0] + c[0];
- result[1] = a[1] * b[1] + c[1];
- result[2] = a[2] * b[2] + c[2];
- result[3] = a[3] * b[3] + c[3];
- store_vector4( inst, machine, result );
- if (DEBUG_FRAG) {
- printf("MAD (%g %g %g %g) = (%g %g %g %g) * "
- "(%g %g %g %g) + (%g %g %g %g)\n",
- result[0], result[1], result[2], result[3],
- a[0], a[1], a[2], a[3],
- b[0], b[1], b[2], b[3],
- c[0], c[1], c[2], c[3]);
- }
- }
- break;
- case OPCODE_MAX:
- {
- GLfloat a[4], b[4], result[4];
- fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a );
- fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b );
- result[0] = MAX2(a[0], b[0]);
- result[1] = MAX2(a[1], b[1]);
- result[2] = MAX2(a[2], b[2]);
- result[3] = MAX2(a[3], b[3]);
- store_vector4( inst, machine, result );
- if (DEBUG_FRAG) {
- printf("MAX (%g %g %g %g) = (%g %g %g %g), (%g %g %g %g)\n",
- result[0], result[1], result[2], result[3],
- a[0], a[1], a[2], a[3],
- b[0], b[1], b[2], b[3]);
- }
- }
- break;
- case OPCODE_MIN:
- {
- GLfloat a[4], b[4], result[4];
- fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a );
- fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b );
- result[0] = MIN2(a[0], b[0]);
- result[1] = MIN2(a[1], b[1]);
- result[2] = MIN2(a[2], b[2]);
- result[3] = MIN2(a[3], b[3]);
- store_vector4( inst, machine, result );
- }
- break;
- case OPCODE_MOV:
- {
- GLfloat result[4];
- fetch_vector4( ctx, &inst->SrcReg[0], machine, program, result );
- store_vector4( inst, machine, result );
- if (DEBUG_FRAG) {
- printf("MOV (%g %g %g %g)\n",
- result[0], result[1], result[2], result[3]);
- }
- }
- break;
- case OPCODE_MUL:
- {
- GLfloat a[4], b[4], result[4];
- fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a );
- fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b );
- result[0] = a[0] * b[0];
- result[1] = a[1] * b[1];
- result[2] = a[2] * b[2];
- result[3] = a[3] * b[3];
- store_vector4( inst, machine, result );
- if (DEBUG_FRAG) {
- printf("MUL (%g %g %g %g) = (%g %g %g %g) * (%g %g %g %g)\n",
- result[0], result[1], result[2], result[3],
- a[0], a[1], a[2], a[3],
- b[0], b[1], b[2], b[3]);
- }
- }
- break;
- case OPCODE_PK2H: /* pack two 16-bit floats in one 32-bit float */
- {
- GLfloat a[4], result[4];
- GLhalfNV hx, hy;
- GLuint *rawResult = (GLuint *) result;
- GLuint twoHalves;
- fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a );
- hx = _mesa_float_to_half(a[0]);
- hy = _mesa_float_to_half(a[1]);
- twoHalves = hx | (hy << 16);
- rawResult[0] = rawResult[1] = rawResult[2] = rawResult[3]
- = twoHalves;
- store_vector4( inst, machine, result );
- }
- break;
- case OPCODE_PK2US: /* pack two GLushorts into one 32-bit float */
- {
- GLfloat a[4], result[4];
- GLuint usx, usy, *rawResult = (GLuint *) result;
- fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a );
- a[0] = CLAMP(a[0], 0.0F, 1.0F);
- a[1] = CLAMP(a[1], 0.0F, 1.0F);
- usx = IROUND(a[0] * 65535.0F);
- usy = IROUND(a[1] * 65535.0F);
- rawResult[0] = rawResult[1] = rawResult[2] = rawResult[3]
- = usx | (usy << 16);
- store_vector4( inst, machine, result );
- }
- break;
- case OPCODE_PK4B: /* pack four GLbytes into one 32-bit float */
- {
- GLfloat a[4], result[4];
- GLuint ubx, uby, ubz, ubw, *rawResult = (GLuint *) result;
- fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a );
- a[0] = CLAMP(a[0], -128.0F / 127.0F, 1.0F);
- a[1] = CLAMP(a[1], -128.0F / 127.0F, 1.0F);
- a[2] = CLAMP(a[2], -128.0F / 127.0F, 1.0F);
- a[3] = CLAMP(a[3], -128.0F / 127.0F, 1.0F);
- ubx = IROUND(127.0F * a[0] + 128.0F);
- uby = IROUND(127.0F * a[1] + 128.0F);
- ubz = IROUND(127.0F * a[2] + 128.0F);
- ubw = IROUND(127.0F * a[3] + 128.0F);
- rawResult[0] = rawResult[1] = rawResult[2] = rawResult[3]
- = ubx | (uby << 8) | (ubz << 16) | (ubw << 24);
- store_vector4( inst, machine, result );
- }
- break;
- case OPCODE_PK4UB: /* pack four GLubytes into one 32-bit float */
- {
- GLfloat a[4], result[4];
- GLuint ubx, uby, ubz, ubw, *rawResult = (GLuint *) result;
- fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a );
- a[0] = CLAMP(a[0], 0.0F, 1.0F);
- a[1] = CLAMP(a[1], 0.0F, 1.0F);
- a[2] = CLAMP(a[2], 0.0F, 1.0F);
- a[3] = CLAMP(a[3], 0.0F, 1.0F);
- ubx = IROUND(255.0F * a[0]);
- uby = IROUND(255.0F * a[1]);
- ubz = IROUND(255.0F * a[2]);
- ubw = IROUND(255.0F * a[3]);
- rawResult[0] = rawResult[1] = rawResult[2] = rawResult[3]
- = ubx | (uby << 8) | (ubz << 16) | (ubw << 24);
- store_vector4( inst, machine, result );
- }
- break;
- case OPCODE_POW:
- {
- GLfloat a[4], b[4], result[4];
- fetch_vector1( ctx, &inst->SrcReg[0], machine, program, a );
- fetch_vector1( ctx, &inst->SrcReg[1], machine, program, b );
- result[0] = result[1] = result[2] = result[3]
- = (GLfloat)_mesa_pow(a[0], b[0]);
- store_vector4( inst, machine, result );
- }
- break;
- case OPCODE_RCP:
- {
- GLfloat a[4], result[4];
- fetch_vector1( ctx, &inst->SrcReg[0], machine, program, a );
- if (DEBUG_FRAG) {
- if (a[0] == 0)
- printf("RCP(0)\n");
- else if (IS_INF_OR_NAN(a[0]))
- printf("RCP(inf)\n");
- }
- result[0] = result[1] = result[2] = result[3] = 1.0F / a[0];
- store_vector4( inst, machine, result );
- }
- break;
- case OPCODE_RET: /* return from subroutine */
- {
- /* NOTE: The return is conditional! */
- const GLuint swizzle = inst->DstReg.CondSwizzle;
- const GLuint condMask = inst->DstReg.CondMask;
- if (test_cc(machine->CondCodes[GET_SWZ(swizzle, 0)], condMask) ||
- test_cc(machine->CondCodes[GET_SWZ(swizzle, 1)], condMask) ||
- test_cc(machine->CondCodes[GET_SWZ(swizzle, 2)], condMask) ||
- test_cc(machine->CondCodes[GET_SWZ(swizzle, 3)], condMask)) {
- if (machine->StackDepth == 0) {
- return GL_TRUE; /* Per GL_NV_vertex_program2 spec */
- }
- pc = machine->CallStack[--machine->StackDepth];
- }
- }
- break;
- case OPCODE_RFL: /* reflection vector */
- {
- GLfloat axis[4], dir[4], result[4], tmpX, tmpW;
- fetch_vector4( ctx, &inst->SrcReg[0], machine, program, axis );
- fetch_vector4( ctx, &inst->SrcReg[1], machine, program, dir );
- tmpW = DOT3(axis, axis);
- tmpX = (2.0F * DOT3(axis, dir)) / tmpW;
- result[0] = tmpX * axis[0] - dir[0];
- result[1] = tmpX * axis[1] - dir[1];
- result[2] = tmpX * axis[2] - dir[2];
- /* result[3] is never written! XXX enforce in parser! */
- store_vector4( inst, machine, result );
- }
- break;
- case OPCODE_RSQ: /* 1 / sqrt() */
- {
- GLfloat a[4], result[4];
- fetch_vector1( ctx, &inst->SrcReg[0], machine, program, a );
- a[0] = FABSF(a[0]);
- result[0] = result[1] = result[2] = result[3] = INV_SQRTF(a[0]);
- store_vector4( inst, machine, result );
- if (DEBUG_FRAG) {
- printf("RSQ %g = 1/sqrt(|%g|)\n", result[0], a[0]);
- }
- }
- break;
- case OPCODE_SCS: /* sine and cos */
- {
- GLfloat a[4], result[4];
- fetch_vector1( ctx, &inst->SrcReg[0], machine, program, a );
- result[0] = (GLfloat)_mesa_cos(a[0]);
- result[1] = (GLfloat)_mesa_sin(a[0]);
- result[2] = 0.0; /* undefined! */
- result[3] = 0.0; /* undefined! */
- store_vector4( inst, machine, result );
- }
- break;
- case OPCODE_SEQ: /* set on equal */
- {
- GLfloat a[4], b[4], result[4];
- fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a );
- fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b );
- result[0] = (a[0] == b[0]) ? 1.0F : 0.0F;
- result[1] = (a[1] == b[1]) ? 1.0F : 0.0F;
- result[2] = (a[2] == b[2]) ? 1.0F : 0.0F;
- result[3] = (a[3] == b[3]) ? 1.0F : 0.0F;
- store_vector4( inst, machine, result );
- }
- break;
- case OPCODE_SFL: /* set false, operands ignored */
- {
- static const GLfloat result[4] = { 0.0F, 0.0F, 0.0F, 0.0F };
- store_vector4( inst, machine, result );
- }
- break;
- case OPCODE_SGE: /* set on greater or equal */
- {
- GLfloat a[4], b[4], result[4];
- fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a );
- fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b );
- result[0] = (a[0] >= b[0]) ? 1.0F : 0.0F;
- result[1] = (a[1] >= b[1]) ? 1.0F : 0.0F;
- result[2] = (a[2] >= b[2]) ? 1.0F : 0.0F;
- result[3] = (a[3] >= b[3]) ? 1.0F : 0.0F;
- store_vector4( inst, machine, result );
- }
- break;
- case OPCODE_SGT: /* set on greater */
- {
- GLfloat a[4], b[4], result[4];
- fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a );
- fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b );
- result[0] = (a[0] > b[0]) ? 1.0F : 0.0F;
- result[1] = (a[1] > b[1]) ? 1.0F : 0.0F;
- result[2] = (a[2] > b[2]) ? 1.0F : 0.0F;
- result[3] = (a[3] > b[3]) ? 1.0F : 0.0F;
- store_vector4( inst, machine, result );
- }
- break;
- case OPCODE_SIN:
- {
- GLfloat a[4], result[4];
- fetch_vector1( ctx, &inst->SrcReg[0], machine, program, a );
- result[0] = result[1] = result[2] = result[3]
- = (GLfloat) _mesa_sin(a[0]);
- store_vector4( inst, machine, result );
- }
- break;
- case OPCODE_SLE: /* set on less or equal */
- {
- GLfloat a[4], b[4], result[4];
- fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a );
- fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b );
- result[0] = (a[0] <= b[0]) ? 1.0F : 0.0F;
- result[1] = (a[1] <= b[1]) ? 1.0F : 0.0F;
- result[2] = (a[2] <= b[2]) ? 1.0F : 0.0F;
- result[3] = (a[3] <= b[3]) ? 1.0F : 0.0F;
- store_vector4( inst, machine, result );
- }
- break;
- case OPCODE_SLT: /* set on less */
- {
- GLfloat a[4], b[4], result[4];
- fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a );
- fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b );
- result[0] = (a[0] < b[0]) ? 1.0F : 0.0F;
- result[1] = (a[1] < b[1]) ? 1.0F : 0.0F;
- result[2] = (a[2] < b[2]) ? 1.0F : 0.0F;
- result[3] = (a[3] < b[3]) ? 1.0F : 0.0F;
- store_vector4( inst, machine, result );
- }
- break;
- case OPCODE_SNE: /* set on not equal */
- {
- GLfloat a[4], b[4], result[4];
- fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a );
- fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b );
- result[0] = (a[0] != b[0]) ? 1.0F : 0.0F;
- result[1] = (a[1] != b[1]) ? 1.0F : 0.0F;
- result[2] = (a[2] != b[2]) ? 1.0F : 0.0F;
- result[3] = (a[3] != b[3]) ? 1.0F : 0.0F;
- store_vector4( inst, machine, result );
- }
- break;
- case OPCODE_STR: /* set true, operands ignored */
- {
- static const GLfloat result[4] = { 1.0F, 1.0F, 1.0F, 1.0F };
- store_vector4( inst, machine, result );
- }
- break;
- case OPCODE_SUB:
- {
- GLfloat a[4], b[4], result[4];
- fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a );
- fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b );
- result[0] = a[0] - b[0];
- result[1] = a[1] - b[1];
- result[2] = a[2] - b[2];
- result[3] = a[3] - b[3];
- store_vector4( inst, machine, result );
- if (DEBUG_FRAG) {
- printf("SUB (%g %g %g %g) = (%g %g %g %g) - (%g %g %g %g)\n",
- result[0], result[1], result[2], result[3],
- a[0], a[1], a[2], a[3], b[0], b[1], b[2], b[3]);
- }
- }
- break;
- case OPCODE_SWZ: /* extended swizzle */
- {
- const struct prog_src_register *source = &inst->SrcReg[0];
- const GLfloat *src = get_register_pointer(ctx, source,
- machine, program);
- GLfloat result[4];
- GLuint i;
- for (i = 0; i < 4; i++) {
- const GLuint swz = GET_SWZ(source->Swizzle, i);
- if (swz == SWIZZLE_ZERO)
- result[i] = 0.0;
- else if (swz == SWIZZLE_ONE)
- result[i] = 1.0;
- else {
- ASSERT(swz >= 0);
- ASSERT(swz <= 3);
- result[i] = src[swz];
- }
- if (source->NegateBase & (1 << i))
- result[i] = -result[i];
- }
- store_vector4( inst, machine, result );
- }
- break;
- case OPCODE_TEX: /* Both ARB and NV frag prog */
- /* Texel lookup */
- {
- /* Note: only use the precomputed lambda value when we're
- * sampling texture unit [K] with texcoord[K].
- * Otherwise, the lambda value may have no relation to the
- * instruction's texcoord or texture image. Using the wrong
- * lambda is usually bad news.
- * The rest of the time, just use zero (until we get a more
- * sophisticated way of computing lambda).
- */
- GLfloat coord[4], color[4], lambda;
- if (inst->SrcReg[0].File == PROGRAM_INPUT &&
- inst->SrcReg[0].Index == FRAG_ATTRIB_TEX0+inst->TexSrcUnit)
- lambda = span->array->lambda[inst->TexSrcUnit][column];
- else
- lambda = 0.0;
- fetch_vector4(ctx, &inst->SrcReg[0], machine, program, coord);
- fetch_texel( ctx, coord, lambda, inst->TexSrcUnit, color );
- if (DEBUG_FRAG) {
- printf("TEX (%g, %g, %g, %g) = texture[%d][%g, %g, %g, %g], "
- "lod %f\n",
- color[0], color[1], color[2], color[3],
- inst->TexSrcUnit,
- coord[0], coord[1], coord[2], coord[3], lambda);
- }
- store_vector4( inst, machine, color );
- }
- break;
- case OPCODE_TXB: /* GL_ARB_fragment_program only */
- /* Texel lookup with LOD bias */
- {
- GLfloat coord[4], color[4], lambda, bias;
- if (inst->SrcReg[0].File == PROGRAM_INPUT &&
- inst->SrcReg[0].Index == FRAG_ATTRIB_TEX0+inst->TexSrcUnit)
- lambda = span->array->lambda[inst->TexSrcUnit][column];
- else
- lambda = 0.0;
- fetch_vector4(ctx, &inst->SrcReg[0], machine, program, coord);
- /* coord[3] is the bias to add to lambda */
- bias = ctx->Texture.Unit[inst->TexSrcUnit].LodBias
- + ctx->Texture.Unit[inst->TexSrcUnit]._Current->LodBias
- + coord[3];
- fetch_texel(ctx, coord, lambda + bias, inst->TexSrcUnit, color);
- store_vector4( inst, machine, color );
- }
- break;
- case OPCODE_TXD: /* GL_NV_fragment_program only */
- /* Texture lookup w/ partial derivatives for LOD */
- {
- GLfloat texcoord[4], dtdx[4], dtdy[4], color[4];
- fetch_vector4( ctx, &inst->SrcReg[0], machine, program, texcoord );
- fetch_vector4( ctx, &inst->SrcReg[1], machine, program, dtdx );
- fetch_vector4( ctx, &inst->SrcReg[2], machine, program, dtdy );
- fetch_texel_deriv( ctx, texcoord, dtdx, dtdy, inst->TexSrcUnit,
- color );
- store_vector4( inst, machine, color );
- }
- break;
- case OPCODE_TXP: /* GL_ARB_fragment_program only */
- /* Texture lookup w/ projective divide */
- {
- GLfloat texcoord[4], color[4], lambda;
- if (inst->SrcReg[0].File == PROGRAM_INPUT &&
- inst->SrcReg[0].Index == FRAG_ATTRIB_TEX0+inst->TexSrcUnit)
- lambda = span->array->lambda[inst->TexSrcUnit][column];
- else
- lambda = 0.0;
- fetch_vector4(ctx, &inst->SrcReg[0], machine, program,texcoord);
- /* Not so sure about this test - if texcoord[3] is
- * zero, we'd probably be fine except for an ASSERT in
- * IROUND_POS() which gets triggered by the inf values created.
- */
- if (texcoord[3] != 0.0) {
- texcoord[0] /= texcoord[3];
- texcoord[1] /= texcoord[3];
- texcoord[2] /= texcoord[3];
- }
- fetch_texel( ctx, texcoord, lambda, inst->TexSrcUnit, color );
- store_vector4( inst, machine, color );
- }
- break;
- case OPCODE_TXP_NV: /* GL_NV_fragment_program only */
- /* Texture lookup w/ projective divide */
- {
- GLfloat texcoord[4], color[4], lambda;
- if (inst->SrcReg[0].File == PROGRAM_INPUT &&
- inst->SrcReg[0].Index == FRAG_ATTRIB_TEX0+inst->TexSrcUnit)
- lambda = span->array->lambda[inst->TexSrcUnit][column];
- else
- lambda = 0.0;
- fetch_vector4(ctx, &inst->SrcReg[0], machine, program,texcoord);
- if (inst->TexSrcTarget != TEXTURE_CUBE_INDEX &&
- texcoord[3] != 0.0) {
- texcoord[0] /= texcoord[3];
- texcoord[1] /= texcoord[3];
- texcoord[2] /= texcoord[3];
- }
- fetch_texel( ctx, texcoord, lambda, inst->TexSrcUnit, color );
- store_vector4( inst, machine, color );
- }
- break;
- case OPCODE_UP2H: /* unpack two 16-bit floats */
- {
- GLfloat a[4], result[4];
- const GLuint *rawBits = (const GLuint *) a;
- GLhalfNV hx, hy;
- fetch_vector1( ctx, &inst->SrcReg[0], machine, program, a );
- hx = rawBits[0] & 0xffff;
- hy = rawBits[0] >> 16;
- result[0] = result[2] = _mesa_half_to_float(hx);
- result[1] = result[3] = _mesa_half_to_float(hy);
- store_vector4( inst, machine, result );
- }
- break;
- case OPCODE_UP2US: /* unpack two GLushorts */
- {
- GLfloat a[4], result[4];
- const GLuint *rawBits = (const GLuint *) a;
- GLushort usx, usy;
- fetch_vector1( ctx, &inst->SrcReg[0], machine, program, a );
- usx = rawBits[0] & 0xffff;
- usy = rawBits[0] >> 16;
- result[0] = result[2] = usx * (1.0f / 65535.0f);
- result[1] = result[3] = usy * (1.0f / 65535.0f);
- store_vector4( inst, machine, result );
- }
- break;
- case OPCODE_UP4B: /* unpack four GLbytes */
- {
- GLfloat a[4], result[4];
- const GLuint *rawBits = (const GLuint *) a;
- fetch_vector1( ctx, &inst->SrcReg[0], machine, program, a );
- result[0] = (((rawBits[0] >> 0) & 0xff) - 128) / 127.0F;
- result[1] = (((rawBits[0] >> 8) & 0xff) - 128) / 127.0F;
- result[2] = (((rawBits[0] >> 16) & 0xff) - 128) / 127.0F;
- result[3] = (((rawBits[0] >> 24) & 0xff) - 128) / 127.0F;
- store_vector4( inst, machine, result );
- }
- break;
- case OPCODE_UP4UB: /* unpack four GLubytes */
- {
- GLfloat a[4], result[4];
- const GLuint *rawBits = (const GLuint *) a;
- fetch_vector1( ctx, &inst->SrcReg[0], machine, program, a );
- result[0] = ((rawBits[0] >> 0) & 0xff) / 255.0F;
- result[1] = ((rawBits[0] >> 8) & 0xff) / 255.0F;
- result[2] = ((rawBits[0] >> 16) & 0xff) / 255.0F;
- result[3] = ((rawBits[0] >> 24) & 0xff) / 255.0F;
- store_vector4( inst, machine, result );
- }
- break;
- case OPCODE_XPD: /* cross product */
- {
- GLfloat a[4], b[4], result[4];
- fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a );
- fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b );
- result[0] = a[1] * b[2] - a[2] * b[1];
- result[1] = a[2] * b[0] - a[0] * b[2];
- result[2] = a[0] * b[1] - a[1] * b[0];
- result[3] = 1.0;
- store_vector4( inst, machine, result );
- }
- break;
- case OPCODE_X2D: /* 2-D matrix transform */
- {
- GLfloat a[4], b[4], c[4], result[4];
- fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a );
- fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b );
- fetch_vector4( ctx, &inst->SrcReg[2], machine, program, c );
- result[0] = a[0] + b[0] * c[0] + b[1] * c[1];
- result[1] = a[1] + b[0] * c[2] + b[1] * c[3];
- result[2] = a[2] + b[0] * c[0] + b[1] * c[1];
- result[3] = a[3] + b[0] * c[2] + b[1] * c[3];
- store_vector4( inst, machine, result );
- }
- break;
- case OPCODE_PRINT:
- {
- if (inst->SrcReg[0].File != -1) {
- GLfloat a[4];
- fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a);
- _mesa_printf("%s%g, %g, %g, %g\n", (const char *) inst->Data,
- a[0], a[1], a[2], a[3]);
- }
- else {
- _mesa_printf("%s\n", (const char *) inst->Data);
- }
- }
- break;
- case OPCODE_END:
- return GL_TRUE;
- default:
- _mesa_problem(ctx, "Bad opcode %d in _mesa_exec_fragment_program",
- inst->Opcode);
- return GL_TRUE; /* return value doesn't matter */
- }
- }
- return GL_TRUE;
-}
-
-
-/**
- * Initialize the virtual fragment program machine state prior to running
- * fragment program on a fragment. This involves initializing the input
- * registers, condition codes, etc.
- * \param machine the virtual machine state to init
- * \param program the fragment program we're about to run
- * \param span the span of pixels we'll operate on
- * \param col which element (column) of the span we'll operate on
- */
-static void
-init_machine( GLcontext *ctx, struct fp_machine *machine,
- const struct gl_fragment_program *program,
- const SWspan *span, GLuint col )
-{
- GLuint inputsRead = program->Base.InputsRead;
- GLuint u;
-
- if (ctx->FragmentProgram.CallbackEnabled)
- inputsRead = ~0;
-
- if (program->Base.Target == GL_FRAGMENT_PROGRAM_NV) {
- /* Clear temporary registers (undefined for ARB_f_p) */
- _mesa_bzero(machine->Temporaries,
- MAX_NV_FRAGMENT_PROGRAM_TEMPS * 4 * sizeof(GLfloat));
- }
-
- /* Load input registers */
- if (inputsRead & (1 << FRAG_ATTRIB_WPOS)) {
- GLfloat *wpos = machine->Inputs[FRAG_ATTRIB_WPOS];
- ASSERT(span->arrayMask & SPAN_Z);
- if (span->arrayMask & SPAN_XY) {
- wpos[0] = (GLfloat) span->array->x[col];
- wpos[1] = (GLfloat) span->array->y[col];
- }
- else {
- wpos[0] = (GLfloat) span->x + col;
- wpos[1] = (GLfloat) span->y;
- }
- wpos[2] = (GLfloat) span->array->z[col] / ctx->DrawBuffer->_DepthMaxF;
- wpos[3] = span->w + col * span->dwdx;
- }
- if (inputsRead & (1 << FRAG_ATTRIB_COL0)) {
- ASSERT(span->arrayMask & SPAN_RGBA);
- COPY_4V(machine->Inputs[FRAG_ATTRIB_COL0],
- span->array->color.sz4.rgba[col]);
- }
- if (inputsRead & (1 << FRAG_ATTRIB_COL1)) {
- ASSERT(span->arrayMask & SPAN_SPEC);
- COPY_4V(machine->Inputs[FRAG_ATTRIB_COL1],
- span->array->color.sz4.spec[col]);
- }
- if (inputsRead & (1 << FRAG_ATTRIB_FOGC)) {
- GLfloat *fogc = machine->Inputs[FRAG_ATTRIB_FOGC];
- ASSERT(span->arrayMask & SPAN_FOG);
- fogc[0] = span->array->fog[col];
- fogc[1] = 0.0F;
- fogc[2] = 0.0F;
- fogc[3] = 0.0F;
- }
- for (u = 0; u < ctx->Const.MaxTextureCoordUnits; u++) {
- if (inputsRead & (1 << (FRAG_ATTRIB_TEX0 + u))) {
- GLfloat *tex = machine->Inputs[FRAG_ATTRIB_TEX0 + u];
- /*ASSERT(ctx->Texture._EnabledCoordUnits & (1 << u));*/
- COPY_4V(tex, span->array->texcoords[u][col]);
- /*ASSERT(tex[0] != 0 || tex[1] != 0 || tex[2] != 0);*/
- }
- }
-
- /* init condition codes */
- machine->CondCodes[0] = COND_EQ;
- machine->CondCodes[1] = COND_EQ;
- machine->CondCodes[2] = COND_EQ;
- machine->CondCodes[3] = COND_EQ;
-
- /* init call stack */
- machine->StackDepth = 0;
-}
-
-
-/**
- * Run fragment program on the pixels in span from 'start' to 'end' - 1.
- */
-static void
-run_program(GLcontext *ctx, SWspan *span, GLuint start, GLuint end)
-{
- const struct gl_fragment_program *program = ctx->FragmentProgram._Current;
- struct fp_machine machine;
- GLuint i;
-
- CurrentMachine = &machine;
-
- for (i = start; i < end; i++) {
- if (span->array->mask[i]) {
- init_machine(ctx, &machine, program, span, i);
-
- if (execute_program(ctx, program, ~0, &machine, span, i)) {
- /* Store result color */
- COPY_4V(span->array->color.sz4.rgba[i],
- machine.Outputs[FRAG_RESULT_COLR]);
-
- /* Store result depth/z */
- if (program->Base.OutputsWritten & (1 << FRAG_RESULT_DEPR)) {
- const GLfloat depth = machine.Outputs[FRAG_RESULT_DEPR][2];
- if (depth <= 0.0)
- span->array->z[i] = 0;
- else if (depth >= 1.0)
- span->array->z[i] = ctx->DrawBuffer->_DepthMax;
- else
- span->array->z[i] = IROUND(depth * ctx->DrawBuffer->_DepthMaxF);
- }
- }
- else {
- /* killed fragment */
- span->array->mask[i] = GL_FALSE;
- span->writeAll = GL_FALSE;
- }
- }
- }
-
- CurrentMachine = NULL;
-}
-
-
-/**
- * Execute the current fragment program for all the fragments
- * in the given span.
- */
-void
-_swrast_exec_fragment_program( GLcontext *ctx, SWspan *span )
-{
- const struct gl_fragment_program *program = ctx->FragmentProgram._Current;
-
- /* incoming colors should be floats */
- ASSERT(span->array->ChanType == GL_FLOAT);
-
- ctx->_CurrentProgram = GL_FRAGMENT_PROGRAM_ARB; /* or NV, doesn't matter */
-
- run_program(ctx, span, 0, span->end);
-
- if (program->Base.OutputsWritten & (1 << FRAG_RESULT_DEPR)) {
- span->interpMask &= ~SPAN_Z;
- span->arrayMask |= SPAN_Z;
- }
-
- ctx->_CurrentProgram = 0;
-}
-
diff --git a/src/mesa/swrast/s_pointtemp.h b/src/mesa/swrast/s_pointtemp.h
index 083f1ebe83c..cc6f999b91b 100644
--- a/src/mesa/swrast/s_pointtemp.h
+++ b/src/mesa/swrast/s_pointtemp.h
@@ -88,8 +88,8 @@ NAME ( GLcontext *ctx, const SWvertex *vert )
const GLuint colorIndex = (GLuint) vert->index; /* XXX round? */
#endif
#if FLAGS & TEXTURE
- GLfloat texcoord[MAX_TEXTURE_COORD_UNITS][4];
- GLuint u;
+ GLfloat attrib[FRAG_ATTRIB_MAX][4]; /* texture & varying */
+ GLuint attr;
#endif
SWcontext *swrast = SWRAST_CONTEXT(ctx);
SWspan *span = &(swrast->PointSpan);
@@ -107,8 +107,9 @@ NAME ( GLcontext *ctx, const SWvertex *vert )
*/
span->interpMask = SPAN_FOG;
span->arrayMask = SPAN_XY | SPAN_Z;
- span->fog = vert->fog;
- span->fogStep = 0.0;
+ span->attrStart[FRAG_ATTRIB_FOGC][0] = vert->fog;
+ span->attrStepX[FRAG_ATTRIB_FOGC][0] = 0.0;
+ span->attrStepY[FRAG_ATTRIB_FOGC][0] = 0.0;
#if FLAGS & RGBA
span->arrayMask |= SPAN_RGBA;
#endif
@@ -120,31 +121,31 @@ NAME ( GLcontext *ctx, const SWvertex *vert )
#endif
#if FLAGS & TEXTURE
span->arrayMask |= (SPAN_TEXTURE | SPAN_LAMBDA);
- if (ctx->FragmentProgram._Active) {
+ if (ctx->FragmentProgram._Current) {
/* Don't divide texture s,t,r by q (use TXP to do that) */
- for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
- if (ctx->Texture._EnabledCoordUnits & (1 << u)) {
- COPY_4V(texcoord[u], vert->texcoord[u]);
+ for (attr = swrast->_MinFragmentAttrib; attr < swrast->_MaxFragmentAttrib; attr++) {
+ if (swrast->_FragmentAttribs & (1 << attr)) {
+ COPY_4V(attrib[attr], vert->attrib[attr]);
}
}
}
else {
/* Divide texture s,t,r by q here */
- for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
- if (ctx->Texture._EnabledCoordUnits & (1 << u)) {
- const GLfloat q = vert->texcoord[u][3];
+ for (attr = swrast->_MinFragmentAttrib; attr < swrast->_MaxFragmentAttrib; attr++) {
+ if (swrast->_FragmentAttribs & (1 << attr)) {
+ const GLfloat q = vert->attrib[attr][3];
const GLfloat invQ = (q == 0.0F || q == 1.0F) ? 1.0F : (1.0F / q);
- texcoord[u][0] = vert->texcoord[u][0] * invQ;
- texcoord[u][1] = vert->texcoord[u][1] * invQ;
- texcoord[u][2] = vert->texcoord[u][2] * invQ;
- texcoord[u][3] = q;
+ attrib[attr][0] = vert->attrib[attr][0] * invQ;
+ attrib[attr][1] = vert->attrib[attr][1] * invQ;
+ attrib[attr][2] = vert->attrib[attr][2] * invQ;
+ attrib[attr][3] = q;
}
}
}
/* need these for fragment programs */
- span->w = 1.0F;
- span->dwdx = 0.0F;
- span->dwdy = 0.0F;
+ span->attrStart[FRAG_ATTRIB_WPOS][3] = 1.0F;
+ span->attrStepX[FRAG_ATTRIB_WPOS][3] = 0.0F;
+ span->attrStepY[FRAG_ATTRIB_WPOS][3] = 0.0F;
#endif
#if FLAGS & SMOOTH
span->arrayMask |= SPAN_COVERAGE;
@@ -259,7 +260,7 @@ NAME ( GLcontext *ctx, const SWvertex *vert )
count = span->end = 0;
}
for (x = xmin; x <= xmax; x++) {
-#if FLAGS & (SPRITE | TEXTURE)
+#if FLAGS & SPRITE
GLuint u;
#endif
@@ -278,10 +279,13 @@ NAME ( GLcontext *ctx, const SWvertex *vert )
span->array->index[count] = colorIndex;
#endif
#if FLAGS & TEXTURE
- for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
- if (ctx->Texture._EnabledCoordUnits & (1 << u)) {
- COPY_4V(span->array->texcoords[u][count], texcoord[u]);
- span->array->lambda[u][count] = 0.0;
+ for (attr = swrast->_MinFragmentAttrib; attr < swrast->_MaxFragmentAttrib; attr++) {
+ if (swrast->_FragmentAttribs & (1 << attr)) {
+ COPY_4V(span->array->attribs[attr][count], attrib[attr]);
+ if (attr < FRAG_ATTRIB_VAR0) {
+ const GLuint u = attr - FRAG_ATTRIB_TEX0;
+ span->array->lambda[u][count] = 0.0;
+ }
}
}
#endif
@@ -328,6 +332,7 @@ NAME ( GLcontext *ctx, const SWvertex *vert )
#if FLAGS & SPRITE
for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
+ GLuint attr = FRAG_ATTRIB_TEX0 + u;
if (ctx->Texture.Unit[u]._ReallyEnabled) {
if (ctx->Point.CoordReplace[u]) {
GLfloat s = 0.5F + (x + 0.5F - vert->win[0]) / size;
@@ -339,17 +344,18 @@ NAME ( GLcontext *ctx, const SWvertex *vert )
if (ctx->Point.SpriteRMode == GL_ZERO)
r = 0.0F;
else if (ctx->Point.SpriteRMode == GL_S)
- r = vert->texcoord[u][0];
+ r = vert->attrib[attr][0];
else /* GL_R */
- r = vert->texcoord[u][2];
- span->array->texcoords[u][count][0] = s;
- span->array->texcoords[u][count][1] = t;
- span->array->texcoords[u][count][2] = r;
- span->array->texcoords[u][count][3] = 1.0F;
+ r = vert->attrib[attr][2];
+ span->array->attribs[attr][count][0] = s;
+ span->array->attribs[attr][count][1] = t;
+ span->array->attribs[attr][count][2] = r;
+ span->array->attribs[attr][count][3] = 1.0F;
span->array->lambda[u][count] = 0.0; /* XXX fix? */
}
else {
- COPY_4V(span->array->texcoords[u][count], vert->texcoord[u]);
+ COPY_4V(span->array->attribs[attr][count],
+ vert->attrib[attr]);
}
}
}
@@ -400,9 +406,9 @@ NAME ( GLcontext *ctx, const SWvertex *vert )
span->array->index[count] = colorIndex;
#endif
#if FLAGS & TEXTURE
- for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
- if (ctx->Texture.Unit[u]._ReallyEnabled) {
- COPY_4V(span->array->texcoords[u][count], texcoord[u]);
+ for (attr = swrast->_MinFragmentAttrib; attr < swrast->_MaxFragmentAttrib; attr++) {
+ if (swrast->_FragmentAttribs & (1 << attr)) {
+ COPY_4V(span->array->attribs[attr][count], attribs[attr]);
}
}
#endif
diff --git a/src/mesa/swrast/s_readpix.c b/src/mesa/swrast/s_readpix.c
index 7dc48aec681..fe9a70f4eae 100644
--- a/src/mesa/swrast/s_readpix.c
+++ b/src/mesa/swrast/s_readpix.c
@@ -404,7 +404,7 @@ read_rgba_pixels( GLcontext *ctx,
/* no convolution */
const GLint dstStride
= _mesa_image_row_stride(packing, width, format, type);
- GLfloat (*rgba)[4] = swrast->SpanArrays->color.sz4.rgba;
+ GLfloat (*rgba)[4] = swrast->SpanArrays->attribs[FRAG_ATTRIB_COL0];
GLint row;
GLubyte *dst
= (GLubyte *) _mesa_image_address2d(packing, pixels, width, height,
diff --git a/src/mesa/swrast/s_span.c b/src/mesa/swrast/s_span.c
index cca1864ea41..fa7761269d9 100644
--- a/src/mesa/swrast/s_span.c
+++ b/src/mesa/swrast/s_span.c
@@ -39,14 +39,13 @@
#include "s_atifragshader.h"
#include "s_alpha.h"
-#include "s_arbshader.h"
#include "s_blend.h"
#include "s_context.h"
#include "s_depth.h"
#include "s_fog.h"
#include "s_logic.h"
#include "s_masking.h"
-#include "s_nvfragprog.h"
+#include "s_fragprog.h"
#include "s_span.h"
#include "s_stencil.h"
#include "s_texcombine.h"
@@ -76,8 +75,10 @@ _swrast_span_default_z( GLcontext *ctx, SWspan *span )
void
_swrast_span_default_fog( GLcontext *ctx, SWspan *span )
{
- span->fog = _swrast_z_to_fogfactor(ctx, ctx->Current.RasterDistance);
- span->fogStep = span->dfogdx = span->dfogdy = 0.0F;
+ span->attrStart[FRAG_ATTRIB_FOGC][0]
+ = _swrast_z_to_fogfactor(ctx, ctx->Current.RasterDistance);
+ span->attrStepX[FRAG_ATTRIB_FOGC][0] = 0.0;
+ span->attrStepY[FRAG_ATTRIB_FOGC][0] = 0.0;
span->interpMask |= SPAN_FOG;
}
@@ -129,22 +130,23 @@ _swrast_span_default_texcoords( GLcontext *ctx, SWspan *span )
{
GLuint i;
for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) {
+ const GLuint attr = FRAG_ATTRIB_TEX0 + i;
const GLfloat *tc = ctx->Current.RasterTexCoords[i];
- if (ctx->FragmentProgram._Enabled || ctx->ATIFragmentShader._Enabled) {
- COPY_4V(span->tex[i], tc);
+ if (ctx->FragmentProgram._Current || ctx->ATIFragmentShader._Enabled) {
+ COPY_4V(span->attrStart[attr], tc);
}
else if (tc[3] > 0.0F) {
/* use (s/q, t/q, r/q, 1) */
- span->tex[i][0] = tc[0] / tc[3];
- span->tex[i][1] = tc[1] / tc[3];
- span->tex[i][2] = tc[2] / tc[3];
- span->tex[i][3] = 1.0;
+ span->attrStart[attr][0] = tc[0] / tc[3];
+ span->attrStart[attr][1] = tc[1] / tc[3];
+ span->attrStart[attr][2] = tc[2] / tc[3];
+ span->attrStart[attr][3] = 1.0;
}
else {
- ASSIGN_4V(span->tex[i], 0.0F, 0.0F, 0.0F, 1.0F);
+ ASSIGN_4V(span->attrStart[attr], 0.0F, 0.0F, 0.0F, 1.0F);
}
- ASSIGN_4V(span->texStepX[i], 0.0F, 0.0F, 0.0F, 0.0F);
- ASSIGN_4V(span->texStepY[i], 0.0F, 0.0F, 0.0F, 0.0F);
+ ASSIGN_4V(span->attrStepX[attr], 0.0F, 0.0F, 0.0F, 0.0F);
+ ASSIGN_4V(span->attrStepY[attr], 0.0F, 0.0F, 0.0F, 0.0F);
}
span->interpMask |= SPAN_TEXTURE;
}
@@ -240,7 +242,7 @@ interpolate_colors(SWspan *span)
#endif
case GL_FLOAT:
{
- GLfloat (*rgba)[4] = span->array->color.sz4.rgba;
+ GLfloat (*rgba)[4] = span->array->attribs[FRAG_ATTRIB_COL0];
GLfloat r, g, b, a, dr, dg, db, da;
r = span->red;
g = span->green;
@@ -352,7 +354,7 @@ interpolate_specular(SWspan *span)
#endif
case GL_FLOAT:
{
- GLfloat (*spec)[4] = span->array->color.sz4.spec;
+ GLfloat (*spec)[4] = span->array->attribs[FRAG_ATTRIB_COL1];
#if CHAN_BITS <= 16
GLfloat r = CHAN_TO_FLOAT(FixedToChan(span->specRed));
GLfloat g = CHAN_TO_FLOAT(FixedToChan(span->specGreen));
@@ -431,15 +433,15 @@ interpolate_indexes(GLcontext *ctx, SWspan *span)
static INLINE void
interpolate_fog(const GLcontext *ctx, SWspan *span)
{
- GLfloat *fog = span->array->fog;
- const GLfloat fogStep = span->fogStep;
- GLfloat fogCoord = span->fog;
+ GLfloat (*fog)[4] = span->array->attribs[FRAG_ATTRIB_FOGC];
+ const GLfloat fogStep = span->attrStepX[FRAG_ATTRIB_FOGC][0];
+ GLfloat fogCoord = span->attrStart[FRAG_ATTRIB_FOGC][0];
const GLuint haveW = (span->interpMask & SPAN_W);
- const GLfloat wStep = haveW ? span->dwdx : 0.0F;
- GLfloat w = haveW ? span->w : 1.0F;
+ const GLfloat wStep = haveW ? span->attrStepX[FRAG_ATTRIB_WPOS][3] : 0.0F;
+ GLfloat w = haveW ? span->attrStart[FRAG_ATTRIB_WPOS][3] : 1.0F;
GLuint i;
for (i = 0; i < span->end; i++) {
- fog[i] = fogCoord / w;
+ fog[i][0] = fogCoord / w;
fogCoord += fogStep;
w += wStep;
}
@@ -539,309 +541,188 @@ _swrast_compute_lambda(GLfloat dsdx, GLfloat dsdy, GLfloat dtdx, GLfloat dtdy,
static void
interpolate_texcoords(GLcontext *ctx, SWspan *span)
{
+ const GLuint maxUnit
+ = (ctx->Texture._EnabledCoordUnits > 1) ? ctx->Const.MaxTextureUnits : 1;
+ GLuint u;
+
ASSERT(span->interpMask & SPAN_TEXTURE);
ASSERT(!(span->arrayMask & SPAN_TEXTURE));
- if (ctx->Texture._EnabledCoordUnits > 1) {
- /* multitexture */
- GLuint u;
- span->arrayMask |= SPAN_TEXTURE;
- /* XXX CoordUnits vs. ImageUnits */
- for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
- if (ctx->Texture._EnabledCoordUnits & (1 << u)) {
- const struct gl_texture_object *obj =ctx->Texture.Unit[u]._Current;
- GLfloat texW, texH;
- GLboolean needLambda;
- if (obj) {
- const struct gl_texture_image *img = obj->Image[0][obj->BaseLevel];
- needLambda = (obj->MinFilter != obj->MagFilter)
- || ctx->FragmentProgram._Enabled;
- texW = img->WidthScale;
- texH = img->HeightScale;
- }
- else {
- /* using a fragment program */
- texW = 1.0;
- texH = 1.0;
- needLambda = GL_FALSE;
- }
- if (needLambda) {
- GLfloat (*texcoord)[4] = span->array->texcoords[u];
- GLfloat *lambda = span->array->lambda[u];
- 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 (ctx->FragmentProgram._Enabled || ctx->ATIFragmentShader._Enabled ||
- ctx->ShaderObjects._FragmentShaderPresent) {
- /* do perspective correction but don't divide s, t, r by q */
- const GLfloat dwdx = span->dwdx;
- GLfloat w = span->w;
- for (i = 0; i < span->end; i++) {
- const GLfloat invW = 1.0F / w;
- texcoord[i][0] = s * invW;
- texcoord[i][1] = t * invW;
- texcoord[i][2] = r * invW;
- texcoord[i][3] = q * invW;
- lambda[i] = _swrast_compute_lambda(dsdx, dsdy, dtdx, dtdy,
- dqdx, dqdy, texW, texH,
- s, t, q, invW);
- s += dsdx;
- t += dtdx;
- r += drdx;
- q += dqdx;
- w += dwdx;
- }
+ span->arrayMask |= SPAN_TEXTURE;
+
+ /* XXX CoordUnits vs. ImageUnits */
+ for (u = 0; u < maxUnit; u++) {
+ if (ctx->Texture._EnabledCoordUnits & (1 << u)) {
+ const GLuint attr = FRAG_ATTRIB_TEX0 + u;
+ const struct gl_texture_object *obj = ctx->Texture.Unit[u]._Current;
+ GLfloat texW, texH;
+ GLboolean needLambda;
+ GLfloat (*texcoord)[4] = span->array->attribs[attr];
+ GLfloat *lambda = span->array->lambda[u];
+ const GLfloat dsdx = span->attrStepX[attr][0];
+ const GLfloat dsdy = span->attrStepY[attr][0];
+ const GLfloat dtdx = span->attrStepX[attr][1];
+ const GLfloat dtdy = span->attrStepY[attr][1];
+ const GLfloat drdx = span->attrStepX[attr][2];
+ const GLfloat dqdx = span->attrStepX[attr][3];
+ const GLfloat dqdy = span->attrStepY[attr][3];
+ GLfloat s = span->attrStart[attr][0];
+ GLfloat t = span->attrStart[attr][1];
+ GLfloat r = span->attrStart[attr][2];
+ GLfloat q = span->attrStart[attr][3];
+
+ if (obj) {
+ const struct gl_texture_image *img = obj->Image[0][obj->BaseLevel];
+ needLambda = (obj->MinFilter != obj->MagFilter)
+ || ctx->FragmentProgram._Current;
+ texW = img->WidthScale;
+ texH = img->HeightScale;
+ }
+ else {
+ /* using a fragment program */
+ texW = 1.0;
+ texH = 1.0;
+ needLambda = GL_FALSE;
+ }
+ if (needLambda) {
+ GLuint i;
+ if (ctx->FragmentProgram._Current
+ || ctx->ATIFragmentShader._Enabled) {
+ /* do perspective correction but don't divide s, t, r by q */
+ const GLfloat dwdx = span->attrStepX[FRAG_ATTRIB_WPOS][3];
+ GLfloat w = span->attrStart[FRAG_ATTRIB_WPOS][3];
+ for (i = 0; i < span->end; i++) {
+ const GLfloat invW = 1.0F / w;
+ texcoord[i][0] = s * invW;
+ texcoord[i][1] = t * invW;
+ texcoord[i][2] = r * invW;
+ texcoord[i][3] = q * invW;
+ lambda[i] = _swrast_compute_lambda(dsdx, dsdy, dtdx, dtdy,
+ dqdx, dqdy, texW, texH,
+ s, t, q, invW);
+ s += dsdx;
+ t += dtdx;
+ r += drdx;
+ q += dqdx;
+ w += dwdx;
}
- else {
- for (i = 0; i < span->end; i++) {
- const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q);
- texcoord[i][0] = s * invQ;
- texcoord[i][1] = t * invQ;
- texcoord[i][2] = r * invQ;
- texcoord[i][3] = q;
- lambda[i] = _swrast_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;
}
else {
- GLfloat (*texcoord)[4] = span->array->texcoords[u];
- GLfloat *lambda = span->array->lambda[u];
- 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 (ctx->FragmentProgram._Enabled || ctx->ATIFragmentShader._Enabled ||
- ctx->ShaderObjects._FragmentShaderPresent) {
- /* do perspective correction but don't divide s, t, r by q */
- const GLfloat dwdx = span->dwdx;
- GLfloat w = span->w;
- for (i = 0; i < span->end; i++) {
- const GLfloat invW = 1.0F / w;
- texcoord[i][0] = s * invW;
- texcoord[i][1] = t * invW;
- texcoord[i][2] = r * invW;
- texcoord[i][3] = q * invW;
- lambda[i] = 0.0;
- s += dsdx;
- t += dtdx;
- r += drdx;
- q += dqdx;
- w += dwdx;
- }
- }
- else if (dqdx == 0.0F) {
- /* 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);
- for (i = 0; i < span->end; i++) {
- texcoord[i][0] = s * invQ;
- texcoord[i][1] = t * invQ;
- texcoord[i][2] = r * invQ;
- texcoord[i][3] = q;
- lambda[i] = 0.0;
- s += dsdx;
- t += dtdx;
- r += drdx;
- }
- }
- else {
- for (i = 0; i < span->end; i++) {
- const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q);
- texcoord[i][0] = s * invQ;
- texcoord[i][1] = t * invQ;
- texcoord[i][2] = r * invQ;
- texcoord[i][3] = q;
- lambda[i] = 0.0;
- s += dsdx;
- t += dtdx;
- r += drdx;
- q += dqdx;
- }
+ texcoord[i][0] = s * invQ;
+ texcoord[i][1] = t * invQ;
+ texcoord[i][2] = r * invQ;
+ texcoord[i][3] = q;
+ lambda[i] = _swrast_compute_lambda(dsdx, dsdy, dtdx, dtdy,
+ dqdx, dqdy, texW, texH,
+ s, t, q, invQ);
+ s += dsdx;
+ t += dtdx;
+ r += drdx;
+ q += dqdx;
}
- } /* lambda */
- } /* if */
- } /* for */
- }
- else {
- /* single texture */
- const struct gl_texture_object *obj = ctx->Texture.Unit[0]._Current;
- GLfloat texW, texH;
- GLboolean needLambda;
- if (obj) {
- const struct gl_texture_image *img = obj->Image[0][obj->BaseLevel];
- needLambda = (obj->MinFilter != obj->MagFilter)
- || ctx->FragmentProgram._Enabled;
- texW = (GLfloat) img->WidthScale;
- texH = (GLfloat) img->HeightScale;
- }
- else {
- needLambda = GL_FALSE;
- texW = texH = 1.0;
- }
- span->arrayMask |= SPAN_TEXTURE;
- if (needLambda) {
- /* just texture unit 0, with lambda */
- GLfloat (*texcoord)[4] = span->array->texcoords[0];
- GLfloat *lambda = span->array->lambda[0];
- 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 (ctx->FragmentProgram._Enabled || ctx->ATIFragmentShader._Enabled ||
- ctx->ShaderObjects._FragmentShaderPresent) {
- /* do perspective correction but don't divide s, t, r by q */
- const GLfloat dwdx = span->dwdx;
- GLfloat w = span->w;
- for (i = 0; i < span->end; i++) {
- const GLfloat invW = 1.0F / w;
- texcoord[i][0] = s * invW;
- texcoord[i][1] = t * invW;
- texcoord[i][2] = r * invW;
- texcoord[i][3] = q * invW;
- lambda[i] = _swrast_compute_lambda(dsdx, dsdy, dtdx, dtdy,
- dqdx, dqdy, texW, texH,
- s, t, q, invW);
- s += dsdx;
- t += dtdx;
- r += drdx;
- q += dqdx;
- w += dwdx;
}
+ span->arrayMask |= SPAN_LAMBDA;
}
else {
- /* tex.c */
- for (i = 0; i < span->end; i++) {
- const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q);
- lambda[i] = _swrast_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;
- q += dqdx;
- }
- }
- span->arrayMask |= SPAN_LAMBDA;
- }
- else {
- /* just texture 0, without lambda */
- GLfloat (*texcoord)[4] = span->array->texcoords[0];
- 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 (ctx->FragmentProgram._Enabled || ctx->ATIFragmentShader._Enabled ||
- ctx->ShaderObjects._FragmentShaderPresent) {
- /* do perspective correction but don't divide s, t, r by q */
- const GLfloat dwdx = span->dwdx;
- GLfloat w = span->w;
- for (i = 0; i < span->end; i++) {
- const GLfloat invW = 1.0F / w;
- texcoord[i][0] = s * invW;
- texcoord[i][1] = t * invW;
- texcoord[i][2] = r * invW;
- texcoord[i][3] = q * invW;
- s += dsdx;
- t += dtdx;
- r += drdx;
- q += dqdx;
- w += dwdx;
- }
- }
- else if (dqdx == 0.0F) {
- /* 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++) {
- 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;
+ GLuint i;
+ if (ctx->FragmentProgram._Current ||
+ ctx->ATIFragmentShader._Enabled) {
+ /* do perspective correction but don't divide s, t, r by q */
+ const GLfloat dwdx = span->attrStepX[FRAG_ATTRIB_WPOS][3];
+ GLfloat w = span->attrStart[FRAG_ATTRIB_WPOS][3];
+ for (i = 0; i < span->end; i++) {
+ const GLfloat invW = 1.0F / w;
+ texcoord[i][0] = s * invW;
+ texcoord[i][1] = t * invW;
+ texcoord[i][2] = r * invW;
+ texcoord[i][3] = q * invW;
+ lambda[i] = 0.0;
+ s += dsdx;
+ t += dtdx;
+ r += drdx;
+ q += dqdx;
+ w += dwdx;
+ }
}
- }
- else {
- for (i = 0; i < span->end; i++) {
+ else if (dqdx == 0.0F) {
+ /* Ortho projection or polygon's parallel to window X axis */
const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q);
- 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;
- q += dqdx;
+ for (i = 0; i < span->end; i++) {
+ texcoord[i][0] = s * invQ;
+ texcoord[i][1] = t * invQ;
+ texcoord[i][2] = r * invQ;
+ texcoord[i][3] = q;
+ lambda[i] = 0.0;
+ s += dsdx;
+ t += dtdx;
+ r += drdx;
+ }
}
- }
- }
- }
+ else {
+ for (i = 0; i < span->end; i++) {
+ const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q);
+ texcoord[i][0] = s * invQ;
+ texcoord[i][1] = t * invQ;
+ texcoord[i][2] = r * invQ;
+ texcoord[i][3] = q;
+ lambda[i] = 0.0;
+ s += dsdx;
+ t += dtdx;
+ r += drdx;
+ q += dqdx;
+ }
+ }
+ } /* lambda */
+ } /* if */
+ } /* for */
}
+
/**
- * Fill in the span.varying array from the interpolation values.
+ * Fill in the arrays->attribs[FRAG_ATTRIB_VARx] arrays from the
+ * interpolation values.
+ * XXX since interpolants/arrays are getting uniformed, we might merge
+ * this with interpolate_texcoords(), interpolate_Fog(), etc. someday.
*/
static INLINE void
interpolate_varying(GLcontext *ctx, SWspan *span)
{
- GLuint i, j;
+ GLuint var;
+ const GLbitfield inputsUsed = ctx->FragmentProgram._Current->Base.InputsRead;
ASSERT(span->interpMask & SPAN_VARYING);
ASSERT(!(span->arrayMask & SPAN_VARYING));
span->arrayMask |= SPAN_VARYING;
- for (i = 0; i < MAX_VARYING_VECTORS; i++) {
- for (j = 0; j < VARYINGS_PER_VECTOR; j++) {
- const GLfloat dvdx = span->varStepX[i][j];
- GLfloat v = span->var[i][j];
- const GLfloat dwdx = span->dwdx;
- GLfloat w = span->w;
+ for (var = 0; var < MAX_VARYING; var++) {
+ if (inputsUsed & FRAG_BIT_VAR(var)) {
+ const GLuint attr = FRAG_ATTRIB_VAR0 + var;
+ const GLfloat dwdx = span->attrStepX[FRAG_ATTRIB_WPOS][3];
+ GLfloat w = span->attrStart[FRAG_ATTRIB_WPOS][3];
+ const GLfloat dv0dx = span->attrStepX[attr][0];
+ const GLfloat dv1dx = span->attrStepX[attr][1];
+ const GLfloat dv2dx = span->attrStepX[attr][2];
+ const GLfloat dv3dx = span->attrStepX[attr][3];
+ GLfloat v0 = span->attrStart[attr][0];
+ GLfloat v1 = span->attrStart[attr][1];
+ GLfloat v2 = span->attrStart[attr][2];
+ GLfloat v3 = span->attrStart[attr][3];
GLuint k;
-
for (k = 0; k < span->end; k++) {
GLfloat invW = 1.0f / w;
- span->array->varying[k][i][j] = v * invW;
- v += dvdx;
+ span->array->attribs[attr][k][0] = v0 * invW;
+ span->array->attribs[attr][k][1] = v1 * invW;
+ span->array->attribs[attr][k][2] = v2 * invW;
+ span->array->attribs[attr][k][3] = v3 * invW;
+ v0 += dv0dx;
+ v1 += dv1dx;
+ v2 += dv2dx;
+ v3 += dv3dx;
w += dwdx;
}
}
@@ -850,28 +731,68 @@ interpolate_varying(GLcontext *ctx, SWspan *span)
/**
+ * Fill in the arrays->attribs[FRAG_ATTRIB_WPOS] array.
+ */
+static INLINE void
+interpolate_wpos(GLcontext *ctx, SWspan *span)
+{
+ GLfloat (*wpos)[4] = span->array->attribs[FRAG_ATTRIB_WPOS];
+ GLuint i;
+ if (span->arrayMask & SPAN_XY) {
+ for (i = 0; i < span->end; i++) {
+ wpos[i][0] = (GLfloat) span->array->x[i];
+ wpos[i][1] = (GLfloat) span->array->y[i];
+ }
+ }
+ else {
+ for (i = 0; i < span->end; i++) {
+ wpos[i][0] = (GLfloat) span->x + i;
+ wpos[i][1] = (GLfloat) span->y;
+ }
+ }
+ for (i = 0; i < span->end; i++) {
+ wpos[i][2] = (GLfloat) span->array->z[i] / ctx->DrawBuffer->_DepthMaxF;
+ wpos[i][3] = span->attrStart[FRAG_ATTRIB_WPOS][3]
+ + i * span->attrStepX[FRAG_ATTRIB_WPOS][3];
+ }
+}
+
+
+/**
* Apply the current polygon stipple pattern to a span of pixels.
*/
static INLINE void
-stipple_polygon_span( GLcontext *ctx, SWspan *span )
+stipple_polygon_span(GLcontext *ctx, SWspan *span)
{
- const GLuint highbit = 0x80000000;
- const GLuint stipple = ctx->PolygonStipple[span->y % 32];
GLubyte *mask = span->array->mask;
- GLuint i, m;
ASSERT(ctx->Polygon.StippleFlag);
- ASSERT((span->arrayMask & SPAN_XY) == 0);
- m = highbit >> (GLuint) (span->x % 32);
-
- for (i = 0; i < span->end; i++) {
- if ((m & stipple) == 0) {
- mask[i] = 0;
+ if (span->arrayMask & SPAN_XY) {
+ /* arrays of x/y pixel coords */
+ GLuint i;
+ for (i = 0; i < span->end; i++) {
+ const GLint col = span->array->x[i] % 32;
+ const GLint row = span->array->y[i] % 32;
+ const GLuint stipple = ctx->PolygonStipple[row];
+ if (((1 << col) & stipple) == 0) {
+ mask[i] = 0;
+ }
}
- m = m >> 1;
- if (m == 0) {
- m = highbit;
+ }
+ else {
+ /* horizontal span of pixels */
+ const GLuint highBit = 1 << 31;
+ const GLuint stipple = ctx->PolygonStipple[span->y % 32];
+ GLuint i, m = highBit >> (GLuint) (span->x % 32);
+ for (i = 0; i < span->end; i++) {
+ if ((m & stipple) == 0) {
+ mask[i] = 0;
+ }
+ m = m >> 1;
+ if (m == 0) {
+ m = highBit;
+ }
}
}
span->writeAll = GL_FALSE;
@@ -1224,8 +1145,8 @@ add_specular(GLcontext *ctx, SWspan *span)
break;
case GL_FLOAT:
{
- GLfloat (*rgba)[4] = span->array->color.sz4.rgba;
- GLfloat (*spec)[4] = span->array->color.sz4.spec;
+ GLfloat (*rgba)[4] = span->array->attribs[FRAG_ATTRIB_COL0];
+ GLfloat (*spec)[4] = span->array->attribs[FRAG_ATTRIB_COL1];
GLuint i;
for (i = 0; i < span->end; i++) {
rgba[i][RCOMP] += spec[i][RCOMP];
@@ -1266,7 +1187,7 @@ apply_aa_coverage(SWspan *span)
}
}
else {
- GLfloat (*rgba)[4] = span->array->color.sz4.rgba;
+ GLfloat (*rgba)[4] = span->array->attribs[FRAG_ATTRIB_COL0];
for (i = 0; i < span->end; i++) {
rgba[i][ACOMP] = rgba[i][ACOMP] * coverage[i];
}
@@ -1280,7 +1201,7 @@ apply_aa_coverage(SWspan *span)
static INLINE void
clamp_colors(SWspan *span)
{
- GLfloat (*rgba)[4] = span->array->color.sz4.rgba;
+ GLfloat (*rgba)[4] = span->array->attribs[FRAG_ATTRIB_COL0];
GLuint i;
ASSERT(span->array->ChanType == GL_FLOAT);
for (i = 0; i < span->end; i++) {
@@ -1294,28 +1215,35 @@ clamp_colors(SWspan *span)
/**
* Convert the span's color arrays to the given type.
+ * The only way 'output' can be greater than one is when we have a fragment
+ * program that writes to gl_FragData[1] or higher.
+ * \param output which fragment program color output is being processed
*/
static INLINE void
-convert_color_type(GLcontext *ctx, SWspan *span, GLenum newType)
+convert_color_type(SWspan *span, GLenum newType, GLuint output)
{
GLvoid *src, *dst;
- if (span->array->ChanType == GL_UNSIGNED_BYTE) {
- src = span->array->color.sz1.rgba;
+
+ if (output > 0 || span->array->ChanType == GL_FLOAT) {
+ src = span->array->attribs[FRAG_ATTRIB_COL0 + output];
+ span->array->ChanType = GL_FLOAT;
}
else if (span->array->ChanType == GL_UNSIGNED_BYTE) {
- src = span->array->color.sz2.rgba;
+ src = span->array->color.sz1.rgba;
}
else {
- src = span->array->color.sz4.rgba;
+ ASSERT(span->array->ChanType == GL_UNSIGNED_SHORT);
+ src = span->array->color.sz2.rgba;
}
+
if (newType == GL_UNSIGNED_BYTE) {
dst = span->array->color.sz1.rgba;
}
- else if (newType == GL_UNSIGNED_BYTE) {
+ else if (newType == GL_UNSIGNED_SHORT) {
dst = span->array->color.sz2.rgba;
}
else {
- dst = span->array->color.sz4.rgba;
+ dst = span->array->attribs[FRAG_ATTRIB_COL0];
}
_mesa_convert_colors(span->array->ChanType, src,
@@ -1333,46 +1261,58 @@ convert_color_type(GLcontext *ctx, SWspan *span, GLenum newType)
static INLINE void
shade_texture_span(GLcontext *ctx, SWspan *span)
{
- /* Now we need the rgba array, fill it in if needed */
- if (span->interpMask & SPAN_RGBA)
+ GLbitfield inputsRead;
+
+ /* Determine which fragment attributes are actually needed */
+ if (ctx->FragmentProgram._Current) {
+ inputsRead = ctx->FragmentProgram._Current->Base.InputsRead;
+ }
+ else {
+ /* XXX we could be a bit smarter about this */
+ inputsRead = ~0;
+ }
+
+ if ((inputsRead & FRAG_BIT_COL0) && (span->interpMask & SPAN_RGBA))
interpolate_colors(span);
if (ctx->Texture._EnabledCoordUnits && (span->interpMask & SPAN_TEXTURE))
interpolate_texcoords(ctx, span);
- if (ctx->ShaderObjects._FragmentShaderPresent ||
- ctx->FragmentProgram._Enabled ||
+ if (ctx->FragmentProgram._Current ||
ctx->ATIFragmentShader._Enabled) {
-
/* use float colors if running a fragment program or shader */
const GLenum oldType = span->array->ChanType;
const GLenum newType = GL_FLOAT;
- if (oldType != newType) {
+
+ if ((inputsRead & FRAG_BIT_COL0) && (oldType != newType)) {
GLvoid *src = (oldType == GL_UNSIGNED_BYTE)
? (GLvoid *) span->array->color.sz1.rgba
: (GLvoid *) span->array->color.sz2.rgba;
+ assert(span->arrayMask & SPAN_RGBA);
_mesa_convert_colors(oldType, src,
- newType, span->array->color.sz4.rgba,
+ newType, span->array->attribs[FRAG_ATTRIB_COL0],
span->end, span->array->mask);
- span->array->ChanType = newType;
}
+ span->array->ChanType = newType;
/* fragment programs/shaders may need specular, fog and Z coords */
- if (span->interpMask & SPAN_SPEC)
+ if ((inputsRead & FRAG_BIT_COL1) && (span->interpMask & SPAN_SPEC))
interpolate_specular(span);
- if (span->interpMask & SPAN_FOG)
+ if ((inputsRead & FRAG_BIT_FOGC) && (span->interpMask & SPAN_FOG))
interpolate_fog(ctx, span);
if (span->interpMask & SPAN_Z)
_swrast_span_interpolate_z (ctx, span);
- /* Run fragment program/shader now */
- if (ctx->ShaderObjects._FragmentShaderPresent) {
+ if ((inputsRead >= FRAG_BIT_VAR0) && (span->interpMask & SPAN_VARYING))
interpolate_varying(ctx, span);
- _swrast_exec_arbshader(ctx, span);
- }
- else if (ctx->FragmentProgram._Enabled) {
+
+ if (inputsRead & FRAG_BIT_WPOS)
+ interpolate_wpos(ctx, span);
+
+ /* Run fragment program/shader now */
+ if (ctx->FragmentProgram._Current) {
_swrast_exec_fragment_program(ctx, span);
}
else {
@@ -1403,11 +1343,11 @@ _swrast_write_rgba_span( GLcontext *ctx, SWspan *span)
const GLbitfield origInterpMask = span->interpMask;
const GLbitfield origArrayMask = span->arrayMask;
const GLenum chanType = span->array->ChanType;
- const GLboolean shader
- = ctx->FragmentProgram._Enabled
- || ctx->ShaderObjects._FragmentShaderPresent
- || ctx->ATIFragmentShader._Enabled;
+ const GLboolean shader = (ctx->FragmentProgram._Current
+ || ctx->ATIFragmentShader._Enabled);
const GLboolean shaderOrTexture = shader || ctx->Texture._EnabledUnits;
+ struct gl_framebuffer *fb = ctx->DrawBuffer;
+ GLuint output;
GLboolean deferredTexture;
/*
@@ -1429,20 +1369,16 @@ _swrast_write_rgba_span( GLcontext *ctx, SWspan *span)
deferredTexture = GL_FALSE;
}
else if (shaderOrTexture) {
- if (ctx->FragmentProgram._Enabled) {
- if (ctx->FragmentProgram.Current->Base.OutputsWritten
+ if (ctx->FragmentProgram._Current) {
+ if (ctx->FragmentProgram._Current->Base.OutputsWritten
& (1 << FRAG_RESULT_DEPR)) {
- /* Z comes from fragment program */
+ /* Z comes from fragment program/shader */
deferredTexture = GL_FALSE;
}
else {
deferredTexture = GL_TRUE;
}
}
- else if (ctx->ShaderObjects._FragmentShaderPresent) {
- /* XXX how do we test if Z is written by shader? */
- deferredTexture = GL_FALSE; /* never defer to be safe */
- }
else {
/* ATI frag shader or conventional texturing */
deferredTexture = GL_TRUE;
@@ -1476,10 +1412,10 @@ _swrast_write_rgba_span( GLcontext *ctx, SWspan *span)
GLuint i;
for (i = 0; i < span->end; i++) {
if (span->array->mask[i]) {
- assert(span->array->x[i] >= ctx->DrawBuffer->_Xmin);
- assert(span->array->x[i] < ctx->DrawBuffer->_Xmax);
- assert(span->array->y[i] >= ctx->DrawBuffer->_Ymin);
- assert(span->array->y[i] < ctx->DrawBuffer->_Ymax);
+ assert(span->array->x[i] >= fb->_Xmin);
+ assert(span->array->x[i] < fb->_Xmax);
+ assert(span->array->y[i] >= fb->_Ymin);
+ assert(span->array->y[i] < fb->_Ymax);
}
}
}
@@ -1511,13 +1447,13 @@ _swrast_write_rgba_span( GLcontext *ctx, SWspan *span)
if (span->interpMask & SPAN_Z)
_swrast_span_interpolate_z(ctx, span);
- if (ctx->Stencil.Enabled && ctx->DrawBuffer->Visual.stencilBits > 0) {
+ if (ctx->Stencil.Enabled && fb->Visual.stencilBits > 0) {
/* Combined Z/stencil tests */
if (!_swrast_stencil_and_ztest_span(ctx, span)) {
goto end;
}
}
- else if (ctx->DrawBuffer->Visual.depthBits > 0) {
+ else if (fb->Visual.depthBits > 0) {
/* Just regular depth testing */
ASSERT(ctx->Depth.Test);
ASSERT(span->arrayMask & SPAN_Z);
@@ -1597,64 +1533,67 @@ _swrast_write_rgba_span( GLcontext *ctx, SWspan *span)
/*
* Write to renderbuffers
*/
- {
- struct gl_framebuffer *fb = ctx->DrawBuffer;
- const GLuint output = 0; /* only frag progs can write to other outputs */
- const GLuint numDrawBuffers = fb->_NumColorDrawBuffers[output];
- GLchan rgbaSave[MAX_WIDTH][4];
- GLuint buf;
-
- if (numDrawBuffers > 0) {
- if (fb->_ColorDrawBuffers[output][0]->DataType
- != span->array->ChanType) {
- convert_color_type(ctx, span,
- fb->_ColorDrawBuffers[output][0]->DataType);
- }
- }
-
- if (numDrawBuffers > 1) {
- /* save colors for second, third renderbuffer writes */
- _mesa_memcpy(rgbaSave, span->array->rgba,
- 4 * span->end * sizeof(GLchan));
- }
-
- for (buf = 0; buf < numDrawBuffers; buf++) {
- struct gl_renderbuffer *rb = fb->_ColorDrawBuffers[output][buf];
- ASSERT(rb->_BaseFormat == GL_RGBA || rb->_BaseFormat == GL_RGB);
-
- if (ctx->Color._LogicOpEnabled) {
- _swrast_logicop_rgba_span(ctx, rb, span);
- }
- else if (ctx->Color.BlendEnabled) {
- _swrast_blend_span(ctx, rb, span);
- }
-
- if (colorMask != 0xffffffff) {
- _swrast_mask_rgba_span(ctx, rb, span);
- }
-
- if (span->arrayMask & SPAN_XY) {
- /* array of pixel coords */
- ASSERT(rb->PutValues);
- rb->PutValues(ctx, rb, span->end,
- span->array->x, span->array->y,
- span->array->rgba, span->array->mask);
- }
- else {
- /* horizontal run of pixels */
- ASSERT(rb->PutRow);
- rb->PutRow(ctx, rb, span->end, span->x, span->y, span->array->rgba,
- span->writeAll ? NULL: span->array->mask);
- }
-
- if (buf + 1 < numDrawBuffers) {
- /* restore original span values */
- _mesa_memcpy(span->array->rgba, rgbaSave,
- 4 * span->end * sizeof(GLchan));
- }
- } /* for buf */
-
- }
+ /* Loop over color outputs (GL_ARB_draw_buffers) written by frag prog */
+ for (output = 0; output < swrast->_NumColorOutputs; output++) {
+ if (swrast->_ColorOutputsMask & (1 << output)) {
+ const GLuint numDrawBuffers = fb->_NumColorDrawBuffers[output];
+ GLchan rgbaSave[MAX_WIDTH][4];
+ GLuint buf;
+
+ ASSERT(numDrawBuffers > 0);
+
+ if (fb->_ColorDrawBuffers[output][0]->DataType
+ != span->array->ChanType || output > 0) {
+ convert_color_type(span,
+ fb->_ColorDrawBuffers[output][0]->DataType,
+ output);
+ }
+
+ if (numDrawBuffers > 1) {
+ /* save colors for second, third renderbuffer writes */
+ _mesa_memcpy(rgbaSave, span->array->rgba,
+ 4 * span->end * sizeof(GLchan));
+ }
+
+ /* Loop over renderbuffers (i.e. GL_FRONT_AND_BACK) */
+ for (buf = 0; buf < numDrawBuffers; buf++) {
+ struct gl_renderbuffer *rb = fb->_ColorDrawBuffers[output][buf];
+ ASSERT(rb->_BaseFormat == GL_RGBA || rb->_BaseFormat == GL_RGB);
+
+ if (ctx->Color._LogicOpEnabled) {
+ _swrast_logicop_rgba_span(ctx, rb, span);
+ }
+ else if (ctx->Color.BlendEnabled) {
+ _swrast_blend_span(ctx, rb, span);
+ }
+
+ if (colorMask != 0xffffffff) {
+ _swrast_mask_rgba_span(ctx, rb, span);
+ }
+
+ if (span->arrayMask & SPAN_XY) {
+ /* array of pixel coords */
+ ASSERT(rb->PutValues);
+ rb->PutValues(ctx, rb, span->end,
+ span->array->x, span->array->y,
+ span->array->rgba, span->array->mask);
+ }
+ else {
+ /* horizontal run of pixels */
+ ASSERT(rb->PutRow);
+ rb->PutRow(ctx, rb, span->end, span->x, span->y,
+ span->array->rgba,
+ span->writeAll ? NULL: span->array->mask);
+ }
+
+ if (buf + 1 < numDrawBuffers) {
+ /* restore original span values */
+ _mesa_memcpy(span->array->rgba, rgbaSave,
+ 4 * span->end * sizeof(GLchan));
+ }
+ } /* for buf */
+ } /* if output is written to */
+ } /* for output */
end:
/* restore these values before returning */
@@ -1665,9 +1604,9 @@ end:
/**
- * Read RGBA pixels from frame buffer. Clipping will be done to prevent
+ * Read RGBA pixels from a renderbuffer. Clipping will be done to prevent
* reading ouside the buffer's boundaries.
- * \param type datatype for returned colors
+ * \param dstType datatype for returned colors
* \param rgba the returned colors
*/
void
@@ -1732,7 +1671,7 @@ _swrast_read_rgba_span( GLcontext *ctx, struct gl_renderbuffer *rb,
/**
- * Read CI pixels from frame buffer. Clipping will be done to prevent
+ * Read CI pixels from a renderbuffer. Clipping will be done to prevent
* reading ouside the buffer's boundaries.
*/
void
@@ -1815,8 +1754,7 @@ _swrast_get_values(GLcontext *ctx, struct gl_renderbuffer *rb,
for (i = 0; i < count; i++) {
if (x[i] >= 0 && y[i] >= 0 &&
- x[i] < (GLint) rb->Width &&
- y[i] < (GLint) rb->Height) {
+ x[i] < (GLint) rb->Width && y[i] < (GLint) rb->Height) {
/* inside */
if (inCount == 0)
inStart = i;
@@ -1850,13 +1788,13 @@ _swrast_put_row(GLcontext *ctx, struct gl_renderbuffer *rb,
{
GLint skip = 0;
- if (y < 0 || (GLint) y >= rb->Height)
+ if (y < 0 || y >= (GLint) rb->Height)
return; /* above or below */
if (x + (GLint) count <= 0 || x >= (GLint) rb->Width)
return; /* entirely left or right */
- if (x + count > rb->Width) {
+ if ((GLint) (x + count) > (GLint) rb->Width) {
/* right clip */
GLint clip = x + count - rb->Width;
count -= clip;
@@ -1885,10 +1823,10 @@ _swrast_get_row(GLcontext *ctx, struct gl_renderbuffer *rb,
{
GLint skip = 0;
- if (y < 0 || y >= rb->Height)
+ if (y < 0 || y >= (GLint) rb->Height)
return; /* above or below */
- if (x + (GLint) count <= 0 || x >= rb->Width)
+ if (x + (GLint) count <= 0 || x >= (GLint) rb->Width)
return; /* entirely left or right */
if (x + count > rb->Width) {
@@ -1933,7 +1871,7 @@ _swrast_get_dest_rgba(GLcontext *ctx, struct gl_renderbuffer *rb,
rbPixels = span->array->color.sz2.spec;
}
else {
- rbPixels = span->array->color.sz4.spec;
+ rbPixels = span->array->attribs[FRAG_ATTRIB_COL1];
}
/* Get destination values from renderbuffer */
diff --git a/src/mesa/swrast/s_span.h b/src/mesa/swrast/s_span.h
index c441106abae..8a9b9eb21c7 100644
--- a/src/mesa/swrast/s_span.h
+++ b/src/mesa/swrast/s_span.h
@@ -31,6 +31,185 @@
#include "swrast.h"
+/**
+ * \defgroup SpanFlags
+ * Bitflags used for interpMask and arrayMask fields below to indicate
+ * which interpolant values and fragment arrays are in use, respectively.
+ *
+ * XXX We should replace these flags with the FRAG_BIT_ values someday...
+ */
+/*@{*/
+#define SPAN_RGBA 0x001
+#define SPAN_SPEC 0x002
+#define SPAN_INDEX 0x004
+#define SPAN_Z 0x008
+#define SPAN_W 0x010
+#define SPAN_FOG 0x020
+#define SPAN_TEXTURE 0x040
+#define SPAN_INT_TEXTURE 0x080
+#define SPAN_LAMBDA 0x100
+#define SPAN_COVERAGE 0x200
+#define SPAN_FLAT 0x400 /**< flat shading? */
+#define SPAN_XY 0x800
+#define SPAN_MASK 0x1000
+#define SPAN_VARYING 0x2000
+/*@}*/
+
+
+#if 0
+/* alternate arrangement for code below */
+struct arrays2 {
+ union {
+ GLubyte sz1[MAX_WIDTH][4]; /* primary color */
+ GLushort sz2[MAX_WIDTH][4];
+ } rgba;
+ union {
+ GLubyte sz1[MAX_WIDTH][4]; /* specular color and temp storage */
+ GLushort sz2[MAX_WIDTH][4];
+ } spec;
+};
+#endif
+
+
+
+/**
+ * \sw_span_arrays
+ * \brief Arrays of fragment values.
+ *
+ * These will either be computed from the span x/xStep values or
+ * filled in by glDraw/CopyPixels, etc.
+ * These arrays are separated out of sw_span to conserve memory.
+ */
+typedef struct sw_span_arrays
+{
+ /** Per-fragment attributes (indexed by FRAG_ATTRIB_* tokens) */
+ /* XXX someday look at transposing first two indexes for better memory
+ * access pattern.
+ */
+ GLfloat attribs[FRAG_ATTRIB_MAX][MAX_WIDTH][4];
+
+ /** This mask indicates which fragments are alive or culled */
+ GLubyte mask[MAX_WIDTH];
+
+ GLenum ChanType; /**< Color channel type, GL_UNSIGNED_BYTE, GL_FLOAT */
+ union {
+ struct {
+ GLubyte rgba[MAX_WIDTH][4]; /**< primary color */
+ GLubyte spec[MAX_WIDTH][4]; /**< specular color and temp storage */
+ } sz1;
+ struct {
+ GLushort rgba[MAX_WIDTH][4];
+ GLushort spec[MAX_WIDTH][4];
+ } sz2;
+ } color;
+ /** XXX these are temporary fields, pointing into above color arrays */
+ GLchan (*rgba)[4];
+ GLchan (*spec)[4];
+
+ GLint x[MAX_WIDTH]; /**< fragment X coords */
+ GLint y[MAX_WIDTH]; /**< fragment Y coords */
+ GLuint z[MAX_WIDTH]; /**< fragment Z coords */
+ GLuint index[MAX_WIDTH]; /**< Color indexes */
+ GLfloat lambda[MAX_TEXTURE_COORD_UNITS][MAX_WIDTH]; /**< Texture LOD */
+ GLfloat coverage[MAX_WIDTH]; /**< Fragment coverage for AA/smoothing */
+} SWspanarrays;
+
+
+/**
+ * The SWspan structure describes the colors, Z, fogcoord, texcoords,
+ * etc for either a horizontal run or an array of independent pixels.
+ * We can either specify a base/step to indicate interpolated values, or
+ * fill in explicit arrays of values. The interpMask and arrayMask bitfields
+ * indicate which attributes are active interpolants or arrays, respectively.
+ *
+ * It would be interesting to experiment with multiprocessor rasterization
+ * with this structure. The triangle rasterizer could simply emit a
+ * stream of these structures which would be consumed by one or more
+ * span-processing threads which could run in parallel.
+ */
+typedef struct sw_span
+{
+ /** Coord of first fragment in horizontal span/run */
+ GLint x, y;
+
+ /** Number of fragments in the span */
+ GLuint end;
+
+ /** This flag indicates that mask[] array is effectively filled with ones */
+ GLboolean writeAll;
+
+ /** either GL_POLYGON, GL_LINE, GL_POLYGON, GL_BITMAP */
+ GLenum primitive;
+
+ /** 0 = front-facing span, 1 = back-facing span (for two-sided stencil) */
+ GLuint facing;
+
+ /**
+ * This bitmask (of \link SpanFlags SPAN_* flags\endlink) indicates
+ * which of the attrStart/StepX/StepY variables are relevant.
+ */
+ GLbitfield interpMask;
+
+ /** Fragment attribute interpolants */
+ GLfloat attrStart[FRAG_ATTRIB_MAX][4]; /**< initial value */
+ GLfloat attrStepX[FRAG_ATTRIB_MAX][4]; /**< dvalue/dx */
+ GLfloat attrStepY[FRAG_ATTRIB_MAX][4]; /**< dvalue/dy */
+
+ /* XXX the rest of these will go away eventually... */
+
+ /* For horizontal spans, step is the partial derivative wrt X.
+ * For lines, step is the delta from one fragment to the next.
+ */
+#if CHAN_TYPE == GL_FLOAT
+ GLfloat red, redStep;
+ GLfloat green, greenStep;
+ GLfloat blue, blueStep;
+ GLfloat alpha, alphaStep;
+ GLfloat specRed, specRedStep;
+ GLfloat specGreen, specGreenStep;
+ GLfloat specBlue, specBlueStep;
+#else /* CHAN_TYPE == GL_UNSIGNED_BYTE or GL_UNSIGNED_SHORT */
+ GLfixed red, redStep;
+ GLfixed green, greenStep;
+ GLfixed blue, blueStep;
+ GLfixed alpha, alphaStep;
+ GLfixed specRed, specRedStep;
+ GLfixed specGreen, specGreenStep;
+ GLfixed specBlue, specBlueStep;
+#endif
+ GLfixed index, indexStep;
+ GLfixed z, zStep; /* XXX z should probably be GLuint */
+ GLfixed intTex[2], intTexStep[2]; /* s, t only */
+
+ /**
+ * This bitmask (of \link SpanFlags SPAN_* flags\endlink) indicates
+ * which of the fragment arrays in the span_arrays struct are relevant.
+ */
+ GLbitfield arrayMask;
+
+ /**
+ * We store the arrays of fragment values in a separate struct so
+ * that we can allocate sw_span structs on the stack without using
+ * a lot of memory. The span_arrays struct is about 1.4MB while the
+ * sw_span struct is only about 512 bytes.
+ */
+ SWspanarrays *array;
+} SWspan;
+
+
+
+#define INIT_SPAN(S, PRIMITIVE, END, INTERP_MASK, ARRAY_MASK) \
+do { \
+ (S).primitive = (PRIMITIVE); \
+ (S).interpMask = (INTERP_MASK); \
+ (S).arrayMask = (ARRAY_MASK); \
+ (S).end = (END); \
+ (S).facing = 0; \
+ (S).array = SWRAST_CONTEXT(ctx)->SpanArrays; \
+} while (0)
+
+
+
extern void
_swrast_span_default_z( GLcontext *ctx, SWspan *span );
diff --git a/src/mesa/swrast/s_texcombine.c b/src/mesa/swrast/s_texcombine.c
index 2a3455f35e2..ebb4c0d936d 100644
--- a/src/mesa/swrast/s_texcombine.c
+++ b/src/mesa/swrast/s_texcombine.c
@@ -1094,6 +1094,9 @@ _swrast_texture_span( GLcontext *ctx, SWspan *span )
*/
for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) {
if (ctx->Texture.Unit[unit]._ReallyEnabled) {
+ const GLfloat (*texcoords)[4]
+ = (const GLfloat (*)[4])
+ span->array->attribs[FRAG_ATTRIB_TEX0 + unit];
const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
const struct gl_texture_object *curObj = texUnit->_Current;
GLfloat *lambda = span->array->lambda[unit];
@@ -1127,8 +1130,7 @@ _swrast_texture_span( GLcontext *ctx, SWspan *span )
/* Sample the texture (span->end = number of fragments) */
swrast->TextureSample[unit]( ctx, texUnit->_Current, span->end,
- (const GLfloat (*)[4]) span->array->texcoords[unit],
- lambda, texels );
+ texcoords, lambda, texels );
/* GL_SGI_texture_color_table */
if (texUnit->ColorTableEnabled) {
diff --git a/src/mesa/swrast/s_triangle.c b/src/mesa/swrast/s_triangle.c
index b17c4354605..3b7960bf80f 100644
--- a/src/mesa/swrast/s_triangle.c
+++ b/src/mesa/swrast/s_triangle.c
@@ -1,8 +1,8 @@
/*
* Mesa 3-D graphics library
- * Version: 6.5.2
+ * Version: 6.5.3
*
- * Copyright (C) 1999-2006 Brian Paul All Rights Reserved.
+ * Copyright (C) 1999-2007 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"),
@@ -676,13 +676,13 @@ fast_persp_span(GLcontext *ctx, SWspan *span,
const GLuint savedTexEnable = ctx->Texture._EnabledUnits;
ctx->Texture._EnabledUnits = 0;
- 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->texStepX[0][3];
+ tex_coord[0] = span->attrStart[FRAG_ATTRIB_TEX0][0] * (info->smask + 1);
+ tex_step[0] = span->attrStepX[FRAG_ATTRIB_TEX0][0] * (info->smask + 1);
+ tex_coord[1] = span->attrStart[FRAG_ATTRIB_TEX0][1] * (info->tmask + 1);
+ tex_step[1] = span->attrStepX[FRAG_ATTRIB_TEX0][1] * (info->tmask + 1);
+ /* span->attrStart[FRAG_ATTRIB_TEX0][2] only if 3D-texturing, here only 2D */
+ tex_coord[2] = span->attrStart[FRAG_ATTRIB_TEX0][3];
+ tex_step[2] = span->attrStepX[FRAG_ATTRIB_TEX0][3];
switch (info->filter) {
case GL_NEAREST:
@@ -866,7 +866,6 @@ fast_persp_span(GLcontext *ctx, SWspan *span,
/*
* Render a smooth-shaded, textured, RGBA triangle.
- * Interpolate S,T,R with perspective correction, w/out mipmapping.
*/
#define NAME general_textured_triangle
#define INTERP_Z 1
@@ -881,24 +880,6 @@ fast_persp_span(GLcontext *ctx, SWspan *span,
-/*
- * This is the big one!
- * Interpolate Z, RGB, Alpha, specular, fog, N sets of texture coordinates, and varying floats.
- * Yup, it's slow.
- */
-#define NAME multitextured_triangle
-#define INTERP_Z 1
-#define INTERP_W 1
-#define INTERP_FOG 1
-#define INTERP_RGB 1
-#define INTERP_ALPHA 1
-#define INTERP_SPEC 1
-#define INTERP_MULTITEX 1
-#define INTERP_VARYING 1
-#define RENDER_SPAN( span ) _swrast_write_rgba_span(ctx, &span);
-#include "s_tritemp.h"
-
-
/*
* Special tri function for occlusion testing
@@ -1073,8 +1054,9 @@ _swrast_choose_triangle( GLcontext *ctx )
}
}
- if (ctx->Texture._EnabledCoordUnits || ctx->FragmentProgram._Enabled ||
- ctx->ATIFragmentShader._Enabled || ctx->ShaderObjects._FragmentShaderPresent) {
+ if (ctx->Texture._EnabledCoordUnits ||
+ ctx->FragmentProgram._Current ||
+ ctx->ATIFragmentShader._Enabled) {
/* Ugh, we do a _lot_ of tests to pick the best textured tri func */
const struct gl_texture_object *texObj2D;
const struct gl_texture_image *texImg;
@@ -1089,9 +1071,8 @@ _swrast_choose_triangle( GLcontext *ctx )
/* First see if we can use an optimized 2-D texture function */
if (ctx->Texture._EnabledCoordUnits == 0x1
- && !ctx->FragmentProgram._Enabled
+ && !ctx->FragmentProgram._Current
&& !ctx->ATIFragmentShader._Enabled
- && !ctx->ShaderObjects._FragmentShaderPresent
&& ctx->Texture.Unit[0]._ReallyEnabled == TEXTURE_2D_BIT
&& texObj2D->WrapS == GL_REPEAT
&& texObj2D->WrapT == GL_REPEAT
@@ -1137,12 +1118,7 @@ _swrast_choose_triangle( GLcontext *ctx )
}
else {
/* general case textured triangles */
- if (ctx->Texture._EnabledCoordUnits > 1) {
- USE(multitextured_triangle);
- }
- else {
- USE(general_textured_triangle);
- }
+ USE(general_textured_triangle);
}
}
else {
diff --git a/src/mesa/swrast/s_tritemp.h b/src/mesa/swrast/s_tritemp.h
index 9e0a8a3d32a..435491a0c80 100644
--- a/src/mesa/swrast/s_tritemp.h
+++ b/src/mesa/swrast/s_tritemp.h
@@ -1,8 +1,8 @@
/*
* Mesa 3-D graphics library
- * Version: 6.5
+ * Version: 6.5.3
*
- * Copyright (C) 1999-2006 Brian Paul All Rights Reserved.
+ * Copyright (C) 1999-2007 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"),
@@ -38,10 +38,8 @@
* INTERP_INDEX - if defined, interpolate color index values
* INTERP_INT_TEX - if defined, interpolate integer ST texcoords
* (fast, simple 2-D texture mapping)
- * INTERP_TEX - if defined, interpolate set 0 float STRQ texcoords
+ * INTERP_TEX - if defined, interpolate texcoords and varying vars
* NOTE: OpenGL STRQ = Mesa STUV (R was taken for red)
- * INTERP_MULTITEX - if defined, interpolate N units of STRQ texcoords
- * INTERP_VARYING - if defined, interpolate M floats of GLSL varyings
*
* When one can directly address pixels in the color buffer the following
* macros can be defined and used to compute pixel addresses during
@@ -119,43 +117,19 @@
#endif
-/*
- * Either loop over all texture units, or just use unit zero.
- */
-#ifdef INTERP_MULTITEX
-#define TEX_UNIT_LOOP(CODE) \
- { \
- GLuint u; \
- for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { \
- if (ctx->Texture._EnabledCoordUnits & (1 << u)) { \
- CODE \
- } \
- } \
+#define TEXVAR_LOOP(CODE) \
+ { \
+ GLuint attr; \
+ for (attr = swrast->_MinFragmentAttrib; \
+ attr < swrast->_MaxFragmentAttrib; attr++) { \
+ if (swrast->_FragmentAttribs & (1 << attr)) { \
+ CODE \
+ } \
+ } \
}
-#define INTERP_TEX
-#elif defined(INTERP_TEX)
-#define TEX_UNIT_LOOP(CODE) \
- { \
- const GLuint u = 0; \
- CODE \
- }
-#endif
-#ifdef INTERP_VARYING
-#define VARYING_LOOP(CODE)\
- {\
- GLuint iv, ic;\
- for (iv = 0; iv < MAX_VARYING_VECTORS; iv++) {\
- for (ic = 0; ic < VARYINGS_PER_VECTOR; ic++) {\
- CODE\
- }\
- }\
- }
-#endif
-
-
/*
* Some code we unfortunately need to prevent negative interpolated colors.
@@ -201,6 +175,7 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
GLint lines; /* number of lines to be sampled on this edge */
} EdgeT;
+ const SWcontext *swrast = SWRAST_CONTEXT(ctx);
#ifdef INTERP_Z
const GLint depthBits = ctx->DrawBuffer->Visual.depthBits;
const GLint fixedToDepthShift = depthBits <= 16 ? FIXED_SHIFT : 0;
@@ -218,6 +193,8 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
SWspan span;
+ (void) swrast;
+
INIT_SPAN(span, GL_POLYGON, 0, 0, 0);
#ifdef INTERP_Z
@@ -465,19 +442,19 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
{
GLfloat eMaj_dz = vMax->win[2] - vMin->win[2];
GLfloat eBot_dz = vMid->win[2] - vMin->win[2];
- span.dzdx = oneOverArea * (eMaj_dz * eBot.dy - eMaj.dy * eBot_dz);
- if (span.dzdx > maxDepth || span.dzdx < -maxDepth) {
+ span.attrStepX[FRAG_ATTRIB_WPOS][2] = oneOverArea * (eMaj_dz * eBot.dy - eMaj.dy * eBot_dz);
+ if (span.attrStepX[FRAG_ATTRIB_WPOS][2] > maxDepth || span.attrStepX[FRAG_ATTRIB_WPOS][2] < -maxDepth) {
/* probably a sliver triangle */
- span.dzdx = 0.0;
- span.dzdy = 0.0;
+ span.attrStepX[FRAG_ATTRIB_WPOS][2] = 0.0;
+ span.attrStepY[FRAG_ATTRIB_WPOS][2] = 0.0;
}
else {
- span.dzdy = oneOverArea * (eMaj.dx * eBot_dz - eMaj_dz * eBot.dx);
+ span.attrStepY[FRAG_ATTRIB_WPOS][2] = oneOverArea * (eMaj.dx * eBot_dz - eMaj_dz * eBot.dx);
}
if (depthBits <= 16)
- span.zStep = SignedFloatToFixed(span.dzdx);
+ span.zStep = SignedFloatToFixed(span.attrStepX[FRAG_ATTRIB_WPOS][2]);
else
- span.zStep = (GLint) span.dzdx;
+ span.zStep = (GLint) span.attrStepX[FRAG_ATTRIB_WPOS][2];
}
#endif
#ifdef INTERP_W
@@ -485,8 +462,8 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
{
const GLfloat eMaj_dw = vMax->win[3] - vMin->win[3];
const GLfloat eBot_dw = vMid->win[3] - vMin->win[3];
- span.dwdx = oneOverArea * (eMaj_dw * eBot.dy - eMaj.dy * eBot_dw);
- span.dwdy = oneOverArea * (eMaj.dx * eBot_dw - eMaj_dw * eBot.dx);
+ span.attrStepX[FRAG_ATTRIB_WPOS][3] = oneOverArea * (eMaj_dw * eBot.dy - eMaj.dy * eBot_dw);
+ span.attrStepY[FRAG_ATTRIB_WPOS][3] = oneOverArea * (eMaj.dx * eBot_dw - eMaj_dw * eBot.dx);
}
#endif
#ifdef INTERP_FOG
@@ -500,9 +477,8 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
const GLfloat eMaj_dfog = vMax->fog - vMin->fog;
const GLfloat eBot_dfog = vMid->fog - vMin->fog;
# endif
- span.dfogdx = oneOverArea * (eMaj_dfog * eBot.dy - eMaj.dy * eBot_dfog);
- span.dfogdy = oneOverArea * (eMaj.dx * eBot_dfog - eMaj_dfog * eBot.dx);
- span.fogStep = span.dfogdx;
+ span.attrStepX[FRAG_ATTRIB_FOGC][0] = oneOverArea * (eMaj_dfog * eBot.dy - eMaj.dy * eBot_dfog);
+ span.attrStepY[FRAG_ATTRIB_FOGC][0] = oneOverArea * (eMaj.dx * eBot_dfog - eMaj_dfog * eBot.dx);
}
#endif
#ifdef INTERP_RGB
@@ -518,37 +494,37 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
GLfloat eMaj_da = (GLfloat) ((ColorTemp) vMax->color[ACOMP] - (ColorTemp) vMin->color[ACOMP]);
GLfloat eBot_da = (GLfloat) ((ColorTemp) vMid->color[ACOMP] - (ColorTemp) vMin->color[ACOMP]);
# endif
- span.drdx = oneOverArea * (eMaj_dr * eBot.dy - eMaj.dy * eBot_dr);
- span.drdy = oneOverArea * (eMaj.dx * eBot_dr - eMaj_dr * eBot.dx);
- span.dgdx = oneOverArea * (eMaj_dg * eBot.dy - eMaj.dy * eBot_dg);
- span.dgdy = oneOverArea * (eMaj.dx * eBot_dg - eMaj_dg * eBot.dx);
- span.dbdx = oneOverArea * (eMaj_db * eBot.dy - eMaj.dy * eBot_db);
- span.dbdy = oneOverArea * (eMaj.dx * eBot_db - eMaj_db * eBot.dx);
+ span.attrStepX[FRAG_ATTRIB_COL0][0] = oneOverArea * (eMaj_dr * eBot.dy - eMaj.dy * eBot_dr);
+ span.attrStepY[FRAG_ATTRIB_COL0][0] = oneOverArea * (eMaj.dx * eBot_dr - eMaj_dr * eBot.dx);
+ span.attrStepX[FRAG_ATTRIB_COL0][1] = oneOverArea * (eMaj_dg * eBot.dy - eMaj.dy * eBot_dg);
+ span.attrStepY[FRAG_ATTRIB_COL0][1] = oneOverArea * (eMaj.dx * eBot_dg - eMaj_dg * eBot.dx);
+ span.attrStepX[FRAG_ATTRIB_COL0][2] = oneOverArea * (eMaj_db * eBot.dy - eMaj.dy * eBot_db);
+ span.attrStepY[FRAG_ATTRIB_COL0][2] = oneOverArea * (eMaj.dx * eBot_db - eMaj_db * eBot.dx);
# if CHAN_TYPE == GL_FLOAT
- span.redStep = span.drdx;
- span.greenStep = span.dgdx;
- span.blueStep = span.dbdx;
+ span.redStep = span.attrStepX[FRAG_ATTRIB_COL0][0];
+ span.greenStep = span.attrStepX[FRAG_ATTRIB_COL0][1];
+ span.blueStep = span.attrStepX[FRAG_ATTRIB_COL0][2];
# else
- span.redStep = SignedFloatToFixed(span.drdx);
- span.greenStep = SignedFloatToFixed(span.dgdx);
- span.blueStep = SignedFloatToFixed(span.dbdx);
+ span.redStep = SignedFloatToFixed(span.attrStepX[FRAG_ATTRIB_COL0][0]);
+ span.greenStep = SignedFloatToFixed(span.attrStepX[FRAG_ATTRIB_COL0][1]);
+ span.blueStep = SignedFloatToFixed(span.attrStepX[FRAG_ATTRIB_COL0][2]);
# endif /* GL_FLOAT */
# ifdef INTERP_ALPHA
- span.dadx = oneOverArea * (eMaj_da * eBot.dy - eMaj.dy * eBot_da);
- span.dady = oneOverArea * (eMaj.dx * eBot_da - eMaj_da * eBot.dx);
+ span.attrStepX[FRAG_ATTRIB_COL0][3] = oneOverArea * (eMaj_da * eBot.dy - eMaj.dy * eBot_da);
+ span.attrStepX[FRAG_ATTRIB_COL0][3] = oneOverArea * (eMaj.dx * eBot_da - eMaj_da * eBot.dx);
# if CHAN_TYPE == GL_FLOAT
- span.alphaStep = span.dadx;
+ span.alphaStep = span.attrStepX[FRAG_ATTRIB_COL0][3];
# else
- span.alphaStep = SignedFloatToFixed(span.dadx);
+ span.alphaStep = SignedFloatToFixed(span.attrStepX[FRAG_ATTRIB_COL0][3]);
# endif /* GL_FLOAT */
# endif /* INTERP_ALPHA */
}
else {
ASSERT(ctx->Light.ShadeModel == GL_FLAT);
span.interpMask |= SPAN_FLAT;
- span.drdx = span.drdy = 0.0F;
- span.dgdx = span.dgdy = 0.0F;
- span.dbdx = span.dbdy = 0.0F;
+ span.attrStepX[FRAG_ATTRIB_COL0][0] = span.attrStepY[FRAG_ATTRIB_COL0][0] = 0.0F;
+ span.attrStepX[FRAG_ATTRIB_COL0][1] = span.attrStepY[FRAG_ATTRIB_COL0][1] = 0.0F;
+ span.attrStepX[FRAG_ATTRIB_COL0][2] = span.attrStepY[FRAG_ATTRIB_COL0][2] = 0.0F;
# if CHAN_TYPE == GL_FLOAT
span.redStep = 0.0F;
span.greenStep = 0.0F;
@@ -559,7 +535,7 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
span.blueStep = 0;
# endif /* GL_FLOAT */
# ifdef INTERP_ALPHA
- span.dadx = span.dady = 0.0F;
+ span.attrStepX[FRAG_ATTRIB_COL0][3] = span.attrStepX[FRAG_ATTRIB_COL0][3] = 0.0F;
# if CHAN_TYPE == GL_FLOAT
span.alphaStep = 0.0F;
# else
@@ -577,26 +553,26 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
GLfloat eBot_dsg = (GLfloat) ((ColorTemp) vMid->specular[GCOMP] - (ColorTemp) vMin->specular[GCOMP]);
GLfloat eMaj_dsb = (GLfloat) ((ColorTemp) vMax->specular[BCOMP] - (ColorTemp) vMin->specular[BCOMP]);
GLfloat eBot_dsb = (GLfloat) ((ColorTemp) vMid->specular[BCOMP] - (ColorTemp) vMin->specular[BCOMP]);
- span.dsrdx = oneOverArea * (eMaj_dsr * eBot.dy - eMaj.dy * eBot_dsr);
- span.dsrdy = oneOverArea * (eMaj.dx * eBot_dsr - eMaj_dsr * eBot.dx);
- span.dsgdx = oneOverArea * (eMaj_dsg * eBot.dy - eMaj.dy * eBot_dsg);
- span.dsgdy = oneOverArea * (eMaj.dx * eBot_dsg - eMaj_dsg * eBot.dx);
- span.dsbdx = oneOverArea * (eMaj_dsb * eBot.dy - eMaj.dy * eBot_dsb);
- span.dsbdy = oneOverArea * (eMaj.dx * eBot_dsb - eMaj_dsb * eBot.dx);
+ span.attrStepX[FRAG_ATTRIB_COL1][0] = oneOverArea * (eMaj_dsr * eBot.dy - eMaj.dy * eBot_dsr);
+ span.attrStepY[FRAG_ATTRIB_COL1][0] = oneOverArea * (eMaj.dx * eBot_dsr - eMaj_dsr * eBot.dx);
+ span.attrStepX[FRAG_ATTRIB_COL1][1] = oneOverArea * (eMaj_dsg * eBot.dy - eMaj.dy * eBot_dsg);
+ span.attrStepY[FRAG_ATTRIB_COL1][1] = oneOverArea * (eMaj.dx * eBot_dsg - eMaj_dsg * eBot.dx);
+ span.attrStepX[FRAG_ATTRIB_COL1][2] = oneOverArea * (eMaj_dsb * eBot.dy - eMaj.dy * eBot_dsb);
+ span.attrStepY[FRAG_ATTRIB_COL1][2] = oneOverArea * (eMaj.dx * eBot_dsb - eMaj_dsb * eBot.dx);
# if CHAN_TYPE == GL_FLOAT
- span.specRedStep = span.dsrdx;
+ span.specRedStep = span.attrStep[FRAG_ATTRIB_COL1][0];
span.specGreenStep = span.dsgdx;
span.specBlueStep = span.dsbdx;
# else
- span.specRedStep = SignedFloatToFixed(span.dsrdx);
- span.specGreenStep = SignedFloatToFixed(span.dsgdx);
- span.specBlueStep = SignedFloatToFixed(span.dsbdx);
+ span.specRedStep = SignedFloatToFixed(span.attrStepX[FRAG_ATTRIB_COL1][0]);
+ span.specGreenStep = SignedFloatToFixed(span.attrStepX[FRAG_ATTRIB_COL1][1]);
+ span.specBlueStep = SignedFloatToFixed(span.attrStepX[FRAG_ATTRIB_COL1][2]);
# endif
}
else {
- span.dsrdx = span.dsrdy = 0.0F;
- span.dsgdx = span.dsgdy = 0.0F;
- span.dsbdx = span.dsbdy = 0.0F;
+ span.attrStepX[FRAG_ATTRIB_COL1][0] = span.attrStepY[FRAG_ATTRIB_COL1][0] = 0.0F;
+ span.attrStepX[FRAG_ATTRIB_COL1][1] = span.attrStepY[FRAG_ATTRIB_COL1][1] = 0.0F;
+ span.attrStepX[FRAG_ATTRIB_COL1][2] = span.attrStepY[FRAG_ATTRIB_COL1][2] = 0.0F;
# if CHAN_TYPE == GL_FLOAT
span.specRedStep = 0.0F;
span.specGreenStep = 0.0F;
@@ -626,53 +602,40 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
#ifdef INTERP_INT_TEX
span.interpMask |= SPAN_INT_TEXTURE;
{
- GLfloat eMaj_ds = (vMax->texcoord[0][0] - vMin->texcoord[0][0]) * S_SCALE;
- GLfloat eBot_ds = (vMid->texcoord[0][0] - vMin->texcoord[0][0]) * S_SCALE;
- GLfloat eMaj_dt = (vMax->texcoord[0][1] - vMin->texcoord[0][1]) * T_SCALE;
- GLfloat eBot_dt = (vMid->texcoord[0][1] - vMin->texcoord[0][1]) * T_SCALE;
- span.texStepX[0][0] = oneOverArea * (eMaj_ds * eBot.dy - eMaj.dy * eBot_ds);
- span.texStepY[0][0] = oneOverArea * (eMaj.dx * eBot_ds - eMaj_ds * eBot.dx);
- span.texStepX[0][1] = oneOverArea * (eMaj_dt * eBot.dy - eMaj.dy * eBot_dt);
- span.texStepY[0][1] = oneOverArea * (eMaj.dx * eBot_dt - eMaj_dt * eBot.dx);
- span.intTexStep[0] = SignedFloatToFixed(span.texStepX[0][0]);
- span.intTexStep[1] = SignedFloatToFixed(span.texStepX[0][1]);
+ GLfloat eMaj_ds = (vMax->attrib[FRAG_ATTRIB_TEX0][0] - vMin->attrib[FRAG_ATTRIB_TEX0][0]) * S_SCALE;
+ GLfloat eBot_ds = (vMid->attrib[FRAG_ATTRIB_TEX0][0] - vMin->attrib[FRAG_ATTRIB_TEX0][0]) * S_SCALE;
+ GLfloat eMaj_dt = (vMax->attrib[FRAG_ATTRIB_TEX0][1] - vMin->attrib[FRAG_ATTRIB_TEX0][1]) * T_SCALE;
+ GLfloat eBot_dt = (vMid->attrib[FRAG_ATTRIB_TEX0][1] - vMin->attrib[FRAG_ATTRIB_TEX0][1]) * T_SCALE;
+ span.attrStepX[FRAG_ATTRIB_TEX0][0] = oneOverArea * (eMaj_ds * eBot.dy - eMaj.dy * eBot_ds);
+ span.attrStepY[FRAG_ATTRIB_TEX0][0] = oneOverArea * (eMaj.dx * eBot_ds - eMaj_ds * eBot.dx);
+ span.attrStepX[FRAG_ATTRIB_TEX0][1] = oneOverArea * (eMaj_dt * eBot.dy - eMaj.dy * eBot_dt);
+ span.attrStepY[FRAG_ATTRIB_TEX0][1] = oneOverArea * (eMaj.dx * eBot_dt - eMaj_dt * eBot.dx);
+ span.intTexStep[0] = SignedFloatToFixed(span.attrStepX[FRAG_ATTRIB_TEX0][0]);
+ span.intTexStep[1] = SignedFloatToFixed(span.attrStepX[FRAG_ATTRIB_TEX0][1]);
}
#endif
#ifdef INTERP_TEX
- span.interpMask |= SPAN_TEXTURE;
+ span.interpMask |= (SPAN_TEXTURE | SPAN_VARYING);
{
/* win[3] is 1/W */
const GLfloat wMax = vMax->win[3], wMin = vMin->win[3], wMid = vMid->win[3];
- TEX_UNIT_LOOP(
- GLfloat eMaj_ds = vMax->texcoord[u][0] * wMax - vMin->texcoord[u][0] * wMin;
- GLfloat eBot_ds = vMid->texcoord[u][0] * wMid - vMin->texcoord[u][0] * wMin;
- GLfloat eMaj_dt = vMax->texcoord[u][1] * wMax - vMin->texcoord[u][1] * wMin;
- GLfloat eBot_dt = vMid->texcoord[u][1] * wMid - vMin->texcoord[u][1] * wMin;
- GLfloat eMaj_du = vMax->texcoord[u][2] * wMax - vMin->texcoord[u][2] * wMin;
- GLfloat eBot_du = vMid->texcoord[u][2] * wMid - vMin->texcoord[u][2] * wMin;
- GLfloat eMaj_dv = vMax->texcoord[u][3] * wMax - vMin->texcoord[u][3] * wMin;
- GLfloat eBot_dv = vMid->texcoord[u][3] * wMid - vMin->texcoord[u][3] * wMin;
- span.texStepX[u][0] = oneOverArea * (eMaj_ds * eBot.dy - eMaj.dy * eBot_ds);
- span.texStepY[u][0] = oneOverArea * (eMaj.dx * eBot_ds - eMaj_ds * eBot.dx);
- span.texStepX[u][1] = oneOverArea * (eMaj_dt * eBot.dy - eMaj.dy * eBot_dt);
- span.texStepY[u][1] = oneOverArea * (eMaj.dx * eBot_dt - eMaj_dt * eBot.dx);
- span.texStepX[u][2] = oneOverArea * (eMaj_du * eBot.dy - eMaj.dy * eBot_du);
- span.texStepY[u][2] = oneOverArea * (eMaj.dx * eBot_du - eMaj_du * eBot.dx);
- span.texStepX[u][3] = oneOverArea * (eMaj_dv * eBot.dy - eMaj.dy * eBot_dv);
- span.texStepY[u][3] = oneOverArea * (eMaj.dx * eBot_dv - eMaj_dv * eBot.dx);
- )
- }
-#endif
-#ifdef INTERP_VARYING
- span.interpMask |= SPAN_VARYING;
- {
- /* win[3] is 1/W */
- const GLfloat wMax = vMax->win[3], wMin = vMin->win[3], wMid = vMid->win[3];
- VARYING_LOOP(
- GLfloat eMaj_dvar = vMax->attribute[iv][ic] * wMax - vMin->attribute[iv][ic] * wMin;
- GLfloat eBot_dvar = vMid->attribute[iv][ic] * wMid - vMin->attribute[iv][ic] * wMin;
- span.varStepX[iv][ic] = oneOverArea * (eMaj_dvar * eBot.dy - eMaj.dy * eBot_dvar);
- span.varStepY[iv][ic] = oneOverArea * (eMaj.dx * eBot_dvar - eMaj_dvar * eBot.dx);
+ TEXVAR_LOOP(
+ GLfloat eMaj_ds = vMax->attrib[attr][0] * wMax - vMin->attrib[attr][0] * wMin;
+ GLfloat eBot_ds = vMid->attrib[attr][0] * wMid - vMin->attrib[attr][0] * wMin;
+ GLfloat eMaj_dt = vMax->attrib[attr][1] * wMax - vMin->attrib[attr][1] * wMin;
+ GLfloat eBot_dt = vMid->attrib[attr][1] * wMid - vMin->attrib[attr][1] * wMin;
+ GLfloat eMaj_du = vMax->attrib[attr][2] * wMax - vMin->attrib[attr][2] * wMin;
+ GLfloat eBot_du = vMid->attrib[attr][2] * wMid - vMin->attrib[attr][2] * wMin;
+ GLfloat eMaj_dv = vMax->attrib[attr][3] * wMax - vMin->attrib[attr][3] * wMin;
+ GLfloat eBot_dv = vMid->attrib[attr][3] * wMid - vMin->attrib[attr][3] * wMin;
+ span.attrStepX[attr][0] = oneOverArea * (eMaj_ds * eBot.dy - eMaj.dy * eBot_ds);
+ span.attrStepY[attr][0] = oneOverArea * (eMaj.dx * eBot_ds - eMaj_ds * eBot.dx);
+ span.attrStepX[attr][1] = oneOverArea * (eMaj_dt * eBot.dy - eMaj.dy * eBot_dt);
+ span.attrStepY[attr][1] = oneOverArea * (eMaj.dx * eBot_dt - eMaj_dt * eBot.dx);
+ span.attrStepX[attr][2] = oneOverArea * (eMaj_du * eBot.dy - eMaj.dy * eBot_du);
+ span.attrStepY[attr][2] = oneOverArea * (eMaj.dx * eBot_du - eMaj_du * eBot.dx);
+ span.attrStepX[attr][3] = oneOverArea * (eMaj_dv * eBot.dy - eMaj.dy * eBot_dv);
+ span.attrStepY[attr][3] = oneOverArea * (eMaj.dx * eBot_dv - eMaj_dv * eBot.dx);
)
}
#endif
@@ -770,19 +733,14 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
GLfixed tLeft=0, dtOuter=0, dtInner;
#endif
#ifdef INTERP_TEX
- GLfloat sLeft[MAX_TEXTURE_COORD_UNITS];
- GLfloat tLeft[MAX_TEXTURE_COORD_UNITS];
- GLfloat uLeft[MAX_TEXTURE_COORD_UNITS];
- GLfloat vLeft[MAX_TEXTURE_COORD_UNITS];
- GLfloat dsOuter[MAX_TEXTURE_COORD_UNITS], dsInner[MAX_TEXTURE_COORD_UNITS];
- GLfloat dtOuter[MAX_TEXTURE_COORD_UNITS], dtInner[MAX_TEXTURE_COORD_UNITS];
- GLfloat duOuter[MAX_TEXTURE_COORD_UNITS], duInner[MAX_TEXTURE_COORD_UNITS];
- GLfloat dvOuter[MAX_TEXTURE_COORD_UNITS], dvInner[MAX_TEXTURE_COORD_UNITS];
-#endif
-#ifdef INTERP_VARYING
- GLfloat varLeft[MAX_VARYING_VECTORS][VARYINGS_PER_VECTOR];
- GLfloat dvarOuter[MAX_VARYING_VECTORS][VARYINGS_PER_VECTOR];
- GLfloat dvarInner[MAX_VARYING_VECTORS][VARYINGS_PER_VECTOR];
+ GLfloat sLeft[FRAG_ATTRIB_MAX];
+ GLfloat tLeft[FRAG_ATTRIB_MAX];
+ GLfloat uLeft[FRAG_ATTRIB_MAX];
+ GLfloat vLeft[FRAG_ATTRIB_MAX];
+ GLfloat dsOuter[FRAG_ATTRIB_MAX], dsInner[FRAG_ATTRIB_MAX];
+ GLfloat dtOuter[FRAG_ATTRIB_MAX], dtInner[FRAG_ATTRIB_MAX];
+ GLfloat duOuter[FRAG_ATTRIB_MAX], duInner[FRAG_ATTRIB_MAX];
+ GLfloat dvOuter[FRAG_ATTRIB_MAX], dvInner[FRAG_ATTRIB_MAX];
#endif
for (subTriangle=0; subTriangle<=1; subTriangle++) {
@@ -894,19 +852,20 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
GLfloat z0 = vLower->win[2];
if (depthBits <= 16) {
/* interpolate fixed-pt values */
- GLfloat tmp = (z0 * FIXED_SCALE + span.dzdx * adjx
- + span.dzdy * adjy) + FIXED_HALF;
+ GLfloat tmp = (z0 * FIXED_SCALE
+ + span.attrStepX[FRAG_ATTRIB_WPOS][2] * adjx
+ + span.attrStepY[FRAG_ATTRIB_WPOS][2] * adjy) + FIXED_HALF;
if (tmp < MAX_GLUINT / 2)
zLeft = (GLfixed) tmp;
else
zLeft = MAX_GLUINT / 2;
- fdzOuter = SignedFloatToFixed(span.dzdy + dxOuter * span.dzdx);
+ fdzOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_WPOS][2] + dxOuter * span.attrStepX[FRAG_ATTRIB_WPOS][2]);
}
else {
/* interpolate depth values w/out scaling */
- zLeft = (GLuint) (z0 + span.dzdx * FixedToFloat(adjx)
- + span.dzdy * FixedToFloat(adjy));
- fdzOuter = (GLint) (span.dzdy + dxOuter * span.dzdx);
+ zLeft = (GLuint) (z0 + span.attrStepX[FRAG_ATTRIB_WPOS][2] * FixedToFloat(adjx)
+ + span.attrStepY[FRAG_ATTRIB_WPOS][2] * FixedToFloat(adjy));
+ fdzOuter = (GLint) (span.attrStepY[FRAG_ATTRIB_WPOS][2] + dxOuter * span.attrStepX[FRAG_ATTRIB_WPOS][2]);
}
# ifdef DEPTH_TYPE
zRow = (DEPTH_TYPE *)
@@ -916,41 +875,41 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
}
#endif
#ifdef INTERP_W
- wLeft = vLower->win[3] + (span.dwdx * adjx + span.dwdy * adjy) * (1.0F/FIXED_SCALE);
- dwOuter = span.dwdy + dxOuter * span.dwdx;
+ wLeft = vLower->win[3] + (span.attrStepX[FRAG_ATTRIB_WPOS][3] * adjx + span.attrStepY[FRAG_ATTRIB_WPOS][3] * adjy) * (1.0F/FIXED_SCALE);
+ dwOuter = span.attrStepY[FRAG_ATTRIB_WPOS][3] + dxOuter * span.attrStepX[FRAG_ATTRIB_WPOS][3];
#endif
#ifdef INTERP_FOG
# ifdef INTERP_W
- fogLeft = vLower->fog * vLower->win[3] + (span.dfogdx * adjx + span.dfogdy * adjy) * (1.0F/FIXED_SCALE);
+ fogLeft = vLower->fog * vLower->win[3] + (span.attrStepX[FRAG_ATTRIB_FOGC][0] * adjx + span.attrStepY[FRAG_ATTRIB_FOGC][0] * adjy) * (1.0F/FIXED_SCALE);
# else
- fogLeft = vLower->fog + (span.dfogdx * adjx + span.dfogdy * adjy) * (1.0F/FIXED_SCALE);
+ fogLeft = vLower->fog + (span.attrStepX[FRAG_ATTRIB_FOGC][0] * adjx + span.attrStepY[FRAG_ATTRIB_FOGC][0] * adjy) * (1.0F/FIXED_SCALE);
# endif
- dfogOuter = span.dfogdy + dxOuter * span.dfogdx;
+ dfogOuter = span.attrStepY[FRAG_ATTRIB_FOGC][0] + dxOuter * span.attrStepX[FRAG_ATTRIB_FOGC][0];
#endif
#ifdef INTERP_RGB
if (ctx->Light.ShadeModel == GL_SMOOTH) {
# if CHAN_TYPE == GL_FLOAT
- rLeft = vLower->color[RCOMP] + (span.drdx * adjx + span.drdy * adjy) * (1.0F / FIXED_SCALE);
- gLeft = vLower->color[GCOMP] + (span.dgdx * adjx + span.dgdy * adjy) * (1.0F / FIXED_SCALE);
- bLeft = vLower->color[BCOMP] + (span.dbdx * adjx + span.dbdy * adjy) * (1.0F / FIXED_SCALE);
- fdrOuter = span.drdy + dxOuter * span.drdx;
- fdgOuter = span.dgdy + dxOuter * span.dgdx;
- fdbOuter = span.dbdy + dxOuter * span.dbdx;
+ rLeft = vLower->color[RCOMP] + (span.attrStepX[FRAG_ATTRIB_COL0][0] * adjx + span.attrStepY[FRAG_ATTRIB_COL0][0] * adjy) * (1.0F / FIXED_SCALE);
+ gLeft = vLower->color[GCOMP] + (span.attrStepX[FRAG_ATTRIB_COL0][1] * adjx + span.attrStepY[FRAG_ATTRIB_COL0][1] * adjy) * (1.0F / FIXED_SCALE);
+ bLeft = vLower->color[BCOMP] + (span.attrStepX[FRAG_ATTRIB_COL0][2] * adjx + span.attrStepY[FRAG_ATTRIB_COL0][2] * adjy) * (1.0F / FIXED_SCALE);
+ fdrOuter = span.attrStepY[FRAG_ATTRIB_COL0][0] + dxOuter * span.attrStepX[FRAG_ATTRIB_COL0][0];
+ fdgOuter = span.attrStepY[FRAG_ATTRIB_COL0][1] + dxOuter * span.attrStepX[FRAG_ATTRIB_COL0][1];
+ fdbOuter = span.attrStepY[FRAG_ATTRIB_COL0][2] + dxOuter * span.attrStepX[FRAG_ATTRIB_COL0][2];
# else
- rLeft = (GLint)(ChanToFixed(vLower->color[RCOMP]) + span.drdx * adjx + span.drdy * adjy) + FIXED_HALF;
- gLeft = (GLint)(ChanToFixed(vLower->color[GCOMP]) + span.dgdx * adjx + span.dgdy * adjy) + FIXED_HALF;
- bLeft = (GLint)(ChanToFixed(vLower->color[BCOMP]) + span.dbdx * adjx + span.dbdy * adjy) + FIXED_HALF;
- fdrOuter = SignedFloatToFixed(span.drdy + dxOuter * span.drdx);
- fdgOuter = SignedFloatToFixed(span.dgdy + dxOuter * span.dgdx);
- fdbOuter = SignedFloatToFixed(span.dbdy + dxOuter * span.dbdx);
+ rLeft = (GLint)(ChanToFixed(vLower->color[RCOMP]) + span.attrStepX[FRAG_ATTRIB_COL0][0] * adjx + span.attrStepY[FRAG_ATTRIB_COL0][0] * adjy) + FIXED_HALF;
+ gLeft = (GLint)(ChanToFixed(vLower->color[GCOMP]) + span.attrStepX[FRAG_ATTRIB_COL0][1] * adjx + span.attrStepY[FRAG_ATTRIB_COL0][1] * adjy) + FIXED_HALF;
+ bLeft = (GLint)(ChanToFixed(vLower->color[BCOMP]) + span.attrStepX[FRAG_ATTRIB_COL0][2] * adjx + span.attrStepY[FRAG_ATTRIB_COL0][2] * adjy) + FIXED_HALF;
+ fdrOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_COL0][0] + dxOuter * span.attrStepX[FRAG_ATTRIB_COL0][0]);
+ fdgOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_COL0][1] + dxOuter * span.attrStepX[FRAG_ATTRIB_COL0][1]);
+ fdbOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_COL0][2] + dxOuter * span.attrStepX[FRAG_ATTRIB_COL0][2]);
# endif
# ifdef INTERP_ALPHA
# if CHAN_TYPE == GL_FLOAT
- aLeft = vLower->color[ACOMP] + (span.dadx * adjx + span.dady * adjy) * (1.0F / FIXED_SCALE);
- fdaOuter = span.dady + dxOuter * span.dadx;
+ aLeft = vLower->color[ACOMP] + (span.attrStepX[FRAG_ATTRIB_COL0][3] * adjx + span.attrStepX[FRAG_ATTRIB_COL0][3] * adjy) * (1.0F / FIXED_SCALE);
+ fdaOuter = span.attrStepX[FRAG_ATTRIB_COL0][3] + dxOuter * span.attrStepX[FRAG_ATTRIB_COL0][3];
# else
- aLeft = (GLint)(ChanToFixed(vLower->color[ACOMP]) + span.dadx * adjx + span.dady * adjy) + FIXED_HALF;
- fdaOuter = SignedFloatToFixed(span.dady + dxOuter * span.dadx);
+ aLeft = (GLint)(ChanToFixed(vLower->color[ACOMP]) + span.attrStepX[FRAG_ATTRIB_COL0][3] * adjx + span.attrStepX[FRAG_ATTRIB_COL0][3] * adjy) + FIXED_HALF;
+ fdaOuter = SignedFloatToFixed(span.attrStepX[FRAG_ATTRIB_COL0][3] + dxOuter * span.attrStepX[FRAG_ATTRIB_COL0][3]);
# endif
# endif
}
@@ -983,19 +942,19 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
#ifdef INTERP_SPEC
if (ctx->Light.ShadeModel == GL_SMOOTH) {
# if CHAN_TYPE == GL_FLOAT
- srLeft = vLower->specular[RCOMP] + (span.dsrdx * adjx + span.dsrdy * adjy) * (1.0F / FIXED_SCALE);
- sgLeft = vLower->specular[GCOMP] + (span.dsgdx * adjx + span.dsgdy * adjy) * (1.0F / FIXED_SCALE);
- sbLeft = vLower->specular[BCOMP] + (span.dsbdx * adjx + span.dsbdy * adjy) * (1.0F / FIXED_SCALE);
- dsrOuter = span.dsrdy + dxOuter * span.dsrdx;
- dsgOuter = span.dsgdy + dxOuter * span.dsgdx;
- dsbOuter = span.dsbdy + dxOuter * span.dsbdx;
+ srLeft = vLower->specular[RCOMP] + (span.attrStepX[FRAG_ATTRIB_COL1][0] * adjx + span.attrStepY[FRAG_ATTRIB_COL1][0] * adjy) * (1.0F / FIXED_SCALE);
+ sgLeft = vLower->specular[GCOMP] + (span.attrStepX[FRAG_ATTRIB_COL1][1] * adjx + span.attrStepY[FRAG_ATTRIB_COL1][1] * adjy) * (1.0F / FIXED_SCALE);
+ sbLeft = vLower->specular[BCOMP] + (span.attrStepX[FRAG_ATTRIB_COL1][2] * adjx + span.attrStepY[FRAG_ATTRIB_COL1][2] * adjy) * (1.0F / FIXED_SCALE);
+ dsrOuter = span.attrStepY[FRAG_ATTRIB_COL1][0] + dxOuter * span.attrStepX[FRAG_ATTRIB_COL1][0];
+ dsgOuter = span.attrStepY[FRAG_ATTRIB_COL1][1] + dxOuter * span.attrStepX[FRAG_ATTRIB_COL1][1];
+ dsbOuter = span.attrStepY[FRAG_ATTRIB_COL1][2] + dxOuter * span.attrStepX[FRAG_ATTRIB_COL1][2];
# else
- srLeft = (GLfixed) (ChanToFixed(vLower->specular[RCOMP]) + span.dsrdx * adjx + span.dsrdy * adjy) + FIXED_HALF;
- sgLeft = (GLfixed) (ChanToFixed(vLower->specular[GCOMP]) + span.dsgdx * adjx + span.dsgdy * adjy) + FIXED_HALF;
- sbLeft = (GLfixed) (ChanToFixed(vLower->specular[BCOMP]) + span.dsbdx * adjx + span.dsbdy * adjy) + FIXED_HALF;
- dsrOuter = SignedFloatToFixed(span.dsrdy + dxOuter * span.dsrdx);
- dsgOuter = SignedFloatToFixed(span.dsgdy + dxOuter * span.dsgdx);
- dsbOuter = SignedFloatToFixed(span.dsbdy + dxOuter * span.dsbdx);
+ srLeft = (GLfixed) (ChanToFixed(vLower->specular[RCOMP]) + span.attrStepX[FRAG_ATTRIB_COL1][0] * adjx + span.attrStepY[FRAG_ATTRIB_COL1][0] * adjy) + FIXED_HALF;
+ sgLeft = (GLfixed) (ChanToFixed(vLower->specular[GCOMP]) + span.attrStepX[FRAG_ATTRIB_COL1][1] * adjx + span.attrStepY[FRAG_ATTRIB_COL1][1] * adjy) + FIXED_HALF;
+ sbLeft = (GLfixed) (ChanToFixed(vLower->specular[BCOMP]) + span.attrStepX[FRAG_ATTRIB_COL1][2] * adjx + span.attrStepY[FRAG_ATTRIB_COL1][2] * adjy) + FIXED_HALF;
+ dsrOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_COL1][0] + dxOuter * span.attrStepX[FRAG_ATTRIB_COL1][0]);
+ dsgOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_COL1][1] + dxOuter * span.attrStepX[FRAG_ATTRIB_COL1][1]);
+ dsbOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_COL1][2] + dxOuter * span.attrStepX[FRAG_ATTRIB_COL1][2]);
# endif
}
else {
@@ -1029,41 +988,32 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
#ifdef INTERP_INT_TEX
{
GLfloat s0, t0;
- s0 = vLower->texcoord[0][0] * S_SCALE;
- sLeft = (GLfixed)(s0 * FIXED_SCALE + span.texStepX[0][0] * adjx
- + span.texStepY[0][0] * adjy) + FIXED_HALF;
- dsOuter = SignedFloatToFixed(span.texStepY[0][0] + dxOuter * span.texStepX[0][0]);
-
- t0 = vLower->texcoord[0][1] * T_SCALE;
- tLeft = (GLfixed)(t0 * FIXED_SCALE + span.texStepX[0][1] * adjx
- + span.texStepY[0][1] * adjy) + FIXED_HALF;
- dtOuter = SignedFloatToFixed(span.texStepY[0][1] + dxOuter * span.texStepX[0][1]);
+ s0 = vLower->attrib[FRAG_ATTRIB_TEX0][0] * S_SCALE;
+ sLeft = (GLfixed)(s0 * FIXED_SCALE + span.attrStepX[FRAG_ATTRIB_TEX0][0] * adjx
+ + span.attrStepY[FRAG_ATTRIB_TEX0][0] * adjy) + FIXED_HALF;
+ dsOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_TEX0][0] + dxOuter * span.attrStepX[FRAG_ATTRIB_TEX0][0]);
+
+ t0 = vLower->attrib[FRAG_ATTRIB_TEX0][1] * T_SCALE;
+ tLeft = (GLfixed)(t0 * FIXED_SCALE + span.attrStepX[FRAG_ATTRIB_TEX0][1] * adjx
+ + span.attrStepY[FRAG_ATTRIB_TEX0][1] * adjy) + FIXED_HALF;
+ dtOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_TEX0][1] + dxOuter * span.attrStepX[FRAG_ATTRIB_TEX0][1]);
}
#endif
#ifdef INTERP_TEX
- TEX_UNIT_LOOP(
+ TEXVAR_LOOP(
const GLfloat invW = vLower->win[3];
- const GLfloat s0 = vLower->texcoord[u][0] * invW;
- const GLfloat t0 = vLower->texcoord[u][1] * invW;
- const GLfloat u0 = vLower->texcoord[u][2] * invW;
- const GLfloat v0 = vLower->texcoord[u][3] * invW;
- sLeft[u] = s0 + (span.texStepX[u][0] * adjx + span.texStepY[u][0] * adjy) * (1.0F/FIXED_SCALE);
- tLeft[u] = t0 + (span.texStepX[u][1] * adjx + span.texStepY[u][1] * adjy) * (1.0F/FIXED_SCALE);
- uLeft[u] = u0 + (span.texStepX[u][2] * adjx + span.texStepY[u][2] * adjy) * (1.0F/FIXED_SCALE);
- vLeft[u] = v0 + (span.texStepX[u][3] * adjx + span.texStepY[u][3] * adjy) * (1.0F/FIXED_SCALE);
- dsOuter[u] = span.texStepY[u][0] + dxOuter * span.texStepX[u][0];
- dtOuter[u] = span.texStepY[u][1] + dxOuter * span.texStepX[u][1];
- duOuter[u] = span.texStepY[u][2] + dxOuter * span.texStepX[u][2];
- dvOuter[u] = span.texStepY[u][3] + dxOuter * span.texStepX[u][3];
- )
-#endif
-#ifdef INTERP_VARYING
- VARYING_LOOP(
- const GLfloat invW = vLower->win[3];
- const GLfloat var0 = vLower->attribute[iv][ic] * invW;
- varLeft[iv][ic] = var0 + (span.varStepX[iv][ic] * adjx +
- span.varStepY[iv][ic] * adjy) * (1.0f / FIXED_SCALE);
- dvarOuter[iv][ic] = span.varStepY[iv][ic] + dxOuter * span.varStepX[iv][ic];
+ const GLfloat s0 = vLower->attrib[attr][0] * invW;
+ const GLfloat t0 = vLower->attrib[attr][1] * invW;
+ const GLfloat u0 = vLower->attrib[attr][2] * invW;
+ const GLfloat v0 = vLower->attrib[attr][3] * invW;
+ sLeft[attr] = s0 + (span.attrStepX[attr][0] * adjx + span.attrStepY[attr][0] * adjy) * (1.0F/FIXED_SCALE);
+ tLeft[attr] = t0 + (span.attrStepX[attr][1] * adjx + span.attrStepY[attr][1] * adjy) * (1.0F/FIXED_SCALE);
+ uLeft[attr] = u0 + (span.attrStepX[attr][2] * adjx + span.attrStepY[attr][2] * adjy) * (1.0F/FIXED_SCALE);
+ vLeft[attr] = v0 + (span.attrStepX[attr][3] * adjx + span.attrStepY[attr][3] * adjy) * (1.0F/FIXED_SCALE);
+ dsOuter[attr] = span.attrStepY[attr][0] + dxOuter * span.attrStepX[attr][0];
+ dtOuter[attr] = span.attrStepY[attr][1] + dxOuter * span.attrStepX[attr][1];
+ duOuter[attr] = span.attrStepY[attr][2] + dxOuter * span.attrStepX[attr][2];
+ dvOuter[attr] = span.attrStepY[attr][3] + dxOuter * span.attrStepX[attr][3];
)
#endif
} /*if setupLeft*/
@@ -1095,10 +1045,10 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
fdzInner = fdzOuter + span.zStep;
#endif
#ifdef INTERP_W
- dwInner = dwOuter + span.dwdx;
+ dwInner = dwOuter + span.attrStepX[FRAG_ATTRIB_WPOS][3];
#endif
#ifdef INTERP_FOG
- dfogInner = dfogOuter + span.dfogdx;
+ dfogInner = dfogOuter + span.attrStepX[FRAG_ATTRIB_FOGC][0];
#endif
#ifdef INTERP_RGB
fdrInner = fdrOuter + span.redStep;
@@ -1121,16 +1071,11 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
dtInner = dtOuter + span.intTexStep[1];
#endif
#ifdef INTERP_TEX
- TEX_UNIT_LOOP(
- 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];
- )
-#endif
-#ifdef INTERP_VARYING
- VARYING_LOOP(
- dvarInner[iv][ic] = dvarOuter[iv][ic] + span.varStepX[iv][ic];
+ TEXVAR_LOOP(
+ dsInner[attr] = dsOuter[attr] + span.attrStepX[attr][0];
+ dtInner[attr] = dtOuter[attr] + span.attrStepX[attr][1];
+ duInner[attr] = duOuter[attr] + span.attrStepX[attr][2];
+ dvInner[attr] = dvOuter[attr] + span.attrStepX[attr][3];
)
#endif
@@ -1148,10 +1093,10 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
span.z = zLeft;
#endif
#ifdef INTERP_W
- span.w = wLeft;
+ span.attrStart[FRAG_ATTRIB_WPOS][3] = wLeft;
#endif
#ifdef INTERP_FOG
- span.fog = fogLeft;
+ span.attrStart[FRAG_ATTRIB_FOGC][0] = fogLeft;
#endif
#ifdef INTERP_RGB
span.red = rLeft;
@@ -1175,16 +1120,11 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
#endif
#ifdef INTERP_TEX
- TEX_UNIT_LOOP(
- span.tex[u][0] = sLeft[u];
- span.tex[u][1] = tLeft[u];
- span.tex[u][2] = uLeft[u];
- span.tex[u][3] = vLeft[u];
- )
-#endif
-#ifdef INTERP_VARYING
- VARYING_LOOP(
- span.var[iv][ic] = varLeft[iv][ic];
+ TEXVAR_LOOP(
+ span.attrStart[attr][0] = sLeft[attr];
+ span.attrStart[attr][1] = tLeft[attr];
+ span.attrStart[attr][2] = uLeft[attr];
+ span.attrStart[attr][3] = vLeft[attr];
)
#endif
@@ -1268,16 +1208,11 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
tLeft += dtOuter;
#endif
#ifdef INTERP_TEX
- TEX_UNIT_LOOP(
- sLeft[u] += dsOuter[u];
- tLeft[u] += dtOuter[u];
- uLeft[u] += duOuter[u];
- vLeft[u] += dvOuter[u];
- )
-#endif
-#ifdef INTERP_VARYING
- VARYING_LOOP(
- varLeft[iv][ic] += dvarOuter[iv][ic];
+ TEXVAR_LOOP(
+ sLeft[attr] += dsOuter[attr];
+ tLeft[attr] += dtOuter[attr];
+ uLeft[attr] += duOuter[attr];
+ vLeft[attr] += dvOuter[attr];
)
#endif
}
@@ -1318,16 +1253,11 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
tLeft += dtInner;
#endif
#ifdef INTERP_TEX
- TEX_UNIT_LOOP(
- sLeft[u] += dsInner[u];
- tLeft[u] += dtInner[u];
- uLeft[u] += duInner[u];
- vLeft[u] += dvInner[u];
- )
-#endif
-#ifdef INTERP_VARYING
- VARYING_LOOP(
- varLeft[iv][ic] += dvarInner[iv][ic];
+ TEXVAR_LOOP(
+ sLeft[attr] += dsInner[attr];
+ tLeft[attr] += dtInner[attr];
+ uLeft[attr] += duInner[attr];
+ vLeft[attr] += dvInner[attr];
)
#endif
}
@@ -1360,8 +1290,6 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
#undef INTERP_INDEX
#undef INTERP_INT_TEX
#undef INTERP_TEX
-#undef INTERP_MULTITEX
-#undef INTERP_VARYING
#undef TEX_UNIT_LOOP
#undef VARYING_LOOP
diff --git a/src/mesa/swrast/s_zoom.c b/src/mesa/swrast/s_zoom.c
index 036a6084dc3..9bec0bb1a1c 100644
--- a/src/mesa/swrast/s_zoom.c
+++ b/src/mesa/swrast/s_zoom.c
@@ -159,8 +159,9 @@ zoom_span( GLcontext *ctx, GLint imgX, GLint imgY, const SWspan *span,
/* copy fog interp info */
- zoomed.fog = span->fog;
- zoomed.fogStep = span->fogStep;
+ zoomed.attrStart[FRAG_ATTRIB_FOGC][0] = span->attrStart[FRAG_ATTRIB_FOGC][0];
+ zoomed.attrStepX[FRAG_ATTRIB_FOGC][0] = span->attrStepX[FRAG_ATTRIB_FOGC][0];
+ zoomed.attrStepY[FRAG_ATTRIB_FOGC][0] = span->attrStepY[FRAG_ATTRIB_FOGC][0];
/* XXX copy texcoord info? */
if (format == GL_RGBA || format == GL_RGB) {
@@ -229,8 +230,8 @@ zoom_span( GLcontext *ctx, GLint imgX, GLint imgY, const SWspan *span,
for (i = 0; i < zoomedWidth; i++) {
GLint j = unzoom_x(ctx->Pixel.ZoomX, imgX, x0 + i) - span->x;
ASSERT(j >= 0);
- ASSERT(j < (GLint) span->end);
- COPY_4V(zoomed.array->color.sz4.rgba[i], rgba[j]);
+ ASSERT(j < span->end);
+ COPY_4V(zoomed.array->attribs[FRAG_ATTRIB_COL0][i], rgba[j]);
}
}
}
@@ -267,11 +268,11 @@ zoom_span( GLcontext *ctx, GLint imgX, GLint imgY, const SWspan *span,
for (i = 0; i < zoomedWidth; i++) {
GLint j = unzoom_x(ctx->Pixel.ZoomX, imgX, x0 + i) - span->x;
ASSERT(j >= 0);
- ASSERT(j < (GLint) span->end);
- zoomed.array->color.sz4.rgba[i][0] = rgb[j][0];
- zoomed.array->color.sz4.rgba[i][1] = rgb[j][1];
- zoomed.array->color.sz4.rgba[i][2] = rgb[j][2];
- zoomed.array->color.sz4.rgba[i][3] = 1.0F;
+ ASSERT(j < span->end);
+ zoomed.array->attribs[FRAG_ATTRIB_COL0][i][0] = rgb[j][0];
+ zoomed.array->attribs[FRAG_ATTRIB_COL0][i][1] = rgb[j][1];
+ zoomed.array->attribs[FRAG_ATTRIB_COL0][i][2] = rgb[j][2];
+ zoomed.array->attribs[FRAG_ATTRIB_COL0][i][3] = 1.0F;
}
}
}
diff --git a/src/mesa/swrast/swrast.h b/src/mesa/swrast/swrast.h
index 09686c8380a..9e1fe24bb40 100644
--- a/src/mesa/swrast/swrast.h
+++ b/src/mesa/swrast/swrast.h
@@ -67,13 +67,12 @@ typedef struct {
* that clip{XYZ} were multiplied by to get ndc{XYZ}.
*/
GLfloat win[4];
- GLfloat texcoord[MAX_TEXTURE_COORD_UNITS][4];
GLchan color[4];
GLchan specular[4];
GLfloat fog;
GLfloat index;
GLfloat pointSize;
- GLfloat attribute[MAX_VERTEX_ATTRIBS][4];
+ GLfloat attrib[FRAG_ATTRIB_MAX][4]; /**< texcoords & varying, more to come */
} SWvertex;