summaryrefslogtreecommitdiff
path: root/src/mesa/swrast
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/swrast')
-rw-r--r--src/mesa/swrast/s_aaline.c43
-rw-r--r--src/mesa/swrast/s_aalinetemp.h155
-rw-r--r--src/mesa/swrast/s_aatriangle.c91
-rw-r--r--src/mesa/swrast/s_aatritemp.h276
-rw-r--r--src/mesa/swrast/s_accum.c4
-rw-r--r--src/mesa/swrast/s_alpha.c4
-rw-r--r--src/mesa/swrast/s_bitmap.c28
-rw-r--r--src/mesa/swrast/s_buffers.c8
-rw-r--r--src/mesa/swrast/s_context.c143
-rw-r--r--src/mesa/swrast/s_context.h41
-rw-r--r--src/mesa/swrast/s_copypix.c48
-rw-r--r--src/mesa/swrast/s_depth.c2
-rw-r--r--src/mesa/swrast/s_drawpix.c72
-rw-r--r--src/mesa/swrast/s_feedback.c126
-rw-r--r--src/mesa/swrast/s_fog.c335
-rw-r--r--src/mesa/swrast/s_fragprog.c29
-rw-r--r--src/mesa/swrast/s_lines.c149
-rw-r--r--src/mesa/swrast/s_linetemp.h173
-rw-r--r--src/mesa/swrast/s_logic.c4
-rw-r--r--src/mesa/swrast/s_masking.c4
-rw-r--r--src/mesa/swrast/s_points.c672
-rw-r--r--src/mesa/swrast/s_pointtemp.h429
-rw-r--r--src/mesa/swrast/s_span.c747
-rw-r--r--src/mesa/swrast/s_span.h114
-rw-r--r--src/mesa/swrast/s_stencil.c4
-rw-r--r--src/mesa/swrast/s_texcombine.c1
-rw-r--r--src/mesa/swrast/s_texfilter.c936
-rw-r--r--src/mesa/swrast/s_triangle.c163
-rw-r--r--src/mesa/swrast/s_tritemp.h691
-rw-r--r--src/mesa/swrast/s_zoom.c68
-rw-r--r--src/mesa/swrast/swrast.h24
31 files changed, 2634 insertions, 2950 deletions
diff --git a/src/mesa/swrast/s_aaline.c b/src/mesa/swrast/s_aaline.c
index c81095163b..d6a9afb421 100644
--- a/src/mesa/swrast/s_aaline.c
+++ b/src/mesa/swrast/s_aaline.c
@@ -59,19 +59,13 @@ struct LineInfo
/* DO_Z */
GLfloat zPlane[4];
- /* DO_FOG */
- GLfloat fPlane[4];
/* DO_RGBA */
GLfloat rPlane[4], gPlane[4], bPlane[4], aPlane[4];
/* DO_INDEX */
GLfloat iPlane[4];
- /* DO_SPEC */
- GLfloat srPlane[4], sgPlane[4], sbPlane[4];
- /* 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];
+ /* DO_ATTRIBS */
+ GLfloat wPlane[4];
+ GLfloat attrPlane[FRAG_ATTRIB_MAX][4][4];
GLfloat lambda[FRAG_ATTRIB_MAX];
GLfloat texWidth[FRAG_ATTRIB_MAX];
GLfloat texHeight[FRAG_ATTRIB_MAX];
@@ -483,32 +477,21 @@ segment(GLcontext *ctx,
#define NAME(x) aa_ci_##x
#define DO_Z
-#define DO_FOG
+#define DO_ATTRIBS /* for fog */
#define DO_INDEX
#include "s_aalinetemp.h"
#define NAME(x) aa_rgba_##x
#define DO_Z
-#define DO_FOG
#define DO_RGBA
#include "s_aalinetemp.h"
-#define NAME(x) aa_tex_rgba_##x
+#define NAME(x) aa_general_rgba_##x
#define DO_Z
-#define DO_FOG
#define DO_RGBA
-#define DO_TEXVAR
-#include "s_aalinetemp.h"
-
-
-#define NAME(x) aa_multitex_spec_##x
-#define DO_Z
-#define DO_FOG
-#define DO_RGBA
-#define DO_TEXVAR
-#define DO_SPEC
+#define DO_ATTRIBS
#include "s_aalinetemp.h"
@@ -523,14 +506,12 @@ _swrast_choose_aa_line_function(GLcontext *ctx)
if (ctx->Visual.rgbMode) {
/* RGBA */
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;
-
+ || ctx->FragmentProgram._Current
+ || (ctx->Light.Enabled &&
+ ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR)
+ || ctx->Fog.ColorSumEnabled
+ || swrast->_FogEnabled) {
+ swrast->Line = aa_general_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 dd741630a1..69a1f0cd39 100644
--- a/src/mesa/swrast/s_aalinetemp.h
+++ b/src/mesa/swrast/s_aalinetemp.h
@@ -1,6 +1,6 @@
/*
* Mesa 3-D graphics library
- * Version: 6.5.3
+ * Version: 7.1
*
* Copyright (C) 1999-2007 Brian Paul All Rights Reserved.
*
@@ -63,9 +63,6 @@ NAME(plot)(GLcontext *ctx, struct LineInfo *line, int ix, int iy)
#ifdef DO_Z
line->span.array->z[i] = (GLuint) solve_plane(fx, fy, line->zPlane);
#endif
-#ifdef DO_FOG
- 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);
line->span.array->rgba[i][GCOMP] = solve_plane_chan(fx, fy, line->gPlane);
@@ -75,37 +72,32 @@ NAME(plot)(GLcontext *ctx, struct LineInfo *line, int ix, int iy)
#ifdef DO_INDEX
line->span.array->index[i] = (GLint) solve_plane(fx, fy, line->iPlane);
#endif
-#ifdef DO_SPEC
- line->span.array->spec[i][RCOMP] = solve_plane_chan(fx, fy, line->srPlane);
- 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
-#if defined(DO_TEXVAR)
- {
- 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) {
- invQ = 1.0F;
- }
- else {
- 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]);
- }
+#if defined(DO_ATTRIBS)
+ ATTRIB_LOOP_BEGIN
+ GLfloat (*attribArray)[4] = line->span.array->attribs[attr];
+ if (attr >= FRAG_ATTRIB_TEX0 && attr < FRAG_ATTRIB_VAR0
+ && !ctx->FragmentProgram._Active) {
+ /* texcoord w/ divide by Q */
+ const GLuint unit = attr - FRAG_ATTRIB_TEX0;
+ const GLfloat invQ = solve_plane_recip(fx, fy, line->attrPlane[attr][3]);
+ GLuint c;
+ for (c = 0; c < 3; c++) {
+ attribArray[i][c] = solve_plane(fx, fy, line->attrPlane[attr][c]) * invQ;
}
+ line->span.array->lambda[unit][i]
+ = compute_lambda(line->attrPlane[attr][0],
+ line->attrPlane[attr][1], invQ,
+ line->texWidth[attr], line->texHeight[attr]);
}
- }
+ else {
+ /* non-texture attrib */
+ const GLfloat invW = solve_plane_recip(fx, fy, line->wPlane);
+ GLuint c;
+ for (c = 0; c < 4; c++) {
+ attribArray[i][c] = solve_plane(fx, fy, line->attrPlane[attr][c]) * invW;
+ }
+ }
+ ATTRIB_LOOP_END
#endif
if (line->span.end == MAX_WIDTH) {
@@ -133,10 +125,10 @@ NAME(line)(GLcontext *ctx, const SWvertex *v0, const SWvertex *v1)
/* Init the LineInfo struct */
struct LineInfo line;
- line.x0 = v0->win[0];
- line.y0 = v0->win[1];
- line.x1 = v1->win[0];
- line.y1 = v1->win[1];
+ line.x0 = v0->attrib[FRAG_ATTRIB_WPOS][0];
+ line.y0 = v0->attrib[FRAG_ATTRIB_WPOS][1];
+ line.x1 = v1->attrib[FRAG_ATTRIB_WPOS][0];
+ line.y1 = v1->attrib[FRAG_ATTRIB_WPOS][1];
line.dx = line.x1 - line.x0;
line.dy = line.y1 - line.y0;
line.len = SQRTF(line.dx * line.dx + line.dy * line.dy);
@@ -145,20 +137,15 @@ NAME(line)(GLcontext *ctx, const SWvertex *v0, const SWvertex *v1)
if (line.len == 0.0 || IS_INF_OR_NAN(line.len))
return;
- INIT_SPAN(line.span, GL_LINE, 0, 0, SPAN_XY | SPAN_COVERAGE);
-
+ INIT_SPAN(line.span, GL_LINE);
+ line.span.arrayMask = SPAN_XY | SPAN_COVERAGE;
line.xAdj = line.dx / line.len * line.halfWidth;
line.yAdj = line.dy / line.len * line.halfWidth;
#ifdef DO_Z
line.span.arrayMask |= SPAN_Z;
compute_plane(line.x0, line.y0, line.x1, line.y1,
- v0->win[2], v1->win[2], line.zPlane);
-#endif
-#ifdef DO_FOG
- line.span.arrayMask |= SPAN_FOG;
- compute_plane(line.x0, line.y0, line.x1, line.y1,
- v0->fog, v1->fog, line.fPlane);
+ v0->attrib[FRAG_ATTRIB_WPOS][2], v1->attrib[FRAG_ATTRIB_WPOS][2], line.zPlane);
#endif
#ifdef DO_RGBA
line.span.arrayMask |= SPAN_RGBA;
@@ -179,61 +166,47 @@ NAME(line)(GLcontext *ctx, const SWvertex *v0, const SWvertex *v1)
constant_plane(v1->color[ACOMP], line.aPlane);
}
#endif
-#ifdef DO_SPEC
- line.span.arrayMask |= SPAN_SPEC;
- if (ctx->Light.ShadeModel == GL_SMOOTH) {
- compute_plane(line.x0, line.y0, line.x1, line.y1,
- v0->specular[RCOMP], v1->specular[RCOMP], line.srPlane);
- compute_plane(line.x0, line.y0, line.x1, line.y1,
- v0->specular[GCOMP], v1->specular[GCOMP], line.sgPlane);
- compute_plane(line.x0, line.y0, line.x1, line.y1,
- v0->specular[BCOMP], v1->specular[BCOMP], line.sbPlane);
- }
- else {
- constant_plane(v1->specular[RCOMP], line.srPlane);
- constant_plane(v1->specular[GCOMP], line.sgPlane);
- constant_plane(v1->specular[BCOMP], line.sbPlane);
- }
-#endif
#ifdef DO_INDEX
line.span.arrayMask |= SPAN_INDEX;
if (ctx->Light.ShadeModel == GL_SMOOTH) {
compute_plane(line.x0, line.y0, line.x1, line.y1,
- v0->index, v1->index, line.iPlane);
+ v0->attrib[FRAG_ATTRIB_CI][0],
+ v1->attrib[FRAG_ATTRIB_CI][0], line.iPlane);
}
else {
- constant_plane(v1->index, line.iPlane);
+ constant_plane(v1->attrib[FRAG_ATTRIB_CI][0], line.iPlane);
}
#endif
-#if defined(DO_TEXVAR)
+#if defined(DO_ATTRIBS)
{
- GLuint attr;
- const GLfloat invW0 = v0->win[3];
- const GLfloat invW1 = v1->win[3];
- 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;
+ const GLfloat invW0 = v0->attrib[FRAG_ATTRIB_WPOS][3];
+ const GLfloat invW1 = v1->attrib[FRAG_ATTRIB_WPOS][3];
+ line.span.arrayMask |= SPAN_LAMBDA;
+ compute_plane(line.x0, line.y0, line.x1, line.y1, invW0, invW1, line.wPlane);
+ ATTRIB_LOOP_BEGIN
+ GLuint c;
+ if (swrast->_InterpMode[attr] == GL_FLAT) {
+ for (c = 0; c < 4; c++) {
+ constant_plane(v1->attrib[attr][c], line.attrPlane[attr][c]);
}
}
- }
+ else {
+ for (c = 0; c < 4; c++) {
+ const GLfloat a0 = v0->attrib[attr][c] * invW0;
+ const GLfloat a1 = v1->attrib[attr][c] * invW1;
+ compute_plane(line.x0, line.y0, line.x1, line.y1, a0, a1,
+ line.attrPlane[attr][c]);
+ }
+ }
+ line.span.arrayAttribs |= (1 << attr);
+ if (attr >= FRAG_ATTRIB_TEX0 && 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;
+ }
+ ATTRIB_LOOP_END
}
#endif
@@ -292,9 +265,7 @@ NAME(line)(GLcontext *ctx, const SWvertex *v0, const SWvertex *v1)
#undef DO_Z
-#undef DO_FOG
#undef DO_RGBA
#undef DO_INDEX
-#undef DO_SPEC
-#undef DO_TEXVAR
+#undef DO_ATTRIBS
#undef NAME
diff --git a/src/mesa/swrast/s_aatriangle.c b/src/mesa/swrast/s_aatriangle.c
index 5e3059af93..66891f9fec 100644
--- a/src/mesa/swrast/s_aatriangle.c
+++ b/src/mesa/swrast/s_aatriangle.c
@@ -144,6 +144,19 @@ solve_plane_chan(GLfloat x, GLfloat y, const GLfloat plane[4])
}
+static INLINE GLfloat
+plane_dx(const GLfloat plane[4])
+{
+ return -plane[0] / plane[2];
+}
+
+static INLINE GLfloat
+plane_dy(const GLfloat plane[4])
+{
+ return -plane[1] / plane[2];
+}
+
+
/*
* Compute how much (area) of the given pixel is inside the triangle.
@@ -337,7 +350,6 @@ compute_coveragei(const GLfloat v0[3], const GLfloat v1[3],
}
-
static void
rgba_aa_tri(GLcontext *ctx,
const SWvertex *v0,
@@ -345,7 +357,6 @@ rgba_aa_tri(GLcontext *ctx,
const SWvertex *v2)
{
#define DO_Z
-#define DO_FOG
#define DO_RGBA
#include "s_aatritemp.h"
}
@@ -358,72 +369,21 @@ index_aa_tri(GLcontext *ctx,
const SWvertex *v2)
{
#define DO_Z
-#define DO_FOG
+#define DO_ATTRIBS
#define DO_INDEX
#include "s_aatritemp.h"
}
-/*
- * Compute mipmap level of detail.
- * XXX we should really include the R coordinate in this computation
- * in order to do 3-D texture mipmapping.
- */
-static INLINE GLfloat
-compute_lambda(const GLfloat sPlane[4], const GLfloat tPlane[4],
- const GLfloat qPlane[4], GLfloat cx, GLfloat cy,
- GLfloat invQ, GLfloat texWidth, GLfloat texHeight)
-{
- const GLfloat s = solve_plane(cx, cy, sPlane);
- const GLfloat t = solve_plane(cx, cy, tPlane);
- const GLfloat invQ_x1 = solve_plane_recip(cx+1.0F, cy, qPlane);
- const GLfloat invQ_y1 = solve_plane_recip(cx, cy+1.0F, qPlane);
- const GLfloat s_x1 = s - sPlane[0] / sPlane[2];
- const GLfloat s_y1 = s - sPlane[1] / sPlane[2];
- const GLfloat t_x1 = t - tPlane[0] / tPlane[2];
- const GLfloat t_y1 = t - tPlane[1] / tPlane[2];
- GLfloat dsdx = s_x1 * invQ_x1 - s * invQ;
- GLfloat dsdy = s_y1 * invQ_y1 - s * invQ;
- GLfloat dtdx = t_x1 * invQ_x1 - t * invQ;
- GLfloat dtdy = t_y1 * invQ_y1 - t * invQ;
- GLfloat maxU, maxV, rho, lambda;
- dsdx = FABSF(dsdx);
- dsdy = FABSF(dsdy);
- dtdx = FABSF(dtdx);
- dtdy = FABSF(dtdy);
- maxU = MAX2(dsdx, dsdy) * texWidth;
- maxV = MAX2(dtdx, dtdy) * texHeight;
- rho = MAX2(maxU, maxV);
- lambda = LOG2(rho);
- return lambda;
-}
-
-
-static void
-tex_aa_tri(GLcontext *ctx,
- const SWvertex *v0,
- const SWvertex *v1,
- const SWvertex *v2)
-{
-#define DO_Z
-#define DO_FOG
-#define DO_RGBA
-#define DO_TEXVAR
-#include "s_aatritemp.h"
-}
-
-
static void
-spec_tex_aa_tri(GLcontext *ctx,
- const SWvertex *v0,
- const SWvertex *v1,
- const SWvertex *v2)
+general_aa_tri(GLcontext *ctx,
+ const SWvertex *v0,
+ const SWvertex *v1,
+ const SWvertex *v2)
{
#define DO_Z
-#define DO_FOG
#define DO_RGBA
-#define DO_TEXVAR
-#define DO_SPEC
+#define DO_ATTRIBS
#include "s_aatritemp.h"
}
@@ -436,16 +396,15 @@ spec_tex_aa_tri(GLcontext *ctx,
void
_swrast_set_aa_triangle_function(GLcontext *ctx)
{
+ SWcontext *swrast = SWRAST_CONTEXT(ctx);
+
ASSERT(ctx->Polygon.SmoothFlag);
if (ctx->Texture._EnabledCoordUnits != 0
- || ctx->FragmentProgram._Current) {
- if (NEED_SECONDARY_COLOR(ctx)) {
- SWRAST_CONTEXT(ctx)->Triangle = spec_tex_aa_tri;
- }
- else {
- SWRAST_CONTEXT(ctx)->Triangle = tex_aa_tri;
- }
+ || ctx->FragmentProgram._Current
+ || swrast->_FogEnabled
+ || NEED_SECONDARY_COLOR(ctx)) {
+ SWRAST_CONTEXT(ctx)->Triangle = general_aa_tri;
}
else if (ctx->Visual.rgbMode) {
SWRAST_CONTEXT(ctx)->Triangle = rgba_aa_tri;
diff --git a/src/mesa/swrast/s_aatritemp.h b/src/mesa/swrast/s_aatritemp.h
index bbf9cc611d..42d74a1632 100644
--- a/src/mesa/swrast/s_aatritemp.h
+++ b/src/mesa/swrast/s_aatritemp.h
@@ -35,16 +35,15 @@
* DO_Z - if defined, compute Z values
* DO_RGBA - if defined, compute RGBA values
* DO_INDEX - if defined, compute color index values
- * DO_SPEC - if defined, compute specular RGB values
- * DO_TEXVAR - if defined, compute texcoords, varying
+ * DO_ATTRIBS - if defined, compute texcoords, varying, etc.
*/
/*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;
+ const GLfloat *p0 = v0->attrib[FRAG_ATTRIB_WPOS];
+ const GLfloat *p1 = v1->attrib[FRAG_ATTRIB_WPOS];
+ const GLfloat *p2 = v2->attrib[FRAG_ATTRIB_WPOS];
const SWvertex *vMin, *vMid, *vMax;
GLint iyMin, iyMax;
GLfloat yMin, yMax;
@@ -56,39 +55,28 @@
#ifdef DO_Z
GLfloat zPlane[4];
#endif
-#ifdef DO_FOG
- GLfloat fogPlane[4];
-#else
- GLfloat *fog = NULL;
-#endif
#ifdef DO_RGBA
GLfloat rPlane[4], gPlane[4], bPlane[4], aPlane[4];
#endif
#ifdef DO_INDEX
GLfloat iPlane[4];
#endif
-#ifdef DO_SPEC
- GLfloat srPlane[4], sgPlane[4], sbPlane[4];
-#endif
-#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];
+#if defined(DO_ATTRIBS)
+ GLfloat attrPlane[FRAG_ATTRIB_MAX][4][4];
+ GLfloat wPlane[4]; /* win[3] */
#endif
GLfloat bf = SWRAST_CONTEXT(ctx)->_BackfaceSign;
(void) swrast;
- INIT_SPAN(span, GL_POLYGON, 0, 0, SPAN_COVERAGE);
+ INIT_SPAN(span, GL_POLYGON);
+ span.arrayMask = SPAN_COVERAGE;
/* determine bottom to top order of vertices */
{
- GLfloat y0 = v0->win[1];
- GLfloat y1 = v1->win[1];
- GLfloat y2 = v2->win[1];
+ GLfloat y0 = v0->attrib[FRAG_ATTRIB_WPOS][1];
+ GLfloat y1 = v1->attrib[FRAG_ATTRIB_WPOS][1];
+ GLfloat y2 = v2->attrib[FRAG_ATTRIB_WPOS][1];
if (y0 <= y1) {
if (y1 <= y2) {
vMin = v0; vMid = v1; vMax = v2; /* y0<=y1<=y2 */
@@ -113,12 +101,12 @@
}
}
- majDx = vMax->win[0] - vMin->win[0];
- majDy = vMax->win[1] - vMin->win[1];
+ majDx = vMax->attrib[FRAG_ATTRIB_WPOS][0] - vMin->attrib[FRAG_ATTRIB_WPOS][0];
+ majDy = vMax->attrib[FRAG_ATTRIB_WPOS][1] - vMin->attrib[FRAG_ATTRIB_WPOS][1];
{
- const GLfloat botDx = vMid->win[0] - vMin->win[0];
- const GLfloat botDy = vMid->win[1] - vMin->win[1];
+ const GLfloat botDx = vMid->attrib[FRAG_ATTRIB_WPOS][0] - vMin->attrib[FRAG_ATTRIB_WPOS][0];
+ const GLfloat botDy = vMid->attrib[FRAG_ATTRIB_WPOS][1] - vMin->attrib[FRAG_ATTRIB_WPOS][1];
const GLfloat area = majDx * botDy - botDx * majDy;
/* Do backface culling */
if (area * bf < 0 || area == 0 || IS_INF_OR_NAN(area))
@@ -135,10 +123,6 @@
compute_plane(p0, p1, p2, p0[2], p1[2], p2[2], zPlane);
span.arrayMask |= SPAN_Z;
#endif
-#ifdef DO_FOG
- compute_plane(p0, p1, p2, v0->fog, v1->fog, v2->fog, fogPlane);
- span.arrayMask |= SPAN_FOG;
-#endif
#ifdef DO_RGBA
if (ctx->Light.ShadeModel == GL_SMOOTH) {
compute_plane(p0, p1, p2, v0->color[RCOMP], v1->color[RCOMP], v2->color[RCOMP], rPlane);
@@ -156,65 +140,43 @@
#endif
#ifdef DO_INDEX
if (ctx->Light.ShadeModel == GL_SMOOTH) {
- compute_plane(p0, p1, p2, (GLfloat) v0->index,
- v1->index, v2->index, iPlane);
+ compute_plane(p0, p1, p2, (GLfloat) v0->attrib[FRAG_ATTRIB_CI][0],
+ v1->attrib[FRAG_ATTRIB_CI][0], v2->attrib[FRAG_ATTRIB_CI][0], iPlane);
}
else {
- constant_plane(v2->index, iPlane);
+ constant_plane(v2->attrib[FRAG_ATTRIB_CI][0], iPlane);
}
span.arrayMask |= SPAN_INDEX;
#endif
-#ifdef DO_SPEC
- if (ctx->Light.ShadeModel == GL_SMOOTH) {
- compute_plane(p0, p1, p2, v0->specular[RCOMP], v1->specular[RCOMP], v2->specular[RCOMP], srPlane);
- compute_plane(p0, p1, p2, v0->specular[GCOMP], v1->specular[GCOMP], v2->specular[GCOMP], sgPlane);
- compute_plane(p0, p1, p2, v0->specular[BCOMP], v1->specular[BCOMP], v2->specular[BCOMP], sbPlane);
- }
- else {
- constant_plane(v2->specular[RCOMP], srPlane);
- constant_plane(v2->specular[GCOMP], sgPlane);
- constant_plane(v2->specular[BCOMP], sbPlane);
- }
- span.arrayMask |= SPAN_SPEC;
-#endif
-#if defined(DO_TEXVAR)
+#if defined(DO_ATTRIBS)
{
- GLuint attr;
- const GLfloat invW0 = v0->win[3];
- const GLfloat invW1 = v1->win[3];
- const GLfloat invW2 = v2->win[3];
- 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;
+ const GLfloat invW0 = v0->attrib[FRAG_ATTRIB_WPOS][3];
+ const GLfloat invW1 = v1->attrib[FRAG_ATTRIB_WPOS][3];
+ const GLfloat invW2 = v2->attrib[FRAG_ATTRIB_WPOS][3];
+ compute_plane(p0, p1, p2, invW0, invW1, invW2, wPlane);
+ span.attrStepX[FRAG_ATTRIB_WPOS][3] = plane_dx(wPlane);
+ span.attrStepY[FRAG_ATTRIB_WPOS][3] = plane_dy(wPlane);
+ ATTRIB_LOOP_BEGIN
+ GLuint c;
+ if (swrast->_InterpMode[attr] == GL_FLAT) {
+ for (c = 0; c < 4; c++) {
+ constant_plane(v2->attrib[attr][c] * invW2, attrPlane[attr][c]);
}
- else {
- texWidth[attr] = texHeight[attr] = 1.0;
+ }
+ else {
+ for (c = 0; c < 4; c++) {
+ const GLfloat a0 = v0->attrib[attr][c] * invW0;
+ const GLfloat a1 = v1->attrib[attr][c] * invW1;
+ const GLfloat a2 = v2->attrib[attr][c] * invW2;
+ compute_plane(p0, p1, p2, a0, a1, a2, attrPlane[attr][c]);
}
}
- }
+ for (c = 0; c < 4; c++) {
+ span.attrStepX[attr][c] = plane_dx(attrPlane[attr][c]);
+ span.attrStepY[attr][c] = plane_dy(attrPlane[attr][c]);
+ }
+ ATTRIB_LOOP_END
}
- span.arrayMask |= (SPAN_TEXTURE | SPAN_LAMBDA | SPAN_VARYING);
#endif
/* Begin bottom-to-top scan over the triangle.
@@ -223,16 +185,16 @@
* edges, stopping when we find that coverage = 0. If the long edge
* is on the left we scan left-to-right. Else, we scan right-to-left.
*/
- yMin = vMin->win[1];
- yMax = vMax->win[1];
+ yMin = vMin->attrib[FRAG_ATTRIB_WPOS][1];
+ yMax = vMax->attrib[FRAG_ATTRIB_WPOS][1];
iyMin = (GLint) yMin;
iyMax = (GLint) yMax + 1;
if (ltor) {
/* scan left to right */
- const GLfloat *pMin = vMin->win;
- const GLfloat *pMid = vMid->win;
- const GLfloat *pMax = vMax->win;
+ const GLfloat *pMin = vMin->attrib[FRAG_ATTRIB_WPOS];
+ const GLfloat *pMid = vMid->attrib[FRAG_ATTRIB_WPOS];
+ const GLfloat *pMax = vMax->attrib[FRAG_ATTRIB_WPOS];
const GLfloat dxdy = majDx / majDy;
const GLfloat xAdj = dxdy < 0.0F ? -dxdy : 0.0F;
GLfloat x = pMin[0] - (yMin - iyMin) * dxdy;
@@ -252,6 +214,18 @@
/* enter interior of triangle */
ix = startX;
+
+#if defined(DO_ATTRIBS)
+ /* compute attributes at left-most fragment */
+ span.attrStart[FRAG_ATTRIB_WPOS][3] = solve_plane(ix + 0.5, iy + 0.5, wPlane);
+ ATTRIB_LOOP_BEGIN
+ GLuint c;
+ for (c = 0; c < 4; c++) {
+ span.attrStart[attr][c] = solve_plane(ix + 0.5, iy + 0.5, attrPlane[attr][c]);
+ }
+ ATTRIB_LOOP_END
+#endif
+
count = 0;
while (coverage > 0.0F) {
/* (cx,cy) = center of fragment */
@@ -265,9 +239,6 @@
#ifdef DO_Z
array->z[count] = (GLuint) solve_plane(cx, cy, zPlane);
#endif
-#ifdef DO_FOG
- 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);
array->rgba[count][GCOMP] = solve_plane_chan(cx, cy, gPlane);
@@ -277,30 +248,6 @@
#ifdef DO_INDEX
array->index[count] = (GLint) solve_plane(cx, cy, iPlane);
#endif
-#ifdef DO_SPEC
- array->spec[count][RCOMP] = solve_plane_chan(cx, cy, srPlane);
- array->spec[count][GCOMP] = solve_plane_chan(cx, cy, sgPlane);
- array->spec[count][BCOMP] = solve_plane_chan(cx, cy, sbPlane);
-#endif
-#if defined(DO_TEXVAR)
- {
- 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]);
- }
- }
- }
- }
-#endif
ix++;
count++;
coverage = compute_coveragef(pMin, pMid, pMax, ix, iy);
@@ -312,7 +259,6 @@
span.x = startX;
span.y = iy;
span.end = (GLuint) ix - (GLuint) startX;
- ASSERT(span.interpMask == 0);
#if defined(DO_RGBA)
_swrast_write_rgba_span(ctx, &span);
#else
@@ -322,9 +268,9 @@
}
else {
/* scan right to left */
- const GLfloat *pMin = vMin->win;
- const GLfloat *pMid = vMid->win;
- const GLfloat *pMax = vMax->win;
+ const GLfloat *pMin = vMin->attrib[FRAG_ATTRIB_WPOS];
+ const GLfloat *pMid = vMid->attrib[FRAG_ATTRIB_WPOS];
+ const GLfloat *pMax = vMax->attrib[FRAG_ATTRIB_WPOS];
const GLfloat dxdy = majDx / majDy;
const GLfloat xAdj = dxdy > 0 ? dxdy : 0.0F;
GLfloat x = pMin[0] - (yMin - iyMin) * dxdy;
@@ -362,9 +308,6 @@
#ifdef DO_Z
array->z[ix] = (GLuint) solve_plane(cx, cy, zPlane);
#endif
-#ifdef DO_FOG
- 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);
array->rgba[ix][GCOMP] = solve_plane_chan(cx, cy, gPlane);
@@ -374,38 +317,22 @@
#ifdef DO_INDEX
array->index[ix] = (GLint) solve_plane(cx, cy, iPlane);
#endif
-#ifdef DO_SPEC
- array->spec[ix][RCOMP] = solve_plane_chan(cx, cy, srPlane);
- array->spec[ix][GCOMP] = solve_plane_chan(cx, cy, sgPlane);
- array->spec[ix][BCOMP] = solve_plane_chan(cx, cy, sbPlane);
-#endif
-#if defined(DO_TEXVAR)
- {
- 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]);
- }
- }
- }
- }
-#endif
ix--;
count++;
coverage = compute_coveragef(pMin, pMax, pMid, ix, iy);
}
+#if defined(DO_ATTRIBS)
+ /* compute attributes at left-most fragment */
+ span.attrStart[FRAG_ATTRIB_WPOS][3] = solve_plane(ix + 1.5, iy + 0.5, wPlane);
+ ATTRIB_LOOP_BEGIN
+ GLuint c;
+ for (c = 0; c < 4; c++) {
+ span.attrStart[attr][c] = solve_plane(ix + 1.5, iy + 0.5, attrPlane[attr][c]);
+ }
+ ATTRIB_LOOP_END
+#endif
+
if (startX <= ix)
continue;
@@ -419,51 +346,22 @@
SWspanarrays *array = span.array;
GLint j;
for (j = 0; j < (GLint) n; j++) {
+ array->coverage[j] = array->coverage[j + left];
#ifdef DO_RGBA
COPY_CHAN4(array->rgba[j], array->rgba[j + left]);
#endif
-#ifdef DO_SPEC
- COPY_CHAN4(array->spec[j], array->spec[j + left]);
-#endif
#ifdef DO_INDEX
array->index[j] = array->index[j + left];
#endif
#ifdef DO_Z
array->z[j] = array->z[j + left];
#endif
-#ifdef DO_FOG
- array->attribs[FRAG_ATTRIB_FOGC][j][0]
- = array->attribs[FRAG_ATTRIB_FOGC][j + left][0];
-#endif
-#if defined(DO_TEXVAR)
- array->lambda[0][j] = array->lambda[0][j + left];
-#endif
- array->coverage[j] = array->coverage[j + left];
}
}
-#ifdef DO_TEXVAR
- /* shift texcoords, varying */
- {
- SWspanarrays *array = span.array;
- 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->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];*/
- }
- }
- }
- }
-#endif
span.x = left;
span.y = iy;
span.end = n;
- ASSERT(span.interpMask == 0);
#if defined(DO_RGBA)
_swrast_write_rgba_span(ctx, &span);
#else
@@ -474,30 +372,8 @@
}
-#ifdef DO_Z
#undef DO_Z
-#endif
-
-#ifdef DO_FOG
-#undef DO_FOG
-#endif
-
-#ifdef DO_RGBA
#undef DO_RGBA
-#endif
-
-#ifdef DO_INDEX
#undef DO_INDEX
-#endif
-
-#ifdef DO_SPEC
-#undef DO_SPEC
-#endif
-
-#ifdef DO_TEXVAR
-#undef DO_TEXVAR
-#endif
-
-#ifdef DO_OCCLUSION_TEST
+#undef DO_ATTRIBS
#undef DO_OCCLUSION_TEST
-#endif
diff --git a/src/mesa/swrast/s_accum.c b/src/mesa/swrast/s_accum.c
index f53e7f52c5..3c45dee399 100644
--- a/src/mesa/swrast/s_accum.c
+++ b/src/mesa/swrast/s_accum.c
@@ -474,7 +474,9 @@ accum_return(GLcontext *ctx, GLfloat value,
SWspan span;
/* init color span */
- INIT_SPAN(span, GL_BITMAP, width, 0, SPAN_RGBA);
+ INIT_SPAN(span, GL_BITMAP);
+ span.end = width;
+ span.arrayMask = SPAN_RGBA;
span.x = xpos;
span.y = ypos + i;
diff --git a/src/mesa/swrast/s_alpha.c b/src/mesa/swrast/s_alpha.c
index af8a6baddc..3c55d3e9e3 100644
--- a/src/mesa/swrast/s_alpha.c
+++ b/src/mesa/swrast/s_alpha.c
@@ -111,13 +111,13 @@ _swrast_alpha_test(const GLcontext *ctx, SWspan *span)
if (span->arrayMask & SPAN_RGBA) {
/* Use array's alpha values */
if (span->array->ChanType == GL_UNSIGNED_BYTE) {
- GLubyte (*rgba)[4] = span->array->color.sz1.rgba;
+ GLubyte (*rgba)[4] = span->array->rgba8;
GLubyte ref;
CLAMPED_FLOAT_TO_UBYTE(ref, ctx->Color.AlphaRef);
ALPHA_TEST(rgba[i][ACOMP], ;);
}
else if (span->array->ChanType == GL_UNSIGNED_SHORT) {
- GLushort (*rgba)[4] = span->array->color.sz2.rgba;
+ GLushort (*rgba)[4] = span->array->rgba16;
GLushort ref;
CLAMPED_FLOAT_TO_USHORT(ref, ctx->Color.AlphaRef);
ALPHA_TEST(rgba[i][ACOMP], ;);
diff --git a/src/mesa/swrast/s_bitmap.c b/src/mesa/swrast/s_bitmap.c
index 59c42e524f..1e7f6c18e6 100644
--- a/src/mesa/swrast/s_bitmap.c
+++ b/src/mesa/swrast/s_bitmap.c
@@ -82,17 +82,10 @@ _swrast_Bitmap( GLcontext *ctx, GLint px, GLint py,
if (SWRAST_CONTEXT(ctx)->NewState)
_swrast_validate_derived( ctx );
- INIT_SPAN(span, GL_BITMAP, width, 0, SPAN_XY);
-
- _swrast_span_default_color(ctx, &span);
- if (ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR)
- _swrast_span_default_secondary_color(ctx, &span);
- if (ctx->Depth.Test)
- _swrast_span_default_z(ctx, &span);
- if (swrast->_FogEnabled)
- _swrast_span_default_fog(ctx, &span);
- if (ctx->Texture._EnabledCoordUnits)
- _swrast_span_default_texcoords(ctx, &span);
+ INIT_SPAN(span, GL_BITMAP);
+ span.end = width;
+ span.arrayMask = SPAN_XY;
+ _swrast_span_default_attribs(ctx, &span);
for (row = 0; row < height; row++) {
const GLubyte *src = (const GLubyte *) _mesa_image_address2d(unpack,
@@ -189,21 +182,16 @@ _swrast_Bitmap( GLcontext *ctx, GLint px, GLint py,
if (SWRAST_CONTEXT(ctx)->NewState)
_swrast_validate_derived( ctx );
- INIT_SPAN(span, GL_BITMAP, width, 0, SPAN_MASK);
+ INIT_SPAN(span, GL_BITMAP);
+ span.end = width;
+ span.arrayMask = SPAN_MASK;
+ _swrast_span_default_attribs(ctx, &span);
/*span.arrayMask |= SPAN_MASK;*/ /* we'll init span.mask[] */
span.x = px;
span.y = py;
/*span.end = width;*/
- _swrast_span_default_color(ctx, &span);
- if (ctx->Depth.Test)
- _swrast_span_default_z(ctx, &span);
- if (swrast->_FogEnabled)
- _swrast_span_default_fog(ctx, &span);
- if (ctx->Texture._EnabledCoordUnits)
- _swrast_span_default_texcoords(ctx, &span);
-
for (row=0; row<height; row++, span.y++) {
const GLubyte *src = (const GLubyte *) _mesa_image_address2d(unpack,
bitmap, width, height, GL_COLOR_INDEX, GL_BITMAP, row, 0);
diff --git a/src/mesa/swrast/s_buffers.c b/src/mesa/swrast/s_buffers.c
index 35f2dd6490..90a56284c5 100644
--- a/src/mesa/swrast/s_buffers.c
+++ b/src/mesa/swrast/s_buffers.c
@@ -55,7 +55,9 @@ clear_rgba_buffer_with_masking(GLcontext *ctx, struct gl_renderbuffer *rb)
/* Initialize color span with clear color */
/* XXX optimize for clearcolor == black/zero (bzero) */
- INIT_SPAN(span, GL_BITMAP, width, 0, SPAN_RGBA);
+ INIT_SPAN(span, GL_BITMAP);
+ span.end = width;
+ span.arrayMask = SPAN_RGBA;
span.array->ChanType = rb->DataType;
if (span.array->ChanType == GL_UNSIGNED_BYTE) {
GLubyte clearColor[4];
@@ -119,7 +121,9 @@ clear_ci_buffer_with_masking(GLcontext *ctx, struct gl_renderbuffer *rb)
ASSERT(rb->DataType == GL_UNSIGNED_INT);
/* Initialize index span with clear index */
- INIT_SPAN(span, GL_BITMAP, width, 0, SPAN_RGBA);
+ INIT_SPAN(span, GL_BITMAP);
+ span.end = width;
+ span.arrayMask = SPAN_INDEX;
for (i = 0; i < width;i++) {
span.array->index[i] = ctx->Color.ClearIndex;
}
diff --git a/src/mesa/swrast/s_context.c b/src/mesa/swrast/s_context.c
index e113adb689..791850cb50 100644
--- a/src/mesa/swrast/s_context.c
+++ b/src/mesa/swrast/s_context.c
@@ -1,6 +1,6 @@
/*
* Mesa 3-D graphics library
- * Version: 6.5.3
+ * Version: 7.1
*
* Copyright (C) 1999-2007 Brian Paul All Rights Reserved.
*
@@ -155,7 +155,7 @@ _swrast_update_polygon( GLcontext *ctx )
/**
* Update the _PreferPixelFog field to indicate if we need to compute
- * fog factors per-fragment.
+ * fog blend factors (from the fog coords) per-fragment.
*/
static void
_swrast_update_fog_hint( GLcontext *ctx )
@@ -189,6 +189,37 @@ _swrast_update_texture_env( GLcontext *ctx )
/**
+ * Determine if we can defer texturing/shading until after Z/stencil
+ * testing. This potentially allows us to skip texturing/shading for
+ * lots of fragments.
+ */
+static void
+_swrast_update_deferred_texture(GLcontext *ctx)
+{
+ SWcontext *swrast = SWRAST_CONTEXT(ctx);
+ if (ctx->Color.AlphaEnabled) {
+ /* alpha test depends on post-texture/shader colors */
+ swrast->_DeferredTexture = GL_FALSE;
+ }
+ else {
+ const struct gl_fragment_program *fprog
+ = ctx->FragmentProgram._Current;
+ if (fprog && (fprog->Base.OutputsWritten & (1 << FRAG_RESULT_DEPR))) {
+ /* Z comes from fragment program/shader */
+ swrast->_DeferredTexture = GL_FALSE;
+ }
+ else if (ctx->Query.CurrentOcclusionObject) {
+ /* occlusion query depends on shader discard/kill results */
+ swrast->_DeferredTexture = GL_FALSE;
+ }
+ else {
+ swrast->_DeferredTexture = GL_TRUE;
+ }
+ }
+}
+
+
+/**
* Update swrast->_FogColor and swrast->_FogEnable values.
*/
static void
@@ -324,7 +355,6 @@ _swrast_validate_line( GLcontext *ctx, const SWvertex *v0, const SWvertex *v1 )
swrast->Line = _swrast_add_spec_terms_line;
}
-
swrast->Line( ctx, v0, v1 );
}
@@ -488,7 +518,7 @@ _swrast_invalidate_state( GLcontext *ctx, GLbitfield new_state )
}
-static void
+void
_swrast_update_texture_samplers(GLcontext *ctx)
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
@@ -505,45 +535,62 @@ _swrast_update_texture_samplers(GLcontext *ctx)
/**
- * Update the swrast->_FragmentAttribs field.
+ * Update swrast->_ActiveAttribs, swrast->_NumActiveAttribs,
+ * swrast->_ActiveAtttribMask.
*/
static void
-_swrast_update_fragment_attribs(GLcontext *ctx)
+_swrast_update_active_attribs(GLcontext *ctx)
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
-
+ GLuint attribsMask;
+
+ /*
+ * Compute _ActiveAttribsMask = which fragment attributes are needed.
+ */
if (ctx->FragmentProgram._Current) {
- swrast->_FragmentAttribs
- = ctx->FragmentProgram._Current->Base.InputsRead;
+ /* fragment program/shader */
+ attribsMask = ctx->FragmentProgram._Current->Base.InputsRead;
+ attribsMask &= ~FRAG_BIT_WPOS; /* WPOS is always handled specially */
+ }
+ else if (ctx->ATIFragmentShader._Enabled) {
+ attribsMask = ~0; /* XXX fix me */
}
else {
- GLuint u;
- swrast->_FragmentAttribs = 0x0;
+ /* fixed function */
+ attribsMask = 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;
+#if CHAN_TYPE == GL_FLOAT
+ attribsMask |= FRAG_BIT_COL0;
+#endif
- for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
- if (ctx->Texture.Unit[u]._ReallyEnabled) {
- swrast->_FragmentAttribs |= FRAG_BIT_TEX(u);
- }
+ if (ctx->Fog.ColorSumEnabled ||
+ (ctx->Light.Enabled &&
+ ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR)) {
+ attribsMask |= FRAG_BIT_COL1;
}
+
+ if (swrast->_FogEnabled)
+ attribsMask |= FRAG_BIT_FOGC;
+
+ attribsMask |= (ctx->Texture._EnabledUnits << FRAG_ATTRIB_TEX0);
}
- /* Find lowest, highest bit set in _FragmentAttribs */
+ swrast->_ActiveAttribMask = attribsMask;
+
+ /* Update _ActiveAttribs[] list */
{
- GLuint bits = swrast->_FragmentAttribs;
- GLuint i = 0;;
- while (bits) {
- i++;
- bits = bits >> 1;
+ GLuint i, num = 0;
+ for (i = 0; i < FRAG_ATTRIB_MAX; i++) {
+ if (attribsMask & (1 << i)) {
+ swrast->_ActiveAttribs[num++] = i;
+ /* how should this attribute be interpolated? */
+ if (i == FRAG_ATTRIB_COL0 || i == FRAG_ATTRIB_COL1)
+ swrast->_InterpMode[i] = ctx->Light.ShadeModel;
+ else
+ swrast->_InterpMode[i] = GL_SMOOTH;
+ }
}
- swrast->_MaxFragmentAttrib = i;
- swrast->_MinFragmentAttrib = FRAG_ATTRIB_TEX0; /* XXX temporary */
+ swrast->_NumActiveAttribs = num;
}
}
@@ -617,20 +664,23 @@ _swrast_validate_derived( GLcontext *ctx )
_NEW_PROGRAM))
_swrast_update_fragment_program( ctx, swrast->NewState );
- if (swrast->NewState & _NEW_TEXTURE)
+ if (swrast->NewState & (_NEW_TEXTURE | _NEW_PROGRAM)) {
_swrast_update_texture_samplers( ctx );
+ _swrast_validate_texture_images(ctx);
+ }
- if (swrast->NewState & (_NEW_TEXTURE | _NEW_PROGRAM))
- _swrast_validate_texture_images( ctx );
+ if (swrast->NewState & (_NEW_COLOR | _NEW_PROGRAM))
+ _swrast_update_deferred_texture(ctx);
if (swrast->NewState & _SWRAST_NEW_RASTERMASK)
_swrast_update_rasterflags( ctx );
if (swrast->NewState & (_NEW_DEPTH |
_NEW_FOG |
+ _NEW_LIGHT |
_NEW_PROGRAM |
_NEW_TEXTURE))
- _swrast_update_fragment_attribs(ctx);
+ _swrast_update_active_attribs(ctx);
if (swrast->NewState & (_NEW_PROGRAM | _NEW_BUFFERS))
_swrast_update_color_outputs(ctx);
@@ -780,14 +830,11 @@ _swrast_CreateContext( GLcontext *ctx )
}
swrast->SpanArrays->ChanType = CHAN_TYPE;
#if CHAN_TYPE == GL_UNSIGNED_BYTE
- swrast->SpanArrays->rgba = swrast->SpanArrays->color.sz1.rgba;
- swrast->SpanArrays->spec = swrast->SpanArrays->color.sz1.spec;
+ swrast->SpanArrays->rgba = swrast->SpanArrays->rgba8;
#elif CHAN_TYPE == GL_UNSIGNED_SHORT
- swrast->SpanArrays->rgba = swrast->SpanArrays->color.sz2.rgba;
- swrast->SpanArrays->spec = swrast->SpanArrays->color.sz2.spec;
+ swrast->SpanArrays->rgba = swrast->SpanArrays->rgba16;
#else
swrast->SpanArrays->rgba = swrast->SpanArrays->attribs[FRAG_ATTRIB_COL0];
- swrast->SpanArrays->spec = swrast->SpanArrays->attribs[FRAG_ATTRIB_COL1];
#endif
/* init point span buffer */
@@ -889,7 +936,10 @@ _swrast_print_vertex( GLcontext *ctx, const SWvertex *v )
if (SWRAST_DEBUG_VERTICES) {
_mesa_debug(ctx, "win %f %f %f %f\n",
- v->win[0], v->win[1], v->win[2], v->win[3]);
+ v->attrib[FRAG_ATTRIB_WPOS][0],
+ v->attrib[FRAG_ATTRIB_WPOS][1],
+ v->attrib[FRAG_ATTRIB_WPOS][2],
+ v->attrib[FRAG_ATTRIB_WPOS][3]);
for (i = 0 ; i < ctx->Const.MaxTextureCoordUnits ; i++)
if (ctx->Texture.Unit[i]._ReallyEnabled)
@@ -902,18 +952,17 @@ _swrast_print_vertex( GLcontext *ctx, const SWvertex *v )
#if CHAN_TYPE == GL_FLOAT
_mesa_debug(ctx, "color %f %f %f %f\n",
v->color[0], v->color[1], v->color[2], v->color[3]);
- _mesa_debug(ctx, "spec %f %f %f %f\n",
- v->specular[0], v->specular[1],
- v->specular[2], v->specular[3]);
#else
_mesa_debug(ctx, "color %d %d %d %d\n",
v->color[0], v->color[1], v->color[2], v->color[3]);
- _mesa_debug(ctx, "spec %d %d %d %d\n",
- v->specular[0], v->specular[1],
- v->specular[2], v->specular[3]);
#endif
- _mesa_debug(ctx, "fog %f\n", v->fog);
- _mesa_debug(ctx, "index %d\n", v->index);
+ _mesa_debug(ctx, "spec %g %g %g %g\n",
+ v->attrib[FRAG_ATTRIB_COL1][0],
+ v->attrib[FRAG_ATTRIB_COL1][1],
+ v->attrib[FRAG_ATTRIB_COL1][2],
+ v->attrib[FRAG_ATTRIB_COL1][3]);
+ _mesa_debug(ctx, "fog %f\n", v->attrib[FRAG_ATTRIB_FOGC][0]);
+ _mesa_debug(ctx, "index %d\n", v->attrib[FRAG_ATTRIB_CI][0]);
_mesa_debug(ctx, "pointsize %f\n", v->pointSize);
_mesa_debug(ctx, "\n");
}
diff --git a/src/mesa/swrast/s_context.h b/src/mesa/swrast/s_context.h
index 3a9a48922e..f118eb92ca 100644
--- a/src/mesa/swrast/s_context.h
+++ b/src/mesa/swrast/s_context.h
@@ -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"),
@@ -46,6 +46,7 @@
#include "mtypes.h"
#include "swrast.h"
#include "s_span.h"
+#include "prog_execute.h"
typedef void (*texture_sample_func)(GLcontext *ctx,
@@ -131,18 +132,21 @@ typedef struct
GLboolean _PreferPixelFog; /* Compute fog blend factor per fragment? */
GLboolean _AnyTextureCombine;
GLboolean _FogEnabled;
+ GLboolean _DeferredTexture;
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 */
+ /** List/array of the fragment attributes to interpolate */
+ GLuint _ActiveAttribs[FRAG_ATTRIB_MAX];
+ /** Same info, but as a bitmask */
+ GLbitfield _ActiveAttribMask;
+ /** Number of fragment attributes to interpolate */
+ GLuint _NumActiveAttribs;
+ /** Indicates how each attrib is to be interpolated (lines/tris) */
+ GLenum _InterpMode[FRAG_ATTRIB_MAX]; /* GL_FLAT or GL_SMOOTH (for now) */
/* Accum buffer temporaries.
*/
@@ -222,12 +226,18 @@ typedef struct
validate_texture_image_func ValidateTextureImage;
+ /** State used during execution of fragment programs */
+ struct gl_program_machine FragProgMachine;
+
} SWcontext;
extern void
_swrast_validate_derived( GLcontext *ctx );
+extern void
+_swrast_update_texture_samplers(GLcontext *ctx);
+
#define SWRAST_CONTEXT(ctx) ((SWcontext *)ctx->swrast_context)
@@ -270,4 +280,19 @@ _swrast_validate_derived( GLcontext *ctx );
#define FixedToChan(X) FixedToInt(X)
#endif
+
+/**
+ * For looping over fragment attributes in the pointe, line
+ * triangle rasterizers.
+ */
+#define ATTRIB_LOOP_BEGIN \
+ { \
+ GLuint a; \
+ for (a = 0; a < swrast->_NumActiveAttribs; a++) { \
+ const GLuint attr = swrast->_ActiveAttribs[a];
+
+#define ATTRIB_LOOP_END } }
+
+
+
#endif
diff --git a/src/mesa/swrast/s_copypix.c b/src/mesa/swrast/s_copypix.c
index dbbfc58c6f..bbe1081860 100644
--- a/src/mesa/swrast/s_copypix.c
+++ b/src/mesa/swrast/s_copypix.c
@@ -94,7 +94,6 @@ static void
copy_conv_rgba_pixels(GLcontext *ctx, GLint srcx, GLint srcy,
GLint width, GLint height, GLint destx, GLint desty)
{
- SWcontext *swrast = SWRAST_CONTEXT(ctx);
GLint row;
const GLboolean zoom = ctx->Pixel.ZoomX != 1.0F || ctx->Pixel.ZoomY != 1.0F;
const GLbitfield transferOps = ctx->_ImageTransferState;
@@ -103,14 +102,10 @@ copy_conv_rgba_pixels(GLcontext *ctx, GLint srcx, GLint srcy,
GLfloat *dest, *tmpImage, *convImage;
SWspan span;
- INIT_SPAN(span, GL_BITMAP, 0, 0, SPAN_RGBA);
-
- if (ctx->Depth.Test)
- _swrast_span_default_z(ctx, &span);
- if (swrast->_FogEnabled)
- _swrast_span_default_fog(ctx, &span);
- if (ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR)
- _swrast_span_default_secondary_color(ctx, &span);
+ INIT_SPAN(span, GL_BITMAP);
+ _swrast_span_default_attribs(ctx, &span);
+ span.arrayMask = SPAN_RGBA;
+ span.arrayAttribs = FRAG_BIT_COL0;
/* allocate space for GLfloat image */
tmpImage = (GLfloat *) _mesa_malloc(width * height * 4 * sizeof(GLfloat));
@@ -163,7 +158,7 @@ copy_conv_rgba_pixels(GLcontext *ctx, GLint srcx, GLint srcy,
/* write the new image */
for (row = 0; row < height; row++) {
const GLfloat *src = convImage + row * width * 4;
- GLvoid *rgba = (GLvoid *) span.array->attribs[FRAG_ATTRIB_COL0];
+ GLfloat *rgba = (GLfloat *) span.array->attribs[FRAG_ATTRIB_COL0];
/* copy convolved colors into span array */
_mesa_memcpy(rgba, src, width * 4 * sizeof(GLfloat));
@@ -195,7 +190,6 @@ static void
copy_rgba_pixels(GLcontext *ctx, GLint srcx, GLint srcy,
GLint width, GLint height, GLint destx, GLint desty)
{
- SWcontext *swrast = SWRAST_CONTEXT(ctx);
GLfloat *tmpImage, *p;
GLint sy, dy, stepy, row;
const GLboolean zoom = ctx->Pixel.ZoomX != 1.0F || ctx->Pixel.ZoomY != 1.0F;
@@ -240,13 +234,10 @@ copy_rgba_pixels(GLcontext *ctx, GLint srcx, GLint srcy,
stepy = 1;
}
- INIT_SPAN(span, GL_BITMAP, 0, 0, SPAN_RGBA);
- if (ctx->Depth.Test)
- _swrast_span_default_z(ctx, &span);
- if (swrast->_FogEnabled)
- _swrast_span_default_fog(ctx, &span);
- if (ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR)
- _swrast_span_default_secondary_color(ctx, &span);
+ INIT_SPAN(span, GL_BITMAP);
+ _swrast_span_default_attribs(ctx, &span);
+ span.arrayMask = SPAN_RGBA;
+ span.arrayAttribs = FRAG_BIT_COL0; /* we'll fill in COL0 attrib values */
if (overlapping) {
tmpImage = (GLfloat *) _mesa_malloc(width * height * sizeof(GLfloat) * 4);
@@ -315,7 +306,6 @@ copy_ci_pixels( GLcontext *ctx, GLint srcx, GLint srcy,
GLint width, GLint height,
GLint destx, GLint desty )
{
- SWcontext *swrast = SWRAST_CONTEXT(ctx);
GLuint *tmpImage,*p;
GLint sy, dy, stepy;
GLint j;
@@ -328,7 +318,9 @@ copy_ci_pixels( GLcontext *ctx, GLint srcx, GLint srcy,
return;
}
- INIT_SPAN(span, GL_BITMAP, 0, 0, SPAN_INDEX);
+ INIT_SPAN(span, GL_BITMAP);
+ _swrast_span_default_attribs(ctx, &span);
+ span.arrayMask = SPAN_INDEX;
if (ctx->DrawBuffer == ctx->ReadBuffer) {
overlapping = regions_overlap(srcx, srcy, destx, desty, width, height,
@@ -352,11 +344,6 @@ copy_ci_pixels( GLcontext *ctx, GLint srcx, GLint srcy,
stepy = 1;
}
- if (ctx->Depth.Test)
- _swrast_span_default_z(ctx, &span);
- if (swrast->_FogEnabled)
- _swrast_span_default_fog(ctx, &span);
-
if (overlapping) {
GLint ssy = sy;
tmpImage = (GLuint *) _mesa_malloc(width * height * sizeof(GLuint));
@@ -452,7 +439,6 @@ copy_depth_pixels( GLcontext *ctx, GLint srcx, GLint srcy,
GLint width, GLint height,
GLint destx, GLint desty )
{
- SWcontext *swrast = SWRAST_CONTEXT(ctx);
struct gl_framebuffer *fb = ctx->ReadBuffer;
struct gl_renderbuffer *readRb = fb->_DepthBuffer;
GLfloat *p, *tmpImage;
@@ -467,7 +453,9 @@ copy_depth_pixels( GLcontext *ctx, GLint srcx, GLint srcy,
return;
}
- INIT_SPAN(span, GL_BITMAP, 0, 0, SPAN_Z);
+ INIT_SPAN(span, GL_BITMAP);
+ _swrast_span_default_attribs(ctx, &span);
+ span.arrayMask = SPAN_Z;
if (ctx->DrawBuffer == ctx->ReadBuffer) {
overlapping = regions_overlap(srcx, srcy, destx, desty, width, height,
@@ -491,12 +479,6 @@ copy_depth_pixels( GLcontext *ctx, GLint srcx, GLint srcy,
stepy = 1;
}
- _swrast_span_default_color(ctx, &span);
- if (ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR)
- _swrast_span_default_secondary_color(ctx, &span);
- if (swrast->_FogEnabled)
- _swrast_span_default_fog(ctx, &span);
-
if (overlapping) {
GLint ssy = sy;
tmpImage = (GLfloat *) _mesa_malloc(width * height * sizeof(GLfloat));
diff --git a/src/mesa/swrast/s_depth.c b/src/mesa/swrast/s_depth.c
index dde2b1db83..408174c990 100644
--- a/src/mesa/swrast/s_depth.c
+++ b/src/mesa/swrast/s_depth.c
@@ -1350,7 +1350,7 @@ _swrast_clear_depth_buffer( GLcontext *ctx, struct gl_renderbuffer *rb )
GLuint clearValue;
GLint x, y, width, height;
- if (!rb || !ctx->Depth.Mask || !rb->Data) {
+ if (!rb || !ctx->Depth.Mask) {
/* no depth buffer, or writing to it is disabled */
return;
}
diff --git a/src/mesa/swrast/s_drawpix.c b/src/mesa/swrast/s_drawpix.c
index 70b57b917c..1c9f64b275 100644
--- a/src/mesa/swrast/s_drawpix.c
+++ b/src/mesa/swrast/s_drawpix.c
@@ -1,8 +1,8 @@
/*
* Mesa 3-D graphics library
- * Version: 6.5.2
+ * Version: 7.1
*
- * 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"),
@@ -70,15 +70,10 @@ fast_draw_rgba_pixels(GLcontext *ctx, GLint x, GLint y,
return GL_FALSE;
}
- INIT_SPAN(span, GL_BITMAP, 0, 0, SPAN_RGBA);
- if (ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR)
- _swrast_span_default_secondary_color(ctx, &span);
- if (ctx->Depth.Test)
- _swrast_span_default_z(ctx, &span);
- if (swrast->_FogEnabled)
- _swrast_span_default_fog(ctx, &span);
- if (ctx->Texture._EnabledCoordUnits)
- _swrast_span_default_texcoords(ctx, &span);
+ INIT_SPAN(span, GL_BITMAP);
+ span.arrayMask = SPAN_RGBA;
+ span.arrayAttribs = FRAG_BIT_COL0;
+ _swrast_span_default_attribs(ctx, &span);
/* copy input params since clipping may change them */
unpack = *userUnpack;
@@ -275,9 +270,9 @@ fast_draw_rgba_pixels(GLcontext *ctx, GLint x, GLint y,
for (row = 0; row < drawHeight; row++) {
ASSERT(drawWidth <= MAX_WIDTH);
_mesa_map_ci8_to_rgba8(ctx, drawWidth, src,
- span.array->color.sz1.rgba);
+ span.array->rgba8);
rb->PutRow(ctx, rb, drawWidth, destX, destY,
- span.array->color.sz1.rgba, NULL);
+ span.array->rgba8, NULL);
src += unpack.RowLength;
destY += yStep;
}
@@ -288,12 +283,12 @@ fast_draw_rgba_pixels(GLcontext *ctx, GLint x, GLint y,
for (row = 0; row < drawHeight; row++) {
ASSERT(drawWidth <= MAX_WIDTH);
_mesa_map_ci8_to_rgba8(ctx, drawWidth, src,
- span.array->color.sz1.rgba);
+ span.array->rgba8);
span.x = destX;
span.y = destY;
span.end = drawWidth;
_swrast_write_zoomed_rgba_span(ctx, imgX, imgY, &span,
- span.array->color.sz1.rgba);
+ span.array->rgba8);
src += unpack.RowLength;
destY++;
}
@@ -334,18 +329,14 @@ draw_index_pixels( GLcontext *ctx, GLint x, GLint y,
const struct gl_pixelstore_attrib *unpack,
const GLvoid *pixels )
{
- SWcontext *swrast = SWRAST_CONTEXT(ctx);
const GLint imgX = x, imgY = y;
const GLboolean zoom = ctx->Pixel.ZoomX!=1.0 || ctx->Pixel.ZoomY!=1.0;
GLint row, skipPixels;
SWspan span;
- INIT_SPAN(span, GL_BITMAP, 0, 0, SPAN_INDEX);
-
- if (ctx->Depth.Test)
- _swrast_span_default_z(ctx, &span);
- if (swrast->_FogEnabled)
- _swrast_span_default_fog(ctx, &span);
+ INIT_SPAN(span, GL_BITMAP);
+ span.arrayMask = SPAN_INDEX;
+ _swrast_span_default_attribs(ctx, &span);
/*
* General solution
@@ -407,10 +398,9 @@ draw_stencil_pixels( GLcontext *ctx, GLint x, GLint y,
width, height,
GL_COLOR_INDEX, type,
row, skipPixels);
- _mesa_unpack_index_span(ctx, spanWidth, destType, values,
- type, source, unpack,
- ctx->_ImageTransferState);
- _mesa_apply_stencil_transfer_ops(ctx, spanWidth, values);
+ _mesa_unpack_stencil_span(ctx, spanWidth, destType, values,
+ type, source, unpack,
+ ctx->_ImageTransferState);
if (zoom) {
_swrast_write_zoomed_stencil_span(ctx, x, y, spanWidth,
spanX, spanY, values);
@@ -434,21 +424,14 @@ draw_depth_pixels( GLcontext *ctx, GLint x, GLint y,
const struct gl_pixelstore_attrib *unpack,
const GLvoid *pixels )
{
- SWcontext *swrast = SWRAST_CONTEXT(ctx);
const GLboolean scaleOrBias
= ctx->Pixel.DepthScale != 1.0 || ctx->Pixel.DepthBias != 0.0;
const GLboolean zoom = ctx->Pixel.ZoomX != 1.0 || ctx->Pixel.ZoomY != 1.0;
SWspan span;
- INIT_SPAN(span, GL_BITMAP, 0, 0, SPAN_Z);
-
- _swrast_span_default_color(ctx, &span);
- if (ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR)
- _swrast_span_default_secondary_color(ctx, &span);
- if (swrast->_FogEnabled)
- _swrast_span_default_fog(ctx, &span);
- if (ctx->Texture._EnabledCoordUnits)
- _swrast_span_default_texcoords(ctx, &span);
+ INIT_SPAN(span, GL_BITMAP);
+ span.arrayMask = SPAN_Z;
+ _swrast_span_default_attribs(ctx, &span);
if (type == GL_UNSIGNED_SHORT
&& ctx->DrawBuffer->Visual.depthBits == 16
@@ -552,7 +535,6 @@ draw_rgba_pixels( GLcontext *ctx, GLint x, GLint y,
const struct gl_pixelstore_attrib *unpack,
const GLvoid *pixels )
{
- SWcontext *swrast = SWRAST_CONTEXT(ctx);
const GLint imgX = x, imgY = y;
const GLboolean zoom = ctx->Pixel.ZoomX!=1.0 || ctx->Pixel.ZoomY!=1.0;
GLfloat *convImage = NULL;
@@ -561,18 +543,14 @@ draw_rgba_pixels( GLcontext *ctx, GLint x, GLint y,
/* Try an optimized glDrawPixels first */
if (fast_draw_rgba_pixels(ctx, x, y, width, height, format, type,
- unpack, pixels))
+ unpack, pixels)) {
return;
+ }
- INIT_SPAN(span, GL_BITMAP, 0, 0, SPAN_RGBA);
- if (ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR)
- _swrast_span_default_secondary_color(ctx, &span);
- if (ctx->Depth.Test)
- _swrast_span_default_z(ctx, &span);
- if (swrast->_FogEnabled)
- _swrast_span_default_fog(ctx, &span);
- if (ctx->Texture._EnabledCoordUnits)
- _swrast_span_default_texcoords(ctx, &span);
+ INIT_SPAN(span, GL_BITMAP);
+ _swrast_span_default_attribs(ctx, &span);
+ span.arrayMask = SPAN_RGBA;
+ span.arrayAttribs = FRAG_BIT_COL0; /* we're fill in COL0 attrib values */
if (ctx->Pixel.Convolution2DEnabled || ctx->Pixel.Separable2DEnabled) {
/* Convolution has to be handled specially. We'll create an
diff --git a/src/mesa/swrast/s_feedback.c b/src/mesa/swrast/s_feedback.c
index 5d3fbdfeb6..07b7409ab5 100644
--- a/src/mesa/swrast/s_feedback.c
+++ b/src/mesa/swrast/s_feedback.c
@@ -1,8 +1,8 @@
/*
* Mesa 3-D graphics library
- * Version: 6.3
+ * Version: 7.0
*
- * 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"),
@@ -34,127 +34,107 @@
#include "s_triangle.h"
-#define FB_3D 0x01
-#define FB_4D 0x02
-#define FB_INDEX 0x04
-#define FB_COLOR 0x08
-#define FB_TEXTURE 0X10
-
-
-
-static void feedback_vertex( GLcontext *ctx,
- const SWvertex *v, const SWvertex *pv )
+static void
+feedback_vertex(GLcontext * ctx, const SWvertex * v, const SWvertex * pv)
{
GLfloat win[4];
- GLfloat color[4];
- GLfloat tc[4];
const GLfloat *vtc = v->attrib[FRAG_ATTRIB_TEX0];
+ const GLfloat *color = v->attrib[FRAG_ATTRIB_COL0];
- win[0] = v->win[0];
- win[1] = v->win[1];
- win[2] = v->win[2] / ctx->DrawBuffer->_DepthMaxF;
- win[3] = 1.0F / v->win[3];
-
- color[0] = CHAN_TO_FLOAT(pv->color[0]);
- color[1] = CHAN_TO_FLOAT(pv->color[1]);
- color[2] = CHAN_TO_FLOAT(pv->color[2]);
- color[3] = CHAN_TO_FLOAT(pv->color[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, vtc);
- }
+ win[0] = v->attrib[FRAG_ATTRIB_WPOS][0];
+ win[1] = v->attrib[FRAG_ATTRIB_WPOS][1];
+ win[2] = v->attrib[FRAG_ATTRIB_WPOS][2] / ctx->DrawBuffer->_DepthMaxF;
+ win[3] = 1.0F / v->attrib[FRAG_ATTRIB_WPOS][3];
- _mesa_feedback_vertex( ctx, win, color, (GLfloat) v->index, tc );
+ _mesa_feedback_vertex(ctx, win, color, v->attrib[FRAG_ATTRIB_CI][0], vtc);
}
/*
* Put triangle in feedback buffer.
*/
-void _swrast_feedback_triangle( GLcontext *ctx,
- const SWvertex *v0,
- const SWvertex *v1,
- const SWvertex *v2)
+void
+_swrast_feedback_triangle(GLcontext *ctx, const SWvertex *v0,
+ const SWvertex *v1, const SWvertex *v2)
{
- if (_swrast_culltriangle( ctx, v0, v1, v2 )) {
- FEEDBACK_TOKEN( ctx, (GLfloat) (GLint) GL_POLYGON_TOKEN );
- FEEDBACK_TOKEN( ctx, (GLfloat) 3 ); /* three vertices */
+ if (_swrast_culltriangle(ctx, v0, v1, v2)) {
+ FEEDBACK_TOKEN(ctx, (GLfloat) (GLint) GL_POLYGON_TOKEN);
+ FEEDBACK_TOKEN(ctx, (GLfloat) 3); /* three vertices */
if (ctx->Light.ShadeModel == GL_SMOOTH) {
- feedback_vertex( ctx, v0, v0 );
- feedback_vertex( ctx, v1, v1 );
- feedback_vertex( ctx, v2, v2 );
- } else {
- feedback_vertex( ctx, v0, v2 );
- feedback_vertex( ctx, v1, v2 );
- feedback_vertex( ctx, v2, v2 );
+ feedback_vertex(ctx, v0, v0);
+ feedback_vertex(ctx, v1, v1);
+ feedback_vertex(ctx, v2, v2);
+ }
+ else {
+ feedback_vertex(ctx, v0, v2);
+ feedback_vertex(ctx, v1, v2);
+ feedback_vertex(ctx, v2, v2);
}
}
}
-void _swrast_feedback_line( GLcontext *ctx, const SWvertex *v0, const SWvertex *v1 )
+void
+_swrast_feedback_line(GLcontext *ctx, const SWvertex *v0,
+ const SWvertex *v1)
{
GLenum token = GL_LINE_TOKEN;
SWcontext *swrast = SWRAST_CONTEXT(ctx);
- if (swrast->StippleCounter==0)
+ if (swrast->StippleCounter == 0)
token = GL_LINE_RESET_TOKEN;
- FEEDBACK_TOKEN( ctx, (GLfloat) (GLint) token );
+ FEEDBACK_TOKEN(ctx, (GLfloat) (GLint) token);
if (ctx->Light.ShadeModel == GL_SMOOTH) {
- feedback_vertex( ctx, v0, v0 );
- feedback_vertex( ctx, v1, v1 );
- } else {
- feedback_vertex( ctx, v0, v1 );
- feedback_vertex( ctx, v1, v1 );
+ feedback_vertex(ctx, v0, v0);
+ feedback_vertex(ctx, v1, v1);
+ }
+ else {
+ feedback_vertex(ctx, v0, v1);
+ feedback_vertex(ctx, v1, v1);
}
swrast->StippleCounter++;
}
-void _swrast_feedback_point( GLcontext *ctx, const SWvertex *v )
+void
+_swrast_feedback_point(GLcontext *ctx, const SWvertex *v)
{
- FEEDBACK_TOKEN( ctx, (GLfloat) (GLint) GL_POINT_TOKEN );
- feedback_vertex( ctx, v, v );
+ FEEDBACK_TOKEN(ctx, (GLfloat) (GLint) GL_POINT_TOKEN);
+ feedback_vertex(ctx, v, v);
}
-void _swrast_select_triangle( GLcontext *ctx,
- const SWvertex *v0,
- const SWvertex *v1,
- const SWvertex *v2)
+void
+_swrast_select_triangle(GLcontext *ctx, const SWvertex *v0,
+ const SWvertex *v1, const SWvertex *v2)
{
- if (_swrast_culltriangle( ctx, v0, v1, v2 )) {
+ if (_swrast_culltriangle(ctx, v0, v1, v2)) {
const GLfloat zs = 1.0F / ctx->DrawBuffer->_DepthMaxF;
- _mesa_update_hitflag( ctx, v0->win[2] * zs );
- _mesa_update_hitflag( ctx, v1->win[2] * zs );
- _mesa_update_hitflag( ctx, v2->win[2] * zs );
+ _mesa_update_hitflag( ctx, v0->attrib[FRAG_ATTRIB_WPOS][2] * zs );
+ _mesa_update_hitflag( ctx, v1->attrib[FRAG_ATTRIB_WPOS][2] * zs );
+ _mesa_update_hitflag( ctx, v2->attrib[FRAG_ATTRIB_WPOS][2] * zs );
}
}
-void _swrast_select_line( GLcontext *ctx, const SWvertex *v0, const SWvertex *v1 )
+void
+_swrast_select_line(GLcontext *ctx, const SWvertex *v0, const SWvertex *v1)
{
const GLfloat zs = 1.0F / ctx->DrawBuffer->_DepthMaxF;
- _mesa_update_hitflag( ctx, v0->win[2] * zs );
- _mesa_update_hitflag( ctx, v1->win[2] * zs );
+ _mesa_update_hitflag( ctx, v0->attrib[FRAG_ATTRIB_WPOS][2] * zs );
+ _mesa_update_hitflag( ctx, v1->attrib[FRAG_ATTRIB_WPOS][2] * zs );
}
-void _swrast_select_point( GLcontext *ctx, const SWvertex *v )
+void
+_swrast_select_point(GLcontext *ctx, const SWvertex *v)
{
const GLfloat zs = 1.0F / ctx->DrawBuffer->_DepthMaxF;
- _mesa_update_hitflag( ctx, v->win[2] * zs );
+ _mesa_update_hitflag( ctx, v->attrib[FRAG_ATTRIB_WPOS][2] * zs );
}
diff --git a/src/mesa/swrast/s_fog.c b/src/mesa/swrast/s_fog.c
index 433fc4a4d0..ed47964a66 100644
--- a/src/mesa/swrast/s_fog.c
+++ b/src/mesa/swrast/s_fog.c
@@ -65,30 +65,92 @@ _swrast_z_to_fogfactor(GLcontext *ctx, GLfloat z)
}
+#define LINEAR_FOG(f, coord) f = (fogEnd - coord) * fogScale
+
+#define EXP_FOG(f, coord) f = EXPF(density * coord)
+
+#define EXP2_FOG(f, coord) \
+do { \
+ GLfloat tmp = negDensitySquared * coord * coord; \
+ if (tmp < FLT_MIN_10_EXP) \
+ tmp = FLT_MIN_10_EXP; \
+ f = EXPF(tmp); \
+ } while(0)
+
+
+#define BLEND_FOG(f, coord) f = coord
+
+
+
/**
* Template code for computing fog blend factor and applying it to colors.
* \param TYPE either GLubyte, GLushort or GLfloat.
* \param COMPUTE_F code to compute the fog blend factor, f.
*/
-#define FOG_LOOP(TYPE, COMPUTE_F) \
-do { \
- 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; \
- COMPUTE_F; \
- f = CLAMP(f, 0.0F, 1.0F); \
- oneMinusF = 1.0F - f; \
- rgba[i][RCOMP] = (TYPE) (f * rgba[i][RCOMP] + oneMinusF * rFog); \
- rgba[i][GCOMP] = (TYPE) (f * rgba[i][GCOMP] + oneMinusF * gFog); \
- rgba[i][BCOMP] = (TYPE) (f * rgba[i][BCOMP] + oneMinusF * bFog); \
- fogCoord += fogStep; \
- w += wStep; \
- } \
-} while (0)
+#define FOG_LOOP(TYPE, FOG_FUNC) \
+if (span->arrayAttribs & FRAG_BIT_FOGC) { \
+ GLuint i; \
+ for (i = 0; i < span->end; i++) { \
+ const GLfloat fogCoord = span->array->attribs[FRAG_ATTRIB_FOGC][i][0]; \
+ const GLfloat c = FABSF(fogCoord); \
+ GLfloat f, oneMinusF; \
+ FOG_FUNC(f, c); \
+ f = CLAMP(f, 0.0F, 1.0F); \
+ oneMinusF = 1.0F - f; \
+ rgba[i][RCOMP] = (TYPE) (f * rgba[i][RCOMP] + oneMinusF * rFog); \
+ rgba[i][GCOMP] = (TYPE) (f * rgba[i][GCOMP] + oneMinusF * gFog); \
+ rgba[i][BCOMP] = (TYPE) (f * rgba[i][BCOMP] + oneMinusF * bFog); \
+ } \
+} \
+else { \
+ const GLfloat fogStep = span->attrStepX[FRAG_ATTRIB_FOGC][0]; \
+ GLfloat fogCoord = span->attrStart[FRAG_ATTRIB_FOGC][0]; \
+ const GLfloat wStep = span->attrStepX[FRAG_ATTRIB_WPOS][3]; \
+ GLfloat w = span->attrStart[FRAG_ATTRIB_WPOS][3]; \
+ GLuint i; \
+ for (i = 0; i < span->end; i++) { \
+ const GLfloat c = FABSF(fogCoord) / w; \
+ GLfloat f, oneMinusF; \
+ FOG_FUNC(f, c); \
+ f = CLAMP(f, 0.0F, 1.0F); \
+ oneMinusF = 1.0F - f; \
+ rgba[i][RCOMP] = (TYPE) (f * rgba[i][RCOMP] + oneMinusF * rFog); \
+ rgba[i][GCOMP] = (TYPE) (f * rgba[i][GCOMP] + oneMinusF * gFog); \
+ rgba[i][BCOMP] = (TYPE) (f * rgba[i][BCOMP] + oneMinusF * bFog); \
+ fogCoord += fogStep; \
+ w += wStep; \
+ } \
+}
+
+/* As above, but CI mode (XXX try to merge someday) */
+#define FOG_LOOP_CI(FOG_FUNC) \
+if (span->arrayAttribs & FRAG_BIT_FOGC) { \
+ GLuint i; \
+ for (i = 0; i < span->end; i++) { \
+ const GLfloat fogCoord = span->array->attribs[FRAG_ATTRIB_FOGC][i][0]; \
+ const GLfloat c = FABSF(fogCoord); \
+ GLfloat f; \
+ FOG_FUNC(f, c); \
+ f = CLAMP(f, 0.0F, 1.0F); \
+ index[i] = (GLuint) ((GLfloat) index[i] + (1.0F - f) * fogIndex); \
+ } \
+} \
+else { \
+ const GLfloat fogStep = span->attrStepX[FRAG_ATTRIB_FOGC][0]; \
+ GLfloat fogCoord = span->attrStart[FRAG_ATTRIB_FOGC][0]; \
+ const GLfloat wStep = span->attrStepX[FRAG_ATTRIB_WPOS][3]; \
+ GLfloat w = span->attrStart[FRAG_ATTRIB_WPOS][3]; \
+ GLuint i; \
+ for (i = 0; i < span->end; i++) { \
+ const GLfloat c = FABSF(fogCoord) / w; \
+ GLfloat f; \
+ FOG_FUNC(f, c); \
+ f = CLAMP(f, 0.0F, 1.0F); \
+ index[i] = (GLuint) ((GLfloat) index[i] + (1.0F - f) * fogIndex); \
+ fogCoord += fogStep; \
+ w += wStep; \
+ } \
+}
@@ -104,12 +166,12 @@ _swrast_fog_rgba_span( const GLcontext *ctx, SWspan *span )
{
const SWcontext *swrast = SWRAST_CONTEXT(ctx);
GLfloat rFog, gFog, bFog;
- const GLuint haveW = (span->interpMask & SPAN_W);
ASSERT(swrast->_FogEnabled);
- ASSERT((span->interpMask | span->arrayMask) & SPAN_FOG);
+ ASSERT(swrast->_ActiveAttribMask & FRAG_BIT_FOGC);
ASSERT(span->arrayMask & SPAN_RGBA);
+ /* compute (scaled) fog color */
if (span->array->ChanType == GL_UNSIGNED_BYTE) {
rFog = ctx->Fog.Color[RCOMP] * 255.0;
gFog = ctx->Fog.Color[GCOMP] * 255.0;
@@ -126,79 +188,68 @@ _swrast_fog_rgba_span( const GLcontext *ctx, SWspan *span )
bFog = ctx->Fog.Color[BCOMP];
}
-
- /* NOTE: if haveW is true, that means the fog start/step values are
- * perspective-corrected and we have to divide each fog coord by W.
- */
-
- /* we need to compute fog blend factors */
if (swrast->_PreferPixelFog) {
/* The span's fog values are fog coordinates, now compute blend factors
* and blend the fragment colors with the fog color.
*/
- 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 density = -ctx->Fog.Density;
- const GLfloat negDensitySquared = -ctx->Fog.Density * ctx->Fog.Density;
-
switch (swrast->_FogMode) {
case GL_LINEAR:
-#define COMPUTE_F f = (fogEnd - FABSF(fogCoord) / w) * fogScale;
- if (span->array->ChanType == GL_UNSIGNED_BYTE) {
- GLubyte (*rgba)[4] = span->array->color.sz1.rgba;
- FOG_LOOP(GLubyte, COMPUTE_F);
- }
- else if (span->array->ChanType == GL_UNSIGNED_SHORT) {
- GLushort (*rgba)[4] = span->array->color.sz2.rgba;
- FOG_LOOP(GLushort, COMPUTE_F);
- }
- else {
- GLfloat (*rgba)[4] = span->array->attribs[FRAG_ATTRIB_COL0];
- ASSERT(span->array->ChanType == GL_FLOAT);
- FOG_LOOP(GLfloat, COMPUTE_F);
+ {
+ 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);
+ if (span->array->ChanType == GL_UNSIGNED_BYTE) {
+ GLubyte (*rgba)[4] = span->array->rgba8;
+ FOG_LOOP(GLubyte, LINEAR_FOG);
+ }
+ else if (span->array->ChanType == GL_UNSIGNED_SHORT) {
+ GLushort (*rgba)[4] = span->array->rgba16;
+ FOG_LOOP(GLushort, LINEAR_FOG);
+ }
+ else {
+ GLfloat (*rgba)[4] = span->array->attribs[FRAG_ATTRIB_COL0];
+ ASSERT(span->array->ChanType == GL_FLOAT);
+ FOG_LOOP(GLfloat, LINEAR_FOG);
+ }
}
-#undef COMPUTE_F
break;
case GL_EXP:
-#define COMPUTE_F f = EXPF(density * FABSF(fogCoord) / w);
- if (span->array->ChanType == GL_UNSIGNED_BYTE) {
- GLubyte (*rgba)[4] = span->array->color.sz1.rgba;
- FOG_LOOP(GLubyte, COMPUTE_F);
- }
- else if (span->array->ChanType == GL_UNSIGNED_SHORT) {
- GLushort (*rgba)[4] = span->array->color.sz2.rgba;
- FOG_LOOP(GLushort, COMPUTE_F);
- }
- else {
- GLfloat (*rgba)[4] = span->array->attribs[FRAG_ATTRIB_COL0];
- ASSERT(span->array->ChanType == GL_FLOAT);
- FOG_LOOP(GLfloat, COMPUTE_F);
+ {
+ const GLfloat density = -ctx->Fog.Density;
+ if (span->array->ChanType == GL_UNSIGNED_BYTE) {
+ GLubyte (*rgba)[4] = span->array->rgba8;
+ FOG_LOOP(GLubyte, EXP_FOG);
+ }
+ else if (span->array->ChanType == GL_UNSIGNED_SHORT) {
+ GLushort (*rgba)[4] = span->array->rgba16;
+ FOG_LOOP(GLushort, EXP_FOG);
+ }
+ else {
+ GLfloat (*rgba)[4] = span->array->attribs[FRAG_ATTRIB_COL0];
+ ASSERT(span->array->ChanType == GL_FLOAT);
+ FOG_LOOP(GLfloat, EXP_FOG);
+ }
}
-#undef COMPUTE_F
break;
case GL_EXP2:
-#define COMPUTE_F const GLfloat coord = fogCoord / w; \
- GLfloat tmp = negDensitySquared * coord * coord; \
- if (tmp < FLT_MIN_10_EXP) \
- tmp = FLT_MIN_10_EXP; \
- f = EXPF(tmp);
- if (span->array->ChanType == GL_UNSIGNED_BYTE) {
- GLubyte (*rgba)[4] = span->array->color.sz1.rgba;
- FOG_LOOP(GLubyte, COMPUTE_F);
- }
- else if (span->array->ChanType == GL_UNSIGNED_SHORT) {
- GLushort (*rgba)[4] = span->array->color.sz2.rgba;
- FOG_LOOP(GLushort, COMPUTE_F);
- }
- else {
- GLfloat (*rgba)[4] = span->array->attribs[FRAG_ATTRIB_COL0];
- ASSERT(span->array->ChanType == GL_FLOAT);
- FOG_LOOP(GLfloat, COMPUTE_F);
+ {
+ const GLfloat negDensitySquared = -ctx->Fog.Density * ctx->Fog.Density;
+ if (span->array->ChanType == GL_UNSIGNED_BYTE) {
+ GLubyte (*rgba)[4] = span->array->rgba8;
+ FOG_LOOP(GLubyte, EXP2_FOG);
+ }
+ else if (span->array->ChanType == GL_UNSIGNED_SHORT) {
+ GLushort (*rgba)[4] = span->array->rgba16;
+ FOG_LOOP(GLushort, EXP2_FOG);
+ }
+ else {
+ GLfloat (*rgba)[4] = span->array->attribs[FRAG_ATTRIB_COL0];
+ ASSERT(span->array->ChanType == GL_FLOAT);
+ FOG_LOOP(GLfloat, EXP2_FOG);
+ }
}
-#undef COMPUTE_F
break;
default:
@@ -206,63 +257,23 @@ _swrast_fog_rgba_span( const GLcontext *ctx, SWspan *span )
return;
}
}
- else if (span->arrayMask & SPAN_FOG) {
- /* The span's fog array values are blend factors.
- * They were previously computed per-vertex.
- */
- GLuint i;
- 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->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);
- rgba[i][BCOMP] = (GLubyte) (f * rgba[i][BCOMP] + oneMinusF * bFog);
- }
- }
- 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->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);
- rgba[i][BCOMP] = (GLushort) (f * rgba[i][BCOMP] + oneMinusF * bFog);
- }
- }
- else {
- 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->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;
- rgba[i][BCOMP] = f * rgba[i][BCOMP] + oneMinusF * bFog;
- }
- }
-
- }
else {
- /* The span's fog start/step values are blend factors.
+ /* The span's fog start/step/array values are blend factors in [0,1].
* They were previously computed per-vertex.
*/
-#define COMPUTE_F f = fogCoord / w;
if (span->array->ChanType == GL_UNSIGNED_BYTE) {
- GLubyte (*rgba)[4] = span->array->color.sz1.rgba;
- FOG_LOOP(GLubyte, COMPUTE_F);
+ GLubyte (*rgba)[4] = span->array->rgba8;
+ FOG_LOOP(GLubyte, BLEND_FOG);
}
else if (span->array->ChanType == GL_UNSIGNED_SHORT) {
- GLushort (*rgba)[4] = span->array->color.sz2.rgba;
- FOG_LOOP(GLushort, COMPUTE_F);
+ GLushort (*rgba)[4] = span->array->rgba16;
+ FOG_LOOP(GLushort, BLEND_FOG);
}
else {
GLfloat (*rgba)[4] = span->array->attribs[FRAG_ATTRIB_COL0];
ASSERT(span->array->ChanType == GL_FLOAT);
- FOG_LOOP(GLfloat, COMPUTE_F);
+ FOG_LOOP(GLfloat, BLEND_FOG);
}
-#undef COMPUTE_F
}
}
@@ -274,13 +285,11 @@ void
_swrast_fog_ci_span( const GLcontext *ctx, SWspan *span )
{
const SWcontext *swrast = SWRAST_CONTEXT(ctx);
- const GLuint haveW = (span->interpMask & SPAN_W);
const GLuint fogIndex = (GLuint) ctx->Fog.Index;
GLuint *index = span->array->index;
ASSERT(swrast->_FogEnabled);
ASSERT(span->arrayMask & SPAN_INDEX);
- ASSERT((span->interpMask | span->arrayMask) & SPAN_FOG);
/* we need to compute fog blend factors */
if (swrast->_PreferPixelFog) {
@@ -293,60 +302,19 @@ _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->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;
- f = CLAMP(f, 0.0F, 1.0F);
- index[i] = (GLuint) ((GLfloat) index[i] + (1.0F - f) * fogIndex);
- fogCoord += fogStep;
- w += wStep;
- }
+ FOG_LOOP_CI(LINEAR_FOG);
}
break;
case GL_EXP:
{
const GLfloat density = -ctx->Fog.Density;
- 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);
- f = CLAMP(f, 0.0F, 1.0F);
- index[i] = (GLuint) ((GLfloat) index[i] + (1.0F - f) * fogIndex);
- fogCoord += fogStep;
- w += wStep;
- }
+ FOG_LOOP_CI(EXP_FOG);
}
break;
case GL_EXP2:
{
const GLfloat negDensitySquared = -ctx->Fog.Density * ctx->Fog.Density;
- 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;
- GLfloat tmp = negDensitySquared * coord * coord;
- GLfloat f;
-#if defined(__alpha__) || defined(__alpha)
- /* XXX this underflow check may be needed for other systems*/
- if (tmp < FLT_MIN_10_EXP)
- tmp = FLT_MIN_10_EXP;
-#endif
- f = EXPF(tmp);
- f = CLAMP(f, 0.0F, 1.0F);
- index[i] = (GLuint) ((GLfloat) index[i] + (1.0F - f) * fogIndex);
- fogCoord += fogStep;
- w += wStep;
- }
+ FOG_LOOP_CI(EXP2_FOG);
}
break;
default:
@@ -354,31 +322,10 @@ _swrast_fog_ci_span( const GLcontext *ctx, SWspan *span )
return;
}
}
- else if (span->arrayMask & SPAN_FOG) {
- /* The span's fog array values are blend factors.
- * They were previously computed per-vertex.
- */
- GLuint i;
- for (i = 0; i < span->end; i++) {
- const GLfloat f = span->array->attribs[FRAG_ATTRIB_FOGC][i][0];
- index[i] = (GLuint) ((GLfloat) index[i] + (1.0F - f) * fogIndex);
- }
- }
else {
- /* The span's fog start/step values are blend factors.
+ /* The span's fog start/step/array values are blend factors in [0,1].
* They were previously computed per-vertex.
*/
- 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++) {
- const GLfloat f = fog / w;
- index[i] = (GLuint) ((GLfloat) index[i] + (1.0F - f) * fogIndex);
- fog += fogStep;
- w += wStep;
- }
+ FOG_LOOP_CI(BLEND_FOG);
}
}
diff --git a/src/mesa/swrast/s_fragprog.c b/src/mesa/swrast/s_fragprog.c
index 7f7c0d6db5..923b67e78e 100644
--- a/src/mesa/swrast/s_fragprog.c
+++ b/src/mesa/swrast/s_fragprog.c
@@ -25,8 +25,8 @@
#include "glheader.h"
#include "colormac.h"
#include "context.h"
-#include "prog_execute.h"
#include "prog_instruction.h"
+#include "texstate.h"
#include "s_fragprog.h"
#include "s_span.h"
@@ -100,11 +100,6 @@ 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,
@@ -114,8 +109,14 @@ init_machine(GLcontext *ctx, struct gl_program_machine *machine,
/* 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->DerivX = (GLfloat (*)[4]) span->attrStepX;
+ machine->DerivY = (GLfloat (*)[4]) span->attrStepY;
+ machine->NumDeriv = FRAG_ATTRIB_MAX;
+
+ if (ctx->Shader.CurrentProgram) {
+ /* Store front/back facing value in register FOGC.Y */
+ machine->Attribs[FRAG_ATTRIB_FOGC][col][1] = (GLfloat) ctx->_Facing;
+ }
machine->CurElement = col;
@@ -142,19 +143,19 @@ 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;
+ struct gl_program_machine *machine = &swrast->FragProgMachine;
GLuint i;
for (i = start; i < end; i++) {
if (span->array->mask[i]) {
- init_machine(ctx, &machine, program, span, i);
+ init_machine(ctx, machine, program, span, i);
- if (_mesa_execute_program(ctx, &program->Base, &machine)) {
+ 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]);
+ machine->Outputs[FRAG_RESULT_COLR]);
}
else {
/* Multiple drawbuffers / render targets
@@ -165,14 +166,14 @@ run_program(GLcontext *ctx, SWspan *span, GLuint start, GLuint end)
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]);
+ 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];
+ const GLfloat depth = machine->Outputs[FRAG_RESULT_DEPR][2];
if (depth <= 0.0)
span->array->z[i] = 0;
else if (depth >= 1.0)
diff --git a/src/mesa/swrast/s_lines.c b/src/mesa/swrast/s_lines.c
index 7b2a52b4ff..781146e67f 100644
--- a/src/mesa/swrast/s_lines.c
+++ b/src/mesa/swrast/s_lines.c
@@ -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"),
@@ -121,29 +121,29 @@ draw_wide_line( GLcontext *ctx, SWspan *span, GLboolean xMajor )
/**********************************************************************/
/* Simple color index line (no stipple, width=1, no Z, no fog, no tex)*/
-#define NAME simple_ci_line
+#define NAME simple_no_z_ci_line
#define INTERP_INDEX
#define RENDER_SPAN(span) _swrast_write_index_span(ctx, &span)
#include "s_linetemp.h"
/* Simple RGBA index line (no stipple, width=1, no Z, no fog, no tex)*/
-#define NAME simple_rgba_line
+#define NAME simple_no_z_rgba_line
#define INTERP_RGBA
#define RENDER_SPAN(span) _swrast_write_rgba_span(ctx, &span);
#include "s_linetemp.h"
/* Z, fog, wide, stipple color index line */
-#define NAME general_ci_line
+#define NAME ci_line
#define INTERP_INDEX
#define INTERP_Z
-#define INTERP_FOG
+#define INTERP_ATTRIBS /* for fog */
#define RENDER_SPAN(span) \
if (ctx->Line.StippleFlag) { \
span.arrayMask |= SPAN_MASK; \
compute_stipple_mask(ctx, span.end, span.array->mask); \
} \
- if (ctx->Line._Width > 1.0) { \
+ if (ctx->Line._Width > 1.0) { \
draw_wide_line(ctx, &span, (GLboolean)(dx > dy)); \
} \
else { \
@@ -153,16 +153,15 @@ draw_wide_line( GLcontext *ctx, SWspan *span, GLboolean xMajor )
/* Z, fog, wide, stipple RGBA line */
-#define NAME general_rgba_line
+#define NAME rgba_line
#define INTERP_RGBA
#define INTERP_Z
-#define INTERP_FOG
#define RENDER_SPAN(span) \
if (ctx->Line.StippleFlag) { \
span.arrayMask |= SPAN_MASK; \
compute_stipple_mask(ctx, span.end, span.array->mask); \
} \
- if (ctx->Line._Width > 1.0) { \
+ if (ctx->Line._Width > 1.0) { \
draw_wide_line(ctx, &span, (GLboolean)(dx > dy)); \
} \
else { \
@@ -171,40 +170,17 @@ draw_wide_line( GLcontext *ctx, SWspan *span, GLboolean xMajor )
#include "s_linetemp.h"
-/* Single-texture line, w/ fog, Z, specular, etc. */
-#define NAME textured_line
+/* General-purpose line (any/all features). */
+#define NAME general_line
#define INTERP_RGBA
#define INTERP_Z
-#define INTERP_FOG
-#define INTERP_TEX
+#define INTERP_ATTRIBS
#define RENDER_SPAN(span) \
if (ctx->Line.StippleFlag) { \
span.arrayMask |= SPAN_MASK; \
compute_stipple_mask(ctx, span.end, span.array->mask); \
} \
- if (ctx->Line._Width > 1.0) { \
- draw_wide_line(ctx, &span, (GLboolean)(dx > dy)); \
- } \
- else { \
- _swrast_write_rgba_span(ctx, &span); \
- }
-#include "s_linetemp.h"
-
-
-/* Multi-texture or separate specular line, w/ fog, Z, specular, etc. */
-#define NAME multitextured_line
-#define INTERP_RGBA
-#define INTERP_SPEC
-#define INTERP_Z
-#define INTERP_FOG
-#define INTERP_MULTITEX
-#define INTERP_VARYING
-#define RENDER_SPAN(span) \
- if (ctx->Line.StippleFlag) { \
- span.arrayMask |= SPAN_MASK; \
- compute_stipple_mask(ctx, span.end, span.array->mask); \
- } \
- if (ctx->Line._Width > 1.0) { \
+ if (ctx->Line._Width > 1.0) { \
draw_wide_line(ctx, &span, (GLboolean)(dx > dy)); \
} \
else { \
@@ -215,50 +191,39 @@ draw_wide_line( GLcontext *ctx, SWspan *span, GLboolean xMajor )
void
-_swrast_add_spec_terms_line( GLcontext *ctx,
- const SWvertex *v0,
- const SWvertex *v1 )
+_swrast_add_spec_terms_line(GLcontext *ctx,
+ const SWvertex *v0, const SWvertex *v1)
{
SWvertex *ncv0 = (SWvertex *)v0;
SWvertex *ncv1 = (SWvertex *)v1;
- GLchan c[2][4];
- COPY_CHAN4( c[0], ncv0->color );
- COPY_CHAN4( c[1], ncv1->color );
- ACC_3V( ncv0->color, ncv0->specular );
- ACC_3V( ncv1->color, ncv1->specular );
+ GLfloat rSum, gSum, bSum;
+ GLchan cSave[2][4];
+
+ /* save original colors */
+ COPY_CHAN4(cSave[0], ncv0->color);
+ COPY_CHAN4(cSave[1], ncv1->color);
+ /* sum v0 */
+ rSum = CHAN_TO_FLOAT(ncv0->color[0]) + ncv0->attrib[FRAG_ATTRIB_COL1][0];
+ gSum = CHAN_TO_FLOAT(ncv0->color[1]) + ncv0->attrib[FRAG_ATTRIB_COL1][1];
+ bSum = CHAN_TO_FLOAT(ncv0->color[2]) + ncv0->attrib[FRAG_ATTRIB_COL1][2];
+ UNCLAMPED_FLOAT_TO_CHAN(ncv0->color[0], rSum);
+ UNCLAMPED_FLOAT_TO_CHAN(ncv0->color[1], gSum);
+ UNCLAMPED_FLOAT_TO_CHAN(ncv0->color[2], bSum);
+ /* sum v1 */
+ rSum = CHAN_TO_FLOAT(ncv1->color[0]) + ncv1->attrib[FRAG_ATTRIB_COL1][0];
+ gSum = CHAN_TO_FLOAT(ncv1->color[1]) + ncv1->attrib[FRAG_ATTRIB_COL1][1];
+ bSum = CHAN_TO_FLOAT(ncv1->color[2]) + ncv1->attrib[FRAG_ATTRIB_COL1][2];
+ UNCLAMPED_FLOAT_TO_CHAN(ncv1->color[0], rSum);
+ UNCLAMPED_FLOAT_TO_CHAN(ncv1->color[1], gSum);
+ UNCLAMPED_FLOAT_TO_CHAN(ncv1->color[2], bSum);
+ /* draw */
SWRAST_CONTEXT(ctx)->SpecLine( ctx, ncv0, ncv1 );
- COPY_CHAN4( ncv0->color, c[0] );
- COPY_CHAN4( ncv1->color, c[1] );
+ /* restore original colors */
+ COPY_CHAN4( ncv0->attrib[FRAG_ATTRIB_COL0], cSave[0] );
+ COPY_CHAN4( ncv1->attrib[FRAG_ATTRIB_COL0], cSave[1] );
}
-#ifdef DEBUG
-extern void
-_mesa_print_line_function(GLcontext *ctx); /* silence compiler warning */
-void
-_mesa_print_line_function(GLcontext *ctx)
-{
- SWcontext *swrast = SWRAST_CONTEXT(ctx);
-
- _mesa_printf("Line Func == ");
- if (swrast->Line == simple_ci_line)
- _mesa_printf("simple_ci_line\n");
- else if (swrast->Line == simple_rgba_line)
- _mesa_printf("simple_rgba_line\n");
- else if (swrast->Line == general_ci_line)
- _mesa_printf("general_ci_line\n");
- else if (swrast->Line == general_rgba_line)
- _mesa_printf("general_rgba_line\n");
- else if (swrast->Line == textured_line)
- _mesa_printf("textured_line\n");
- else if (swrast->Line == multitextured_line)
- _mesa_printf("multitextured_line\n");
- else
- _mesa_printf("Driver func %p\n", (void *(*)()) swrast->Line);
-}
-#endif
-
-
#ifdef DEBUG
@@ -280,7 +245,7 @@ do { \
-/*
+/**
* Determine which line drawing function to use given the current
* rendering context.
*
@@ -292,6 +257,9 @@ _swrast_choose_line( GLcontext *ctx )
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
const GLboolean rgbmode = ctx->Visual.rgbMode;
+ GLboolean specular = (ctx->Fog.ColorSumEnabled ||
+ (ctx->Light.Enabled &&
+ ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR));
if (ctx->RenderMode == GL_RENDER) {
if (ctx->Line.SmoothFlag) {
@@ -300,32 +268,27 @@ _swrast_choose_line( GLcontext *ctx )
ASSERT(swrast->Line);
}
else if (ctx->Texture._EnabledCoordUnits
- || ctx->FragmentProgram._Current) {
- /* textured lines */
- if (ctx->Texture._EnabledCoordUnits > 0x1
- || NEED_SECONDARY_COLOR(ctx)
- || ctx->FragmentProgram._Current) {
- /* multi-texture and/or separate specular color */
- USE(multitextured_line);
- }
- else {
- USE(textured_line);
- }
+ || ctx->FragmentProgram._Current
+ || swrast->_FogEnabled
+ || specular) {
+ USE(general_line);
}
- else if (ctx->Depth.Test || swrast->_FogEnabled || ctx->Line._Width != 1.0
+ else if (ctx->Depth.Test
+ || ctx->Line._Width != 1.0
|| ctx->Line.StippleFlag) {
/* no texture, but Z, fog, width>1, stipple, etc. */
if (rgbmode)
- USE(general_rgba_line);
+ USE(rgba_line);
else
- USE(general_ci_line);
+ USE(ci_line);
}
else {
- /* simplest lines */
+ ASSERT(!ctx->Depth.Test);
+ /* simple lines */
if (rgbmode)
- USE(simple_rgba_line);
+ USE(simple_no_z_rgba_line);
else
- USE(simple_ci_line);
+ USE(simple_no_z_ci_line);
}
}
else if (ctx->RenderMode == GL_FEEDBACK) {
@@ -335,6 +298,4 @@ _swrast_choose_line( GLcontext *ctx )
ASSERT(ctx->RenderMode == GL_SELECT);
USE(_swrast_select_line);
}
-
- /*_mesa_print_line_function(ctx);*/
}
diff --git a/src/mesa/swrast/s_linetemp.h b/src/mesa/swrast/s_linetemp.h
index 7b66291eb5..1accfc67e2 100644
--- a/src/mesa/swrast/s_linetemp.h
+++ b/src/mesa/swrast/s_linetemp.h
@@ -1,6 +1,6 @@
/*
* Mesa 3-D graphics library
- * Version: 6.5.3
+ * Version: 7.0
*
* Copyright (C) 1999-2007 Brian Paul All Rights Reserved.
*
@@ -31,13 +31,9 @@
* The following macros may be defined to indicate what auxillary information
* must be interplated along the line:
* INTERP_Z - if defined, interpolate Z values
- * INTERP_FOG - if defined, interpolate FOG values
* INTERP_RGBA - if defined, interpolate RGBA values
- * INTERP_SPEC - if defined, interpolate specular RGB values
* 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
+ * INTERP_ATTRIBS - if defined, interpolate attribs (texcoords, varying, etc)
*
* When one can directly address pixels in the color buffer the following
* macros can be defined and used to directly compute pixel addresses during
@@ -74,10 +70,10 @@ 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];
- GLint x1 = (GLint) vert1->win[0];
- GLint y0 = (GLint) vert0->win[1];
- GLint y1 = (GLint) vert1->win[1];
+ GLint x0 = (GLint) vert0->attrib[FRAG_ATTRIB_WPOS][0];
+ GLint x1 = (GLint) vert1->attrib[FRAG_ATTRIB_WPOS][0];
+ GLint y0 = (GLint) vert0->attrib[FRAG_ATTRIB_WPOS][1];
+ GLint y1 = (GLint) vert1->attrib[FRAG_ATTRIB_WPOS][1];
GLint dx, dy;
GLint numPixels;
GLint xstep, ystep;
@@ -106,8 +102,8 @@ NAME( GLcontext *ctx, const SWvertex *vert0, const SWvertex *vert1 )
/* Cull primitives with malformed coordinates.
*/
{
- GLfloat tmp = vert0->win[0] + vert0->win[1]
- + vert1->win[0] + vert1->win[1];
+ GLfloat tmp = vert0->attrib[FRAG_ATTRIB_WPOS][0] + vert0->attrib[FRAG_ATTRIB_WPOS][1]
+ + vert1->attrib[FRAG_ATTRIB_WPOS][0] + vert1->attrib[FRAG_ATTRIB_WPOS][1];
if (IS_INF_OR_NAN(tmp))
return;
}
@@ -115,8 +111,12 @@ NAME( GLcontext *ctx, const SWvertex *vert0, const SWvertex *vert1 )
/*
printf("%s():\n", __FUNCTION__);
printf(" (%f, %f, %f) -> (%f, %f, %f)\n",
- vert0->win[0], vert0->win[1], vert0->win[2],
- vert1->win[0], vert1->win[1], vert1->win[2]);
+ vert0->attrib[FRAG_ATTRIB_WPOS][0],
+ vert0->attrib[FRAG_ATTRIB_WPOS][1],
+ vert0->attrib[FRAG_ATTRIB_WPOS][2],
+ vert1->attrib[FRAG_ATTRIB_WPOS][0],
+ vert1->attrib[FRAG_ATTRIB_WPOS][1],
+ vert1->attrib[FRAG_ATTRIB_WPOS][2]);
printf(" (%d, %d, %d) -> (%d, %d, %d)\n",
vert0->color[0], vert0->color[1], vert0->color[2],
vert1->color[0], vert1->color[1], vert1->color[2]);
@@ -156,6 +156,18 @@ NAME( GLcontext *ctx, const SWvertex *vert0, const SWvertex *vert1 )
if (dx == 0 && dy == 0)
return;
+ /*
+ printf("%s %d,%d %g %g %g %g %g %g %g %g\n", __FUNCTION__, dx, dy,
+ vert0->attrib[FRAG_ATTRIB_COL1][0],
+ vert0->attrib[FRAG_ATTRIB_COL1][1],
+ vert0->attrib[FRAG_ATTRIB_COL1][2],
+ vert0->attrib[FRAG_ATTRIB_COL1][3],
+ vert1->attrib[FRAG_ATTRIB_COL1][0],
+ vert1->attrib[FRAG_ATTRIB_COL1][1],
+ vert1->attrib[FRAG_ATTRIB_COL1][2],
+ vert1->attrib[FRAG_ATTRIB_COL1][3]);
+ */
+
#ifdef DEPTH_TYPE
zPtr = (DEPTH_TYPE *) zrb->GetPointer(ctx, zrb, x0, y0);
#endif
@@ -234,33 +246,15 @@ NAME( GLcontext *ctx, const SWvertex *vert0, const SWvertex *vert1 )
span.alphaStep = 0;
}
#endif
-#ifdef INTERP_SPEC
- interpFlags |= SPAN_SPEC;
- if (ctx->Light.ShadeModel == GL_SMOOTH) {
- span.specRed = ChanToFixed(vert0->specular[0]);
- span.specGreen = ChanToFixed(vert0->specular[1]);
- span.specBlue = ChanToFixed(vert0->specular[2]);
- span.specRedStep = (ChanToFixed(vert1->specular[0]) - span.specRed) / numPixels;
- span.specGreenStep = (ChanToFixed(vert1->specular[1]) - span.specBlue) / numPixels;
- span.specBlueStep = (ChanToFixed(vert1->specular[2]) - span.specGreen) / numPixels;
- }
- else {
- span.specRed = ChanToFixed(vert1->specular[0]);
- span.specGreen = ChanToFixed(vert1->specular[1]);
- span.specBlue = ChanToFixed(vert1->specular[2]);
- span.specRedStep = 0;
- span.specGreenStep = 0;
- span.specBlueStep = 0;
- }
-#endif
#ifdef INTERP_INDEX
interpFlags |= SPAN_INDEX;
if (ctx->Light.ShadeModel == GL_SMOOTH) {
- span.index = FloatToFixed(vert0->index);
- span.indexStep = FloatToFixed(vert1->index - vert0->index) / numPixels;
+ span.index = FloatToFixed(vert0->attrib[FRAG_ATTRIB_CI][0]);
+ span.indexStep = FloatToFixed( vert1->attrib[FRAG_ATTRIB_CI][0]
+ - vert0->attrib[FRAG_ATTRIB_CI][0]) / numPixels;
}
else {
- span.index = FloatToFixed(vert1->index);
+ span.index = FloatToFixed(vert1->attrib[FRAG_ATTRIB_CI][0]);
span.indexStep = 0;
}
#endif
@@ -268,83 +262,51 @@ NAME( GLcontext *ctx, const SWvertex *vert0, const SWvertex *vert1 )
interpFlags |= SPAN_Z;
{
if (depthBits <= 16) {
- span.z = FloatToFixed(vert0->win[2]) + FIXED_HALF;
- span.zStep = FloatToFixed(vert1->win[2] - vert0->win[2]) / numPixels;
+ span.z = FloatToFixed(vert0->attrib[FRAG_ATTRIB_WPOS][2]) + FIXED_HALF;
+ span.zStep = FloatToFixed( vert1->attrib[FRAG_ATTRIB_WPOS][2]
+ - vert0->attrib[FRAG_ATTRIB_WPOS][2]) / numPixels;
}
else {
/* don't use fixed point */
- span.z = (GLuint) vert0->win[2];
- span.zStep = (GLint) ((vert1->win[2] - vert0->win[2]) / numPixels);
+ span.z = (GLuint) vert0->attrib[FRAG_ATTRIB_WPOS][2];
+ span.zStep = (GLint) (( vert1->attrib[FRAG_ATTRIB_WPOS][2]
+ - vert0->attrib[FRAG_ATTRIB_WPOS][2]) / numPixels);
}
}
#endif
-#ifdef INTERP_FOG
- interpFlags |= SPAN_FOG;
- 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;
+#if defined(INTERP_ATTRIBS)
{
- const GLfloat invw0 = vert0->win[3];
- const GLfloat invw1 = vert1->win[3];
const GLfloat invLen = 1.0F / numPixels;
- GLfloat ds, dt, dr, dq;
- 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
-#if defined(INTERP_MULTITEX) || defined(INTERP_VARYING)
- interpFlags |= (SPAN_TEXTURE | SPAN_VARYING);
- {
- const GLfloat invLen = 1.0F / numPixels;
- 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.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;
- }
- }
+ const GLfloat invw0 = vert0->attrib[FRAG_ATTRIB_WPOS][3];
+ const GLfloat invw1 = vert1->attrib[FRAG_ATTRIB_WPOS][3];
+
+ span.attrStart[FRAG_ATTRIB_WPOS][3] = invw0;
+ span.attrStepX[FRAG_ATTRIB_WPOS][3] = (invw1 - invw0) * invLen;
+ span.attrStepY[FRAG_ATTRIB_WPOS][3] = 0.0;
+
+ ATTRIB_LOOP_BEGIN
+ if (swrast->_InterpMode[attr] == GL_FLAT) {
+ COPY_4V(span.attrStart[attr], vert1->attrib[attr]);
+ ASSIGN_4V(span.attrStepX[attr], 0.0, 0.0, 0.0, 0.0);
+ }
+ else {
+ GLuint c;
+ for (c = 0; c < 4; c++) {
+ float da;
+ span.attrStart[attr][c] = invw0 * vert0->attrib[attr][c];
+ da = (invw1 * vert1->attrib[attr][c]) - span.attrStart[attr][c];
+ span.attrStepX[attr][c] = da * invLen;
+ }
+ }
+ ASSIGN_4V(span.attrStepY[attr], 0.0, 0.0, 0.0, 0.0);
+ ATTRIB_LOOP_END
}
#endif
- INIT_SPAN(span, GL_LINE, numPixels, interpFlags, SPAN_XY);
-
- /* Need these for fragment prog texcoord interpolation */
- span.attrStart[FRAG_ATTRIB_WPOS][3] = 1.0F;
- span.attrStepX[FRAG_ATTRIB_WPOS][3] = 0.0F;
- span.attrStepY[FRAG_ATTRIB_WPOS][3] = 0.0F;
+ INIT_SPAN(span, GL_LINE);
+ span.end = numPixels;
+ span.interpMask = interpFlags;
+ span.arrayMask = SPAN_XY;
/*
* Draw
@@ -375,7 +337,7 @@ NAME( GLcontext *ctx, const SWvertex *vert0, const SWvertex *vert1 )
#ifdef PIXEL_ADDRESS
pixelPtr = (PIXEL_TYPE*) ((GLubyte*) pixelPtr + pixelXstep);
#endif
- if (error<0) {
+ if (error < 0) {
error += errorInc;
}
else {
@@ -442,11 +404,8 @@ NAME( GLcontext *ctx, const SWvertex *vert0, const SWvertex *vert1 )
#undef NAME
#undef INTERP_Z
-#undef INTERP_FOG
#undef INTERP_RGBA
-#undef INTERP_SPEC
-#undef INTERP_TEX
-#undef INTERP_MULTITEX
+#undef INTERP_ATTRIBS
#undef INTERP_INDEX
#undef PIXEL_ADDRESS
#undef PIXEL_TYPE
diff --git a/src/mesa/swrast/s_logic.c b/src/mesa/swrast/s_logic.c
index e680732bee..0af9063968 100644
--- a/src/mesa/swrast/s_logic.c
+++ b/src/mesa/swrast/s_logic.c
@@ -229,13 +229,13 @@ _swrast_logicop_rgba_span(GLcontext *ctx, struct gl_renderbuffer *rb,
if (span->array->ChanType == GL_UNSIGNED_BYTE) {
/* treat 4*GLubyte as GLuint */
logicop_uint1(ctx, span->end,
- (GLuint *) span->array->color.sz1.rgba,
+ (GLuint *) span->array->rgba8,
(const GLuint *) rbPixels, span->array->mask);
}
else if (span->array->ChanType == GL_UNSIGNED_SHORT) {
/* treat 2*GLushort as GLuint */
logicop_uint2(ctx, 2 * span->end,
- (GLuint *) span->array->color.sz2.rgba,
+ (GLuint *) span->array->rgba16,
(const GLuint *) rbPixels, span->array->mask);
}
else {
diff --git a/src/mesa/swrast/s_masking.c b/src/mesa/swrast/s_masking.c
index 8800f7d8e3..a69720e83a 100644
--- a/src/mesa/swrast/s_masking.c
+++ b/src/mesa/swrast/s_masking.c
@@ -61,7 +61,7 @@ _swrast_mask_rgba_span(GLcontext *ctx, struct gl_renderbuffer *rb,
const GLuint srcMask = *((GLuint *) ctx->Color.ColorMask);
const GLuint dstMask = ~srcMask;
const GLuint *dst = (const GLuint *) rbPixels;
- GLuint *src = (GLuint *) span->array->color.sz1.rgba;
+ GLuint *src = (GLuint *) span->array->rgba8;
GLuint i;
for (i = 0; i < n; i++) {
src[i] = (src[i] & srcMask) | (dst[i] & dstMask);
@@ -75,7 +75,7 @@ _swrast_mask_rgba_span(GLcontext *ctx, struct gl_renderbuffer *rb,
const GLushort bMask = ctx->Color.ColorMask[BCOMP] ? 0xffff : 0x0;
const GLushort aMask = ctx->Color.ColorMask[ACOMP] ? 0xffff : 0x0;
const GLushort (*dst)[4] = (const GLushort (*)[4]) rbPixels;
- GLushort (*src)[4] = span->array->color.sz2.rgba;
+ GLushort (*src)[4] = span->array->rgba16;
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_points.c b/src/mesa/swrast/s_points.c
index 5879bccf1e..8eba53c807 100644
--- a/src/mesa/swrast/s_points.c
+++ b/src/mesa/swrast/s_points.c
@@ -1,8 +1,8 @@
/*
* Mesa 3-D graphics library
- * Version: 6.1
+ * Version: 7.1
*
- * 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"),
@@ -34,242 +34,536 @@
#include "s_span.h"
-
-#define RGBA 0x1
-#define INDEX 0x2
-#define SMOOTH 0x4
-#define TEXTURE 0x8
-#define SPECULAR 0x10
-#define LARGE 0x20
-#define ATTENUATE 0x40
-#define SPRITE 0x80
-
-
-/*
- * CI points with size == 1.0
+/**
+ * Used to cull points with invalid coords
*/
-#define FLAGS (INDEX)
-#define NAME size1_ci_point
-#include "s_pointtemp.h"
+#define CULL_INVALID(V) \
+ do { \
+ float tmp = (V)->attrib[FRAG_ATTRIB_WPOS][0] \
+ + (V)->attrib[FRAG_ATTRIB_WPOS][1]; \
+ if (IS_INF_OR_NAN(tmp)) \
+ return; \
+ } while(0)
-/*
- * General CI points.
+/**
+ * Draw a point sprite
*/
-#define FLAGS (INDEX | LARGE)
-#define NAME general_ci_point
-#include "s_pointtemp.h"
-
-
-/*
- * Antialiased CI points.
- */
-#define FLAGS (INDEX | SMOOTH)
-#define NAME antialiased_ci_point
-#include "s_pointtemp.h"
+static void
+sprite_point(GLcontext *ctx, const SWvertex *vert)
+{
+ SWcontext *swrast = SWRAST_CONTEXT(ctx);
+ SWspan span;
+ GLfloat size;
+ GLuint tCoords[MAX_TEXTURE_COORD_UNITS];
+ GLuint numTcoords = 0;
+ GLfloat t0, dtdy;
+
+ CULL_INVALID(vert);
+
+ /* z coord */
+ if (ctx->DrawBuffer->Visual.depthBits <= 16)
+ span.z = FloatToFixed(vert->attrib[FRAG_ATTRIB_WPOS][2] + 0.5F);
+ else
+ span.z = (GLuint) (vert->attrib[FRAG_ATTRIB_WPOS][2] + 0.5F);
+ span.zStep = 0;
+
+ /* compute size */
+ if (ctx->Point._Attenuated || ctx->VertexProgram.PointSizeEnabled) {
+ /* use vertex's point size */
+ /* first, clamp attenuated size to the user-specifed range */
+ size = CLAMP(vert->pointSize, ctx->Point.MinSize, ctx->Point.MaxSize);
+ }
+ else {
+ /* use constant point size */
+ size = ctx->Point._Size; /* already clamped to user range */
+ }
+ /* clamp to non-AA implementation limits */
+ size = CLAMP(size, ctx->Const.MinPointSize, ctx->Const.MaxPointSize);
+
+ /* span init */
+ INIT_SPAN(span, GL_POINT);
+ span.interpMask = SPAN_Z | SPAN_RGBA;
+
+ span.red = ChanToFixed(vert->color[0]);
+ span.green = ChanToFixed(vert->color[1]);
+ span.blue = ChanToFixed(vert->color[2]);
+ span.alpha = ChanToFixed(vert->color[3]);
+ span.redStep = 0;
+ span.greenStep = 0;
+ span.blueStep = 0;
+ span.alphaStep = 0;
+
+ /* need these for fragment programs */
+ span.attrStart[FRAG_ATTRIB_WPOS][3] = 1.0F;
+ span.attrStepX[FRAG_ATTRIB_WPOS][3] = 0.0F;
+ span.attrStepY[FRAG_ATTRIB_WPOS][3] = 0.0F;
+
+ ATTRIB_LOOP_BEGIN
+ if (attr >= FRAG_ATTRIB_TEX0 && attr < FRAG_ATTRIB_VAR0) {
+ const GLuint u = attr - FRAG_ATTRIB_TEX0;
+ /* a texcoord */
+ if (ctx->Point.CoordReplace[u]) {
+ GLfloat s, r, dsdx;
+
+ s = 0.0;
+ dsdx = 1.0 / size;
+
+ if (ctx->Point.SpriteOrigin == GL_LOWER_LEFT) {
+ t0 = 0.0;
+ dtdy = 1.0 / size;
+ }
+ else {
+ /* GL_UPPER_LEFT */
+ t0 = 1.0;
+ dtdy = -1.0 / size;
+ }
+ tCoords[numTcoords++] = attr;
+
+ if (ctx->Point.SpriteRMode == GL_ZERO)
+ r = 0.0F;
+ else if (ctx->Point.SpriteRMode == GL_S)
+ r = vert->attrib[attr][0];
+ else /* GL_R */
+ r = vert->attrib[attr][2];
+
+ span.attrStart[attr][0] = s;
+ span.attrStart[attr][1] = 0.0; /* overwritten below */
+ span.attrStart[attr][2] = r;
+ span.attrStart[attr][3] = 1.0;
+
+ span.attrStepX[attr][0] = dsdx;
+ span.attrStepX[attr][1] = 0.0;
+ span.attrStepX[attr][2] = 0.0;
+ span.attrStepX[attr][3] = 0.0;
+
+ span.attrStepY[attr][0] = 0.0;
+ span.attrStepY[attr][1] = dtdy;
+ span.attrStepY[attr][2] = 0.0;
+ span.attrStepY[attr][3] = 0.0;
+
+ continue;
+ }
+ }
+ /* use vertex's texcoord/attrib */
+ COPY_4V(span.attrStart[attr], vert->attrib[attr]);
+ ASSIGN_4V(span.attrStepX[attr], 0, 0, 0, 0);
+ ASSIGN_4V(span.attrStepY[attr], 0, 0, 0, 0);
+ ATTRIB_LOOP_END
+
+ /* compute pos, bounds and render */
+ {
+ const GLfloat x = vert->attrib[FRAG_ATTRIB_WPOS][0];
+ const GLfloat y = vert->attrib[FRAG_ATTRIB_WPOS][1];
+ GLint iSize = (GLint) (size + 0.5F);
+ GLint xmin, xmax, ymin, ymax, iy;
+ GLint iRadius;
+ GLfloat tcoord = t0;
+
+ iSize = MAX2(1, iSize);
+ iRadius = iSize / 2;
+
+ if (iSize & 1) {
+ /* odd size */
+ xmin = (GLint) (x - iRadius);
+ xmax = (GLint) (x + iRadius);
+ ymin = (GLint) (y - iRadius);
+ ymax = (GLint) (y + iRadius);
+ }
+ else {
+ /* even size */
+ xmin = (GLint) x - iRadius + 1;
+ xmax = xmin + iSize - 1;
+ ymin = (GLint) y - iRadius + 1;
+ ymax = ymin + iSize - 1;
+ }
+ /* render spans */
+ for (iy = ymin; iy <= ymax; iy++) {
+ GLuint i;
+ /* setup texcoord T for this row */
+ for (i = 0; i < numTcoords; i++) {
+ span.attrStart[tCoords[i]][1] = tcoord;
+ }
-/*
- * Distance attenuated, general CI points.
- */
-#define FLAGS (INDEX | ATTENUATE)
-#define NAME atten_general_ci_point
-#include "s_pointtemp.h"
+ /* these might get changed by span clipping */
+ span.x = xmin;
+ span.y = iy;
+ span.end = xmax - xmin + 1;
+ _swrast_write_rgba_span(ctx, &span);
-/*
- * RGBA points with size == 1.0
- */
-#define FLAGS (RGBA)
-#define NAME size1_rgba_point
-#include "s_pointtemp.h"
+ tcoord += dtdy;
+ }
+ }
+}
-/*
- * General RGBA points.
+/**
+ * Draw smooth/antialiased point. RGB or CI mode.
*/
-#define FLAGS (RGBA | LARGE)
-#define NAME general_rgba_point
-#include "s_pointtemp.h"
-
+static void
+smooth_point(GLcontext *ctx, const SWvertex *vert)
+{
+ SWcontext *swrast = SWRAST_CONTEXT(ctx);
+ const GLboolean ciMode = !ctx->Visual.rgbMode;
+ SWspan span;
+ GLfloat size, alphaAtten;
+
+ CULL_INVALID(vert);
+
+ /* z coord */
+ if (ctx->DrawBuffer->Visual.depthBits <= 16)
+ span.z = FloatToFixed(vert->attrib[FRAG_ATTRIB_WPOS][2] + 0.5F);
+ else
+ span.z = (GLuint) (vert->attrib[FRAG_ATTRIB_WPOS][2] + 0.5F);
+ span.zStep = 0;
+
+ /* compute size */
+ if (ctx->Point._Attenuated || ctx->VertexProgram.PointSizeEnabled) {
+ /* use vertex's point size */
+ /* first, clamp attenuated size to the user-specifed range */
+ size = CLAMP(vert->pointSize, ctx->Point.MinSize, ctx->Point.MaxSize);
+ }
+ else {
+ /* use constant point size */
+ size = ctx->Point._Size; /* this is already clamped */
+ }
+ /* clamp to AA implementation limits */
+ size = CLAMP(size, ctx->Const.MinPointSizeAA, ctx->Const.MaxPointSizeAA);
-/*
- * Antialiased RGBA points.
- */
-#define FLAGS (RGBA | SMOOTH)
-#define NAME antialiased_rgba_point
-#include "s_pointtemp.h"
+ /* alpha attenuation / fade factor */
+ if (ctx->Multisample.Enabled) {
+ if (vert->pointSize >= ctx->Point.Threshold) {
+ alphaAtten = 1.0F;
+ }
+ else {
+ GLfloat dsize = vert->pointSize / ctx->Point.Threshold;
+ alphaAtten = dsize * dsize;
+ }
+ }
+ else {
+ alphaAtten = 1.0;
+ }
+ (void) alphaAtten; /* not used */
+
+ /* span init */
+ INIT_SPAN(span, GL_POINT);
+ span.interpMask = SPAN_Z | SPAN_RGBA;
+ span.arrayMask = SPAN_COVERAGE | SPAN_MASK;
+
+ span.red = ChanToFixed(vert->color[0]);
+ span.green = ChanToFixed(vert->color[1]);
+ span.blue = ChanToFixed(vert->color[2]);
+ span.alpha = ChanToFixed(vert->color[3]);
+ span.redStep = 0;
+ span.greenStep = 0;
+ span.blueStep = 0;
+ span.alphaStep = 0;
+
+ /* need these for fragment programs */
+ span.attrStart[FRAG_ATTRIB_WPOS][3] = 1.0F;
+ span.attrStepX[FRAG_ATTRIB_WPOS][3] = 0.0F;
+ span.attrStepY[FRAG_ATTRIB_WPOS][3] = 0.0F;
+
+ ATTRIB_LOOP_BEGIN
+ COPY_4V(span.attrStart[attr], vert->attrib[attr]);
+ ASSIGN_4V(span.attrStepX[attr], 0, 0, 0, 0);
+ ASSIGN_4V(span.attrStepY[attr], 0, 0, 0, 0);
+ ATTRIB_LOOP_END
+
+ /* compute pos, bounds and render */
+ {
+ const GLfloat x = vert->attrib[FRAG_ATTRIB_WPOS][0];
+ const GLfloat y = vert->attrib[FRAG_ATTRIB_WPOS][1];
+ const GLfloat radius = 0.5F * size;
+ const GLfloat rmin = radius - 0.7071F; /* 0.7071 = sqrt(2)/2 */
+ const GLfloat rmax = radius + 0.7071F;
+ const GLfloat rmin2 = MAX2(0.0F, rmin * rmin);
+ const GLfloat rmax2 = rmax * rmax;
+ const GLfloat cscale = 1.0F / (rmax2 - rmin2);
+ const GLint xmin = (GLint) (x - radius);
+ const GLint xmax = (GLint) (x + radius);
+ const GLint ymin = (GLint) (y - radius);
+ const GLint ymax = (GLint) (y + radius);
+ GLint ix, iy;
+
+ for (iy = ymin; iy <= ymax; iy++) {
+
+ /* these might get changed by span clipping */
+ span.x = xmin;
+ span.y = iy;
+ span.end = xmax - xmin + 1;
+
+ /* compute coverage for each pixel in span */
+ for (ix = xmin; ix <= xmax; ix++) {
+ const GLfloat dx = ix - x + 0.5F;
+ const GLfloat dy = iy - y + 0.5F;
+ const GLfloat dist2 = dx * dx + dy * dy;
+ GLfloat coverage;
+
+ if (dist2 < rmax2) {
+ if (dist2 >= rmin2) {
+ /* compute partial coverage */
+ coverage = 1.0F - (dist2 - rmin2) * cscale;
+ if (ciMode) {
+ /* coverage in [0,15] */
+ coverage *= 15.0;
+ }
+ }
+ else {
+ /* full coverage */
+ coverage = 1.0F;
+ }
+ span.array->mask[ix - xmin] = 1;
+ }
+ else {
+ /* zero coverage - fragment outside the radius */
+ coverage = 0.0;
+ span.array->mask[ix - xmin] = 0;
+ }
+ span.array->coverage[ix - xmin] = coverage;
+ }
+ /* render span */
+ _swrast_write_rgba_span(ctx, &span);
-/*
- * Textured RGBA points.
- */
-#define FLAGS (RGBA | LARGE | TEXTURE | SPECULAR)
-#define NAME textured_rgba_point
-#include "s_pointtemp.h"
+ }
+ }
+}
-/*
- * Antialiased points with texture mapping.
+/**
+ * Draw large (size >= 1) non-AA point. RGB or CI mode.
*/
-#define FLAGS (RGBA | SMOOTH | TEXTURE | SPECULAR)
-#define NAME antialiased_tex_rgba_point
-#include "s_pointtemp.h"
+static void
+large_point(GLcontext *ctx, const SWvertex *vert)
+{
+ SWcontext *swrast = SWRAST_CONTEXT(ctx);
+ const GLboolean ciMode = !ctx->Visual.rgbMode;
+ SWspan span;
+ GLfloat size;
+
+ CULL_INVALID(vert);
+
+ /* z coord */
+ if (ctx->DrawBuffer->Visual.depthBits <= 16)
+ span.z = FloatToFixed(vert->attrib[FRAG_ATTRIB_WPOS][2] + 0.5F);
+ else
+ span.z = (GLuint) (vert->attrib[FRAG_ATTRIB_WPOS][2] + 0.5F);
+ span.zStep = 0;
+
+ /* compute size */
+ if (ctx->Point._Attenuated || ctx->VertexProgram.PointSizeEnabled) {
+ /* use vertex's point size */
+ /* first, clamp attenuated size to the user-specifed range */
+ size = CLAMP(vert->pointSize, ctx->Point.MinSize, ctx->Point.MaxSize);
+ }
+ else {
+ /* use constant point size */
+ size = ctx->Point._Size; /* already clamped to user range */
+ }
+ /* clamp to non-AA implementation limits */
+ size = CLAMP(size, ctx->Const.MinPointSize, ctx->Const.MaxPointSize);
+ /* span init */
+ INIT_SPAN(span, GL_POINT);
+ span.arrayMask = SPAN_XY;
-/*
- * Distance attenuated, general RGBA points.
- */
-#define FLAGS (RGBA | ATTENUATE)
-#define NAME atten_general_rgba_point
-#include "s_pointtemp.h"
+ if (ciMode) {
+ span.interpMask = SPAN_Z | SPAN_INDEX;
+ span.index = FloatToFixed(vert->attrib[FRAG_ATTRIB_CI][0]);
+ span.indexStep = 0;
+ }
+ else {
+ span.interpMask = SPAN_Z | SPAN_RGBA;
+ span.red = ChanToFixed(vert->color[0]);
+ span.green = ChanToFixed(vert->color[1]);
+ span.blue = ChanToFixed(vert->color[2]);
+ span.alpha = ChanToFixed(vert->color[3]);
+ span.redStep = 0;
+ span.greenStep = 0;
+ span.blueStep = 0;
+ span.alphaStep = 0;
+ }
+ /* need these for fragment programs */
+ span.attrStart[FRAG_ATTRIB_WPOS][3] = 1.0F;
+ span.attrStepX[FRAG_ATTRIB_WPOS][3] = 0.0F;
+ span.attrStepY[FRAG_ATTRIB_WPOS][3] = 0.0F;
+
+ ATTRIB_LOOP_BEGIN
+ COPY_4V(span.attrStart[attr], vert->attrib[attr]);
+ ASSIGN_4V(span.attrStepX[attr], 0, 0, 0, 0);
+ ASSIGN_4V(span.attrStepY[attr], 0, 0, 0, 0);
+ ATTRIB_LOOP_END
+
+ /* compute pos, bounds and render */
+ {
+ const GLfloat x = vert->attrib[FRAG_ATTRIB_WPOS][0];
+ const GLfloat y = vert->attrib[FRAG_ATTRIB_WPOS][1];
+ GLint iSize = (GLint) (size + 0.5F);
+ GLint xmin, xmax, ymin, ymax, ix, iy;
+ GLint iRadius;
+
+ iSize = MAX2(1, iSize);
+ iRadius = iSize / 2;
+
+ if (iSize & 1) {
+ /* odd size */
+ xmin = (GLint) (x - iRadius);
+ xmax = (GLint) (x + iRadius);
+ ymin = (GLint) (y - iRadius);
+ ymax = (GLint) (y + iRadius);
+ }
+ else {
+ /* even size */
+ xmin = (GLint) x - iRadius + 1;
+ xmax = xmin + iSize - 1;
+ ymin = (GLint) y - iRadius + 1;
+ ymax = ymin + iSize - 1;
+ }
-/*
- * Distance attenuated, textured RGBA points.
- */
-#define FLAGS (RGBA | ATTENUATE | TEXTURE | SPECULAR)
-#define NAME atten_textured_rgba_point
-#include "s_pointtemp.h"
+ /* generate fragments */
+ span.end = 0;
+ for (iy = ymin; iy <= ymax; iy++) {
+ for (ix = xmin; ix <= xmax; ix++) {
+ span.array->x[span.end] = ix;
+ span.array->y[span.end] = iy;
+ span.end++;
+ }
+ }
+ assert(span.end <= MAX_WIDTH);
+ _swrast_write_rgba_span(ctx, &span);
+ }
+}
-/*
- * Distance attenuated, antialiased points with or without texture mapping.
+/**
+ * Draw size=1, single-pixel point
*/
-#define FLAGS (RGBA | ATTENUATE | TEXTURE | SMOOTH)
-#define NAME atten_antialiased_rgba_point
-#include "s_pointtemp.h"
+static void
+pixel_point(GLcontext *ctx, const SWvertex *vert)
+{
+ SWcontext *swrast = SWRAST_CONTEXT(ctx);
+ const GLboolean ciMode = !ctx->Visual.rgbMode;
+ /*
+ * Note that unlike the other functions, we put single-pixel points
+ * into a special span array in order to render as many points as
+ * possible with a single _swrast_write_rgba_span() call.
+ */
+ SWspan *span = &(swrast->PointSpan);
+ GLuint count;
+
+ CULL_INVALID(vert);
+
+ /* Span init */
+ span->interpMask = 0;
+ span->arrayMask = SPAN_XY | SPAN_Z;
+ if (ciMode)
+ span->arrayMask |= SPAN_INDEX;
+ else
+ span->arrayMask |= SPAN_RGBA;
+ /*span->arrayMask |= SPAN_LAMBDA;*/
+ span->arrayAttribs = swrast->_ActiveAttribMask; /* we'll produce these vals */
+
+ /* need these for fragment programs */
+ span->attrStart[FRAG_ATTRIB_WPOS][3] = 1.0F;
+ span->attrStepX[FRAG_ATTRIB_WPOS][3] = 0.0F;
+ span->attrStepY[FRAG_ATTRIB_WPOS][3] = 0.0F;
+
+ /* check if we need to flush */
+ if (span->end >= MAX_WIDTH ||
+ (swrast->_RasterMask & (BLEND_BIT | LOGIC_OP_BIT | MASKING_BIT))) {
+ if (ciMode)
+ _swrast_write_index_span(ctx, span);
+ else
+ _swrast_write_rgba_span(ctx, span);
+ span->end = 0;
+ }
+ count = span->end;
-/*
- * Sprite (textured point)
- */
-#define FLAGS (RGBA | SPRITE | SPECULAR)
-#define NAME sprite_point
-#include "s_pointtemp.h"
-
+ /* fragment attributes */
+ if (ciMode) {
+ span->array->index[count] = (GLuint) vert->attrib[FRAG_ATTRIB_CI][0];
+ }
+ else {
+ span->array->rgba[count][RCOMP] = vert->color[0];
+ span->array->rgba[count][GCOMP] = vert->color[1];
+ span->array->rgba[count][BCOMP] = vert->color[2];
+ span->array->rgba[count][ACOMP] = vert->color[3];
+ }
+ ATTRIB_LOOP_BEGIN
+ COPY_4V(span->array->attribs[attr][count], vert->attrib[attr]);
+ ATTRIB_LOOP_END
-#define FLAGS (RGBA | SPRITE | SPECULAR | ATTENUATE)
-#define NAME atten_sprite_point
-#include "s_pointtemp.h"
+ /* fragment position */
+ span->array->x[count] = (GLint) vert->attrib[FRAG_ATTRIB_WPOS][0];
+ span->array->y[count] = (GLint) vert->attrib[FRAG_ATTRIB_WPOS][1];
+ span->array->z[count] = (GLint) (vert->attrib[FRAG_ATTRIB_WPOS][2] + 0.5F);
+ span->end = count + 1;
+ ASSERT(span->end <= MAX_WIDTH);
+}
-void _swrast_add_spec_terms_point( GLcontext *ctx,
- const SWvertex *v0 )
+/**
+ * Add specular color to primary color, draw point, restore original
+ * primary color.
+ */
+void
+_swrast_add_spec_terms_point(GLcontext *ctx, const SWvertex *v0)
{
- SWvertex *ncv0 = (SWvertex *)v0;
- GLchan c[1][4];
- COPY_CHAN4( c[0], ncv0->color );
- ACC_3V( ncv0->color, ncv0->specular );
- SWRAST_CONTEXT(ctx)->SpecPoint( ctx, ncv0 );
- COPY_CHAN4( ncv0->color, c[0] );
+ SWvertex *ncv0 = (SWvertex *) v0; /* cast away const */
+ GLfloat rSum, gSum, bSum;
+ GLchan cSave[4];
+
+ /* save */
+ COPY_CHAN4(cSave, ncv0->color);
+ /* sum */
+ rSum = CHAN_TO_FLOAT(ncv0->color[0]) + ncv0->attrib[FRAG_ATTRIB_COL1][0];
+ gSum = CHAN_TO_FLOAT(ncv0->color[1]) + ncv0->attrib[FRAG_ATTRIB_COL1][1];
+ bSum = CHAN_TO_FLOAT(ncv0->color[2]) + ncv0->attrib[FRAG_ATTRIB_COL1][2];
+ UNCLAMPED_FLOAT_TO_CHAN(ncv0->color[0], rSum);
+ UNCLAMPED_FLOAT_TO_CHAN(ncv0->color[1], gSum);
+ UNCLAMPED_FLOAT_TO_CHAN(ncv0->color[2], bSum);
+ /* draw */
+ SWRAST_CONTEXT(ctx)->SpecPoint(ctx, ncv0);
+ /* restore */
+ COPY_CHAN4(ncv0->color, cSave);
}
-
-/* record the current point function name */
-#ifdef DEBUG
-
-static const char *pntFuncName = NULL;
-
-#define USE(pntFunc) \
-do { \
- pntFuncName = #pntFunc; \
- /*printf("%s\n", pntFuncName);*/ \
- swrast->Point = pntFunc; \
-} while (0)
-
-#else
-
-#define USE(pntFunc) swrast->Point = pntFunc
-
-#endif
-
-
-/*
- * Examine the current context to determine which point drawing function
- * should be used.
+/**
+ * Examine current state to determine which point drawing function to use.
*/
void
-_swrast_choose_point( GLcontext *ctx )
+_swrast_choose_point(GLcontext *ctx)
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
- GLboolean rgbMode = ctx->Visual.rgbMode;
- if (ctx->RenderMode==GL_RENDER) {
+ if (ctx->RenderMode == GL_RENDER) {
if (ctx->Point.PointSprite) {
- /* GL_ARB_point_sprite / GL_NV_point_sprite */
- /* XXX this might not be good enough */
- if (ctx->Point._Attenuated)
- USE(atten_sprite_point);
- else
- USE(sprite_point);
+ swrast->Point = sprite_point;
}
else if (ctx->Point.SmoothFlag) {
- /* Smooth points */
- if (rgbMode) {
- if (ctx->Point._Attenuated || ctx->VertexProgram.PointSizeEnabled) {
- USE(atten_antialiased_rgba_point);
- }
- else if (ctx->Texture._EnabledCoordUnits) {
- USE(antialiased_tex_rgba_point);
- }
- else {
- USE(antialiased_rgba_point);
- }
- }
- else {
- USE(antialiased_ci_point);
- }
+ swrast->Point = smooth_point;
}
- else if (ctx->Point._Attenuated || ctx->VertexProgram.PointSizeEnabled) {
- if (rgbMode) {
- if (ctx->Texture._EnabledCoordUnits) {
- if (ctx->Point.SmoothFlag) {
- USE(atten_antialiased_rgba_point);
- }
- else {
- USE(atten_textured_rgba_point);
- }
- }
- else {
- USE(atten_general_rgba_point);
- }
- }
- else {
- /* ci, atten */
- USE(atten_general_ci_point);
- }
- }
- else if (ctx->Texture._EnabledCoordUnits && rgbMode) {
- /* textured */
- USE(textured_rgba_point);
- }
- else if (ctx->Point._Size != 1.0) {
- /* large points */
- if (rgbMode) {
- USE(general_rgba_point);
- }
- else {
- USE(general_ci_point);
- }
+ else if (ctx->Point._Size > 1.0 ||
+ ctx->Point._Attenuated ||
+ ctx->VertexProgram.PointSizeEnabled) {
+ swrast->Point = large_point;
}
else {
- /* single pixel points */
- if (rgbMode) {
- USE(size1_rgba_point);
- }
- else {
- USE(size1_ci_point);
- }
+ swrast->Point = pixel_point;
}
}
- else if (ctx->RenderMode==GL_FEEDBACK) {
- USE(_swrast_feedback_point);
+ else if (ctx->RenderMode == GL_FEEDBACK) {
+ swrast->Point = _swrast_feedback_point;
}
else {
/* GL_SELECT mode */
- USE(_swrast_select_point);
+ swrast->Point = _swrast_select_point;
}
}
diff --git a/src/mesa/swrast/s_pointtemp.h b/src/mesa/swrast/s_pointtemp.h
deleted file mode 100644
index 1956eeba50..0000000000
--- a/src/mesa/swrast/s_pointtemp.h
+++ /dev/null
@@ -1,429 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version: 6.5.3
- *
- * 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"),
- * 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_point_sprite:
- *
- * 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.
- */
-
-
-/*
- * Point rendering template code.
- *
- * Set FLAGS = bitwise-OR of the following tokens:
- *
- * RGBA = do rgba instead of color index
- * SMOOTH = do antialiasing
- * TEXTURE = do texture coords
- * SPECULAR = do separate specular color
- * LARGE = do points with diameter > 1 pixel
- * ATTENUATE = compute point size attenuation
- * SPRITE = GL_ARB_point_sprite / GL_NV_point_sprite
- *
- * Notes: LARGE and ATTENUATE are exclusive of each other.
- * TEXTURE requires RGBA
- */
-
-
-/*
- * NOTES on antialiased point rasterization:
- *
- * Let d = distance of fragment center from vertex.
- * if d < rmin2 then
- * fragment has 100% coverage
- * else if d > rmax2 then
- * fragment has 0% coverage
- * else
- * fragment has % coverage = (d - rmin2) / (rmax2 - rmin2)
- */
-
-
-
-static void
-NAME ( GLcontext *ctx, const SWvertex *vert )
-{
-#if FLAGS & (ATTENUATE | LARGE | SMOOTH | SPRITE)
- GLfloat size;
-#endif
-#if FLAGS & RGBA
-#if (FLAGS & ATTENUATE) && (FLAGS & SMOOTH)
- GLfloat alphaAtten;
-#endif
- const GLchan red = vert->color[0];
- const GLchan green = vert->color[1];
- const GLchan blue = vert->color[2];
- const GLchan alpha = vert->color[3];
-#endif
-#if FLAGS & SPECULAR
- const GLchan specRed = vert->specular[0];
- const GLchan specGreen = vert->specular[1];
- const GLchan specBlue = vert->specular[2];
-#endif
-#if FLAGS & INDEX
- const GLuint colorIndex = (GLuint) vert->index; /* XXX round? */
-#endif
-#if FLAGS & TEXTURE
- GLfloat attrib[FRAG_ATTRIB_MAX][4]; /* texture & varying */
- GLuint attr;
-#endif
- SWcontext *swrast = SWRAST_CONTEXT(ctx);
- SWspan *span = &(swrast->PointSpan);
-
- /* Cull primitives with malformed coordinates.
- */
- {
- float tmp = vert->win[0] + vert->win[1];
- if (IS_INF_OR_NAN(tmp))
- return;
- }
-
- /*
- * Span init
- */
- span->interpMask = SPAN_FOG;
- span->arrayMask = SPAN_XY | SPAN_Z;
- 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
-#if FLAGS & SPECULAR
- span->arrayMask |= SPAN_SPEC;
-#endif
-#if FLAGS & INDEX
- span->arrayMask |= SPAN_INDEX;
-#endif
-#if FLAGS & TEXTURE
- span->arrayMask |= (SPAN_TEXTURE | SPAN_LAMBDA);
- if (ctx->FragmentProgram._Active) {
- /* Don't divide texture s,t,r by q (use TXP to do that) */
- 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 (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);
- 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->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;
-#endif
-#if FLAGS & SPRITE
- span->arrayMask |= (SPAN_TEXTURE | SPAN_LAMBDA);
-#endif
-
- /* Compute point size if not known to be one */
-#if FLAGS & ATTENUATE
- /* first, clamp attenuated size to the user-specifed range */
- size = CLAMP(vert->pointSize, ctx->Point.MinSize, ctx->Point.MaxSize);
-#if (FLAGS & RGBA) && (FLAGS & SMOOTH)
- /* only if multisampling, compute the fade factor */
- if (ctx->Multisample.Enabled) {
- if (vert->pointSize >= ctx->Point.Threshold) {
- alphaAtten = 1.0F;
- }
- else {
- GLfloat dsize = vert->pointSize / ctx->Point.Threshold;
- alphaAtten = dsize * dsize;
- }
- }
- else {
- alphaAtten = 1.0;
- }
-#endif
-#elif FLAGS & (LARGE | SMOOTH | SPRITE)
- /* constant, non-attenuated size */
- size = ctx->Point._Size; /* this is already clamped */
-#endif
-
-
-#if FLAGS & (ATTENUATE | LARGE | SMOOTH | SPRITE)
- /***
- *** Multi-pixel points
- ***/
-
- /* do final clamping now */
- if (ctx->Point.SmoothFlag) {
- size = CLAMP(size, ctx->Const.MinPointSizeAA, ctx->Const.MaxPointSizeAA);
- }
- else {
- size = CLAMP(size, ctx->Const.MinPointSize, ctx->Const.MaxPointSize);
- }
-
- {{
- GLint x, y;
- const GLfloat radius = 0.5F * size;
- const GLuint z = (GLuint) (vert->win[2] + 0.5F);
- GLuint count;
-#if FLAGS & SMOOTH
- const GLfloat rmin = radius - 0.7071F; /* 0.7071 = sqrt(2)/2 */
- const GLfloat rmax = radius + 0.7071F;
- const GLfloat rmin2 = MAX2(0.0F, rmin * rmin);
- const GLfloat rmax2 = rmax * rmax;
- const GLfloat cscale = 1.0F / (rmax2 - rmin2);
- const GLint xmin = (GLint) (vert->win[0] - radius);
- const GLint xmax = (GLint) (vert->win[0] + radius);
- const GLint ymin = (GLint) (vert->win[1] - radius);
- const GLint ymax = (GLint) (vert->win[1] + radius);
-#else
- /* non-smooth */
- GLint xmin, xmax, ymin, ymax;
- GLint iSize = (GLint) (size + 0.5F);
- GLint iRadius;
- iSize = MAX2(1, iSize);
- iRadius = iSize / 2;
- if (iSize & 1) {
- /* odd size */
- xmin = (GLint) (vert->win[0] - iRadius);
- xmax = (GLint) (vert->win[0] + iRadius);
- ymin = (GLint) (vert->win[1] - iRadius);
- ymax = (GLint) (vert->win[1] + iRadius);
- }
- else {
- /* even size */
- xmin = (GLint) vert->win[0] - iRadius + 1;
- xmax = xmin + iSize - 1;
- ymin = (GLint) vert->win[1] - iRadius + 1;
- ymax = ymin + iSize - 1;
- }
-#endif /*SMOOTH*/
-
- /* check if we need to flush */
- if (span->end + (xmax-xmin+1) * (ymax-ymin+1) >= MAX_WIDTH ||
- (swrast->_RasterMask & (BLEND_BIT | LOGIC_OP_BIT | MASKING_BIT))) {
- if (span->end > 0) {
-#if FLAGS & RGBA
- _swrast_write_rgba_span(ctx, span);
-#else
- _swrast_write_index_span(ctx, span);
-#endif
- span->end = 0;
- }
- }
-
- /*
- * OK, generate fragments
- */
- count = span->end;
- (void) radius;
- for (y = ymin; y <= ymax; y++) {
- /* check if we need to flush */
- if (count + (xmax-xmin+1) >= MAX_WIDTH) {
- span->end = count;
-#if FLAGS & RGBA
- _swrast_write_rgba_span(ctx, span);
-#else
- _swrast_write_index_span(ctx, span);
-#endif
- count = span->end = 0;
- }
- for (x = xmin; x <= xmax; x++) {
-#if FLAGS & SPRITE
- GLuint u;
-#endif
-
-#if FLAGS & RGBA
- span->array->rgba[count][RCOMP] = red;
- span->array->rgba[count][GCOMP] = green;
- span->array->rgba[count][BCOMP] = blue;
- span->array->rgba[count][ACOMP] = alpha;
-#endif
-#if FLAGS & SPECULAR
- span->array->spec[count][RCOMP] = specRed;
- span->array->spec[count][GCOMP] = specGreen;
- span->array->spec[count][BCOMP] = specBlue;
-#endif
-#if FLAGS & INDEX
- span->array->index[count] = colorIndex;
-#endif
-#if FLAGS & TEXTURE
- 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
-
-#if FLAGS & SMOOTH
- /* compute coverage */
- {
- const GLfloat dx = x - vert->win[0] + 0.5F;
- const GLfloat dy = y - vert->win[1] + 0.5F;
- const GLfloat dist2 = dx * dx + dy * dy;
- if (dist2 < rmax2) {
- if (dist2 >= rmin2) {
- /* compute partial coverage */
- span->array->coverage[count] = 1.0F - (dist2 - rmin2) * cscale;
-#if FLAGS & INDEX
- /* coverage in [0,15] */
- span->array->coverage[count] *= 15.0;
-#endif
- }
- else {
- /* full coverage */
- span->array->coverage[count] = 1.0F;
- }
-
- span->array->x[count] = x;
- span->array->y[count] = y;
- span->array->z[count] = z;
-
-#if (FLAGS & ATTENUATE) && (FLAGS & RGBA)
- span->array->rgba[count][ACOMP] = (GLchan) (alpha * alphaAtten);
-#elif FLAGS & RGBA
- span->array->rgba[count][ACOMP] = alpha;
-#endif /*ATTENUATE*/
- count++;
- } /*if*/
- }
-
-#else /*SMOOTH*/
-
- /* not smooth (square points) */
- span->array->x[count] = x;
- span->array->y[count] = y;
- span->array->z[count] = z;
-
-#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;
- GLfloat t, r;
- if (ctx->Point.SpriteOrigin == GL_LOWER_LEFT)
- t = 0.5F + (y + 0.5F - vert->win[1]) / size;
- else /* GL_UPPER_LEFT */
- t = 0.5F - (y + 0.5F - vert->win[1]) / size;
- if (ctx->Point.SpriteRMode == GL_ZERO)
- r = 0.0F;
- else if (ctx->Point.SpriteRMode == GL_S)
- r = vert->attrib[attr][0];
- else /* GL_R */
- 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->attribs[attr][count],
- vert->attrib[attr]);
- }
- }
- }
-#endif /*SPRITE*/
-
- count++; /* square point */
-
-#endif /*SMOOTH*/
-
- } /*for x*/
- } /*for y*/
- span->end = count;
- }}
-
-#else /* LARGE | ATTENUATE | SMOOTH | SPRITE */
-
- /***
- *** Single-pixel points
- ***/
- {{
- GLuint count;
-
- /* check if we need to flush */
- if (span->end >= MAX_WIDTH ||
- (swrast->_RasterMask & (BLEND_BIT | LOGIC_OP_BIT | MASKING_BIT))) {
-#if FLAGS & RGBA
- _swrast_write_rgba_span(ctx, span);
-#else
- _swrast_write_index_span(ctx, span);
-#endif
- span->end = 0;
- }
-
- count = span->end;
-
-#if FLAGS & RGBA
- span->array->rgba[count][RCOMP] = red;
- span->array->rgba[count][GCOMP] = green;
- span->array->rgba[count][BCOMP] = blue;
- span->array->rgba[count][ACOMP] = alpha;
-#endif
-#if FLAGS & SPECULAR
- span->array->spec[count][RCOMP] = specRed;
- span->array->spec[count][GCOMP] = specGreen;
- span->array->spec[count][BCOMP] = specBlue;
-#endif
-#if FLAGS & INDEX
- span->array->index[count] = colorIndex;
-#endif
-#if FLAGS & TEXTURE
- for (attr = swrast->_MinFragmentAttrib; attr < swrast->_MaxFragmentAttrib; attr++) {
- if (swrast->_FragmentAttribs & (1 << attr)) {
- COPY_4V(span->array->attribs[attr][count], attribs[attr]);
- }
- }
-#endif
-
- span->array->x[count] = (GLint) vert->win[0];
- span->array->y[count] = (GLint) vert->win[1];
- span->array->z[count] = (GLint) (vert->win[2] + 0.5F);
- span->end = count + 1;
- }}
-
-#endif /* LARGE || ATTENUATE || SMOOTH */
-
- ASSERT(span->end <= MAX_WIDTH);
-}
-
-
-#undef FLAGS
-#undef NAME
diff --git a/src/mesa/swrast/s_span.c b/src/mesa/swrast/s_span.c
index b0c04ad021..f23272c2be 100644
--- a/src/mesa/swrast/s_span.c
+++ b/src/mesa/swrast/s_span.c
@@ -1,8 +1,8 @@
/*
* Mesa 3-D graphics library
- * Version: 6.5
+ * Version: 7.1
*
- * 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"),
@@ -52,44 +52,30 @@
/**
- * Init span's Z interpolation values to the RasterPos Z.
- * Used during setup for glDraw/CopyPixels.
+ * Set default fragment attributes for the span using the
+ * current raster values. Used prior to glDraw/CopyPixels
+ * and glBitmap.
*/
void
-_swrast_span_default_z( GLcontext *ctx, SWspan *span )
+_swrast_span_default_attribs(GLcontext *ctx, SWspan *span)
{
- const GLfloat depthMax = ctx->DrawBuffer->_DepthMaxF;
- if (ctx->DrawBuffer->Visual.depthBits <= 16)
- span->z = FloatToFixed(ctx->Current.RasterPos[2] * depthMax + 0.5F);
- else
- span->z = (GLint) (ctx->Current.RasterPos[2] * depthMax + 0.5F);
- span->zStep = 0;
- span->interpMask |= SPAN_Z;
-}
-
-
-/**
- * Init span's fog interpolation values to the RasterPos fog.
- * Used during setup for glDraw/CopyPixels.
- */
-void
-_swrast_span_default_fog( GLcontext *ctx, SWspan *span )
-{
- 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;
-}
+ /* Z*/
+ {
+ const GLfloat depthMax = ctx->DrawBuffer->_DepthMaxF;
+ if (ctx->DrawBuffer->Visual.depthBits <= 16)
+ span->z = FloatToFixed(ctx->Current.RasterPos[2] * depthMax + 0.5F);
+ else
+ span->z = (GLint) (ctx->Current.RasterPos[2] * depthMax + 0.5F);
+ span->zStep = 0;
+ span->interpMask |= SPAN_Z;
+ }
+ /* W (for perspective correction) */
+ span->attrStart[FRAG_ATTRIB_WPOS][3] = 1.0;
+ span->attrStepX[FRAG_ATTRIB_WPOS][3] = 0.0;
+ span->attrStepY[FRAG_ATTRIB_WPOS][3] = 0.0;
-/**
- * Init span's rgba or index interpolation values to the RasterPos color.
- * Used during setup for glDraw/CopyPixels.
- */
-void
-_swrast_span_default_color( GLcontext *ctx, SWspan *span )
-{
+ /* primary color, or color index */
if (ctx->Visual.rgbMode) {
GLchan r, g, b, a;
UNCLAMPED_FLOAT_TO_CHAN(r, ctx->Current.RasterColor[0]);
@@ -112,92 +98,136 @@ _swrast_span_default_color( GLcontext *ctx, SWspan *span )
span->blueStep = 0;
span->alphaStep = 0;
span->interpMask |= SPAN_RGBA;
+
+ COPY_4V(span->attrStart[FRAG_ATTRIB_COL0], ctx->Current.RasterColor);
+ ASSIGN_4V(span->attrStepX[FRAG_ATTRIB_COL0], 0.0, 0.0, 0.0, 0.0);
+ ASSIGN_4V(span->attrStepY[FRAG_ATTRIB_COL0], 0.0, 0.0, 0.0, 0.0);
}
else {
span->index = FloatToFixed(ctx->Current.RasterIndex);
span->indexStep = 0;
span->interpMask |= SPAN_INDEX;
}
-}
+ /* Secondary color */
+ if (ctx->Visual.rgbMode && (ctx->Light.Enabled || ctx->Fog.ColorSumEnabled))
+ {
+ COPY_4V(span->attrStart[FRAG_ATTRIB_COL1], ctx->Current.RasterSecondaryColor);
+ ASSIGN_4V(span->attrStepX[FRAG_ATTRIB_COL1], 0.0, 0.0, 0.0, 0.0);
+ ASSIGN_4V(span->attrStepY[FRAG_ATTRIB_COL1], 0.0, 0.0, 0.0, 0.0);
+ }
+
+ /* fog */
+ {
+ const SWcontext *swrast = SWRAST_CONTEXT(ctx);
+ GLfloat fogVal; /* a coord or a blend factor */
+ if (swrast->_PreferPixelFog) {
+ /* fog blend factors will be computed from fog coordinates per pixel */
+ fogVal = ctx->Current.RasterDistance;
+ }
+ else {
+ /* fog blend factor should be computed from fogcoord now */
+ fogVal = _swrast_z_to_fogfactor(ctx, ctx->Current.RasterDistance);
+ }
+ span->attrStart[FRAG_ATTRIB_FOGC][0] = fogVal;
+ span->attrStepX[FRAG_ATTRIB_FOGC][0] = 0.0;
+ span->attrStepY[FRAG_ATTRIB_FOGC][0] = 0.0;
+ }
-void
-_swrast_span_default_secondary_color(GLcontext *ctx, SWspan *span)
-{
- if (ctx->Visual.rgbMode) {
- GLchan r, g, b, a;
- UNCLAMPED_FLOAT_TO_CHAN(r, ctx->Current.RasterSecondaryColor[0]);
- UNCLAMPED_FLOAT_TO_CHAN(g, ctx->Current.RasterSecondaryColor[1]);
- UNCLAMPED_FLOAT_TO_CHAN(b, ctx->Current.RasterSecondaryColor[2]);
- UNCLAMPED_FLOAT_TO_CHAN(a, ctx->Current.RasterSecondaryColor[3]);
-#if CHAN_TYPE == GL_FLOAT
- span->specRed = r;
- span->specGreen = g;
- span->specBlue = b;
- /*span->specAlpha = a;*/
-#else
- span->specRed = IntToFixed(r);
- span->specGreen = IntToFixed(g);
- span->specBlue = IntToFixed(b);
- /*span->specAlpha = IntToFixed(a);*/
-#endif
- span->specRedStep = 0;
- span->specGreenStep = 0;
- span->specBlueStep = 0;
- /*span->specAlphaStep = 0;*/
- span->interpMask |= SPAN_SPEC;
+ /* texcoords */
+ {
+ 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._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->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->attrStart[attr], 0.0F, 0.0F, 0.0F, 1.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);
+ }
}
}
/**
- * Init span's texcoord interpolation values to the RasterPos texcoords.
- * Used during setup for glDraw/CopyPixels.
+ * Interpolate the active attributes (and'd with attrMask) to
+ * fill in span->array->attribs[].
+ * Perspective correction will be done. The point/line/triangle function
+ * should have computed attrStart/Step values for FRAG_ATTRIB_WPOS[3]!
*/
-void
-_swrast_span_default_texcoords( GLcontext *ctx, SWspan *span )
+static INLINE void
+interpolate_active_attribs(GLcontext *ctx, SWspan *span, GLbitfield attrMask)
{
- 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._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->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->attrStart[attr], 0.0F, 0.0F, 0.0F, 1.0F);
+ const SWcontext *swrast = SWRAST_CONTEXT(ctx);
+
+ /*
+ * Don't overwrite existing array values, such as colors that may have
+ * been produced by glDraw/CopyPixels.
+ */
+ attrMask &= ~span->arrayAttribs;
+
+ ATTRIB_LOOP_BEGIN
+ if (attrMask & (1 << attr)) {
+ 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++) {
+ const GLfloat invW = 1.0f / w;
+ 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;
+ }
+ ASSERT((span->arrayAttribs & (1 << attr)) == 0);
+ span->arrayAttribs |= (1 << attr);
}
- 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;
+ ATTRIB_LOOP_END
}
/**
- * Interpolate primary colors to fill in the span->array->color array.
+ * Interpolate primary colors to fill in the span->array->rgba8 (or rgb16)
+ * color array.
*/
static INLINE void
-interpolate_colors(SWspan *span)
+interpolate_int_colors(GLcontext *ctx, SWspan *span)
{
const GLuint n = span->end;
GLuint i;
- ASSERT((span->interpMask & SPAN_RGBA) &&
- !(span->arrayMask & SPAN_RGBA));
+#if CHAN_BITS != 32
+ ASSERT(!(span->arrayMask & SPAN_RGBA));
+#endif
switch (span->array->ChanType) {
#if CHAN_BITS != 32
case GL_UNSIGNED_BYTE:
{
- GLubyte (*rgba)[4] = span->array->color.sz1.rgba;
+ GLubyte (*rgba)[4] = span->array->rgba8;
if (span->interpMask & SPAN_FLAT) {
GLubyte color[4];
color[RCOMP] = FixedToInt(span->red);
@@ -232,7 +262,7 @@ interpolate_colors(SWspan *span)
break;
case GL_UNSIGNED_SHORT:
{
- GLushort (*rgba)[4] = span->array->color.sz2.rgba;
+ GLushort (*rgba)[4] = span->array->rgba16;
if (span->interpMask & SPAN_FLAT) {
GLushort color[4];
color[RCOMP] = FixedToInt(span->red);
@@ -244,7 +274,7 @@ interpolate_colors(SWspan *span)
}
}
else {
- GLushort (*rgba)[4] = span->array->color.sz2.rgba;
+ GLushort (*rgba)[4] = span->array->rgba16;
GLfixed r, g, b, a;
GLint dr, dg, db, da;
r = span->red;
@@ -270,162 +300,76 @@ interpolate_colors(SWspan *span)
break;
#endif
case GL_FLOAT:
- {
- GLfloat (*rgba)[4] = span->array->attribs[FRAG_ATTRIB_COL0];
- GLfloat r, g, b, a, dr, dg, db, da;
- r = span->red;
- g = span->green;
- b = span->blue;
- a = span->alpha;
- if (span->interpMask & SPAN_FLAT) {
- dr = dg = db = da = 0.0;
- }
- else {
- dr = span->redStep;
- dg = span->greenStep;
- db = span->blueStep;
- da = span->alphaStep;
- }
- for (i = 0; i < n; i++) {
- rgba[i][RCOMP] = r;
- rgba[i][GCOMP] = g;
- rgba[i][BCOMP] = b;
- rgba[i][ACOMP] = a;
- r += dr;
- g += dg;
- b += db;
- a += da;
- }
- }
+ interpolate_active_attribs(ctx, span, FRAG_BIT_COL0);
break;
default:
- _mesa_problem(NULL, "bad datatype in interpolate_colors");
+ _mesa_problem(NULL, "bad datatype in interpolate_int_colors");
}
span->arrayMask |= SPAN_RGBA;
}
/**
- * Interpolate specular/secondary colors.
+ * Populate the FRAG_ATTRIB_COL0 array.
*/
static INLINE void
-interpolate_specular(SWspan *span)
+interpolate_float_colors(SWspan *span)
{
+ GLfloat (*col0)[4] = span->array->attribs[FRAG_ATTRIB_COL0];
const GLuint n = span->end;
GLuint i;
- switch (span->array->ChanType) {
-#if CHAN_BITS != 32
- case GL_UNSIGNED_BYTE:
- {
- GLubyte (*spec)[4] = span->array->color.sz1.spec;
- if (span->interpMask & SPAN_FLAT) {
- GLubyte color[4];
- color[RCOMP] = FixedToInt(span->specRed);
- color[GCOMP] = FixedToInt(span->specGreen);
- color[BCOMP] = FixedToInt(span->specBlue);
- color[ACOMP] = 0;
- for (i = 0; i < n; i++) {
- COPY_4UBV(spec[i], color);
- }
- }
- else {
- GLfixed r = span->specRed;
- GLfixed g = span->specGreen;
- GLfixed b = span->specBlue;
- GLint dr = span->specRedStep;
- GLint dg = span->specGreenStep;
- GLint db = span->specBlueStep;
- for (i = 0; i < n; i++) {
- spec[i][RCOMP] = CLAMP(FixedToChan(r), 0, 255);
- spec[i][GCOMP] = CLAMP(FixedToChan(g), 0, 255);
- spec[i][BCOMP] = CLAMP(FixedToChan(b), 0, 255);
- spec[i][ACOMP] = 0;
- r += dr;
- g += dg;
- b += db;
- }
- }
+ assert(!(span->arrayAttribs & FRAG_BIT_COL0));
+
+ if (span->arrayMask & SPAN_RGBA) {
+ /* convert array of int colors */
+ for (i = 0; i < n; i++) {
+ col0[i][0] = UBYTE_TO_FLOAT(span->array->rgba8[i][0]);
+ col0[i][1] = UBYTE_TO_FLOAT(span->array->rgba8[i][1]);
+ col0[i][2] = UBYTE_TO_FLOAT(span->array->rgba8[i][2]);
+ col0[i][3] = UBYTE_TO_FLOAT(span->array->rgba8[i][3]);
}
- break;
- case GL_UNSIGNED_SHORT:
- {
- GLushort (*spec)[4] = span->array->color.sz2.spec;
- if (span->interpMask & SPAN_FLAT) {
- GLushort color[4];
- color[RCOMP] = FixedToInt(span->specRed);
- color[GCOMP] = FixedToInt(span->specGreen);
- color[BCOMP] = FixedToInt(span->specBlue);
- color[ACOMP] = 0;
- for (i = 0; i < n; i++) {
- COPY_4V(spec[i], color);
- }
- }
- else {
- GLfixed r = FloatToFixed(span->specRed);
- GLfixed g = FloatToFixed(span->specGreen);
- GLfixed b = FloatToFixed(span->specBlue);
- GLint dr = FloatToFixed(span->specRedStep);
- GLint dg = FloatToFixed(span->specGreenStep);
- GLint db = FloatToFixed(span->specBlueStep);
- for (i = 0; i < n; i++) {
- spec[i][RCOMP] = FixedToInt(r);
- spec[i][GCOMP] = FixedToInt(g);
- spec[i][BCOMP] = FixedToInt(b);
- spec[i][ACOMP] = 0;
- r += dr;
- g += dg;
- b += db;
- }
+ }
+ else {
+ /* interpolate red/green/blue/alpha to get float colors */
+ ASSERT(span->interpMask & SPAN_RGBA);
+ if (span->interpMask & SPAN_FLAT) {
+ GLfloat r = FixedToFloat(span->red);
+ GLfloat g = FixedToFloat(span->green);
+ GLfloat b = FixedToFloat(span->blue);
+ GLfloat a = FixedToFloat(span->alpha);
+ for (i = 0; i < n; i++) {
+ ASSIGN_4V(col0[i], r, g, b, a);
}
}
- break;
-#endif
- case GL_FLOAT:
- {
- 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));
- GLfloat b = CHAN_TO_FLOAT(FixedToChan(span->specBlue));
-#else
- GLfloat r = span->specRed;
- GLfloat g = span->specGreen;
- GLfloat b = span->specBlue;
-#endif
- GLfloat dr, dg, db;
- if (span->interpMask & SPAN_FLAT) {
- dr = dg = db = 0.0;
- }
- else {
-#if CHAN_BITS <= 16
- dr = CHAN_TO_FLOAT(FixedToChan(span->specRedStep));
- dg = CHAN_TO_FLOAT(FixedToChan(span->specGreenStep));
- db = CHAN_TO_FLOAT(FixedToChan(span->specBlueStep));
-#else
- dr = span->specRedStep;
- dg = span->specGreenStep;
- db = span->specBlueStep;
-#endif
- }
+ else {
+ GLfloat r = FixedToFloat(span->red);
+ GLfloat g = FixedToFloat(span->green);
+ GLfloat b = FixedToFloat(span->blue);
+ GLfloat a = FixedToFloat(span->alpha);
+ GLfloat dr = FixedToFloat(span->redStep);
+ GLfloat dg = FixedToFloat(span->greenStep);
+ GLfloat db = FixedToFloat(span->blueStep);
+ GLfloat da = FixedToFloat(span->alphaStep);
for (i = 0; i < n; i++) {
- spec[i][RCOMP] = r;
- spec[i][GCOMP] = g;
- spec[i][BCOMP] = b;
- spec[i][ACOMP] = 0.0F;
+ col0[i][0] = r;
+ col0[i][1] = g;
+ col0[i][2] = b;
+ col0[i][3] = a;
r += dr;
g += dg;
b += db;
+ a += da;
}
}
- break;
- default:
- _mesa_problem(NULL, "bad datatype in interpolate_specular");
}
- span->arrayMask |= SPAN_SPEC;
+
+ span->arrayAttribs |= FRAG_BIT_COL0;
+ span->array->ChanType = GL_FLOAT;
}
+
/* Fill in the span.color.index array from the interpolation values */
static INLINE void
interpolate_indexes(GLcontext *ctx, SWspan *span)
@@ -436,8 +380,8 @@ interpolate_indexes(GLcontext *ctx, SWspan *span)
GLuint *indexes = span->array->index;
GLuint i;
(void) ctx;
- ASSERT((span->interpMask & SPAN_INDEX) &&
- !(span->arrayMask & SPAN_INDEX));
+
+ ASSERT(!(span->arrayMask & SPAN_INDEX));
if ((span->interpMask & SPAN_FLAT) || (indexStep == 0)) {
/* constant color */
@@ -458,35 +402,16 @@ interpolate_indexes(GLcontext *ctx, SWspan *span)
}
-/* Fill in the span.array.fog values from the interpolation values */
-static INLINE void
-interpolate_fog(const GLcontext *ctx, SWspan *span)
-{
- 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->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][0] = fogCoord / w;
- fogCoord += fogStep;
- w += wStep;
- }
- span->arrayMask |= SPAN_FOG;
-}
-
-
-/* Fill in the span.zArray array from the interpolation values */
+/**
+ * Fill in the span.zArray array from the span->z, zStep values.
+ */
void
_swrast_span_interpolate_z( const GLcontext *ctx, SWspan *span )
{
const GLuint n = span->end;
GLuint i;
- ASSERT((span->interpMask & SPAN_Z) &&
- !(span->arrayMask & SPAN_Z));
+ ASSERT(!(span->arrayMask & SPAN_Z));
if (ctx->DrawBuffer->Visual.depthBits <= 16) {
GLfixed zval = span->z;
@@ -510,7 +435,8 @@ _swrast_span_interpolate_z( const GLcontext *ctx, SWspan *span )
}
-/*
+/**
+ * Compute mipmap LOD from partial derivatives.
* This the ideal solution, as given in the OpenGL spec.
*/
#if 0
@@ -532,8 +458,9 @@ compute_lambda(GLfloat dsdx, GLfloat dsdy, GLfloat dtdx, GLfloat dtdy,
#endif
-/*
- * This is a faster approximation
+/**
+ * Compute mipmap LOD from partial derivatives.
+ * This is a faster approximation than above function.
*/
GLfloat
_swrast_compute_lambda(GLfloat dsdx, GLfloat dsdy, GLfloat dtdx, GLfloat dtdy,
@@ -558,14 +485,15 @@ _swrast_compute_lambda(GLfloat dsdx, GLfloat dsdy, GLfloat dtdx, GLfloat dtdy,
/**
- * Fill in the span.texcoords array from the interpolation values.
+ * Fill in the span.array->attrib[FRAG_ATTRIB_TEXn] arrays from the
+ * using the attrStart/Step values.
+ *
+ * This function only used during fixed-function fragment processing.
+ *
* Note: in the places where we divide by Q (or mult by invQ) we're
* really doing two things: perspective correction and texcoord
* projection. Remember, for texcoord (s,t,r,q) we need to index
* texels with (s/q, t/q, r/q).
- * If we're using a fragment program, we never do the division
- * for texcoord projection. That's done by the TXP instruction
- * or user-written code.
*/
static void
interpolate_texcoords(GLcontext *ctx, SWspan *span)
@@ -574,11 +502,6 @@ interpolate_texcoords(GLcontext *ctx, SWspan *span)
= (ctx->Texture._EnabledCoordUnits > 1) ? ctx->Const.MaxTextureUnits : 1;
GLuint u;
- ASSERT(span->interpMask & SPAN_TEXTURE);
- ASSERT(!(span->arrayMask & SPAN_TEXTURE));
-
- span->arrayMask |= SPAN_TEXTURE;
-
/* XXX CoordUnits vs. ImageUnits */
for (u = 0; u < maxUnit; u++) {
if (ctx->Texture._EnabledCoordUnits & (1 << u)) {
@@ -710,55 +633,6 @@ interpolate_texcoords(GLcontext *ctx, SWspan *span)
}
-
-/**
- * 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 var;
- const GLbitfield inputsUsed = ctx->FragmentProgram._Current->Base.InputsRead;
-
- ASSERT(span->interpMask & SPAN_VARYING);
- ASSERT(!(span->arrayMask & SPAN_VARYING));
-
- span->arrayMask |= SPAN_VARYING;
-
- 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->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;
- }
- }
- }
-}
-
-
/**
* Fill in the arrays->attribs[FRAG_ATTRIB_WPOS] array.
*/
@@ -767,6 +641,9 @@ interpolate_wpos(GLcontext *ctx, SWspan *span)
{
GLfloat (*wpos)[4] = span->array->attribs[FRAG_ATTRIB_WPOS];
GLuint i;
+ const GLfloat zScale = 1.0 / ctx->DrawBuffer->_DepthMaxF;
+ GLfloat w, dw;
+
if (span->arrayMask & SPAN_XY) {
for (i = 0; i < span->end; i++) {
wpos[i][0] = (GLfloat) span->array->x[i];
@@ -779,10 +656,13 @@ interpolate_wpos(GLcontext *ctx, SWspan *span)
wpos[i][1] = (GLfloat) span->y;
}
}
+
+ w = span->attrStart[FRAG_ATTRIB_WPOS][3];
+ dw = span->attrStepX[FRAG_ATTRIB_WPOS][3];
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];
+ wpos[i][2] = (GLfloat) span->array->z[i] * zScale;
+ wpos[i][3] = w;
+ w += dw;
}
}
@@ -914,7 +794,9 @@ _swrast_write_index_span( GLcontext *ctx, SWspan *span)
ASSERT(span->primitive == GL_POINT || span->primitive == GL_LINE ||
span->primitive == GL_POLYGON || span->primitive == GL_BITMAP);
ASSERT((span->interpMask | span->arrayMask) & SPAN_INDEX);
+ /*
ASSERT((span->interpMask & span->arrayMask) == 0);
+ */
if (span->arrayMask & SPAN_MASK) {
/* mask was initialized by caller, probably glBitmap */
@@ -961,7 +843,7 @@ _swrast_write_index_span( GLcontext *ctx, SWspan *span)
/* Stencil and Z testing */
if (ctx->Depth.Test || ctx->Stencil.Enabled) {
- if (span->interpMask & SPAN_Z)
+ if (!(span->arrayMask & SPAN_Z))
_swrast_span_interpolate_z(ctx, span);
if (ctx->Stencil.Enabled) {
@@ -1002,7 +884,7 @@ _swrast_write_index_span( GLcontext *ctx, SWspan *span)
ctx->Color.IndexLogicOpEnabled ||
ctx->Color.IndexMask != 0xffffffff ||
(span->arrayMask & SPAN_COVERAGE)) {
- if (span->interpMask & SPAN_INDEX) {
+ if (!(span->arrayMask & SPAN_INDEX) /*span->interpMask & SPAN_INDEX*/) {
interpolate_indexes(ctx, span);
}
}
@@ -1051,7 +933,7 @@ _swrast_write_index_span( GLcontext *ctx, SWspan *span)
_swrast_mask_ci_span(ctx, rb, span);
}
- if ((span->interpMask & SPAN_INDEX) && span->indexStep == 0) {
+ if (!(span->arrayMask & SPAN_INDEX) && span->indexStep == 0) {
/* all fragments have same color index */
GLubyte index8;
GLushort index16;
@@ -1131,63 +1013,52 @@ _swrast_write_index_span( GLcontext *ctx, SWspan *span)
/**
- * Add specular color to base color. This is used only when
- * GL_LIGHT_MODEL_COLOR_CONTROL = GL_SEPARATE_SPECULAR_COLOR.
+ * Add specular colors to primary colors.
+ * Only called during fixed-function operation.
+ * Result is float color array (FRAG_ATTRIB_COL0).
*/
static INLINE void
add_specular(GLcontext *ctx, SWspan *span)
{
- switch (span->array->ChanType) {
- case GL_UNSIGNED_BYTE:
- {
- GLubyte (*rgba)[4] = span->array->color.sz1.rgba;
- GLubyte (*spec)[4] = span->array->color.sz1.spec;
- GLuint i;
- for (i = 0; i < span->end; i++) {
- GLint r = rgba[i][RCOMP] + spec[i][RCOMP];
- GLint g = rgba[i][GCOMP] + spec[i][GCOMP];
- GLint b = rgba[i][BCOMP] + spec[i][BCOMP];
- GLint a = rgba[i][ACOMP] + spec[i][ACOMP];
- rgba[i][RCOMP] = MIN2(r, 255);
- rgba[i][GCOMP] = MIN2(g, 255);
- rgba[i][BCOMP] = MIN2(b, 255);
- rgba[i][ACOMP] = MIN2(a, 255);
- }
+ const SWcontext *swrast = SWRAST_CONTEXT(ctx);
+ const GLubyte *mask = span->array->mask;
+ GLfloat (*col0)[4] = span->array->attribs[FRAG_ATTRIB_COL0];
+ GLfloat (*col1)[4] = span->array->attribs[FRAG_ATTRIB_COL1];
+ GLuint i;
+
+ ASSERT(!ctx->FragmentProgram._Current);
+ ASSERT(span->arrayMask & SPAN_RGBA);
+ ASSERT(swrast->_ActiveAttribMask & FRAG_BIT_COL1);
+
+ if (span->array->ChanType == GL_FLOAT) {
+ if ((span->arrayAttribs & FRAG_BIT_COL0) == 0) {
+ interpolate_active_attribs(ctx, span, FRAG_BIT_COL0);
}
- break;
- case GL_UNSIGNED_SHORT:
- {
- GLushort (*rgba)[4] = span->array->color.sz2.rgba;
- GLushort (*spec)[4] = span->array->color.sz2.spec;
- GLuint i;
- for (i = 0; i < span->end; i++) {
- GLint r = rgba[i][RCOMP] + spec[i][RCOMP];
- GLint g = rgba[i][GCOMP] + spec[i][GCOMP];
- GLint b = rgba[i][BCOMP] + spec[i][BCOMP];
- GLint a = rgba[i][ACOMP] + spec[i][ACOMP];
- rgba[i][RCOMP] = MIN2(r, 65535);
- rgba[i][GCOMP] = MIN2(g, 65535);
- rgba[i][BCOMP] = MIN2(b, 65535);
- rgba[i][ACOMP] = MIN2(a, 65535);
- }
+ }
+ else {
+ /* need float colors */
+ if ((span->arrayAttribs & FRAG_BIT_COL0) == 0) {
+ interpolate_float_colors(span);
}
- break;
- case GL_FLOAT:
- {
- 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];
- rgba[i][GCOMP] += spec[i][GCOMP];
- rgba[i][BCOMP] += spec[i][BCOMP];
- rgba[i][ACOMP] += spec[i][ACOMP];
- }
+ }
+
+ if ((span->arrayAttribs & FRAG_BIT_COL1) == 0) {
+ /* XXX could avoid this and interpolate COL1 in the loop below */
+ interpolate_active_attribs(ctx, span, FRAG_BIT_COL1);
+ }
+
+ ASSERT(span->arrayAttribs & FRAG_BIT_COL0);
+ ASSERT(span->arrayAttribs & FRAG_BIT_COL1);
+
+ for (i = 0; i < span->end; i++) {
+ if (mask[i]) {
+ col0[i][0] += col1[i][0];
+ col0[i][1] += col1[i][1];
+ col0[i][2] += col1[i][2];
}
- break;
- default:
- _mesa_problem(ctx, "Invalid datatype in add_specular");
}
+
+ span->array->ChanType = GL_FLOAT;
}
@@ -1200,7 +1071,7 @@ apply_aa_coverage(SWspan *span)
const GLfloat *coverage = span->array->coverage;
GLuint i;
if (span->array->ChanType == GL_UNSIGNED_BYTE) {
- GLubyte (*rgba)[4] = span->array->color.sz1.rgba;
+ GLubyte (*rgba)[4] = span->array->rgba8;
for (i = 0; i < span->end; i++) {
const GLfloat a = rgba[i][ACOMP] * coverage[i];
rgba[i][ACOMP] = (GLubyte) CLAMP(a, 0.0, 255.0);
@@ -1209,7 +1080,7 @@ apply_aa_coverage(SWspan *span)
}
}
else if (span->array->ChanType == GL_UNSIGNED_SHORT) {
- GLushort (*rgba)[4] = span->array->color.sz2.rgba;
+ GLushort (*rgba)[4] = span->array->rgba16;
for (i = 0; i < span->end; i++) {
const GLfloat a = rgba[i][ACOMP] * coverage[i];
rgba[i][ACOMP] = (GLushort) CLAMP(a, 0.0, 65535.0);
@@ -1219,6 +1090,7 @@ apply_aa_coverage(SWspan *span)
GLfloat (*rgba)[4] = span->array->attribs[FRAG_ATTRIB_COL0];
for (i = 0; i < span->end; i++) {
rgba[i][ACOMP] = rgba[i][ACOMP] * coverage[i];
+ /* clamp later */
}
}
}
@@ -1258,18 +1130,18 @@ convert_color_type(SWspan *span, GLenum newType, GLuint output)
span->array->ChanType = GL_FLOAT;
}
else if (span->array->ChanType == GL_UNSIGNED_BYTE) {
- src = span->array->color.sz1.rgba;
+ src = span->array->rgba8;
}
else {
ASSERT(span->array->ChanType == GL_UNSIGNED_SHORT);
- src = span->array->color.sz2.rgba;
+ src = span->array->rgba16;
}
if (newType == GL_UNSIGNED_BYTE) {
- dst = span->array->color.sz1.rgba;
+ dst = span->array->rgba8;
}
else if (newType == GL_UNSIGNED_SHORT) {
- dst = span->array->color.sz2.rgba;
+ dst = span->array->rgba16;
}
else {
dst = span->array->attribs[FRAG_ATTRIB_COL0];
@@ -1280,6 +1152,7 @@ convert_color_type(SWspan *span, GLenum newType, GLuint output)
span->end, span->array->mask);
span->array->ChanType = newType;
+ span->array->rgba = dst;
}
@@ -1301,43 +1174,26 @@ shade_texture_span(GLcontext *ctx, SWspan *span)
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->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 ((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->attribs[FRAG_ATTRIB_COL0],
- span->end, span->array->mask);
+ /* programmable shading */
+ if (span->primitive == GL_BITMAP && span->array->ChanType != GL_FLOAT) {
+ convert_color_type(span, GL_FLOAT, 0);
}
- span->array->ChanType = newType;
-
- /* fragment programs/shaders may need specular, fog and Z coords */
- if ((inputsRead & FRAG_BIT_COL1) && (span->interpMask & SPAN_SPEC))
- interpolate_specular(span);
-
- if ((inputsRead & FRAG_BIT_FOGC) && (span->interpMask & SPAN_FOG))
- interpolate_fog(ctx, span);
+ if (span->primitive != GL_POINT) {
+ /* for points, we populated the arrays already */
+ interpolate_active_attribs(ctx, span, ~0);
+ }
+ span->array->ChanType = GL_FLOAT;
- if (span->interpMask & SPAN_Z)
+ if (!(span->arrayMask & SPAN_Z))
_swrast_span_interpolate_z (ctx, span);
- if ((inputsRead >= FRAG_BIT_VAR0) && (span->interpMask & SPAN_VARYING))
- interpolate_varying(ctx, span);
-
+#if 0
if (inputsRead & FRAG_BIT_WPOS)
+#else
+ /* XXX always interpolate wpos so that DDX/DDY work */
+#endif
interpolate_wpos(ctx, span);
/* Run fragment program/shader now */
@@ -1349,8 +1205,20 @@ shade_texture_span(GLcontext *ctx, SWspan *span)
_swrast_exec_fragment_shader(ctx, span);
}
}
- else if (ctx->Texture._EnabledUnits && (span->arrayMask & SPAN_TEXTURE)) {
+ else if (ctx->Texture._EnabledUnits) {
/* conventional texturing */
+
+#if CHAN_BITS == 32
+ if ((span->arrayAttribs & FRAG_BIT_COL0) == 0) {
+ interpolate_int_colors(ctx, span);
+ }
+#else
+ if (!(span->arrayMask & SPAN_RGBA))
+ interpolate_int_colors(ctx, span);
+#endif
+ if ((span->arrayAttribs & FRAG_BITS_TEX_ANY) == 0x0)
+ interpolate_texcoords(ctx, span);
+
_swrast_texture_span(ctx, span);
}
}
@@ -1371,13 +1239,14 @@ _swrast_write_rgba_span( GLcontext *ctx, SWspan *span)
const GLuint colorMask = *((GLuint *) ctx->Color.ColorMask);
const GLbitfield origInterpMask = span->interpMask;
const GLbitfield origArrayMask = span->arrayMask;
- const GLenum chanType = span->array->ChanType;
+ const GLbitfield origArrayAttribs = span->arrayAttribs;
+ const GLenum origChanType = span->array->ChanType;
+ void * const origRgba = span->array->rgba;
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;
/*
printf("%s() interp 0x%x array 0x%x\n", __FUNCTION__,
@@ -1389,34 +1258,6 @@ _swrast_write_rgba_span( GLcontext *ctx, SWspan *span)
span->primitive == GL_POLYGON ||
span->primitive == GL_BITMAP);
ASSERT(span->end <= MAX_WIDTH);
- ASSERT((span->interpMask & span->arrayMask) == 0);
- ASSERT((span->interpMask & SPAN_RGBA) ^ (span->arrayMask & SPAN_RGBA));
-
- /* check for conditions that prevent deferred shading */
- if (ctx->Color.AlphaEnabled) {
- /* alpha test depends on post-texture/shader colors */
- deferredTexture = GL_FALSE;
- }
- else if (shaderOrTexture) {
- if (ctx->FragmentProgram._Current) {
- if (ctx->FragmentProgram._Current->Base.OutputsWritten
- & (1 << FRAG_RESULT_DEPR)) {
- /* Z comes from fragment program/shader */
- deferredTexture = GL_FALSE;
- }
- else {
- deferredTexture = GL_TRUE;
- }
- }
- else {
- /* ATI frag shader or conventional texturing */
- deferredTexture = GL_TRUE;
- }
- }
- else {
- /* no texturing or shadering */
- deferredTexture = GL_FALSE;
- }
/* Fragment write masks */
if (span->arrayMask & SPAN_MASK) {
@@ -1455,12 +1296,10 @@ _swrast_write_rgba_span( GLcontext *ctx, SWspan *span)
stipple_polygon_span(ctx, span);
}
- /* This is the normal place to compute the resulting fragment color/Z.
- * As an optimization, we try to defer this until after Z/stencil
- * testing in order to try to avoid computing colors that we won't
- * actually need.
+ /* This is the normal place to compute the fragment color/Z
+ * from texturing or shading.
*/
- if (shaderOrTexture && !deferredTexture) {
+ if (shaderOrTexture && !swrast->_DeferredTexture) {
shade_texture_span(ctx, span);
}
@@ -1473,7 +1312,7 @@ _swrast_write_rgba_span( GLcontext *ctx, SWspan *span)
/* Stencil and Z testing */
if (ctx->Stencil.Enabled || ctx->Depth.Test) {
- if (span->interpMask & SPAN_Z)
+ if (!(span->arrayMask & SPAN_Z))
_swrast_span_interpolate_z(ctx, span);
if (ctx->Stencil.Enabled && fb->Visual.stencilBits > 0) {
@@ -1513,14 +1352,19 @@ _swrast_write_rgba_span( GLcontext *ctx, SWspan *span)
* a good chance that many fragments will have already been killed by
* Z/stencil testing.
*/
- if (deferredTexture) {
- ASSERT(shaderOrTexture);
+ if (shaderOrTexture && swrast->_DeferredTexture) {
shade_texture_span(ctx, span);
}
+#if CHAN_BITS == 32
+ if ((span->arrayAttribs & FRAG_BIT_COL0) == 0) {
+ interpolate_int_colors(ctx, span);
+ }
+#else
if ((span->arrayMask & SPAN_RGBA) == 0) {
- interpolate_colors(span);
+ interpolate_int_colors(ctx, span);
}
+#endif
ASSERT(span->arrayMask & SPAN_RGBA);
@@ -1529,17 +1373,7 @@ _swrast_write_rgba_span( GLcontext *ctx, SWspan *span)
if (ctx->Fog.ColorSumEnabled ||
(ctx->Light.Enabled &&
ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR)) {
- if (span->interpMask & SPAN_SPEC) {
- interpolate_specular(span);
- }
- if (span->arrayMask & SPAN_SPEC) {
- add_specular(ctx, span);
- }
- else {
- /* We probably added the base/specular colors during the
- * vertex stage!
- */
- }
+ add_specular(ctx, span);
}
}
@@ -1628,7 +1462,9 @@ end:
/* restore these values before returning */
span->interpMask = origInterpMask;
span->arrayMask = origArrayMask;
- span->array->ChanType = chanType;
+ span->arrayAttribs = origArrayAttribs;
+ span->array->ChanType = origChanType;
+ span->array->rgba = origRgba;
}
@@ -1890,18 +1726,9 @@ _swrast_get_dest_rgba(GLcontext *ctx, struct gl_renderbuffer *rb,
void *rbPixels;
/*
- * Determine pixel size (in bytes).
* Point rbPixels to a temporary space (use specular color arrays).
*/
- if (span->array->ChanType == GL_UNSIGNED_BYTE) {
- rbPixels = span->array->color.sz1.spec;
- }
- else if (span->array->ChanType == GL_UNSIGNED_SHORT) {
- rbPixels = span->array->color.sz2.spec;
- }
- else {
- rbPixels = span->array->attribs[FRAG_ATTRIB_COL1];
- }
+ rbPixels = span->array->attribs[FRAG_ATTRIB_COL1];
/* Get destination values from renderbuffer */
if (span->arrayMask & SPAN_XY) {
diff --git a/src/mesa/swrast/s_span.h b/src/mesa/swrast/s_span.h
index f650a27d66..512134db0f 100644
--- a/src/mesa/swrast/s_span.h
+++ b/src/mesa/swrast/s_span.h
@@ -33,45 +33,24 @@
/**
* \defgroup SpanFlags
- * Bitflags used for interpMask and arrayMask fields below to indicate
- * which interpolant values and fragment arrays are in use, respectively.
+ * Special bitflags to describe span data.
*
- * XXX We should replace these flags with the FRAG_BIT_ values someday...
+ * In general, the point/line/triangle functions interpolate/emit the
+ * attributes specified by swrast->_ActiveAttribs (i.e. FRAT_BIT_* values).
+ * Some things don't fit into that, though, so we have these flags.
*/
/*@{*/
-#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
+#define SPAN_RGBA 0x01 /**< interpMask and arrayMask */
+#define SPAN_INDEX 0x02 /**< interpMask and arrayMask */
+#define SPAN_Z 0x04 /**< interpMask and arrayMask */
+#define SPAN_FLAT 0x08 /**< interpMask: flat shading? */
+#define SPAN_XY 0x10 /**< array.x[], y[] valid? */
+#define SPAN_MASK 0x20 /**< was array.mask[] filled in by caller? */
+#define SPAN_LAMBDA 0x40 /**< array.lambda[] valid? */
+#define SPAN_COVERAGE 0x80 /**< array.coverage[] valid? */
/*@}*/
-#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.
@@ -92,26 +71,19 @@ typedef struct sw_span_arrays
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];
+ /** Attribute arrays that don't fit into attribs[] array above */
+ /*@{*/
+ GLubyte rgba8[MAX_WIDTH][4];
+ GLushort rgba16[MAX_WIDTH][4];
+ GLchan (*rgba)[4]; /** either == rgba8 or rgba16 */
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;
@@ -160,26 +132,13 @@ typedef struct sw_span
/* 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 */
+ GLfixed z, zStep; /**< XXX z should probably be GLuint */
+ GLfixed intTex[2], intTexStep[2]; /**< (s,t) for unit[0] only */
/**
* This bitmask (of \link SpanFlags SPAN_* flags\endlink) indicates
@@ -187,6 +146,8 @@ typedef struct sw_span
*/
GLbitfield arrayMask;
+ GLbitfield arrayAttribs;
+
/**
* We store the arrays of fragment values in a separate struct so
* that we can allocate sw_span structs on the stack without using
@@ -198,36 +159,25 @@ typedef struct sw_span
-#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; \
+#define INIT_SPAN(S, PRIMITIVE) \
+do { \
+ (S).primitive = (PRIMITIVE); \
+ (S).interpMask = 0x0; \
+ (S).arrayMask = 0x0; \
+ (S).arrayAttribs = 0x0; \
+ (S).end = 0; \
+ (S).facing = 0; \
+ (S).array = SWRAST_CONTEXT(ctx)->SpanArrays; \
} while (0)
extern void
-_swrast_span_default_z( GLcontext *ctx, SWspan *span );
+_swrast_span_default_attribs(GLcontext *ctx, SWspan *span);
extern void
_swrast_span_interpolate_z( const GLcontext *ctx, SWspan *span );
-extern void
-_swrast_span_default_fog( GLcontext *ctx, SWspan *span );
-
-extern void
-_swrast_span_default_color( GLcontext *ctx, SWspan *span );
-
-extern void
-_swrast_span_default_secondary_color(GLcontext *ctx, SWspan *span);
-
-extern void
-_swrast_span_default_texcoords( GLcontext *ctx, SWspan *span );
-
extern GLfloat
_swrast_compute_lambda(GLfloat dsdx, GLfloat dsdy, GLfloat dtdx, GLfloat dtdy,
GLfloat dqdx, GLfloat dqdy, GLfloat texW, GLfloat texH,
diff --git a/src/mesa/swrast/s_stencil.c b/src/mesa/swrast/s_stencil.c
index 43475c0e81..89991fad02 100644
--- a/src/mesa/swrast/s_stencil.c
+++ b/src/mesa/swrast/s_stencil.c
@@ -1009,8 +1009,6 @@ stencil_and_ztest_pixels( GLcontext *ctx, SWspan *span, GLuint face )
GLboolean
_swrast_stencil_and_ztest_span(GLcontext *ctx, SWspan *span)
{
- /* span->facing can only be non-zero if using two-sided stencil */
- ASSERT(ctx->Stencil._TestTwoSide || span->facing == 0);
if (span->arrayMask & SPAN_XY)
return stencil_and_ztest_pixels(ctx, span, span->facing);
else
@@ -1154,7 +1152,7 @@ _swrast_clear_stencil_buffer( GLcontext *ctx, struct gl_renderbuffer *rb )
const GLuint stencilMax = (1 << stencilBits) - 1;
GLint x, y, width, height;
- if (!rb || mask == 0 || !rb->Data)
+ if (!rb || mask == 0)
return;
ASSERT(rb->DataType == GL_UNSIGNED_BYTE ||
diff --git a/src/mesa/swrast/s_texcombine.c b/src/mesa/swrast/s_texcombine.c
index ebb4c0d936..4ac7222daa 100644
--- a/src/mesa/swrast/s_texcombine.c
+++ b/src/mesa/swrast/s_texcombine.c
@@ -1080,7 +1080,6 @@ _swrast_texture_span( GLcontext *ctx, SWspan *span )
GLuint unit;
ASSERT(span->end < MAX_WIDTH);
- ASSERT(span->arrayMask & SPAN_TEXTURE);
/*
* Save copy of the incoming fragment colors (the GL_PRIMARY_COLOR)
diff --git a/src/mesa/swrast/s_texfilter.c b/src/mesa/swrast/s_texfilter.c
index b2c5574d95..c2a7512388 100644
--- a/src/mesa/swrast/s_texfilter.c
+++ b/src/mesa/swrast/s_texfilter.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"),
@@ -2026,6 +2026,60 @@ sample_lambda_cube( GLcontext *ctx,
/* Texture Rectangle Sampling Functions */
/**********************************************************************/
+
+/**
+ * Do clamp/wrap for a texture rectangle coord, GL_NEAREST filter mode.
+ */
+static INLINE GLint
+clamp_rect_coord_nearest(GLenum wrapMode, GLfloat coord, GLint max)
+{
+ if (wrapMode == GL_CLAMP) {
+ return IFLOOR( CLAMP(coord, 0.0F, max - 1) );
+ }
+ else if (wrapMode == GL_CLAMP_TO_EDGE) {
+ return IFLOOR( CLAMP(coord, 0.5F, max - 0.5F) );
+ }
+ else {
+ return IFLOOR( CLAMP(coord, -0.5F, max + 0.5F) );
+ }
+}
+
+
+/*
+ * As above, but GL_LINEAR filtering.
+ */
+static INLINE void
+clamp_rect_coord_linear(GLenum wrapMode, GLfloat coord, GLint max,
+ GLint *i0out, GLint *i1out)
+{
+ GLfloat fcol;
+ GLint i0, i1;
+ if (wrapMode == GL_CLAMP) {
+ /* Not exactly what the spec says, but it matches NVIDIA output */
+ fcol = CLAMP(coord - 0.5F, 0.0, max-1);
+ i0 = IFLOOR(fcol);
+ i1 = i0 + 1;
+ }
+ else if (wrapMode == GL_CLAMP_TO_EDGE) {
+ fcol = CLAMP(coord, 0.5F, max - 0.5F);
+ fcol -= 0.5F;
+ i0 = IFLOOR(fcol);
+ i1 = i0 + 1;
+ if (i1 > max - 1)
+ i1 = max - 1;
+ }
+ else {
+ ASSERT(wrapMode == GL_CLAMP_TO_BORDER);
+ fcol = CLAMP(coord, -0.5F, max + 0.5F);
+ fcol -= 0.5F;
+ i0 = IFLOOR(fcol);
+ i1 = i0 + 1;
+ }
+ *i0out = i0;
+ *i1out = i1;
+}
+
+
static void
sample_nearest_rect(GLcontext *ctx,
const struct gl_texture_object *tObj, GLuint n,
@@ -2050,29 +2104,10 @@ sample_nearest_rect(GLcontext *ctx,
tObj->WrapT == GL_CLAMP_TO_BORDER);
ASSERT(img->_BaseFormat != GL_COLOR_INDEX);
- /* XXX move Wrap mode tests outside of loops for common cases */
for (i = 0; i < n; i++) {
GLint row, col;
- /* NOTE: we DO NOT use [0, 1] texture coordinates! */
- if (tObj->WrapS == GL_CLAMP) {
- col = IFLOOR( CLAMP(texcoords[i][0], 0.0F, width - 1) );
- }
- else if (tObj->WrapS == GL_CLAMP_TO_EDGE) {
- col = IFLOOR( CLAMP(texcoords[i][0], 0.5F, width - 0.5F) );
- }
- else {
- col = IFLOOR( CLAMP(texcoords[i][0], -0.5F, width + 0.5F) );
- }
- if (tObj->WrapT == GL_CLAMP) {
- row = IFLOOR( CLAMP(texcoords[i][1], 0.0F, height - 1) );
- }
- else if (tObj->WrapT == GL_CLAMP_TO_EDGE) {
- row = IFLOOR( CLAMP(texcoords[i][1], 0.5F, height - 0.5F) );
- }
- else {
- row = IFLOOR( CLAMP(texcoords[i][1], -0.5F, height + 0.5F) );
- }
-
+ col = clamp_rect_coord_nearest(tObj->WrapS, texcoords[i][0], width);
+ row = clamp_rect_coord_nearest(tObj->WrapT, texcoords[i][1], height);
if (col < 0 || col > width_minus_1 || row < 0 || row > height_minus_1)
COPY_CHAN4(rgba[i], tObj->_BorderChan);
else
@@ -2232,6 +2267,597 @@ sample_lambda_rect( GLcontext *ctx,
+/**********************************************************************/
+/* 2D Texture Array Sampling Functions */
+/**********************************************************************/
+
+/*
+ * Return the texture sample for coordinate (s,t,r) using GL_NEAREST filter.
+ */
+static void
+sample_2d_array_nearest(GLcontext *ctx,
+ const struct gl_texture_object *tObj,
+ const struct gl_texture_image *img,
+ const GLfloat texcoord[4],
+ GLchan rgba[4])
+{
+ const GLint width = img->Width2; /* without border, power of two */
+ const GLint height = img->Height2; /* without border, power of two */
+ const GLint depth = img->Depth;
+ GLint i, j;
+ GLint array;
+ (void) ctx;
+
+ COMPUTE_NEAREST_TEXEL_LOCATION(tObj->WrapS, texcoord[0], width, i);
+ COMPUTE_NEAREST_TEXEL_LOCATION(tObj->WrapT, texcoord[1], height, j);
+ array = clamp_rect_coord_nearest(tObj->WrapR, texcoord[2], depth);
+
+ if (i < 0 || i >= (GLint) img->Width ||
+ j < 0 || j >= (GLint) img->Height ||
+ array < 0 || array >= (GLint) img->Depth) {
+ /* Need this test for GL_CLAMP_TO_BORDER mode */
+ COPY_CHAN4(rgba, tObj->_BorderChan);
+ }
+ else {
+ img->FetchTexelc(img, i, j, array, rgba);
+ }
+}
+
+
+
+/*
+ * Return the texture sample for coordinate (s,t,r) using GL_LINEAR filter.
+ */
+static void
+sample_2d_array_linear(GLcontext *ctx,
+ const struct gl_texture_object *tObj,
+ const struct gl_texture_image *img,
+ const GLfloat texcoord[4],
+ GLchan rgba[4])
+{
+ const GLint width = img->Width2;
+ const GLint height = img->Height2;
+ const GLint depth = img->Depth;
+ GLint i0, j0, i1, j1;
+ GLint array;
+ GLbitfield useBorderColor = 0x0;
+ GLfloat u, v;
+ GLfloat a, b;
+ GLchan t00[4], t01[4], t10[4], t11[4];
+
+ COMPUTE_LINEAR_TEXEL_LOCATIONS(tObj->WrapS, texcoord[0], u, width, i0, i1);
+ COMPUTE_LINEAR_TEXEL_LOCATIONS(tObj->WrapT, texcoord[1], v, height, j0, j1);
+ array = clamp_rect_coord_nearest(tObj->WrapR, texcoord[2], depth);
+
+ if (array < 0 || array >= depth) {
+ COPY_CHAN4(rgba, tObj->_BorderChan);
+ }
+ else {
+ if (img->Border) {
+ i0 += img->Border;
+ i1 += img->Border;
+ j0 += img->Border;
+ j1 += img->Border;
+ }
+ else {
+ /* check if sampling texture border color */
+ if (i0 < 0 || i0 >= width) useBorderColor |= I0BIT;
+ if (i1 < 0 || i1 >= width) useBorderColor |= I1BIT;
+ if (j0 < 0 || j0 >= height) useBorderColor |= J0BIT;
+ if (j1 < 0 || j1 >= height) useBorderColor |= J1BIT;
+ }
+
+ /* Fetch texels */
+ if (useBorderColor & (I0BIT | J0BIT)) {
+ COPY_CHAN4(t00, tObj->_BorderChan);
+ }
+ else {
+ img->FetchTexelc(img, i0, j0, array, t00);
+ }
+ if (useBorderColor & (I1BIT | J0BIT)) {
+ COPY_CHAN4(t10, tObj->_BorderChan);
+ }
+ else {
+ img->FetchTexelc(img, i1, j0, array, t10);
+ }
+ if (useBorderColor & (I0BIT | J1BIT)) {
+ COPY_CHAN4(t01, tObj->_BorderChan);
+ }
+ else {
+ img->FetchTexelc(img, i0, j1, array, t01);
+ }
+ if (useBorderColor & (I1BIT | J1BIT)) {
+ COPY_CHAN4(t11, tObj->_BorderChan);
+ }
+ else {
+ img->FetchTexelc(img, i1, j1, array, t11);
+ }
+
+ /* trilinear interpolation of samples */
+ a = FRAC(u);
+ b = FRAC(v);
+ lerp_rgba_2d(rgba, a, b, t00, t10, t01, t11);
+ }
+}
+
+
+
+static void
+sample_2d_array_nearest_mipmap_nearest(GLcontext *ctx,
+ const struct gl_texture_object *tObj,
+ GLuint n, const GLfloat texcoord[][4],
+ const GLfloat lambda[], GLchan rgba[][4] )
+{
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ GLint level = nearest_mipmap_level(tObj, lambda[i]);
+ sample_2d_array_nearest(ctx, tObj, tObj->Image[0][level], texcoord[i],
+ rgba[i]);
+ }
+}
+
+
+static void
+sample_2d_array_linear_mipmap_nearest(GLcontext *ctx,
+ const struct gl_texture_object *tObj,
+ GLuint n, const GLfloat texcoord[][4],
+ const GLfloat lambda[], GLchan rgba[][4])
+{
+ GLuint i;
+ ASSERT(lambda != NULL);
+ for (i = 0; i < n; i++) {
+ GLint level = nearest_mipmap_level(tObj, lambda[i]);
+ sample_2d_array_linear(ctx, tObj, tObj->Image[0][level],
+ texcoord[i], rgba[i]);
+ }
+}
+
+
+static void
+sample_2d_array_nearest_mipmap_linear(GLcontext *ctx,
+ const struct gl_texture_object *tObj,
+ GLuint n, const GLfloat texcoord[][4],
+ const GLfloat lambda[], GLchan rgba[][4])
+{
+ GLuint i;
+ ASSERT(lambda != NULL);
+ for (i = 0; i < n; i++) {
+ GLint level = linear_mipmap_level(tObj, lambda[i]);
+ if (level >= tObj->_MaxLevel) {
+ sample_2d_array_nearest(ctx, tObj, tObj->Image[0][tObj->_MaxLevel],
+ texcoord[i], rgba[i]);
+ }
+ else {
+ GLchan t0[4], t1[4]; /* texels */
+ const GLfloat f = FRAC(lambda[i]);
+ sample_2d_array_nearest(ctx, tObj, tObj->Image[0][level ], texcoord[i], t0);
+ sample_2d_array_nearest(ctx, tObj, tObj->Image[0][level+1], texcoord[i], t1);
+ lerp_rgba(rgba[i], f, t0, t1);
+ }
+ }
+}
+
+
+static void
+sample_2d_array_linear_mipmap_linear(GLcontext *ctx,
+ const struct gl_texture_object *tObj,
+ GLuint n, const GLfloat texcoord[][4],
+ const GLfloat lambda[], GLchan rgba[][4])
+{
+ GLuint i;
+ ASSERT(lambda != NULL);
+ for (i = 0; i < n; i++) {
+ GLint level = linear_mipmap_level(tObj, lambda[i]);
+ if (level >= tObj->_MaxLevel) {
+ sample_2d_array_linear(ctx, tObj, tObj->Image[0][tObj->_MaxLevel],
+ texcoord[i], rgba[i]);
+ }
+ else {
+ GLchan t0[4], t1[4]; /* texels */
+ const GLfloat f = FRAC(lambda[i]);
+ sample_2d_array_linear(ctx, tObj, tObj->Image[0][level ], texcoord[i], t0);
+ sample_2d_array_linear(ctx, tObj, tObj->Image[0][level+1], texcoord[i], t1);
+ lerp_rgba(rgba[i], f, t0, t1);
+ }
+ }
+}
+
+
+static void
+sample_nearest_2d_array(GLcontext *ctx,
+ const struct gl_texture_object *tObj, GLuint n,
+ const GLfloat texcoords[][4], const GLfloat lambda[],
+ GLchan rgba[][4])
+{
+ GLuint i;
+ struct gl_texture_image *image = tObj->Image[0][tObj->BaseLevel];
+ (void) lambda;
+ for (i=0;i<n;i++) {
+ sample_2d_array_nearest(ctx, tObj, image, texcoords[i], rgba[i]);
+ }
+}
+
+
+
+static void
+sample_linear_2d_array(GLcontext *ctx,
+ const struct gl_texture_object *tObj, GLuint n,
+ const GLfloat texcoords[][4],
+ const GLfloat lambda[], GLchan rgba[][4])
+{
+ GLuint i;
+ struct gl_texture_image *image = tObj->Image[0][tObj->BaseLevel];
+ (void) lambda;
+ for (i=0;i<n;i++) {
+ sample_2d_array_linear(ctx, tObj, image, texcoords[i], rgba[i]);
+ }
+}
+
+
+/*
+ * Given an (s,t,r) texture coordinate and lambda (level of detail) value,
+ * return a texture sample.
+ */
+static void
+sample_lambda_2d_array(GLcontext *ctx,
+ const struct gl_texture_object *tObj, GLuint n,
+ const GLfloat texcoords[][4], const GLfloat lambda[],
+ GLchan rgba[][4])
+{
+ GLuint minStart, minEnd; /* texels with minification */
+ GLuint magStart, magEnd; /* texels with magnification */
+ GLuint i;
+
+ ASSERT(lambda != NULL);
+ compute_min_mag_ranges(tObj, n, lambda,
+ &minStart, &minEnd, &magStart, &magEnd);
+
+ if (minStart < minEnd) {
+ /* do the minified texels */
+ GLuint m = minEnd - minStart;
+ switch (tObj->MinFilter) {
+ case GL_NEAREST:
+ for (i = minStart; i < minEnd; i++)
+ sample_2d_array_nearest(ctx, tObj, tObj->Image[0][tObj->BaseLevel],
+ texcoords[i], rgba[i]);
+ break;
+ case GL_LINEAR:
+ for (i = minStart; i < minEnd; i++)
+ sample_2d_array_linear(ctx, tObj, tObj->Image[0][tObj->BaseLevel],
+ texcoords[i], rgba[i]);
+ break;
+ case GL_NEAREST_MIPMAP_NEAREST:
+ sample_2d_array_nearest_mipmap_nearest(ctx, tObj, m, texcoords + minStart,
+ lambda + minStart, rgba + minStart);
+ break;
+ case GL_LINEAR_MIPMAP_NEAREST:
+ sample_2d_array_linear_mipmap_nearest(ctx, tObj, m,
+ texcoords + minStart,
+ lambda + minStart,
+ rgba + minStart);
+ break;
+ case GL_NEAREST_MIPMAP_LINEAR:
+ sample_2d_array_nearest_mipmap_linear(ctx, tObj, m, texcoords + minStart,
+ lambda + minStart, rgba + minStart);
+ break;
+ case GL_LINEAR_MIPMAP_LINEAR:
+ sample_2d_array_linear_mipmap_linear(ctx, tObj, m,
+ texcoords + minStart,
+ lambda + minStart,
+ rgba + minStart);
+ break;
+ default:
+ _mesa_problem(ctx, "Bad min filter in sample_2d_array_texture");
+ return;
+ }
+ }
+
+ if (magStart < magEnd) {
+ /* do the magnified texels */
+ switch (tObj->MagFilter) {
+ case GL_NEAREST:
+ for (i = magStart; i < magEnd; i++)
+ sample_2d_array_nearest(ctx, tObj, tObj->Image[0][tObj->BaseLevel],
+ texcoords[i], rgba[i]);
+ break;
+ case GL_LINEAR:
+ for (i = magStart; i < magEnd; i++)
+ sample_2d_array_linear(ctx, tObj, tObj->Image[0][tObj->BaseLevel],
+ texcoords[i], rgba[i]);
+ break;
+ default:
+ _mesa_problem(ctx, "Bad mag filter in sample_2d_array_texture");
+ return;
+ }
+ }
+}
+
+
+
+
+/**********************************************************************/
+/* 1D Texture Array Sampling Functions */
+/**********************************************************************/
+
+/*
+ * Return the texture sample for coordinate (s,t,r) using GL_NEAREST filter.
+ */
+static void
+sample_1d_array_nearest(GLcontext *ctx,
+ const struct gl_texture_object *tObj,
+ const struct gl_texture_image *img,
+ const GLfloat texcoord[4],
+ GLchan rgba[4])
+{
+ const GLint width = img->Width2; /* without border, power of two */
+ const GLint height = img->Height;
+ GLint i;
+ GLint array;
+ (void) ctx;
+
+ COMPUTE_NEAREST_TEXEL_LOCATION(tObj->WrapS, texcoord[0], width, i);
+ array = clamp_rect_coord_nearest(tObj->WrapT, texcoord[1], height);
+
+ if (i < 0 || i >= (GLint) img->Width ||
+ array < 0 || array >= (GLint) img->Height) {
+ /* Need this test for GL_CLAMP_TO_BORDER mode */
+ COPY_CHAN4(rgba, tObj->_BorderChan);
+ }
+ else {
+ img->FetchTexelc(img, i, array, 0, rgba);
+ }
+}
+
+
+
+/*
+ * Return the texture sample for coordinate (s,t,r) using GL_LINEAR filter.
+ */
+static void
+sample_1d_array_linear(GLcontext *ctx,
+ const struct gl_texture_object *tObj,
+ const struct gl_texture_image *img,
+ const GLfloat texcoord[4],
+ GLchan rgba[4])
+{
+ const GLint width = img->Width2;
+ const GLint height = img->Height;
+ GLint i0, i1;
+ GLint array;
+ GLbitfield useBorderColor = 0x0;
+ GLfloat u;
+ GLfloat a;
+ GLchan t0[4], t1[4];
+
+ COMPUTE_LINEAR_TEXEL_LOCATIONS(tObj->WrapS, texcoord[0], u, width, i0, i1);
+ array = clamp_rect_coord_nearest(tObj->WrapT, texcoord[1], height);
+
+ if (img->Border) {
+ i0 += img->Border;
+ i1 += img->Border;
+ }
+ else {
+ /* check if sampling texture border color */
+ if (i0 < 0 || i0 >= width) useBorderColor |= I0BIT;
+ if (i1 < 0 || i1 >= width) useBorderColor |= I1BIT;
+ }
+
+ if (array < 0 || array >= height) useBorderColor |= K0BIT;
+
+ /* Fetch texels */
+ if (useBorderColor & (I0BIT | K0BIT)) {
+ COPY_CHAN4(t0, tObj->_BorderChan);
+ }
+ else {
+ img->FetchTexelc(img, i0, array, 0, t0);
+ }
+ if (useBorderColor & (I1BIT | K0BIT)) {
+ COPY_CHAN4(t1, tObj->_BorderChan);
+ }
+ else {
+ img->FetchTexelc(img, i1, array, 0, t1);
+ }
+
+ /* bilinear interpolation of samples */
+ a = FRAC(u);
+ lerp_rgba(rgba, a, t0, t1);
+}
+
+
+
+static void
+sample_1d_array_nearest_mipmap_nearest(GLcontext *ctx,
+ const struct gl_texture_object *tObj,
+ GLuint n, const GLfloat texcoord[][4],
+ const GLfloat lambda[], GLchan rgba[][4] )
+{
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ GLint level = nearest_mipmap_level(tObj, lambda[i]);
+ sample_1d_array_nearest(ctx, tObj, tObj->Image[0][level], texcoord[i],
+ rgba[i]);
+ }
+}
+
+
+static void
+sample_1d_array_linear_mipmap_nearest(GLcontext *ctx,
+ const struct gl_texture_object *tObj,
+ GLuint n, const GLfloat texcoord[][4],
+ const GLfloat lambda[], GLchan rgba[][4])
+{
+ GLuint i;
+ ASSERT(lambda != NULL);
+ for (i = 0; i < n; i++) {
+ GLint level = nearest_mipmap_level(tObj, lambda[i]);
+ sample_1d_array_linear(ctx, tObj, tObj->Image[0][level],
+ texcoord[i], rgba[i]);
+ }
+}
+
+
+static void
+sample_1d_array_nearest_mipmap_linear(GLcontext *ctx,
+ const struct gl_texture_object *tObj,
+ GLuint n, const GLfloat texcoord[][4],
+ const GLfloat lambda[], GLchan rgba[][4])
+{
+ GLuint i;
+ ASSERT(lambda != NULL);
+ for (i = 0; i < n; i++) {
+ GLint level = linear_mipmap_level(tObj, lambda[i]);
+ if (level >= tObj->_MaxLevel) {
+ sample_1d_array_nearest(ctx, tObj, tObj->Image[0][tObj->_MaxLevel],
+ texcoord[i], rgba[i]);
+ }
+ else {
+ GLchan t0[4], t1[4]; /* texels */
+ const GLfloat f = FRAC(lambda[i]);
+ sample_1d_array_nearest(ctx, tObj, tObj->Image[0][level ], texcoord[i], t0);
+ sample_1d_array_nearest(ctx, tObj, tObj->Image[0][level+1], texcoord[i], t1);
+ lerp_rgba(rgba[i], f, t0, t1);
+ }
+ }
+}
+
+
+static void
+sample_1d_array_linear_mipmap_linear(GLcontext *ctx,
+ const struct gl_texture_object *tObj,
+ GLuint n, const GLfloat texcoord[][4],
+ const GLfloat lambda[], GLchan rgba[][4])
+{
+ GLuint i;
+ ASSERT(lambda != NULL);
+ for (i = 0; i < n; i++) {
+ GLint level = linear_mipmap_level(tObj, lambda[i]);
+ if (level >= tObj->_MaxLevel) {
+ sample_1d_array_linear(ctx, tObj, tObj->Image[0][tObj->_MaxLevel],
+ texcoord[i], rgba[i]);
+ }
+ else {
+ GLchan t0[4], t1[4]; /* texels */
+ const GLfloat f = FRAC(lambda[i]);
+ sample_1d_array_linear(ctx, tObj, tObj->Image[0][level ], texcoord[i], t0);
+ sample_1d_array_linear(ctx, tObj, tObj->Image[0][level+1], texcoord[i], t1);
+ lerp_rgba(rgba[i], f, t0, t1);
+ }
+ }
+}
+
+
+static void
+sample_nearest_1d_array(GLcontext *ctx,
+ const struct gl_texture_object *tObj, GLuint n,
+ const GLfloat texcoords[][4], const GLfloat lambda[],
+ GLchan rgba[][4])
+{
+ GLuint i;
+ struct gl_texture_image *image = tObj->Image[0][tObj->BaseLevel];
+ (void) lambda;
+ for (i=0;i<n;i++) {
+ sample_1d_array_nearest(ctx, tObj, image, texcoords[i], rgba[i]);
+ }
+}
+
+
+
+static void
+sample_linear_1d_array(GLcontext *ctx,
+ const struct gl_texture_object *tObj, GLuint n,
+ const GLfloat texcoords[][4],
+ const GLfloat lambda[], GLchan rgba[][4])
+{
+ GLuint i;
+ struct gl_texture_image *image = tObj->Image[0][tObj->BaseLevel];
+ (void) lambda;
+ for (i=0;i<n;i++) {
+ sample_1d_array_linear(ctx, tObj, image, texcoords[i], rgba[i]);
+ }
+}
+
+
+/*
+ * Given an (s,t,r) texture coordinate and lambda (level of detail) value,
+ * return a texture sample.
+ */
+static void
+sample_lambda_1d_array(GLcontext *ctx,
+ const struct gl_texture_object *tObj, GLuint n,
+ const GLfloat texcoords[][4], const GLfloat lambda[],
+ GLchan rgba[][4])
+{
+ GLuint minStart, minEnd; /* texels with minification */
+ GLuint magStart, magEnd; /* texels with magnification */
+ GLuint i;
+
+ ASSERT(lambda != NULL);
+ compute_min_mag_ranges(tObj, n, lambda,
+ &minStart, &minEnd, &magStart, &magEnd);
+
+ if (minStart < minEnd) {
+ /* do the minified texels */
+ GLuint m = minEnd - minStart;
+ switch (tObj->MinFilter) {
+ case GL_NEAREST:
+ for (i = minStart; i < minEnd; i++)
+ sample_1d_array_nearest(ctx, tObj, tObj->Image[0][tObj->BaseLevel],
+ texcoords[i], rgba[i]);
+ break;
+ case GL_LINEAR:
+ for (i = minStart; i < minEnd; i++)
+ sample_1d_array_linear(ctx, tObj, tObj->Image[0][tObj->BaseLevel],
+ texcoords[i], rgba[i]);
+ break;
+ case GL_NEAREST_MIPMAP_NEAREST:
+ sample_1d_array_nearest_mipmap_nearest(ctx, tObj, m, texcoords + minStart,
+ lambda + minStart, rgba + minStart);
+ break;
+ case GL_LINEAR_MIPMAP_NEAREST:
+ sample_1d_array_linear_mipmap_nearest(ctx, tObj, m,
+ texcoords + minStart,
+ lambda + minStart,
+ rgba + minStart);
+ break;
+ case GL_NEAREST_MIPMAP_LINEAR:
+ sample_1d_array_nearest_mipmap_linear(ctx, tObj, m, texcoords + minStart,
+ lambda + minStart, rgba + minStart);
+ break;
+ case GL_LINEAR_MIPMAP_LINEAR:
+ sample_1d_array_linear_mipmap_linear(ctx, tObj, m,
+ texcoords + minStart,
+ lambda + minStart,
+ rgba + minStart);
+ break;
+ default:
+ _mesa_problem(ctx, "Bad min filter in sample_1d_array_texture");
+ return;
+ }
+ }
+
+ if (magStart < magEnd) {
+ /* do the magnified texels */
+ switch (tObj->MagFilter) {
+ case GL_NEAREST:
+ for (i = magStart; i < magEnd; i++)
+ sample_1d_array_nearest(ctx, tObj, tObj->Image[0][tObj->BaseLevel],
+ texcoords[i], rgba[i]);
+ break;
+ case GL_LINEAR:
+ for (i = magStart; i < magEnd; i++)
+ sample_1d_array_linear(ctx, tObj, tObj->Image[0][tObj->BaseLevel],
+ texcoords[i], rgba[i]);
+ break;
+ default:
+ _mesa_problem(ctx, "Bad mag filter in sample_1d_array_texture");
+ return;
+ }
+ }
+}
+
+
+
+
/*
* Sample a shadow/depth texture.
*/
@@ -2245,6 +2871,9 @@ sample_depth_texture( GLcontext *ctx,
const struct gl_texture_image *img = tObj->Image[0][baseLevel];
const GLint width = img->Width;
const GLint height = img->Height;
+ const GLint depth = img->Depth;
+ const GLuint compare_coord = (tObj->Target == GL_TEXTURE_2D_ARRAY_EXT)
+ ? 3 : 2;
GLchan ambient;
GLenum function;
GLchan result;
@@ -2256,41 +2885,61 @@ sample_depth_texture( GLcontext *ctx,
ASSERT(tObj->Target == GL_TEXTURE_1D ||
tObj->Target == GL_TEXTURE_2D ||
- tObj->Target == GL_TEXTURE_RECTANGLE_NV);
+ tObj->Target == GL_TEXTURE_RECTANGLE_NV ||
+ tObj->Target == GL_TEXTURE_1D_ARRAY_EXT ||
+ tObj->Target == GL_TEXTURE_2D_ARRAY_EXT);
UNCLAMPED_FLOAT_TO_CHAN(ambient, tObj->ShadowAmbient);
/* XXXX if tObj->MinFilter != tObj->MagFilter, we're ignoring lambda */
- /* XXX this could be precomputed and saved in the texture object */
- if (tObj->CompareFlag) {
- /* GL_SGIX_shadow */
- if (tObj->CompareOperator == GL_TEXTURE_LEQUAL_R_SGIX) {
- function = GL_LEQUAL;
- }
- else {
- ASSERT(tObj->CompareOperator == GL_TEXTURE_GEQUAL_R_SGIX);
- function = GL_GEQUAL;
- }
- }
- else if (tObj->CompareMode == GL_COMPARE_R_TO_TEXTURE_ARB) {
- /* GL_ARB_shadow */
- function = tObj->CompareFunc;
- }
- else {
- function = GL_NONE; /* pass depth through as grayscale */
- }
-
+ function = tObj->_Function;
if (tObj->MagFilter == GL_NEAREST) {
GLuint i;
for (i = 0; i < n; i++) {
GLfloat depthSample;
- GLint col, row;
- /* XXX fix for texture rectangle! */
- COMPUTE_NEAREST_TEXEL_LOCATION(tObj->WrapS, texcoords[i][0], width, col);
- COMPUTE_NEAREST_TEXEL_LOCATION(tObj->WrapT, texcoords[i][1], height, row);
- if (col >= 0 && row >= 0 && col < width && row < height) {
- img->FetchTexelf(img, col, row, 0, &depthSample);
+ GLint col, row, slice;
+
+ switch (tObj->Target) {
+ case GL_TEXTURE_RECTANGLE_ARB:
+ col = clamp_rect_coord_nearest(tObj->WrapS, texcoords[i][0], width);
+ row = clamp_rect_coord_nearest(tObj->WrapT, texcoords[i][1], height);
+ slice = 0;
+ break;
+
+ case GL_TEXTURE_1D:
+ COMPUTE_NEAREST_TEXEL_LOCATION(tObj->WrapS, texcoords[i][0],
+ width, col);
+ row = 0;
+ slice = 0;
+ break;
+
+ case GL_TEXTURE_2D:
+ COMPUTE_NEAREST_TEXEL_LOCATION(tObj->WrapS, texcoords[i][0],
+ width, col);
+ COMPUTE_NEAREST_TEXEL_LOCATION(tObj->WrapT, texcoords[i][1],
+ height, row);
+ slice = 0;
+ break;
+
+ case GL_TEXTURE_1D_ARRAY_EXT:
+ COMPUTE_NEAREST_TEXEL_LOCATION(tObj->WrapS, texcoords[i][0],
+ width, col);
+ row = clamp_rect_coord_nearest(tObj->WrapT, texcoords[i][1], height);
+ slice = 0;
+
+ case GL_TEXTURE_2D_ARRAY_EXT:
+ COMPUTE_NEAREST_TEXEL_LOCATION(tObj->WrapS, texcoords[i][0],
+ width, col);
+ COMPUTE_NEAREST_TEXEL_LOCATION(tObj->WrapT, texcoords[i][1],
+ height, row);
+ slice = clamp_rect_coord_nearest(tObj->WrapR, texcoords[i][2], depth);
+ break;
+ }
+
+ if (col >= 0 && row >= 0 && col < width && row < height &&
+ slice >= 0 && slice < depth) {
+ img->FetchTexelf(img, col, row, slice, &depthSample);
}
else {
depthSample = tObj->BorderColor[0];
@@ -2298,22 +2947,22 @@ sample_depth_texture( GLcontext *ctx,
switch (function) {
case GL_LEQUAL:
- result = (texcoords[i][2] <= depthSample) ? CHAN_MAX : ambient;
+ result = (texcoords[i][compare_coord] <= depthSample) ? CHAN_MAX : ambient;
break;
case GL_GEQUAL:
- result = (texcoords[i][2] >= depthSample) ? CHAN_MAX : ambient;
+ result = (texcoords[i][compare_coord] >= depthSample) ? CHAN_MAX : ambient;
break;
case GL_LESS:
- result = (texcoords[i][2] < depthSample) ? CHAN_MAX : ambient;
+ result = (texcoords[i][compare_coord] < depthSample) ? CHAN_MAX : ambient;
break;
case GL_GREATER:
- result = (texcoords[i][2] > depthSample) ? CHAN_MAX : ambient;
+ result = (texcoords[i][compare_coord] > depthSample) ? CHAN_MAX : ambient;
break;
case GL_EQUAL:
- result = (texcoords[i][2] == depthSample) ? CHAN_MAX : ambient;
+ result = (texcoords[i][compare_coord] == depthSample) ? CHAN_MAX : ambient;
break;
case GL_NOTEQUAL:
- result = (texcoords[i][2] != depthSample) ? CHAN_MAX : ambient;
+ result = (texcoords[i][compare_coord] != depthSample) ? CHAN_MAX : ambient;
break;
case GL_ALWAYS:
result = CHAN_MAX;
@@ -2359,19 +3008,52 @@ sample_depth_texture( GLcontext *ctx,
for (i = 0; i < n; i++) {
GLfloat depth00, depth01, depth10, depth11;
GLint i0, i1, j0, j1;
+ GLint slice;
GLfloat u, v;
GLuint useBorderTexel;
- /* XXX fix for texture rectangle! */
- COMPUTE_LINEAR_TEXEL_LOCATIONS(tObj->WrapS, texcoords[i][0], u, width, i0, i1);
- COMPUTE_LINEAR_TEXEL_LOCATIONS(tObj->WrapT, texcoords[i][1], v, height,j0, j1);
+ switch (tObj->Target) {
+ case GL_TEXTURE_RECTANGLE_ARB:
+ clamp_rect_coord_linear(tObj->WrapS, texcoords[i][0],
+ width, &i0, &i1);
+ clamp_rect_coord_linear(tObj->WrapT, texcoords[i][1],
+ height, &j0, &j1);
+ slice = 0;
+ break;
+
+ case GL_TEXTURE_1D:
+ case GL_TEXTURE_2D:
+ COMPUTE_LINEAR_TEXEL_LOCATIONS(tObj->WrapS, texcoords[i][0],
+ u, width, i0, i1);
+ COMPUTE_LINEAR_TEXEL_LOCATIONS(tObj->WrapT, texcoords[i][1],
+ v, height,j0, j1);
+ slice = 0;
+ break;
+
+ case GL_TEXTURE_1D_ARRAY_EXT:
+ COMPUTE_LINEAR_TEXEL_LOCATIONS(tObj->WrapS, texcoords[i][0],
+ u, width, i0, i1);
+ j0 = clamp_rect_coord_nearest(tObj->WrapT, texcoords[i][1], height);
+ j1 = j0;
+ slice = 0;
+
+ case GL_TEXTURE_2D_ARRAY_EXT:
+ COMPUTE_LINEAR_TEXEL_LOCATIONS(tObj->WrapS, texcoords[i][0],
+ u, width, i0, i1);
+ COMPUTE_LINEAR_TEXEL_LOCATIONS(tObj->WrapT, texcoords[i][1],
+ v, height,j0, j1);
+ slice = clamp_rect_coord_nearest(tObj->WrapR, texcoords[i][2], depth);
+ break;
+ }
useBorderTexel = 0;
if (img->Border) {
i0 += img->Border;
i1 += img->Border;
- j0 += img->Border;
- j1 += img->Border;
+ if (tObj->Target != GL_TEXTURE_1D_ARRAY_EXT) {
+ j0 += img->Border;
+ j1 += img->Border;
+ }
}
else {
if (i0 < 0 || i0 >= (GLint) width) useBorderTexel |= I0BIT;
@@ -2380,30 +3062,45 @@ sample_depth_texture( GLcontext *ctx,
if (j1 < 0 || j1 >= (GLint) height) useBorderTexel |= J1BIT;
}
- /* get four depth samples from the texture */
- if (useBorderTexel & (I0BIT | J0BIT)) {
+ if (slice < 0 || slice >= (GLint) depth) {
depth00 = tObj->BorderColor[0];
- }
- else {
- img->FetchTexelf(img, i0, j0, 0, &depth00);
- }
- if (useBorderTexel & (I1BIT | J0BIT)) {
- depth10 = tObj->BorderColor[0];
- }
- else {
- img->FetchTexelf(img, i1, j0, 0, &depth10);
- }
- if (useBorderTexel & (I0BIT | J1BIT)) {
depth01 = tObj->BorderColor[0];
- }
- else {
- img->FetchTexelf(img, i0, j1, 0, &depth01);
- }
- if (useBorderTexel & (I1BIT | J1BIT)) {
+ depth10 = tObj->BorderColor[0];
depth11 = tObj->BorderColor[0];
}
else {
- img->FetchTexelf(img, i1, j1, 0, &depth11);
+ /* get four depth samples from the texture */
+ if (useBorderTexel & (I0BIT | J0BIT)) {
+ depth00 = tObj->BorderColor[0];
+ }
+ else {
+ img->FetchTexelf(img, i0, j0, slice, &depth00);
+ }
+ if (useBorderTexel & (I1BIT | J0BIT)) {
+ depth10 = tObj->BorderColor[0];
+ }
+ else {
+ img->FetchTexelf(img, i1, j0, slice, &depth10);
+ }
+
+ if (tObj->Target != GL_TEXTURE_1D_ARRAY_EXT) {
+ if (useBorderTexel & (I0BIT | J1BIT)) {
+ depth01 = tObj->BorderColor[0];
+ }
+ else {
+ img->FetchTexelf(img, i0, j1, slice, &depth01);
+ }
+ if (useBorderTexel & (I1BIT | J1BIT)) {
+ depth11 = tObj->BorderColor[0];
+ }
+ else {
+ img->FetchTexelf(img, i1, j1, slice, &depth11);
+ }
+ }
+ else {
+ depth01 = depth00;
+ depth11 = depth10;
+ }
}
if (0) {
@@ -2412,8 +3109,8 @@ sample_depth_texture( GLcontext *ctx,
const GLfloat b = FRAC(v + 1.0F);
const GLfloat depthSample
= lerp_2d(a, b, depth00, depth10, depth01, depth11);
- if ((depthSample <= texcoords[i][2] && function == GL_LEQUAL) ||
- (depthSample >= texcoords[i][2] && function == GL_GEQUAL)) {
+ if ((depthSample <= texcoords[i][compare_coord] && function == GL_LEQUAL) ||
+ (depthSample >= texcoords[i][compare_coord] && function == GL_GEQUAL)) {
result = ambient;
}
else {
@@ -2430,45 +3127,45 @@ sample_depth_texture( GLcontext *ctx,
switch (function) {
case GL_LEQUAL:
- if (depth00 <= texcoords[i][2]) luminance -= d;
- if (depth01 <= texcoords[i][2]) luminance -= d;
- if (depth10 <= texcoords[i][2]) luminance -= d;
- if (depth11 <= texcoords[i][2]) luminance -= d;
+ if (depth00 <= texcoords[i][compare_coord]) luminance -= d;
+ if (depth01 <= texcoords[i][compare_coord]) luminance -= d;
+ if (depth10 <= texcoords[i][compare_coord]) luminance -= d;
+ if (depth11 <= texcoords[i][compare_coord]) luminance -= d;
result = (GLchan) luminance;
break;
case GL_GEQUAL:
- if (depth00 >= texcoords[i][2]) luminance -= d;
- if (depth01 >= texcoords[i][2]) luminance -= d;
- if (depth10 >= texcoords[i][2]) luminance -= d;
- if (depth11 >= texcoords[i][2]) luminance -= d;
+ if (depth00 >= texcoords[i][compare_coord]) luminance -= d;
+ if (depth01 >= texcoords[i][compare_coord]) luminance -= d;
+ if (depth10 >= texcoords[i][compare_coord]) luminance -= d;
+ if (depth11 >= texcoords[i][compare_coord]) luminance -= d;
result = (GLchan) luminance;
break;
case GL_LESS:
- if (depth00 < texcoords[i][2]) luminance -= d;
- if (depth01 < texcoords[i][2]) luminance -= d;
- if (depth10 < texcoords[i][2]) luminance -= d;
- if (depth11 < texcoords[i][2]) luminance -= d;
+ if (depth00 < texcoords[i][compare_coord]) luminance -= d;
+ if (depth01 < texcoords[i][compare_coord]) luminance -= d;
+ if (depth10 < texcoords[i][compare_coord]) luminance -= d;
+ if (depth11 < texcoords[i][compare_coord]) luminance -= d;
result = (GLchan) luminance;
break;
case GL_GREATER:
- if (depth00 > texcoords[i][2]) luminance -= d;
- if (depth01 > texcoords[i][2]) luminance -= d;
- if (depth10 > texcoords[i][2]) luminance -= d;
- if (depth11 > texcoords[i][2]) luminance -= d;
+ if (depth00 > texcoords[i][compare_coord]) luminance -= d;
+ if (depth01 > texcoords[i][compare_coord]) luminance -= d;
+ if (depth10 > texcoords[i][compare_coord]) luminance -= d;
+ if (depth11 > texcoords[i][compare_coord]) luminance -= d;
result = (GLchan) luminance;
break;
case GL_EQUAL:
- if (depth00 == texcoords[i][2]) luminance -= d;
- if (depth01 == texcoords[i][2]) luminance -= d;
- if (depth10 == texcoords[i][2]) luminance -= d;
- if (depth11 == texcoords[i][2]) luminance -= d;
+ if (depth00 == texcoords[i][compare_coord]) luminance -= d;
+ if (depth01 == texcoords[i][compare_coord]) luminance -= d;
+ if (depth10 == texcoords[i][compare_coord]) luminance -= d;
+ if (depth11 == texcoords[i][compare_coord]) luminance -= d;
result = (GLchan) luminance;
break;
case GL_NOTEQUAL:
- if (depth00 != texcoords[i][2]) luminance -= d;
- if (depth01 != texcoords[i][2]) luminance -= d;
- if (depth10 != texcoords[i][2]) luminance -= d;
- if (depth11 != texcoords[i][2]) luminance -= d;
+ if (depth00 != texcoords[i][compare_coord]) luminance -= d;
+ if (depth01 != texcoords[i][compare_coord]) luminance -= d;
+ if (depth10 != texcoords[i][compare_coord]) luminance -= d;
+ if (depth11 != texcoords[i][compare_coord]) luminance -= d;
result = (GLchan) luminance;
break;
case GL_ALWAYS:
@@ -2650,7 +3347,7 @@ texture_sample_func
_swrast_choose_texture_sample_func( GLcontext *ctx,
const struct gl_texture_object *t )
{
- if (!t || !t->Complete) {
+ if (!t || !t->_Complete) {
return &null_sample_func;
}
else {
@@ -2727,7 +3424,10 @@ _swrast_choose_texture_sample_func( GLcontext *ctx,
return &sample_nearest_cube;
}
case GL_TEXTURE_RECTANGLE_NV:
- if (needLambda) {
+ if (format == GL_DEPTH_COMPONENT || format == GL_DEPTH_STENCIL_EXT) {
+ return &sample_depth_texture;
+ }
+ else if (needLambda) {
return &sample_lambda_rect;
}
else if (t->MinFilter == GL_LINEAR) {
@@ -2737,6 +3437,28 @@ _swrast_choose_texture_sample_func( GLcontext *ctx,
ASSERT(t->MinFilter == GL_NEAREST);
return &sample_nearest_rect;
}
+ case GL_TEXTURE_1D_ARRAY_EXT:
+ if (needLambda) {
+ return &sample_lambda_1d_array;
+ }
+ else if (t->MinFilter == GL_LINEAR) {
+ return &sample_linear_1d_array;
+ }
+ else {
+ ASSERT(t->MinFilter == GL_NEAREST);
+ return &sample_nearest_1d_array;
+ }
+ case GL_TEXTURE_2D_ARRAY_EXT:
+ if (needLambda) {
+ return &sample_lambda_2d_array;
+ }
+ else if (t->MinFilter == GL_LINEAR) {
+ return &sample_linear_2d_array;
+ }
+ else {
+ ASSERT(t->MinFilter == GL_NEAREST);
+ return &sample_nearest_2d_array;
+ }
default:
_mesa_problem(ctx,
"invalid target in _swrast_choose_texture_sample_func");
diff --git a/src/mesa/swrast/s_triangle.c b/src/mesa/swrast/s_triangle.c
index 3b7960bf80..c255545217 100644
--- a/src/mesa/swrast/s_triangle.c
+++ b/src/mesa/swrast/s_triangle.c
@@ -52,10 +52,10 @@ _swrast_culltriangle( GLcontext *ctx,
const SWvertex *v1,
const SWvertex *v2 )
{
- GLfloat ex = v1->win[0] - v0->win[0];
- GLfloat ey = v1->win[1] - v0->win[1];
- GLfloat fx = v2->win[0] - v0->win[0];
- GLfloat fy = v2->win[1] - v0->win[1];
+ GLfloat ex = v1->attrib[FRAG_ATTRIB_WPOS][0] - v0->attrib[FRAG_ATTRIB_WPOS][0];
+ GLfloat ey = v1->attrib[FRAG_ATTRIB_WPOS][1] - v0->attrib[FRAG_ATTRIB_WPOS][1];
+ GLfloat fx = v2->attrib[FRAG_ATTRIB_WPOS][0] - v0->attrib[FRAG_ATTRIB_WPOS][0];
+ GLfloat fy = v2->attrib[FRAG_ATTRIB_WPOS][1] - v0->attrib[FRAG_ATTRIB_WPOS][1];
GLfloat c = ex*fy-ey*fx;
if (c * SWRAST_CONTEXT(ctx)->_BackfaceSign > 0)
@@ -67,26 +67,11 @@ _swrast_culltriangle( GLcontext *ctx,
/*
- * Render a flat-shaded color index triangle.
+ * Render a smooth or flat-shaded color index triangle.
*/
-#define NAME flat_ci_triangle
+#define NAME ci_triangle
#define INTERP_Z 1
-#define INTERP_FOG 1
-#define SETUP_CODE \
- span.interpMask |= SPAN_INDEX; \
- span.index = FloatToFixed(v2->index);\
- span.indexStep = 0;
-#define RENDER_SPAN( span ) _swrast_write_index_span(ctx, &span);
-#include "s_tritemp.h"
-
-
-
-/*
- * Render a smooth-shaded color index triangle.
- */
-#define NAME smooth_ci_triangle
-#define INTERP_Z 1
-#define INTERP_FOG 1
+#define INTERP_ATTRIBS 1 /* just for fog */
#define INTERP_INDEX 1
#define RENDER_SPAN( span ) _swrast_write_index_span(ctx, &span);
#include "s_tritemp.h"
@@ -98,7 +83,6 @@ _swrast_culltriangle( GLcontext *ctx,
*/
#define NAME flat_rgba_triangle
#define INTERP_Z 1
-#define INTERP_FOG 1
#define SETUP_CODE \
ASSERT(ctx->Texture._EnabledCoordUnits == 0);\
ASSERT(ctx->Light.ShadeModel==GL_FLAT); \
@@ -121,7 +105,6 @@ _swrast_culltriangle( GLcontext *ctx,
*/
#define NAME smooth_rgba_triangle
#define INTERP_Z 1
-#define INTERP_FOG 1
#define INTERP_RGB 1
#define INTERP_ALPHA 1
#define SETUP_CODE \
@@ -139,7 +122,7 @@ _swrast_culltriangle( GLcontext *ctx,
* Render an RGB, GL_DECAL, textured triangle.
* Interpolate S,T only w/out mipmapping or perspective correction.
*
- * No fog.
+ * No fog. No depth testing.
*/
#define NAME simple_textured_triangle
#define INTERP_INT_TEX 1
@@ -243,7 +226,6 @@ _swrast_culltriangle( GLcontext *ctx,
#include "s_tritemp.h"
-
#if CHAN_TYPE != GL_FLOAT
struct affine_info
@@ -526,7 +508,6 @@ affine_span(GLcontext *ctx, SWspan *span,
*/
#define NAME affine_textured_triangle
#define INTERP_Z 1
-#define INTERP_FOG 1
#define INTERP_RGB 1
#define INTERP_ALPHA 1
#define INTERP_INT_TEX 1
@@ -799,11 +780,9 @@ fast_persp_span(GLcontext *ctx, SWspan *span,
*/
#define NAME persp_textured_triangle
#define INTERP_Z 1
-#define INTERP_W 1
-#define INTERP_FOG 1
#define INTERP_RGB 1
#define INTERP_ALPHA 1
-#define INTERP_TEX 1
+#define INTERP_ATTRIBS 1
#define SETUP_CODE \
struct persp_info info; \
@@ -858,23 +837,18 @@ fast_persp_span(GLcontext *ctx, SWspan *span,
#include "s_tritemp.h"
+#endif /*CHAN_TYPE != GL_FLOAT*/
-#endif /* CHAN_BITS != GL_FLOAT */
-
-
/*
- * Render a smooth-shaded, textured, RGBA triangle.
+ * Render an RGBA triangle with arbitrary attributes.
*/
-#define NAME general_textured_triangle
+#define NAME general_triangle
#define INTERP_Z 1
-#define INTERP_W 1
-#define INTERP_FOG 1
#define INTERP_RGB 1
-#define INTERP_SPEC 1
#define INTERP_ALPHA 1
-#define INTERP_TEX 1
+#define INTERP_ATTRIBS 1
#define RENDER_SPAN( span ) _swrast_write_rgba_span(ctx, &span);
#include "s_tritemp.h"
@@ -939,51 +913,47 @@ nodraw_triangle( GLcontext *ctx,
* draw the triangle, then restore the original primary color.
* Inefficient, but seldom needed.
*/
-void _swrast_add_spec_terms_triangle( GLcontext *ctx,
- const SWvertex *v0,
- const SWvertex *v1,
- const SWvertex *v2 )
+void
+_swrast_add_spec_terms_triangle(GLcontext *ctx, const SWvertex *v0,
+ const SWvertex *v1, const SWvertex *v2)
{
SWvertex *ncv0 = (SWvertex *)v0; /* drop const qualifier */
SWvertex *ncv1 = (SWvertex *)v1;
SWvertex *ncv2 = (SWvertex *)v2;
-#if CHAN_TYPE == GL_FLOAT
GLfloat rSum, gSum, bSum;
-#else
- GLint rSum, gSum, bSum;
-#endif
- GLchan c[3][4];
+ GLchan cSave[3][4];
+
/* save original colors */
- COPY_CHAN4( c[0], ncv0->color );
- COPY_CHAN4( c[1], ncv1->color );
- COPY_CHAN4( c[2], ncv2->color );
+ COPY_CHAN4( cSave[0], ncv0->color );
+ COPY_CHAN4( cSave[1], ncv1->color );
+ COPY_CHAN4( cSave[2], ncv2->color );
/* sum v0 */
- rSum = ncv0->color[0] + ncv0->specular[0];
- gSum = ncv0->color[1] + ncv0->specular[1];
- bSum = ncv0->color[2] + ncv0->specular[2];
- ncv0->color[0] = MIN2(rSum, CHAN_MAX);
- ncv0->color[1] = MIN2(gSum, CHAN_MAX);
- ncv0->color[2] = MIN2(bSum, CHAN_MAX);
+ rSum = CHAN_TO_FLOAT(ncv0->color[0]) + ncv0->attrib[FRAG_ATTRIB_COL1][0];
+ gSum = CHAN_TO_FLOAT(ncv0->color[1]) + ncv0->attrib[FRAG_ATTRIB_COL1][1];
+ bSum = CHAN_TO_FLOAT(ncv0->color[2]) + ncv0->attrib[FRAG_ATTRIB_COL1][2];
+ UNCLAMPED_FLOAT_TO_CHAN(ncv0->color[0], rSum);
+ UNCLAMPED_FLOAT_TO_CHAN(ncv0->color[1], gSum);
+ UNCLAMPED_FLOAT_TO_CHAN(ncv0->color[2], bSum);
/* sum v1 */
- rSum = ncv1->color[0] + ncv1->specular[0];
- gSum = ncv1->color[1] + ncv1->specular[1];
- bSum = ncv1->color[2] + ncv1->specular[2];
- ncv1->color[0] = MIN2(rSum, CHAN_MAX);
- ncv1->color[1] = MIN2(gSum, CHAN_MAX);
- ncv1->color[2] = MIN2(bSum, CHAN_MAX);
+ rSum = CHAN_TO_FLOAT(ncv1->color[0]) + ncv1->attrib[FRAG_ATTRIB_COL1][0];
+ gSum = CHAN_TO_FLOAT(ncv1->color[1]) + ncv1->attrib[FRAG_ATTRIB_COL1][1];
+ bSum = CHAN_TO_FLOAT(ncv1->color[2]) + ncv1->attrib[FRAG_ATTRIB_COL1][2];
+ UNCLAMPED_FLOAT_TO_CHAN(ncv1->color[0], rSum);
+ UNCLAMPED_FLOAT_TO_CHAN(ncv1->color[1], gSum);
+ UNCLAMPED_FLOAT_TO_CHAN(ncv1->color[2], bSum);
/* sum v2 */
- rSum = ncv2->color[0] + ncv2->specular[0];
- gSum = ncv2->color[1] + ncv2->specular[1];
- bSum = ncv2->color[2] + ncv2->specular[2];
- ncv2->color[0] = MIN2(rSum, CHAN_MAX);
- ncv2->color[1] = MIN2(gSum, CHAN_MAX);
- ncv2->color[2] = MIN2(bSum, CHAN_MAX);
+ rSum = CHAN_TO_FLOAT(ncv2->color[0]) + ncv2->attrib[FRAG_ATTRIB_COL1][0];
+ gSum = CHAN_TO_FLOAT(ncv2->color[1]) + ncv2->attrib[FRAG_ATTRIB_COL1][1];
+ bSum = CHAN_TO_FLOAT(ncv2->color[2]) + ncv2->attrib[FRAG_ATTRIB_COL1][2];
+ UNCLAMPED_FLOAT_TO_CHAN(ncv2->color[0], rSum);
+ UNCLAMPED_FLOAT_TO_CHAN(ncv2->color[1], gSum);
+ UNCLAMPED_FLOAT_TO_CHAN(ncv2->color[2], bSum);
/* draw */
SWRAST_CONTEXT(ctx)->SpecTriangle( ctx, ncv0, ncv1, ncv2 );
/* restore original colors */
- COPY_CHAN4( ncv0->color, c[0] );
- COPY_CHAN4( ncv1->color, c[1] );
- COPY_CHAN4( ncv2->color, c[2] );
+ COPY_CHAN4( ncv0->color, cSave[0] );
+ COPY_CHAN4( ncv1->color, cSave[1] );
+ COPY_CHAN4( ncv2->color, cSave[2] );
}
@@ -1054,9 +1024,20 @@ _swrast_choose_triangle( GLcontext *ctx )
}
}
+ if (!rgbmode) {
+ USE(ci_triangle);
+ return;
+ }
+
+ /*
+ * XXX should examine swrast->_ActiveAttribMask to determine what
+ * needs to be interpolated.
+ */
if (ctx->Texture._EnabledCoordUnits ||
ctx->FragmentProgram._Current ||
- ctx->ATIFragmentShader._Enabled) {
+ ctx->ATIFragmentShader._Enabled ||
+ NEED_SECONDARY_COLOR(ctx) ||
+ swrast->_FogEnabled) {
/* 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;
@@ -1082,6 +1063,7 @@ _swrast_choose_triangle( GLcontext *ctx )
&& (format == MESA_FORMAT_RGB || format == MESA_FORMAT_RGBA)
&& minFilter == magFilter
&& ctx->Light.Model.ColorControl == GL_SINGLE_COLOR
+ && !swrast->_FogEnabled
&& ctx->Texture.Unit[0].EnvMode != GL_COMBINE_EXT) {
if (ctx->Hint.PerspectiveCorrection==GL_FASTEST) {
if (minFilter == GL_NEAREST
@@ -1101,16 +1083,16 @@ _swrast_choose_triangle( GLcontext *ctx )
}
}
else {
-#if (CHAN_BITS == 16 || CHAN_BITS == 32)
- USE(general_textured_triangle);
+#if CHAN_BITS != 8
+ USE(general_triangle);
#else
USE(affine_textured_triangle);
#endif
}
}
else {
-#if (CHAN_BITS == 16 || CHAN_BITS == 32)
- USE(general_textured_triangle);
+#if CHAN_BITS != 8
+ USE(general_triangle);
#else
USE(persp_textured_triangle);
#endif
@@ -1118,28 +1100,27 @@ _swrast_choose_triangle( GLcontext *ctx )
}
else {
/* general case textured triangles */
- USE(general_textured_triangle);
+ USE(general_triangle);
}
}
else {
- ASSERT(!ctx->Texture._EnabledCoordUnits);
+ ASSERT(!swrast->_FogEnabled);
+ ASSERT(!NEED_SECONDARY_COLOR(ctx));
if (ctx->Light.ShadeModel==GL_SMOOTH) {
/* smooth shaded, no texturing, stippled or some raster ops */
- if (rgbmode) {
- USE(smooth_rgba_triangle);
- }
- else {
- USE(smooth_ci_triangle);
- }
+#if CHAN_BITS != 8
+ USE(general_triangle);
+#else
+ USE(smooth_rgba_triangle);
+#endif
}
else {
/* flat shaded, no texturing, stippled or some raster ops */
- if (rgbmode) {
- USE(flat_rgba_triangle);
- }
- else {
- USE(flat_ci_triangle);
- }
+#if CHAN_BITS != 8
+ USE(general_triangle);
+#else
+ USE(flat_rgba_triangle);
+#endif
}
}
}
diff --git a/src/mesa/swrast/s_tritemp.h b/src/mesa/swrast/s_tritemp.h
index b25d3d1550..cded4a6c1c 100644
--- a/src/mesa/swrast/s_tritemp.h
+++ b/src/mesa/swrast/s_tritemp.h
@@ -1,6 +1,6 @@
/*
* Mesa 3-D graphics library
- * Version: 6.5.3
+ * Version: 7.0
*
* Copyright (C) 1999-2007 Brian Paul All Rights Reserved.
*
@@ -29,17 +29,16 @@
*
* The following macros may be defined to indicate what auxillary information
* must be interpolated across the triangle:
- * INTERP_Z - if defined, interpolate vertex Z values
- * INTERP_W - if defined, interpolate vertex W values
- * INTERP_FOG - if defined, interpolate fog values
- * INTERP_RGB - if defined, interpolate RGB values
- * INTERP_ALPHA - if defined, interpolate Alpha values (req's INTERP_RGB)
- * INTERP_SPEC - if defined, interpolate specular RGB values
+ * INTERP_Z - if defined, interpolate integer Z values
+ * INTERP_RGB - if defined, interpolate integer RGB values
+ * INTERP_ALPHA - if defined, interpolate integer Alpha values
* 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 texcoords and varying vars
- * NOTE: OpenGL STRQ = Mesa STUV (R was taken for red)
+ * (fast, simple 2-D texture mapping, without
+ * perspective correction)
+ * INTERP_ATTRIBS - if defined, interpolate arbitrary attribs (texcoords,
+ * varying vars, etc) This also causes W to be
+ * computed for perspective correction).
*
* When one can directly address pixels in the color buffer the following
* macros can be defined and used to compute pixel addresses during
@@ -50,12 +49,11 @@
* Y==0 at bottom of screen and increases upward.
*
* Similarly, for direct depth buffer access, this type is used for depth
- * buffer addressing:
+ * buffer addressing (see zRow):
* DEPTH_TYPE - either GLushort or GLuint
*
* Optionally, one may provide one-time setup code per triangle:
* SETUP_CODE - code which is to be executed once per triangle
- * CLEANUP_CODE - code to execute at end of triangle
*
* The following macro MUST be defined:
* RENDER_SPAN(span) - code to write a span of pixels.
@@ -93,43 +91,6 @@
* SUB_PIXEL_BITS.
*/
-/*
- * ColorTemp is used for intermediate color values.
- */
-#if CHAN_TYPE == GL_FLOAT
-#define ColorTemp GLfloat
-#else
-#define ColorTemp GLint /* same as GLfixed */
-#endif
-
-
-/*
- * Walk triangle edges with GLfixed or GLdouble
- */
-#if TRIANGLE_WALK_DOUBLE
-#define GLinterp GLdouble
-#define InterpToInt(X) ((GLint) (X))
-#define INTERP_ONE 1.0
-#else
-#define GLinterp GLfixed
-#define InterpToInt(X) FixedToInt(X)
-#define INTERP_ONE FIXED_ONE
-#endif
-
-
-#define TEXVAR_LOOP(CODE) \
- { \
- GLuint attr; \
- for (attr = swrast->_MinFragmentAttrib; \
- attr < swrast->_MaxFragmentAttrib; attr++) { \
- if (swrast->_FragmentAttribs & (1 << attr)) { \
- CODE \
- } \
- } \
- }
-
-
-
/*
* Some code we unfortunately need to prevent negative interpolated colors.
@@ -154,15 +115,6 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
{
typedef struct {
const SWvertex *v0, *v1; /* Y(v0) < Y(v1) */
-#if TRIANGLE_WALK_DOUBLE
- GLdouble dx; /* X(v1) - X(v0) */
- GLdouble dy; /* Y(v1) - Y(v0) */
- GLdouble dxdy; /* dx/dy */
- GLdouble adjy; /* adjust from v[0]->fy to fsy, scaled */
- GLdouble fsx; /* first sample point x coord */
- GLdouble fsy;
- GLdouble fx0; /*X of lower endpoint */
-#else
GLfloat dx; /* X(v1) - X(v0) */
GLfloat dy; /* Y(v1) - Y(v0) */
GLfloat dxdy; /* dx/dy */
@@ -171,7 +123,6 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
GLfixed fsx; /* first sample point x coord */
GLfixed fsy;
GLfixed fx0; /* fixed pt X of lower endpoint */
-#endif
GLint lines; /* number of lines to be sampled on this edge */
} EdgeT;
@@ -186,16 +137,14 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
GLfloat oneOverArea;
const SWvertex *vMin, *vMid, *vMax; /* Y(vMin)<=Y(vMid)<=Y(vMax) */
GLfloat bf = SWRAST_CONTEXT(ctx)->_BackfaceSign;
-#if !TRIANGLE_WALK_DOUBLE
const GLint snapMask = ~((FIXED_ONE / (1 << SUB_PIXEL_BITS)) - 1); /* for x/y coord snapping */
-#endif
- GLinterp vMin_fx, vMin_fy, vMid_fx, vMid_fy, vMax_fx, vMax_fy;
+ GLfixed vMin_fx, vMin_fy, vMid_fx, vMid_fy, vMax_fx, vMax_fy;
SWspan span;
(void) swrast;
- INIT_SPAN(span, GL_POLYGON, 0, 0, 0);
+ INIT_SPAN(span, GL_POLYGON);
span.y = 0; /* silence warnings */
#ifdef INTERP_Z
@@ -204,28 +153,27 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
/*
printf("%s()\n", __FUNCTION__);
- printf(" %g, %g, %g\n", v0->win[0], v0->win[1], v0->win[2]);
- printf(" %g, %g, %g\n", v1->win[0], v1->win[1], v1->win[2]);
- printf(" %g, %g, %g\n", v2->win[0], v2->win[1], v2->win[2]);
- */
- /*
- ASSERT(v0->win[2] >= 0.0);
- ASSERT(v1->win[2] >= 0.0);
- ASSERT(v2->win[2] >= 0.0);
+ printf(" %g, %g, %g\n",
+ v0->attrib[FRAG_ATTRIB_WPOS][0],
+ v0->attrib[FRAG_ATTRIB_WPOS][1],
+ v0->attrib[FRAG_ATTRIB_WPOS][2]);
+ printf(" %g, %g, %g\n",
+ v1->attrib[FRAG_ATTRIB_WPOS][0],
+ v1->attrib[FRAG_ATTRIB_WPOS][1],
+ v1->attrib[FRAG_ATTRIB_WPOS][2]);
+ printf(" %g, %g, %g\n",
+ v2->attrib[FRAG_ATTRIB_WPOS][0],
+ v2->attrib[FRAG_ATTRIB_WPOS][1],
+ v2->attrib[FRAG_ATTRIB_WPOS][2]);
*/
+
/* Compute fixed point x,y coords w/ half-pixel offsets and snapping.
* And find the order of the 3 vertices along the Y axis.
*/
{
-#if TRIANGLE_WALK_DOUBLE
- const GLdouble fy0 = v0->win[1] - 0.5;
- const GLdouble fy1 = v1->win[1] - 0.5;
- const GLdouble fy2 = v2->win[1] - 0.5;
-#else
- const GLfixed fy0 = FloatToFixed(v0->win[1] - 0.5F) & snapMask;
- const GLfixed fy1 = FloatToFixed(v1->win[1] - 0.5F) & snapMask;
- const GLfixed fy2 = FloatToFixed(v2->win[1] - 0.5F) & snapMask;
-#endif
+ const GLfixed fy0 = FloatToFixed(v0->attrib[FRAG_ATTRIB_WPOS][1] - 0.5F) & snapMask;
+ const GLfixed fy1 = FloatToFixed(v1->attrib[FRAG_ATTRIB_WPOS][1] - 0.5F) & snapMask;
+ const GLfixed fy2 = FloatToFixed(v2->attrib[FRAG_ATTRIB_WPOS][1] - 0.5F) & snapMask;
if (fy0 <= fy1) {
if (fy1 <= fy2) {
/* y0 <= y1 <= y2 */
@@ -265,15 +213,9 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
}
/* fixed point X coords */
-#if TRIANGLE_WALK_DOUBLE
- vMin_fx = vMin->win[0] + 0.5;
- vMid_fx = vMid->win[0] + 0.5;
- vMax_fx = vMax->win[0] + 0.5;
-#else
- vMin_fx = FloatToFixed(vMin->win[0] + 0.5F) & snapMask;
- vMid_fx = FloatToFixed(vMid->win[0] + 0.5F) & snapMask;
- vMax_fx = FloatToFixed(vMax->win[0] + 0.5F) & snapMask;
-#endif
+ vMin_fx = FloatToFixed(vMin->attrib[FRAG_ATTRIB_WPOS][0] + 0.5F) & snapMask;
+ vMid_fx = FloatToFixed(vMid->attrib[FRAG_ATTRIB_WPOS][0] + 0.5F) & snapMask;
+ vMax_fx = FloatToFixed(vMax->attrib[FRAG_ATTRIB_WPOS][0] + 0.5F) & snapMask;
}
/* vertex/edge relationship */
@@ -282,29 +224,16 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
eBot.v0 = vMin; eBot.v1 = vMid;
/* compute deltas for each edge: vertex[upper] - vertex[lower] */
-#if TRIANGLE_WALK_DOUBLE
- eMaj.dx = vMax_fx - vMin_fx;
- eMaj.dy = vMax_fy - vMin_fy;
- eTop.dx = vMax_fx - vMid_fx;
- eTop.dy = vMax_fy - vMid_fy;
- eBot.dx = vMid_fx - vMin_fx;
- eBot.dy = vMid_fy - vMin_fy;
-#else
eMaj.dx = FixedToFloat(vMax_fx - vMin_fx);
eMaj.dy = FixedToFloat(vMax_fy - vMin_fy);
eTop.dx = FixedToFloat(vMax_fx - vMid_fx);
eTop.dy = FixedToFloat(vMax_fy - vMid_fy);
eBot.dx = FixedToFloat(vMid_fx - vMin_fx);
eBot.dy = FixedToFloat(vMid_fy - vMin_fy);
-#endif
/* compute area, oneOverArea and perform backface culling */
{
-#if TRIANGLE_WALK_DOUBLE
- const GLdouble area = eMaj.dx * eBot.dy - eBot.dx * eMaj.dy;
-#else
const GLfloat area = eMaj.dx * eBot.dy - eBot.dx * eMaj.dy;
-#endif
/* Do backface culling */
if (area * bf < 0.0)
return;
@@ -320,70 +249,37 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
/* Edge setup. For a triangle strip these could be reused... */
{
-#if TRIANGLE_WALK_DOUBLE
- eMaj.fsy = CEILF(vMin_fy);
- eMaj.lines = (GLint) CEILF(vMax_fy - eMaj.fsy);
-#else
eMaj.fsy = FixedCeil(vMin_fy);
eMaj.lines = FixedToInt(FixedCeil(vMax_fy - eMaj.fsy));
-#endif
if (eMaj.lines > 0) {
eMaj.dxdy = eMaj.dx / eMaj.dy;
-#if TRIANGLE_WALK_DOUBLE
- eMaj.adjy = (eMaj.fsy - vMin_fy) * FIXED_SCALE; /* SCALED! */
- eMaj.fx0 = vMin_fx;
- eMaj.fsx = eMaj.fx0 + (eMaj.adjy * eMaj.dxdy) / (GLdouble) FIXED_SCALE;
-#else
eMaj.fdxdy = SignedFloatToFixed(eMaj.dxdy);
eMaj.adjy = (GLfloat) (eMaj.fsy - vMin_fy); /* SCALED! */
eMaj.fx0 = vMin_fx;
eMaj.fsx = eMaj.fx0 + (GLfixed) (eMaj.adjy * eMaj.dxdy);
-#endif
}
else {
return; /*CULLED*/
}
-#if TRIANGLE_WALK_DOUBLE
- eTop.fsy = CEILF(vMid_fy);
- eTop.lines = (GLint) CEILF(vMax_fy - eTop.fsy);
-#else
eTop.fsy = FixedCeil(vMid_fy);
eTop.lines = FixedToInt(FixedCeil(vMax_fy - eTop.fsy));
-#endif
if (eTop.lines > 0) {
eTop.dxdy = eTop.dx / eTop.dy;
-#if TRIANGLE_WALK_DOUBLE
- eTop.adjy = (eTop.fsy - vMid_fy) * FIXED_SCALE; /* SCALED! */
- eTop.fx0 = vMid_fx;
- eTop.fsx = eTop.fx0 + (eTop.adjy * eTop.dxdy) / (GLdouble) FIXED_SCALE;
-#else
eTop.fdxdy = SignedFloatToFixed(eTop.dxdy);
eTop.adjy = (GLfloat) (eTop.fsy - vMid_fy); /* SCALED! */
eTop.fx0 = vMid_fx;
eTop.fsx = eTop.fx0 + (GLfixed) (eTop.adjy * eTop.dxdy);
-#endif
}
-#if TRIANGLE_WALK_DOUBLE
- eBot.fsy = CEILF(vMin_fy);
- eBot.lines = (GLint) CEILF(vMid_fy - eBot.fsy);
-#else
eBot.fsy = FixedCeil(vMin_fy);
eBot.lines = FixedToInt(FixedCeil(vMid_fy - eBot.fsy));
-#endif
if (eBot.lines > 0) {
eBot.dxdy = eBot.dx / eBot.dy;
-#if TRIANGLE_WALK_DOUBLE
- eBot.adjy = (eBot.fsy - vMin_fy) * FIXED_SCALE; /* SCALED! */
- eBot.fx0 = vMin_fx;
- eBot.fsx = eBot.fx0 + (eBot.adjy * eBot.dxdy) / (GLdouble) FIXED_SCALE;
-#else
eBot.fdxdy = SignedFloatToFixed(eBot.dxdy);
eBot.adjy = (GLfloat) (eBot.fsy - vMin_fy); /* SCALED! */
eBot.fx0 = vMin_fx;
eBot.fsx = eBot.fx0 + (GLfixed) (eBot.adjy * eBot.dxdy);
-#endif
}
}
@@ -441,10 +337,11 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
#ifdef INTERP_Z
span.interpMask |= SPAN_Z;
{
- GLfloat eMaj_dz = vMax->win[2] - vMin->win[2];
- GLfloat eBot_dz = vMid->win[2] - vMin->win[2];
+ GLfloat eMaj_dz = vMax->attrib[FRAG_ATTRIB_WPOS][2] - vMin->attrib[FRAG_ATTRIB_WPOS][2];
+ GLfloat eBot_dz = vMid->attrib[FRAG_ATTRIB_WPOS][2] - vMin->attrib[FRAG_ATTRIB_WPOS][2];
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) {
+ if (span.attrStepX[FRAG_ATTRIB_WPOS][2] > maxDepth ||
+ span.attrStepX[FRAG_ATTRIB_WPOS][2] < -maxDepth) {
/* probably a sliver triangle */
span.attrStepX[FRAG_ATTRIB_WPOS][2] = 0.0;
span.attrStepY[FRAG_ATTRIB_WPOS][2] = 0.0;
@@ -458,42 +355,18 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
span.zStep = (GLint) span.attrStepX[FRAG_ATTRIB_WPOS][2];
}
#endif
-#ifdef INTERP_W
- span.interpMask |= SPAN_W;
- {
- const GLfloat eMaj_dw = vMax->win[3] - vMin->win[3];
- const GLfloat eBot_dw = vMid->win[3] - vMin->win[3];
- 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
- span.interpMask |= SPAN_FOG;
- {
-# ifdef INTERP_W
- const GLfloat wMax = vMax->win[3], wMin = vMin->win[3], wMid = vMid->win[3];
- const GLfloat eMaj_dfog = vMax->fog * wMax - vMin->fog * wMin;
- const GLfloat eBot_dfog = vMid->fog * wMid - vMin->fog * wMin;
-# else
- const GLfloat eMaj_dfog = vMax->fog - vMin->fog;
- const GLfloat eBot_dfog = vMid->fog - vMin->fog;
-# endif
- 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
span.interpMask |= SPAN_RGBA;
if (ctx->Light.ShadeModel == GL_SMOOTH) {
- GLfloat eMaj_dr = (GLfloat) ((ColorTemp) vMax->color[RCOMP] - (ColorTemp) vMin->color[RCOMP]);
- GLfloat eBot_dr = (GLfloat) ((ColorTemp) vMid->color[RCOMP] - (ColorTemp) vMin->color[RCOMP]);
- GLfloat eMaj_dg = (GLfloat) ((ColorTemp) vMax->color[GCOMP] - (ColorTemp) vMin->color[GCOMP]);
- GLfloat eBot_dg = (GLfloat) ((ColorTemp) vMid->color[GCOMP] - (ColorTemp) vMin->color[GCOMP]);
- GLfloat eMaj_db = (GLfloat) ((ColorTemp) vMax->color[BCOMP] - (ColorTemp) vMin->color[BCOMP]);
- GLfloat eBot_db = (GLfloat) ((ColorTemp) vMid->color[BCOMP] - (ColorTemp) vMin->color[BCOMP]);
+ GLfloat eMaj_dr = (GLfloat) (vMax->color[RCOMP] - vMin->color[RCOMP]);
+ GLfloat eBot_dr = (GLfloat) (vMid->color[RCOMP] - vMin->color[RCOMP]);
+ GLfloat eMaj_dg = (GLfloat) (vMax->color[GCOMP] - vMin->color[GCOMP]);
+ GLfloat eBot_dg = (GLfloat) (vMid->color[GCOMP] - vMin->color[GCOMP]);
+ GLfloat eMaj_db = (GLfloat) (vMax->color[BCOMP] - vMin->color[BCOMP]);
+ GLfloat eBot_db = (GLfloat) (vMid->color[BCOMP] - vMin->color[BCOMP]);
# ifdef INTERP_ALPHA
- GLfloat eMaj_da = (GLfloat) ((ColorTemp) vMax->color[ACOMP] - (ColorTemp) vMin->color[ACOMP]);
- GLfloat eBot_da = (GLfloat) ((ColorTemp) vMid->color[ACOMP] - (ColorTemp) vMin->color[ACOMP]);
+ GLfloat eMaj_da = (GLfloat) (vMax->color[ACOMP] - vMin->color[ACOMP]);
+ GLfloat eBot_da = (GLfloat) (vMid->color[ACOMP] - vMin->color[ACOMP]);
# endif
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);
@@ -501,23 +374,13 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
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.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.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.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.attrStepX[FRAG_ATTRIB_COL0][3];
-# else
+ span.attrStepY[FRAG_ATTRIB_COL0][3] = oneOverArea * (eMaj.dx * eBot_da - eMaj_da * eBot.dx);
span.alphaStep = SignedFloatToFixed(span.attrStepX[FRAG_ATTRIB_COL0][3]);
-# endif /* GL_FLOAT */
# endif /* INTERP_ALPHA */
}
else {
@@ -526,70 +389,20 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
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;
- span.blueStep = 0.0F;
-# else
span.redStep = 0;
span.greenStep = 0;
span.blueStep = 0;
-# endif /* GL_FLOAT */
# ifdef INTERP_ALPHA
- span.attrStepX[FRAG_ATTRIB_COL0][3] = span.attrStepX[FRAG_ATTRIB_COL0][3] = 0.0F;
-# if CHAN_TYPE == GL_FLOAT
- span.alphaStep = 0.0F;
-# else
+ span.attrStepX[FRAG_ATTRIB_COL0][3] = span.attrStepY[FRAG_ATTRIB_COL0][3] = 0.0F;
span.alphaStep = 0;
-# endif /* GL_FLOAT */
# endif
}
#endif /* INTERP_RGB */
-#ifdef INTERP_SPEC
- span.interpMask |= SPAN_SPEC;
- if (ctx->Light.ShadeModel == GL_SMOOTH) {
- GLfloat eMaj_dsr = (GLfloat) ((ColorTemp) vMax->specular[RCOMP] - (ColorTemp) vMin->specular[RCOMP]);
- GLfloat eBot_dsr = (GLfloat) ((ColorTemp) vMid->specular[RCOMP] - (ColorTemp) vMin->specular[RCOMP]);
- GLfloat eMaj_dsg = (GLfloat) ((ColorTemp) vMax->specular[GCOMP] - (ColorTemp) vMin->specular[GCOMP]);
- 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.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.attrStepX[FRAG_ATTRIB_COL1][0];
- span.specGreenStep = span.attrStepX[FRAG_ATTRIB_COL1][1];
- span.specBlueStep = span.attrStepX[FRAG_ATTRIB_COL1][2];
-# else
- 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.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;
- span.specBlueStep = 0.0F;
-# else
- span.specRedStep = 0;
- span.specGreenStep = 0;
- span.specBlueStep = 0;
-# endif
- }
-#endif /* INTERP_SPEC */
#ifdef INTERP_INDEX
span.interpMask |= SPAN_INDEX;
if (ctx->Light.ShadeModel == GL_SMOOTH) {
- GLfloat eMaj_di = vMax->index - vMin->index;
- GLfloat eBot_di = vMid->index - vMin->index;
+ GLfloat eMaj_di = vMax->attrib[FRAG_ATTRIB_CI][0] - vMin->attrib[FRAG_ATTRIB_CI][0];
+ GLfloat eBot_di = vMid->attrib[FRAG_ATTRIB_CI][0] - vMin->attrib[FRAG_ATTRIB_CI][0];
didx = oneOverArea * (eMaj_di * eBot.dy - eMaj.dy * eBot_di);
didy = oneOverArea * (eMaj.dx * eBot_di - eMaj_di * eBot.dx);
span.indexStep = SignedFloatToFixed(didx);
@@ -601,7 +414,6 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
}
#endif
#ifdef INTERP_INT_TEX
- span.interpMask |= SPAN_INT_TEXTURE;
{
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;
@@ -615,29 +427,33 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
span.intTexStep[1] = SignedFloatToFixed(span.attrStepX[FRAG_ATTRIB_TEX0][1]);
}
#endif
-#ifdef INTERP_TEX
- span.interpMask |= (SPAN_TEXTURE | SPAN_VARYING);
+#ifdef INTERP_ATTRIBS
{
- /* win[3] is 1/W */
- const GLfloat wMax = vMax->win[3], wMin = vMin->win[3], wMid = vMid->win[3];
- 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);
- )
+ /* attrib[FRAG_ATTRIB_WPOS][3] is 1/W */
+ const GLfloat wMax = vMax->attrib[FRAG_ATTRIB_WPOS][3];
+ const GLfloat wMin = vMin->attrib[FRAG_ATTRIB_WPOS][3];
+ const GLfloat wMid = vMid->attrib[FRAG_ATTRIB_WPOS][3];
+ {
+ const GLfloat eMaj_dw = wMax - wMin;
+ const GLfloat eBot_dw = wMid - wMin;
+ 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);
+ }
+ ATTRIB_LOOP_BEGIN
+ if (swrast->_InterpMode[attr] == GL_FLAT) {
+ ASSIGN_4V(span.attrStepX[attr], 0.0, 0.0, 0.0, 0.0);
+ ASSIGN_4V(span.attrStepY[attr], 0.0, 0.0, 0.0, 0.0);
+ }
+ else {
+ GLuint c;
+ for (c = 0; c < 4; c++) {
+ GLfloat eMaj_da = vMax->attrib[attr][c] * wMax - vMin->attrib[attr][c] * wMin;
+ GLfloat eBot_da = vMid->attrib[attr][c] * wMid - vMin->attrib[attr][c] * wMin;
+ span.attrStepX[attr][c] = oneOverArea * (eMaj_da * eBot.dy - eMaj.dy * eBot_da);
+ span.attrStepY[attr][c] = oneOverArea * (eMaj.dx * eBot_da - eMaj_da * eBot.dx);
+ }
+ }
+ ATTRIB_LOOP_END
}
#endif
@@ -690,9 +506,9 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
{
GLint subTriangle;
- GLinterp fxLeftEdge = 0, fxRightEdge = 0;
- GLinterp fdxLeftEdge = 0, fdxRightEdge = 0;
- GLinterp fError = 0, fdError = 0;
+ GLfixed fxLeftEdge = 0, fxRightEdge = 0;
+ GLfixed fdxLeftEdge = 0, fdxRightEdge = 0;
+ GLfixed fError = 0, fdError = 0;
#ifdef PIXEL_ADDRESS
PIXEL_TYPE *pRow = NULL;
GLint dPRowOuter = 0, dPRowInner; /* offset in bytes */
@@ -707,24 +523,13 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
GLuint zLeft = 0;
GLfixed fdzOuter = 0, fdzInner;
#endif
-#ifdef INTERP_W
- GLfloat wLeft = 0, dwOuter = 0, dwInner;
-#endif
-#ifdef INTERP_FOG
- GLfloat fogLeft = 0, dfogOuter = 0, dfogInner;
-#endif
#ifdef INTERP_RGB
- ColorTemp rLeft = 0, fdrOuter = 0, fdrInner;
- ColorTemp gLeft = 0, fdgOuter = 0, fdgInner;
- ColorTemp bLeft = 0, fdbOuter = 0, fdbInner;
+ GLint rLeft = 0, fdrOuter = 0, fdrInner;
+ GLint gLeft = 0, fdgOuter = 0, fdgInner;
+ GLint bLeft = 0, fdbOuter = 0, fdbInner;
#endif
#ifdef INTERP_ALPHA
- ColorTemp aLeft = 0, fdaOuter = 0, fdaInner;
-#endif
-#ifdef INTERP_SPEC
- ColorTemp srLeft=0, dsrOuter=0, dsrInner;
- ColorTemp sgLeft=0, dsgOuter=0, dsgInner;
- ColorTemp sbLeft=0, dsbOuter=0, dsbInner;
+ GLint aLeft = 0, fdaOuter = 0, fdaInner;
#endif
#ifdef INTERP_INDEX
GLfixed iLeft=0, diOuter=0, diInner;
@@ -733,15 +538,10 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
GLfixed sLeft=0, dsOuter=0, dsInner;
GLfixed tLeft=0, dtOuter=0, dtInner;
#endif
-#ifdef INTERP_TEX
- 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];
+#ifdef INTERP_ATTRIBS
+ GLfloat wLeft = 0, dwOuter = 0, dwInner;
+ GLfloat attrLeft[FRAG_ATTRIB_MAX][4];
+ GLfloat daOuter[FRAG_ATTRIB_MAX][4], daInner[FRAG_ATTRIB_MAX][4];
#endif
for (subTriangle=0; subTriangle<=1; subTriangle++) {
@@ -788,30 +588,12 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
if (setupLeft && eLeft->lines > 0) {
const SWvertex *vLower = eLeft->v0;
-#if TRIANGLE_WALK_DOUBLE
- const GLdouble fsy = eLeft->fsy;
- const GLdouble fsx = eLeft->fsx;
- const GLdouble fx = CEILF(fsx);
- const GLdouble adjx = (fx - eLeft->fx0) * FIXED_SCALE; /* SCALED! */
-#else
const GLfixed fsy = eLeft->fsy;
const GLfixed fsx = eLeft->fsx; /* no fractional part */
const GLfixed fx = FixedCeil(fsx); /* no fractional part */
- const GLfixed adjx = (GLinterp) (fx - eLeft->fx0); /* SCALED! */
-#endif
- const GLinterp adjy = (GLinterp) eLeft->adjy; /* SCALED! */
+ const GLfixed adjx = (GLfixed) (fx - eLeft->fx0); /* SCALED! */
+ const GLfixed adjy = (GLfixed) eLeft->adjy; /* SCALED! */
GLint idxOuter;
-#if TRIANGLE_WALK_DOUBLE
- GLdouble dxOuter;
-
- fError = fx - fsx - 1.0;
- fxLeftEdge = fsx;
- fdxLeftEdge = eLeft->dxdy;
- dxOuter = FLOORF(fdxLeftEdge);
- fdError = dxOuter - fdxLeftEdge + 1.0;
- idxOuter = (GLint) dxOuter;
- span.y = (GLint) fsy;
-#else
GLfloat dxOuter;
GLfixed fdxOuter;
@@ -823,7 +605,6 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
idxOuter = FixedToInt(fdxOuter);
dxOuter = (GLfloat) idxOuter;
span.y = FixedToInt(fsy);
-#endif
/* silence warnings on some compilers */
(void) dxOuter;
@@ -833,7 +614,7 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
#ifdef PIXEL_ADDRESS
{
- pRow = (PIXEL_TYPE *) PIXEL_ADDRESS(InterpToInt(fxLeftEdge), span.y);
+ pRow = (PIXEL_TYPE *) PIXEL_ADDRESS(FixedToInt(fxLeftEdge), span.y);
dPRowOuter = -((int)BYTES_PER_ROW) + idxOuter * sizeof(PIXEL_TYPE);
/* negative because Y=0 at bottom and increases upward */
}
@@ -850,7 +631,7 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
#ifdef INTERP_Z
{
- GLfloat z0 = vLower->win[2];
+ GLfloat z0 = vLower->attrib[FRAG_ATTRIB_WPOS][2];
if (depthBits <= 16) {
/* interpolate fixed-pt values */
GLfloat tmp = (z0 * FIXED_SCALE
@@ -860,129 +641,71 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
zLeft = (GLfixed) tmp;
else
zLeft = MAX_GLUINT / 2;
- fdzOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_WPOS][2] + dxOuter * span.attrStepX[FRAG_ATTRIB_WPOS][2]);
+ 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.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]);
+ fdzOuter = (GLint) (span.attrStepY[FRAG_ATTRIB_WPOS][2] +
+ dxOuter * span.attrStepX[FRAG_ATTRIB_WPOS][2]);
}
# ifdef DEPTH_TYPE
zRow = (DEPTH_TYPE *)
- zrb->GetPointer(ctx, zrb, InterpToInt(fxLeftEdge), span.y);
+ zrb->GetPointer(ctx, zrb, FixedToInt(fxLeftEdge), span.y);
dZRowOuter = (ctx->DrawBuffer->Width + idxOuter) * sizeof(DEPTH_TYPE);
# endif
}
#endif
-#ifdef INTERP_W
- 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.attrStepX[FRAG_ATTRIB_FOGC][0] * adjx + span.attrStepY[FRAG_ATTRIB_FOGC][0] * adjy) * (1.0F/FIXED_SCALE);
-# else
- fogLeft = vLower->fog + (span.attrStepX[FRAG_ATTRIB_FOGC][0] * adjx + span.attrStepY[FRAG_ATTRIB_FOGC][0] * adjy) * (1.0F/FIXED_SCALE);
-# endif
- 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.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.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
+ 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]);
# ifdef INTERP_ALPHA
-# if CHAN_TYPE == GL_FLOAT
- 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.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
+ aLeft = (GLint)(ChanToFixed(vLower->color[ACOMP])
+ + span.attrStepX[FRAG_ATTRIB_COL0][3] * adjx
+ + span.attrStepY[FRAG_ATTRIB_COL0][3] * adjy) + FIXED_HALF;
+ fdaOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_COL0][3]
+ + dxOuter * span.attrStepX[FRAG_ATTRIB_COL0][3]);
# endif
}
else {
ASSERT(ctx->Light.ShadeModel == GL_FLAT);
-# if CHAN_TYPE == GL_FLOAT
- rLeft = v2->color[RCOMP];
- gLeft = v2->color[GCOMP];
- bLeft = v2->color[BCOMP];
- fdrOuter = fdgOuter = fdbOuter = 0.0F;
-# else
rLeft = ChanToFixed(v2->color[RCOMP]);
gLeft = ChanToFixed(v2->color[GCOMP]);
bLeft = ChanToFixed(v2->color[BCOMP]);
fdrOuter = fdgOuter = fdbOuter = 0;
-# endif
# ifdef INTERP_ALPHA
-# if CHAN_TYPE == GL_FLOAT
- aLeft = v2->color[ACOMP];
- fdaOuter = 0.0F;
-# else
aLeft = ChanToFixed(v2->color[ACOMP]);
fdaOuter = 0;
-# endif
# endif
}
#endif /* INTERP_RGB */
-#ifdef INTERP_SPEC
- if (ctx->Light.ShadeModel == GL_SMOOTH) {
-# if CHAN_TYPE == GL_FLOAT
- 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.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 {
- ASSERT(ctx->Light.ShadeModel == GL_FLAT);
-#if CHAN_TYPE == GL_FLOAT
- srLeft = v2->specular[RCOMP];
- sgLeft = v2->specular[GCOMP];
- sbLeft = v2->specular[BCOMP];
- dsrOuter = dsgOuter = dsbOuter = 0.0F;
-# else
- srLeft = ChanToFixed(v2->specular[RCOMP]);
- sgLeft = ChanToFixed(v2->specular[GCOMP]);
- sbLeft = ChanToFixed(v2->specular[BCOMP]);
- dsrOuter = dsgOuter = dsbOuter = 0;
-# endif
- }
-#endif
-
#ifdef INTERP_INDEX
if (ctx->Light.ShadeModel == GL_SMOOTH) {
- iLeft = (GLfixed)(vLower->index * FIXED_SCALE
+ iLeft = (GLfixed)(vLower->attrib[FRAG_ATTRIB_CI][0] * FIXED_SCALE
+ didx * adjx + didy * adjy) + FIXED_HALF;
diOuter = SignedFloatToFixed(didy + dxOuter * didx);
}
else {
ASSERT(ctx->Light.ShadeModel == GL_FLAT);
- iLeft = FloatToFixed(v2->index);
+ iLeft = FloatToFixed(v2->attrib[FRAG_ATTRIB_CI][0]);
diOuter = 0;
}
#endif
@@ -992,42 +715,50 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
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]);
+ 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]);
+ dtOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_TEX0][1]
+ + dxOuter * span.attrStepX[FRAG_ATTRIB_TEX0][1]);
}
#endif
-#ifdef INTERP_TEX
- TEXVAR_LOOP(
- const GLfloat invW = vLower->win[3];
- 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];
- )
+#ifdef INTERP_ATTRIBS
+ {
+ const GLuint attr = FRAG_ATTRIB_WPOS;
+ wLeft = vLower->attrib[FRAG_ATTRIB_WPOS][3]
+ + (span.attrStepX[attr][3] * adjx
+ + span.attrStepY[attr][3] * adjy) * (1.0F/FIXED_SCALE);
+ dwOuter = span.attrStepY[attr][3] + dxOuter * span.attrStepX[attr][3];
+ }
+ ATTRIB_LOOP_BEGIN
+ const GLfloat invW = vLower->attrib[FRAG_ATTRIB_WPOS][3];
+ if (swrast->_InterpMode[attr] == GL_FLAT) {
+ GLuint c;
+ for (c = 0; c < 4; c++) {
+ attrLeft[attr][c] = v2->attrib[attr][c] * invW;
+ daOuter[attr][c] = 0.0;
+ }
+ }
+ else {
+ GLuint c;
+ for (c = 0; c < 4; c++) {
+ const GLfloat a = vLower->attrib[attr][c] * invW;
+ attrLeft[attr][c] = a + ( span.attrStepX[attr][c] * adjx
+ + span.attrStepY[attr][c] * adjy) * (1.0F/FIXED_SCALE);
+ daOuter[attr][c] = span.attrStepY[attr][c] + dxOuter * span.attrStepX[attr][c];
+ }
+ }
+ ATTRIB_LOOP_END
#endif
} /*if setupLeft*/
if (setupRight && eRight->lines>0) {
-#if TRIANGLE_WALK_DOUBLE
- fxRightEdge = eRight->fsx;
- fdxRightEdge = eRight->dxdy;
-#else
fxRightEdge = eRight->fsx - FIXED_EPSILON;
fdxRightEdge = eRight->fdxdy;
-#endif
}
if (lines==0) {
@@ -1045,12 +776,6 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
# endif
fdzInner = fdzOuter + span.zStep;
#endif
-#ifdef INTERP_W
- dwInner = dwOuter + span.attrStepX[FRAG_ATTRIB_WPOS][3];
-#endif
-#ifdef INTERP_FOG
- dfogInner = dfogOuter + span.attrStepX[FRAG_ATTRIB_FOGC][0];
-#endif
#ifdef INTERP_RGB
fdrInner = fdrOuter + span.redStep;
fdgInner = fdgOuter + span.greenStep;
@@ -1059,11 +784,6 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
#ifdef INTERP_ALPHA
fdaInner = fdaOuter + span.alphaStep;
#endif
-#ifdef INTERP_SPEC
- dsrInner = dsrOuter + span.specRedStep;
- dsgInner = dsgOuter + span.specGreenStep;
- dsbInner = dsbOuter + span.specBlueStep;
-#endif
#ifdef INTERP_INDEX
diInner = diOuter + span.indexStep;
#endif
@@ -1071,20 +791,21 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
dsInner = dsOuter + span.intTexStep[0];
dtInner = dtOuter + span.intTexStep[1];
#endif
-#ifdef INTERP_TEX
- 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];
- )
+#ifdef INTERP_ATTRIBS
+ dwInner = dwOuter + span.attrStepX[FRAG_ATTRIB_WPOS][3];
+ ATTRIB_LOOP_BEGIN
+ GLuint c;
+ for (c = 0; c < 4; c++) {
+ daInner[attr][c] = daOuter[attr][c] + span.attrStepX[attr][c];
+ }
+ ATTRIB_LOOP_END
#endif
while (lines > 0) {
/* initialize the span interpolants to the leftmost value */
/* ff = fixed-pt fragment */
- const GLint right = InterpToInt(fxRightEdge);
- span.x = InterpToInt(fxLeftEdge);
+ const GLint right = FixedToInt(fxRightEdge);
+ span.x = FixedToInt(fxLeftEdge);
if (right <= span.x)
span.end = 0;
else
@@ -1093,12 +814,6 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
#ifdef INTERP_Z
span.z = zLeft;
#endif
-#ifdef INTERP_W
- span.attrStart[FRAG_ATTRIB_WPOS][3] = wLeft;
-#endif
-#ifdef INTERP_FOG
- span.attrStart[FRAG_ATTRIB_FOGC][0] = fogLeft;
-#endif
#ifdef INTERP_RGB
span.red = rLeft;
span.green = gLeft;
@@ -1107,11 +822,6 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
#ifdef INTERP_ALPHA
span.alpha = aLeft;
#endif
-#ifdef INTERP_SPEC
- span.specRed = srLeft;
- span.specGreen = sgLeft;
- span.specBlue = sbLeft;
-#endif
#ifdef INTERP_INDEX
span.index = iLeft;
#endif
@@ -1120,13 +830,14 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
span.intTex[1] = tLeft;
#endif
-#ifdef INTERP_TEX
- 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];
- )
+#ifdef INTERP_ATTRIBS
+ span.attrStart[FRAG_ATTRIB_WPOS][3] = wLeft;
+ ATTRIB_LOOP_BEGIN
+ GLuint c;
+ for (c = 0; c < 4; c++) {
+ span.attrStart[attr][c] = attrLeft[attr][c];
+ }
+ ATTRIB_LOOP_END
#endif
/* This is where we actually generate fragments */
@@ -1144,11 +855,6 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
#ifdef INTERP_ALPHA
CLAMP_INTERPOLANT(alpha, alphaStep, len);
#endif
-#ifdef INTERP_SPEC
- CLAMP_INTERPOLANT(specRed, specRedStep, len);
- CLAMP_INTERPOLANT(specGreen, specGreenStep, len);
- CLAMP_INTERPOLANT(specBlue, specBlueStep, len);
-#endif
#ifdef INTERP_INDEX
CLAMP_INTERPOLANT(index, indexStep, len);
#endif
@@ -1171,7 +877,7 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
fError += fdError;
if (fError >= 0) {
- fError -= INTERP_ONE;
+ fError -= FIXED_ONE;
#ifdef PIXEL_ADDRESS
pRow = (PIXEL_TYPE *) ((GLubyte *) pRow + dPRowOuter);
@@ -1182,12 +888,6 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
# endif
zLeft += fdzOuter;
#endif
-#ifdef INTERP_W
- wLeft += dwOuter;
-#endif
-#ifdef INTERP_FOG
- fogLeft += dfogOuter;
-#endif
#ifdef INTERP_RGB
rLeft += fdrOuter;
gLeft += fdgOuter;
@@ -1196,11 +896,6 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
#ifdef INTERP_ALPHA
aLeft += fdaOuter;
#endif
-#ifdef INTERP_SPEC
- srLeft += dsrOuter;
- sgLeft += dsgOuter;
- sbLeft += dsbOuter;
-#endif
#ifdef INTERP_INDEX
iLeft += diOuter;
#endif
@@ -1208,13 +903,14 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
sLeft += dsOuter;
tLeft += dtOuter;
#endif
-#ifdef INTERP_TEX
- TEXVAR_LOOP(
- sLeft[attr] += dsOuter[attr];
- tLeft[attr] += dtOuter[attr];
- uLeft[attr] += duOuter[attr];
- vLeft[attr] += dvOuter[attr];
- )
+#ifdef INTERP_ATTRIBS
+ wLeft += dwOuter;
+ ATTRIB_LOOP_BEGIN
+ GLuint c;
+ for (c = 0; c < 4; c++) {
+ attrLeft[attr][c] += daOuter[attr][c];
+ }
+ ATTRIB_LOOP_END
#endif
}
else {
@@ -1227,12 +923,6 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
# endif
zLeft += fdzInner;
#endif
-#ifdef INTERP_W
- wLeft += dwInner;
-#endif
-#ifdef INTERP_FOG
- fogLeft += dfogInner;
-#endif
#ifdef INTERP_RGB
rLeft += fdrInner;
gLeft += fdgInner;
@@ -1241,11 +931,6 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
#ifdef INTERP_ALPHA
aLeft += fdaInner;
#endif
-#ifdef INTERP_SPEC
- srLeft += dsrInner;
- sgLeft += dsgInner;
- sbLeft += dsbInner;
-#endif
#ifdef INTERP_INDEX
iLeft += diInner;
#endif
@@ -1253,13 +938,14 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
sLeft += dsInner;
tLeft += dtInner;
#endif
-#ifdef INTERP_TEX
- TEXVAR_LOOP(
- sLeft[attr] += dsInner[attr];
- tLeft[attr] += dtInner[attr];
- uLeft[attr] += duInner[attr];
- vLeft[attr] += dvInner[attr];
- )
+#ifdef INTERP_ATTRIBS
+ wLeft += dwInner;
+ ATTRIB_LOOP_BEGIN
+ GLuint c;
+ for (c = 0; c < 4; c++) {
+ attrLeft[attr][c] += daInner[attr][c];
+ }
+ ATTRIB_LOOP_END
#endif
}
} /*while lines>0*/
@@ -1267,14 +953,10 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
} /* for subTriangle */
}
-#ifdef CLEANUP_CODE
- CLEANUP_CODE
-#endif
}
}
#undef SETUP_CODE
-#undef CLEANUP_CODE
#undef RENDER_SPAN
#undef PIXEL_TYPE
@@ -1283,24 +965,15 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
#undef DEPTH_TYPE
#undef INTERP_Z
-#undef INTERP_W
-#undef INTERP_FOG
#undef INTERP_RGB
#undef INTERP_ALPHA
-#undef INTERP_SPEC
#undef INTERP_INDEX
#undef INTERP_INT_TEX
-#undef INTERP_TEX
-#undef TEX_UNIT_LOOP
-#undef VARYING_LOOP
+#undef INTERP_ATTRIBS
#undef S_SCALE
#undef T_SCALE
#undef FixedToDepth
-#undef ColorTemp
-#undef GLinterp
-#undef InterpToInt
-#undef INTERP_ONE
#undef NAME
diff --git a/src/mesa/swrast/s_zoom.c b/src/mesa/swrast/s_zoom.c
index 1fac7498aa..9f1a4c6f0a 100644
--- a/src/mesa/swrast/s_zoom.c
+++ b/src/mesa/swrast/s_zoom.c
@@ -37,8 +37,9 @@
* Compute the bounds of the region resulting from zooming a pixel span.
* The resulting region will be entirely inside the window/scissor bounds
* so no additional clipping is needed.
- * \param imageX, imageY position of the overall image being drawn
+ * \param imageX, imageY position of the mage being drawn (gl WindowPos)
* \param spanX, spanY position of span being drawing
+ * \param width number of pixels in span
* \param x0, x1 returned X bounds of zoomed region [x0, x1)
* \param y0, y1 returned Y bounds of zoomed region [y0, y1)
* \return GL_TRUE if any zoomed pixels visible, GL_FALSE if totally clipped
@@ -98,7 +99,11 @@ compute_zoomed_bounds(GLcontext *ctx, GLint imageX, GLint imageY,
/**
- * Can use this for unzooming X or Y values.
+ * Convert a zoomed x image coordinate back to an unzoomed x coord.
+ * 'zx' is screen position of a pixel in the zoomed image, who's left edge
+ * is at 'imageX'.
+ * return corresponding x coord in the original, unzoomed image.
+ * This can use this for unzooming X or Y values.
*/
static INLINE GLint
unzoom_x(GLfloat zoomX, GLint imageX, GLint zx)
@@ -108,7 +113,10 @@ unzoom_x(GLfloat zoomX, GLint imageX, GLint zx)
zx - imageX = (x - imageX) * zoomX;
(zx - imageX) / zoomX = x - imageX;
*/
- GLint x = imageX + (GLint) ((zx - imageX) / zoomX);
+ GLint x;
+ if (zoomX < 0.0)
+ zx++;
+ x = imageX + (GLint) ((zx - imageX) / zoomX);
return x;
}
@@ -140,29 +148,25 @@ zoom_span( GLcontext *ctx, GLint imgX, GLint imgY, const SWspan *span,
ASSERT((span->arrayMask & SPAN_XY) == 0);
ASSERT(span->primitive == GL_BITMAP);
- INIT_SPAN(zoomed, GL_BITMAP, 0, 0, 0);
+ INIT_SPAN(zoomed, GL_BITMAP);
zoomed.x = x0;
zoomed.end = zoomedWidth;
zoomed.array = &zoomed_arrays;
zoomed_arrays.ChanType = span->array->ChanType;
- /* XXX temporary */
-#if CHAN_TYPE == GL_UNSIGNED_BYTE
- zoomed_arrays.rgba = zoomed_arrays.color.sz1.rgba;
- zoomed_arrays.spec = zoomed_arrays.color.sz1.spec;
-#elif CHAN_TYPE == GL_UNSIGNED_SHORT
- zoomed_arrays.rgba = zoomed_arrays.color.sz2.rgba;
- zoomed_arrays.spec = zoomed_arrays.color.sz2.spec;
-#else
- zoomed_arrays.rgba = zoomed_arrays.attribs[FRAG_ATTRIB_COL0];
- zoomed_arrays.spec = zoomed_arrays.attribs[FRAG_ATTRIB_COL1];
-#endif
-
-
- /* copy fog interp info */
+ if (zoomed_arrays.ChanType == GL_UNSIGNED_BYTE)
+ zoomed_arrays.rgba = (GLchan (*)[4]) zoomed_arrays.rgba8;
+ else if (zoomed_arrays.ChanType == GL_UNSIGNED_SHORT)
+ zoomed_arrays.rgba = (GLchan (*)[4]) zoomed_arrays.rgba16;
+ else
+ zoomed_arrays.rgba = (GLchan (*)[4]) zoomed_arrays.attribs[FRAG_ATTRIB_COL0];
+
+ COPY_4V(zoomed.attrStart[FRAG_ATTRIB_WPOS], span->attrStart[FRAG_ATTRIB_WPOS]);
+ COPY_4V(zoomed.attrStepX[FRAG_ATTRIB_WPOS], span->attrStepX[FRAG_ATTRIB_WPOS]);
+ COPY_4V(zoomed.attrStepY[FRAG_ATTRIB_WPOS], span->attrStepY[FRAG_ATTRIB_WPOS]);
+
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) {
/* copy Z info */
@@ -171,6 +175,7 @@ zoom_span( GLcontext *ctx, GLint imgX, GLint imgY, const SWspan *span,
/* we'll generate an array of colorss */
zoomed.interpMask = span->interpMask & ~SPAN_RGBA;
zoomed.arrayMask |= SPAN_RGBA;
+ zoomed.arrayAttribs |= FRAG_BIT_COL0; /* we'll produce these values */
ASSERT(span->arrayMask & SPAN_RGBA);
}
else if (format == GL_COLOR_INDEX) {
@@ -211,7 +216,7 @@ zoom_span( GLcontext *ctx, GLint imgX, GLint imgY, const SWspan *span,
GLint j = unzoom_x(ctx->Pixel.ZoomX, imgX, x0 + i) - span->x;
ASSERT(j >= 0);
ASSERT(j < (GLint) span->end);
- COPY_4UBV(zoomed.array->color.sz1.rgba[i], rgba[j]);
+ COPY_4UBV(zoomed.array->rgba8[i], rgba[j]);
}
}
else if (zoomed.array->ChanType == GL_UNSIGNED_SHORT) {
@@ -221,7 +226,7 @@ zoom_span( GLcontext *ctx, GLint imgX, GLint imgY, const SWspan *span,
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.sz2.rgba[i], rgba[j]);
+ COPY_4V(zoomed.array->rgba16[i], rgba[j]);
}
}
else {
@@ -243,10 +248,10 @@ zoom_span( GLcontext *ctx, GLint imgX, GLint imgY, const SWspan *span,
GLint j = unzoom_x(ctx->Pixel.ZoomX, imgX, x0 + i) - span->x;
ASSERT(j >= 0);
ASSERT(j < (GLint) span->end);
- zoomed.array->color.sz1.rgba[i][0] = rgb[j][0];
- zoomed.array->color.sz1.rgba[i][1] = rgb[j][1];
- zoomed.array->color.sz1.rgba[i][2] = rgb[j][2];
- zoomed.array->color.sz1.rgba[i][3] = 0xff;
+ zoomed.array->rgba8[i][0] = rgb[j][0];
+ zoomed.array->rgba8[i][1] = rgb[j][1];
+ zoomed.array->rgba8[i][2] = rgb[j][2];
+ zoomed.array->rgba8[i][3] = 0xff;
}
}
else if (zoomed.array->ChanType == GL_UNSIGNED_SHORT) {
@@ -256,10 +261,10 @@ zoom_span( GLcontext *ctx, GLint imgX, GLint imgY, const SWspan *span,
GLint j = unzoom_x(ctx->Pixel.ZoomX, imgX, x0 + i) - span->x;
ASSERT(j >= 0);
ASSERT(j < (GLint) span->end);
- zoomed.array->color.sz2.rgba[i][0] = rgb[j][0];
- zoomed.array->color.sz2.rgba[i][1] = rgb[j][1];
- zoomed.array->color.sz2.rgba[i][2] = rgb[j][2];
- zoomed.array->color.sz2.rgba[i][3] = 0xffff;
+ zoomed.array->rgba16[i][0] = rgb[j][0];
+ zoomed.array->rgba16[i][1] = rgb[j][1];
+ zoomed.array->rgba16[i][2] = rgb[j][2];
+ zoomed.array->rgba16[i][3] = 0xffff;
}
}
else {
@@ -306,8 +311,7 @@ zoom_span( GLcontext *ctx, GLint imgX, GLint imgY, const SWspan *span,
* Also, clipping may change the span end value, so store it as well.
*/
const GLint end = zoomed.end; /* save */
- /* use specular color array for temp storage */
- void *rgbaSave = zoomed.array->spec;
+ GLuint rgbaSave[MAX_WIDTH][4];
const GLint pixelSize =
(zoomed.array->ChanType == GL_UNSIGNED_BYTE) ? 4 * sizeof(GLubyte) :
((zoomed.array->ChanType == GL_UNSIGNED_SHORT) ? 4 * sizeof(GLushort)
@@ -326,7 +330,7 @@ zoom_span( GLcontext *ctx, GLint imgX, GLint imgY, const SWspan *span,
}
else if (format == GL_COLOR_INDEX) {
/* use specular color array for temp storage */
- GLuint *indexSave = (GLuint *) zoomed.array->spec;
+ GLuint *indexSave = (GLuint *) zoomed.array->attribs[FRAG_ATTRIB_FOGC];
const GLint end = zoomed.end; /* save */
if (y1 - y0 > 1) {
MEMCPY(indexSave, zoomed.array->index, zoomed.end * sizeof(GLuint));
diff --git a/src/mesa/swrast/swrast.h b/src/mesa/swrast/swrast.h
index 9e1fe24bb4..d101a9e2ae 100644
--- a/src/mesa/swrast/swrast.h
+++ b/src/mesa/swrast/swrast.h
@@ -45,6 +45,14 @@
* improve its usefulness as a fallback mechanism for hardware
* drivers.
*
+ * wpos = attr[FRAG_ATTRIB_WPOS] and MUST BE THE FIRST values in the
+ * vertex because of the tnl clipping code.
+
+ * wpos[0] and [1] are the screen-coords of SWvertex.
+ * wpos[2] is the z-buffer coord (if 16-bit Z buffer, in range [0,65535]).
+ * wpos[3] is 1/w where w is the clip-space W coord. This is the value
+ * that clip{XYZ} were multiplied by to get ndc{XYZ}.
+ *
* Full software drivers:
* - Register the rastersetup and triangle functions from
* utils/software_helper.
@@ -61,21 +69,15 @@
* primitives unaccelerated), hook in swrast_setup instead.
*/
typedef struct {
- /** win[0], win[1] are the screen-coords of SWvertex.
- * win[2] is the z-buffer coord (if 16-bit Z buffer, in range [0,65535]).
- * win[3] is 1/w where w is the clip-space W coord. This is the value
- * that clip{XYZ} were multiplied by to get ndc{XYZ}.
- */
- GLfloat win[4];
- GLchan color[4];
- GLchan specular[4];
- GLfloat fog;
- GLfloat index;
+ GLfloat attrib[FRAG_ATTRIB_MAX][4];
+ GLchan color[4]; /** integer color */
GLfloat pointSize;
- GLfloat attrib[FRAG_ATTRIB_MAX][4]; /**< texcoords & varying, more to come */
} SWvertex;
+#define FRAG_ATTRIB_CI FRAG_ATTRIB_COL0
+
+
struct swrast_device_driver;