summaryrefslogtreecommitdiff
path: root/xc/extras/Mesa/src/swrast
diff options
context:
space:
mode:
Diffstat (limited to 'xc/extras/Mesa/src/swrast')
-rw-r--r--xc/extras/Mesa/src/swrast/s_aaline.c25
-rw-r--r--xc/extras/Mesa/src/swrast/s_aalinetemp.h131
-rw-r--r--xc/extras/Mesa/src/swrast/s_aatriangle.c70
-rw-r--r--xc/extras/Mesa/src/swrast/s_aatritemp.h308
-rw-r--r--xc/extras/Mesa/src/swrast/s_accum.c30
-rw-r--r--xc/extras/Mesa/src/swrast/s_alpha.c243
-rw-r--r--xc/extras/Mesa/src/swrast/s_alpha.h9
-rw-r--r--xc/extras/Mesa/src/swrast/s_alphabuf.c114
-rw-r--r--xc/extras/Mesa/src/swrast/s_bitmap.c186
-rw-r--r--xc/extras/Mesa/src/swrast/s_blend.c236
-rw-r--r--xc/extras/Mesa/src/swrast/s_blend.h14
-rw-r--r--xc/extras/Mesa/src/swrast/s_buffers.c130
-rw-r--r--xc/extras/Mesa/src/swrast/s_context.c224
-rw-r--r--xc/extras/Mesa/src/swrast/s_context.h110
-rw-r--r--xc/extras/Mesa/src/swrast/s_copypix.c411
-rw-r--r--xc/extras/Mesa/src/swrast/s_depth.c129
-rw-r--r--xc/extras/Mesa/src/swrast/s_depth.h11
-rw-r--r--xc/extras/Mesa/src/swrast/s_drawpix.c387
-rw-r--r--xc/extras/Mesa/src/swrast/s_fog.c183
-rw-r--r--xc/extras/Mesa/src/swrast/s_fog.h27
-rw-r--r--xc/extras/Mesa/src/swrast/s_imaging.c29
-rw-r--r--xc/extras/Mesa/src/swrast/s_lines.c1260
-rw-r--r--xc/extras/Mesa/src/swrast/s_linetemp.h96
-rw-r--r--xc/extras/Mesa/src/swrast/s_logic.c110
-rw-r--r--xc/extras/Mesa/src/swrast/s_logic.h26
-rw-r--r--xc/extras/Mesa/src/swrast/s_masking.c125
-rw-r--r--xc/extras/Mesa/src/swrast/s_masking.h32
-rw-r--r--xc/extras/Mesa/src/swrast/s_pb.c517
-rw-r--r--xc/extras/Mesa/src/swrast/s_pb.h244
-rw-r--r--xc/extras/Mesa/src/swrast/s_pixeltex.c64
-rw-r--r--xc/extras/Mesa/src/swrast/s_pixeltex.h9
-rw-r--r--xc/extras/Mesa/src/swrast/s_points.c37
-rw-r--r--xc/extras/Mesa/src/swrast/s_points.h5
-rw-r--r--xc/extras/Mesa/src/swrast/s_pointtemp.h406
-rw-r--r--xc/extras/Mesa/src/swrast/s_readpix.c27
-rw-r--r--xc/extras/Mesa/src/swrast/s_scissor.c64
-rw-r--r--xc/extras/Mesa/src/swrast/s_scissor.h40
-rw-r--r--xc/extras/Mesa/src/swrast/s_span.c1764
-rw-r--r--xc/extras/Mesa/src/swrast/s_span.h48
-rw-r--r--xc/extras/Mesa/src/swrast/s_stencil.c387
-rw-r--r--xc/extras/Mesa/src/swrast/s_stencil.h11
-rw-r--r--xc/extras/Mesa/src/swrast/s_texstore.c167
-rw-r--r--xc/extras/Mesa/src/swrast/s_texture.c2783
-rw-r--r--xc/extras/Mesa/src/swrast/s_texture.h11
-rw-r--r--xc/extras/Mesa/src/swrast/s_triangle.c838
-rw-r--r--xc/extras/Mesa/src/swrast/s_trispan.h62
-rw-r--r--xc/extras/Mesa/src/swrast/s_tritemp.h190
-rw-r--r--xc/extras/Mesa/src/swrast/s_zoom.c474
-rw-r--r--xc/extras/Mesa/src/swrast/s_zoom.h32
-rw-r--r--xc/extras/Mesa/src/swrast/swrast.h244
50 files changed, 6267 insertions, 6813 deletions
diff --git a/xc/extras/Mesa/src/swrast/s_aaline.c b/xc/extras/Mesa/src/swrast/s_aaline.c
index 08bcaac63..cef87b2c1 100644
--- a/xc/extras/Mesa/src/swrast/s_aaline.c
+++ b/xc/extras/Mesa/src/swrast/s_aaline.c
@@ -1,10 +1,9 @@
-/* $Id: s_aaline.c,v 1.1.1.1 2002/10/22 13:06:56 alanh Exp $ */
/*
* Mesa 3-D graphics library
- * Version: 3.5
+ * Version: 4.1
*
- * Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
+ * Copyright (C) 1999-2002 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"),
@@ -27,8 +26,8 @@
#include "glheader.h"
#include "swrast/s_aaline.h"
-#include "swrast/s_pb.h"
#include "swrast/s_context.h"
+#include "swrast/s_span.h"
#include "swrast/swrast.h"
#include "mtypes.h"
#include "mmath.h"
@@ -75,6 +74,8 @@ struct LineInfo
GLfloat vPlane[MAX_TEXTURE_UNITS][4];
GLfloat lambda[MAX_TEXTURE_UNITS];
GLfloat texWidth[MAX_TEXTURE_UNITS], texHeight[MAX_TEXTURE_UNITS];
+
+ struct sw_span span;
};
@@ -326,8 +327,9 @@ compute_coveragef(const struct LineInfo *info,
-typedef void (*plot_func)(GLcontext *ctx, const struct LineInfo *line,
- struct pixel_buffer *pb, int ix, int iy);
+typedef void (*plot_func)(GLcontext *ctx, struct LineInfo *line,
+ int ix, int iy);
+
/*
@@ -337,7 +339,6 @@ static void
segment(GLcontext *ctx,
struct LineInfo *line,
plot_func plot,
- struct pixel_buffer *pb,
GLfloat t0, GLfloat t1)
{
const GLfloat absDx = (line->dx < 0.0F) ? -line->dx : line->dx;
@@ -407,7 +408,7 @@ segment(GLcontext *ctx,
GLint iy;
/* scan across the line, bottom-to-top */
for (iy = iyBot; iy < iyTop; iy++) {
- (*plot)(ctx, line, pb, ix, iy);
+ (*plot)(ctx, line, ix, iy);
}
yBot += dydx;
yTop += dydx;
@@ -453,7 +454,7 @@ segment(GLcontext *ctx,
GLint ix;
/* scan across the line, left-to-right */
for (ix = ixLeft; ix < ixRight; ix++) {
- (*plot)(ctx, line, pb, ix, iy);
+ (*plot)(ctx, line, ix, iy);
}
xLeft += dxdy;
xRight += dxdy;
@@ -486,6 +487,7 @@ segment(GLcontext *ctx,
#define NAME(x) aa_multitex_rgba_##x
#define DO_Z
+#define DO_FOG
#define DO_RGBA
#define DO_MULTITEX
#include "s_aalinetemp.h"
@@ -493,6 +495,7 @@ segment(GLcontext *ctx,
#define NAME(x) aa_multitex_spec_##x
#define DO_Z
+#define DO_FOG
#define DO_RGBA
#define DO_MULTITEX
#define DO_SPEC
@@ -509,8 +512,8 @@ _swrast_choose_aa_line_function(GLcontext *ctx)
if (ctx->Visual.rgbMode) {
/* RGBA */
- if (ctx->Texture._ReallyEnabled) {
- if (ctx->Texture._ReallyEnabled > TEXTURE0_ANY) {
+ if (ctx->Texture._EnabledUnits != 0) {
+ if (ctx->Texture._EnabledUnits > 1) {
/* Multitextured! */
if (ctx->Light.Model.ColorControl==GL_SEPARATE_SPECULAR_COLOR ||
ctx->Fog.ColorSumEnabled)
diff --git a/xc/extras/Mesa/src/swrast/s_aalinetemp.h b/xc/extras/Mesa/src/swrast/s_aalinetemp.h
index bd675f365..4dc2691a1 100644
--- a/xc/extras/Mesa/src/swrast/s_aalinetemp.h
+++ b/xc/extras/Mesa/src/swrast/s_aalinetemp.h
@@ -1,10 +1,9 @@
-/* $Id: s_aalinetemp.h,v 1.1.1.1 2002/10/22 13:06:52 alanh Exp $ */
/*
* Mesa 3-D graphics library
- * Version: 3.5
+ * Version: 4.1
*
- * Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
+ * Copyright (C) 1999-2002 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,107 +33,81 @@
* Function to render each fragment in the AA line.
*/
static void
-NAME(plot)(GLcontext *ctx, const struct LineInfo *line,
- struct pixel_buffer *pb, int ix, int iy)
+NAME(plot)(GLcontext *ctx, struct LineInfo *line, int ix, int iy)
{
const GLfloat fx = (GLfloat) ix;
const GLfloat fy = (GLfloat) iy;
const GLfloat coverage = compute_coveragef(line, ix, iy);
- GLdepth z;
- GLfloat fog;
-#ifdef DO_RGBA
- GLchan red, green, blue, alpha;
-#else
- GLint index;
-#endif
- GLchan specRed, specGreen, specBlue;
- GLfloat tex[MAX_TEXTURE_UNITS][4], lambda[MAX_TEXTURE_UNITS];
+ const GLuint i = line->span.end;
if (coverage == 0.0)
return;
+ line->span.end++;
+ line->span.array->coverage[i] = coverage;
+ line->span.array->x[i] = ix;
+ line->span.array->y[i] = iy;
+
/*
* Compute Z, color, texture coords, fog for the fragment by
* solving the plane equations at (ix,iy).
*/
#ifdef DO_Z
- z = (GLdepth) solve_plane(fx, fy, line->zPlane);
-#else
- z = 0.0;
+ line->span.array->z[i] = (GLdepth) solve_plane(fx, fy, line->zPlane);
#endif
#ifdef DO_FOG
- fog = solve_plane(fx, fy, line->fPlane);
-#else
- fog = 0.0;
+ line->span.array->fog[i] = solve_plane(fx, fy, line->fPlane);
#endif
#ifdef DO_RGBA
- red = solve_plane_chan(fx, fy, line->rPlane);
- green = solve_plane_chan(fx, fy, line->gPlane);
- blue = solve_plane_chan(fx, fy, line->bPlane);
- alpha = solve_plane_chan(fx, fy, line->aPlane);
+ 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);
+ line->span.array->rgba[i][BCOMP] = solve_plane_chan(fx, fy, line->bPlane);
+ line->span.array->rgba[i][ACOMP] = solve_plane_chan(fx, fy, line->aPlane);
#endif
#ifdef DO_INDEX
- index = (GLint) solve_plane(fx, fy, line->iPlane);
+ line->span.array->index[i] = (GLint) solve_plane(fx, fy, line->iPlane);
#endif
#ifdef DO_SPEC
- specRed = solve_plane_chan(fx, fy, line->srPlane);
- specGreen = solve_plane_chan(fx, fy, line->sgPlane);
- specBlue = solve_plane_chan(fx, fy, line->sbPlane);
-#else
- (void) specRed;
- (void) specGreen;
- (void) specBlue;
+ 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
#ifdef DO_TEX
{
- GLfloat invQ = solve_plane_recip(fx, fy, line->vPlane[0]);
- tex[0][0] = solve_plane(fx, fy, line->sPlane[0]) * invQ;
- tex[0][1] = solve_plane(fx, fy, line->tPlane[0]) * invQ;
- tex[0][2] = solve_plane(fx, fy, line->uPlane[0]) * invQ;
- lambda[0] = compute_lambda(line->sPlane[0], line->tPlane[0], invQ,
- line->texWidth[0], line->texHeight[0]);
+ const GLfloat invQ = solve_plane_recip(fx, fy, line->vPlane[0]);
+ line->span.array->texcoords[0][i][0] = solve_plane(fx, fy, line->sPlane[0]) * invQ;
+ line->span.array->texcoords[0][i][1] = solve_plane(fx, fy, line->tPlane[0]) * invQ;
+ line->span.array->texcoords[0][i][2] = solve_plane(fx, fy, line->uPlane[0]) * invQ;
+ line->span.array->lambda[0][i] = compute_lambda(line->sPlane[0], line->tPlane[0], invQ,
+ line->texWidth[0], line->texHeight[0]);
}
#elif defined(DO_MULTITEX)
{
GLuint unit;
for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) {
if (ctx->Texture.Unit[unit]._ReallyEnabled) {
- GLfloat invQ = solve_plane_recip(fx, fy, line->vPlane[unit]);
- tex[unit][0] = solve_plane(fx, fy, line->sPlane[unit]) * invQ;
- tex[unit][1] = solve_plane(fx, fy, line->tPlane[unit]) * invQ;
- tex[unit][2] = solve_plane(fx, fy, line->uPlane[unit]) * invQ;
- lambda[unit] = compute_lambda(line->sPlane[unit],
- line->tPlane[unit], invQ,
- line->texWidth[unit], line->texHeight[unit]);
+ const GLfloat invQ = solve_plane_recip(fx, fy, line->vPlane[unit]);
+ line->span.array->texcoords[unit][i][0] = solve_plane(fx, fy, line->sPlane[unit]) * invQ;
+ line->span.array->texcoords[unit][i][1] = solve_plane(fx, fy, line->tPlane[unit]) * invQ;
+ line->span.array->texcoords[unit][i][2] = solve_plane(fx, fy, line->uPlane[unit]) * invQ;
+ line->span.array->lambda[unit][i] = compute_lambda(line->sPlane[unit],
+ line->tPlane[unit], invQ,
+ line->texWidth[unit], line->texHeight[unit]);
}
}
}
-#else
- (void) tex[0][0];
- (void) lambda[0];
#endif
-
- PB_COVERAGE(pb, coverage);
-
-#if defined(DO_MULTITEX)
-#if defined(DO_SPEC)
- PB_WRITE_MULTITEX_SPEC_PIXEL(pb, ix, iy, z, fog, red, green, blue, alpha,
- specRed, specGreen, specBlue, tex);
-#else
- PB_WRITE_MULTITEX_PIXEL(pb, ix, iy, z, fog, red, green, blue, alpha, tex);
-#endif
-#elif defined(DO_TEX)
- PB_WRITE_TEX_PIXEL(pb, ix, iy, z, fog, red, green, blue, alpha,
- tex[0][0], tex[0][1], tex[0][2]);
+ if (line->span.end == MAX_WIDTH) {
+#if defined(DO_TEX) || defined(DO_MULTITEX)
+ _mesa_write_texture_span(ctx, &(line->span));
#elif defined(DO_RGBA)
- PB_WRITE_RGBA_PIXEL(pb, ix, iy, z, fog, red, green, blue, alpha);
-#elif defined(DO_INDEX)
- PB_WRITE_CI_PIXEL(pb, ix, iy, z, fog, index);
+ _mesa_write_rgba_span(ctx, &(line->span));
+#else
+ _mesa_write_index_span(ctx, &(line->span));
#endif
-
- pb->haveCoverage = GL_TRUE;
- PB_CHECK_FLUSH(ctx, pb);
+ line->span.end = 0; /* reset counter */
+ }
}
@@ -146,7 +119,6 @@ static void
NAME(line)(GLcontext *ctx, const SWvertex *v0, const SWvertex *v1)
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
- struct pixel_buffer *pb = SWRAST_CONTEXT(ctx)->PB;
GLfloat tStart, tEnd; /* segment start, end along line length */
GLboolean inSegment;
GLint iLen, i;
@@ -165,18 +137,23 @@ 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);
+
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);
#endif
#ifdef DO_RGBA
+ line.span.arrayMask |= SPAN_RGBA;
if (ctx->Light.ShadeModel == GL_SMOOTH) {
compute_plane(line.x0, line.y0, line.x1, line.y1,
v0->color[RCOMP], v1->color[RCOMP], line.rPlane);
@@ -195,6 +172,7 @@ NAME(line)(GLcontext *ctx, const SWvertex *v0, const SWvertex *v1)
}
#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);
@@ -210,6 +188,7 @@ NAME(line)(GLcontext *ctx, const SWvertex *v0, const SWvertex *v1)
}
#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,
(GLfloat) v0->index, (GLfloat) v1->index, line.iPlane);
@@ -232,6 +211,7 @@ NAME(line)(GLcontext *ctx, const SWvertex *v0, const SWvertex *v1)
const GLfloat r1 = v1->texcoord[0][2] * invW0;
const GLfloat q0 = v0->texcoord[0][3] * invW0;
const GLfloat q1 = v1->texcoord[0][3] * invW0;
+ line.span.arrayMask |= (SPAN_TEXTURE | SPAN_LAMBDA);
compute_plane(line.x0, line.y0, line.x1, line.y1, s0, s1, line.sPlane[0]);
compute_plane(line.x0, line.y0, line.x1, line.y1, t0, t1, line.tPlane[0]);
compute_plane(line.x0, line.y0, line.x1, line.y1, r0, r1, line.uPlane[0]);
@@ -242,6 +222,7 @@ NAME(line)(GLcontext *ctx, const SWvertex *v0, const SWvertex *v1)
#elif defined(DO_MULTITEX)
{
GLuint u;
+ line.span.arrayMask |= (SPAN_TEXTURE | SPAN_LAMBDA);
for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
if (ctx->Texture.Unit[u]._ReallyEnabled) {
const struct gl_texture_object *obj = ctx->Texture.Unit[u]._Current;
@@ -291,7 +272,7 @@ NAME(line)(GLcontext *ctx, const SWvertex *v0, const SWvertex *v1)
/* stipple bit is off */
if (inSegment && (tEnd > tStart)) {
/* draw the segment */
- segment(ctx, &line, NAME(plot), pb, tStart, tEnd);
+ segment(ctx, &line, NAME(plot), tStart, tEnd);
inSegment = GL_FALSE;
}
else {
@@ -303,13 +284,21 @@ NAME(line)(GLcontext *ctx, const SWvertex *v0, const SWvertex *v1)
if (inSegment) {
/* draw the final segment of the line */
- segment(ctx, &line, NAME(plot), pb, tStart, 1.0F);
+ segment(ctx, &line, NAME(plot), tStart, 1.0F);
}
}
else {
/* non-stippled */
- segment(ctx, &line, NAME(plot), pb, 0.0, 1.0);
+ segment(ctx, &line, NAME(plot), 0.0, 1.0);
}
+
+#if defined(DO_TEX) || defined(DO_MULTITEX)
+ _mesa_write_texture_span(ctx, &(line.span));
+#elif defined(DO_RGBA)
+ _mesa_write_rgba_span(ctx, &(line.span));
+#else
+ _mesa_write_index_span(ctx, &(line.span));
+#endif
}
diff --git a/xc/extras/Mesa/src/swrast/s_aatriangle.c b/xc/extras/Mesa/src/swrast/s_aatriangle.c
index e58e93b7e..6a8c38ea3 100644
--- a/xc/extras/Mesa/src/swrast/s_aatriangle.c
+++ b/xc/extras/Mesa/src/swrast/s_aatriangle.c
@@ -1,10 +1,9 @@
-/* $Id: s_aatriangle.c,v 1.1.1.1 2002/10/22 13:06:45 alanh Exp $ */
/*
* Mesa 3-D graphics library
- * Version: 4.0.1
+ * Version: 4.1
*
- * Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
+ * Copyright (C) 1999-2002 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"),
@@ -30,7 +29,9 @@
*/
-#include "mem.h"
+#include "glheader.h"
+#include "macros.h"
+#include "imports.h"
#include "mmath.h"
#include "s_aatriangle.h"
#include "s_context.h"
@@ -40,6 +41,7 @@
/*
* Compute coefficients of a plane using the X,Y coords of the v0, v1, v2
* vertices and the given Z values.
+ * A point (x,y,z) lies on plane iff a*x+b*y+c*z+d = 0.
*/
static INLINE void
compute_plane(const GLfloat v0[], const GLfloat v1[], const GLfloat v2[],
@@ -53,9 +55,15 @@ compute_plane(const GLfloat v0[], const GLfloat v1[], const GLfloat v2[],
const GLfloat qy = v2[1] - v0[1];
const GLfloat qz = z2 - z0;
+ /* Crossproduct "(a,b,c):= dv1 x dv2" is orthogonal to plane. */
const GLfloat a = py * qz - pz * qy;
const GLfloat b = pz * qx - px * qz;
const GLfloat c = px * qy - py * qx;
+ /* Point on the plane = "r*(a,b,c) + w", with fixed "r" depending
+ on the distance of plane from origin and arbitrary "w" parallel
+ to the plane. */
+ /* The scalar product "(r*(a,b,c)+w)*(a,b,c)" is "r*(a^2+b^2+c^2)",
+ which is equal to "-d" below. */
const GLfloat d = -(a * v0[0] + b * v0[1] + c * z0);
plane[0] = a;
@@ -93,8 +101,8 @@ do { \
static INLINE GLfloat
solve_plane(GLfloat x, GLfloat y, const GLfloat plane[4])
{
- const GLfloat z = (plane[3] + plane[0] * x + plane[1] * y) / -plane[2];
- return z;
+ ASSERT(plane[2] != 0.0F);
+ return (plane[3] + plane[0] * x + plane[1] * y) / -plane[2];
}
@@ -116,7 +124,6 @@ solve_plane_recip(GLfloat x, GLfloat y, const GLfloat plane[4])
}
-
/*
* Solve plane and return clamped GLchan value.
*/
@@ -193,7 +200,7 @@ compute_coveragef(const GLfloat v0[3], const GLfloat v1[3],
#ifdef DEBUG
{
const GLfloat area = dx0 * dy1 - dx1 * dy0;
- assert(area >= 0.0);
+ ASSERT(area >= 0.0);
}
#endif
@@ -276,7 +283,7 @@ compute_coveragei(const GLfloat v0[3], const GLfloat v1[3],
#ifdef DEBUG
{
const GLfloat area = dx0 * dy1 - dx1 * dy0;
- assert(area >= 0.0);
+ ASSERT(area >= 0.0);
}
#endif
@@ -344,23 +351,36 @@ index_aa_tri(GLcontext *ctx,
/*
* 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],
- GLfloat invQ, GLfloat width, GLfloat height)
+ const GLfloat qPlane[4], GLfloat cx, GLfloat cy,
+ GLfloat invQ, GLfloat texWidth, GLfloat texHeight)
{
- GLfloat dudx = sPlane[0] / sPlane[2] * invQ * width;
- GLfloat dudy = sPlane[1] / sPlane[2] * invQ * width;
- GLfloat dvdx = tPlane[0] / tPlane[2] * invQ * height;
- GLfloat dvdy = tPlane[1] / tPlane[2] * invQ * height;
- GLfloat r1 = dudx * dudx + dudy * dudy;
- GLfloat r2 = dvdx * dvdx + dvdy * dvdy;
- GLfloat rho2 = r1 + r2;
- /* return log base 2 of rho */
- if (rho2 == 0.0F)
- return 0.0;
- else
- return (GLfloat) (log(rho2) * 1.442695 * 0.5); /* 1.442695 = 1/log(2) */
+ 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;
}
@@ -430,9 +450,9 @@ _mesa_set_aa_triangle_function(GLcontext *ctx)
{
ASSERT(ctx->Polygon.SmoothFlag);
- if (ctx->Texture._ReallyEnabled) {
+ if (ctx->Texture._EnabledUnits != 0) {
if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR) {
- if (ctx->Texture._ReallyEnabled > TEXTURE0_ANY) {
+ if (ctx->Texture._EnabledUnits > 1) {
SWRAST_CONTEXT(ctx)->Triangle = spec_multitex_aa_tri;
}
else {
@@ -440,7 +460,7 @@ _mesa_set_aa_triangle_function(GLcontext *ctx)
}
}
else {
- if (ctx->Texture._ReallyEnabled > TEXTURE0_ANY) {
+ if (ctx->Texture._EnabledUnits > 1) {
SWRAST_CONTEXT(ctx)->Triangle = multitex_aa_tri;
}
else {
diff --git a/xc/extras/Mesa/src/swrast/s_aatritemp.h b/xc/extras/Mesa/src/swrast/s_aatritemp.h
index 0b2e073de..abe99ecf4 100644
--- a/xc/extras/Mesa/src/swrast/s_aatritemp.h
+++ b/xc/extras/Mesa/src/swrast/s_aatritemp.h
@@ -1,10 +1,9 @@
-/* $Id: s_aatritemp.h,v 1.1.1.1 2002/10/22 13:06:51 alanh Exp $ */
/*
* Mesa 3-D graphics library
- * Version: 3.5
+ * Version: 4.1
*
- * Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
+ * Copyright (C) 1999-2002 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,64 +51,40 @@
GLfloat yMin, yMax;
GLboolean ltor;
GLfloat majDx, majDy; /* major (i.e. long) edge dx and dy */
-
+
+ struct sw_span span;
+
#ifdef DO_Z
GLfloat zPlane[4];
- GLdepth z[MAX_WIDTH];
#endif
#ifdef DO_FOG
GLfloat fogPlane[4];
- GLfloat fog[MAX_WIDTH];
#else
GLfloat *fog = NULL;
#endif
#ifdef DO_RGBA
GLfloat rPlane[4], gPlane[4], bPlane[4], aPlane[4];
- DEFMARRAY(GLchan, rgba, MAX_WIDTH, 4); /* mac 32k limitation */
#endif
#ifdef DO_INDEX
GLfloat iPlane[4];
- GLuint index[MAX_WIDTH];
- GLint icoverageSpan[MAX_WIDTH];
-#else
- GLfloat coverageSpan[MAX_WIDTH];
#endif
#ifdef DO_SPEC
GLfloat srPlane[4], sgPlane[4], sbPlane[4];
- DEFMARRAY(GLchan, spec, MAX_WIDTH, 4);
#endif
#ifdef DO_TEX
GLfloat sPlane[4], tPlane[4], uPlane[4], vPlane[4];
GLfloat texWidth, texHeight;
- DEFARRAY(GLfloat, s, MAX_WIDTH); /* mac 32k limitation */
- DEFARRAY(GLfloat, t, MAX_WIDTH);
- DEFARRAY(GLfloat, u, MAX_WIDTH);
- DEFARRAY(GLfloat, lambda, MAX_WIDTH);
#elif defined(DO_MULTITEX)
- GLfloat sPlane[MAX_TEXTURE_UNITS][4];
- GLfloat tPlane[MAX_TEXTURE_UNITS][4];
- GLfloat uPlane[MAX_TEXTURE_UNITS][4];
- GLfloat vPlane[MAX_TEXTURE_UNITS][4];
+ GLfloat sPlane[MAX_TEXTURE_UNITS][4]; /* texture S */
+ GLfloat tPlane[MAX_TEXTURE_UNITS][4]; /* texture T */
+ GLfloat uPlane[MAX_TEXTURE_UNITS][4]; /* texture R */
+ GLfloat vPlane[MAX_TEXTURE_UNITS][4]; /* texture Q */
GLfloat texWidth[MAX_TEXTURE_UNITS], texHeight[MAX_TEXTURE_UNITS];
- DEFMARRAY(GLfloat, s, MAX_TEXTURE_UNITS, MAX_WIDTH); /* mac 32k limit */
- DEFMARRAY(GLfloat, t, MAX_TEXTURE_UNITS, MAX_WIDTH);
- DEFMARRAY(GLfloat, u, MAX_TEXTURE_UNITS, MAX_WIDTH);
- DEFMARRAY(GLfloat, lambda, MAX_TEXTURE_UNITS, MAX_WIDTH);
#endif
GLfloat bf = SWRAST_CONTEXT(ctx)->_backface_sign;
-
-#ifdef DO_RGBA
- CHECKARRAY(rgba, return); /* mac 32k limitation */
-#endif
-#ifdef DO_SPEC
- CHECKARRAY(spec, return);
-#endif
-#if defined(DO_TEX) || defined(DO_MULTITEX)
- CHECKARRAY(s, return);
- CHECKARRAY(t, return);
- CHECKARRAY(u, return);
- CHECKARRAY(lambda, return);
-#endif
+
+
+ INIT_SPAN(span, GL_POLYGON, 0, 0, SPAN_COVERAGE);
/* determine bottom to top order of vertices */
{
@@ -164,9 +139,11 @@
*/
#ifdef DO_Z
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) {
@@ -181,6 +158,7 @@
constant_plane(v2->color[BCOMP], bPlane);
constant_plane(v2->color[ACOMP], aPlane);
}
+ span.arrayMask |= SPAN_RGBA;
#endif
#ifdef DO_INDEX
if (ctx->Light.ShadeModel == GL_SMOOTH) {
@@ -190,6 +168,7 @@
else {
constant_plane((GLfloat) v2->index, iPlane);
}
+ span.arrayMask |= SPAN_INDEX;
#endif
#ifdef DO_SPEC
if (ctx->Light.ShadeModel == GL_SMOOTH) {
@@ -202,6 +181,7 @@
constant_plane(v2->specular[GCOMP], sgPlane);
constant_plane(v2->specular[BCOMP], sbPlane);
}
+ span.arrayMask |= SPAN_SPEC;
#endif
#ifdef DO_TEX
{
@@ -229,6 +209,7 @@
texWidth = (GLfloat) texImage->Width;
texHeight = (GLfloat) texImage->Height;
}
+ span.arrayMask |= (SPAN_TEXTURE | SPAN_LAMBDA);
#elif defined(DO_MULTITEX)
{
GLuint u;
@@ -260,6 +241,7 @@
}
}
}
+ span.arrayMask |= (SPAN_TEXTURE | SPAN_LAMBDA);
#endif
/* Begin bottom-to-top scan over the triangle.
@@ -284,8 +266,9 @@
GLint iy;
for (iy = iyMin; iy < iyMax; iy++, x += dxdy) {
GLint ix, startX = (GLint) (x - xAdj);
- GLuint count, n;
+ GLuint count;
GLfloat coverage = 0.0F;
+
/* skip over fragments with zero coverage */
while (startX < MAX_WIDTH) {
coverage = compute_coveragef(pMin, pMid, pMax, startX, iy);
@@ -300,39 +283,41 @@
while (coverage > 0.0F) {
/* (cx,cy) = center of fragment */
const GLfloat cx = ix + 0.5F, cy = iy + 0.5F;
+ struct span_arrays *array = span.array;
#ifdef DO_INDEX
- icoverageSpan[count] = compute_coveragei(pMin, pMid, pMax, ix, iy);
+ array->coverage[count] = (GLfloat) compute_coveragei(pMin, pMid, pMax, ix, iy);
#else
- coverageSpan[count] = coverage;
+ array->coverage[count] = coverage;
#endif
#ifdef DO_Z
- z[count] = (GLdepth) solve_plane(cx, cy, zPlane);
+ array->z[count] = (GLdepth) solve_plane(cx, cy, zPlane);
#endif
#ifdef DO_FOG
- fog[count] = solve_plane(cx, cy, fogPlane);
+ array->fog[count] = solve_plane(cx, cy, fogPlane);
#endif
#ifdef DO_RGBA
- rgba[count][RCOMP] = solve_plane_chan(cx, cy, rPlane);
- rgba[count][GCOMP] = solve_plane_chan(cx, cy, gPlane);
- rgba[count][BCOMP] = solve_plane_chan(cx, cy, bPlane);
- rgba[count][ACOMP] = solve_plane_chan(cx, cy, aPlane);
+ array->rgba[count][RCOMP] = solve_plane_chan(cx, cy, rPlane);
+ array->rgba[count][GCOMP] = solve_plane_chan(cx, cy, gPlane);
+ array->rgba[count][BCOMP] = solve_plane_chan(cx, cy, bPlane);
+ array->rgba[count][ACOMP] = solve_plane_chan(cx, cy, aPlane);
#endif
#ifdef DO_INDEX
- index[count] = (GLint) solve_plane(cx, cy, iPlane);
+ array->index[count] = (GLint) solve_plane(cx, cy, iPlane);
#endif
#ifdef DO_SPEC
- spec[count][RCOMP] = solve_plane_chan(cx, cy, srPlane);
- spec[count][GCOMP] = solve_plane_chan(cx, cy, sgPlane);
- spec[count][BCOMP] = solve_plane_chan(cx, cy, sbPlane);
+ 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
#ifdef DO_TEX
{
const GLfloat invQ = solve_plane_recip(cx, cy, vPlane);
- s[count] = solve_plane(cx, cy, sPlane) * invQ;
- t[count] = solve_plane(cx, cy, tPlane) * invQ;
- u[count] = solve_plane(cx, cy, uPlane) * invQ;
- lambda[count] = compute_lambda(sPlane, tPlane, invQ,
- texWidth, texHeight);
+ array->texcoords[0][count][0] = solve_plane(cx, cy, sPlane) * invQ;
+ array->texcoords[0][count][1] = solve_plane(cx, cy, tPlane) * invQ;
+ array->texcoords[0][count][2] = solve_plane(cx, cy, uPlane) * invQ;
+ array->lambda[0][count] = compute_lambda(sPlane, tPlane, vPlane,
+ cx, cy, invQ,
+ texWidth, texHeight);
}
#elif defined(DO_MULTITEX)
{
@@ -340,11 +325,12 @@
for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) {
if (ctx->Texture.Unit[unit]._ReallyEnabled) {
GLfloat invQ = solve_plane_recip(cx, cy, vPlane[unit]);
- s[unit][count] = solve_plane(cx, cy, sPlane[unit]) * invQ;
- t[unit][count] = solve_plane(cx, cy, tPlane[unit]) * invQ;
- u[unit][count] = solve_plane(cx, cy, uPlane[unit]) * invQ;
- lambda[unit][count] = compute_lambda(sPlane[unit],
- tPlane[unit], invQ, texWidth[unit], texHeight[unit]);
+ array->texcoords[unit][count][0] = solve_plane(cx, cy, sPlane[unit]) * invQ;
+ array->texcoords[unit][count][1] = solve_plane(cx, cy, tPlane[unit]) * invQ;
+ array->texcoords[unit][count][2] = solve_plane(cx, cy, uPlane[unit]) * invQ;
+ array->lambda[unit][count] = compute_lambda(sPlane[unit],
+ tPlane[unit], vPlane[unit], cx, cy, invQ,
+ texWidth[unit], texHeight[unit]);
}
}
}
@@ -353,46 +339,20 @@
count++;
coverage = compute_coveragef(pMin, pMid, pMax, ix, iy);
}
-
+
if (ix <= startX)
continue;
-
- n = (GLuint) ix - (GLuint) startX;
-
-#ifdef DO_MULTITEX
-# ifdef DO_SPEC
- _mesa_write_multitexture_span(ctx, n, startX, iy, z, fog,
- (const GLfloat (*)[MAX_WIDTH]) s,
- (const GLfloat (*)[MAX_WIDTH]) t,
- (const GLfloat (*)[MAX_WIDTH]) u,
- (GLfloat (*)[MAX_WIDTH]) lambda,
- rgba, (const GLchan (*)[4]) spec,
- coverageSpan, GL_POLYGON);
-# else
- _mesa_write_multitexture_span(ctx, n, startX, iy, z, fog,
- (const GLfloat (*)[MAX_WIDTH]) s,
- (const GLfloat (*)[MAX_WIDTH]) t,
- (const GLfloat (*)[MAX_WIDTH]) u,
- lambda, rgba, NULL, coverageSpan,
- GL_POLYGON);
-# endif
-#elif defined(DO_TEX)
-# ifdef DO_SPEC
- _mesa_write_texture_span(ctx, n, startX, iy, z, fog,
- s, t, u, lambda, rgba,
- (const GLchan (*)[4]) spec,
- coverageSpan, GL_POLYGON);
-# else
- _mesa_write_texture_span(ctx, n, startX, iy, z, fog,
- s, t, u, lambda,
- rgba, NULL, coverageSpan, GL_POLYGON);
-# endif
+
+ span.x = startX;
+ span.y = iy;
+ span.end = (GLuint) ix - (GLuint) startX;
+ ASSERT(span.interpMask == 0);
+#if defined(DO_MULTITEX) || defined(DO_TEX)
+ _mesa_write_texture_span(ctx, &span);
#elif defined(DO_RGBA)
- _mesa_write_rgba_span(ctx, n, startX, iy, z, fog, rgba,
- coverageSpan, GL_POLYGON);
+ _mesa_write_rgba_span(ctx, &span);
#elif defined(DO_INDEX)
- _mesa_write_index_span(ctx, n, startX, iy, z, fog, index,
- icoverageSpan, GL_POLYGON);
+ _mesa_write_index_span(ctx, &span);
#endif
}
}
@@ -409,7 +369,7 @@
GLint ix, left, startX = (GLint) (x + xAdj);
GLuint count, n;
GLfloat coverage = 0.0F;
-
+
/* make sure we're not past the window edge */
if (startX >= ctx->DrawBuffer->_Xmax) {
startX = ctx->DrawBuffer->_Xmax - 1;
@@ -422,46 +382,47 @@
break;
startX--;
}
-
+
/* enter interior of triangle */
ix = startX;
count = 0;
while (coverage > 0.0F) {
/* (cx,cy) = center of fragment */
const GLfloat cx = ix + 0.5F, cy = iy + 0.5F;
+ struct span_arrays *array = span.array;
#ifdef DO_INDEX
- icoverageSpan[ix] = compute_coveragei(pMin, pMid, pMax, ix, iy);
+ array->coverage[ix] = (GLfloat) compute_coveragei(pMin, pMax, pMid, ix, iy);
#else
- coverageSpan[ix] = coverage;
+ array->coverage[ix] = coverage;
#endif
#ifdef DO_Z
- z[ix] = (GLdepth) solve_plane(cx, cy, zPlane);
+ array->z[ix] = (GLdepth) solve_plane(cx, cy, zPlane);
#endif
#ifdef DO_FOG
- fog[ix] = solve_plane(cx, cy, fogPlane);
+ array->fog[ix] = solve_plane(cx, cy, fogPlane);
#endif
#ifdef DO_RGBA
- rgba[ix][RCOMP] = solve_plane_chan(cx, cy, rPlane);
- rgba[ix][GCOMP] = solve_plane_chan(cx, cy, gPlane);
- rgba[ix][BCOMP] = solve_plane_chan(cx, cy, bPlane);
- rgba[ix][ACOMP] = solve_plane_chan(cx, cy, aPlane);
+ array->rgba[ix][RCOMP] = solve_plane_chan(cx, cy, rPlane);
+ array->rgba[ix][GCOMP] = solve_plane_chan(cx, cy, gPlane);
+ array->rgba[ix][BCOMP] = solve_plane_chan(cx, cy, bPlane);
+ array->rgba[ix][ACOMP] = solve_plane_chan(cx, cy, aPlane);
#endif
#ifdef DO_INDEX
- index[ix] = (GLint) solve_plane(cx, cy, iPlane);
+ array->index[ix] = (GLint) solve_plane(cx, cy, iPlane);
#endif
#ifdef DO_SPEC
- spec[ix][RCOMP] = solve_plane_chan(cx, cy, srPlane);
- spec[ix][GCOMP] = solve_plane_chan(cx, cy, sgPlane);
- spec[ix][BCOMP] = solve_plane_chan(cx, cy, sbPlane);
+ 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
#ifdef DO_TEX
{
const GLfloat invQ = solve_plane_recip(cx, cy, vPlane);
- s[ix] = solve_plane(cx, cy, sPlane) * invQ;
- t[ix] = solve_plane(cx, cy, tPlane) * invQ;
- u[ix] = solve_plane(cx, cy, uPlane) * invQ;
- lambda[ix] = compute_lambda(sPlane, tPlane, invQ,
- texWidth, texHeight);
+ array->texcoords[0][ix][0] = solve_plane(cx, cy, sPlane) * invQ;
+ array->texcoords[0][ix][1] = solve_plane(cx, cy, tPlane) * invQ;
+ array->texcoords[0][ix][2] = solve_plane(cx, cy, uPlane) * invQ;
+ array->lambda[0][ix] = compute_lambda(sPlane, tPlane, vPlane,
+ cx, cy, invQ, texWidth, texHeight);
}
#elif defined(DO_MULTITEX)
{
@@ -469,11 +430,15 @@
for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) {
if (ctx->Texture.Unit[unit]._ReallyEnabled) {
GLfloat invQ = solve_plane_recip(cx, cy, vPlane[unit]);
- s[unit][ix] = solve_plane(cx, cy, sPlane[unit]) * invQ;
- t[unit][ix] = solve_plane(cx, cy, tPlane[unit]) * invQ;
- u[unit][ix] = solve_plane(cx, cy, uPlane[unit]) * invQ;
- lambda[unit][ix] = compute_lambda(sPlane[unit],
- tPlane[unit], invQ, texWidth[unit], texHeight[unit]);
+ array->texcoords[unit][ix][0] = solve_plane(cx, cy, sPlane[unit]) * invQ;
+ array->texcoords[unit][ix][1] = solve_plane(cx, cy, tPlane[unit]) * invQ;
+ array->texcoords[unit][ix][2] = solve_plane(cx, cy, uPlane[unit]) * invQ;
+ array->lambda[unit][ix] = compute_lambda(sPlane[unit],
+ tPlane[unit],
+ vPlane[unit],
+ cx, cy, invQ,
+ texWidth[unit],
+ texHeight[unit]);
}
}
}
@@ -482,83 +447,76 @@
count++;
coverage = compute_coveragef(pMin, pMax, pMid, ix, iy);
}
-
+
if (startX <= ix)
continue;
n = (GLuint) startX - (GLuint) ix;
left = ix + 1;
+
+ /* shift all values to the left */
+ /* XXX this is temporary */
+ {
+ struct span_arrays *array = span.array;
+ GLint j;
+ for (j = 0; j < (GLint) n; j++) {
+#ifdef DO_RGBA
+ COPY_4V(array->rgba[j], array->rgba[j + left]);
+#endif
+#ifdef DO_SPEC
+ COPY_4V(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->fog[j] = array->fog[j + left];
+#endif
+#ifdef DO_TEX
+ COPY_4V(array->texcoords[0][j], array->texcoords[0][j + left]);
+#endif
+#if defined(DO_MULTITEX) || defined(DO_TEX)
+ array->lambda[0][j] = array->lambda[0][j + left];
+#endif
+ array->coverage[j] = array->coverage[j + left];
+ }
+ }
#ifdef DO_MULTITEX
+ /* shift texcoords */
{
+ struct span_arrays *array = span.array;
GLuint unit;
for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) {
if (ctx->Texture.Unit[unit]._ReallyEnabled) {
GLint j;
for (j = 0; j < (GLint) n; j++) {
- s[unit][j] = s[unit][j + left];
- t[unit][j] = t[unit][j + left];
- u[unit][j] = u[unit][j + left];
- lambda[unit][j] = lambda[unit][j + left];
+ array->texcoords[unit][j][0] = array->texcoords[unit][j + left][0];
+ array->texcoords[unit][j][1] = array->texcoords[unit][j + left][1];
+ array->texcoords[unit][j][2] = array->texcoords[unit][j + left][2];
+ array->lambda[unit][j] = array->lambda[unit][j + left];
}
}
}
}
-# ifdef DO_SPEC
- _mesa_write_multitexture_span(ctx, n, left, iy, z + left, fog + left,
- (const GLfloat (*)[MAX_WIDTH]) s,
- (const GLfloat (*)[MAX_WIDTH]) t,
- (const GLfloat (*)[MAX_WIDTH]) u,
- lambda, rgba + left,
- (const GLchan (*)[4]) (spec + left),
- coverageSpan + left,
- GL_POLYGON);
-# else
- _mesa_write_multitexture_span(ctx, n, left, iy, z + left, fog + left,
- (const GLfloat (*)[MAX_WIDTH]) s,
- (const GLfloat (*)[MAX_WIDTH]) t,
- (const GLfloat (*)[MAX_WIDTH]) u,
- lambda,
- rgba + left, NULL, coverageSpan + left,
- GL_POLYGON);
-# endif
-#elif defined(DO_TEX)
-# ifdef DO_SPEC
- _mesa_write_texture_span(ctx, n, left, iy, z + left, fog + left,
- s + left, t + left, u + left,
- lambda + left, rgba + left,
- (const GLchan (*)[4]) (spec + left),
- coverageSpan + left,
- GL_POLYGON);
-# else
- _mesa_write_texture_span(ctx, n, left, iy, z + left, fog + left,
- s + left, t + left,
- u + left, lambda + left,
- rgba + left, NULL,
- coverageSpan + left, GL_POLYGON);
-# endif
+#endif
+
+ span.x = left;
+ span.y = iy;
+ span.end = n;
+ ASSERT(span.interpMask == 0);
+#if defined(DO_MULTITEX) || defined(DO_TEX)
+ _mesa_write_texture_span(ctx, &span);
#elif defined(DO_RGBA)
- _mesa_write_rgba_span(ctx, n, left, iy, z + left, fog + left,
- rgba + left, coverageSpan + left, GL_POLYGON);
+ _mesa_write_rgba_span(ctx, &span);
#elif defined(DO_INDEX)
- _mesa_write_index_span(ctx, n, left, iy, z + left, fog + left,
- index + left, icoverageSpan + left, GL_POLYGON);
+ _mesa_write_index_span(ctx, &span);
#endif
}
}
-
-#ifdef DO_RGBA
- UNDEFARRAY(rgba); /* mac 32k limitation */
-#endif
-#ifdef DO_SPEC
- UNDEFARRAY(spec);
-#endif
-#if defined(DO_TEX) || defined(DO_MULTITEX)
- UNDEFARRAY(s);
- UNDEFARRAY(t);
- UNDEFARRAY(u);
- UNDEFARRAY(lambda);
-#endif
}
diff --git a/xc/extras/Mesa/src/swrast/s_accum.c b/xc/extras/Mesa/src/swrast/s_accum.c
index b93f8379e..16eca43d5 100644
--- a/xc/extras/Mesa/src/swrast/s_accum.c
+++ b/xc/extras/Mesa/src/swrast/s_accum.c
@@ -1,8 +1,7 @@
-/* $Id: s_accum.c,v 1.1.1.1 2002/10/22 13:06:55 alanh Exp $ */
/*
* Mesa 3-D graphics library
- * Version: 4.0.2
+ * Version: 4.1
*
* Copyright (C) 1999-2002 Brian Paul All Rights Reserved.
*
@@ -29,7 +28,7 @@
#include "context.h"
#include "macros.h"
#include "mmath.h"
-#include "mem.h"
+#include "imports.h"
#include "s_accum.h"
#include "s_alphabuf.h"
@@ -62,10 +61,11 @@
*/
-#if CHAN_BITS == 8
+#if CHAN_BITS == 8 && ACCUM_BITS < 32
#define USE_OPTIMIZED_ACCUM /* enable the optimization */
#endif
+
void
_mesa_alloc_accum_buffer( GLframebuffer *buffer )
{
@@ -194,7 +194,8 @@ _mesa_clear_accum_buffer( GLcontext *ctx )
ctx->Accum.ClearColor[2]==0.0 &&
ctx->Accum.ClearColor[3]==0.0) {
/* Black */
- BZERO( ctx->DrawBuffer->Accum, buffersize * 4 * sizeof(GLaccum) );
+ _mesa_bzero( ctx->DrawBuffer->Accum,
+ buffersize * 4 * sizeof(GLaccum) );
}
else {
/* Not black */
@@ -242,6 +243,7 @@ _swrast_Accum( GLcontext *ctx, GLenum op, GLfloat value,
GLchan rgba[MAX_WIDTH][4];
const GLuint colorMask = *((GLuint *) &ctx->Color.ColorMask);
+
if (SWRAST_CONTEXT(ctx)->NewState)
_swrast_validate_derived( ctx );
@@ -304,8 +306,7 @@ _swrast_Accum( GLcontext *ctx, GLenum op, GLfloat value,
if (value == 0.0F)
return;
- (*swrast->Driver.SetReadBuffer)( ctx, ctx->ReadBuffer,
- ctx->Pixel.DriverReadBuffer );
+ _swrast_use_read_buffer(ctx);
/* May have to leave optimized accum buffer mode */
if (swrast->_IntegerAccumScaler == 0.0 && value > 0.0 && value <= 1.0)
@@ -357,14 +358,13 @@ _swrast_Accum( GLcontext *ctx, GLenum op, GLfloat value,
}
}
/* restore read buffer = draw buffer (the default) */
- (*swrast->Driver.SetReadBuffer)( ctx, ctx->DrawBuffer,
- ctx->Color.DriverDrawBuffer );
+ _swrast_use_draw_buffer(ctx);
+
RENDER_FINISH(swrast,ctx);
break;
case GL_LOAD:
- (*swrast->Driver.SetReadBuffer)( ctx, ctx->ReadBuffer,
- ctx->Pixel.DriverReadBuffer );
+ _swrast_use_read_buffer(ctx);
/* This is a change to go into optimized accum buffer mode */
if (value > 0.0 && value <= 1.0) {
@@ -431,8 +431,8 @@ _swrast_Accum( GLcontext *ctx, GLenum op, GLfloat value,
}
/* restore read buffer = draw buffer (the default) */
- (*swrast->Driver.SetReadBuffer)( ctx, ctx->DrawBuffer,
- ctx->Color.DriverDrawBuffer );
+ _swrast_use_draw_buffer(ctx);
+
RENDER_FINISH(swrast,ctx);
break;
@@ -472,7 +472,7 @@ _swrast_Accum( GLcontext *ctx, GLenum op, GLfloat value,
rgba[i][ACOMP] = multTable[acc[i4+3]];
}
if (colorMask != 0xffffffff) {
- _mesa_mask_rgba_span( ctx, width, xpos, ypos, rgba );
+ _mesa_mask_rgba_array( ctx, width, xpos, ypos, rgba );
}
(*swrast->Driver.WriteRGBASpan)( ctx, width, xpos, ypos,
(const GLchan (*)[4])rgba, NULL );
@@ -507,7 +507,7 @@ _swrast_Accum( GLcontext *ctx, GLenum op, GLfloat value,
rgba[i][ACOMP] = CLAMP( a, 0, CHAN_MAX );
}
if (colorMask != 0xffffffff) {
- _mesa_mask_rgba_span( ctx, width, xpos, ypos, rgba );
+ _mesa_mask_rgba_array( ctx, width, xpos, ypos, rgba );
}
(*swrast->Driver.WriteRGBASpan)( ctx, width, xpos, ypos,
(const GLchan (*)[4])rgba, NULL );
diff --git a/xc/extras/Mesa/src/swrast/s_alpha.c b/xc/extras/Mesa/src/swrast/s_alpha.c
index 0d6353ec0..22ccff6dc 100644
--- a/xc/extras/Mesa/src/swrast/s_alpha.c
+++ b/xc/extras/Mesa/src/swrast/s_alpha.c
@@ -1,10 +1,9 @@
-/* $Id: s_alpha.c,v 1.1.1.1 2002/10/22 13:06:58 alanh Exp $ */
/*
* Mesa 3-D graphics library
- * Version: 3.5
+ * Version: 4.1
*
- * Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
+ * Copyright (C) 1999-2002 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"),
@@ -24,6 +23,10 @@
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
+/**
+ * \file swrast/s_alpha.c
+ * \brief Functions to apply alpha test.
+ */
#include "glheader.h"
#include "context.h"
@@ -32,67 +35,191 @@
#include "mmath.h"
#include "s_alpha.h"
+#include "s_context.h"
-
-
-
-/*
- * Apply the alpha test to a span of pixels.
- * In: rgba - array of pixels
- * In/Out: mask - current pixel mask. Pixels which fail the alpha test
- * will set the corresponding mask flag to 0.
- * Return: 0 = all pixels in the span failed the alpha test.
- * 1 = one or more pixels passed the alpha test.
+/**
+ * \fn GLint _mesa_alpha_test( const GLcontext *ctx, struct sw_span *span )
+ * \brief Apply the alpha test to a span of pixels.
+ * \return
+ * - "0" = all pixels in the span failed the alpha test.
+ * - "1" = one or more pixels passed the alpha test.
*/
GLint
-_mesa_alpha_test( const GLcontext *ctx,
- GLuint n, CONST GLchan rgba[][4], GLubyte mask[] )
+_mesa_alpha_test( const GLcontext *ctx, struct sw_span *span )
{
+ const GLchan (*rgba)[4] = (const GLchan (*)[4]) span->array->rgba;
+ GLchan ref;
+ const GLuint n = span->end;
+ GLubyte *mask = span->array->mask;
GLuint i;
- GLchan ref = ctx->Color.AlphaRef;
- /* switch cases ordered from most frequent to less frequent */
- switch (ctx->Color.AlphaFunc) {
- case GL_LESS:
- for (i=0;i<n;i++) {
- mask[i] &= (rgba[i][ACOMP] < ref);
- }
- return 1;
- case GL_LEQUAL:
- for (i=0;i<n;i++)
- mask[i] &= (rgba[i][ACOMP] <= ref);
- return 1;
- case GL_GEQUAL:
- for (i=0;i<n;i++) {
- mask[i] &= (rgba[i][ACOMP] >= ref);
- }
- return 1;
- case GL_GREATER:
- for (i=0;i<n;i++) {
- mask[i] &= (rgba[i][ACOMP] > ref);
- }
- return 1;
- case GL_NOTEQUAL:
- for (i=0;i<n;i++) {
- mask[i] &= (rgba[i][ACOMP] != ref);
- }
- return 1;
- case GL_EQUAL:
- for (i=0;i<n;i++) {
- mask[i] &= (rgba[i][ACOMP] == ref);
- }
- return 1;
- case GL_ALWAYS:
- /* do nothing */
- return 1;
- case GL_NEVER:
- /* caller should check for zero! */
- return 0;
- default:
- _mesa_problem( ctx, "Invalid alpha test in gl_alpha_test" );
- return 0;
+ CLAMPED_FLOAT_TO_CHAN(ref, ctx->Color.AlphaRef);
+
+ if (span->arrayMask & SPAN_RGBA) {
+ /* Use the array values */
+ switch (ctx->Color.AlphaFunc) {
+ case GL_LESS:
+ for (i = 0; i < n; i++)
+ mask[i] &= (rgba[i][ACOMP] < ref);
+ break;
+ case GL_LEQUAL:
+ for (i = 0; i < n; i++)
+ mask[i] &= (rgba[i][ACOMP] <= ref);
+ break;
+ case GL_GEQUAL:
+ for (i = 0; i < n; i++)
+ mask[i] &= (rgba[i][ACOMP] >= ref);
+ break;
+ case GL_GREATER:
+ for (i = 0; i < n; i++)
+ mask[i] &= (rgba[i][ACOMP] > ref);
+ break;
+ case GL_NOTEQUAL:
+ for (i = 0; i < n; i++)
+ mask[i] &= (rgba[i][ACOMP] != ref);
+ break;
+ case GL_EQUAL:
+ for (i = 0; i < n; i++)
+ mask[i] &= (rgba[i][ACOMP] == ref);
+ break;
+ case GL_ALWAYS:
+ /* do nothing */
+ return 1;
+ case GL_NEVER:
+ /* caller should check for zero! */
+ span->writeAll = GL_FALSE;
+ return 0;
+ default:
+ _mesa_problem( ctx, "Invalid alpha test in _mesa_alpha_test" );
+ return 0;
+ }
}
- /* Never get here */
- /*return 1;*/
+ else {
+ /* Use the interpolation values */
+#if CHAN_TYPE == GL_FLOAT
+ const GLfloat alphaStep = span->alphaStep;
+ GLfloat alpha = span->alpha;
+ ASSERT(span->interpMask & SPAN_RGBA);
+ switch (ctx->Color.AlphaFunc) {
+ case GL_LESS:
+ for (i = 0; i < n; i++) {
+ mask[i] &= (alpha < ref);
+ alpha += alphaStep;
+ }
+ break;
+ case GL_LEQUAL:
+ for (i = 0; i < n; i++) {
+ mask[i] &= (alpha <= ref);
+ alpha += alphaStep;
+ }
+ break;
+ case GL_GEQUAL:
+ for (i = 0; i < n; i++) {
+ mask[i] &= (alpha >= ref);
+ alpha += alphaStep;
+ }
+ break;
+ case GL_GREATER:
+ for (i = 0; i < n; i++) {
+ mask[i] &= (alpha > ref);
+ alpha += alphaStep;
+ }
+ break;
+ case GL_NOTEQUAL:
+ for (i = 0; i < n; i++) {
+ mask[i] &= (alpha != ref);
+ alpha += alphaStep;
+ }
+ break;
+ case GL_EQUAL:
+ for (i = 0; i < n; i++) {
+ mask[i] &= (alpha == ref);
+ alpha += alphaStep;
+ }
+ break;
+ case GL_ALWAYS:
+ /* do nothing */
+ return 1;
+ case GL_NEVER:
+ /* caller should check for zero! */
+ span->writeAll = GL_FALSE;
+ return 0;
+ default:
+ _mesa_problem( ctx, "Invalid alpha test in gl_alpha_test" );
+ return 0;
+ }
+#else
+ /* 8 or 16-bit channel interpolation */
+ const GLfixed alphaStep = span->alphaStep;
+ GLfixed alpha = span->alpha;
+ ASSERT(span->interpMask & SPAN_RGBA);
+ switch (ctx->Color.AlphaFunc) {
+ case GL_LESS:
+ for (i = 0; i < n; i++) {
+ mask[i] &= (FixedToChan(alpha) < ref);
+ alpha += alphaStep;
+ }
+ break;
+ case GL_LEQUAL:
+ for (i = 0; i < n; i++) {
+ mask[i] &= (FixedToChan(alpha) <= ref);
+ alpha += alphaStep;
+ }
+ break;
+ case GL_GEQUAL:
+ for (i = 0; i < n; i++) {
+ mask[i] &= (FixedToChan(alpha) >= ref);
+ alpha += alphaStep;
+ }
+ break;
+ case GL_GREATER:
+ for (i = 0; i < n; i++) {
+ mask[i] &= (FixedToChan(alpha) > ref);
+ alpha += alphaStep;
+ }
+ break;
+ case GL_NOTEQUAL:
+ for (i = 0; i < n; i++) {
+ mask[i] &= (FixedToChan(alpha) != ref);
+ alpha += alphaStep;
+ }
+ break;
+ case GL_EQUAL:
+ for (i = 0; i < n; i++) {
+ mask[i] &= (FixedToChan(alpha) == ref);
+ alpha += alphaStep;
+ }
+ break;
+ case GL_ALWAYS:
+ /* do nothing */
+ return 1;
+ case GL_NEVER:
+ /* caller should check for zero! */
+ span->writeAll = GL_FALSE;
+ return 0;
+ default:
+ _mesa_problem( ctx, "Invalid alpha test in gl_alpha_test" );
+ return 0;
+ }
+#endif /* CHAN_TYPE */
+ }
+
+#if 0
+ /* XXXX This causes conformance failures!!!! */
+ while ((span->start <= span->end) &&
+ (mask[span->start] == 0))
+ span->start ++;
+
+ while ((span->end >= span->start) &&
+ (mask[span->end] == 0))
+ span->end --;
+#endif
+
+ span->writeAll = GL_FALSE;
+
+ if (span->start >= span->end)
+ return 0;
+ else
+ return 1;
}
diff --git a/xc/extras/Mesa/src/swrast/s_alpha.h b/xc/extras/Mesa/src/swrast/s_alpha.h
index 63e872c08..86a7d0654 100644
--- a/xc/extras/Mesa/src/swrast/s_alpha.h
+++ b/xc/extras/Mesa/src/swrast/s_alpha.h
@@ -1,10 +1,9 @@
-/* $Id: s_alpha.h,v 1.1.1.1 2002/10/22 13:06:58 alanh Exp $ */
/*
* Mesa 3-D graphics library
- * Version: 3.5
+ * Version: 4.1
*
- * Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
+ * Copyright (C) 1999-2002 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,9 +33,7 @@
extern GLint
-_mesa_alpha_test( const GLcontext *ctx, GLuint n,
- CONST GLchan rgba[][4], GLubyte mask[] );
-
+_mesa_alpha_test( const GLcontext *ctx, struct sw_span *span );
#endif
diff --git a/xc/extras/Mesa/src/swrast/s_alphabuf.c b/xc/extras/Mesa/src/swrast/s_alphabuf.c
index ee1c15933..e677fb7d6 100644
--- a/xc/extras/Mesa/src/swrast/s_alphabuf.c
+++ b/xc/extras/Mesa/src/swrast/s_alphabuf.c
@@ -1,8 +1,7 @@
-/* $Id: s_alphabuf.c,v 1.1.1.1 2002/10/22 13:06:44 alanh Exp $ */
/*
* Mesa 3-D graphics library
- * Version: 4.0.2
+ * Version: 5.0.1
*
* Copyright (C) 1999-2002 Brian Paul All Rights Reserved.
*
@@ -32,26 +31,20 @@
#include "glheader.h"
+#include "colormac.h"
#include "context.h"
-#include "mem.h"
+#include "imports.h"
+#include "s_context.h"
#include "s_alphabuf.h"
-#define ALPHA_DRAW_ADDR(X,Y) \
- (ctx->DrawBuffer->Alpha + (Y) * ctx->DrawBuffer->Width + (X))
-
-#define ALPHA_READ_ADDR(X,Y) \
- (ctx->ReadBuffer->Alpha + (Y) * ctx->ReadBuffer->Width + (X))
-
-
/*
* Allocate a new front and back alpha buffer.
*/
void
_mesa_alloc_alpha_buffers( GLframebuffer *buffer )
{
- GET_CURRENT_CONTEXT(ctx);
const GLint bytes = buffer->Width * buffer->Height * sizeof(GLchan);
ASSERT(buffer->UseSoftwareAlphaBuffers);
@@ -59,7 +52,7 @@ _mesa_alloc_alpha_buffers( GLframebuffer *buffer )
if (buffer->FrontLeftAlpha) {
MESA_PBUFFER_FREE( buffer->FrontLeftAlpha );
}
- buffer->FrontLeftAlpha = (GLchan *) MESA_PBUFFER_ALLOC( bytes );
+ buffer->FrontLeftAlpha = MESA_PBUFFER_ALLOC( bytes );
if (!buffer->FrontLeftAlpha) {
/* out of memory */
_mesa_error( NULL, GL_OUT_OF_MEMORY,
@@ -70,7 +63,7 @@ _mesa_alloc_alpha_buffers( GLframebuffer *buffer )
if (buffer->BackLeftAlpha) {
MESA_PBUFFER_FREE( buffer->BackLeftAlpha );
}
- buffer->BackLeftAlpha = (GLchan *) MESA_PBUFFER_ALLOC( bytes );
+ buffer->BackLeftAlpha = MESA_PBUFFER_ALLOC( bytes );
if (!buffer->BackLeftAlpha) {
/* out of memory */
_mesa_error( NULL, GL_OUT_OF_MEMORY,
@@ -82,7 +75,7 @@ _mesa_alloc_alpha_buffers( GLframebuffer *buffer )
if (buffer->FrontRightAlpha) {
MESA_PBUFFER_FREE( buffer->FrontRightAlpha );
}
- buffer->FrontRightAlpha = (GLchan *) MESA_PBUFFER_ALLOC( bytes );
+ buffer->FrontRightAlpha = MESA_PBUFFER_ALLOC( bytes );
if (!buffer->FrontRightAlpha) {
/* out of memory */
_mesa_error( NULL, GL_OUT_OF_MEMORY,
@@ -93,7 +86,7 @@ _mesa_alloc_alpha_buffers( GLframebuffer *buffer )
if (buffer->BackRightAlpha) {
MESA_PBUFFER_FREE( buffer->BackRightAlpha );
}
- buffer->BackRightAlpha = (GLchan *) MESA_PBUFFER_ALLOC( bytes );
+ buffer->BackRightAlpha = MESA_PBUFFER_ALLOC( bytes );
if (!buffer->BackRightAlpha) {
/* out of memory */
_mesa_error( NULL, GL_OUT_OF_MEMORY,
@@ -101,17 +94,6 @@ _mesa_alloc_alpha_buffers( GLframebuffer *buffer )
}
}
}
-
- if (ctx) {
- if (ctx->Color.DriverDrawBuffer == GL_FRONT_LEFT)
- buffer->Alpha = buffer->FrontLeftAlpha;
- else if (ctx->Color.DriverDrawBuffer == GL_BACK_LEFT)
- buffer->Alpha = buffer->BackLeftAlpha;
- else if (ctx->Color.DriverDrawBuffer == GL_FRONT_RIGHT)
- buffer->Alpha = buffer->FrontRightAlpha;
- else if (ctx->Color.DriverDrawBuffer == GL_BACK_RIGHT)
- buffer->Alpha = buffer->BackRightAlpha;
- }
}
@@ -121,27 +103,29 @@ _mesa_alloc_alpha_buffers( GLframebuffer *buffer )
void
_mesa_clear_alpha_buffers( GLcontext *ctx )
{
- const GLchan aclear = ctx->Color.ClearColor[3];
+ GLchan aclear;
GLuint bufferBit;
+ CLAMPED_FLOAT_TO_CHAN(aclear, ctx->Color.ClearColor[3]);
+
ASSERT(ctx->DrawBuffer->UseSoftwareAlphaBuffers);
ASSERT(ctx->Color.ColorMask[ACOMP]);
/* loop over four possible alpha buffers */
for (bufferBit = 1; bufferBit <= 8; bufferBit = bufferBit << 1) {
- if (bufferBit & ctx->Color.DrawDestMask) {
+ if (bufferBit & ctx->Color._DrawDestMask) {
GLchan *buffer;
if (bufferBit == FRONT_LEFT_BIT) {
- buffer = ctx->DrawBuffer->FrontLeftAlpha;
+ buffer = (GLchan *) ctx->DrawBuffer->FrontLeftAlpha;
}
else if (bufferBit == FRONT_RIGHT_BIT) {
- buffer = ctx->DrawBuffer->FrontRightAlpha;
+ buffer = (GLchan *) ctx->DrawBuffer->FrontRightAlpha;
}
else if (bufferBit == BACK_LEFT_BIT) {
- buffer = ctx->DrawBuffer->BackLeftAlpha;
+ buffer = (GLchan *) ctx->DrawBuffer->BackLeftAlpha;
}
else {
- buffer = ctx->DrawBuffer->BackRightAlpha;
+ buffer = (GLchan *) ctx->DrawBuffer->BackRightAlpha;
}
if (ctx->Scissor.Enabled) {
@@ -187,13 +171,41 @@ _mesa_clear_alpha_buffers( GLcontext *ctx )
+static INLINE
+GLchan *get_alpha_buffer( GLcontext *ctx )
+{
+ SWcontext *swrast = SWRAST_CONTEXT(ctx);
+
+ switch (swrast->CurrentBuffer) {
+ case FRONT_LEFT_BIT:
+ return (GLchan *) ctx->DrawBuffer->FrontLeftAlpha;
+ break;
+ case BACK_LEFT_BIT:
+ return (GLchan *) ctx->DrawBuffer->BackLeftAlpha;
+ break;
+ case FRONT_RIGHT_BIT:
+ return (GLchan *) ctx->DrawBuffer->FrontRightAlpha;
+ break;
+ case BACK_RIGHT_BIT:
+ return (GLchan *) ctx->DrawBuffer->BackRightAlpha;
+ break;
+ default:
+ _mesa_problem(ctx, "Bad CurrentBuffer in get_alpha_buffer()");
+ return (GLchan *) ctx->DrawBuffer->FrontLeftAlpha;
+ }
+}
+
+
void
_mesa_write_alpha_span( GLcontext *ctx, GLuint n, GLint x, GLint y,
CONST GLchan rgba[][4], const GLubyte mask[] )
{
- GLchan *aptr = ALPHA_DRAW_ADDR( x, y );
+ GLchan *buffer, *aptr;
GLuint i;
+ buffer = get_alpha_buffer(ctx);
+ aptr = buffer + y * ctx->DrawBuffer->Width + x;
+
if (mask) {
for (i=0;i<n;i++) {
if (mask[i]) {
@@ -214,9 +226,12 @@ void
_mesa_write_mono_alpha_span( GLcontext *ctx, GLuint n, GLint x, GLint y,
GLchan alpha, const GLubyte mask[] )
{
- GLchan *aptr = ALPHA_DRAW_ADDR( x, y );
+ GLchan *buffer, *aptr;
GLuint i;
+ buffer = get_alpha_buffer(ctx);
+ aptr = buffer + y * ctx->DrawBuffer->Width + x;
+
if (mask) {
for (i=0;i<n;i++) {
if (mask[i]) {
@@ -238,19 +253,22 @@ _mesa_write_alpha_pixels( GLcontext *ctx,
GLuint n, const GLint x[], const GLint y[],
CONST GLchan rgba[][4], const GLubyte mask[] )
{
+ GLchan *buffer;
GLuint i;
+ buffer = get_alpha_buffer(ctx);
+
if (mask) {
for (i=0;i<n;i++) {
if (mask[i]) {
- GLchan *aptr = ALPHA_DRAW_ADDR( x[i], y[i] );
+ GLchan *aptr = buffer + y[i] * ctx->DrawBuffer->Width + x[i];
*aptr = rgba[i][ACOMP];
}
}
}
else {
for (i=0;i<n;i++) {
- GLchan *aptr = ALPHA_DRAW_ADDR( x[i], y[i] );
+ GLchan *aptr = buffer + y[i] * ctx->DrawBuffer->Width + x[i];
*aptr = rgba[i][ACOMP];
}
}
@@ -262,19 +280,22 @@ _mesa_write_mono_alpha_pixels( GLcontext *ctx,
GLuint n, const GLint x[], const GLint y[],
GLchan alpha, const GLubyte mask[] )
{
+ GLchan *buffer;
GLuint i;
+ buffer = get_alpha_buffer(ctx);
+
if (mask) {
for (i=0;i<n;i++) {
if (mask[i]) {
- GLchan *aptr = ALPHA_DRAW_ADDR( x[i], y[i] );
+ GLchan *aptr = buffer + y[i] * ctx->DrawBuffer->Width + x[i];
*aptr = alpha;
}
}
}
else {
for (i=0;i<n;i++) {
- GLchan *aptr = ALPHA_DRAW_ADDR( x[i], y[i] );
+ GLchan *aptr = buffer + y[i] * ctx->DrawBuffer->Width + x[i];
*aptr = alpha;
}
}
@@ -286,11 +307,14 @@ void
_mesa_read_alpha_span( GLcontext *ctx,
GLuint n, GLint x, GLint y, GLchan rgba[][4] )
{
- GLchan *aptr = ALPHA_READ_ADDR( x, y );
+ const GLchan *buffer, *aptr;
GLuint i;
- for (i=0;i<n;i++) {
+
+ buffer = get_alpha_buffer(ctx);
+ aptr = buffer + y * ctx->DrawBuffer->Width + x;
+
+ for (i = 0; i < n; i++)
rgba[i][ACOMP] = *aptr++;
- }
}
@@ -299,10 +323,14 @@ _mesa_read_alpha_pixels( GLcontext *ctx,
GLuint n, const GLint x[], const GLint y[],
GLchan rgba[][4], const GLubyte mask[] )
{
+ const GLchan *buffer;
GLuint i;
- for (i=0;i<n;i++) {
+
+ buffer = get_alpha_buffer(ctx);
+
+ for (i = 0; i < n; i++) {
if (mask[i]) {
- GLchan *aptr = ALPHA_READ_ADDR( x[i], y[i] );
+ const GLchan *aptr = buffer + y[i] * ctx->DrawBuffer->Width + x[i];
rgba[i][ACOMP] = *aptr;
}
}
diff --git a/xc/extras/Mesa/src/swrast/s_bitmap.c b/xc/extras/Mesa/src/swrast/s_bitmap.c
index 2cb088369..bc6c103a9 100644
--- a/xc/extras/Mesa/src/swrast/s_bitmap.c
+++ b/xc/extras/Mesa/src/swrast/s_bitmap.c
@@ -1,10 +1,9 @@
-/* $Id: s_bitmap.c,v 1.1.1.1 2002/10/22 13:06:54 alanh Exp $ */
/*
* Mesa 3-D graphics library
- * Version: 3.5
+ * Version: 5.0
*
- * Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
+ * Copyright (C) 1999-2002 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"),
@@ -24,15 +23,20 @@
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
+/**
+ * \file swrast/s_bitmap.c
+ * \brief glBitmap rendering.
+ * \author Brian Paul
+ */
#include "glheader.h"
#include "image.h"
#include "macros.h"
+#include "mmath.h"
#include "pixel.h"
#include "s_context.h"
-#include "s_fog.h"
-#include "s_pb.h"
+#include "s_span.h"
@@ -46,10 +50,9 @@ _swrast_Bitmap( GLcontext *ctx, GLint px, GLint py,
const GLubyte *bitmap )
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
- struct pixel_buffer *PB = swrast->PB;
GLint row, col;
- GLdepth fragZ;
- GLfloat fog;
+ GLuint count = 0;
+ struct sw_span span;
ASSERT(ctx->RenderMode == GL_RENDER);
ASSERT(bitmap);
@@ -59,32 +62,146 @@ _swrast_Bitmap( GLcontext *ctx, GLint px, GLint py,
if (SWRAST_CONTEXT(ctx)->NewState)
_swrast_validate_derived( ctx );
- /* Set bitmap drawing color */
+ INIT_SPAN(span, GL_BITMAP, width, 0, SPAN_XY);
+
if (ctx->Visual.rgbMode) {
- GLint r, g, b, a;
- r = (GLint) (ctx->Current.RasterColor[0] * CHAN_MAXF);
- g = (GLint) (ctx->Current.RasterColor[1] * CHAN_MAXF);
- b = (GLint) (ctx->Current.RasterColor[2] * CHAN_MAXF);
- a = (GLint) (ctx->Current.RasterColor[3] * CHAN_MAXF);
- PB_SET_COLOR( PB, r, g, b, a );
+ span.interpMask |= SPAN_RGBA;
+ span.red = FloatToFixed(ctx->Current.RasterColor[0] * CHAN_MAXF);
+ span.green = FloatToFixed(ctx->Current.RasterColor[1] * CHAN_MAXF);
+ span.blue = FloatToFixed(ctx->Current.RasterColor[2] * CHAN_MAXF);
+ span.alpha = FloatToFixed(ctx->Current.RasterColor[3] * CHAN_MAXF);
+ span.redStep = span.greenStep = span.blueStep = span.alphaStep = 0;
}
else {
- PB_SET_INDEX( PB, ctx->Current.RasterIndex );
+ span.interpMask |= SPAN_INDEX;
+ span.index = ChanToFixed(ctx->Current.RasterIndex);
+ span.indexStep = 0;
+ }
+
+ if (ctx->Depth.Test)
+ _mesa_span_default_z(ctx, &span);
+ if (ctx->Fog.Enabled)
+ _mesa_span_default_fog(ctx, &span);
+ if (ctx->Texture._EnabledUnits)
+ _mesa_span_default_texcoords(ctx, &span);
+
+ for (row = 0; row < height; row++, span.y++) {
+ const GLubyte *src = (const GLubyte *) _mesa_image_address( unpack,
+ bitmap, width, height, GL_COLOR_INDEX, GL_BITMAP, 0, row, 0 );
+
+ if (unpack->LsbFirst) {
+ /* Lsb first */
+ GLubyte mask = 1U << (unpack->SkipPixels & 0x7);
+ for (col = 0; col < width; col++) {
+ if (*src & mask) {
+ span.array->x[count] = px + col;
+ span.array->y[count] = py + row;
+ count++;
+ }
+ if (mask == 128U) {
+ src++;
+ mask = 1U;
+ }
+ else {
+ mask = mask << 1;
+ }
+ }
+
+ /* get ready for next row */
+ if (mask != 1)
+ src++;
+ }
+ else {
+ /* Msb first */
+ GLubyte mask = 128U >> (unpack->SkipPixels & 0x7);
+ for (col = 0; col < width; col++) {
+ if (*src & mask) {
+ span.array->x[count] = px + col;
+ span.array->y[count] = py + row;
+ count++;
+ }
+ if (mask == 1U) {
+ src++;
+ mask = 128U;
+ }
+ else {
+ mask = mask >> 1;
+ }
+ }
+
+ /* get ready for next row */
+ if (mask != 128)
+ src++;
+ }
+
+ if (count + width >= MAX_WIDTH || row + 1 == height) {
+ /* flush the span */
+ span.end = count;
+ if (ctx->Visual.rgbMode)
+ _mesa_write_rgba_span(ctx, &span);
+ else
+ _mesa_write_index_span(ctx, &span);
+ span.end = 0;
+ count = 0;
+ }
}
- fragZ = (GLdepth) ( ctx->Current.RasterPos[2] * ctx->DepthMaxF);
+ RENDER_FINISH(swrast,ctx);
+}
+
+
+#if 0
+/*
+ * XXX this is another way to implement Bitmap. Use horizontal runs of
+ * fragments, initializing the mask array to indicate which fragmens to
+ * draw or skip.
+ */
+void
+_swrast_Bitmap( GLcontext *ctx, GLint px, GLint py,
+ GLsizei width, GLsizei height,
+ const struct gl_pixelstore_attrib *unpack,
+ const GLubyte *bitmap )
+{
+ SWcontext *swrast = SWRAST_CONTEXT(ctx);
+ GLint row, col;
+ struct sw_span span;
+
+ ASSERT(ctx->RenderMode == GL_RENDER);
+ ASSERT(bitmap);
+
+ RENDER_START(swrast,ctx);
- if (ctx->Fog.Enabled) {
- if (ctx->Fog.FogCoordinateSource == GL_FOG_COORDINATE_EXT)
- fog = _mesa_z_to_fogfactor(ctx, ctx->Current.FogCoord);
- else
- fog = _mesa_z_to_fogfactor(ctx, ctx->Current.RasterDistance);
+ if (SWRAST_CONTEXT(ctx)->NewState)
+ _swrast_validate_derived( ctx );
+
+ INIT_SPAN(span, GL_BITMAP, width, 0, SPAN_MASK);
+
+ /*span.arrayMask |= SPAN_MASK;*/ /* we'll init span.mask[] */
+ span.x = px;
+ span.y = py;
+ /*span.end = width;*/
+ if (ctx->Visual.rgbMode) {
+ span.interpMask |= SPAN_RGBA;
+ span.red = FloatToFixed(ctx->Current.RasterColor[0] * CHAN_MAXF);
+ span.green = FloatToFixed(ctx->Current.RasterColor[1] * CHAN_MAXF);
+ span.blue = FloatToFixed(ctx->Current.RasterColor[2] * CHAN_MAXF);
+ span.alpha = FloatToFixed(ctx->Current.RasterColor[3] * CHAN_MAXF);
+ span.redStep = span.greenStep = span.blueStep = span.alphaStep = 0;
}
else {
- fog = 0.0;
+ span.interpMask |= SPAN_INDEX;
+ span.index = ChanToFixed(ctx->Current.RasterIndex);
+ span.indexStep = 0;
}
- for (row=0; row<height; row++) {
+ if (ctx->Depth.Test)
+ _mesa_span_default_z(ctx, &span);
+ if (ctx->Fog.Enabled)
+ _mesa_span_default_fog(ctx, &span);
+ if (ctx->Texture._EnabledUnits)
+ _mesa_span_default_texcoords(ctx, &span);
+
+ for (row=0; row<height; row++, span.y++) {
const GLubyte *src = (const GLubyte *) _mesa_image_address( unpack,
bitmap, width, height, GL_COLOR_INDEX, GL_BITMAP, 0, row, 0 );
@@ -92,9 +209,7 @@ _swrast_Bitmap( GLcontext *ctx, GLint px, GLint py,
/* Lsb first */
GLubyte mask = 1U << (unpack->SkipPixels & 0x7);
for (col=0; col<width; col++) {
- if (*src & mask) {
- PB_WRITE_PIXEL( PB, px+col, py+row, fragZ, fog );
- }
+ span.array->mask[col] = (*src & mask) ? GL_TRUE : GL_FALSE;
if (mask == 128U) {
src++;
mask = 1U;
@@ -104,7 +219,10 @@ _swrast_Bitmap( GLcontext *ctx, GLint px, GLint py,
}
}
- PB_CHECK_FLUSH( ctx, PB );
+ if (ctx->Visual.rgbMode)
+ _mesa_write_rgba_span(ctx, &span);
+ else
+ _mesa_write_index_span(ctx, &span);
/* get ready for next row */
if (mask != 1)
@@ -114,9 +232,7 @@ _swrast_Bitmap( GLcontext *ctx, GLint px, GLint py,
/* Msb first */
GLubyte mask = 128U >> (unpack->SkipPixels & 0x7);
for (col=0; col<width; col++) {
- if (*src & mask) {
- PB_WRITE_PIXEL( PB, px+col, py+row, fragZ, fog );
- }
+ span.array->mask[col] = (*src & mask) ? GL_TRUE : GL_FALSE;
if (mask == 1U) {
src++;
mask = 128U;
@@ -126,7 +242,10 @@ _swrast_Bitmap( GLcontext *ctx, GLint px, GLint py,
}
}
- PB_CHECK_FLUSH( ctx, PB );
+ if (ctx->Visual.rgbMode)
+ _mesa_write_rgba_span(ctx, &span);
+ else
+ _mesa_write_index_span(ctx, &span);
/* get ready for next row */
if (mask != 128)
@@ -134,7 +253,6 @@ _swrast_Bitmap( GLcontext *ctx, GLint px, GLint py,
}
}
- _mesa_flush_pb(ctx);
-
RENDER_FINISH(swrast,ctx);
}
+#endif
diff --git a/xc/extras/Mesa/src/swrast/s_blend.c b/xc/extras/Mesa/src/swrast/s_blend.c
index ad6764f16..acd454811 100644
--- a/xc/extras/Mesa/src/swrast/s_blend.c
+++ b/xc/extras/Mesa/src/swrast/s_blend.c
@@ -1,8 +1,7 @@
-/* $Id: s_blend.c,v 1.1.1.1 2002/10/22 13:06:41 alanh Exp $ */
/*
* Mesa 3-D graphics library
- * Version: 4.0.3
+ * Version: 4.1
*
* Copyright (C) 1999-2002 Brian Paul All Rights Reserved.
*
@@ -25,14 +24,15 @@
*/
+
#include "glheader.h"
#include "context.h"
+#include "colormac.h"
#include "macros.h"
#include "s_alphabuf.h"
#include "s_blend.h"
#include "s_context.h"
-#include "s_pb.h"
#include "s_span.h"
@@ -60,10 +60,7 @@ blend_noop( GLcontext *ctx, GLuint n, const GLubyte mask[],
for (i = 0; i < n; i++) {
if (mask[i]) {
- rgba[i][RCOMP] = dest[i][RCOMP];
- rgba[i][GCOMP] = dest[i][GCOMP];
- rgba[i][BCOMP] = dest[i][BCOMP];
- rgba[i][ACOMP] = dest[i][ACOMP];
+ COPY_CHAN4( rgba[i], dest[i] );
}
}
}
@@ -102,7 +99,7 @@ blend_transparency( GLcontext *ctx, GLuint n, const GLubyte mask[],
for (i=0;i<n;i++) {
if (mask[i]) {
- const GLint t = rgba[i][ACOMP]; /* t in [0, CHAN_MAX] */
+ const GLchan t = rgba[i][ACOMP]; /* t in [0, CHAN_MAX] */
if (t == 0) {
/* 0% alpha */
rgba[i][RCOMP] = dest[i][RCOMP];
@@ -132,27 +129,31 @@ blend_transparency( GLcontext *ctx, GLuint n, const GLubyte mask[],
#if CHAN_BITS == 8
/* This satisfies Glean and should be reasonably fast */
/* Contributed by Nathan Hand */
+#if 0
#define DIV255(X) (((X) << 8) + (X) + 256) >> 16
- const GLint s = CHAN_MAX - t;
- const GLint r = DIV255(rgba[i][RCOMP] * t + dest[i][RCOMP] * s);
- const GLint g = DIV255(rgba[i][GCOMP] * t + dest[i][GCOMP] * s);
- const GLint b = DIV255(rgba[i][BCOMP] * t + dest[i][BCOMP] * s);
- const GLint a = DIV255(rgba[i][ACOMP] * t + dest[i][ACOMP] * s);
+#else
+ GLint temp;
+#define DIV255(X) (temp = (X), ((temp << 8) + temp + 256) >> 16)
+#endif
+ const GLint r = DIV255((rgba[i][RCOMP] - dest[i][RCOMP]) * t) + dest[i][RCOMP];
+ const GLint g = DIV255((rgba[i][GCOMP] - dest[i][GCOMP]) * t) + dest[i][GCOMP];
+ const GLint b = DIV255((rgba[i][BCOMP] - dest[i][BCOMP]) * t) + dest[i][BCOMP];
+ const GLint a = DIV255((rgba[i][ACOMP] - dest[i][ACOMP]) * t) + dest[i][ACOMP];
+
#undef DIV255
#elif CHAN_BITS == 16
const GLfloat tt = (GLfloat) t / CHAN_MAXF;
- const GLfloat s = 1.0 - tt;
- const GLint r = (GLint) (rgba[i][RCOMP] * tt + dest[i][RCOMP] * s);
- const GLint g = (GLint) (rgba[i][GCOMP] * tt + dest[i][GCOMP] * s);
- const GLint b = (GLint) (rgba[i][BCOMP] * tt + dest[i][BCOMP] * s);
- const GLint a = (GLint) (rgba[i][ACOMP] * tt + dest[i][ACOMP] * s);
+ const GLint r = (GLint) ((rgba[i][RCOMP] - dest[i][RCOMP]) * tt + dest[i][RCOMP]);
+ const GLint g = (GLint) ((rgba[i][GCOMP] - dest[i][GCOMP]) * tt + dest[i][GCOMP]);
+ const GLint b = (GLint) ((rgba[i][BCOMP] - dest[i][BCOMP]) * tt + dest[i][BCOMP]);
+ const GLint a = (GLint) ((rgba[i][ACOMP] - dest[i][ACOMP]) * tt + dest[i][ACOMP]);
#else /* CHAN_BITS == 32 */
const GLfloat tt = (GLfloat) t / CHAN_MAXF;
- const GLfloat s = 1.0 - tt;
- const GLfloat r = rgba[i][RCOMP] * tt + dest[i][RCOMP] * s;
- const GLfloat g = rgba[i][GCOMP] * tt + dest[i][GCOMP] * s;
- const GLfloat b = rgba[i][BCOMP] * tt + dest[i][BCOMP] * s;
- const GLfloat a = rgba[i][ACOMP] * tt + dest[i][ACOMP] * s;
+ const GLfloat r = (rgba[i][RCOMP] - dest[i][RCOMP]) * tt + dest[i][RCOMP];
+ const GLfloat g = (rgba[i][GCOMP] - dest[i][GCOMP]) * tt + dest[i][GCOMP];
+ const GLfloat b = (rgba[i][BCOMP] - dest[i][BCOMP]) * tt + dest[i][BCOMP];
+ const GLfloat a = CLAMP( rgba[i][ACOMP], 0.0F, CHAN_MAXF ) * t +
+ CLAMP( dest[i][ACOMP], 0.0F, CHAN_MAXF ) * (1.0F - t);
#endif
#endif
ASSERT(r <= CHAN_MAX);
@@ -186,20 +187,22 @@ blend_add( GLcontext *ctx, GLuint n, const GLubyte mask[],
for (i=0;i<n;i++) {
if (mask[i]) {
#if CHAN_TYPE == GL_FLOAT
- GLfloat r = rgba[i][RCOMP] + dest[i][RCOMP];
- GLfloat g = rgba[i][GCOMP] + dest[i][GCOMP];
- GLfloat b = rgba[i][BCOMP] + dest[i][BCOMP];
- GLfloat a = rgba[i][ACOMP] + dest[i][ACOMP];
+ /* don't RGB clamp to max */
+ GLfloat a = CLAMP(rgba[i][ACOMP], 0.0F, CHAN_MAXF) + dest[i][ACOMP];
+ rgba[i][RCOMP] += dest[i][RCOMP];
+ rgba[i][GCOMP] += dest[i][GCOMP];
+ rgba[i][BCOMP] += dest[i][BCOMP];
+ rgba[i][ACOMP] = (GLchan) MIN2( a, CHAN_MAXF );
#else
GLint r = rgba[i][RCOMP] + dest[i][RCOMP];
GLint g = rgba[i][GCOMP] + dest[i][GCOMP];
GLint b = rgba[i][BCOMP] + dest[i][BCOMP];
GLint a = rgba[i][ACOMP] + dest[i][ACOMP];
-#endif
rgba[i][RCOMP] = (GLchan) MIN2( r, CHAN_MAX );
rgba[i][GCOMP] = (GLchan) MIN2( g, CHAN_MAX );
rgba[i][BCOMP] = (GLchan) MIN2( b, CHAN_MAX );
rgba[i][ACOMP] = (GLchan) MIN2( a, CHAN_MAX );
+#endif
}
}
}
@@ -222,7 +225,12 @@ blend_min( GLcontext *ctx, GLuint n, const GLubyte mask[],
rgba[i][RCOMP] = (GLchan) MIN2( rgba[i][RCOMP], dest[i][RCOMP] );
rgba[i][GCOMP] = (GLchan) MIN2( rgba[i][GCOMP], dest[i][GCOMP] );
rgba[i][BCOMP] = (GLchan) MIN2( rgba[i][BCOMP], dest[i][BCOMP] );
+#if CHAN_TYPE == GL_FLOAT
+ rgba[i][ACOMP] = (GLchan) MIN2(CLAMP(rgba[i][ACOMP], 0.0F, CHAN_MAXF),
+ dest[i][ACOMP]);
+#else
rgba[i][ACOMP] = (GLchan) MIN2( rgba[i][ACOMP], dest[i][ACOMP] );
+#endif
}
}
}
@@ -245,7 +253,12 @@ blend_max( GLcontext *ctx, GLuint n, const GLubyte mask[],
rgba[i][RCOMP] = (GLchan) MAX2( rgba[i][RCOMP], dest[i][RCOMP] );
rgba[i][GCOMP] = (GLchan) MAX2( rgba[i][GCOMP], dest[i][GCOMP] );
rgba[i][BCOMP] = (GLchan) MAX2( rgba[i][BCOMP], dest[i][BCOMP] );
+#if CHAN_TYPE == GL_FLOAT
+ rgba[i][ACOMP] = (GLchan) MAX2(CLAMP(rgba[i][ACOMP], 0.0F, CHAN_MAXF),
+ dest[i][ACOMP]);
+#else
rgba[i][ACOMP] = (GLchan) MAX2( rgba[i][ACOMP], dest[i][ACOMP] );
+#endif
}
}
}
@@ -269,11 +282,20 @@ blend_modulate( GLcontext *ctx, GLuint n, const GLubyte mask[],
rgba[i][GCOMP] = rgba[i][GCOMP] * dest[i][GCOMP];
rgba[i][BCOMP] = rgba[i][BCOMP] * dest[i][BCOMP];
rgba[i][ACOMP] = rgba[i][ACOMP] * dest[i][ACOMP];
+#elif CHAN_TYPE == GL_UNSIGNED_SHORT
+ GLint r = (rgba[i][RCOMP] * dest[i][RCOMP] + 65535) >> 16;
+ GLint g = (rgba[i][GCOMP] * dest[i][GCOMP] + 65535) >> 16;
+ GLint b = (rgba[i][BCOMP] * dest[i][BCOMP] + 65535) >> 16;
+ GLint a = (rgba[i][ACOMP] * dest[i][ACOMP] + 65535) >> 16;
+ rgba[i][RCOMP] = (GLchan) r;
+ rgba[i][GCOMP] = (GLchan) g;
+ rgba[i][BCOMP] = (GLchan) b;
+ rgba[i][ACOMP] = (GLchan) a;
#else
- GLint r = (rgba[i][RCOMP] * dest[i][RCOMP]) >> 8;
- GLint g = (rgba[i][GCOMP] * dest[i][GCOMP]) >> 8;
- GLint b = (rgba[i][BCOMP] * dest[i][BCOMP]) >> 8;
- GLint a = (rgba[i][ACOMP] * dest[i][ACOMP]) >> 8;
+ GLint r = (rgba[i][RCOMP] * dest[i][RCOMP] + 255) >> 8;
+ GLint g = (rgba[i][GCOMP] * dest[i][GCOMP] + 255) >> 8;
+ GLint b = (rgba[i][BCOMP] * dest[i][BCOMP] + 255) >> 8;
+ GLint a = (rgba[i][ACOMP] * dest[i][ACOMP] + 255) >> 8;
rgba[i][RCOMP] = (GLchan) r;
rgba[i][GCOMP] = (GLchan) g;
rgba[i][BCOMP] = (GLchan) b;
@@ -296,10 +318,10 @@ static void _BLENDAPI
blend_general( GLcontext *ctx, GLuint n, const GLubyte mask[],
GLchan rgba[][4], CONST GLchan dest[][4] )
{
- GLfloat rscale = 1.0F / CHAN_MAXF;
- GLfloat gscale = 1.0F / CHAN_MAXF;
- GLfloat bscale = 1.0F / CHAN_MAXF;
- GLfloat ascale = 1.0F / CHAN_MAXF;
+ const GLfloat rscale = 1.0F / CHAN_MAXF;
+ const GLfloat gscale = 1.0F / CHAN_MAXF;
+ const GLfloat bscale = 1.0F / CHAN_MAXF;
+ const GLfloat ascale = 1.0F / CHAN_MAXF;
GLuint i;
for (i=0;i<n;i++) {
@@ -313,19 +335,33 @@ blend_general( GLcontext *ctx, GLuint n, const GLubyte mask[],
#endif
GLfloat sR, sG, sB, sA; /* Source scaling */
GLfloat dR, dG, dB, dA; /* Dest scaling */
- GLfloat r, g, b, a;
+ GLfloat r, g, b, a; /* result color */
- /* Source Color */
+ /* Incoming/source Color */
Rs = rgba[i][RCOMP];
Gs = rgba[i][GCOMP];
Bs = rgba[i][BCOMP];
As = rgba[i][ACOMP];
+#if CHAN_TYPE == GL_FLOAT
+ /* clamp */
+ Rs = MIN2(Rs, CHAN_MAXF);
+ Gs = MIN2(Gs, CHAN_MAXF);
+ Bs = MIN2(Bs, CHAN_MAXF);
+ As = MIN2(As, CHAN_MAXF);
+#endif
- /* Frame buffer color */
+ /* Frame buffer/dest color */
Rd = dest[i][RCOMP];
Gd = dest[i][GCOMP];
Bd = dest[i][BCOMP];
Ad = dest[i][ACOMP];
+#if CHAN_TYPE == GL_FLOAT
+ /* clamp */
+ Rd = MIN2(Rd, CHAN_MAXF);
+ Gd = MIN2(Gd, CHAN_MAXF);
+ Bd = MIN2(Bd, CHAN_MAXF);
+ Ad = MIN2(Ad, CHAN_MAXF);
+#endif
/* Source RGB factor */
switch (ctx->Color.BlendSrcRGB) {
@@ -349,7 +385,7 @@ blend_general( GLcontext *ctx, GLuint n, const GLubyte mask[],
sR = sG = sB = (GLfloat) As * ascale;
break;
case GL_ONE_MINUS_SRC_ALPHA:
- sR = sG = sB = (GLfloat) 1.0F - (GLfloat) As * ascale;
+ sR = sG = sB = 1.0F - (GLfloat) As * ascale;
break;
case GL_DST_ALPHA:
sR = sG = sB = (GLfloat) Ad * ascale;
@@ -415,7 +451,7 @@ blend_general( GLcontext *ctx, GLuint n, const GLubyte mask[],
sA = (GLfloat) As * ascale;
break;
case GL_ONE_MINUS_SRC_ALPHA:
- sA = (GLfloat) 1.0F - (GLfloat) As * ascale;
+ sA = 1.0F - (GLfloat) As * ascale;
break;
case GL_DST_ALPHA:
sA =(GLfloat) Ad * ascale;
@@ -472,7 +508,7 @@ blend_general( GLcontext *ctx, GLuint n, const GLubyte mask[],
dR = dG = dB = (GLfloat) As * ascale;
break;
case GL_ONE_MINUS_SRC_ALPHA:
- dR = dG = dB = (GLfloat) 1.0F - (GLfloat) As * ascale;
+ dR = dG = dB = 1.0F - (GLfloat) As * ascale;
break;
case GL_DST_ALPHA:
dR = dG = dB = (GLfloat) Ad * ascale;
@@ -530,7 +566,7 @@ blend_general( GLcontext *ctx, GLuint n, const GLubyte mask[],
dA = (GLfloat) As * ascale;
break;
case GL_ONE_MINUS_SRC_ALPHA:
- dA = (GLfloat) 1.0F - (GLfloat) As * ascale;
+ dA = 1.0F - (GLfloat) As * ascale;
break;
case GL_DST_ALPHA:
dA = (GLfloat) Ad * ascale;
@@ -560,7 +596,7 @@ blend_general( GLcontext *ctx, GLuint n, const GLubyte mask[],
/* this should never happen */
dA = 0.0F;
_mesa_problem(ctx, "Bad blend dest A factor in do_blend");
- return;
+ return;
}
/* Due to round-off problems we have to clamp against zero. */
@@ -610,9 +646,9 @@ blend_general( GLcontext *ctx, GLuint n, const GLubyte mask[],
}
/* final clamping */
- rgba[i][RCOMP] = CLAMP( r, 0.0F, CHAN_MAXF );
- rgba[i][GCOMP] = CLAMP( g, 0.0F, CHAN_MAXF );
- rgba[i][BCOMP] = CLAMP( b, 0.0F, CHAN_MAXF );
+ rgba[i][RCOMP] = MAX2( r, 0.0F );
+ rgba[i][GCOMP] = MAX2( g, 0.0F );
+ rgba[i][BCOMP] = MAX2( b, 0.0F );
rgba[i][ACOMP] = CLAMP( a, 0.0F, CHAN_MAXF );
#else
if (ctx->Color.BlendEquation==GL_FUNC_ADD_EXT) {
@@ -669,30 +705,54 @@ void _swrast_choose_blend_func( GLcontext *ctx )
SWRAST_CONTEXT(ctx)->BlendFunc = blend_general;
}
else if (eq==GL_FUNC_ADD_EXT && srcRGB==GL_SRC_ALPHA
- && dstRGB==GL_ONE_MINUS_SRC_ALPHA) {
+ && dstRGB==GL_ONE_MINUS_SRC_ALPHA) {
#if defined(USE_MMX_ASM)
if ( cpu_has_mmx ) {
- SWRAST_CONTEXT(ctx)->BlendFunc = _mesa_mmx_blend_transparency;
+ SWRAST_CONTEXT(ctx)->BlendFunc = _mesa_mmx_blend_transparency;
}
else
#endif
SWRAST_CONTEXT(ctx)->BlendFunc = blend_transparency;
}
else if (eq==GL_FUNC_ADD_EXT && srcRGB==GL_ONE && dstRGB==GL_ONE) {
- SWRAST_CONTEXT(ctx)->BlendFunc = blend_add;
+#if defined(USE_MMX_ASM)
+ if ( cpu_has_mmx ) {
+ SWRAST_CONTEXT(ctx)->BlendFunc = _mesa_mmx_blend_add;
+ }
+ else
+#endif
+ SWRAST_CONTEXT(ctx)->BlendFunc = blend_add;
}
else if (((eq==GL_FUNC_ADD_EXT || eq==GL_FUNC_REVERSE_SUBTRACT_EXT)
&& (srcRGB==GL_ZERO && dstRGB==GL_SRC_COLOR))
||
((eq==GL_FUNC_ADD_EXT || eq==GL_FUNC_SUBTRACT_EXT)
&& (srcRGB==GL_DST_COLOR && dstRGB==GL_ZERO))) {
- SWRAST_CONTEXT(ctx)->BlendFunc = blend_modulate;
+#if defined(USE_MMX_ASM)
+ if ( cpu_has_mmx ) {
+ SWRAST_CONTEXT(ctx)->BlendFunc = _mesa_mmx_blend_modulate;
+ }
+ else
+#endif
+ SWRAST_CONTEXT(ctx)->BlendFunc = blend_modulate;
}
else if (eq==GL_MIN_EXT) {
- SWRAST_CONTEXT(ctx)->BlendFunc = blend_min;
+#if defined(USE_MMX_ASM)
+ if ( cpu_has_mmx ) {
+ SWRAST_CONTEXT(ctx)->BlendFunc = _mesa_mmx_blend_min;
+ }
+ else
+#endif
+ SWRAST_CONTEXT(ctx)->BlendFunc = blend_min;
}
else if (eq==GL_MAX_EXT) {
- SWRAST_CONTEXT(ctx)->BlendFunc = blend_max;
+#if defined(USE_MMX_ASM)
+ if ( cpu_has_mmx ) {
+ SWRAST_CONTEXT(ctx)->BlendFunc = _mesa_mmx_blend_max;
+ }
+ else
+#endif
+ SWRAST_CONTEXT(ctx)->BlendFunc = blend_max;
}
else if (eq==GL_FUNC_ADD_EXT && srcRGB == GL_ZERO && dstRGB == GL_ONE) {
SWRAST_CONTEXT(ctx)->BlendFunc = blend_noop;
@@ -709,58 +769,38 @@ void _swrast_choose_blend_func( GLcontext *ctx )
/*
* Apply the blending operator to a span of pixels.
- * Input: n - number of pixels in span
- * x, y - location of leftmost pixel in span in window coords.
- * mask - boolean mask indicating which pixels to blend.
- * In/Out: rgba - pixel values
+ * We can handle horizontal runs of pixels (spans) or arrays of x/y
+ * pixel coordinates.
*/
void
-_mesa_blend_span( GLcontext *ctx, GLuint n, GLint x, GLint y,
- GLchan rgba[][4], const GLubyte mask[] )
+_mesa_blend_span( GLcontext *ctx, const struct sw_span *span,
+ GLchan rgba[][4] )
{
- GLchan dest[MAX_WIDTH][4];
+ SWcontext *swrast = SWRAST_CONTEXT(ctx);
+ GLchan framebuffer[MAX_WIDTH][4];
- /* Check if device driver can do the work */
- if (ctx->Color.BlendEquation==GL_LOGIC_OP &&
- !ctx->Color.ColorLogicOpEnabled) {
- return;
- }
+ ASSERT(span->end <= MAX_WIDTH);
+ ASSERT(span->arrayMask & SPAN_RGBA);
+ ASSERT(!ctx->Color.ColorLogicOpEnabled);
/* Read span of current frame buffer pixels */
- _mesa_read_rgba_span( ctx, ctx->DrawBuffer, n, x, y, dest );
-
- SWRAST_CONTEXT(ctx)->BlendFunc( ctx, n, mask, rgba,
- (const GLchan (*)[4]) dest );
-}
-
-
-
-/*
- * Apply the blending operator to an array of pixels.
- * Input: n - number of pixels in span
- * x, y - array of pixel locations
- * mask - boolean mask indicating which pixels to blend.
- * In/Out: rgba - pixel values
- */
-void
-_mesa_blend_pixels( GLcontext *ctx,
- GLuint n, const GLint x[], const GLint y[],
- GLchan rgba[][4], const GLubyte mask[] )
-{
- SWcontext *swrast = SWRAST_CONTEXT(ctx);
- GLchan dest[PB_SIZE][4];
-
- /* Check if device driver can do the work */
- if (ctx->Color.BlendEquation==GL_LOGIC_OP &&
- !ctx->Color.ColorLogicOpEnabled) {
- return;
+ if (span->arrayMask & SPAN_XY) {
+ /* array of x/y pixel coords */
+ (*swrast->Driver.ReadRGBAPixels)( ctx, span->end,
+ span->array->x, span->array->y,
+ framebuffer, span->array->mask );
+ if (swrast->_RasterMask & ALPHABUF_BIT) {
+ _mesa_read_alpha_pixels( ctx, span->end,
+ span->array->x, span->array->y,
+ framebuffer, span->array->mask );
+ }
}
-
- /* Read pixels from current color buffer */
- (*swrast->Driver.ReadRGBAPixels)( ctx, n, x, y, dest, mask );
- if (swrast->_RasterMask & ALPHABUF_BIT) {
- _mesa_read_alpha_pixels( ctx, n, x, y, dest, mask );
+ else {
+ /* horizontal run of pixels */
+ _mesa_read_rgba_span( ctx, ctx->DrawBuffer, span->end,
+ span->x, span->y, framebuffer );
}
- swrast->BlendFunc( ctx, n, mask, rgba, (const GLchan (*)[4])dest );
+ SWRAST_CONTEXT(ctx)->BlendFunc( ctx, span->end, span->array->mask, rgba,
+ (const GLchan (*)[4]) framebuffer );
}
diff --git a/xc/extras/Mesa/src/swrast/s_blend.h b/xc/extras/Mesa/src/swrast/s_blend.h
index 1882b18e2..c9357748d 100644
--- a/xc/extras/Mesa/src/swrast/s_blend.h
+++ b/xc/extras/Mesa/src/swrast/s_blend.h
@@ -1,10 +1,9 @@
-/* $Id: s_blend.h,v 1.1.1.1 2002/10/22 13:06:41 alanh Exp $ */
/*
* Mesa 3-D graphics library
- * Version: 3.5
+ * Version: 4.1
*
- * Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
+ * Copyright (C) 1999-2002 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"),
@@ -35,16 +34,11 @@
extern void
-_mesa_blend_span( GLcontext *ctx, GLuint n, GLint x, GLint y,
- GLchan rgba[][4], const GLubyte mask[] );
+_mesa_blend_span( GLcontext *ctx, const struct sw_span *span,
+ GLchan rgba[][4] );
extern void
-_mesa_blend_pixels( GLcontext *ctx,
- GLuint n, const GLint x[], const GLint y[],
- GLchan rgba[][4], const GLubyte mask[] );
-
-extern void
_swrast_choose_blend_func( GLcontext *ctx );
diff --git a/xc/extras/Mesa/src/swrast/s_buffers.c b/xc/extras/Mesa/src/swrast/s_buffers.c
index 59524ba09..18d11891c 100644
--- a/xc/extras/Mesa/src/swrast/s_buffers.c
+++ b/xc/extras/Mesa/src/swrast/s_buffers.c
@@ -1,10 +1,9 @@
-/* $Id: s_buffers.c,v 1.1.1.1 2002/10/22 13:06:40 alanh Exp $ */
/*
* Mesa 3-D graphics library
- * Version: 3.5
+ * Version: 4.1
*
- * Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
+ * Copyright (C) 1999-2002 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"),
@@ -26,8 +25,9 @@
#include "glheader.h"
+#include "colormac.h"
#include "macros.h"
-#include "mem.h"
+#include "imports.h"
#include "s_accum.h"
#include "s_alphabuf.h"
@@ -53,21 +53,19 @@ clear_color_buffer_with_masking( GLcontext *ctx )
if (ctx->Visual.rgbMode) {
/* RGBA mode */
- const GLchan r = ctx->Color.ClearColor[0];
- const GLchan g = ctx->Color.ClearColor[1];
- const GLchan b = ctx->Color.ClearColor[2];
- const GLchan a = ctx->Color.ClearColor[3];
+ GLchan clearColor[4];
GLint i;
+ CLAMPED_FLOAT_TO_CHAN(clearColor[RCOMP], ctx->Color.ClearColor[0]);
+ CLAMPED_FLOAT_TO_CHAN(clearColor[GCOMP], ctx->Color.ClearColor[1]);
+ CLAMPED_FLOAT_TO_CHAN(clearColor[BCOMP], ctx->Color.ClearColor[2]);
+ CLAMPED_FLOAT_TO_CHAN(clearColor[ACOMP], ctx->Color.ClearColor[3]);
for (i = 0; i < height; i++) {
GLchan rgba[MAX_WIDTH][4];
GLint j;
for (j = 0; j < width; j++) {
- rgba[j][RCOMP] = r;
- rgba[j][GCOMP] = g;
- rgba[j][BCOMP] = b;
- rgba[j][ACOMP] = a;
+ COPY_CHAN4(rgba[j], clearColor);
}
- _mesa_mask_rgba_span( ctx, width, x, y + i, rgba );
+ _mesa_mask_rgba_array( ctx, width, x, y + i, rgba );
(*swrast->Driver.WriteRGBASpan)( ctx, width, x, y + i,
(CONST GLchan (*)[4]) rgba, NULL );
}
@@ -82,7 +80,7 @@ clear_color_buffer_with_masking( GLcontext *ctx )
for (j=0;j<width;j++) {
span[j] = ctx->Color.ClearIndex;
}
- _mesa_mask_index_span( ctx, width, x, y + i, span );
+ _mesa_mask_index_array( ctx, width, x, y + i, span );
(*swrast->Driver.WriteCI32Span)( ctx, width, x, y + i, span, mask );
}
}
@@ -104,20 +102,19 @@ clear_color_buffer(GLcontext *ctx)
if (ctx->Visual.rgbMode) {
/* RGBA mode */
- const GLchan r = ctx->Color.ClearColor[0];
- const GLchan g = ctx->Color.ClearColor[1];
- const GLchan b = ctx->Color.ClearColor[2];
- const GLchan a = ctx->Color.ClearColor[3];
+ GLchan clearColor[4];
GLchan span[MAX_WIDTH][4];
GLint i;
+ CLAMPED_FLOAT_TO_CHAN(clearColor[RCOMP], ctx->Color.ClearColor[0]);
+ CLAMPED_FLOAT_TO_CHAN(clearColor[GCOMP], ctx->Color.ClearColor[1]);
+ CLAMPED_FLOAT_TO_CHAN(clearColor[BCOMP], ctx->Color.ClearColor[2]);
+ CLAMPED_FLOAT_TO_CHAN(clearColor[ACOMP], ctx->Color.ClearColor[3]);
+
ASSERT(*((GLuint *) &ctx->Color.ColorMask) == 0xffffffff);
for (i = 0; i < width; i++) {
- span[i][RCOMP] = r;
- span[i][GCOMP] = g;
- span[i][BCOMP] = b;
- span[i][ACOMP] = a;
+ COPY_CHAN4(span[i], clearColor);
}
for (i = 0; i < height; i++) {
(*swrast->Driver.WriteRGBASpan)( ctx, width, x, y + i,
@@ -167,23 +164,8 @@ clear_color_buffers(GLcontext *ctx)
/* loop over four possible dest color buffers */
for (bufferBit = 1; bufferBit <= 8; bufferBit = bufferBit << 1) {
- if (bufferBit & ctx->Color.DrawDestMask) {
- if (bufferBit == FRONT_LEFT_BIT) {
- (void) (*ctx->Driver.SetDrawBuffer)( ctx, GL_FRONT_LEFT);
- (void) (*swrast->Driver.SetReadBuffer)( ctx, ctx->DrawBuffer, GL_FRONT_LEFT);
- }
- else if (bufferBit == FRONT_RIGHT_BIT) {
- (void) (*ctx->Driver.SetDrawBuffer)( ctx, GL_FRONT_RIGHT);
- (void) (*swrast->Driver.SetReadBuffer)( ctx, ctx->DrawBuffer, GL_FRONT_RIGHT);
- }
- else if (bufferBit == BACK_LEFT_BIT) {
- (void) (*ctx->Driver.SetDrawBuffer)( ctx, GL_BACK_LEFT);
- (void) (*swrast->Driver.SetReadBuffer)( ctx, ctx->DrawBuffer, GL_BACK_LEFT);
- }
- else {
- (void) (*ctx->Driver.SetDrawBuffer)( ctx, GL_BACK_RIGHT);
- (void) (*swrast->Driver.SetReadBuffer)( ctx, ctx->DrawBuffer, GL_BACK_RIGHT);
- }
+ if (bufferBit & ctx->Color._DrawDestMask) {
+ (*swrast->Driver.SetBuffer)(ctx, ctx->DrawBuffer, bufferBit);
if (colorMask != 0xffffffff) {
clear_color_buffer_with_masking(ctx);
@@ -194,9 +176,8 @@ clear_color_buffers(GLcontext *ctx)
}
}
- /* restore default read/draw buffers */
- (void) (*ctx->Driver.SetDrawBuffer)( ctx, ctx->Color.DriverDrawBuffer );
- (void) (*swrast->Driver.SetReadBuffer)( ctx, ctx->ReadBuffer, ctx->Pixel.DriverReadBuffer );
+ /* restore default read/draw buffer */
+ _swrast_use_draw_buffer(ctx);
}
@@ -224,7 +205,7 @@ _swrast_Clear( GLcontext *ctx, GLbitfield mask,
/* do software clearing here */
if (mask) {
- if (mask & ctx->Color.DrawDestMask) clear_color_buffers(ctx);
+ if (mask & ctx->Color._DrawDestMask) clear_color_buffers(ctx);
if (mask & GL_DEPTH_BUFFER_BIT) _mesa_clear_depth_buffer(ctx);
if (mask & GL_ACCUM_BUFFER_BIT) _mesa_clear_accum_buffer(ctx);
if (mask & GL_STENCIL_BUFFER_BIT) _mesa_clear_stencil_buffer(ctx);
@@ -258,3 +239,66 @@ _swrast_alloc_buffers( GLframebuffer *buffer )
_mesa_alloc_alpha_buffers( buffer );
}
}
+
+
+/*
+ * Fallback for ctx->Driver.DrawBuffer()
+ */
+void
+_swrast_DrawBuffer( GLcontext *ctx, GLenum mode )
+{
+ _swrast_use_draw_buffer(ctx);
+}
+
+
+/*
+ * Setup things so that we read/write spans from the user-designated
+ * read buffer (set via glReadPixels). We usually just have to call
+ * this for glReadPixels, glCopyPixels, etc.
+ */
+void
+_swrast_use_read_buffer( GLcontext *ctx )
+{
+ SWcontext *swrast = SWRAST_CONTEXT(ctx);
+
+ /* Do this so the software-emulated alpha plane span functions work! */
+ swrast->CurrentBuffer = ctx->Pixel._ReadSrcMask;
+ /* Tell the device driver where to read/write spans */
+ (*swrast->Driver.SetBuffer)( ctx, ctx->ReadBuffer, swrast->CurrentBuffer );
+}
+
+
+/*
+ * Setup things so that we read/write spans from the default draw buffer.
+ * This is the usual mode that Mesa's software rasterizer operates in.
+ */
+void
+_swrast_use_draw_buffer( GLcontext *ctx )
+{
+ SWcontext *swrast = SWRAST_CONTEXT(ctx);
+
+ /* The user can specify rendering to zero, one, two, or four color
+ * buffers simultaneously with glDrawBuffer()!
+ * We don't expect the span/point/line/triangle functions to deal with
+ * that mess so we'll iterate over the multiple buffers as needed.
+ * But usually we only render to one color buffer at a time.
+ * We set ctx->Color._DriverDrawBuffer to that buffer and tell the
+ * device driver to use that buffer.
+ * Look in s_span.c's multi_write_rgba_span() function to see how
+ * we loop over multiple color buffers when needed.
+ */
+
+ if (ctx->Color._DrawDestMask & FRONT_LEFT_BIT)
+ swrast->CurrentBuffer = FRONT_LEFT_BIT;
+ else if (ctx->Color._DrawDestMask & BACK_LEFT_BIT)
+ swrast->CurrentBuffer = BACK_LEFT_BIT;
+ else if (ctx->Color._DrawDestMask & FRONT_RIGHT_BIT)
+ swrast->CurrentBuffer = FRONT_RIGHT_BIT;
+ else if (ctx->Color._DrawDestMask & BACK_RIGHT_BIT)
+ swrast->CurrentBuffer = BACK_RIGHT_BIT;
+ else
+ /* glDrawBuffer(GL_NONE) */
+ swrast->CurrentBuffer = FRONT_LEFT_BIT; /* we always have this buffer */
+
+ (*swrast->Driver.SetBuffer)( ctx, ctx->DrawBuffer, swrast->CurrentBuffer );
+}
diff --git a/xc/extras/Mesa/src/swrast/s_context.c b/xc/extras/Mesa/src/swrast/s_context.c
index 042797d08..16acc154a 100644
--- a/xc/extras/Mesa/src/swrast/s_context.c
+++ b/xc/extras/Mesa/src/swrast/s_context.c
@@ -1,8 +1,7 @@
-/* $Id: s_context.c,v 1.1.1.1 2002/10/22 13:06:44 alanh Exp $ */
/*
* Mesa 3-D graphics library
- * Version: 4.0.3
+ * Version: 4.1
*
* Copyright (C) 1999-2002 Brian Paul All Rights Reserved.
*
@@ -24,25 +23,24 @@
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* Authors:
- * Keith Whitwell <keithw@valinux.com>
+ * Keith Whitwell <keith@tungstengraphics.com>
*/
#include "glheader.h"
+#include "context.h"
#include "mtypes.h"
-#include "mem.h"
+#include "imports.h"
-#include "s_pb.h"
-#include "s_points.h"
-#include "s_lines.h"
-#include "s_triangle.h"
+#include "swrast.h"
#include "s_blend.h"
#include "s_context.h"
+#include "s_lines.h"
+#include "s_points.h"
+#include "s_span.h"
+#include "s_triangle.h"
#include "s_texture.h"
-
-
-
/*
* Recompute the value of swrast->_RasterMask, etc. according to
* the current context.
@@ -56,13 +54,13 @@ _swrast_update_rasterflags( GLcontext *ctx )
if (ctx->Color.BlendEnabled) RasterMask |= BLEND_BIT;
if (ctx->Depth.Test) RasterMask |= DEPTH_BIT;
if (ctx->Fog.Enabled) RasterMask |= FOG_BIT;
- if (ctx->Scissor.Enabled) RasterMask |= SCISSOR_BIT;
+ if (ctx->Scissor.Enabled) RasterMask |= CLIP_BIT;
if (ctx->Stencil.Enabled) RasterMask |= STENCIL_BIT;
if (ctx->Visual.rgbMode) {
const GLuint colorMask = *((GLuint *) &ctx->Color.ColorMask);
if (colorMask != 0xffffffff) RasterMask |= MASKING_BIT;
if (ctx->Color.ColorLogicOpEnabled) RasterMask |= LOGIC_OP_BIT;
- if (ctx->Texture._ReallyEnabled) RasterMask |= TEXTURE_BIT;
+ if (ctx->Texture._EnabledUnits) RasterMask |= TEXTURE_BIT;
}
else {
if (ctx->Color.IndexMask != 0xffffffff) RasterMask |= MASKING_BIT;
@@ -78,7 +76,7 @@ _swrast_update_rasterflags( GLcontext *ctx )
|| ctx->Viewport.X + ctx->Viewport.Width > (GLint) ctx->DrawBuffer->Width
|| ctx->Viewport.Y < 0
|| ctx->Viewport.Y + ctx->Viewport.Height > (GLint) ctx->DrawBuffer->Height) {
- RasterMask |= WINCLIP_BIT;
+ RasterMask |= CLIP_BIT;
}
if (ctx->Depth.OcclusionTest)
@@ -89,8 +87,11 @@ _swrast_update_rasterflags( GLcontext *ctx )
* MULTI_DRAW_BIT flag. Also set it if we're drawing to no
* buffers or the RGBA or CI mask disables all writes.
*/
- if (ctx->Color.DrawBuffer == GL_FRONT_AND_BACK ||
- ctx->Color.DrawBuffer == GL_NONE) {
+ if (ctx->Color._DrawDestMask != FRONT_LEFT_BIT &&
+ ctx->Color._DrawDestMask != BACK_LEFT_BIT &&
+ ctx->Color._DrawDestMask != FRONT_RIGHT_BIT &&
+ ctx->Color._DrawDestMask != BACK_RIGHT_BIT) {
+ /* more than one color buffer designated for writing (or zero buffers) */
RasterMask |= MULTI_DRAW_BIT;
}
else if (ctx->Visual.rgbMode && *((GLuint *) ctx->Color.ColorMask) == 0) {
@@ -143,6 +144,26 @@ _swrast_update_hint( GLcontext *ctx )
swrast->AllowPixelFog));
}
+
+/*
+ * Update the swrast->_AnyTextureCombine flag.
+ */
+static void
+_swrast_update_texture_env( GLcontext *ctx )
+{
+ SWcontext *swrast = SWRAST_CONTEXT(ctx);
+ GLuint i;
+ swrast->_AnyTextureCombine = GL_FALSE;
+ for (i = 0; i < ctx->Const.MaxTextureUnits; i++) {
+ if (ctx->Texture.Unit[i].EnvMode == GL_COMBINE_EXT ||
+ ctx->Texture.Unit[i].EnvMode == GL_COMBINE4_NV) {
+ swrast->_AnyTextureCombine = GL_TRUE;
+ return;
+ }
+ }
+}
+
+
#define _SWRAST_NEW_DERIVED (_SWRAST_NEW_RASTERMASK | \
_NEW_TEXTURE | \
_NEW_HINT | \
@@ -181,6 +202,8 @@ _swrast_update_hint( GLcontext *ctx )
#define _SWRAST_NEW_TEXTURE_SAMPLE_FUNC _NEW_TEXTURE
+#define _SWRAST_NEW_TEXTURE_ENV_MODE _NEW_TEXTURE
+
#define _SWRAST_NEW_BLEND_FUNC _NEW_COLOR
@@ -200,7 +223,7 @@ _swrast_validate_triangle( GLcontext *ctx,
swrast->choose_triangle( ctx );
if ((ctx->_TriangleCaps & DD_SEPARATE_SPECULAR) &&
- !ctx->Texture._ReallyEnabled) {
+ ctx->Texture._EnabledUnits == 0) {
swrast->SpecTriangle = swrast->Triangle;
swrast->Triangle = _swrast_add_spec_terms_triangle;
}
@@ -217,7 +240,7 @@ _swrast_validate_line( GLcontext *ctx, const SWvertex *v0, const SWvertex *v1 )
swrast->choose_line( ctx );
if ((ctx->_TriangleCaps & DD_SEPARATE_SPECULAR) &&
- !ctx->Texture._ReallyEnabled) {
+ ctx->Texture._EnabledUnits == 0) {
swrast->SpecLine = swrast->Line;
swrast->Line = _swrast_add_spec_terms_line;
}
@@ -235,7 +258,7 @@ _swrast_validate_point( GLcontext *ctx, const SWvertex *v0 )
swrast->choose_point( ctx );
if ((ctx->_TriangleCaps & DD_SEPARATE_SPECULAR) &&
- !ctx->Texture._ReallyEnabled) {
+ ctx->Texture._EnabledUnits == 0) {
swrast->SpecPoint = swrast->Point;
swrast->Point = _swrast_add_spec_terms_point;
}
@@ -261,17 +284,15 @@ _swrast_validate_blend_func( GLcontext *ctx, GLuint n,
static void
_swrast_validate_texture_sample( GLcontext *ctx, GLuint texUnit,
const struct gl_texture_object *tObj,
- GLuint n,
- const GLfloat s[], const GLfloat t[],
- const GLfloat u[], const GLfloat lambda[],
- GLchan rgba[][4] )
+ GLuint n, GLfloat texcoords[][4],
+ const GLfloat lambda[], GLchan rgba[][4] )
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
_swrast_validate_derived( ctx );
_swrast_choose_texture_sample_func( ctx, texUnit, tObj );
- swrast->TextureSample[texUnit]( ctx, texUnit, tObj, n, s, t, u,
+ swrast->TextureSample[texUnit]( ctx, texUnit, tObj, n, texcoords,
lambda, rgba );
}
@@ -315,7 +336,6 @@ _swrast_invalidate_state( GLcontext *ctx, GLuint new_state )
for (i = 0 ; i < ctx->Const.MaxTextureUnits ; i++)
swrast->TextureSample[i] = _swrast_validate_texture_sample;
-
if (ctx->Visual.rgbMode) {
ASSERT(swrast->Driver.WriteRGBASpan);
ASSERT(swrast->Driver.WriteRGBSpan);
@@ -334,18 +354,15 @@ _swrast_invalidate_state( GLcontext *ctx, GLuint new_state )
ASSERT(swrast->Driver.ReadCI32Span);
ASSERT(swrast->Driver.ReadCI32Pixels);
}
-
}
-
void
_swrast_validate_derived( GLcontext *ctx )
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
- if (swrast->NewState)
- {
+ if (swrast->NewState) {
if (swrast->NewState & _SWRAST_NEW_RASTERMASK)
_swrast_update_rasterflags( ctx );
@@ -355,6 +372,9 @@ _swrast_validate_derived( GLcontext *ctx )
if (swrast->NewState & _NEW_HINT)
_swrast_update_hint( ctx );
+ if (swrast->NewState & _SWRAST_NEW_TEXTURE_ENV_MODE)
+ _swrast_update_texture_env( ctx );
+
swrast->NewState = 0;
swrast->StateChanges = 0;
swrast->InvalidateState = _swrast_invalidate_state;
@@ -371,7 +391,7 @@ _swrast_Quad( GLcontext *ctx,
const SWvertex *v2, const SWvertex *v3 )
{
if (SWRAST_DEBUG) {
- fprintf(stderr, "_swrast_Quad\n");
+ _mesa_debug(ctx, "_swrast_Quad\n");
_swrast_print_vertex( ctx, v0 );
_swrast_print_vertex( ctx, v1 );
_swrast_print_vertex( ctx, v2 );
@@ -386,7 +406,7 @@ _swrast_Triangle( GLcontext *ctx, const SWvertex *v0,
const SWvertex *v1, const SWvertex *v2 )
{
if (SWRAST_DEBUG) {
- fprintf(stderr, "_swrast_Triangle\n");
+ _mesa_debug(ctx, "_swrast_Triangle\n");
_swrast_print_vertex( ctx, v0 );
_swrast_print_vertex( ctx, v1 );
_swrast_print_vertex( ctx, v2 );
@@ -398,7 +418,7 @@ void
_swrast_Line( GLcontext *ctx, const SWvertex *v0, const SWvertex *v1 )
{
if (SWRAST_DEBUG) {
- fprintf(stderr, "_swrast_Line\n");
+ _mesa_debug(ctx, "_swrast_Line\n");
_swrast_print_vertex( ctx, v0 );
_swrast_print_vertex( ctx, v1 );
}
@@ -409,7 +429,7 @@ void
_swrast_Point( GLcontext *ctx, const SWvertex *v0 )
{
if (SWRAST_DEBUG) {
- fprintf(stderr, "_swrast_Point\n");
+ _mesa_debug(ctx, "_swrast_Point\n");
_swrast_print_vertex( ctx, v0 );
}
SWRAST_CONTEXT(ctx)->Point( ctx, v0 );
@@ -419,7 +439,7 @@ void
_swrast_InvalidateState( GLcontext *ctx, GLuint new_state )
{
if (SWRAST_DEBUG) {
- fprintf(stderr, "_swrast_InvalidateState\n");
+ _mesa_debug(ctx, "_swrast_InvalidateState\n");
}
SWRAST_CONTEXT(ctx)->InvalidateState( ctx, new_state );
}
@@ -428,7 +448,7 @@ void
_swrast_ResetLineStipple( GLcontext *ctx )
{
if (SWRAST_DEBUG) {
- fprintf(stderr, "_swrast_ResetLineStipple\n");
+ _mesa_debug(ctx, "_swrast_ResetLineStipple\n");
}
SWRAST_CONTEXT(ctx)->StippleCounter = 0;
}
@@ -437,7 +457,7 @@ void
_swrast_allow_vertex_fog( GLcontext *ctx, GLboolean value )
{
if (SWRAST_DEBUG) {
- fprintf(stderr, "_swrast_allow_vertex_fog %d\n", value);
+ _mesa_debug(ctx, "_swrast_allow_vertex_fog %d\n", value);
}
SWRAST_CONTEXT(ctx)->InvalidateState( ctx, _NEW_HINT );
SWRAST_CONTEXT(ctx)->AllowVertexFog = value;
@@ -447,7 +467,7 @@ void
_swrast_allow_pixel_fog( GLcontext *ctx, GLboolean value )
{
if (SWRAST_DEBUG) {
- fprintf(stderr, "_swrast_allow_pixel_fog %d\n", value);
+ _mesa_debug(ctx, "_swrast_allow_pixel_fog %d\n", value);
}
SWRAST_CONTEXT(ctx)->InvalidateState( ctx, _NEW_HINT );
SWRAST_CONTEXT(ctx)->AllowPixelFog = value;
@@ -461,18 +481,12 @@ _swrast_CreateContext( GLcontext *ctx )
SWcontext *swrast = (SWcontext *)CALLOC(sizeof(SWcontext));
if (SWRAST_DEBUG) {
- fprintf(stderr, "_swrast_CreateContext\n");
+ _mesa_debug(ctx, "_swrast_CreateContext\n");
}
if (!swrast)
return GL_FALSE;
- swrast->PB = _mesa_alloc_pb();
- if (!swrast->PB) {
- FREE(swrast);
- return GL_FALSE;
- }
-
swrast->NewState = ~0;
swrast->choose_point = _swrast_choose_point;
@@ -492,15 +506,44 @@ _swrast_CreateContext( GLcontext *ctx )
swrast->AllowVertexFog = GL_TRUE;
swrast->AllowPixelFog = GL_TRUE;
+ if (ctx->Visual.doubleBufferMode)
+ swrast->CurrentBuffer = BACK_LEFT_BIT;
+ else
+ swrast->CurrentBuffer = FRONT_LEFT_BIT;
+
/* Optimized Accum buffer */
swrast->_IntegerAccumMode = GL_TRUE;
swrast->_IntegerAccumScaler = 0.0;
-
for (i = 0 ; i < MAX_TEXTURE_UNITS ; i++)
swrast->TextureSample[i] = _swrast_validate_texture_sample;
+ swrast->SpanArrays = MALLOC_STRUCT(span_arrays);
+ if (!swrast->SpanArrays) {
+ FREE(swrast);
+ return GL_FALSE;
+ }
+
+ /* init point span buffer */
+ swrast->PointSpan.primitive = GL_POINT;
+ swrast->PointSpan.start = 0;
+ swrast->PointSpan.end = 0;
+ swrast->PointSpan.facing = 0;
+ swrast->PointSpan.array = swrast->SpanArrays;
+
+ assert(ctx->Const.MaxTextureUnits > 0);
+ assert(ctx->Const.MaxTextureUnits <= MAX_TEXTURE_UNITS);
+
+ swrast->TexelBuffer = (GLchan *) MALLOC(ctx->Const.MaxTextureUnits *
+ MAX_WIDTH * 4 * sizeof(GLchan));
+ if (!swrast->TexelBuffer) {
+ FREE(swrast->SpanArrays);
+ FREE(swrast);
+ return GL_FALSE;
+ }
+
ctx->swrast_context = swrast;
+
return GL_TRUE;
}
@@ -510,10 +553,11 @@ _swrast_DestroyContext( GLcontext *ctx )
SWcontext *swrast = SWRAST_CONTEXT(ctx);
if (SWRAST_DEBUG) {
- fprintf(stderr, "_swrast_DestroyContext\n");
+ _mesa_debug(ctx, "_swrast_DestroyContext\n");
}
- FREE( swrast->PB );
+ FREE( swrast->SpanArrays );
+ FREE( swrast->TexelBuffer );
FREE( swrast );
ctx->swrast_context = 0;
@@ -527,6 +571,56 @@ _swrast_GetDeviceDriverReference( GLcontext *ctx )
return &swrast->Driver;
}
+void
+_swrast_flush( GLcontext *ctx )
+{
+ SWcontext *swrast = SWRAST_CONTEXT(ctx);
+ /* flush any pending fragments from rendering points */
+ if (swrast->PointSpan.end > 0) {
+ if (ctx->Visual.rgbMode) {
+ if (ctx->Texture._EnabledUnits)
+ _mesa_write_texture_span(ctx, &(swrast->PointSpan));
+ else
+ _mesa_write_rgba_span(ctx, &(swrast->PointSpan));
+ }
+ else {
+ _mesa_write_index_span(ctx, &(swrast->PointSpan));
+ }
+ swrast->PointSpan.end = 0;
+ }
+}
+
+void
+_swrast_render_primitive( GLcontext *ctx, GLenum prim )
+{
+ SWcontext *swrast = SWRAST_CONTEXT(ctx);
+ if (swrast->Primitive == GL_POINTS && prim != GL_POINTS) {
+ _swrast_flush(ctx);
+ }
+ swrast->Primitive = prim;
+}
+
+
+void
+_swrast_render_start( GLcontext *ctx )
+{
+ SWcontext *swrast = SWRAST_CONTEXT(ctx);
+ if (swrast->Driver.SpanRenderStart)
+ swrast->Driver.SpanRenderStart( ctx );
+ swrast->PointSpan.end = 0;
+}
+
+void
+_swrast_render_finish( GLcontext *ctx )
+{
+ SWcontext *swrast = SWRAST_CONTEXT(ctx);
+ if (swrast->Driver.SpanRenderFinish)
+ swrast->Driver.SpanRenderFinish( ctx );
+
+ _swrast_flush(ctx);
+}
+
+
#define SWRAST_DEBUG_VERTICES 0
void
@@ -535,29 +629,31 @@ _swrast_print_vertex( GLcontext *ctx, const SWvertex *v )
GLuint i;
if (SWRAST_DEBUG_VERTICES) {
- fprintf(stderr, "win %f %f %f %f\n",
- v->win[0], v->win[1], v->win[2], v->win[3]);
+ _mesa_debug(ctx, "win %f %f %f %f\n",
+ v->win[0], v->win[1], v->win[2], v->win[3]);
for (i = 0 ; i < ctx->Const.MaxTextureUnits ; i++)
if (ctx->Texture.Unit[i]._ReallyEnabled)
- fprintf(stderr, "texcoord[%d] %f %f %f %f\n", i,
- v->texcoord[i][0], v->texcoord[i][1],
- v->texcoord[i][2], v->texcoord[i][3]);
+ _mesa_debug(ctx, "texcoord[%d] %f %f %f %f\n", i,
+ v->texcoord[i][0], v->texcoord[i][1],
+ v->texcoord[i][2], v->texcoord[i][3]);
#if CHAN_TYPE == GL_FLOAT
- fprintf(stderr, "color %f %f %f %f\n",
- v->color[0], v->color[1], v->color[2], v->color[3]);
- fprintf(stderr, "spec %f %f %f %f\n",
- v->specular[0], v->specular[1], v->specular[2], v->specular[3]);
+ _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
- fprintf(stderr, "color %d %d %d %d\n",
- v->color[0], v->color[1], v->color[2], v->color[3]);
- fprintf(stderr, "spec %d %d %d %d\n",
- v->specular[0], v->specular[1], v->specular[2], v->specular[3]);
+ _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
- fprintf(stderr, "fog %f\n", v->fog);
- fprintf(stderr, "index %d\n", v->index);
- fprintf(stderr, "pointsize %f\n", v->pointSize);
- fprintf(stderr, "\n");
+ _mesa_debug(ctx, "fog %f\n", v->fog);
+ _mesa_debug(ctx, "index %d\n", v->index);
+ _mesa_debug(ctx, "pointsize %f\n", v->pointSize);
+ _mesa_debug(ctx, "\n");
}
}
diff --git a/xc/extras/Mesa/src/swrast/s_context.h b/xc/extras/Mesa/src/swrast/s_context.h
index 79081b809..75b72f3a2 100644
--- a/xc/extras/Mesa/src/swrast/s_context.h
+++ b/xc/extras/Mesa/src/swrast/s_context.h
@@ -1,10 +1,9 @@
-/* $Id: s_context.h,v 1.1.1.1 2002/10/22 13:06:45 alanh Exp $ */
/*
* Mesa 3-D graphics library
- * Version: 3.5
+ * Version: 4.1
*
- * Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
+ * Copyright (C) 1999-2002 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"),
@@ -24,7 +23,13 @@
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* Authors:
- * Keith Whitwell <keithw@valinux.com>
+ * Keith Whitwell <keith@tungstengraphics.com>
+ */
+
+/**
+ * \file swrast/s_context.h
+ * \brief fill in description
+ * \author Keith Whitwell <keith@tungstengraphics.com>
*/
#ifndef S_CONTEXT_H
@@ -38,10 +43,8 @@
*/
typedef void (*TextureSampleFunc)( GLcontext *ctx, GLuint texUnit,
const struct gl_texture_object *tObj,
- GLuint n,
- const GLfloat s[], const GLfloat t[],
- const GLfloat u[], const GLfloat lambda[],
- GLchan rgba[][4] );
+ GLuint n, GLfloat texcoords[][4],
+ const GLfloat lambda[], GLchan rgba[][4] );
@@ -66,25 +69,25 @@ typedef void (*swrast_tri_func)( GLcontext *ctx, const SWvertex *,
const SWvertex *, const SWvertex *);
-
-/*
- * Bitmasks to indicate which rasterization options are enabled (RasterMask)
+/** \defgroup Bitmasks
+ * Bitmasks to indicate which rasterization options are enabled
+ * (RasterMask)
*/
-#define ALPHATEST_BIT 0x001 /* Alpha-test pixels */
-#define BLEND_BIT 0x002 /* Blend pixels */
-#define DEPTH_BIT 0x004 /* Depth-test pixels */
-#define FOG_BIT 0x008 /* Fog pixels */
-#define LOGIC_OP_BIT 0x010 /* Apply logic op in software */
-#define SCISSOR_BIT 0x020 /* Scissor pixels */
-#define STENCIL_BIT 0x040 /* Stencil pixels */
-#define MASKING_BIT 0x080 /* Do glColorMask or glIndexMask */
-#define ALPHABUF_BIT 0x100 /* Using software alpha buffer */
-#define WINCLIP_BIT 0x200 /* Clip pixels/primitives to window */
-#define MULTI_DRAW_BIT 0x400 /* Write to more than one color- */
- /* buffer or no buffers. */
-#define OCCLUSION_BIT 0x800 /* GL_HP_occlusion_test enabled */
-#define TEXTURE_BIT 0x1000 /* Texturing really enabled */
-
+/*@{*/
+#define ALPHATEST_BIT 0x001 /**< Alpha-test pixels */
+#define BLEND_BIT 0x002 /**< Blend pixels */
+#define DEPTH_BIT 0x004 /**< Depth-test pixels */
+#define FOG_BIT 0x008 /**< Fog pixels */
+#define LOGIC_OP_BIT 0x010 /**< Apply logic op in software */
+#define CLIP_BIT 0x020 /**< Scissor or window clip pixels */
+#define STENCIL_BIT 0x040 /**< Stencil pixels */
+#define MASKING_BIT 0x080 /**< Do glColorMask or glIndexMask */
+#define ALPHABUF_BIT 0x100 /**< Using software alpha buffer */
+#define MULTI_DRAW_BIT 0x400 /**< Write to more than one color- */
+ /**< buffer or no buffers. */
+#define OCCLUSION_BIT 0x800 /**< GL_HP_occlusion_test enabled */
+#define TEXTURE_BIT 0x1000 /**< Texturing really enabled */
+/*@}*/
#define _SWRAST_NEW_RASTERMASK (_NEW_BUFFERS| \
_NEW_SCISSOR| \
@@ -97,43 +100,49 @@ typedef void (*swrast_tri_func)( GLcontext *ctx, const SWvertex *,
_NEW_DEPTH)
-
+/**
+ * \struct SWcontext
+ * \brief SWContext?
+ */
typedef struct
{
- /* Driver interface:
+ /** Driver interface:
*/
struct swrast_device_driver Driver;
- /* Configuration mechanisms to make software rasterizer match
+ /** Configuration mechanisms to make software rasterizer match
* characteristics of the hardware rasterizer (if present):
*/
GLboolean AllowVertexFog;
GLboolean AllowPixelFog;
- /* Derived values, invalidated on statechanges, updated from
+ /** Derived values, invalidated on statechanges, updated from
* _swrast_validate_derived():
*/
GLuint _RasterMask;
GLfloat _MinMagThresh[MAX_TEXTURE_UNITS];
GLfloat _backface_sign;
GLboolean _PreferPixelFog;
+ GLboolean _AnyTextureCombine;
/* Accum buffer temporaries.
*/
- GLboolean _IntegerAccumMode; /* Storing unscaled integers? */
- GLfloat _IntegerAccumScaler; /* Implicit scale factor */
+ GLboolean _IntegerAccumMode; /**< Storing unscaled integers? */
+ GLfloat _IntegerAccumScaler; /**< Implicit scale factor */
/* Working values:
*/
- struct pixel_buffer* PB;
- GLuint StippleCounter; /* Line stipple counter */
+ GLuint StippleCounter; /**< Line stipple counter */
GLuint NewState;
GLuint StateChanges;
+ GLenum Primitive; /* current primitive being drawn (ala glBegin) */
+ GLuint CurrentBuffer; /* exactly one of FRONT_LEFT_BIT, BACK_LEFT_BIT, etc*/
- /* Mechanism to allow driver (like X11) to register further
+ /** Mechanism to allow driver (like X11) to register further
* software rasterization routines.
*/
+ /*@{*/
void (*choose_point)( GLcontext * );
void (*choose_line)( GLcontext * );
void (*choose_triangle)( GLcontext * );
@@ -141,29 +150,50 @@ typedef struct
GLuint invalidate_point;
GLuint invalidate_line;
GLuint invalidate_triangle;
+ /*@}*/
-
- /* Function pointers for dispatch behind public entrypoints.
- */
+ /** Function pointers for dispatch behind public entrypoints. */
+ /*@{*/
void (*InvalidateState)( GLcontext *ctx, GLuint new_state );
swrast_point_func Point;
swrast_line_func Line;
swrast_tri_func Triangle;
+ /*@}*/
- /* Placeholders for when separate specular (or secondary color) is
+ /**
+ * Placeholders for when separate specular (or secondary color) is
* enabled but texturing is not.
*/
+ /*@{*/
swrast_point_func SpecPoint;
swrast_line_func SpecLine;
swrast_tri_func SpecTriangle;
+ /*@}*/
+ /**
+ * Typically, we'll allocate a sw_span structure as a local variable
+ * and set its 'array' pointer to point to this object. The reason is
+ * this object is big and causes problems when allocated on the stack
+ * on some systems.
+ */
+ struct span_arrays *SpanArrays;
- /* Internal hooks, kept uptodate by the same mechanism as above.
+ /**
+ * Used to buffer N GL_POINTS, instead of rendering one by one.
+ */
+ struct sw_span PointSpan;
+
+ /** Internal hooks, kept uptodate by the same mechanism as above.
*/
blend_func BlendFunc;
TextureSampleFunc TextureSample[MAX_TEXTURE_UNITS];
+ /** Buffer for saving the sampled texture colors.
+ * Needed for GL_ARB_texture_env_crossbar implementation.
+ */
+ GLchan *TexelBuffer;
+
} SWcontext;
diff --git a/xc/extras/Mesa/src/swrast/s_copypix.c b/xc/extras/Mesa/src/swrast/s_copypix.c
index 10c66ef89..eab359090 100644
--- a/xc/extras/Mesa/src/swrast/s_copypix.c
+++ b/xc/extras/Mesa/src/swrast/s_copypix.c
@@ -1,8 +1,7 @@
-/* $Id: s_copypix.c,v 1.1.1.1 2002/10/22 13:06:52 alanh Exp $ */
/*
* Mesa 3-D graphics library
- * Version: 4.0.3
+ * Version: 5.0
*
* Copyright (C) 1999-2002 Brian Paul All Rights Reserved.
*
@@ -31,13 +30,12 @@
#include "convolve.h"
#include "feedback.h"
#include "macros.h"
-#include "mem.h"
+#include "imports.h"
#include "mmath.h"
#include "pixel.h"
#include "s_context.h"
#include "s_depth.h"
-#include "s_fog.h"
#include "s_histogram.h"
#include "s_pixeltex.h"
#include "s_span.h"
@@ -67,6 +65,9 @@ regions_overlap(GLint srcx, GLint srcy,
else if (srcy < dsty) { /* this is OK */
return GL_FALSE;
}
+ else if (srcy > dsty + height) {
+ return GL_FALSE;
+ }
else {
return GL_TRUE;
}
@@ -98,32 +99,21 @@ copy_conv_rgba_pixels(GLcontext *ctx, GLint srcx, GLint srcy,
GLint width, GLint height, GLint destx, GLint desty)
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
- GLdepth zspan[MAX_WIDTH];
- GLfloat fogSpan[MAX_WIDTH];
GLboolean quick_draw;
GLint row;
GLboolean changeBuffer;
- GLchan *saveReadAlpha;
const GLboolean zoom = ctx->Pixel.ZoomX != 1.0F || ctx->Pixel.ZoomY != 1.0F;
const GLuint transferOps = ctx->_ImageTransferState;
GLfloat *dest, *tmpImage, *convImage;
+ struct sw_span span;
- if (ctx->Depth.Test || ctx->Fog.Enabled) {
- /* fill in array of z values */
- GLdepth z = (GLdepth) (ctx->Current.RasterPos[2] * ctx->DepthMax);
- GLfloat fog;
- GLint i;
+ INIT_SPAN(span, GL_BITMAP, 0, 0, SPAN_RGBA);
- if (ctx->Fog.FogCoordinateSource == GL_FOG_COORDINATE_EXT)
- fog = _mesa_z_to_fogfactor(ctx, ctx->Current.RasterFogCoord);
- else
- fog = _mesa_z_to_fogfactor(ctx, ctx->Current.RasterDistance);
+ if (ctx->Depth.Test)
+ _mesa_span_default_z(ctx, &span);
+ if (ctx->Fog.Enabled)
+ _mesa_span_default_fog(ctx, &span);
- for (i = 0; i < width; i++) {
- zspan[i] = z;
- fogSpan[i] = fog;
- }
- }
if (SWRAST_CONTEXT(ctx)->_RasterMask == 0
&& !zoom
@@ -136,7 +126,6 @@ copy_conv_rgba_pixels(GLcontext *ctx, GLint srcx, GLint srcy,
}
/* If read and draw buffer are different we must do buffer switching */
- saveReadAlpha = ctx->ReadBuffer->Alpha;
changeBuffer = ctx->Pixel.ReadBuffer != ctx->Color.DrawBuffer
|| ctx->DrawBuffer != ctx->ReadBuffer;
@@ -157,16 +146,8 @@ copy_conv_rgba_pixels(GLcontext *ctx, GLint srcx, GLint srcy,
dest = tmpImage;
if (changeBuffer) {
- (*swrast->Driver.SetReadBuffer)( ctx, ctx->ReadBuffer,
- ctx->Pixel.DriverReadBuffer );
- if (ctx->Pixel.DriverReadBuffer == GL_FRONT_LEFT)
- ctx->ReadBuffer->Alpha = ctx->ReadBuffer->FrontLeftAlpha;
- else if (ctx->Pixel.DriverReadBuffer == GL_BACK_LEFT)
- ctx->ReadBuffer->Alpha = ctx->ReadBuffer->BackLeftAlpha;
- else if (ctx->Pixel.DriverReadBuffer == GL_FRONT_RIGHT)
- ctx->ReadBuffer->Alpha = ctx->ReadBuffer->FrontRightAlpha;
- else
- ctx->ReadBuffer->Alpha = ctx->ReadBuffer->BackRightAlpha;
+ /* choose the read buffer */
+ _swrast_use_read_buffer(ctx);
}
/* read source image */
@@ -184,11 +165,9 @@ copy_conv_rgba_pixels(GLcontext *ctx, GLint srcx, GLint srcy,
}
}
- /* read from the draw buffer again (in case of blending) */
if (changeBuffer) {
- (*swrast->Driver.SetReadBuffer)( ctx, ctx->DrawBuffer,
- ctx->Color.DriverDrawBuffer );
- ctx->ReadBuffer->Alpha = saveReadAlpha;
+ /* restore default src/dst buffer */
+ _swrast_use_draw_buffer(ctx);
}
/* do image transfer ops up until convolution */
@@ -251,7 +230,6 @@ copy_conv_rgba_pixels(GLcontext *ctx, GLint srcx, GLint srcy,
for (row = 0; row < height; row++) {
const GLfloat *src = convImage + row * width * 4;
- GLchan rgba[MAX_WIDTH][4];
GLint i, dy;
/* clamp to [0,1] and convert float back to chan */
@@ -260,27 +238,15 @@ copy_conv_rgba_pixels(GLcontext *ctx, GLint srcx, GLint srcy,
GLint g = (GLint) (src[i * 4 + GCOMP] * CHAN_MAXF);
GLint b = (GLint) (src[i * 4 + BCOMP] * CHAN_MAXF);
GLint a = (GLint) (src[i * 4 + ACOMP] * CHAN_MAXF);
- rgba[i][RCOMP] = (GLchan) CLAMP(r, 0, CHAN_MAX);
- rgba[i][GCOMP] = (GLchan) CLAMP(g, 0, CHAN_MAX);
- rgba[i][BCOMP] = (GLchan) CLAMP(b, 0, CHAN_MAX);
- rgba[i][ACOMP] = (GLchan) CLAMP(a, 0, CHAN_MAX);
- }
-
- if (ctx->Texture._ReallyEnabled && ctx->Pixel.PixelTextureEnabled) {
- GLfloat s[MAX_WIDTH], t[MAX_WIDTH], r[MAX_WIDTH], q[MAX_WIDTH];
- GLchan primary_rgba[MAX_WIDTH][4];
- GLuint unit;
- /* XXX not sure how multitexture is supposed to work here */
-
- MEMCPY(primary_rgba, rgba, 4 * width * sizeof(GLchan));
-
- for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) {
- _mesa_pixeltexgen(ctx, width, (const GLchan (*)[4]) rgba,
- s, t, r, q);
- _swrast_texture_fragments(ctx, unit, width, s, t, r, NULL,
- (CONST GLchan (*)[4]) primary_rgba,
- rgba);
- }
+ span.array->rgba[i][RCOMP] = (GLchan) CLAMP(r, 0, CHAN_MAX);
+ span.array->rgba[i][GCOMP] = (GLchan) CLAMP(g, 0, CHAN_MAX);
+ span.array->rgba[i][BCOMP] = (GLchan) CLAMP(b, 0, CHAN_MAX);
+ span.array->rgba[i][ACOMP] = (GLchan) CLAMP(a, 0, CHAN_MAX);
+ }
+
+ if (ctx->Pixel.PixelTextureEnabled && ctx->Texture._EnabledUnits) {
+ span.end = width;
+ _swrast_pixel_texture(ctx, &span);
}
/* write row to framebuffer */
@@ -288,15 +254,21 @@ copy_conv_rgba_pixels(GLcontext *ctx, GLint srcx, GLint srcy,
dy = desty + row;
if (quick_draw && dy >= 0 && dy < (GLint) ctx->DrawBuffer->Height) {
(*swrast->Driver.WriteRGBASpan)( ctx, width, destx, dy,
- (const GLchan (*)[4])rgba, NULL );
+ (const GLchan (*)[4])span.array->rgba, NULL );
}
else if (zoom) {
- _mesa_write_zoomed_rgba_span( ctx, width, destx, dy, zspan, fogSpan,
- (const GLchan (*)[4])rgba, desty);
+ span.x = destx;
+ span.y = dy;
+ span.end = width;
+ _mesa_write_zoomed_rgba_span(ctx, &span,
+ (CONST GLchan (*)[4])span.array->rgba,
+ desty);
}
else {
- _mesa_write_rgba_span( ctx, width, destx, dy, zspan, fogSpan, rgba,
- NULL, GL_BITMAP );
+ span.x = destx;
+ span.y = dy;
+ span.end = width;
+ _mesa_write_rgba_span(ctx, &span);
}
}
@@ -312,18 +284,16 @@ copy_rgba_pixels(GLcontext *ctx, GLint srcx, GLint srcy,
GLint width, GLint height, GLint destx, GLint desty)
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
- GLdepth zspan[MAX_WIDTH];
- GLfloat fogSpan[MAX_WIDTH];
- GLchan rgba[MAX_WIDTH][4];
GLchan *tmpImage,*p;
GLboolean quick_draw;
- GLint sy, dy, stepy;
- GLint i, j;
+ GLint sy, dy, stepy, j;
GLboolean changeBuffer;
- GLchan *saveReadAlpha;
const GLboolean zoom = ctx->Pixel.ZoomX != 1.0F || ctx->Pixel.ZoomY != 1.0F;
GLint overlapping;
const GLuint transferOps = ctx->_ImageTransferState;
+ struct sw_span span;
+
+ INIT_SPAN(span, GL_BITMAP, 0, 0, SPAN_RGBA);
if (ctx->Pixel.Convolution2DEnabled || ctx->Pixel.Separable2DEnabled) {
copy_conv_rgba_pixels(ctx, srcx, srcy, width, height, destx, desty);
@@ -347,21 +317,10 @@ copy_rgba_pixels(GLcontext *ctx, GLint srcx, GLint srcy,
overlapping = regions_overlap(srcx, srcy, destx, desty, width, height,
ctx->Pixel.ZoomX, ctx->Pixel.ZoomY);
- if (ctx->Depth.Test || ctx->Fog.Enabled) {
- /* fill in array of z values */
- GLdepth z = (GLdepth) (ctx->Current.RasterPos[2] * ctx->DepthMax);
- GLfloat fog;
-
- if (ctx->Fog.FogCoordinateSource == GL_FOG_COORDINATE_EXT)
- fog = _mesa_z_to_fogfactor(ctx, ctx->Current.RasterFogCoord);
- else
- fog = _mesa_z_to_fogfactor(ctx, ctx->Current.RasterDistance);
-
- for (i=0;i<width;i++) {
- zspan[i] = z;
- fogSpan[i] = fog;
- }
- }
+ if (ctx->Depth.Test)
+ _mesa_span_default_z(ctx, &span);
+ if (ctx->Fog.Enabled)
+ _mesa_span_default_fog(ctx, &span);
if (SWRAST_CONTEXT(ctx)->_RasterMask == 0
&& !zoom
@@ -374,13 +333,9 @@ copy_rgba_pixels(GLcontext *ctx, GLint srcx, GLint srcy,
}
/* If read and draw buffer are different we must do buffer switching */
- saveReadAlpha = ctx->ReadBuffer->Alpha;
changeBuffer = ctx->Pixel.ReadBuffer != ctx->Color.DrawBuffer
|| ctx->DrawBuffer != ctx->ReadBuffer;
- (*swrast->Driver.SetReadBuffer)( ctx, ctx->ReadBuffer,
- ctx->Pixel.DriverReadBuffer );
-
if (overlapping) {
GLint ssy = sy;
tmpImage = (GLchan *) MALLOC(width * height * sizeof(GLchan) * 4);
@@ -388,25 +343,22 @@ copy_rgba_pixels(GLcontext *ctx, GLint srcx, GLint srcy,
_mesa_error( ctx, GL_OUT_OF_MEMORY, "glCopyPixels" );
return;
}
+ /* setup source */
+ if (changeBuffer)
+ _swrast_use_read_buffer(ctx);
+ /* read the source image */
p = tmpImage;
- if (changeBuffer) {
- (*swrast->Driver.SetReadBuffer)( ctx, ctx->ReadBuffer,
- ctx->Pixel.DriverReadBuffer );
- if (ctx->Pixel.DriverReadBuffer == GL_FRONT_LEFT)
- ctx->ReadBuffer->Alpha = ctx->ReadBuffer->FrontLeftAlpha;
- else if (ctx->Pixel.DriverReadBuffer == GL_BACK_LEFT)
- ctx->ReadBuffer->Alpha = ctx->ReadBuffer->BackLeftAlpha;
- else if (ctx->Pixel.DriverReadBuffer == GL_FRONT_RIGHT)
- ctx->ReadBuffer->Alpha = ctx->ReadBuffer->FrontRightAlpha;
- else
- ctx->ReadBuffer->Alpha = ctx->ReadBuffer->BackRightAlpha;
- }
for (j = 0; j < height; j++, ssy += stepy) {
_mesa_read_rgba_span( ctx, ctx->ReadBuffer, width, srcx, ssy,
(GLchan (*)[4]) p );
p += width * 4;
}
p = tmpImage;
+ /* restore dest */
+ if (changeBuffer) {
+ _swrast_use_draw_buffer(ctx);
+ changeBuffer = GL_FALSE;
+ }
}
else {
tmpImage = NULL; /* silence compiler warnings */
@@ -417,35 +369,17 @@ copy_rgba_pixels(GLcontext *ctx, GLint srcx, GLint srcy,
/* Get source pixels */
if (overlapping) {
/* get from buffered image */
- MEMCPY(rgba, p, width * sizeof(GLchan) * 4);
+ MEMCPY(span.array->rgba, p, width * sizeof(GLchan) * 4);
p += width * 4;
}
else {
/* get from framebuffer */
- if (changeBuffer) {
- (*swrast->Driver.SetReadBuffer)( ctx, ctx->ReadBuffer,
- ctx->Pixel.DriverReadBuffer );
- if (ctx->Pixel.DriverReadBuffer == GL_FRONT_LEFT) {
- ctx->ReadBuffer->Alpha = ctx->ReadBuffer->FrontLeftAlpha;
- }
- else if (ctx->Pixel.DriverReadBuffer == GL_BACK_LEFT) {
- ctx->ReadBuffer->Alpha = ctx->ReadBuffer->BackLeftAlpha;
- }
- else if (ctx->Pixel.DriverReadBuffer == GL_FRONT_RIGHT) {
- ctx->ReadBuffer->Alpha = ctx->ReadBuffer->FrontRightAlpha;
- }
- else {
- ctx->ReadBuffer->Alpha = ctx->ReadBuffer->BackRightAlpha;
- }
- }
- _mesa_read_rgba_span( ctx, ctx->ReadBuffer, width, srcx, sy, rgba );
- }
-
- if (changeBuffer) {
- /* read from the draw buffer again (in case of blending) */
- (*swrast->Driver.SetReadBuffer)( ctx, ctx->DrawBuffer,
- ctx->Color.DriverDrawBuffer );
- ctx->ReadBuffer->Alpha = saveReadAlpha;
+ if (changeBuffer)
+ _swrast_use_read_buffer(ctx);
+ _mesa_read_rgba_span( ctx, ctx->ReadBuffer, width, srcx, sy,
+ span.array->rgba );
+ if (changeBuffer)
+ _swrast_use_draw_buffer(ctx);
}
if (transferOps) {
@@ -456,10 +390,10 @@ copy_rgba_pixels(GLcontext *ctx, GLint srcx, GLint srcy,
/* convert chan to float */
for (k = 0; k < width; k++) {
- rgbaFloat[k][RCOMP] = (GLfloat) rgba[k][RCOMP] * scale;
- rgbaFloat[k][GCOMP] = (GLfloat) rgba[k][GCOMP] * scale;
- rgbaFloat[k][BCOMP] = (GLfloat) rgba[k][BCOMP] * scale;
- rgbaFloat[k][ACOMP] = (GLfloat) rgba[k][ACOMP] * scale;
+ rgbaFloat[k][RCOMP] = (GLfloat) span.array->rgba[k][RCOMP] * scale;
+ rgbaFloat[k][GCOMP] = (GLfloat) span.array->rgba[k][GCOMP] * scale;
+ rgbaFloat[k][BCOMP] = (GLfloat) span.array->rgba[k][BCOMP] * scale;
+ rgbaFloat[k][ACOMP] = (GLfloat) span.array->rgba[k][ACOMP] * scale;
}
/* scale & bias */
if (transferOps & IMAGE_SCALE_BIAS_BIT) {
@@ -479,7 +413,8 @@ copy_rgba_pixels(GLcontext *ctx, GLint srcx, GLint srcy,
}
/* convolution */
if (transferOps & IMAGE_CONVOLUTION_BIT) {
- /* XXX to do */
+ _mesa_problem(ctx, "Convolution should not be enabled in copy_rgba_pixels()");
+ return;
}
/* GL_POST_CONVOLUTION_RED/GREEN/BLUE/ALPHA_SCALE/BIAS */
if (transferOps & IMAGE_POST_CONVOLUTION_SCALE_BIAS) {
@@ -519,61 +454,39 @@ copy_rgba_pixels(GLcontext *ctx, GLint srcx, GLint srcy,
GLint g = (GLint) (rgbaFloat[k][GCOMP] * CHAN_MAXF);
GLint b = (GLint) (rgbaFloat[k][BCOMP] * CHAN_MAXF);
GLint a = (GLint) (rgbaFloat[k][ACOMP] * CHAN_MAXF);
- rgba[k][RCOMP] = (GLchan) CLAMP(r, 0, CHAN_MAX);
- rgba[k][GCOMP] = (GLchan) CLAMP(g, 0, CHAN_MAX);
- rgba[k][BCOMP] = (GLchan) CLAMP(b, 0, CHAN_MAX);
- rgba[k][ACOMP] = (GLchan) CLAMP(a, 0, CHAN_MAX);
+ span.array->rgba[k][RCOMP] = (GLchan) CLAMP(r, 0, CHAN_MAX);
+ span.array->rgba[k][GCOMP] = (GLchan) CLAMP(g, 0, CHAN_MAX);
+ span.array->rgba[k][BCOMP] = (GLchan) CLAMP(b, 0, CHAN_MAX);
+ span.array->rgba[k][ACOMP] = (GLchan) CLAMP(a, 0, CHAN_MAX);
}
UNDEFARRAY(rgbaFloat); /* mac 32k limitation */
}
- if (ctx->Texture._ReallyEnabled && ctx->Pixel.PixelTextureEnabled) {
- GLuint unit;
- GLchan primary_rgba[MAX_WIDTH][4];
- DEFARRAY(GLfloat, s, MAX_WIDTH); /* mac 32k limitation */
- DEFARRAY(GLfloat, t, MAX_WIDTH); /* mac 32k limitation */
- DEFARRAY(GLfloat, r, MAX_WIDTH); /* mac 32k limitation */
- DEFARRAY(GLfloat, q, MAX_WIDTH); /* mac 32k limitation */
- CHECKARRAY(s, return); /* mac 32k limitation */
- CHECKARRAY(t, return);
- CHECKARRAY(r, return);
- CHECKARRAY(q, return);
-
- /* XXX not sure how multitexture is supposed to work here */
- MEMCPY(primary_rgba, rgba, 4 * width * sizeof(GLchan));
-
- for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) {
- _mesa_pixeltexgen(ctx, width, (const GLchan (*)[4]) rgba,
- s, t, r, q);
- _swrast_texture_fragments(ctx, unit, width, s, t, r, NULL,
- (CONST GLchan (*)[4]) primary_rgba,
- rgba);
- }
-
- UNDEFARRAY(s); /* mac 32k limitation */
- UNDEFARRAY(t);
- UNDEFARRAY(r);
- UNDEFARRAY(q);
+ if (ctx->Pixel.PixelTextureEnabled && ctx->Texture._EnabledUnits) {
+ span.end = width;
+ _swrast_pixel_texture(ctx, &span);
}
if (quick_draw && dy >= 0 && dy < (GLint) ctx->DrawBuffer->Height) {
(*swrast->Driver.WriteRGBASpan)( ctx, width, destx, dy,
- (const GLchan (*)[4])rgba, NULL );
+ (const GLchan (*)[4])span.array->rgba, NULL );
}
else if (zoom) {
- _mesa_write_zoomed_rgba_span( ctx, width, destx, dy, zspan, fogSpan,
- (const GLchan (*)[4])rgba, desty);
+ span.x = destx;
+ span.y = dy;
+ span.end = width;
+ _mesa_write_zoomed_rgba_span(ctx, &span,
+ (CONST GLchan (*)[4]) span.array->rgba,
+ desty);
}
else {
- _mesa_write_rgba_span( ctx, width, destx, dy, zspan, fogSpan, rgba,
- NULL, GL_BITMAP );
+ span.x = destx;
+ span.y = dy;
+ span.end = width;
+ _mesa_write_rgba_span(ctx, &span);
}
}
- /* Restore pixel source to be the draw buffer (for blending, etc) */
- (*swrast->Driver.SetReadBuffer)( ctx, ctx->DrawBuffer,
- ctx->Color.DriverDrawBuffer );
-
if (overlapping)
FREE(tmpImage);
}
@@ -583,16 +496,16 @@ static void copy_ci_pixels( GLcontext *ctx,
GLint srcx, GLint srcy, GLint width, GLint height,
GLint destx, GLint desty )
{
- SWcontext *swrast = SWRAST_CONTEXT(ctx);
- GLdepth zspan[MAX_WIDTH];
- GLfloat fogSpan[MAX_WIDTH];
GLuint *tmpImage,*p;
GLint sy, dy, stepy;
- GLint i, j;
+ GLint j;
GLboolean changeBuffer;
const GLboolean zoom = ctx->Pixel.ZoomX != 1.0F || ctx->Pixel.ZoomY != 1.0F;
const GLboolean shift_or_offset = ctx->Pixel.IndexShift || ctx->Pixel.IndexOffset;
GLint overlapping;
+ struct sw_span span;
+
+ INIT_SPAN(span, GL_BITMAP, 0, 0, SPAN_INDEX);
/* Determine if copy should be bottom-to-top or top-to-bottom */
if (srcy<desty) {
@@ -611,29 +524,15 @@ static void copy_ci_pixels( GLcontext *ctx,
overlapping = regions_overlap(srcx, srcy, destx, desty, width, height,
ctx->Pixel.ZoomX, ctx->Pixel.ZoomY);
- if (ctx->Depth.Test || ctx->Fog.Enabled) {
- /* fill in array of z values */
- GLdepth z = (GLdepth) (ctx->Current.RasterPos[2] * ctx->DepthMax);
- GLfloat fog;
-
- if (ctx->Fog.FogCoordinateSource == GL_FOG_COORDINATE_EXT)
- fog = _mesa_z_to_fogfactor(ctx, ctx->Current.RasterFogCoord);
- else
- fog = _mesa_z_to_fogfactor(ctx, ctx->Current.RasterDistance);
-
- for (i=0;i<width;i++) {
- zspan[i] = z;
- fogSpan[i] = fog;
- }
- }
+ if (ctx->Depth.Test)
+ _mesa_span_default_z(ctx, &span);
+ if (ctx->Fog.Enabled)
+ _mesa_span_default_fog(ctx, &span);
/* If read and draw buffer are different we must do buffer switching */
changeBuffer = ctx->Pixel.ReadBuffer != ctx->Color.DrawBuffer
|| ctx->DrawBuffer != ctx->ReadBuffer;
- (*swrast->Driver.SetReadBuffer)( ctx, ctx->ReadBuffer,
- ctx->Pixel.DriverReadBuffer );
-
if (overlapping) {
GLint ssy = sy;
tmpImage = (GLuint *) MALLOC(width * height * sizeof(GLuint));
@@ -641,16 +540,21 @@ static void copy_ci_pixels( GLcontext *ctx,
_mesa_error( ctx, GL_OUT_OF_MEMORY, "glCopyPixels" );
return;
}
+ /* setup source */
+ if (changeBuffer)
+ _swrast_use_read_buffer(ctx);
+ /* read the image */
p = tmpImage;
- if (changeBuffer) {
- (*swrast->Driver.SetReadBuffer)( ctx, ctx->ReadBuffer,
- ctx->Pixel.DriverReadBuffer );
- }
for (j = 0; j < height; j++, ssy += stepy) {
_mesa_read_index_span( ctx, ctx->ReadBuffer, width, srcx, ssy, p );
p += width;
}
p = tmpImage;
+ /* restore to draw buffer */
+ if (changeBuffer) {
+ _swrast_use_draw_buffer(ctx);
+ changeBuffer = GL_FALSE;
+ }
}
else {
tmpImage = NULL; /* silence compiler warning */
@@ -658,46 +562,35 @@ static void copy_ci_pixels( GLcontext *ctx,
}
for (j = 0; j < height; j++, sy += stepy, dy += stepy) {
- GLuint indexes[MAX_WIDTH];
if (overlapping) {
- MEMCPY(indexes, p, width * sizeof(GLuint));
+ MEMCPY(span.array->index, p, width * sizeof(GLuint));
p += width;
}
else {
- if (changeBuffer) {
- (*swrast->Driver.SetReadBuffer)( ctx, ctx->ReadBuffer,
- ctx->Pixel.DriverReadBuffer );
- }
- _mesa_read_index_span( ctx, ctx->ReadBuffer, width, srcx, sy, indexes );
- }
-
- if (changeBuffer) {
- /* set read buffer back to draw buffer (in case of logicops) */
- (*swrast->Driver.SetReadBuffer)( ctx, ctx->DrawBuffer,
- ctx->Color.DriverDrawBuffer );
+ if (changeBuffer)
+ _swrast_use_read_buffer(ctx);
+ _mesa_read_index_span( ctx, ctx->ReadBuffer, width, srcx, sy,
+ span.array->index );
+ if (changeBuffer)
+ _swrast_use_draw_buffer(ctx);
}
if (shift_or_offset) {
- _mesa_shift_and_offset_ci( ctx, width, indexes );
+ _mesa_shift_and_offset_ci( ctx, width, span.array->index );
}
if (ctx->Pixel.MapColorFlag) {
- _mesa_map_ci( ctx, width, indexes );
+ _mesa_map_ci( ctx, width, span.array->index );
}
- if (zoom) {
- _mesa_write_zoomed_index_span(ctx, width, destx, dy, zspan, fogSpan,
- indexes, desty );
- }
- else {
- _mesa_write_index_span(ctx, width, destx, dy, zspan, fogSpan, indexes,
- NULL, GL_BITMAP);
- }
+ span.x = destx;
+ span.y = dy;
+ span.end = width;
+ if (zoom)
+ _mesa_write_zoomed_index_span(ctx, &span, desty);
+ else
+ _mesa_write_index_span(ctx, &span);
}
- /* Restore pixel source to be the draw buffer (for blending, etc) */
- (*swrast->Driver.SetReadBuffer)( ctx, ctx->DrawBuffer,
- ctx->Color.DriverDrawBuffer );
-
if (overlapping)
FREE(tmpImage);
}
@@ -712,20 +605,17 @@ static void copy_depth_pixels( GLcontext *ctx, GLint srcx, GLint srcy,
GLint destx, GLint desty )
{
GLfloat depth[MAX_WIDTH];
- GLdepth zspan[MAX_WIDTH];
- GLfloat fogSpan[MAX_WIDTH];
GLfloat *p, *tmpImage;
- GLuint indexes[MAX_WIDTH];
GLint sy, dy, stepy;
GLint i, j;
const GLboolean zoom = ctx->Pixel.ZoomX != 1.0F || ctx->Pixel.ZoomY != 1.0F;
GLint overlapping;
- DEFMARRAY(GLchan, rgba, MAX_WIDTH, 4); /* mac 32k limitation */
- CHECKARRAY(rgba, return); /* mac 32k limitation */
+ struct sw_span span;
+
+ INIT_SPAN(span, GL_BITMAP, 0, 0, SPAN_Z);
if (!ctx->Visual.depthBits) {
_mesa_error( ctx, GL_INVALID_OPERATION, "glCopyPixels" );
- UNDEFARRAY(rgba); /* mac 32k limitation */
return;
}
@@ -746,39 +636,15 @@ static void copy_depth_pixels( GLcontext *ctx, GLint srcx, GLint srcy,
overlapping = regions_overlap(srcx, srcy, destx, desty, width, height,
ctx->Pixel.ZoomX, ctx->Pixel.ZoomY);
- /* setup colors or indexes */
- if (ctx->Visual.rgbMode) {
- GLuint *rgba32 = (GLuint *) rgba;
- GLuint color = *(GLuint*)( ctx->Current.Color );
- for (i = 0; i < width; i++) {
- rgba32[i] = color;
- }
- }
- else {
- for (i = 0; i < width; i++) {
- indexes[i] = ctx->Current.Index;
- }
- }
-
- if (ctx->Fog.Enabled) {
- GLfloat fog;
-
- if (ctx->Fog.FogCoordinateSource == GL_FOG_COORDINATE_EXT)
- fog = _mesa_z_to_fogfactor(ctx, ctx->Current.RasterFogCoord);
- else
- fog = _mesa_z_to_fogfactor(ctx, ctx->Current.RasterDistance);
-
- for (i = 0; i < width; i++) {
- fogSpan[i] = fog;
- }
- }
+ _mesa_span_default_color(ctx, &span);
+ if (ctx->Fog.Enabled)
+ _mesa_span_default_fog(ctx, &span);
if (overlapping) {
GLint ssy = sy;
tmpImage = (GLfloat *) MALLOC(width * height * sizeof(GLfloat));
if (!tmpImage) {
_mesa_error( ctx, GL_OUT_OF_MEMORY, "glCopyPixels" );
- UNDEFARRAY(rgba); /* mac 32k limitation */
return;
}
p = tmpImage;
@@ -804,33 +670,28 @@ static void copy_depth_pixels( GLcontext *ctx, GLint srcx, GLint srcy,
for (i = 0; i < width; i++) {
GLfloat d = depth[i] * ctx->Pixel.DepthScale + ctx->Pixel.DepthBias;
- zspan[i] = (GLdepth) (CLAMP(d, 0.0F, 1.0F) * ctx->DepthMax);
+ span.array->z[i] = (GLdepth) (CLAMP(d, 0.0F, 1.0F) * ctx->DepthMax);
}
+ span.x = destx;
+ span.y = dy;
+ span.end = width;
if (ctx->Visual.rgbMode) {
- if (zoom) {
- _mesa_write_zoomed_rgba_span( ctx, width, destx, dy, zspan,
- fogSpan, (const GLchan (*)[4])rgba, desty );
- }
- else {
- _mesa_write_rgba_span( ctx, width, destx, dy, zspan, fogSpan,
- (GLchan (*)[4])rgba, NULL, GL_BITMAP);
- }
+ if (zoom)
+ _mesa_write_zoomed_rgba_span( ctx, &span,
+ (const GLchan (*)[4])span.array->rgba,
+ desty );
+ else
+ _mesa_write_rgba_span(ctx, &span);
}
else {
- if (zoom) {
- _mesa_write_zoomed_index_span( ctx, width, destx, dy,
- zspan, fogSpan, indexes, desty );
- }
- else {
- _mesa_write_index_span( ctx, width, destx, dy,
- zspan, fogSpan, indexes, NULL, GL_BITMAP );
- }
+ if (zoom)
+ _mesa_write_zoomed_index_span( ctx, &span, desty );
+ else
+ _mesa_write_index_span(ctx, &span);
}
}
- UNDEFARRAY(rgba); /* mac 32k limitation */
-
if (overlapping)
FREE(tmpImage);
}
diff --git a/xc/extras/Mesa/src/swrast/s_depth.c b/xc/extras/Mesa/src/swrast/s_depth.c
index 76ef0d9cb..d3279d634 100644
--- a/xc/extras/Mesa/src/swrast/s_depth.c
+++ b/xc/extras/Mesa/src/swrast/s_depth.c
@@ -1,8 +1,7 @@
-/* $Id: s_depth.c,v 1.1.1.1 2002/10/22 13:06:45 alanh Exp $ */
/*
* Mesa 3-D graphics library
- * Version: 4.0.3
+ * Version: 4.1
*
* Copyright (C) 1999-2002 Brian Paul All Rights Reserved.
*
@@ -28,25 +27,24 @@
#include "glheader.h"
#include "context.h"
#include "macros.h"
-#include "mem.h"
+#include "imports.h"
#include "s_depth.h"
#include "s_context.h"
-#include "s_pb.h"
-
-
-/*
+/**
* Return address of depth buffer value for given window coord.
*/
GLvoid *
_mesa_zbuffer_address(GLcontext *ctx, GLint x, GLint y)
{
if (ctx->Visual.depthBits <= 16)
- return (GLushort *) ctx->DrawBuffer->DepthBuffer + ctx->DrawBuffer->Width * y + x;
+ return (GLushort *) ctx->DrawBuffer->DepthBuffer
+ + ctx->DrawBuffer->Width * y + x;
else
- return (GLuint *) ctx->DrawBuffer->DepthBuffer + ctx->DrawBuffer->Width * y + x;
+ return (GLuint *) ctx->DrawBuffer->DepthBuffer
+ + ctx->DrawBuffer->Width * y + x;
}
@@ -73,7 +71,7 @@ _mesa_zbuffer_address(GLcontext *ctx, GLint x, GLint y)
* Return: number of fragments which pass the test.
*/
static GLuint
-depth_test_span16( GLcontext *ctx, GLuint n, GLint x, GLint y,
+depth_test_span16( GLcontext *ctx, GLuint n,
GLushort zbuffer[], const GLdepth z[], GLubyte mask[] )
{
GLuint passed = 0;
@@ -291,7 +289,7 @@ depth_test_span16( GLcontext *ctx, GLuint n, GLint x, GLint y,
}
break;
case GL_NEVER:
- BZERO(mask, n * sizeof(GLubyte));
+ _mesa_bzero(mask, n * sizeof(GLubyte));
break;
default:
_mesa_problem(ctx, "Bad depth func in depth_test_span16");
@@ -302,7 +300,7 @@ depth_test_span16( GLcontext *ctx, GLuint n, GLint x, GLint y,
static GLuint
-depth_test_span32( GLcontext *ctx, GLuint n, GLint x, GLint y,
+depth_test_span32( GLcontext *ctx, GLuint n,
GLuint zbuffer[], const GLdepth z[], GLubyte mask[] )
{
GLuint passed = 0;
@@ -520,7 +518,7 @@ depth_test_span32( GLcontext *ctx, GLuint n, GLint x, GLint y,
}
break;
case GL_NEVER:
- BZERO(mask, n * sizeof(GLubyte));
+ _mesa_bzero(mask, n * sizeof(GLubyte));
break;
default:
_mesa_problem(ctx, "Bad depth func in depth_test_span32");
@@ -534,33 +532,59 @@ depth_test_span32( GLcontext *ctx, GLuint n, GLint x, GLint y,
/*
* Apply depth test to span of fragments. Hardware or software z buffer.
*/
-GLuint
-_mesa_depth_test_span( GLcontext *ctx, GLuint n, GLint x, GLint y,
- const GLdepth z[], GLubyte mask[] )
+static GLuint
+depth_test_span( GLcontext *ctx, struct sw_span *span)
{
+ const GLint x = span->x;
+ const GLint y = span->y;
+ const GLuint n = span->end;
SWcontext *swrast = SWRAST_CONTEXT(ctx);
+
+ ASSERT((span->arrayMask & SPAN_XY) == 0);
+ ASSERT(span->arrayMask & SPAN_Z);
+
if (swrast->Driver.ReadDepthSpan) {
/* hardware-based depth buffer */
GLdepth zbuffer[MAX_WIDTH];
GLuint passed;
(*swrast->Driver.ReadDepthSpan)(ctx, n, x, y, zbuffer);
- passed = depth_test_span32(ctx, n, x, y, zbuffer, z, mask);
- assert(swrast->Driver.WriteDepthSpan);
- (*swrast->Driver.WriteDepthSpan)(ctx, n, x, y, zbuffer, mask);
+ passed = depth_test_span32(ctx, n, zbuffer, span->array->z,
+ span->array->mask);
+ ASSERT(swrast->Driver.WriteDepthSpan);
+ (*swrast->Driver.WriteDepthSpan)(ctx, n, x, y, zbuffer,
+ span->array->mask);
+ if (passed < n)
+ span->writeAll = GL_FALSE;
return passed;
}
else {
+ GLuint passed;
/* software depth buffer */
if (ctx->Visual.depthBits <= 16) {
GLushort *zptr = (GLushort *) Z_ADDRESS16(ctx, x, y);
- GLuint passed = depth_test_span16(ctx, n, x, y, zptr, z, mask);
- return passed;
+ passed = depth_test_span16(ctx, n, zptr, span->array->z, span->array->mask);
}
else {
GLuint *zptr = (GLuint *) Z_ADDRESS32(ctx, x, y);
- GLuint passed = depth_test_span32(ctx, n, x, y, zptr, z, mask);
- return passed;
+ passed = depth_test_span32(ctx, n, zptr, span->array->z, span->array->mask);
}
+#if 1
+ if (passed < span->end) {
+ span->writeAll = GL_FALSE;
+ }
+#else
+ /* this causes a glDrawPixels(GL_DEPTH_COMPONENT) conformance failure */
+ if (passed < span->end) {
+ span->writeAll = GL_FALSE;
+ if (passed == 0) {
+ span->end = 0;
+ return 0;
+ }
+ while (span->end > 0 && span->mask[span->end - 1] == 0)
+ span->end --;
+ }
+#endif
+ return passed;
}
}
@@ -804,7 +828,7 @@ software_depth_test_pixels16( GLcontext *ctx, GLuint n,
break;
case GL_NEVER:
/* depth test never passes */
- BZERO(mask, n * sizeof(GLubyte));
+ _mesa_bzero(mask, n * sizeof(GLubyte));
break;
default:
_mesa_problem(ctx, "Bad depth func in software_depth_test_pixels");
@@ -1050,7 +1074,7 @@ software_depth_test_pixels32( GLcontext *ctx, GLuint n,
break;
case GL_NEVER:
/* depth test never passes */
- BZERO(mask, n * sizeof(GLubyte));
+ _mesa_bzero(mask, n * sizeof(GLubyte));
break;
default:
_mesa_problem(ctx, "Bad depth func in software_depth_test_pixels");
@@ -1284,7 +1308,7 @@ hardware_depth_test_pixels( GLcontext *ctx, GLuint n, GLdepth zbuffer[],
break;
case GL_NEVER:
/* depth test never passes */
- BZERO(mask, n * sizeof(GLubyte));
+ _mesa_bzero(mask, n * sizeof(GLubyte));
break;
default:
_mesa_problem(ctx, "Bad depth func in hardware_depth_test_pixels");
@@ -1293,15 +1317,19 @@ hardware_depth_test_pixels( GLcontext *ctx, GLuint n, GLdepth zbuffer[],
-void
-_mesa_depth_test_pixels( GLcontext *ctx,
- GLuint n, const GLint x[], const GLint y[],
- const GLdepth z[], GLubyte mask[] )
+static GLuint
+depth_test_pixels( GLcontext *ctx, struct sw_span *span )
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
+ const GLuint n = span->end;
+ const GLint *x = span->array->x;
+ const GLint *y = span->array->y;
+ const GLdepth *z = span->array->z;
+ GLubyte *mask = span->array->mask;
+
if (swrast->Driver.ReadDepthPixels) {
/* read depth values from hardware Z buffer */
- GLdepth zbuffer[PB_SIZE];
+ GLdepth zbuffer[MAX_WIDTH];
(*swrast->Driver.ReadDepthPixels)(ctx, n, x, y, zbuffer);
hardware_depth_test_pixels( ctx, n, zbuffer, z, mask );
@@ -1317,9 +1345,22 @@ _mesa_depth_test_pixels( GLcontext *ctx,
else
software_depth_test_pixels32(ctx, n, x, y, z, mask);
}
+ return n; /* not really correct, but OK */
}
+/**
+ * Apply depth (Z) buffer testing to the span.
+ * \return approx number of pixels that passed (only zero is reliable)
+ */
+GLuint
+_mesa_depth_test_span( GLcontext *ctx, struct sw_span *span)
+{
+ if (span->arrayMask & SPAN_XY)
+ return depth_test_pixels(ctx, span);
+ else
+ return depth_test_span(ctx, span);
+}
@@ -1328,7 +1369,7 @@ _mesa_depth_test_pixels( GLcontext *ctx,
/**********************************************************************/
-/*
+/**
* Read a span of depth values from the depth buffer.
* This function does clipping before calling the device driver function.
*/
@@ -1339,7 +1380,7 @@ _mesa_read_depth_span( GLcontext *ctx,
SWcontext *swrast = SWRAST_CONTEXT(ctx);
if (y < 0 || y >= (GLint) ctx->DrawBuffer->Height ||
- x + n <= 0 || x >= (GLint) ctx->DrawBuffer->Width) {
+ x + (GLint) n <= 0 || x >= (GLint) ctx->DrawBuffer->Width) {
/* span is completely outside framebuffer */
GLint i;
for (i = 0; i < n; i++)
@@ -1390,7 +1431,7 @@ _mesa_read_depth_span( GLcontext *ctx,
}
else {
/* no depth buffer */
- BZERO(depth, n * sizeof(GLfloat));
+ _mesa_bzero(depth, n * sizeof(GLfloat));
}
}
@@ -1398,7 +1439,7 @@ _mesa_read_depth_span( GLcontext *ctx,
-/*
+/**
* Return a span of depth values from the depth buffer as floats in [0,1].
* This is used for both hardware and software depth buffers.
* Input: n - how many pixels
@@ -1413,7 +1454,7 @@ _mesa_read_depth_span_float( GLcontext *ctx,
const GLfloat scale = 1.0F / ctx->DepthMaxF;
if (y < 0 || y >= (GLint) ctx->DrawBuffer->Height ||
- x + n <= 0 || x >= (GLint) ctx->DrawBuffer->Width) {
+ x + (GLint) n <= 0 || x >= (GLint) ctx->DrawBuffer->Width) {
/* span is completely outside framebuffer */
GLint i;
for (i = 0; i < n; i++)
@@ -1469,7 +1510,7 @@ _mesa_read_depth_span_float( GLcontext *ctx,
}
else {
/* no depth buffer */
- BZERO(depth, n * sizeof(GLfloat));
+ _mesa_bzero(depth, n * sizeof(GLfloat));
}
}
@@ -1481,9 +1522,10 @@ _mesa_read_depth_span_float( GLcontext *ctx,
-/*
+/**
* Allocate a new depth buffer. If there's already a depth buffer allocated
* it will be free()'d. The new depth buffer will be uniniitalized.
+ * This function is only called through Driver.alloc_depth_buffer.
*/
void
_mesa_alloc_depth_buffer( GLframebuffer *buffer )
@@ -1504,7 +1546,8 @@ _mesa_alloc_depth_buffer( GLframebuffer *buffer )
else
bytesPerValue = sizeof(GLuint);
- buffer->DepthBuffer = MESA_PBUFFER_ALLOC(buffer->Width * buffer->Height * bytesPerValue);
+ buffer->DepthBuffer = MESA_PBUFFER_ALLOC(buffer->Width * buffer->Height
+ * bytesPerValue);
if (!buffer->DepthBuffer) {
/* out of memory */
@@ -1518,9 +1561,7 @@ _mesa_alloc_depth_buffer( GLframebuffer *buffer )
}
-
-
-/*
+/**
* Clear the depth buffer. If the depth buffer doesn't exist yet we'll
* allocate it now.
* This function is only called through Driver.clear_depth_buffer.
@@ -1578,7 +1619,7 @@ _mesa_clear_depth_buffer( GLcontext *ctx )
const GLushort clearValue = (GLushort) (ctx->Depth.Clear * ctx->DepthMax);
if ((clearValue & 0xff) == (clearValue >> 8)) {
if (clearValue == 0) {
- BZERO(ctx->DrawBuffer->DepthBuffer,
+ _mesa_bzero(ctx->DrawBuffer->DepthBuffer,
2*ctx->DrawBuffer->Width*ctx->DrawBuffer->Height);
}
else {
@@ -1612,7 +1653,7 @@ _mesa_clear_depth_buffer( GLcontext *ctx )
/* >16 bit depth buffer */
const GLuint clearValue = (GLuint) (ctx->Depth.Clear * ctx->DepthMax);
if (clearValue == 0) {
- BZERO(ctx->DrawBuffer->DepthBuffer,
+ _mesa_bzero(ctx->DrawBuffer->DepthBuffer,
ctx->DrawBuffer->Width*ctx->DrawBuffer->Height*sizeof(GLuint));
}
else {
diff --git a/xc/extras/Mesa/src/swrast/s_depth.h b/xc/extras/Mesa/src/swrast/s_depth.h
index 9f04d727b..f1bd65e3a 100644
--- a/xc/extras/Mesa/src/swrast/s_depth.h
+++ b/xc/extras/Mesa/src/swrast/s_depth.h
@@ -1,8 +1,7 @@
-/* $Id: s_depth.h,v 1.1.1.1 2002/10/22 13:06:46 alanh Exp $ */
/*
* Mesa 3-D graphics library
- * Version: 4.0.2
+ * Version: 4.1
*
* Copyright (C) 1999-2002 Brian Paul All Rights Reserved.
*
@@ -37,14 +36,10 @@ extern GLvoid *
_mesa_zbuffer_address(GLcontext *ctx, GLint x, GLint y);
+
extern GLuint
-_mesa_depth_test_span( GLcontext *ctx, GLuint n, GLint x, GLint y,
- const GLdepth z[], GLubyte mask[] );
+_mesa_depth_test_span( GLcontext *ctx, struct sw_span *span);
-extern void
-_mesa_depth_test_pixels( GLcontext *ctx,
- GLuint n, const GLint x[], const GLint y[],
- const GLdepth z[], GLubyte mask[] );
extern void
diff --git a/xc/extras/Mesa/src/swrast/s_drawpix.c b/xc/extras/Mesa/src/swrast/s_drawpix.c
index 7f5ed8077..3bcee0fc6 100644
--- a/xc/extras/Mesa/src/swrast/s_drawpix.c
+++ b/xc/extras/Mesa/src/swrast/s_drawpix.c
@@ -1,8 +1,7 @@
-/* $Id: s_drawpix.c,v 1.1.1.1 2002/10/22 13:06:58 alanh Exp $ */
/*
* Mesa 3-D graphics library
- * Version: 4.0.3
+ * Version: 5.0
*
* Copyright (C) 1999-2002 Brian Paul All Rights Reserved.
*
@@ -31,13 +30,12 @@
#include "convolve.h"
#include "image.h"
#include "macros.h"
-#include "mem.h"
+#include "imports.h"
#include "mmath.h"
#include "pixel.h"
#include "s_context.h"
#include "s_drawpix.h"
-#include "s_fog.h"
#include "s_pixeltex.h"
#include "s_span.h"
#include "s_stencil.h"
@@ -103,15 +101,23 @@ fast_draw_pixels(GLcontext *ctx, GLint x, GLint y,
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
const struct gl_pixelstore_attrib *unpack = &ctx->Unpack;
- GLchan rgb[MAX_WIDTH][3];
- GLchan rgba[MAX_WIDTH][4];
+ struct sw_span span;
+
+ INIT_SPAN(span, GL_BITMAP, 0, 0, SPAN_RGBA);
if (!ctx->Current.RasterPosValid) {
return GL_TRUE; /* no-op */
}
- if ((SWRAST_CONTEXT(ctx)->_RasterMask&(~(SCISSOR_BIT|WINCLIP_BIT)))==0
- && ctx->Texture._ReallyEnabled == 0
+ if (ctx->Depth.Test)
+ _mesa_span_default_z(ctx, &span);
+ if (ctx->Fog.Enabled)
+ _mesa_span_default_fog(ctx, &span);
+ if (ctx->Texture._EnabledUnits)
+ _mesa_span_default_texcoords(ctx, &span);
+
+ if ((SWRAST_CONTEXT(ctx)->_RasterMask & ~CLIP_BIT) == 0
+ && ctx->Texture._EnabledUnits == 0
&& unpack->Alignment == 1
&& !unpack->SwapBytes
&& !unpack->LsbFirst) {
@@ -232,8 +238,11 @@ fast_draw_pixels(GLcontext *ctx, GLint x, GLint y,
/* with zooming */
GLint row;
for (row=0; row<drawHeight; row++) {
- _mesa_write_zoomed_rgba_span(ctx, drawWidth, destX, destY,
- zSpan, 0, (CONST GLchan (*)[4]) src, zoomY0);
+ span.x = destX;
+ span.y = destY;
+ span.end = drawWidth;
+ _mesa_write_zoomed_rgba_span(ctx, &span,
+ (CONST GLchan (*)[4]) src, zoomY0);
src += rowLength * 4;
destY++;
}
@@ -269,8 +278,11 @@ fast_draw_pixels(GLcontext *ctx, GLint x, GLint y,
/* with zooming */
GLint row;
for (row=0; row<drawHeight; row++) {
- _mesa_write_zoomed_rgb_span(ctx, drawWidth, destX, destY,
- zSpan, 0, (CONST GLchan (*)[3]) src, zoomY0);
+ span.x = destX;
+ span.y = destY;
+ span.end = drawWidth;
+ _mesa_write_zoomed_rgb_span(ctx, &span,
+ (CONST GLchan (*)[3]) src, zoomY0);
src += rowLength * 3;
destY++;
}
@@ -290,12 +302,12 @@ fast_draw_pixels(GLcontext *ctx, GLint x, GLint y,
for (row=0; row<drawHeight; row++) {
GLint i;
for (i=0;i<drawWidth;i++) {
- rgb[i][0] = src[i];
- rgb[i][1] = src[i];
- rgb[i][2] = src[i];
+ span.array->rgb[i][0] = src[i];
+ span.array->rgb[i][1] = src[i];
+ span.array->rgb[i][2] = src[i];
}
(*swrast->Driver.WriteRGBSpan)(ctx, drawWidth, destX, destY,
- (CONST GLchan (*)[3]) rgb, NULL);
+ (CONST GLchan (*)[3]) span.array->rgb, NULL);
src += rowLength;
destY++;
}
@@ -307,13 +319,13 @@ fast_draw_pixels(GLcontext *ctx, GLint x, GLint y,
for (row=0; row<drawHeight; row++) {
GLint i;
for (i=0;i<drawWidth;i++) {
- rgb[i][0] = src[i];
- rgb[i][1] = src[i];
- rgb[i][2] = src[i];
+ span.array->rgb[i][0] = src[i];
+ span.array->rgb[i][1] = src[i];
+ span.array->rgb[i][2] = src[i];
}
destY--;
(*swrast->Driver.WriteRGBSpan)(ctx, drawWidth, destX, destY,
- (CONST GLchan (*)[3]) rgb, NULL);
+ (CONST GLchan (*)[3]) span.array->rgb, NULL);
src += rowLength;
}
}
@@ -324,12 +336,15 @@ fast_draw_pixels(GLcontext *ctx, GLint x, GLint y,
for (row=0; row<drawHeight; row++) {
GLint i;
for (i=0;i<drawWidth;i++) {
- rgb[i][0] = src[i];
- rgb[i][1] = src[i];
- rgb[i][2] = src[i];
+ span.array->rgb[i][0] = src[i];
+ span.array->rgb[i][1] = src[i];
+ span.array->rgb[i][2] = src[i];
}
- _mesa_write_zoomed_rgb_span(ctx, drawWidth, destX, destY,
- zSpan, 0, (CONST GLchan (*)[3]) rgb, zoomY0);
+ span.x = destX;
+ span.y = destY;
+ span.end = drawWidth;
+ _mesa_write_zoomed_rgb_span(ctx, &span,
+ (CONST GLchan (*)[3]) span.array->rgb, zoomY0);
src += rowLength;
destY++;
}
@@ -350,13 +365,13 @@ fast_draw_pixels(GLcontext *ctx, GLint x, GLint y,
GLint i;
GLchan *ptr = src;
for (i=0;i<drawWidth;i++) {
- rgba[i][0] = *ptr;
- rgba[i][1] = *ptr;
- rgba[i][2] = *ptr++;
- rgba[i][3] = *ptr++;
+ span.array->rgba[i][0] = *ptr;
+ span.array->rgba[i][1] = *ptr;
+ span.array->rgba[i][2] = *ptr++;
+ span.array->rgba[i][3] = *ptr++;
}
(*swrast->Driver.WriteRGBASpan)(ctx, drawWidth, destX, destY,
- (CONST GLchan (*)[4]) rgba, NULL);
+ (CONST GLchan (*)[4]) span.array->rgba, NULL);
src += rowLength*2;
destY++;
}
@@ -369,14 +384,14 @@ fast_draw_pixels(GLcontext *ctx, GLint x, GLint y,
GLint i;
GLchan *ptr = src;
for (i=0;i<drawWidth;i++) {
- rgba[i][0] = *ptr;
- rgba[i][1] = *ptr;
- rgba[i][2] = *ptr++;
- rgba[i][3] = *ptr++;
+ span.array->rgba[i][0] = *ptr;
+ span.array->rgba[i][1] = *ptr;
+ span.array->rgba[i][2] = *ptr++;
+ span.array->rgba[i][3] = *ptr++;
}
destY--;
(*swrast->Driver.WriteRGBASpan)(ctx, drawWidth, destX, destY,
- (CONST GLchan (*)[4]) rgba, NULL);
+ (CONST GLchan (*)[4]) span.array->rgba, NULL);
src += rowLength*2;
}
}
@@ -388,13 +403,16 @@ fast_draw_pixels(GLcontext *ctx, GLint x, GLint y,
GLchan *ptr = src;
GLint i;
for (i=0;i<drawWidth;i++) {
- rgba[i][0] = *ptr;
- rgba[i][1] = *ptr;
- rgba[i][2] = *ptr++;
- rgba[i][3] = *ptr++;
+ span.array->rgba[i][0] = *ptr;
+ span.array->rgba[i][1] = *ptr;
+ span.array->rgba[i][2] = *ptr++;
+ span.array->rgba[i][3] = *ptr++;
}
- _mesa_write_zoomed_rgba_span(ctx, drawWidth, destX, destY,
- zSpan, 0, (CONST GLchan (*)[4]) rgba, zoomY0);
+ span.x = destX;
+ span.y = destY;
+ span.end = drawWidth;
+ _mesa_write_zoomed_rgba_span(ctx, &span,
+ (CONST GLchan (*)[4]) span.array->rgba, zoomY0);
src += rowLength*2;
destY++;
}
@@ -411,10 +429,9 @@ fast_draw_pixels(GLcontext *ctx, GLint x, GLint y,
GLint row;
for (row=0; row<drawHeight; row++) {
ASSERT(drawWidth < MAX_WIDTH);
- _mesa_map_ci8_to_rgba(ctx, drawWidth, src, rgba);
+ _mesa_map_ci8_to_rgba(ctx, drawWidth, src, span.array->rgba);
(*swrast->Driver.WriteRGBASpan)(ctx, drawWidth, destX, destY,
- (const GLchan (*)[4]) rgba,
- NULL);
+ (const GLchan (*)[4]) span.array->rgba, NULL);
src += rowLength;
destY++;
}
@@ -425,11 +442,10 @@ fast_draw_pixels(GLcontext *ctx, GLint x, GLint y,
GLint row;
for (row=0; row<drawHeight; row++) {
ASSERT(drawWidth < MAX_WIDTH);
- _mesa_map_ci8_to_rgba(ctx, drawWidth, src, rgba);
+ _mesa_map_ci8_to_rgba(ctx, drawWidth, src, span.array->rgba);
destY--;
(*swrast->Driver.WriteRGBASpan)(ctx, drawWidth, destX, destY,
- (CONST GLchan (*)[4]) rgba,
- NULL);
+ (CONST GLchan (*)[4]) span.array->rgba, NULL);
src += rowLength;
}
return GL_TRUE;
@@ -439,9 +455,12 @@ fast_draw_pixels(GLcontext *ctx, GLint x, GLint y,
GLint row;
for (row=0; row<drawHeight; row++) {
ASSERT(drawWidth < MAX_WIDTH);
- _mesa_map_ci8_to_rgba(ctx, drawWidth, src, rgba);
- _mesa_write_zoomed_rgba_span(ctx, drawWidth, destX, destY,
- zSpan, 0, (CONST GLchan (*)[4]) rgba, zoomY0);
+ _mesa_map_ci8_to_rgba(ctx, drawWidth, src, span.array->rgba);
+ span.x = destX;
+ span.y = destY;
+ span.end = drawWidth;
+ _mesa_write_zoomed_rgba_span(ctx, &span,
+ (CONST GLchan (*)[4]) span.array->rgba, zoomY0);
src += rowLength;
destY++;
}
@@ -489,47 +508,33 @@ draw_index_pixels( GLcontext *ctx, GLint x, GLint y,
{
const GLboolean zoom = ctx->Pixel.ZoomX!=1.0 || ctx->Pixel.ZoomY!=1.0;
const GLint desty = y;
- GLint row, drawWidth;
- GLdepth zspan[MAX_WIDTH];
- GLfloat fogSpan[MAX_WIDTH];
+ GLint row, drawWidth = (width > MAX_WIDTH) ? MAX_WIDTH : width;
+ struct sw_span span;
- drawWidth = (width > MAX_WIDTH) ? MAX_WIDTH : width;
-
- /* Fragment depth values */
- if (ctx->Depth.Test || ctx->Fog.Enabled) {
- GLdepth zval = (GLdepth) (ctx->Current.RasterPos[2] * ctx->DepthMaxF);
- GLfloat fog;
- GLint i;
+ INIT_SPAN(span, GL_BITMAP, drawWidth, 0, SPAN_INDEX);
- if (ctx->Fog.FogCoordinateSource == GL_FOG_COORDINATE_EXT)
- fog = _mesa_z_to_fogfactor(ctx, ctx->Current.RasterFogCoord);
- else
- fog = _mesa_z_to_fogfactor(ctx, ctx->Current.RasterDistance);
-
- for (i = 0; i < drawWidth; i++) {
- zspan[i] = zval;
- fogSpan[i] = fog;
- }
- }
+ if (ctx->Depth.Test)
+ _mesa_span_default_z(ctx, &span);
+ if (ctx->Fog.Enabled)
+ _mesa_span_default_fog(ctx, &span);
/*
* General solution
*/
for (row = 0; row < height; row++, y++) {
- GLuint indexes[MAX_WIDTH];
const GLvoid *source = _mesa_image_address(&ctx->Unpack,
pixels, width, height, GL_COLOR_INDEX, type, 0, row, 0);
- _mesa_unpack_index_span(ctx, drawWidth, GL_UNSIGNED_INT, indexes,
+ _mesa_unpack_index_span(ctx, drawWidth, GL_UNSIGNED_INT,
+ span.array->index,
type, source, &ctx->Unpack,
ctx->_ImageTransferState);
- if (zoom) {
- _mesa_write_zoomed_index_span(ctx, drawWidth, x, y, zspan, fogSpan,
- indexes, desty);
- }
- else {
- _mesa_write_index_span(ctx, drawWidth, x, y, zspan, fogSpan, indexes,
- NULL, GL_BITMAP);
- }
+ span.x = x;
+ span.y = y;
+ span.end = drawWidth;
+ if (zoom)
+ _mesa_write_zoomed_index_span(ctx, &span, desty);
+ else
+ _mesa_write_index_span(ctx, &span);
}
}
@@ -594,7 +599,6 @@ draw_stencil_pixels( GLcontext *ctx, GLint x, GLint y,
}
-
/*
* Do a glDrawPixels of depth values.
*/
@@ -606,9 +610,10 @@ draw_depth_pixels( GLcontext *ctx, GLint x, GLint y,
const GLboolean bias_or_scale = ctx->Pixel.DepthBias!=0.0 || ctx->Pixel.DepthScale!=1.0;
const GLboolean zoom = ctx->Pixel.ZoomX!=1.0 || ctx->Pixel.ZoomY!=1.0;
const GLint desty = y;
- GLchan rgba[MAX_WIDTH][4];
- GLuint ispan[MAX_WIDTH];
GLint drawWidth = (width > MAX_WIDTH) ? MAX_WIDTH : width;
+ struct sw_span span;
+
+ INIT_SPAN(span, GL_BITMAP, drawWidth, 0, SPAN_Z);
if (type != GL_BYTE
&& type != GL_UNSIGNED_BYTE
@@ -621,62 +626,53 @@ draw_depth_pixels( GLcontext *ctx, GLint x, GLint y,
return;
}
- /* Colors or indexes */
- if (ctx->Visual.rgbMode) {
- GLint i;
- GLint r, g, b, a;
- UNCLAMPED_FLOAT_TO_CHAN(r, ctx->Current.RasterColor[0]);
- UNCLAMPED_FLOAT_TO_CHAN(g, ctx->Current.RasterColor[1]);
- UNCLAMPED_FLOAT_TO_CHAN(b, ctx->Current.RasterColor[2]);
- UNCLAMPED_FLOAT_TO_CHAN(a, ctx->Current.RasterColor[3]);
- for (i = 0; i < drawWidth; i++) {
- rgba[i][RCOMP] = r;
- rgba[i][GCOMP] = g;
- rgba[i][BCOMP] = b;
- rgba[i][ACOMP] = a;
- }
- }
- else {
- GLint i;
- for (i = 0; i < drawWidth; i++) {
- ispan[i] = ctx->Current.RasterIndex;
- }
- }
+ _mesa_span_default_color(ctx, &span);
+
+ if (ctx->Fog.Enabled)
+ _mesa_span_default_fog(ctx, &span);
+ if (ctx->Texture._EnabledUnits)
+ _mesa_span_default_texcoords(ctx, &span);
if (type==GL_UNSIGNED_SHORT && ctx->Visual.depthBits == 16
&& !bias_or_scale && !zoom && ctx->Visual.rgbMode) {
/* Special case: directly write 16-bit depth values */
GLint row;
- for (row = 0; row < height; row++, y++) {
- GLdepth zspan[MAX_WIDTH];
+ span.x = x;
+ span.y = y;
+ span.end = drawWidth;
+ for (row = 0; row < height; row++, span.y++) {
const GLushort *zptr = (const GLushort *)
_mesa_image_address(&ctx->Unpack, pixels, width, height,
GL_DEPTH_COMPONENT, type, 0, row, 0);
GLint i;
- for (i = 0; i < width; i++)
- zspan[i] = zptr[i];
- _mesa_write_rgba_span(ctx, width, x, y, zspan, 0, rgba,
- NULL, GL_BITMAP);
+ for (i = 0; i < drawWidth; i++)
+ span.array->z[i] = zptr[i];
+ _mesa_write_rgba_span(ctx, &span);
}
}
else if (type==GL_UNSIGNED_INT && ctx->Visual.depthBits == 32
&& !bias_or_scale && !zoom && ctx->Visual.rgbMode) {
/* Special case: directly write 32-bit depth values */
GLint row;
- for (row = 0; row < height; row++, y++) {
+ span.x = x;
+ span.y = y;
+ span.end = drawWidth;
+ for (row = 0; row < height; row++, span.y++) {
const GLuint *zptr = (const GLuint *)
_mesa_image_address(&ctx->Unpack, pixels, width, height,
GL_DEPTH_COMPONENT, type, 0, row, 0);
- _mesa_write_rgba_span(ctx, width, x, y, zptr, 0, rgba,
- NULL, GL_BITMAP);
+ MEMCPY(span.array->z, zptr, drawWidth * sizeof(GLdepth));
+ _mesa_write_rgba_span(ctx, &span);
}
}
else {
/* General case */
GLint row;
- for (row = 0; row < height; row++, y++) {
+ span.x = x;
+ span.y = y;
+ span.end = drawWidth;
+ for (row = 0; row < height; row++, span.y++) {
GLfloat fspan[MAX_WIDTH];
- GLdepth zspan[MAX_WIDTH];
const GLvoid *src = _mesa_image_address(&ctx->Unpack,
pixels, width, height, GL_DEPTH_COMPONENT, type, 0, row, 0);
_mesa_unpack_depth_span( ctx, drawWidth, fspan, type, src,
@@ -686,31 +682,23 @@ draw_depth_pixels( GLcontext *ctx, GLint x, GLint y,
const GLfloat zs = ctx->DepthMaxF;
GLint i;
for (i = 0; i < drawWidth; i++) {
- zspan[i] = (GLdepth) (fspan[i] * zs + 0.5F);
+ span.array->z[i] = (GLdepth) (fspan[i] * zs + 0.5F);
}
}
-
if (ctx->Visual.rgbMode) {
if (zoom) {
- _mesa_write_zoomed_rgba_span(ctx, width, x, y, zspan, 0,
- (const GLchan (*)[4]) rgba, desty);
- }
- else {
- _mesa_write_rgba_span(ctx, width, x, y, zspan, 0,
- rgba, NULL, GL_BITMAP);
+ _mesa_write_zoomed_rgba_span(ctx, &span,
+ (const GLchan (*)[4]) span.array->rgba, desty);
}
+ else
+ _mesa_write_rgba_span(ctx, &span);
}
else {
- if (zoom) {
- _mesa_write_zoomed_index_span(ctx, width, x, y, zspan, 0,
- ispan, GL_BITMAP);
- }
- else {
- _mesa_write_index_span(ctx, width, x, y, zspan, 0,
- ispan, NULL, GL_BITMAP);
- }
+ if (zoom)
+ _mesa_write_zoomed_index_span(ctx, &span, desty);
+ else
+ _mesa_write_index_span(ctx, &span);
}
-
}
}
}
@@ -728,11 +716,12 @@ draw_rgba_pixels( GLcontext *ctx, GLint x, GLint y,
const struct gl_pixelstore_attrib *unpack = &ctx->Unpack;
const GLboolean zoom = ctx->Pixel.ZoomX!=1.0 || ctx->Pixel.ZoomY!=1.0;
const GLint desty = y;
- GLdepth zspan[MAX_WIDTH];
- GLfloat fogSpan[MAX_WIDTH];
GLboolean quickDraw;
GLfloat *convImage = NULL;
GLuint transferOps = ctx->_ImageTransferState;
+ struct sw_span span;
+
+ INIT_SPAN(span, GL_BITMAP, 0, 0, SPAN_RGBA);
if (!_mesa_is_legal_format_and_type(format, type)) {
_mesa_error(ctx, GL_INVALID_ENUM, "glDrawPixels(format or type)");
@@ -743,24 +732,12 @@ draw_rgba_pixels( GLcontext *ctx, GLint x, GLint y,
if (fast_draw_pixels(ctx, x, y, width, height, format, type, pixels))
return;
- /* Fragment depth values */
- if (ctx->Depth.Test || ctx->Fog.Enabled) {
- /* fill in array of z values */
- GLdepth z = (GLdepth) (ctx->Current.RasterPos[2] * ctx->DepthMaxF);
- GLfloat fog;
- GLint i;
-
- if (ctx->Fog.FogCoordinateSource == GL_FOG_COORDINATE_EXT)
- fog = _mesa_z_to_fogfactor(ctx, ctx->Current.RasterFogCoord);
- else
- fog = _mesa_z_to_fogfactor(ctx, ctx->Current.RasterDistance);
-
- for (i=0;i<width;i++) {
- zspan[i] = z;
- fogSpan[i] = fog;
- }
- }
-
+ if (ctx->Depth.Test)
+ _mesa_span_default_z(ctx, &span);
+ if (ctx->Fog.Enabled)
+ _mesa_span_default_fog(ctx, &span);
+ if (ctx->Texture._EnabledUnits)
+ _mesa_span_default_texcoords(ctx, &span);
if (SWRAST_CONTEXT(ctx)->_RasterMask == 0 && !zoom && x >= 0 && y >= 0
&& x + width <= (GLint) ctx->DrawBuffer->Width
@@ -827,61 +804,44 @@ draw_rgba_pixels( GLcontext *ctx, GLint x, GLint y,
* General solution
*/
{
- GLchan rgba[MAX_WIDTH][4];
GLint row;
if (width > MAX_WIDTH)
width = MAX_WIDTH;
+
for (row = 0; row < height; row++, y++) {
const GLvoid *source = _mesa_image_address(unpack,
pixels, width, height, format, type, 0, row, 0);
- _mesa_unpack_chan_color_span(ctx, width, GL_RGBA, (GLchan *) rgba,
+
+ _mesa_unpack_chan_color_span(ctx, width, GL_RGBA,
+ (GLchan *) span.array->rgba,
format, type, source, unpack,
transferOps);
+
if ((ctx->Pixel.MinMaxEnabled && ctx->MinMax.Sink) ||
(ctx->Pixel.HistogramEnabled && ctx->Histogram.Sink))
continue;
- if (ctx->Texture._ReallyEnabled && ctx->Pixel.PixelTextureEnabled) {
- GLchan primary_rgba[MAX_WIDTH][4];
- GLuint unit;
- DEFARRAY(GLfloat, s, MAX_WIDTH); /* mac 32k limitation */
- DEFARRAY(GLfloat, t, MAX_WIDTH);
- DEFARRAY(GLfloat, r, MAX_WIDTH);
- DEFARRAY(GLfloat, q, MAX_WIDTH);
- CHECKARRAY(s, return); /* mac 32k limitation */
- CHECKARRAY(t, return);
- CHECKARRAY(r, return);
- CHECKARRAY(q, return);
-
- /* XXX not sure how multitexture is supposed to work here */
- MEMCPY(primary_rgba, rgba, 4 * width * sizeof(GLchan));
-
- for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) {
- if (ctx->Texture.Unit[unit]._ReallyEnabled) {
- _mesa_pixeltexgen(ctx, width, (const GLchan (*)[4]) rgba,
- s, t, r, q);
- _swrast_texture_fragments(ctx, unit, width, s, t, r, NULL,
- (CONST GLchan (*)[4]) primary_rgba,
- rgba);
- }
- }
- UNDEFARRAY(s); /* mac 32k limitation */
- UNDEFARRAY(t);
- UNDEFARRAY(r);
- UNDEFARRAY(q);
+ if (ctx->Pixel.PixelTextureEnabled && ctx->Texture._EnabledUnits) {
+ span.end = width;
+ _swrast_pixel_texture(ctx, &span);
}
if (quickDraw) {
(*swrast->Driver.WriteRGBASpan)(ctx, width, x, y,
- (CONST GLchan (*)[4]) rgba, NULL);
+ (CONST GLchan (*)[4]) span.array->rgba, NULL);
}
else if (zoom) {
- _mesa_write_zoomed_rgba_span(ctx, width, x, y, zspan, fogSpan,
- (CONST GLchan (*)[4]) rgba, desty);
+ span.x = x;
+ span.y = y;
+ span.end = width;
+ _mesa_write_zoomed_rgba_span(ctx, &span,
+ (CONST GLchan (*)[4]) span.array->rgba, desty);
}
else {
- _mesa_write_rgba_span(ctx, (GLuint) width, x, y, zspan, fogSpan,
- rgba, NULL, GL_BITMAP);
+ span.x = x;
+ span.y = y;
+ span.end = width;
+ _mesa_write_rgba_span(ctx, &span);
}
}
}
@@ -907,7 +867,6 @@ _swrast_DrawPixels( GLcontext *ctx,
SWcontext *swrast = SWRAST_CONTEXT(ctx);
(void) unpack;
-
if (swrast->NewState)
_swrast_validate_derived( ctx );
@@ -945,3 +904,55 @@ _swrast_DrawPixels( GLcontext *ctx,
RENDER_FINISH(swrast,ctx);
}
+
+
+
+#if 0 /* experimental */
+/*
+ * Execute glDrawDepthPixelsMESA().
+ */
+void
+_swrast_DrawDepthPixelsMESA( GLcontext *ctx,
+ GLint x, GLint y,
+ GLsizei width, GLsizei height,
+ GLenum colorFormat, GLenum colorType,
+ const GLvoid *colors,
+ GLenum depthType, const GLvoid *depths,
+ const struct gl_pixelstore_attrib *unpack )
+{
+ SWcontext *swrast = SWRAST_CONTEXT(ctx);
+ (void) unpack;
+
+ if (swrast->NewState)
+ _swrast_validate_derived( ctx );
+
+ RENDER_START(swrast,ctx);
+
+ switch (colorFormat) {
+ case GL_COLOR_INDEX:
+ if (ctx->Visual.rgbMode)
+ draw_rgba_pixels(ctx, x,y, width, height, colorFormat, colorType, colors);
+ else
+ draw_index_pixels(ctx, x, y, width, height, colorType, colors);
+ break;
+ case GL_RED:
+ case GL_GREEN:
+ case GL_BLUE:
+ case GL_ALPHA:
+ case GL_LUMINANCE:
+ case GL_LUMINANCE_ALPHA:
+ case GL_RGB:
+ case GL_BGR:
+ case GL_RGBA:
+ case GL_BGRA:
+ case GL_ABGR_EXT:
+ draw_rgba_pixels(ctx, x, y, width, height, colorFormat, colorType, colors);
+ break;
+ default:
+ _mesa_error( ctx, GL_INVALID_ENUM,
+ "glDrawDepthPixelsMESA(colorFormat)" );
+ }
+
+ RENDER_FINISH(swrast,ctx);
+}
+#endif
diff --git a/xc/extras/Mesa/src/swrast/s_fog.c b/xc/extras/Mesa/src/swrast/s_fog.c
index b7e880528..2e2390c08 100644
--- a/xc/extras/Mesa/src/swrast/s_fog.c
+++ b/xc/extras/Mesa/src/swrast/s_fog.c
@@ -1,8 +1,7 @@
-/* $Id: s_fog.c,v 1.1.1.1 2002/10/22 13:06:41 alanh Exp $ */
/*
* Mesa 3-D graphics library
- * Version: 4.0.3
+ * Version: 4.1
*
* Copyright (C) 1999-2002 Brian Paul All Rights Reserved.
*
@@ -33,12 +32,12 @@
#include "s_context.h"
#include "s_fog.h"
-#include "s_pb.h"
+#include "s_span.h"
-/*
+/**
* Used to convert current raster distance to a fog factor in [0,1].
*/
GLfloat
@@ -63,67 +62,14 @@ _mesa_z_to_fogfactor(GLcontext *ctx, GLfloat z)
f = (GLfloat) exp(-(d * d * z * z));
return f;
default:
- _mesa_problem(ctx, "Bad fog mode in make_fog_coord");
+ _mesa_problem(ctx, "Bad fog mode in _mesa_z_to_fogfactor");
return 0.0;
}
}
-/*
- * Apply fog to an array of RGBA pixels.
- * Input: n - number of pixels
- * fog - array of fog factors in [0,1]
- * red, green, blue, alpha - pixel colors
- * Output: red, green, blue, alpha - fogged pixel colors
- */
-void
-_mesa_fog_rgba_pixels( const GLcontext *ctx,
- GLuint n,
- const GLfloat fog[],
- GLchan rgba[][4] )
-{
- GLuint i;
- GLchan rFog, gFog, bFog;
-
- UNCLAMPED_FLOAT_TO_CHAN(rFog, ctx->Fog.Color[RCOMP]);
- UNCLAMPED_FLOAT_TO_CHAN(gFog, ctx->Fog.Color[GCOMP]);
- UNCLAMPED_FLOAT_TO_CHAN(bFog, ctx->Fog.Color[BCOMP]);
-
- for (i = 0; i < n; i++) {
- const GLfloat f = fog[i];
- const GLfloat g = 1.0F - f;
- rgba[i][RCOMP] = (GLchan) (f * rgba[i][RCOMP] + g * rFog);
- rgba[i][GCOMP] = (GLchan) (f * rgba[i][GCOMP] + g * gFog);
- rgba[i][BCOMP] = (GLchan) (f * rgba[i][BCOMP] + g * bFog);
- }
-}
-
-
-
-/*
- * Apply fog to an array of color index pixels.
- * Input: n - number of pixels
- * fog - array of fog factors in [0,1]
- * index - pixel color indexes
- * Output: index - fogged pixel color indexes
- */
-void
-_mesa_fog_ci_pixels( const GLcontext *ctx,
- GLuint n, const GLfloat fog[], GLuint index[] )
-{
- GLuint idx = (GLuint) ctx->Fog.Index;
- GLuint i;
-
- for (i = 0; i < n; i++) {
- const GLfloat f = CLAMP(fog[i], 0.0F, 1.0F);
- index[i] = (GLuint) ((GLfloat) index[i] + (1.0F - f) * idx);
- }
-}
-
-
-
-/*
+/**
* Calculate fog factors (in [0,1]) from window z values
* Input: n - number of pixels
* z - array of integer depth values
@@ -138,9 +84,10 @@ compute_fog_factors_from_z( const GLcontext *ctx,
const GLdepth z[],
GLfloat fogFact[] )
{
- const GLboolean ortho = (ctx->ProjectionMatrix.m[15] != 0.0F);
- const GLfloat p10 = ctx->ProjectionMatrix.m[10];
- const GLfloat p14 = ctx->ProjectionMatrix.m[14];
+ const GLfloat *proj = ctx->ProjectionMatrixStack.Top->m;
+ const GLboolean ortho = (proj[15] != 0.0F);
+ const GLfloat p10 = proj[10];
+ const GLfloat p14 = proj[14];
const GLfloat tz = ctx->Viewport._WindowMap.m[MAT_TZ];
GLfloat szInv;
GLuint i;
@@ -267,37 +214,101 @@ compute_fog_factors_from_z( const GLcontext *ctx,
}
-/*
- * Apply fog to an array of RGBA pixels.
- * Input: n - number of pixels
- * z - array of integer depth values
- * red, green, blue, alpha - pixel colors
- * Output: red, green, blue, alpha - fogged pixel colors
+
+/**
+ * Apply fog to a span of RGBA pixels.
+ * The fog factors are either in the span->array->fog or stored as base/step.
+ * These are fog _factors_, not fog coords. Fog coords were converted to
+ * fog factors per vertex.
*/
void
-_mesa_depth_fog_rgba_pixels( const GLcontext *ctx,
- GLuint n, const GLdepth z[], GLchan rgba[][4] )
+_mesa_fog_rgba_span( const GLcontext *ctx, struct sw_span *span )
{
- GLfloat fogFact[PB_SIZE];
- ASSERT(n <= PB_SIZE);
- compute_fog_factors_from_z( ctx, n, z, fogFact );
- _mesa_fog_rgba_pixels( ctx, n, fogFact, rgba );
+ const SWcontext *swrast = SWRAST_CONTEXT(ctx);
+ const GLuint n = span->end;
+ GLchan (*rgba)[4] = (GLchan (*)[4]) span->array->rgba;
+ GLchan rFog, gFog, bFog;
+
+ ASSERT(ctx->Fog.Enabled);
+ ASSERT((span->interpMask | span->arrayMask) & SPAN_FOG);
+ ASSERT(span->arrayMask & SPAN_RGBA);
+
+ UNCLAMPED_FLOAT_TO_CHAN(rFog, ctx->Fog.Color[RCOMP]);
+ UNCLAMPED_FLOAT_TO_CHAN(gFog, ctx->Fog.Color[GCOMP]);
+ UNCLAMPED_FLOAT_TO_CHAN(bFog, ctx->Fog.Color[BCOMP]);
+
+ if (swrast->_PreferPixelFog) {
+ /* compute fog factor from each fragment's Z value */
+ if ((span->interpMask & SPAN_Z) && (span->arrayMask & SPAN_Z) == 0)
+ _mesa_span_interpolate_z(ctx, span);
+ compute_fog_factors_from_z(ctx, n, span->array->z, span->array->fog);
+ span->arrayMask |= SPAN_FOG;
+ }
+
+ if (span->arrayMask & SPAN_FOG) {
+ /* use fog array in span */
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ const GLfloat fog = span->array->fog[i];
+ const GLfloat oneMinusFog = 1.0F - fog;
+ rgba[i][RCOMP] = (GLchan) (fog * rgba[i][RCOMP] + oneMinusFog * rFog);
+ rgba[i][GCOMP] = (GLchan) (fog * rgba[i][GCOMP] + oneMinusFog * gFog);
+ rgba[i][BCOMP] = (GLchan) (fog * rgba[i][BCOMP] + oneMinusFog * bFog);
+ }
+ }
+ else {
+ /* interpolate fog factors */
+ GLfloat fog = span->fog, dFog = span->fogStep;
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ const GLfloat oneMinusFog = 1.0F - fog;
+ rgba[i][RCOMP] = (GLchan) (fog * rgba[i][RCOMP] + oneMinusFog * rFog);
+ rgba[i][GCOMP] = (GLchan) (fog * rgba[i][GCOMP] + oneMinusFog * gFog);
+ rgba[i][BCOMP] = (GLchan) (fog * rgba[i][BCOMP] + oneMinusFog * bFog);
+ fog += dFog;
+ }
+ }
}
-/*
- * Apply fog to an array of color index pixels.
- * Input: n - number of pixels
- * z - array of integer depth values
- * index - pixel color indexes
- * Output: index - fogged pixel color indexes
+/**
+ * As above, but color index mode.
*/
void
-_mesa_depth_fog_ci_pixels( const GLcontext *ctx,
- GLuint n, const GLdepth z[], GLuint index[] )
+_mesa_fog_ci_span( const GLcontext *ctx, struct sw_span *span )
{
- GLfloat fogFact[PB_SIZE];
- ASSERT(n <= PB_SIZE);
- compute_fog_factors_from_z( ctx, n, z, fogFact );
- _mesa_fog_ci_pixels( ctx, n, fogFact, index );
+ const SWcontext *swrast = SWRAST_CONTEXT(ctx);
+ const GLuint n = span->end;
+ GLuint *index = span->array->index;
+
+ ASSERT(ctx->Fog.Enabled);
+ ASSERT(span->arrayMask & SPAN_INDEX);
+ ASSERT((span->interpMask | span->arrayMask) & SPAN_FOG);
+
+ if (swrast->_PreferPixelFog) {
+ /* compute fog factor from each fragment's Z value */
+ if ((span->interpMask & SPAN_Z) && (span->arrayMask & SPAN_Z) == 0)
+ _mesa_span_interpolate_z(ctx, span);
+ compute_fog_factors_from_z(ctx, n, span->array->z, span->array->fog);
+ span->arrayMask |= SPAN_FOG;
+ }
+
+ if (span->arrayMask & SPAN_FOG) {
+ const GLuint idx = (GLuint) ctx->Fog.Index;
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ const GLfloat f = CLAMP(span->array->fog[i], 0.0F, 1.0F);
+ index[i] = (GLuint) ((GLfloat) index[i] + (1.0F - f) * idx);
+ }
+ }
+ else {
+ GLfloat fog = span->fog, dFog = span->fogStep;
+ const GLuint idx = (GLuint) ctx->Fog.Index;
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ const GLfloat f = CLAMP(fog, 0.0F, 1.0F);
+ index[i] = (GLuint) ((GLfloat) index[i] + (1.0F - f) * idx);
+ fog += dFog;
+ }
+ }
}
diff --git a/xc/extras/Mesa/src/swrast/s_fog.h b/xc/extras/Mesa/src/swrast/s_fog.h
index a3c35759c..6e23647d1 100644
--- a/xc/extras/Mesa/src/swrast/s_fog.h
+++ b/xc/extras/Mesa/src/swrast/s_fog.h
@@ -1,10 +1,9 @@
-/* $Id: s_fog.h,v 1.1.1.1 2002/10/22 13:06:41 alanh Exp $ */
/*
* Mesa 3-D graphics library
- * Version: 3.5
+ * Version: 4.1
*
- * Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
+ * Copyright (C) 1999-2002 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -36,29 +35,11 @@
extern GLfloat
_mesa_z_to_fogfactor(GLcontext *ctx, GLfloat z);
-
-extern void
-_mesa_fog_rgba_pixels( const GLcontext *ctx,
- GLuint n, const GLfloat fog[],
- GLchan rgba[][4] );
-
-extern void
-_mesa_fog_ci_pixels( const GLcontext *ctx,
- GLuint n, const GLfloat fog[], GLuint indx[] );
-
-extern void
-_mesa_win_fog_coords_from_z( const GLcontext *ctx,
- GLuint n,
- const GLdepth z[],
- GLfloat fogcoord[] );
-
extern void
-_mesa_depth_fog_rgba_pixels( const GLcontext *ctx,
- GLuint n, const GLdepth z[], GLchan rgba[][4] );
+_mesa_fog_rgba_span( const GLcontext *ctx, struct sw_span *span );
extern void
-_mesa_depth_fog_ci_pixels( const GLcontext *ctx,
- GLuint n, const GLdepth z[], GLuint index[] );
+_mesa_fog_ci_span( const GLcontext *ctx, struct sw_span *span );
#endif
diff --git a/xc/extras/Mesa/src/swrast/s_imaging.c b/xc/extras/Mesa/src/swrast/s_imaging.c
index 495ef3197..4b5438f88 100644
--- a/xc/extras/Mesa/src/swrast/s_imaging.c
+++ b/xc/extras/Mesa/src/swrast/s_imaging.c
@@ -1,8 +1,7 @@
-/* $Id: s_imaging.c,v 1.1.1.1 2002/10/22 13:06:48 alanh Exp $ */
/*
* Mesa 3-D graphics library
- * Version: 4.0.3
+ * Version: 4.1
*
* Copyright (C) 1999-2002 Brian Paul All Rights Reserved.
*
@@ -37,12 +36,10 @@ _swrast_CopyColorTable( GLcontext *ctx,
GLenum target, GLenum internalformat,
GLint x, GLint y, GLsizei width)
{
- SWcontext *swrast = SWRAST_CONTEXT(ctx);
GLchan data[MAX_WIDTH][4];
/* Select buffer to read from */
- (*swrast->Driver.SetReadBuffer)( ctx, ctx->ReadBuffer,
- ctx->Pixel.DriverReadBuffer );
+ _swrast_use_read_buffer(ctx);
if (width > MAX_WIDTH)
width = MAX_WIDTH;
@@ -51,8 +48,7 @@ _swrast_CopyColorTable( GLcontext *ctx,
_mesa_read_rgba_span( ctx, ctx->ReadBuffer, width, x, y, data );
/* Restore reading from draw buffer (the default) */
- (*swrast->Driver.SetReadBuffer)( ctx, ctx->DrawBuffer,
- ctx->Color.DriverDrawBuffer );
+ _swrast_use_draw_buffer(ctx);
glColorTable(target, internalformat, width, GL_RGBA, CHAN_TYPE, data);
}
@@ -61,12 +57,10 @@ void
_swrast_CopyColorSubTable( GLcontext *ctx,GLenum target, GLsizei start,
GLint x, GLint y, GLsizei width)
{
- SWcontext *swrast = SWRAST_CONTEXT(ctx);
GLchan data[MAX_WIDTH][4];
/* Select buffer to read from */
- (*swrast->Driver.SetReadBuffer)( ctx, ctx->ReadBuffer,
- ctx->Pixel.DriverReadBuffer );
+ _swrast_use_read_buffer(ctx);
if (width > MAX_WIDTH)
width = MAX_WIDTH;
@@ -75,8 +69,7 @@ _swrast_CopyColorSubTable( GLcontext *ctx,GLenum target, GLsizei start,
_mesa_read_rgba_span( ctx, ctx->ReadBuffer, width, x, y, data );
/* Restore reading from draw buffer (the default) */
- (*swrast->Driver.SetReadBuffer)( ctx, ctx->DrawBuffer,
- ctx->Color.DriverDrawBuffer );
+ _swrast_use_draw_buffer(ctx);
glColorSubTable(target, start, width, GL_RGBA, CHAN_TYPE, data);
}
@@ -90,6 +83,9 @@ _swrast_CopyConvolutionFilter1D(GLcontext *ctx, GLenum target,
SWcontext *swrast = SWRAST_CONTEXT(ctx);
GLchan rgba[MAX_CONVOLUTION_WIDTH][4];
+ /* Select buffer to read from */
+ _swrast_use_read_buffer(ctx);
+
RENDER_START( swrast, ctx );
/* read the data from framebuffer */
@@ -98,6 +94,9 @@ _swrast_CopyConvolutionFilter1D(GLcontext *ctx, GLenum target,
RENDER_FINISH( swrast, ctx );
+ /* Restore reading from draw buffer (the default) */
+ _swrast_use_draw_buffer(ctx);
+
/* store as convolution filter */
glConvolutionFilter1D(target, internalFormat, width,
GL_RGBA, CHAN_TYPE, rgba);
@@ -114,6 +113,9 @@ _swrast_CopyConvolutionFilter2D(GLcontext *ctx, GLenum target,
GLchan rgba[MAX_CONVOLUTION_HEIGHT][MAX_CONVOLUTION_WIDTH][4];
GLint i;
+ /* Select buffer to read from */
+ _swrast_use_read_buffer(ctx);
+
RENDER_START(swrast,ctx);
/* read pixels from framebuffer */
@@ -124,6 +126,9 @@ _swrast_CopyConvolutionFilter2D(GLcontext *ctx, GLenum target,
RENDER_FINISH(swrast,ctx);
+ /* Restore reading from draw buffer (the default) */
+ _swrast_use_draw_buffer(ctx);
+
/*
* HACK: save & restore context state so we can store this as a
* convolution filter via the GL api. Doesn't call any callbacks
diff --git a/xc/extras/Mesa/src/swrast/s_lines.c b/xc/extras/Mesa/src/swrast/s_lines.c
index ec8c343e3..eabfdcce0 100644
--- a/xc/extras/Mesa/src/swrast/s_lines.c
+++ b/xc/extras/Mesa/src/swrast/s_lines.c
@@ -1,10 +1,9 @@
-/* $Id: s_lines.c,v 1.1.1.1 2002/10/22 13:06:48 alanh Exp $ */
/*
* Mesa 3-D graphics library
- * Version: 3.5
+ * Version: 5.0
*
- * Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
+ * Copyright (C) 1999-2002 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"),
@@ -30,334 +29,294 @@
#include "macros.h"
#include "mmath.h"
#include "s_aaline.h"
-#include "s_pb.h"
#include "s_context.h"
#include "s_depth.h"
-#include "s_lines.h"
#include "s_feedback.h"
+#include "s_lines.h"
+#include "s_span.h"
+/*
+ * Init the mask[] array to implement a line stipple.
+ */
+static void
+compute_stipple_mask( GLcontext *ctx, GLuint len, GLubyte mask[] )
+{
+ SWcontext *swrast = SWRAST_CONTEXT(ctx);
+ GLuint i;
-/**********************************************************************/
-/***** Rasterization *****/
-/**********************************************************************/
+ for (i = 0; i < len; i++) {
+ GLuint bit = (swrast->StippleCounter / ctx->Line.StippleFactor) & 0xf;
+ if ((1 << bit) & ctx->Line.StipplePattern) {
+ mask[i] = GL_TRUE;
+ }
+ else {
+ mask[i] = GL_FALSE;
+ }
+ swrast->StippleCounter++;
+ }
+}
/*
- * There are 4 pairs (RGBA, CI) of line drawing functions:
- * 1. simple: width=1 and no special rasterization functions (fastest)
- * 2. flat: width=1, non-stippled, flat-shaded, any raster operations
- * 3. smooth: width=1, non-stippled, smooth-shaded, any raster operations
- * 4. general: any other kind of line (slowest)
+ * To draw a wide line we can simply redraw the span N times, side by side.
*/
-
-
-/* Flat, color index line */
-static void flat_ci_line( GLcontext *ctx,
- const SWvertex *vert0,
- const SWvertex *vert1 )
+static void
+draw_wide_line( GLcontext *ctx, struct sw_span *span, GLboolean xMajor )
{
- struct pixel_buffer *PB = SWRAST_CONTEXT(ctx)->PB;
+ GLint width, start;
- PB_SET_INDEX( PB, vert0->index );
+ ASSERT(span->end < MAX_WIDTH);
-#define INTERP_XY 1
-#define PLOT(X,Y) PB_WRITE_PIXEL(PB, X, Y, 0, 0);
+ width = (GLint) CLAMP( ctx->Line.Width, MIN_LINE_WIDTH, MAX_LINE_WIDTH );
-#include "s_linetemp.h"
-
- _mesa_flush_pb(ctx);
+ if (width & 1)
+ start = width / 2;
+ else
+ start = width / 2 - 1;
+
+ if (xMajor) {
+ GLint *y = span->array->y;
+ GLuint i;
+ GLint w;
+ for (w = 0; w < width; w++) {
+ if (w == 0) {
+ for (i = 0; i < span->end; i++)
+ y[i] -= start;
+ }
+ else {
+ for (i = 0; i < span->end; i++)
+ y[i]++;
+ }
+ if ((span->interpMask | span->arrayMask) & SPAN_TEXTURE)
+ _mesa_write_texture_span(ctx, span);
+ else if ((span->interpMask | span->arrayMask) & SPAN_RGBA)
+ _mesa_write_rgba_span(ctx, span);
+ else
+ _mesa_write_index_span(ctx, span);
+ }
+ }
+ else {
+ GLint *x = span->array->x;
+ GLuint i;
+ GLint w;
+ for (w = 0; w < width; w++) {
+ if (w == 0) {
+ for (i = 0; i < span->end; i++)
+ x[i] -= start;
+ }
+ else {
+ for (i = 0; i < span->end; i++)
+ x[i]++;
+ }
+ if ((span->interpMask | span->arrayMask) & SPAN_TEXTURE)
+ _mesa_write_texture_span(ctx, span);
+ else if ((span->interpMask | span->arrayMask) & SPAN_RGBA)
+ _mesa_write_rgba_span(ctx, span);
+ else
+ _mesa_write_index_span(ctx, span);
+ }
+ }
}
-/* Flat, color index line with Z interpolation/testing */
-static void flat_ci_z_line( GLcontext *ctx,
- const SWvertex *vert0,
- const SWvertex *vert1 )
+/**********************************************************************/
+/***** Rasterization *****/
+/**********************************************************************/
+
+
+/* Flat, color index line */
+static void flat_ci_line( GLcontext *ctx,
+ const SWvertex *vert0,
+ const SWvertex *vert1 )
{
- struct pixel_buffer *PB = SWRAST_CONTEXT(ctx)->PB;
- PB_SET_INDEX( PB, vert0->index );
+ GLint *x, *y;
+ struct sw_span span;
+
+ ASSERT(ctx->Light.ShadeModel == GL_FLAT);
+ ASSERT(!ctx->Line.StippleFlag);
+ ASSERT(ctx->Line.Width == 1.0F);
+
+ INIT_SPAN(span, GL_LINE, 0, SPAN_INDEX, SPAN_XY);
+ span.index = IntToFixed(vert1->index);
+ span.indexStep = 0;
+ x = span.array->x;
+ y = span.array->y;
#define INTERP_XY 1
-#define INTERP_Z 1
-#define INTERP_FOG 1
-#define PLOT(X,Y) PB_WRITE_PIXEL(PB, X, Y, Z, fog0);
+#define PLOT(X,Y) \
+ { \
+ x[span.end] = X; \
+ y[span.end] = Y; \
+ span.end++; \
+ }
#include "s_linetemp.h"
- _mesa_flush_pb(ctx);
+ _mesa_write_index_span(ctx, &span);
}
-
/* Flat-shaded, RGBA line */
static void flat_rgba_line( GLcontext *ctx,
const SWvertex *vert0,
const SWvertex *vert1 )
{
- const GLchan *color = vert1->color;
- struct pixel_buffer *PB = SWRAST_CONTEXT(ctx)->PB;
- PB_SET_COLOR( PB, color[0], color[1], color[2], color[3] );
+ struct sw_span span;
+ GLint *x, *y;
+
+ ASSERT(ctx->Light.ShadeModel == GL_FLAT);
+ ASSERT(!ctx->Line.StippleFlag);
+ ASSERT(ctx->Line.Width == 1.0F);
+
+ INIT_SPAN(span, GL_LINE, 0, SPAN_RGBA, SPAN_XY);
+ span.red = ChanToFixed(vert1->color[0]);
+ span.green = ChanToFixed(vert1->color[1]);
+ span.blue = ChanToFixed(vert1->color[2]);
+ span.alpha = ChanToFixed(vert1->color[3]);
+ span.redStep = 0;
+ span.greenStep = 0;
+ span.blueStep = 0;
+ span.alphaStep = 0;
+ x = span.array->x;
+ y = span.array->y;
#define INTERP_XY 1
-#define PLOT(X,Y) PB_WRITE_PIXEL(PB, X, Y, 0, 0);
-
-#include "s_linetemp.h"
-
- _mesa_flush_pb(ctx);
-}
-
-
-
-/* Flat-shaded, RGBA line with Z interpolation/testing */
-static void flat_rgba_z_line( GLcontext *ctx,
- const SWvertex *vert0,
- const SWvertex *vert1 )
-{
- const GLchan *color = vert1->color;
- struct pixel_buffer *PB = SWRAST_CONTEXT(ctx)->PB;
- PB_SET_COLOR( PB, color[0], color[1], color[2], color[3] );
-
-#define INTERP_XY 1
-#define INTERP_Z 1
-#define INTERP_FOG 1
-#define PLOT(X,Y) PB_WRITE_PIXEL(PB, X, Y, Z, fog0);
+#define PLOT(X,Y) \
+ { \
+ x[span.end] = X; \
+ y[span.end] = Y; \
+ span.end++; \
+ }
#include "s_linetemp.h"
- _mesa_flush_pb(ctx);
+ _mesa_write_rgba_span(ctx, &span);
}
-
/* Smooth shaded, color index line */
static void smooth_ci_line( GLcontext *ctx,
const SWvertex *vert0,
const SWvertex *vert1 )
{
- struct pixel_buffer *PB = SWRAST_CONTEXT(ctx)->PB;
- GLint count = PB->count;
- GLint *pbx = PB->x;
- GLint *pby = PB->y;
- GLuint *pbi = PB->index;
+ struct sw_span span;
+ GLint *x, *y;
+ GLuint *index;
- PB->mono = GL_FALSE;
+ ASSERT(ctx->Light.ShadeModel == GL_SMOOTH);
+ ASSERT(!ctx->Line.StippleFlag);
+ ASSERT(ctx->Line.Width == 1.0F);
-#define INTERP_XY 1
-#define INTERP_INDEX 1
-
-#define PLOT(X,Y) \
- pbx[count] = X; \
- pby[count] = Y; \
- pbi[count] = I; \
- count++;
-
-#include "s_linetemp.h"
-
- PB->count = count;
- _mesa_flush_pb(ctx);
-}
-
-
-
-/* Smooth shaded, color index line with Z interpolation/testing */
-static void smooth_ci_z_line( GLcontext *ctx,
- const SWvertex *vert0,
- const SWvertex *vert1 )
-{
- struct pixel_buffer *PB = SWRAST_CONTEXT(ctx)->PB;
- GLint count = PB->count;
- GLint *pbx = PB->x;
- GLint *pby = PB->y;
- GLdepth *pbz = PB->z;
- GLuint *pbi = PB->index;
-
- PB->mono = GL_FALSE;
+ INIT_SPAN(span, GL_LINE, 0, 0, SPAN_XY | SPAN_INDEX);
+ x = span.array->x;
+ y = span.array->y;
+ index = span.array->index;
#define INTERP_XY 1
-#define INTERP_Z 1
-#define INTERP_FOG 1
#define INTERP_INDEX 1
-
#define PLOT(X,Y) \
- pbx[count] = X; \
- pby[count] = Y; \
- pbz[count] = Z; \
- pbi[count] = I; \
- count++;
+ { \
+ x[span.end] = X; \
+ y[span.end] = Y; \
+ index[span.end] = I; \
+ span.end++; \
+ }
#include "s_linetemp.h"
- PB->count = count;
- _mesa_flush_pb(ctx);
+ _mesa_write_index_span(ctx, &span);
}
-
/* Smooth-shaded, RGBA line */
static void smooth_rgba_line( GLcontext *ctx,
const SWvertex *vert0,
const SWvertex *vert1 )
{
- struct pixel_buffer *PB = SWRAST_CONTEXT(ctx)->PB;
- GLint count = PB->count;
- GLint *pbx = PB->x;
- GLint *pby = PB->y;
- GLchan (*pbrgba)[4] = PB->rgba;
-
- PB->mono = GL_FALSE;
-
-#define INTERP_XY 1
-#define INTERP_RGB 1
-#define INTERP_ALPHA 1
-
-#define PLOT(X,Y) \
- pbx[count] = X; \
- pby[count] = Y; \
- pbrgba[count][RCOMP] = FixedToInt(r0); \
- pbrgba[count][GCOMP] = FixedToInt(g0); \
- pbrgba[count][BCOMP] = FixedToInt(b0); \
- pbrgba[count][ACOMP] = FixedToInt(a0); \
- count++;
-
-#include "s_linetemp.h"
-
- PB->count = count;
- _mesa_flush_pb(ctx);
-}
-
-
-
-/* Smooth-shaded, RGBA line with Z interpolation/testing */
-static void smooth_rgba_z_line( GLcontext *ctx,
- const SWvertex *vert0,
- const SWvertex *vert1 )
-{
- struct pixel_buffer *PB = SWRAST_CONTEXT(ctx)->PB;
- GLint count = PB->count;
- GLint *pbx = PB->x;
- GLint *pby = PB->y;
- GLdepth *pbz = PB->z;
- GLfloat *pbfog = PB->fog;
- GLchan (*pbrgba)[4] = PB->rgba;
+ struct sw_span span;
+ GLint *x, *y;
+ GLchan (*rgba)[4];
+ ASSERT(ctx->Light.ShadeModel == GL_SMOOTH);
+ ASSERT(!ctx->Line.StippleFlag);
+ ASSERT(ctx->Line.Width == 1.0F);
- PB->mono = GL_FALSE;
+ INIT_SPAN(span, GL_LINE, 0, 0, SPAN_XY | SPAN_RGBA);
+ x = span.array->x;
+ y = span.array->y;
+ rgba = span.array->rgba;
#define INTERP_XY 1
-#define INTERP_Z 1
-#define INTERP_FOG 1
#define INTERP_RGB 1
#define INTERP_ALPHA 1
-
#define PLOT(X,Y) \
- pbx[count] = X; \
- pby[count] = Y; \
- pbz[count] = Z; \
- pbfog[count] = fog0; \
- pbrgba[count][RCOMP] = FixedToInt(r0); \
- pbrgba[count][GCOMP] = FixedToInt(g0); \
- pbrgba[count][BCOMP] = FixedToInt(b0); \
- pbrgba[count][ACOMP] = FixedToInt(a0); \
- count++;
+ { \
+ x[span.end] = X; \
+ y[span.end] = Y; \
+ rgba[span.end][RCOMP] = FixedToInt(r0); \
+ rgba[span.end][GCOMP] = FixedToInt(g0); \
+ rgba[span.end][BCOMP] = FixedToInt(b0); \
+ rgba[span.end][ACOMP] = FixedToInt(a0); \
+ span.end++; \
+ }
#include "s_linetemp.h"
- PB->count = count;
- _mesa_flush_pb(ctx);
+ _mesa_write_rgba_span(ctx, &span);
}
-#define CHECK_FULL(count) \
- if (count >= PB_SIZE-MAX_WIDTH) { \
- PB->count = count; \
- _mesa_flush_pb(ctx); \
- count = PB->count; \
- }
-
-
-
/* Smooth shaded, color index, any width, maybe stippled */
static void general_smooth_ci_line( GLcontext *ctx,
const SWvertex *vert0,
const SWvertex *vert1 )
{
- struct pixel_buffer *PB = SWRAST_CONTEXT(ctx)->PB;
- GLint count = PB->count;
- GLint *pbx = PB->x;
- GLint *pby = PB->y;
- GLdepth *pbz = PB->z;
- GLfloat *pbfog = PB->fog;
- GLuint *pbi = PB->index;
-
- PB->mono = GL_FALSE;
-
- if (ctx->Line.StippleFlag) {
- /* stippled */
+ GLboolean xMajor = GL_FALSE;
+ struct sw_span span;
+ GLint *x, *y;
+ GLdepth *z;
+ GLfloat *fog;
+ GLuint *index;
+
+ ASSERT(ctx->Light.ShadeModel == GL_SMOOTH);
+
+ INIT_SPAN(span, GL_LINE, 0, 0,
+ SPAN_XY | SPAN_Z | SPAN_FOG | SPAN_INDEX);
+ x = span.array->x;
+ y = span.array->y;
+ z = span.array->z;
+ fog = span.array->fog;
+ index = span.array->index;
+
+#define SET_XMAJOR 1
#define INTERP_XY 1
#define INTERP_Z 1
#define INTERP_FOG 1
#define INTERP_INDEX 1
-#define WIDE 1
-#define STIPPLE 1
#define PLOT(X,Y) \
- pbx[count] = X; \
- pby[count] = Y; \
- pbz[count] = Z; \
- pbfog[count] = fog0; \
- pbi[count] = I; \
- count++; \
- CHECK_FULL(count);
-#include "s_linetemp.h"
+ { \
+ x[span.end] = X; \
+ y[span.end] = Y; \
+ z[span.end] = Z; \
+ fog[span.end] = fog0; \
+ index[span.end] = I; \
+ span.end++; \
}
- else {
- /* unstippled */
- if (ctx->Line.Width==2.0F) {
- /* special case: unstippled and width=2 */
-#define INTERP_XY 1
-#define INTERP_Z 1
-#define INTERP_FOG 1
-#define INTERP_INDEX 1
-#define XMAJOR_PLOT(X,Y) \
- pbx[count] = X; pbx[count+1] = X; \
- pby[count] = Y; pby[count+1] = Y+1; \
- pbz[count] = Z; pbz[count+1] = Z; \
- pbfog[count] = fog0; pbfog[count+1] = fog0; \
- pbi[count] = I; pbi[count+1] = I; \
- count += 2; \
- CHECK_FULL(count);
-#define YMAJOR_PLOT(X,Y) \
- pbx[count] = X; pbx[count+1] = X+1; \
- pby[count] = Y; pby[count+1] = Y; \
- pbz[count] = Z; pbz[count+1] = Z; \
- pbfog[count] = fog0; pbfog[count+1] = fog0; \
- pbi[count] = I; pbi[count+1] = I; \
- count += 2; \
- CHECK_FULL(count);
-#include "s_linetemp.h"
- }
- else {
- /* unstippled, any width */
-#define INTERP_XY 1
-#define INTERP_Z 1
-#define INTERP_FOG 1
-#define INTERP_INDEX 1
-#define WIDE 1
-#define PLOT(X,Y) \
- pbx[count] = X; \
- pby[count] = Y; \
- pbz[count] = Z; \
- pbi[count] = I; \
- pbfog[count] = fog0; \
- count++; \
- CHECK_FULL(count);
#include "s_linetemp.h"
- }
+
+ if (ctx->Line.StippleFlag) {
+ span.arrayMask |= SPAN_MASK;
+ compute_stipple_mask(ctx, span.end, span.array->mask);
}
- PB->count = count;
- _mesa_flush_pb(ctx);
+ if (ctx->Line.Width > 1.0) {
+ draw_wide_line(ctx, &span, xMajor);
+ }
+ else {
+ _mesa_write_index_span(ctx, &span);
+ }
}
@@ -366,73 +325,48 @@ static void general_flat_ci_line( GLcontext *ctx,
const SWvertex *vert0,
const SWvertex *vert1 )
{
- struct pixel_buffer *PB = SWRAST_CONTEXT(ctx)->PB;
- GLint count;
- GLint *pbx = PB->x;
- GLint *pby = PB->y;
- GLdepth *pbz = PB->z;
- GLfloat *pbfog = PB->fog;
- PB_SET_INDEX( PB, vert0->index );
- count = PB->count;
-
- if (ctx->Line.StippleFlag) {
- /* stippled, any width */
+ GLboolean xMajor = GL_FALSE;
+ struct sw_span span;
+ GLint *x, *y;
+ GLdepth *z;
+ GLfloat *fog;
+
+ ASSERT(ctx->Light.ShadeModel == GL_FLAT);
+
+ INIT_SPAN(span, GL_LINE, 0, SPAN_INDEX,
+ SPAN_XY | SPAN_Z | SPAN_FOG);
+ span.index = IntToFixed(vert1->index);
+ span.indexStep = 0;
+ x = span.array->x;
+ y = span.array->y;
+ z = span.array->z;
+ fog = span.array->fog;
+
+#define SET_XMAJOR 1
#define INTERP_XY 1
#define INTERP_Z 1
#define INTERP_FOG 1
-#define WIDE 1
-#define STIPPLE 1
#define PLOT(X,Y) \
- pbx[count] = X; \
- pby[count] = Y; \
- pbz[count] = Z; \
- pbfog[count] = fog0; \
- count++; \
- CHECK_FULL(count);
-#include "s_linetemp.h"
+ { \
+ x[span.end] = X; \
+ y[span.end] = Y; \
+ z[span.end] = Z; \
+ fog[span.end] = fog0; \
+ span.end++; \
}
- else {
- /* unstippled */
- if (ctx->Line.Width==2.0F) {
- /* special case: unstippled and width=2 */
-#define INTERP_XY 1
-#define INTERP_Z 1
-#define INTERP_FOG 1
-#define XMAJOR_PLOT(X,Y) \
- pbx[count] = X; pbx[count+1] = X; \
- pby[count] = Y; pby[count+1] = Y+1; \
- pbz[count] = Z; pbz[count+1] = Z; \
- pbfog[count] = fog0; pbfog[count+1] = fog0; \
- count += 2; \
- CHECK_FULL(count);
-#define YMAJOR_PLOT(X,Y) \
- pbx[count] = X; pbx[count+1] = X+1; \
- pby[count] = Y; pby[count+1] = Y; \
- pbz[count] = Z; pbz[count+1] = Z; \
- pbfog[count] = fog0; pbfog[count+1] = fog0; \
- count += 2; \
- CHECK_FULL(count);
#include "s_linetemp.h"
- }
- else {
- /* unstippled, any width */
-#define INTERP_XY 1
-#define INTERP_Z 1
-#define INTERP_FOG 1
-#define WIDE 1
-#define PLOT(X,Y) \
- pbx[count] = X; \
- pby[count] = Y; \
- pbz[count] = Z; \
- pbfog[count] = fog0; \
- count++; \
- CHECK_FULL(count);
-#include "s_linetemp.h"
- }
+
+ if (ctx->Line.StippleFlag) {
+ span.arrayMask |= SPAN_MASK;
+ compute_stipple_mask(ctx, span.end, span.array->mask);
}
- PB->count = count;
- _mesa_flush_pb(ctx);
+ if (ctx->Line.Width > 1.0) {
+ draw_wide_line(ctx, &span, xMajor);
+ }
+ else {
+ _mesa_write_index_span(ctx, &span);
+ }
}
@@ -441,104 +375,54 @@ static void general_smooth_rgba_line( GLcontext *ctx,
const SWvertex *vert0,
const SWvertex *vert1 )
{
- struct pixel_buffer *PB = SWRAST_CONTEXT(ctx)->PB;
- GLint count = PB->count;
- GLint *pbx = PB->x;
- GLint *pby = PB->y;
- GLdepth *pbz = PB->z;
- GLfloat *pbfog = PB->fog;
- GLchan (*pbrgba)[4] = PB->rgba;
-
- PB->mono = GL_FALSE;
-
- if (ctx->Line.StippleFlag) {
- /* stippled */
+ GLboolean xMajor = GL_FALSE;
+ struct sw_span span;
+ GLint *x, *y;
+ GLdepth *z;
+ GLchan (*rgba)[4];
+ GLfloat *fog;
+
+ ASSERT(ctx->Light.ShadeModel == GL_SMOOTH);
+
+ INIT_SPAN(span, GL_LINE, 0, 0,
+ SPAN_XY | SPAN_Z | SPAN_FOG | SPAN_RGBA);
+ x = span.array->x;
+ y = span.array->y;
+ z = span.array->z;
+ rgba = span.array->rgba;
+ fog = span.array->fog;
+
+#define SET_XMAJOR 1
#define INTERP_XY 1
#define INTERP_Z 1
#define INTERP_FOG 1
#define INTERP_RGB 1
#define INTERP_ALPHA 1
-#define WIDE 1
-#define STIPPLE 1
#define PLOT(X,Y) \
- pbx[count] = X; \
- pby[count] = Y; \
- pbz[count] = Z; \
- pbfog[count] = fog0; \
- pbrgba[count][RCOMP] = FixedToInt(r0); \
- pbrgba[count][GCOMP] = FixedToInt(g0); \
- pbrgba[count][BCOMP] = FixedToInt(b0); \
- pbrgba[count][ACOMP] = FixedToInt(a0); \
- count++; \
- CHECK_FULL(count);
-#include "s_linetemp.h"
+ { \
+ x[span.end] = X; \
+ y[span.end] = Y; \
+ z[span.end] = Z; \
+ rgba[span.end][RCOMP] = FixedToInt(r0); \
+ rgba[span.end][GCOMP] = FixedToInt(g0); \
+ rgba[span.end][BCOMP] = FixedToInt(b0); \
+ rgba[span.end][ACOMP] = FixedToInt(a0); \
+ fog[span.end] = fog0; \
+ span.end++; \
}
- else {
- /* unstippled */
- if (ctx->Line.Width==2.0F) {
- /* special case: unstippled and width=2 */
-#define INTERP_XY 1
-#define INTERP_Z 1
-#define INTERP_FOG 1
-#define INTERP_RGB 1
-#define INTERP_ALPHA 1
-#define XMAJOR_PLOT(X,Y) \
- pbx[count] = X; pbx[count+1] = X; \
- pby[count] = Y; pby[count+1] = Y+1; \
- pbz[count] = Z; pbz[count+1] = Z; \
- pbfog[count] = fog0; pbfog[count+1] = fog0; \
- pbrgba[count][RCOMP] = FixedToInt(r0); \
- pbrgba[count][GCOMP] = FixedToInt(g0); \
- pbrgba[count][BCOMP] = FixedToInt(b0); \
- pbrgba[count][ACOMP] = FixedToInt(a0); \
- pbrgba[count+1][RCOMP] = FixedToInt(r0); \
- pbrgba[count+1][GCOMP] = FixedToInt(g0); \
- pbrgba[count+1][BCOMP] = FixedToInt(b0); \
- pbrgba[count+1][ACOMP] = FixedToInt(a0); \
- count += 2; \
- CHECK_FULL(count);
-#define YMAJOR_PLOT(X,Y) \
- pbx[count] = X; pbx[count+1] = X+1; \
- pby[count] = Y; pby[count+1] = Y; \
- pbz[count] = Z; pbz[count+1] = Z; \
- pbfog[count] = fog0; pbfog[count+1] = fog0; \
- pbrgba[count][RCOMP] = FixedToInt(r0); \
- pbrgba[count][GCOMP] = FixedToInt(g0); \
- pbrgba[count][BCOMP] = FixedToInt(b0); \
- pbrgba[count][ACOMP] = FixedToInt(a0); \
- pbrgba[count+1][RCOMP] = FixedToInt(r0); \
- pbrgba[count+1][GCOMP] = FixedToInt(g0); \
- pbrgba[count+1][BCOMP] = FixedToInt(b0); \
- pbrgba[count+1][ACOMP] = FixedToInt(a0); \
- count += 2; \
- CHECK_FULL(count);
-#include "s_linetemp.h"
- }
- else {
- /* unstippled, any width */
-#define INTERP_XY 1
-#define INTERP_Z 1
-#define INTERP_FOG 1
-#define INTERP_RGB 1
-#define INTERP_ALPHA 1
-#define WIDE 1
-#define PLOT(X,Y) \
- pbx[count] = X; \
- pby[count] = Y; \
- pbz[count] = Z; \
- pbfog[count] = fog0; \
- pbrgba[count][RCOMP] = FixedToInt(r0); \
- pbrgba[count][GCOMP] = FixedToInt(g0); \
- pbrgba[count][BCOMP] = FixedToInt(b0); \
- pbrgba[count][ACOMP] = FixedToInt(a0); \
- count++; \
- CHECK_FULL(count);
#include "s_linetemp.h"
- }
+
+ if (ctx->Line.StippleFlag) {
+ span.arrayMask |= SPAN_MASK;
+ compute_stipple_mask(ctx, span.end, span.array->mask);
}
- PB->count = count;
- _mesa_flush_pb(ctx);
+ if (ctx->Line.Width > 1.0) {
+ draw_wide_line(ctx, &span, xMajor);
+ }
+ else {
+ _mesa_write_rgba_span(ctx, &span);
+ }
}
@@ -546,52 +430,54 @@ static void general_flat_rgba_line( GLcontext *ctx,
const SWvertex *vert0,
const SWvertex *vert1 )
{
- struct pixel_buffer *PB = SWRAST_CONTEXT(ctx)->PB;
- const GLchan *color = vert1->color;
- GLuint count;
- PB_SET_COLOR( PB, color[0], color[1], color[2], color[3] );
-
- if (ctx->Line.StippleFlag) {
- /* stippled */
+ GLboolean xMajor = GL_FALSE;
+ struct sw_span span;
+ GLint *x, *y;
+ GLdepth *z;
+ GLfloat *fog;
+
+ ASSERT(ctx->Light.ShadeModel == GL_FLAT);
+
+ INIT_SPAN(span, GL_LINE, 0, SPAN_RGBA,
+ SPAN_XY | SPAN_Z | SPAN_FOG);
+ span.red = ChanToFixed(vert1->color[0]);
+ span.green = ChanToFixed(vert1->color[1]);
+ span.blue = ChanToFixed(vert1->color[2]);
+ span.alpha = ChanToFixed(vert1->color[3]);
+ span.redStep = 0;
+ span.greenStep = 0;
+ span.blueStep = 0;
+ span.alphaStep = 0;
+ x = span.array->x;
+ y = span.array->y;
+ z = span.array->z;
+ fog = span.array->fog;
+
+#define SET_XMAJOR 1
#define INTERP_XY 1
#define INTERP_Z 1
#define INTERP_FOG 1
-#define WIDE 1
-#define STIPPLE 1
-#define PLOT(X,Y) \
- PB_WRITE_PIXEL(PB, X, Y, Z, fog0); \
- count = PB->count; \
- CHECK_FULL(count);
-#include "s_linetemp.h"
+#define PLOT(X,Y) \
+ { \
+ x[span.end] = X; \
+ y[span.end] = Y; \
+ z[span.end] = Z; \
+ fog[span.end] = fog0; \
+ span.end++; \
}
- else {
- /* unstippled */
- if (ctx->Line.Width==2.0F) {
- /* special case: unstippled and width=2 */
-#define INTERP_XY 1
-#define INTERP_Z 1
-#define INTERP_FOG 1
-#define XMAJOR_PLOT(X,Y) PB_WRITE_PIXEL(PB, X, Y, Z, fog0); \
- PB_WRITE_PIXEL(PB, X, Y+1, Z, fog0);
-#define YMAJOR_PLOT(X,Y) PB_WRITE_PIXEL(PB, X, Y, Z, fog0); \
- PB_WRITE_PIXEL(PB, X+1, Y, Z, fog0);
#include "s_linetemp.h"
- }
- else {
- /* unstippled, any width */
-#define INTERP_XY 1
-#define INTERP_Z 1
-#define INTERP_FOG 1
-#define WIDE 1
-#define PLOT(X,Y) \
- PB_WRITE_PIXEL(PB, X, Y, Z, fog0); \
- count = PB->count; \
- CHECK_FULL(count);
-#include "s_linetemp.h"
- }
+
+ if (ctx->Line.StippleFlag) {
+ span.arrayMask |= SPAN_MASK;
+ compute_stipple_mask(ctx, span.end, span.array->mask);
}
- _mesa_flush_pb(ctx);
+ if (ctx->Line.Width > 1.0) {
+ draw_wide_line(ctx, &span, xMajor);
+ }
+ else {
+ _mesa_write_rgba_span(ctx, &span);
+ }
}
@@ -600,65 +486,58 @@ static void flat_textured_line( GLcontext *ctx,
const SWvertex *vert0,
const SWvertex *vert1 )
{
- struct pixel_buffer *PB = SWRAST_CONTEXT(ctx)->PB;
- GLint count;
- GLint *pbx = PB->x;
- GLint *pby = PB->y;
- GLdepth *pbz = PB->z;
- GLfloat *pbfog = PB->fog;
- GLfloat *pbs = PB->s[0];
- GLfloat *pbt = PB->t[0];
- GLfloat *pbu = PB->u[0];
- GLchan *color = (GLchan*) vert1->color;
- PB_SET_COLOR( PB, color[0], color[1], color[2], color[3] );
- count = PB->count;
-
- if (ctx->Line.StippleFlag) {
- /* stippled */
+ GLboolean xMajor = GL_FALSE;
+ struct sw_span span;
+
+ ASSERT(ctx->Light.ShadeModel == GL_FLAT);
+
+ INIT_SPAN(span, GL_LINE, 0, SPAN_RGBA | SPAN_SPEC,
+ SPAN_XY | SPAN_Z | SPAN_FOG | SPAN_TEXTURE | SPAN_LAMBDA);
+ span.red = ChanToFixed(vert1->color[0]);
+ span.green = ChanToFixed(vert1->color[1]);
+ span.blue = ChanToFixed(vert1->color[2]);
+ span.alpha = ChanToFixed(vert1->color[3]);
+ span.redStep = 0;
+ span.greenStep = 0;
+ span.blueStep = 0;
+ span.alphaStep = 0;
+ 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;
+
+#define SET_XMAJOR 1
#define INTERP_XY 1
#define INTERP_Z 1
#define INTERP_FOG 1
#define INTERP_TEX 1
-#define WIDE 1
-#define STIPPLE 1
-#define PLOT(X,Y) \
- { \
- pbx[count] = X; \
- pby[count] = Y; \
- pbz[count] = Z; \
- pbfog[count] = fog0; \
- pbs[count] = fragTexcoord[0];\
- pbt[count] = fragTexcoord[1];\
- pbu[count] = fragTexcoord[2];\
- count++; \
- CHECK_FULL(count); \
- }
-#include "s_linetemp.h"
+#define PLOT(X,Y) \
+ { \
+ span.array->x[span.end] = X; \
+ span.array->y[span.end] = Y; \
+ span.array->z[span.end] = Z; \
+ span.array->fog[span.end] = fog0; \
+ span.array->texcoords[0][span.end][0] = fragTexcoord[0]; \
+ span.array->texcoords[0][span.end][1] = fragTexcoord[1]; \
+ span.array->texcoords[0][span.end][2] = fragTexcoord[2]; \
+ span.array->lambda[0][span.end] = 0.0; \
+ span.end++; \
}
- else {
- /* unstippled */
-#define INTERP_XY 1
-#define INTERP_Z 1
-#define INTERP_FOG 1
-#define INTERP_TEX 1
-#define WIDE 1
-#define PLOT(X,Y) \
- { \
- pbx[count] = X; \
- pby[count] = Y; \
- pbz[count] = Z; \
- pbfog[count] = fog0; \
- pbs[count] = fragTexcoord[0];\
- pbt[count] = fragTexcoord[1];\
- pbu[count] = fragTexcoord[2];\
- count++; \
- CHECK_FULL(count); \
- }
#include "s_linetemp.h"
+
+ if (ctx->Line.StippleFlag) {
+ span.arrayMask |= SPAN_MASK;
+ compute_stipple_mask(ctx, span.end, span.array->mask);
}
- PB->count = count;
- _mesa_flush_pb(ctx);
+ if (ctx->Line.Width > 1.0) {
+ draw_wide_line(ctx, &span, xMajor);
+ }
+ else {
+ _mesa_write_texture_span(ctx, &span);
+ }
}
@@ -668,77 +547,50 @@ static void smooth_textured_line( GLcontext *ctx,
const SWvertex *vert0,
const SWvertex *vert1 )
{
- struct pixel_buffer *PB = SWRAST_CONTEXT(ctx)->PB;
- GLint count = PB->count;
- GLint *pbx = PB->x;
- GLint *pby = PB->y;
- GLdepth *pbz = PB->z;
- GLfloat *pbfog = PB->fog;
- GLfloat *pbs = PB->s[0];
- GLfloat *pbt = PB->t[0];
- GLfloat *pbu = PB->u[0];
- GLchan (*pbrgba)[4] = PB->rgba;
-
- PB->mono = GL_FALSE;
+ GLboolean xMajor = GL_FALSE;
+ struct sw_span span;
- if (ctx->Line.StippleFlag) {
- /* stippled */
+ ASSERT(ctx->Light.ShadeModel == GL_SMOOTH);
+
+ INIT_SPAN(span, GL_LINE, 0, 0,
+ SPAN_XY | SPAN_Z | SPAN_FOG | SPAN_RGBA | SPAN_TEXTURE | SPAN_LAMBDA);
+
+#define SET_XMAJOR 1
#define INTERP_XY 1
#define INTERP_Z 1
#define INTERP_FOG 1
#define INTERP_RGB 1
#define INTERP_ALPHA 1
#define INTERP_TEX 1
-#define WIDE 1
-#define STIPPLE 1
-#define PLOT(X,Y) \
- { \
- pbx[count] = X; \
- pby[count] = Y; \
- pbz[count] = Z; \
- pbfog[count] = fog0; \
- pbs[count] = fragTexcoord[0]; \
- pbt[count] = fragTexcoord[1]; \
- pbu[count] = fragTexcoord[2]; \
- pbrgba[count][RCOMP] = FixedToInt(r0); \
- pbrgba[count][GCOMP] = FixedToInt(g0); \
- pbrgba[count][BCOMP] = FixedToInt(b0); \
- pbrgba[count][ACOMP] = FixedToInt(a0); \
- count++; \
- CHECK_FULL(count); \
- }
-#include "s_linetemp.h"
+#define PLOT(X,Y) \
+ { \
+ span.array->x[span.end] = X; \
+ span.array->y[span.end] = Y; \
+ span.array->z[span.end] = Z; \
+ span.array->fog[span.end] = fog0; \
+ span.array->rgba[span.end][RCOMP] = FixedToInt(r0); \
+ span.array->rgba[span.end][GCOMP] = FixedToInt(g0); \
+ span.array->rgba[span.end][BCOMP] = FixedToInt(b0); \
+ span.array->rgba[span.end][ACOMP] = FixedToInt(a0); \
+ span.array->texcoords[0][span.end][0] = fragTexcoord[0]; \
+ span.array->texcoords[0][span.end][1] = fragTexcoord[1]; \
+ span.array->texcoords[0][span.end][2] = fragTexcoord[2]; \
+ span.array->lambda[0][span.end] = 0.0; \
+ span.end++; \
}
- else {
- /* unstippled */
-#define INTERP_XY 1
-#define INTERP_Z 1
-#define INTERP_FOG 1
-#define INTERP_RGB 1
-#define INTERP_ALPHA 1
-#define INTERP_TEX 1
-#define WIDE 1
-#define PLOT(X,Y) \
- { \
- pbx[count] = X; \
- pby[count] = Y; \
- pbz[count] = Z; \
- pbfog[count] = fog0; \
- pbs[count] = fragTexcoord[0]; \
- pbt[count] = fragTexcoord[1]; \
- pbu[count] = fragTexcoord[2]; \
- pbrgba[count][RCOMP] = FixedToInt(r0); \
- pbrgba[count][GCOMP] = FixedToInt(g0); \
- pbrgba[count][BCOMP] = FixedToInt(b0); \
- pbrgba[count][ACOMP] = FixedToInt(a0); \
- count++; \
- CHECK_FULL(count); \
- }
#include "s_linetemp.h"
+
+ if (ctx->Line.StippleFlag) {
+ span.arrayMask |= SPAN_MASK;
+ compute_stipple_mask(ctx, span.end, span.array->mask);
}
- PB->count = count;
- _mesa_flush_pb(ctx);
+ if (ctx->Line.Width > 1.0) {
+ draw_wide_line(ctx, &span, xMajor);
+ }
+ else {
+ _mesa_write_texture_span(ctx, &span);
+ }
}
@@ -749,20 +601,16 @@ static void smooth_multitextured_line( GLcontext *ctx,
const SWvertex *vert0,
const SWvertex *vert1 )
{
- struct pixel_buffer *PB = SWRAST_CONTEXT(ctx)->PB;
- GLint count = PB->count;
- GLint *pbx = PB->x;
- GLint *pby = PB->y;
- GLdepth *pbz = PB->z;
- GLfloat *pbfog = PB->fog;
- GLchan (*pbrgba)[4] = PB->rgba;
- GLchan (*pbspec)[3] = PB->spec;
-
- PB->mono = GL_FALSE;
- PB->haveSpec = GL_TRUE;
+ GLboolean xMajor = GL_FALSE;
+ struct sw_span span;
+ GLuint u;
- if (ctx->Line.StippleFlag) {
- /* stippled */
+ ASSERT(ctx->Light.ShadeModel == GL_SMOOTH);
+
+ INIT_SPAN(span, GL_LINE, 0, 0,
+ SPAN_XY | SPAN_Z | SPAN_FOG | SPAN_RGBA | SPAN_SPEC | SPAN_TEXTURE | SPAN_LAMBDA);
+
+#define SET_XMAJOR 1
#define INTERP_XY 1
#define INTERP_Z 1
#define INTERP_FOG 1
@@ -770,73 +618,42 @@ static void smooth_multitextured_line( GLcontext *ctx,
#define INTERP_SPEC 1
#define INTERP_ALPHA 1
#define INTERP_MULTITEX 1
-#define WIDE 1
-#define STIPPLE 1
-#define PLOT(X,Y) \
- { \
- GLuint u; \
- pbx[count] = X; \
- pby[count] = Y; \
- pbz[count] = Z; \
- pbfog[count] = fog0; \
- pbrgba[count][RCOMP] = FixedToInt(r0); \
- pbrgba[count][GCOMP] = FixedToInt(g0); \
- pbrgba[count][BCOMP] = FixedToInt(b0); \
- pbrgba[count][ACOMP] = FixedToInt(a0); \
- pbspec[count][RCOMP] = FixedToInt(sr0); \
- pbspec[count][GCOMP] = FixedToInt(sg0); \
- pbspec[count][BCOMP] = FixedToInt(sb0); \
- for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { \
- if (ctx->Texture.Unit[u]._ReallyEnabled) { \
- PB->s[u][count] = fragTexcoord[u][0]; \
- PB->t[u][count] = fragTexcoord[u][1]; \
- PB->u[u][count] = fragTexcoord[u][2]; \
- } \
- } \
- count++; \
- CHECK_FULL(count); \
- }
-#include "s_linetemp.h"
+#define PLOT(X,Y) \
+ { \
+ span.array->x[span.end] = X; \
+ span.array->y[span.end] = Y; \
+ span.array->z[span.end] = Z; \
+ span.array->fog[span.end] = fog0; \
+ span.array->rgba[span.end][RCOMP] = FixedToInt(r0); \
+ span.array->rgba[span.end][GCOMP] = FixedToInt(g0); \
+ span.array->rgba[span.end][BCOMP] = FixedToInt(b0); \
+ span.array->rgba[span.end][ACOMP] = FixedToInt(a0); \
+ span.array->spec[span.end][RCOMP] = FixedToInt(sr0); \
+ span.array->spec[span.end][GCOMP] = FixedToInt(sg0); \
+ span.array->spec[span.end][BCOMP] = FixedToInt(sb0); \
+ for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { \
+ if (ctx->Texture.Unit[u]._ReallyEnabled) { \
+ span.array->texcoords[u][span.end][0] = fragTexcoord[u][0]; \
+ span.array->texcoords[u][span.end][1] = fragTexcoord[u][1]; \
+ span.array->texcoords[u][span.end][2] = fragTexcoord[u][2]; \
+ span.array->lambda[u][span.end] = 0.0; \
+ } \
+ } \
+ span.end++; \
}
- else {
- /* unstippled */
-#define INTERP_XY 1
-#define INTERP_Z 1
-#define INTERP_FOG 1
-#define INTERP_RGB 1
-#define INTERP_SPEC 1
-#define INTERP_ALPHA 1
-#define INTERP_MULTITEX 1
-#define WIDE 1
-#define PLOT(X,Y) \
- { \
- GLuint u; \
- pbx[count] = X; \
- pby[count] = Y; \
- pbz[count] = Z; \
- pbfog[count] = fog0; \
- pbrgba[count][RCOMP] = FixedToInt(r0); \
- pbrgba[count][GCOMP] = FixedToInt(g0); \
- pbrgba[count][BCOMP] = FixedToInt(b0); \
- pbrgba[count][ACOMP] = FixedToInt(a0); \
- pbspec[count][RCOMP] = FixedToInt(sr0); \
- pbspec[count][GCOMP] = FixedToInt(sg0); \
- pbspec[count][BCOMP] = FixedToInt(sb0); \
- for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { \
- if (ctx->Texture.Unit[u]._ReallyEnabled) { \
- PB->s[u][count] = fragTexcoord[u][0]; \
- PB->t[u][count] = fragTexcoord[u][1]; \
- PB->u[u][count] = fragTexcoord[u][2]; \
- } \
- } \
- count++; \
- CHECK_FULL(count); \
- }
#include "s_linetemp.h"
+
+ if (ctx->Line.StippleFlag) {
+ span.arrayMask |= SPAN_MASK;
+ compute_stipple_mask(ctx, span.end, span.array->mask);
}
- PB->count = count;
- _mesa_flush_pb(ctx);
+ if (ctx->Line.Width > 1.0) {
+ draw_wide_line(ctx, &span, xMajor);
+ }
+ else {
+ _mesa_write_texture_span(ctx, &span);
+ }
}
@@ -847,94 +664,63 @@ static void flat_multitextured_line( GLcontext *ctx,
const SWvertex *vert0,
const SWvertex *vert1 )
{
- struct pixel_buffer *PB = SWRAST_CONTEXT(ctx)->PB;
- GLint count = PB->count;
- GLint *pbx = PB->x;
- GLint *pby = PB->y;
- GLdepth *pbz = PB->z;
- GLfloat *pbfog = PB->fog;
- GLchan (*pbrgba)[4] = PB->rgba;
- GLchan (*pbspec)[3] = PB->spec;
- GLchan *color = (GLchan*) vert1->color;
- GLchan sRed = vert1->specular[0];
- GLchan sGreen = vert1->specular[1];
- GLchan sBlue = vert1->specular[2];
-
- PB->mono = GL_FALSE;
- PB->haveSpec = GL_TRUE;
-
- if (ctx->Line.StippleFlag) {
- /* stippled */
+ GLboolean xMajor = GL_FALSE;
+ struct sw_span span;
+ GLuint u;
+
+ ASSERT(ctx->Light.ShadeModel == GL_FLAT);
+
+ INIT_SPAN(span, GL_LINE, 0, SPAN_RGBA | SPAN_SPEC,
+ SPAN_XY | SPAN_Z | SPAN_FOG | SPAN_TEXTURE | SPAN_LAMBDA);
+ span.red = ChanToFixed(vert1->color[0]);
+ span.green = ChanToFixed(vert1->color[1]);
+ span.blue = ChanToFixed(vert1->color[2]);
+ span.alpha = ChanToFixed(vert1->color[3]);
+ span.redStep = 0;
+ span.greenStep = 0;
+ span.blueStep = 0;
+ span.alphaStep = 0;
+ 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;
+
+#define SET_XMAJOR 1
#define INTERP_XY 1
#define INTERP_Z 1
#define INTERP_FOG 1
-#define INTERP_ALPHA 1
#define INTERP_MULTITEX 1
-#define WIDE 1
-#define STIPPLE 1
-#define PLOT(X,Y) \
- { \
- GLuint u; \
- pbx[count] = X; \
- pby[count] = Y; \
- pbz[count] = Z; \
- pbfog[count] = fog0; \
- pbrgba[count][RCOMP] = color[0]; \
- pbrgba[count][GCOMP] = color[1]; \
- pbrgba[count][BCOMP] = color[2]; \
- pbrgba[count][ACOMP] = color[3]; \
- pbspec[count][RCOMP] = sRed; \
- pbspec[count][GCOMP] = sGreen; \
- pbspec[count][BCOMP] = sBlue; \
- for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { \
- if (ctx->Texture.Unit[u]._ReallyEnabled) { \
- PB->s[u][count] = fragTexcoord[u][0]; \
- PB->t[u][count] = fragTexcoord[u][1]; \
- PB->u[u][count] = fragTexcoord[u][2]; \
- } \
- } \
- count++; \
- CHECK_FULL(count); \
- }
-#include "s_linetemp.h"
+#define PLOT(X,Y) \
+ { \
+ span.array->x[span.end] = X; \
+ span.array->y[span.end] = Y; \
+ span.array->z[span.end] = Z; \
+ span.array->fog[span.end] = fog0; \
+ for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { \
+ if (ctx->Texture.Unit[u]._ReallyEnabled) { \
+ span.array->texcoords[u][span.end][0] = fragTexcoord[u][0]; \
+ span.array->texcoords[u][span.end][1] = fragTexcoord[u][1]; \
+ span.array->texcoords[u][span.end][2] = fragTexcoord[u][2]; \
+ span.array->lambda[u][span.end] = 0.0; \
+ } \
+ } \
+ span.end++; \
}
- else {
- /* unstippled */
-#define INTERP_XY 1
-#define INTERP_Z 1
-#define INTERP_FOG 1
-#define INTERP_ALPHA 1
-#define INTERP_MULTITEX 1
-#define WIDE 1
-#define PLOT(X,Y) \
- { \
- GLuint u; \
- pbx[count] = X; \
- pby[count] = Y; \
- pbz[count] = Z; \
- pbfog[count] = fog0; \
- pbrgba[count][RCOMP] = color[0]; \
- pbrgba[count][GCOMP] = color[1]; \
- pbrgba[count][BCOMP] = color[2]; \
- pbrgba[count][ACOMP] = color[3]; \
- pbspec[count][RCOMP] = sRed; \
- pbspec[count][GCOMP] = sGreen; \
- pbspec[count][BCOMP] = sBlue; \
- for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { \
- if (ctx->Texture.Unit[u]._ReallyEnabled) { \
- PB->s[u][count] = fragTexcoord[u][0]; \
- PB->t[u][count] = fragTexcoord[u][1]; \
- PB->u[u][count] = fragTexcoord[u][2]; \
- } \
- } \
- count++; \
- CHECK_FULL(count); \
- }
#include "s_linetemp.h"
+
+ if (ctx->Line.StippleFlag) {
+ span.arrayMask |= SPAN_MASK;
+ compute_stipple_mask(ctx, span.end, span.array->mask);
}
- PB->count = count;
- _mesa_flush_pb(ctx);
+ if (ctx->Line.Width > 1.0) {
+ draw_wide_line(ctx, &span, xMajor);
+ }
+ else {
+ _mesa_write_texture_span(ctx, &span);
+ }
}
@@ -963,41 +749,33 @@ _mesa_print_line_function(GLcontext *ctx)
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
- printf("Line Func == ");
+ _mesa_printf("Line Func == ");
if (swrast->Line == flat_ci_line)
- printf("flat_ci_line\n");
- else if (swrast->Line == flat_ci_z_line)
- printf("flat_ci_z_line\n");
+ _mesa_printf("flat_ci_line\n");
else if (swrast->Line == flat_rgba_line)
- printf("flat_rgba_line\n");
- else if (swrast->Line == flat_rgba_z_line)
- printf("flat_rgba_z_line\n");
+ _mesa_printf("flat_rgba_line\n");
else if (swrast->Line == smooth_ci_line)
- printf("smooth_ci_line\n");
- else if (swrast->Line == smooth_ci_z_line)
- printf("smooth_ci_z_line\n");
+ _mesa_printf("smooth_ci_line\n");
else if (swrast->Line == smooth_rgba_line)
- printf("smooth_rgba_line\n");
- else if (swrast->Line == smooth_rgba_z_line)
- printf("smooth_rgba_z_line\n");
+ _mesa_printf("smooth_rgba_line\n");
else if (swrast->Line == general_smooth_ci_line)
- printf("general_smooth_ci_line\n");
+ _mesa_printf("general_smooth_ci_line\n");
else if (swrast->Line == general_flat_ci_line)
- printf("general_flat_ci_line\n");
+ _mesa_printf("general_flat_ci_line\n");
else if (swrast->Line == general_smooth_rgba_line)
- printf("general_smooth_rgba_line\n");
+ _mesa_printf("general_smooth_rgba_line\n");
else if (swrast->Line == general_flat_rgba_line)
- printf("general_flat_rgba_line\n");
+ _mesa_printf("general_flat_rgba_line\n");
else if (swrast->Line == flat_textured_line)
- printf("flat_textured_line\n");
+ _mesa_printf("flat_textured_line\n");
else if (swrast->Line == smooth_textured_line)
- printf("smooth_textured_line\n");
+ _mesa_printf("smooth_textured_line\n");
else if (swrast->Line == smooth_multitextured_line)
- printf("smooth_multitextured_line\n");
+ _mesa_printf("smooth_multitextured_line\n");
else if (swrast->Line == flat_multitextured_line)
- printf("flat_multitextured_line\n");
+ _mesa_printf("flat_multitextured_line\n");
else
- printf("Driver func %p\n", (void *) swrast->Line);
+ _mesa_printf("Driver func %p\n", (void *) swrast->Line);
}
#endif
@@ -1011,7 +789,7 @@ static const char *lineFuncName = NULL;
#define USE(lineFunc) \
do { \
lineFuncName = #lineFunc; \
- /*printf("%s\n", lineFuncName);*/ \
+ /*_mesa_printf("%s\n", lineFuncName);*/ \
swrast->Line = lineFunc; \
} while (0)
@@ -1036,23 +814,23 @@ _swrast_choose_line( GLcontext *ctx )
SWcontext *swrast = SWRAST_CONTEXT(ctx);
const GLboolean rgbmode = ctx->Visual.rgbMode;
- if (ctx->RenderMode==GL_RENDER) {
+ if (ctx->RenderMode == GL_RENDER) {
if (ctx->Line.SmoothFlag) {
/* antialiased lines */
_swrast_choose_aa_line_function(ctx);
ASSERT(swrast->Triangle);
}
- else if (ctx->Texture._ReallyEnabled) {
- if (ctx->Texture._ReallyEnabled > TEXTURE0_ANY ||
+ else if (ctx->Texture._EnabledUnits) {
+ if (ctx->Texture._EnabledUnits > 1 ||
(ctx->_TriangleCaps & DD_SEPARATE_SPECULAR)) {
/* multi-texture and/or separate specular color */
- if (ctx->Light.ShadeModel==GL_SMOOTH)
+ if (ctx->Light.ShadeModel == GL_SMOOTH)
USE(smooth_multitextured_line);
else
USE(flat_multitextured_line);
}
else {
- if (ctx->Light.ShadeModel==GL_SMOOTH) {
+ if (ctx->Light.ShadeModel == GL_SMOOTH) {
USE(smooth_textured_line);
}
else {
@@ -1060,28 +838,14 @@ _swrast_choose_line( GLcontext *ctx )
}
}
}
- else if (ctx->Line.Width!=1.0 || ctx->Line.StippleFlag) {
- if (ctx->Light.ShadeModel==GL_SMOOTH) {
- if (rgbmode)
- USE(general_smooth_rgba_line);
- else
- USE(general_smooth_ci_line);
- }
- else {
- if (rgbmode)
- USE(general_flat_rgba_line);
- else
- USE(general_flat_ci_line);
- }
- }
else {
- if (ctx->Light.ShadeModel==GL_SMOOTH) {
- /* Width==1, non-stippled, smooth-shaded */
- if (ctx->Depth.Test || ctx->Fog.Enabled) {
+ if (ctx->Light.ShadeModel == GL_SMOOTH) {
+ if (ctx->Depth.Test || ctx->Fog.Enabled || ctx->Line.Width != 1.0
+ || ctx->Line.StippleFlag) {
if (rgbmode)
- USE(smooth_rgba_z_line);
+ USE(general_smooth_rgba_line);
else
- USE(smooth_ci_z_line);
+ USE(general_smooth_ci_line);
}
else {
if (rgbmode)
@@ -1091,12 +855,12 @@ _swrast_choose_line( GLcontext *ctx )
}
}
else {
- /* Width==1, non-stippled, flat-shaded */
- if (ctx->Depth.Test || ctx->Fog.Enabled) {
+ if (ctx->Depth.Test || ctx->Fog.Enabled || ctx->Line.Width != 1.0
+ || ctx->Line.StippleFlag) {
if (rgbmode)
- USE(flat_rgba_z_line);
+ USE(general_flat_rgba_line);
else
- USE(flat_ci_z_line);
+ USE(general_flat_ci_line);
}
else {
if (rgbmode)
@@ -1107,11 +871,11 @@ _swrast_choose_line( GLcontext *ctx )
}
}
}
- else if (ctx->RenderMode==GL_FEEDBACK) {
+ else if (ctx->RenderMode == GL_FEEDBACK) {
USE(_mesa_feedback_line);
}
else {
- /* GL_SELECT mode */
+ ASSERT(ctx->RenderMode == GL_SELECT);
USE(_mesa_select_line);
}
diff --git a/xc/extras/Mesa/src/swrast/s_linetemp.h b/xc/extras/Mesa/src/swrast/s_linetemp.h
index c5e7984c5..9c7541315 100644
--- a/xc/extras/Mesa/src/swrast/s_linetemp.h
+++ b/xc/extras/Mesa/src/swrast/s_linetemp.h
@@ -1,8 +1,7 @@
-/* $Id: s_linetemp.h,v 1.1.1.1 2002/10/22 13:06:55 alanh Exp $ */
/*
* Mesa 3-D graphics library
- * Version: 4.0.2
+ * Version: 5.0
*
* Copyright (C) 1999-2002 Brian Paul All Rights Reserved.
*
@@ -56,11 +55,7 @@
* Optionally, one may provide one-time setup code
* SETUP_CODE - code which is to be executed once per line
*
- * To enable line stippling define STIPPLE = 1
- * To enable wide lines define WIDE = 1
- *
- * To actually "plot" each pixel either the PLOT macro or
- * (XMAJOR_PLOT and YMAJOR_PLOT macros) must be defined...
+ * To actually "plot" each pixel the PLOT macro must be defined...
* PLOT(X,Y) - code to plot a pixel. Example:
* if (Z < *zPtr) {
* *zPtr = Z;
@@ -140,16 +135,6 @@
PIXEL_TYPE *pixelPtr;
GLint pixelXstep, pixelYstep;
#endif
-#ifdef STIPPLE
- SWcontext *swrast = SWRAST_CONTEXT(ctx);
-#endif
-#ifdef WIDE
- /* for wide lines, draw all X in [x+min, x+max] or Y in [y+min, y+max] */
- GLint width, min, max;
- width = (GLint) CLAMP( ctx->Line.Width, MIN_LINE_WIDTH, MAX_LINE_WIDTH );
- min = (width-1) / -2;
- max = min + width - 1;
-#endif
#ifdef INTERP_TEX
{
tex[0] = invw0 * vert0->texcoord[0][0];
@@ -188,6 +173,19 @@
return;
}
+ /*
+ 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]);
+ 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]);
+ printf(" (%d, %d, %d) -> (%d, %d, %d)\n",
+ vert0->specular[0], vert0->specular[1], vert0->specular[2],
+ vert1->specular[0], vert1->specular[1], vert1->specular[2]);
+ */
+
/*
* Despite being clipped to the view volume, the line's window coordinates
* may just lie outside the window bounds. That is, if the legal window
@@ -231,8 +229,8 @@
zPtr = (DEPTH_TYPE *) _mesa_zbuffer_address(ctx, x0, y0);
# endif
if (depthBits <= 16) {
- z0 = FloatToFixed(vert0->win[2]);
- z1 = FloatToFixed(vert1->win[2]);
+ z0 = FloatToFixed(vert0->win[2]) + FIXED_HALF;
+ z1 = FloatToFixed(vert1->win[2]) + FIXED_HALF;
}
else {
z0 = (int) vert0->win[2];
@@ -301,6 +299,9 @@
GLint errorInc = dy+dy;
GLint error = errorInc-dx;
GLint errorDec = error-dx;
+#ifdef SET_XMAJOR
+ xMajor = GL_TRUE;
+#endif
#ifdef INTERP_Z
dz = (z1-z0) / dx;
#endif
@@ -348,11 +349,6 @@
#endif
for (i=0;i<dx;i++) {
-#ifdef STIPPLE
- GLushort m;
- m = 1 << ((swrast->StippleCounter/ctx->Line.StippleFactor) & 0xf);
- if (ctx->Line.StipplePattern & m) {
-#endif
#ifdef INTERP_Z
GLdepth Z = FixedToDepth(z0);
#endif
@@ -382,26 +378,9 @@
}
}
#endif
-#ifdef WIDE
- {
- GLint yy;
- GLint ymin = y0 + min;
- GLint ymax = y0 + max;
- for (yy=ymin;yy<=ymax;yy++) {
- PLOT( x0, yy );
- }
- }
-#else
-# ifdef XMAJOR_PLOT
- XMAJOR_PLOT( x0, y0 );
-# else
+
PLOT( x0, y0 );
-# endif
-#endif /*WIDE*/
-#ifdef STIPPLE
- }
- swrast->StippleCounter++;
-#endif
+
#ifdef INTERP_XY
x0 += xstep;
#endif
@@ -523,11 +502,6 @@
#endif
for (i=0;i<dy;i++) {
-#ifdef STIPPLE
- GLushort m;
- m = 1 << ((swrast->StippleCounter/ctx->Line.StippleFactor) & 0xf);
- if (ctx->Line.StipplePattern & m) {
-#endif
#ifdef INTERP_Z
GLdepth Z = FixedToDepth(z0);
#endif
@@ -557,26 +531,9 @@
}
}
#endif
-#ifdef WIDE
- {
- GLint xx;
- GLint xmin = x0 + min;
- GLint xmax = x0 + max;
- for (xx=xmin;xx<=xmax;xx++) {
- PLOT( xx, y0 );
- }
- }
-#else
-# ifdef YMAJOR_PLOT
- YMAJOR_PLOT( x0, y0 );
-# else
+
PLOT( x0, y0 );
-# endif
-#endif /*WIDE*/
-#ifdef STIPPLE
- }
- swrast->StippleCounter++;
-#endif
+
#ifdef INTERP_XY
y0 += ystep;
#endif
@@ -663,9 +620,6 @@
#undef BYTES_PER_ROW
#undef SETUP_CODE
#undef PLOT
-#undef XMAJOR_PLOT
-#undef YMAJOR_PLOT
#undef CLIP_HACK
-#undef STIPPLE
-#undef WIDE
#undef FixedToDepth
+#undef SET_XMAJOR
diff --git a/xc/extras/Mesa/src/swrast/s_logic.c b/xc/extras/Mesa/src/swrast/s_logic.c
index 3521418bf..4f5b3b387 100644
--- a/xc/extras/Mesa/src/swrast/s_logic.c
+++ b/xc/extras/Mesa/src/swrast/s_logic.c
@@ -1,10 +1,9 @@
-/* $Id: s_logic.c,v 1.1.1.1 2002/10/22 13:06:51 alanh Exp $ */
/*
* Mesa 3-D graphics library
- * Version: 3.5
+ * Version: 4.1
*
- * Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
+ * Copyright (C) 1999-2002 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"),
@@ -27,12 +26,12 @@
#include "glheader.h"
#include "context.h"
+#include "imports.h"
#include "macros.h"
#include "s_alphabuf.h"
#include "s_context.h"
#include "s_logic.h"
-#include "s_pb.h"
#include "s_span.h"
@@ -40,9 +39,9 @@
/*
* Apply logic op to array of CI pixels.
*/
-static void index_logicop( GLcontext *ctx, GLuint n,
- GLuint index[], const GLuint dest[],
- const GLubyte mask[] )
+static void
+index_logicop( GLcontext *ctx, GLuint n, GLuint index[], const GLuint dest[],
+ const GLubyte mask[] )
{
GLuint i;
switch (ctx->Color.LogicOp) {
@@ -166,32 +165,25 @@ static void index_logicop( GLcontext *ctx, GLuint n,
* used if the device driver can't do logic ops.
*/
void
-_mesa_logicop_ci_span( GLcontext *ctx, GLuint n, GLint x, GLint y,
- GLuint index[], const GLubyte mask[] )
+_mesa_logicop_ci_span( GLcontext *ctx, const struct sw_span *span,
+ GLuint index[] )
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
GLuint dest[MAX_WIDTH];
- /* Read dest values from frame buffer */
- (*swrast->Driver.ReadCI32Span)( ctx, n, x, y, dest );
- index_logicop( ctx, n, index, dest, mask );
-}
+ ASSERT(span->end < MAX_WIDTH);
-
-/*
- * Apply the current logic operator to an array of CI pixels. This is only
- * used if the device driver can't do logic ops.
- */
-void
-_mesa_logicop_ci_pixels( GLcontext *ctx,
- GLuint n, const GLint x[], const GLint y[],
- GLuint index[], const GLubyte mask[] )
-{
- SWcontext *swrast = SWRAST_CONTEXT(ctx);
- GLuint dest[PB_SIZE];
/* Read dest values from frame buffer */
- (*swrast->Driver.ReadCI32Pixels)( ctx, n, x, y, dest, mask );
- index_logicop( ctx, n, index, dest, mask );
+ if (span->arrayMask & SPAN_XY) {
+ (*swrast->Driver.ReadCI32Pixels)( ctx, span->end,
+ span->array->x, span->array->y,
+ dest, span->array->mask );
+ }
+ else {
+ (*swrast->Driver.ReadCI32Span)( ctx, span->end, span->x, span->y, dest );
+ }
+
+ index_logicop( ctx, span->end, index, dest, span->array->mask );
}
@@ -207,9 +199,9 @@ _mesa_logicop_ci_pixels( GLcontext *ctx,
* Note: Since the R, G, B, and A channels are all treated the same we
* process them as 4-byte GLuints instead of four GLubytes.
*/
-static void rgba_logicop_ui( const GLcontext *ctx, GLuint n,
- const GLubyte mask[],
- GLuint src[], const GLuint dest[] )
+static void
+rgba_logicop_ui( const GLcontext *ctx, GLuint n, const GLubyte mask[],
+ GLuint src[], const GLuint dest[] )
{
GLuint i;
switch (ctx->Color.LogicOp) {
@@ -332,9 +324,9 @@ static void rgba_logicop_ui( const GLcontext *ctx, GLuint n,
* As above, but operate on GLchan values
* Note: need to pass n = numPixels * 4.
*/
-static void rgba_logicop_chan( const GLcontext *ctx, GLuint n,
- const GLubyte mask[],
- GLchan srcPtr[], const GLchan destPtr[] )
+static void
+rgba_logicop_chan( const GLcontext *ctx, GLuint n, const GLubyte mask[],
+ GLchan srcPtr[], const GLchan destPtr[] )
{
#if CHAN_TYPE == GL_FLOAT
GLuint *src = (GLuint *) srcPtr;
@@ -466,46 +458,40 @@ static void rgba_logicop_chan( const GLcontext *ctx, GLuint n,
/*
* Apply the current logic operator to a span of RGBA pixels.
- * This is only used if the device driver can't do logic ops.
+ * We can handle horizontal runs of pixels (spans) or arrays of x/y
+ * pixel coordinates.
*/
void
-_mesa_logicop_rgba_span( GLcontext *ctx,
- GLuint n, GLint x, GLint y,
- GLchan rgba[][4], const GLubyte mask[] )
+_mesa_logicop_rgba_span( GLcontext *ctx, const struct sw_span *span,
+ GLchan rgba[][4] )
{
+ SWcontext *swrast = SWRAST_CONTEXT(ctx);
GLchan dest[MAX_WIDTH][4];
- _mesa_read_rgba_span( ctx, ctx->DrawBuffer, n, x, y, dest );
- if (sizeof(GLchan) * 4 == sizeof(GLuint)) {
- rgba_logicop_ui(ctx, n, mask, (GLuint *) rgba, (const GLuint *) dest);
+
+ ASSERT(span->end < MAX_WIDTH);
+ ASSERT(span->arrayMask & SPAN_RGBA);
+
+ if (span->arrayMask & SPAN_XY) {
+ (*swrast->Driver.ReadRGBAPixels)(ctx, span->end,
+ span->array->x, span->array->y,
+ dest, span->array->mask);
+ if (SWRAST_CONTEXT(ctx)->_RasterMask & ALPHABUF_BIT) {
+ _mesa_read_alpha_pixels(ctx, span->end,
+ span->array->x, span->array->y,
+ dest, span->array->mask);
+ }
}
else {
- rgba_logicop_chan(ctx, 4 * n, mask,
- (GLchan *) rgba, (const GLchan *) dest);
+ _mesa_read_rgba_span(ctx, ctx->DrawBuffer, span->end,
+ span->x, span->y, dest);
}
-}
-
-
-/*
- * Apply the current logic operator to an array of RGBA pixels.
- * This is only used if the device driver can't do logic ops.
- */
-void
-_mesa_logicop_rgba_pixels( GLcontext *ctx,
- GLuint n, const GLint x[], const GLint y[],
- GLchan rgba[][4], const GLubyte mask[] )
-{
- SWcontext *swrast = SWRAST_CONTEXT(ctx);
- GLchan dest[PB_SIZE][4];
- (*swrast->Driver.ReadRGBAPixels)( ctx, n, x, y, dest, mask );
- if (SWRAST_CONTEXT(ctx)->_RasterMask & ALPHABUF_BIT) {
- _mesa_read_alpha_pixels( ctx, n, x, y, dest, mask );
- }
if (sizeof(GLchan) * 4 == sizeof(GLuint)) {
- rgba_logicop_ui(ctx, n, mask, (GLuint *) rgba, (const GLuint *) dest);
+ rgba_logicop_ui(ctx, span->end, span->array->mask,
+ (GLuint *) rgba, (const GLuint *) dest);
}
else {
- rgba_logicop_chan(ctx, 4 * n, mask,
+ rgba_logicop_chan(ctx, 4 * span->end, span->array->mask,
(GLchan *) rgba, (const GLchan *) dest);
}
}
diff --git a/xc/extras/Mesa/src/swrast/s_logic.h b/xc/extras/Mesa/src/swrast/s_logic.h
index 8ac68f830..820451d9b 100644
--- a/xc/extras/Mesa/src/swrast/s_logic.h
+++ b/xc/extras/Mesa/src/swrast/s_logic.h
@@ -1,10 +1,9 @@
-/* $Id: s_logic.h,v 1.1.1.1 2002/10/22 13:06:51 alanh Exp $ */
/*
* Mesa 3-D graphics library
- * Version: 3.5
+ * Version: 4.1
*
- * Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
+ * Copyright (C) 1999-2002 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,26 +33,13 @@
extern void
-_mesa_logicop_ci_span( GLcontext *ctx,
- GLuint n, GLint x, GLint y, GLuint index[],
- const GLubyte mask[] );
+_mesa_logicop_ci_span( GLcontext *ctx, const struct sw_span *span,
+ GLuint index[] );
extern void
-_mesa_logicop_ci_pixels( GLcontext *ctx,
- GLuint n, const GLint x[], const GLint y[],
- GLuint index[], const GLubyte mask[] );
-
-
-extern void
-_mesa_logicop_rgba_span( GLcontext *ctx, GLuint n, GLint x, GLint y,
- GLchan rgba[][4], const GLubyte mask[] );
-
-
-extern void
-_mesa_logicop_rgba_pixels( GLcontext *ctx,
- GLuint n, const GLint x[], const GLint y[],
- GLchan rgba[][4], const GLubyte mask[] );
+_mesa_logicop_rgba_span( GLcontext *ctx, const struct sw_span *span,
+ GLchan rgba[][4] );
#endif
diff --git a/xc/extras/Mesa/src/swrast/s_masking.c b/xc/extras/Mesa/src/swrast/s_masking.c
index d4d57140d..74e1fb5bc 100644
--- a/xc/extras/Mesa/src/swrast/s_masking.c
+++ b/xc/extras/Mesa/src/swrast/s_masking.c
@@ -1,10 +1,9 @@
-/* $Id: s_masking.c,v 1.1.1.1 2002/10/22 13:06:44 alanh Exp $ */
/*
* Mesa 3-D graphics library
- * Version: 3.5
+ * Version: 4.1
*
- * Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
+ * Copyright (C) 1999-2002 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"),
@@ -37,62 +36,70 @@
#include "s_alphabuf.h"
#include "s_context.h"
#include "s_masking.h"
-#include "s_pb.h"
#include "s_span.h"
-/*
- * Apply glColorMask to a span of RGBA pixels.
- */
+
void
-_mesa_mask_rgba_span( GLcontext *ctx,
- GLuint n, GLint x, GLint y, GLchan rgba[][4] )
+_mesa_mask_rgba_span( GLcontext *ctx, const struct sw_span *span,
+ GLchan rgba[][4] )
{
+ SWcontext *swrast = SWRAST_CONTEXT(ctx);
GLchan dest[MAX_WIDTH][4];
- GLuint i;
-
#if CHAN_BITS == 8
-
GLuint srcMask = *((GLuint*)ctx->Color.ColorMask);
GLuint dstMask = ~srcMask;
GLuint *rgba32 = (GLuint *) rgba;
GLuint *dest32 = (GLuint *) dest;
+#else
+ const GLboolean rMask = ctx->Color.ColorMask[RCOMP];
+ const GLboolean gMask = ctx->Color.ColorMask[GCOMP];
+ const GLboolean bMask = ctx->Color.ColorMask[BCOMP];
+ const GLboolean aMask = ctx->Color.ColorMask[ACOMP];
+#endif
+ const GLuint n = span->end;
+ GLuint i;
- _mesa_read_rgba_span( ctx, ctx->DrawBuffer, n, x, y, dest );
+ ASSERT(n < MAX_WIDTH);
+ ASSERT(span->arrayMask & SPAN_RGBA);
+
+ if (span->arrayMask & SPAN_XY) {
+ (*swrast->Driver.ReadRGBAPixels)(ctx, n, span->array->x, span->array->y,
+ dest, span->array->mask);
+ if (SWRAST_CONTEXT(ctx)->_RasterMask & ALPHABUF_BIT) {
+ _mesa_read_alpha_pixels(ctx, n, span->array->x, span->array->y,
+ dest, span->array->mask);
+ }
+ }
+ else {
+ _mesa_read_rgba_span(ctx, ctx->DrawBuffer, n, span->x, span->y, dest);
+ }
+
+#if CHAN_BITS == 8
for (i = 0; i < n; i++) {
rgba32[i] = (rgba32[i] & srcMask) | (dest32[i] & dstMask);
}
-
#else
-
- const GLint rMask = ctx->Color.ColorMask[RCOMP];
- const GLint gMask = ctx->Color.ColorMask[GCOMP];
- const GLint bMask = ctx->Color.ColorMask[BCOMP];
- const GLint aMask = ctx->Color.ColorMask[ACOMP];
-
- _mesa_read_rgba_span( ctx, ctx->DrawBuffer, n, x, y, dest );
for (i = 0; i < n; i++) {
if (!rMask) rgba[i][RCOMP] = dest[i][RCOMP];
if (!gMask) rgba[i][GCOMP] = dest[i][GCOMP];
if (!bMask) rgba[i][BCOMP] = dest[i][BCOMP];
if (!aMask) rgba[i][ACOMP] = dest[i][ACOMP];
}
-
#endif
}
+
/*
- * Apply glColorMask to an array of RGBA pixels.
+ * Apply glColorMask to a span of RGBA pixels.
*/
void
-_mesa_mask_rgba_pixels( GLcontext *ctx,
- GLuint n, const GLint x[], const GLint y[],
- GLchan rgba[][4], const GLubyte mask[] )
+_mesa_mask_rgba_array( GLcontext *ctx,
+ GLuint n, GLint x, GLint y, GLchan rgba[][4] )
{
- SWcontext *swrast = SWRAST_CONTEXT(ctx);
- GLchan dest[PB_SIZE][4];
+ GLchan dest[MAX_WIDTH][4];
GLuint i;
#if CHAN_BITS == 8
@@ -102,12 +109,8 @@ _mesa_mask_rgba_pixels( GLcontext *ctx,
GLuint *rgba32 = (GLuint *) rgba;
GLuint *dest32 = (GLuint *) dest;
- (*swrast->Driver.ReadRGBAPixels)( ctx, n, x, y, dest, mask );
- if (SWRAST_CONTEXT(ctx)->_RasterMask & ALPHABUF_BIT) {
- _mesa_read_alpha_pixels( ctx, n, x, y, dest, mask );
- }
-
- for (i=0; i<n; i++) {
+ _mesa_read_rgba_span( ctx, ctx->DrawBuffer, n, x, y, dest );
+ for (i = 0; i < n; i++) {
rgba32[i] = (rgba32[i] & srcMask) | (dest32[i] & dstMask);
}
@@ -118,11 +121,7 @@ _mesa_mask_rgba_pixels( GLcontext *ctx,
const GLint bMask = ctx->Color.ColorMask[BCOMP];
const GLint aMask = ctx->Color.ColorMask[ACOMP];
- (*swrast->Driver.ReadRGBAPixels)( ctx, n, x, y, dest, mask );
- if (SWRAST_CONTEXT(ctx)->_RasterMask & ALPHABUF_BIT) {
- _mesa_read_alpha_pixels( ctx, n, x, y, dest, mask );
- }
-
+ _mesa_read_rgba_span( ctx, ctx->DrawBuffer, n, x, y, dest );
for (i = 0; i < n; i++) {
if (!rMask) rgba[i][RCOMP] = dest[i][RCOMP];
if (!gMask) rgba[i][GCOMP] = dest[i][GCOMP];
@@ -135,43 +134,53 @@ _mesa_mask_rgba_pixels( GLcontext *ctx,
-/*
- * Apply glIndexMask to a span of CI pixels.
- */
void
-_mesa_mask_index_span( GLcontext *ctx,
- GLuint n, GLint x, GLint y, GLuint index[] )
+_mesa_mask_index_span( GLcontext *ctx, const struct sw_span *span,
+ GLuint index[] )
{
- GLuint i;
+ SWcontext *swrast = SWRAST_CONTEXT(ctx);
+ const GLuint msrc = ctx->Color.IndexMask;
+ const GLuint mdest = ~msrc;
GLuint fbindexes[MAX_WIDTH];
- GLuint msrc, mdest;
+ GLuint i;
- _mesa_read_index_span( ctx, ctx->DrawBuffer, n, x, y, fbindexes );
+ ASSERT(span->arrayMask & SPAN_INDEX);
+ ASSERT(span->end < MAX_WIDTH);
- msrc = ctx->Color.IndexMask;
- mdest = ~msrc;
+ if (span->arrayMask & SPAN_XY) {
- for (i=0;i<n;i++) {
- index[i] = (index[i] & msrc) | (fbindexes[i] & mdest);
+ (*swrast->Driver.ReadCI32Pixels)(ctx, span->end, span->array->x,
+ span->array->y, fbindexes,
+ span->array->mask);
+
+ for (i = 0; i < span->end; i++) {
+ index[i] = (index[i] & msrc) | (fbindexes[i] & mdest);
+ }
+ }
+ else {
+ _mesa_read_index_span(ctx, ctx->DrawBuffer, span->end, span->x, span->y,
+ fbindexes );
+
+ for (i = 0; i < span->end; i++) {
+ index[i] = (index[i] & msrc) | (fbindexes[i] & mdest);
+ }
}
}
/*
- * Apply glIndexMask to an array of CI pixels.
+ * Apply glIndexMask to a span of CI pixels.
*/
void
-_mesa_mask_index_pixels( GLcontext *ctx,
- GLuint n, const GLint x[], const GLint y[],
- GLuint index[], const GLubyte mask[] )
+_mesa_mask_index_array( GLcontext *ctx,
+ GLuint n, GLint x, GLint y, GLuint index[] )
{
- SWcontext *swrast = SWRAST_CONTEXT(ctx);
GLuint i;
- GLuint fbindexes[PB_SIZE];
+ GLuint fbindexes[MAX_WIDTH];
GLuint msrc, mdest;
- (*swrast->Driver.ReadCI32Pixels)( ctx, n, x, y, fbindexes, mask );
+ _mesa_read_index_span( ctx, ctx->DrawBuffer, n, x, y, fbindexes );
msrc = ctx->Color.IndexMask;
mdest = ~msrc;
diff --git a/xc/extras/Mesa/src/swrast/s_masking.h b/xc/extras/Mesa/src/swrast/s_masking.h
index f79acf413..8b5c86366 100644
--- a/xc/extras/Mesa/src/swrast/s_masking.h
+++ b/xc/extras/Mesa/src/swrast/s_masking.h
@@ -1,10 +1,9 @@
-/* $Id: s_masking.h,v 1.1.1.1 2002/10/22 13:06:44 alanh Exp $ */
/*
* Mesa 3-D graphics library
- * Version: 3.5
+ * Version: 4.1
*
- * Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
+ * Copyright (C) 1999-2002 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"),
@@ -37,39 +36,26 @@
* Implement glColorMask for a span of RGBA pixels.
*/
extern void
-_mesa_mask_rgba_span( GLcontext *ctx,
- GLuint n, GLint x, GLint y,
+_mesa_mask_rgba_span( GLcontext *ctx, const struct sw_span *span,
GLchan rgba[][4] );
-
-/*
- * Implement glColorMask for an array of RGBA pixels.
- */
extern void
-_mesa_mask_rgba_pixels( GLcontext *ctx,
- GLuint n, const GLint x[], const GLint y[],
- GLchan rgba[][4], const GLubyte mask[] );
-
+_mesa_mask_rgba_array( GLcontext *ctx, GLuint n, GLint x, GLint y,
+ GLchan rgba[][4] );
/*
* Implement glIndexMask for a span of CI pixels.
*/
extern void
-_mesa_mask_index_span( GLcontext *ctx,
- GLuint n, GLint x, GLint y, GLuint index[] );
+_mesa_mask_index_span( GLcontext *ctx, const struct sw_span *span,
+ GLuint index[] );
-
-/*
- * Implement glIndexMask for an array of CI pixels.
- */
extern void
-_mesa_mask_index_pixels( GLcontext *ctx,
- GLuint n, const GLint x[], const GLint y[],
- GLuint index[], const GLubyte mask[] );
-
+_mesa_mask_index_array( GLcontext *ctx,
+ GLuint n, GLint x, GLint y, GLuint index[] );
#endif
diff --git a/xc/extras/Mesa/src/swrast/s_pb.c b/xc/extras/Mesa/src/swrast/s_pb.c
deleted file mode 100644
index a0da3a6b3..000000000
--- a/xc/extras/Mesa/src/swrast/s_pb.c
+++ /dev/null
@@ -1,517 +0,0 @@
-/* $Id: s_pb.c,v 1.1.1.1 2002/10/22 13:06:53 alanh Exp $ */
-
-/*
- * Mesa 3-D graphics library
- * Version: 3.5
- *
- * Copyright (C) 1999-2001 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.
- */
-
-
-
-/*
- * Pixel buffer:
- *
- * As fragments are produced (by point, line, and bitmap drawing) they
- * are accumlated in a buffer. When the buffer is full or has to be
- * flushed (glEnd), we apply all enabled rasterization functions to the
- * pixels and write the results to the display buffer. The goal is to
- * maximize the number of pixels processed inside loops and to minimize
- * the number of function calls.
- */
-
-
-#include "glheader.h"
-#include "macros.h"
-#include "mem.h"
-
-#include "s_alpha.h"
-#include "s_alphabuf.h"
-#include "s_blend.h"
-#include "s_context.h"
-#include "s_depth.h"
-#include "s_fog.h"
-#include "s_logic.h"
-#include "s_masking.h"
-#include "s_pb.h"
-#include "s_scissor.h"
-#include "s_stencil.h"
-#include "s_texture.h"
-
-
-
-/*
- * Allocate and initialize a new pixel buffer structure.
- */
-struct pixel_buffer *_mesa_alloc_pb(void)
-{
- struct pixel_buffer *pb;
- pb = CALLOC_STRUCT(pixel_buffer);
- if (pb) {
- int i, j;
- /* set non-zero fields */
- pb->mono = GL_TRUE;
-
- /* Set all lambda values to 0.0 since we don't do mipmapping for
- * points or lines and want to use the level 0 texture image.
- */
- for (j=0;j<MAX_TEXTURE_UNITS;j++) {
- for (i=0; i<PB_SIZE; i++) {
- pb->lambda[j][i] = 0.0;
- }
- }
- }
- return pb;
-}
-
-
-
-/*
- * Draw to more than one color buffer (or none).
- */
-static void multi_write_index_pixels( GLcontext *ctx, GLuint n,
- const GLint x[], const GLint y[],
- const GLuint indexes[],
- const GLubyte mask[] )
-{
- SWcontext *swrast = SWRAST_CONTEXT(ctx);
- GLuint bufferBit;
-
- if (ctx->Color.DrawBuffer == GL_NONE)
- return;
-
- /* loop over four possible dest color buffers */
- for (bufferBit = 1; bufferBit <= 8; bufferBit = bufferBit << 1) {
- if (bufferBit & ctx->Color.DrawDestMask) {
- GLuint indexTmp[PB_SIZE];
- ASSERT(n < PB_SIZE);
-
- if (bufferBit == FRONT_LEFT_BIT)
- (void) (*ctx->Driver.SetDrawBuffer)( ctx, GL_FRONT_LEFT);
- else if (bufferBit == FRONT_RIGHT_BIT)
- (void) (*ctx->Driver.SetDrawBuffer)( ctx, GL_FRONT_RIGHT);
- else if (bufferBit == BACK_LEFT_BIT)
- (void) (*ctx->Driver.SetDrawBuffer)( ctx, GL_BACK_LEFT);
- else
- (void) (*ctx->Driver.SetDrawBuffer)( ctx, GL_BACK_RIGHT);
-
- /* make copy of incoming indexes */
- MEMCPY( indexTmp, indexes, n * sizeof(GLuint) );
- if (ctx->Color.IndexLogicOpEnabled) {
- _mesa_logicop_ci_pixels( ctx, n, x, y, indexTmp, mask );
- }
- if (ctx->Color.IndexMask != 0xffffffff) {
- _mesa_mask_index_pixels( ctx, n, x, y, indexTmp, mask );
- }
- (*swrast->Driver.WriteCI32Pixels)( ctx, n, x, y, indexTmp, mask );
- }
- }
-
- /* restore default dest buffer */
- (void) (*ctx->Driver.SetDrawBuffer)( ctx, ctx->Color.DriverDrawBuffer);
-}
-
-
-
-/*
- * Draw to more than one RGBA color buffer (or none).
- */
-static void multi_write_rgba_pixels( GLcontext *ctx, GLuint n,
- const GLint x[], const GLint y[],
- CONST GLchan rgba[][4],
- const GLubyte mask[] )
-{
- SWcontext *swrast = SWRAST_CONTEXT(ctx);
- GLuint bufferBit;
-
- if (ctx->Color.DrawBuffer == GL_NONE)
- return;
-
- /* loop over four possible dest color buffers */
- for (bufferBit = 1; bufferBit <= 8; bufferBit = bufferBit << 1) {
- if (bufferBit & ctx->Color.DrawDestMask) {
- GLchan rgbaTmp[PB_SIZE][4];
- ASSERT(n < PB_SIZE);
-
- if (bufferBit == FRONT_LEFT_BIT) {
- (void) (*ctx->Driver.SetDrawBuffer)( ctx, GL_FRONT_LEFT);
- ctx->DrawBuffer->Alpha = ctx->DrawBuffer->FrontLeftAlpha;
- }
- else if (bufferBit == FRONT_RIGHT_BIT) {
- (void) (*ctx->Driver.SetDrawBuffer)( ctx, GL_FRONT_RIGHT);
- ctx->DrawBuffer->Alpha = ctx->DrawBuffer->FrontRightAlpha;
- }
- else if (bufferBit == BACK_LEFT_BIT) {
- (void) (*ctx->Driver.SetDrawBuffer)( ctx, GL_BACK_LEFT);
- ctx->DrawBuffer->Alpha = ctx->DrawBuffer->BackLeftAlpha;
- }
- else {
- (void) (*ctx->Driver.SetDrawBuffer)( ctx, GL_BACK_RIGHT);
- ctx->DrawBuffer->Alpha = ctx->DrawBuffer->BackRightAlpha;
- }
-
- /* make copy of incoming colors */
- MEMCPY( rgbaTmp, rgba, 4 * n * sizeof(GLchan) );
-
- if (ctx->Color.ColorLogicOpEnabled) {
- _mesa_logicop_rgba_pixels( ctx, n, x, y, rgbaTmp, mask );
- }
- else if (ctx->Color.BlendEnabled) {
- _mesa_blend_pixels( ctx, n, x, y, rgbaTmp, mask );
- }
- if (*((GLuint *) &ctx->Color.ColorMask) != 0xffffffff) {
- _mesa_mask_rgba_pixels( ctx, n, x, y, rgbaTmp, mask );
- }
-
- (*swrast->Driver.WriteRGBAPixels)( ctx, n, x, y,
- (const GLchan (*)[4])rgbaTmp, mask );
- if (SWRAST_CONTEXT(ctx)->_RasterMask & ALPHABUF_BIT) {
- _mesa_write_alpha_pixels( ctx, n, x, y,
- (const GLchan (*)[4])rgbaTmp, mask );
- }
- }
- }
-
- /* restore default dest buffer */
- (void) (*ctx->Driver.SetDrawBuffer)( ctx, ctx->Color.DriverDrawBuffer);
-}
-
-
-
-/*
- * Add specular color to primary color. This is used only when
- * GL_LIGHT_MODEL_COLOR_CONTROL = GL_SEPARATE_SPECULAR_COLOR.
- */
-static void add_colors( GLuint n, GLchan rgba[][4], CONST GLchan spec[][3] )
-{
- GLuint i;
- for (i=0; i<n; 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];
- rgba[i][RCOMP] = MIN2(r, CHAN_MAX);
- rgba[i][GCOMP] = MIN2(g, CHAN_MAX);
- rgba[i][BCOMP] = MIN2(b, CHAN_MAX);
- }
-}
-
-
-
-/*
- * When the pixel buffer is full, or needs to be flushed, call this
- * function. All the pixels in the pixel buffer will be subjected
- * to texturing, scissoring, stippling, alpha testing, stenciling,
- * depth testing, blending, and finally written to the frame buffer.
- */
-void _mesa_flush_pb( GLcontext *ctx )
-{
- SWcontext *swrast = SWRAST_CONTEXT(ctx);
- GLuint RasterMask = swrast->_RasterMask;
-
- /* Pixel colors may be changed if any of these raster ops enabled */
- const GLuint modBits = FOG_BIT | TEXTURE_BIT | BLEND_BIT |
- MASKING_BIT | LOGIC_OP_BIT;
- struct pixel_buffer *PB = swrast->PB;
- GLubyte mask[PB_SIZE];
-
- if (PB->count == 0)
- goto CleanUp;
-
- /* initialize mask array and clip pixels simultaneously */
- {
- const GLint xmin = ctx->DrawBuffer->_Xmin;
- const GLint xmax = ctx->DrawBuffer->_Xmax;
- const GLint ymin = ctx->DrawBuffer->_Ymin;
- const GLint ymax = ctx->DrawBuffer->_Ymax;
- const GLuint n = PB->count;
- GLint *x = PB->x;
- GLint *y = PB->y;
- GLuint i;
- for (i = 0; i < n; i++) {
- mask[i] = (x[i] >= xmin) & (x[i] < xmax) & (y[i] >= ymin) & (y[i] < ymax);
- }
- }
-
- if (ctx->Visual.rgbMode) {
- /*
- * RGBA COLOR PIXELS
- */
-
- /* If each pixel can be of a different color... */
- if ((RasterMask & modBits) || !PB->mono) {
-
- if (PB->mono) {
- /* copy mono color into rgba array */
- GLuint i;
- for (i = 0; i < PB->count; i++) {
- COPY_CHAN4(PB->rgba[i], PB->currentColor);
- }
- }
-
- if (ctx->Texture._ReallyEnabled) {
- GLchan primary_rgba[PB_SIZE][4];
- GLuint texUnit;
-
- /* must make a copy of primary colors since they may be modified */
- MEMCPY(primary_rgba, PB->rgba, 4 * PB->count * sizeof(GLchan));
-
- for (texUnit = 0; texUnit < ctx->Const.MaxTextureUnits; texUnit++){
- _swrast_texture_fragments( ctx, texUnit, PB->count,
- PB->s[texUnit], PB->t[texUnit],
- PB->u[texUnit], PB->lambda[texUnit],
- (CONST GLchan (*)[4]) primary_rgba,
- PB->rgba );
- }
- }
-
- if ((ctx->Fog.ColorSumEnabled ||
- (ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR
- && ctx->Light.Enabled)) && PB->haveSpec) {
- /* add specular color to primary color */
- add_colors( PB->count, PB->rgba, (const GLchan (*)[3]) PB->spec );
- }
-
- if (ctx->Fog.Enabled) {
- if (swrast->_PreferPixelFog)
- _mesa_depth_fog_rgba_pixels( ctx, PB->count, PB->z, PB->rgba );
- else
- _mesa_fog_rgba_pixels( ctx, PB->count, PB->fog, PB->rgba );
- }
-
- /* Antialias coverage application */
- if (PB->haveCoverage) {
- const GLuint n = PB->count;
- GLuint i;
- for (i = 0; i < n; i++) {
- PB->rgba[i][ACOMP] = (GLchan) (PB->rgba[i][ACOMP] * PB->coverage[i]);
- }
- }
-
- /* Scissoring already done above */
-
- if (ctx->Color.AlphaEnabled) {
- if (_mesa_alpha_test( ctx, PB->count,
- (const GLchan (*)[4]) PB->rgba, mask )==0) {
- goto CleanUp;
- }
- }
-
- if (ctx->Stencil.Enabled) {
- /* first stencil test */
- if (_mesa_stencil_and_ztest_pixels(ctx, PB->count,
- PB->x, PB->y, PB->z, mask) == 0) {
- goto CleanUp;
- }
- }
- else if (ctx->Depth.Test) {
- /* regular depth testing */
- _mesa_depth_test_pixels( ctx, PB->count, PB->x, PB->y, PB->z, mask );
- }
-
-
- if (RasterMask & MULTI_DRAW_BIT) {
- multi_write_rgba_pixels( ctx, PB->count, PB->x, PB->y,
- (const GLchan (*)[4])PB->rgba, mask );
- }
- else {
- /* normal case: write to exactly one buffer */
- const GLuint colorMask = *((GLuint *) ctx->Color.ColorMask);
-
- if (ctx->Color.ColorLogicOpEnabled) {
- _mesa_logicop_rgba_pixels( ctx, PB->count, PB->x, PB->y,
- PB->rgba, mask);
- }
- else if (ctx->Color.BlendEnabled) {
- _mesa_blend_pixels( ctx, PB->count, PB->x, PB->y, PB->rgba, mask);
- }
- if (colorMask == 0x0) {
- goto CleanUp;
- }
- else if (colorMask != 0xffffffff) {
- _mesa_mask_rgba_pixels(ctx, PB->count, PB->x, PB->y, PB->rgba, mask);
- }
-
- (*swrast->Driver.WriteRGBAPixels)( ctx, PB->count, PB->x, PB->y,
- (const GLchan (*)[4]) PB->rgba,
- mask );
- if (RasterMask & ALPHABUF_BIT) {
- _mesa_write_alpha_pixels( ctx, PB->count, PB->x, PB->y,
- (const GLchan (*)[4]) PB->rgba, mask );
- }
- }
- }
- else {
- /* Same color for all pixels */
-
- /* Scissoring already done above */
-
- if (ctx->Color.AlphaEnabled) {
- if (_mesa_alpha_test( ctx, PB->count,
- (const GLchan (*)[4]) PB->rgba, mask )==0) {
- goto CleanUp;
- }
- }
-
- if (ctx->Stencil.Enabled) {
- /* first stencil test */
- if (_mesa_stencil_and_ztest_pixels(ctx, PB->count,
- PB->x, PB->y, PB->z, mask) == 0) {
- goto CleanUp;
- }
- }
- else if (ctx->Depth.Test) {
- /* regular depth testing */
- _mesa_depth_test_pixels( ctx, PB->count, PB->x, PB->y, PB->z, mask );
- }
-
- if (ctx->Color.DrawBuffer == GL_NONE) {
- goto CleanUp;
- }
-
- if (RasterMask & MULTI_DRAW_BIT) {
- if (PB->mono) {
- /* copy mono color into rgba array */
- GLuint i;
- for (i = 0; i < PB->count; i++) {
- COPY_CHAN4(PB->rgba[i], PB->currentColor);
- }
- }
- multi_write_rgba_pixels( ctx, PB->count, PB->x, PB->y,
- (const GLchan (*)[4]) PB->rgba, mask );
- }
- else {
- /* normal case: write to exactly one buffer */
- (*swrast->Driver.WriteMonoRGBAPixels)( ctx, PB->count, PB->x, PB->y,
- PB->currentColor, mask );
- if (RasterMask & ALPHABUF_BIT) {
- _mesa_write_mono_alpha_pixels( ctx, PB->count, PB->x, PB->y,
- PB->currentColor[ACOMP], mask );
- }
- }
- /*** ALL DONE ***/
- }
- }
- else {
- /*
- * COLOR INDEX PIXELS
- */
-
- /* If we may be writting pixels with different indexes... */
- if ((RasterMask & modBits) || !PB->mono) {
-
- if (PB->mono) {
- GLuint i;
- for (i = 0; i < PB->count; i++) {
- PB->index[i] = PB->currentIndex;
- }
- }
- if (ctx->Fog.Enabled) {
- if (swrast->_PreferPixelFog)
- _mesa_depth_fog_ci_pixels( ctx, PB->count, PB->z, PB->index );
- else
- _mesa_fog_ci_pixels( ctx, PB->count, PB->fog, PB->index );
- }
-
- /* Antialias coverage application */
- if (PB->haveCoverage) {
- const GLuint n = PB->count;
- GLuint i;
- for (i = 0; i < n; i++) {
- GLint frac = (GLint) (15.0 * PB->coverage[i]);
- PB->index[i] = (PB->index[i] & ~0xf) | frac;
- }
- }
-
- /* Scissoring already done above */
-
- if (ctx->Stencil.Enabled) {
- /* first stencil test */
- if (_mesa_stencil_and_ztest_pixels(ctx, PB->count,
- PB->x, PB->y, PB->z, mask) == 0) {
- goto CleanUp;
- }
- }
- else if (ctx->Depth.Test) {
- /* regular depth testing */
- _mesa_depth_test_pixels( ctx, PB->count, PB->x, PB->y, PB->z, mask );
- }
- if (RasterMask & MULTI_DRAW_BIT) {
- multi_write_index_pixels( ctx, PB->count, PB->x, PB->y, PB->index, mask );
- }
- else {
- /* normal case: write to exactly one buffer */
-
- if (ctx->Color.IndexLogicOpEnabled) {
- _mesa_logicop_ci_pixels(ctx, PB->count, PB->x, PB->y,
- PB->index, mask);
- }
- if (ctx->Color.IndexMask != 0xffffffff) {
- _mesa_mask_index_pixels(ctx, PB->count, PB->x, PB->y,
- PB->index, mask);
- }
- (*swrast->Driver.WriteCI32Pixels)( ctx, PB->count, PB->x, PB->y,
- PB->index, mask );
- }
-
- /*** ALL DONE ***/
- }
- else {
- /* Same color index for all pixels */
-
- /* Scissoring already done above */
-
- if (ctx->Stencil.Enabled) {
- /* first stencil test */
- if (_mesa_stencil_and_ztest_pixels(ctx, PB->count,
- PB->x, PB->y, PB->z, mask) == 0) {
- goto CleanUp;
- }
- }
- else if (ctx->Depth.Test) {
- /* regular depth testing */
- _mesa_depth_test_pixels(ctx, PB->count, PB->x, PB->y, PB->z, mask);
- }
-
- if (RasterMask & MULTI_DRAW_BIT) {
- multi_write_index_pixels(ctx, PB->count, PB->x, PB->y,
- PB->index, mask);
- }
- else {
- /* normal case: write to exactly one buffer */
- (*swrast->Driver.WriteMonoCIPixels)(ctx, PB->count, PB->x, PB->y,
- PB->currentIndex, mask);
- }
- }
- }
-
-CleanUp:
- PB->count = 0;
- PB->mono = GL_TRUE;
- PB->haveSpec = GL_FALSE;
- PB->haveCoverage = GL_FALSE;
-}
-
-
-void
-_swrast_flush( GLcontext *ctx )
-{
- if (SWRAST_CONTEXT(ctx)->PB->count > 0)
- _mesa_flush_pb(ctx);
-}
diff --git a/xc/extras/Mesa/src/swrast/s_pb.h b/xc/extras/Mesa/src/swrast/s_pb.h
deleted file mode 100644
index 72d2df353..000000000
--- a/xc/extras/Mesa/src/swrast/s_pb.h
+++ /dev/null
@@ -1,244 +0,0 @@
-/* $Id: s_pb.h,v 1.1.1.1 2002/10/22 13:06:53 alanh Exp $ */
-
-/*
- * Mesa 3-D graphics library
- * Version: 3.5
- *
- * Copyright (C) 1999-2001 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.
- */
-
-
-#ifndef PB_H
-#define PB_H
-
-
-#include "mtypes.h"
-#include "swrast.h"
-#include "colormac.h"
-
-
-/*
- * Pixel buffer size, must be larger than MAX_WIDTH.
- */
-#define PB_SIZE (3*MAX_WIDTH)
-
-
-struct pixel_buffer {
- GLchan currentColor[4]; /* Current color, for subsequent pixels */
- GLuint currentIndex; /* Current index, for subsequent pixels */
- GLuint count; /* Number of pixels in buffer */
- GLboolean mono; /* Same color or index for all pixels? */
- GLboolean haveSpec; /* any specular colors? */
- GLboolean haveCoverage; /* apply AA coverage? */
-
- GLint x[PB_SIZE]; /* X window coord in [0,MAX_WIDTH) */
- GLint y[PB_SIZE]; /* Y window coord in [0,MAX_HEIGHT) */
- GLdepth z[PB_SIZE]; /* Z window coord in [0,Visual.MaxDepth] */
- GLfloat fog[PB_SIZE]; /* Fog window coord in [0,1] */
- GLchan rgba[PB_SIZE][4]; /* Colors */
- GLchan spec[PB_SIZE][3]; /* Separate specular colors */
- GLuint index[PB_SIZE]; /* Color indexes */
- GLfloat coverage[PB_SIZE]; /* Antialiasing coverage in [0,1] */
- GLfloat s[MAX_TEXTURE_UNITS][PB_SIZE]; /* Texture S coordinates */
- GLfloat t[MAX_TEXTURE_UNITS][PB_SIZE]; /* Texture T coordinates */
- GLfloat u[MAX_TEXTURE_UNITS][PB_SIZE]; /* Texture R coordinates */
- GLfloat lambda[MAX_TEXTURE_UNITS][PB_SIZE]; /* Texture lambda values */
-};
-
-
-
-/*
- * Set the color used for all subsequent pixels in the buffer.
- */
-#define PB_SET_COLOR( PB, R, G, B, A ) \
-do { \
- if ((PB)->count > 0) \
- (PB)->mono = GL_FALSE; \
- (PB)->currentColor[RCOMP] = (R); \
- (PB)->currentColor[GCOMP] = (G); \
- (PB)->currentColor[BCOMP] = (B); \
- (PB)->currentColor[ACOMP] = (A); \
-} while (0)
-
-
-/*
- * Set the color index used for all subsequent pixels in the buffer.
- */
-#define PB_SET_INDEX( PB, I ) \
-do { \
- if ((PB)->count > 0) \
- (PB)->mono = GL_FALSE; \
- (PB)->currentIndex = (I); \
-} while (0)
-
-
-/*
- * "write" a pixel using current color or index
- */
-#define PB_WRITE_PIXEL( PB, X, Y, Z, FOG ) \
-do { \
- GLuint count = (PB)->count; \
- (PB)->x[count] = X; \
- (PB)->y[count] = Y; \
- (PB)->z[count] = Z; \
- (PB)->fog[count] = FOG; \
- COPY_CHAN4((PB)->rgba[count], (PB)->currentColor); \
- (PB)->index[count] = (PB)->currentIndex; \
- (PB)->count++; \
-} while (0)
-
-
-/*
- * "write" an RGBA pixel
- */
-#define PB_WRITE_RGBA_PIXEL( PB, X, Y, Z, FOG, R, G, B, A ) \
-do { \
- GLuint count = (PB)->count; \
- (PB)->x[count] = X; \
- (PB)->y[count] = Y; \
- (PB)->z[count] = Z; \
- (PB)->fog[count] = FOG; \
- (PB)->rgba[count][RCOMP] = R; \
- (PB)->rgba[count][GCOMP] = G; \
- (PB)->rgba[count][BCOMP] = B; \
- (PB)->rgba[count][ACOMP] = A; \
- (PB)->mono = GL_FALSE; \
- (PB)->count++; \
-} while (0)
-
-
-/*
- * "write" a color-index pixel
- */
-#define PB_WRITE_CI_PIXEL( PB, X, Y, Z, FOG, I ) \
-do { \
- GLuint count = (PB)->count; \
- (PB)->x[count] = X; \
- (PB)->y[count] = Y; \
- (PB)->z[count] = Z; \
- (PB)->fog[count] = FOG; \
- (PB)->index[count] = I; \
- (PB)->mono = GL_FALSE; \
- (PB)->count++; \
-} while (0)
-
-
-
-/*
- * "write" an RGBA pixel with texture coordinates
- */
-#define PB_WRITE_TEX_PIXEL( PB, X, Y, Z, FOG, R, G, B, A, S, T, U ) \
-do { \
- GLuint count = (PB)->count; \
- (PB)->x[count] = X; \
- (PB)->y[count] = Y; \
- (PB)->z[count] = Z; \
- (PB)->fog[count] = FOG; \
- (PB)->rgba[count][RCOMP] = R; \
- (PB)->rgba[count][GCOMP] = G; \
- (PB)->rgba[count][BCOMP] = B; \
- (PB)->rgba[count][ACOMP] = A; \
- (PB)->s[0][count] = S; \
- (PB)->t[0][count] = T; \
- (PB)->u[0][count] = U; \
- (PB)->mono = GL_FALSE; \
- (PB)->count++; \
-} while (0)
-
-
-/*
- * "write" an RGBA pixel with multiple texture coordinates
- */
-#define PB_WRITE_MULTITEX_PIXEL( PB, X, Y, Z, FOG, R, G, B, A, TEXCOORDS ) \
-do { \
- GLuint count = (PB)->count; \
- GLuint unit; \
- (PB)->x[count] = X; \
- (PB)->y[count] = Y; \
- (PB)->z[count] = Z; \
- (PB)->fog[count] = FOG; \
- (PB)->rgba[count][RCOMP] = R; \
- (PB)->rgba[count][GCOMP] = G; \
- (PB)->rgba[count][BCOMP] = B; \
- (PB)->rgba[count][ACOMP] = A; \
- for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) { \
- if (ctx->Texture.Unit[unit]._ReallyEnabled) { \
- (PB)->s[unit][count] = TEXCOORDS[unit][0]; \
- (PB)->t[unit][count] = TEXCOORDS[unit][1]; \
- (PB)->u[unit][count] = TEXCOORDS[unit][2]; \
- } \
- } \
- (PB)->mono = GL_FALSE; \
- (PB)->count++; \
-} while (0)
-
-
-/*
- * "write" an RGBA pixel with multiple texture coordinates and specular color
- */
-#define PB_WRITE_MULTITEX_SPEC_PIXEL( PB, X, Y, Z, FOG, R, G, B, A, SR, SG, SB, TEXCOORDS )\
-do { \
- GLuint count = (PB)->count; \
- GLuint unit; \
- (PB)->haveSpec = GL_TRUE; \
- (PB)->x[count] = X; \
- (PB)->y[count] = Y; \
- (PB)->z[count] = Z; \
- (PB)->fog[count] = FOG; \
- (PB)->rgba[count][RCOMP] = R; \
- (PB)->rgba[count][GCOMP] = G; \
- (PB)->rgba[count][BCOMP] = B; \
- (PB)->rgba[count][ACOMP] = A; \
- (PB)->spec[count][RCOMP] = SR; \
- (PB)->spec[count][GCOMP] = SG; \
- (PB)->spec[count][BCOMP] = SB; \
- for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) { \
- if (ctx->Texture.Unit[unit]._ReallyEnabled) { \
- (PB)->s[unit][count] = TEXCOORDS[unit][0]; \
- (PB)->t[unit][count] = TEXCOORDS[unit][1]; \
- (PB)->u[unit][count] = TEXCOORDS[unit][2]; \
- } \
- } \
- (PB)->mono = GL_FALSE; \
- (PB)->count++; \
-} while (0)
-
-
-#define PB_COVERAGE(PB, COVERAGE) \
- (PB)->coverage[(PB)->count] = COVERAGE;
-
-
-/*
- * Call this function at least every MAX_WIDTH pixels:
- */
-#define PB_CHECK_FLUSH( CTX, PB ) \
-do { \
- if ((PB)->count >= PB_SIZE - MAX_WIDTH) { \
- _mesa_flush_pb( CTX ); \
- } \
-} while(0)
-
-
-extern struct pixel_buffer *_mesa_alloc_pb(void);
-
-extern void _mesa_flush_pb( GLcontext *ctx );
-
-
-#endif
diff --git a/xc/extras/Mesa/src/swrast/s_pixeltex.c b/xc/extras/Mesa/src/swrast/s_pixeltex.c
index f52972ff7..776a38c91 100644
--- a/xc/extras/Mesa/src/swrast/s_pixeltex.c
+++ b/xc/extras/Mesa/src/swrast/s_pixeltex.c
@@ -1,10 +1,9 @@
-/* $Id: s_pixeltex.c,v 1.1.1.1 2002/10/22 13:06:56 alanh Exp $ */
/*
* Mesa 3-D graphics library
- * Version: 3.5
+ * Version: 4.1
*
- * Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
+ * Copyright (C) 1999-2002 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"),
@@ -35,47 +34,84 @@
#include "glheader.h"
#include "colormac.h"
+#include "imports.h"
#include "s_context.h"
#include "s_pixeltex.h"
+#include "s_texture.h"
/*
* Convert RGBA values into strq texture coordinates.
*/
-void
-_mesa_pixeltexgen(GLcontext *ctx, GLuint n, const GLchan rgba[][4],
- GLfloat s[], GLfloat t[], GLfloat r[], GLfloat q[])
+static void
+pixeltexgen(GLcontext *ctx, GLuint n, const GLchan rgba[][4],
+ GLfloat texcoord[][4])
{
if (ctx->Pixel.FragmentRgbSource == GL_CURRENT_RASTER_COLOR) {
GLuint i;
for (i = 0; i < n; i++) {
- s[i] = ctx->Current.RasterColor[RCOMP];
- t[i] = ctx->Current.RasterColor[GCOMP];
- r[i] = ctx->Current.RasterColor[BCOMP];
+ texcoord[i][0] = ctx->Current.RasterColor[RCOMP];
+ texcoord[i][1] = ctx->Current.RasterColor[GCOMP];
+ texcoord[i][2] = ctx->Current.RasterColor[BCOMP];
}
}
else {
GLuint i;
ASSERT(ctx->Pixel.FragmentRgbSource == GL_PIXEL_GROUP_COLOR_SGIS);
for (i = 0; i < n; i++) {
- s[i] = CHAN_TO_FLOAT(rgba[i][RCOMP]);
- t[i] = CHAN_TO_FLOAT(rgba[i][GCOMP]);
- r[i] = CHAN_TO_FLOAT(rgba[i][BCOMP]);
+ texcoord[i][0] = CHAN_TO_FLOAT(rgba[i][RCOMP]);
+ texcoord[i][1] = CHAN_TO_FLOAT(rgba[i][GCOMP]);
+ texcoord[i][2] = CHAN_TO_FLOAT(rgba[i][BCOMP]);
}
}
if (ctx->Pixel.FragmentAlphaSource == GL_CURRENT_RASTER_COLOR) {
GLuint i;
for (i = 0; i < n; i++) {
- q[i] = ctx->Current.RasterColor[ACOMP];
+ texcoord[i][3] = ctx->Current.RasterColor[ACOMP];
}
}
else {
GLuint i;
ASSERT(ctx->Pixel.FragmentAlphaSource == GL_PIXEL_GROUP_COLOR_SGIS);
for (i = 0; i < n; i++) {
- q[i] = CHAN_TO_FLOAT(rgba[i][ACOMP]);
+ texcoord[i][3] = CHAN_TO_FLOAT(rgba[i][ACOMP]);
+ }
+ }
+}
+
+
+
+/*
+ * Used by glDraw/CopyPixels: the incoming image colors are treated
+ * as texture coordinates. Use those coords to texture the image.
+ * This is for GL_SGIS_pixel_texture / GL_SGIX_pixel_texture.
+ */
+void
+_swrast_pixel_texture(GLcontext *ctx, struct sw_span *span)
+{
+ GLuint unit;
+
+ ASSERT(!(span->arrayMask & SPAN_TEXTURE));
+ span->arrayMask |= SPAN_TEXTURE;
+
+ /* convert colors into texture coordinates */
+ pixeltexgen( ctx, span->end,
+ (const GLchan (*)[4]) span->array->rgba,
+ span->array->texcoords[0] );
+
+ /* copy the new texture units for all enabled units */
+ for (unit = 1; unit < ctx->Const.MaxTextureUnits; unit++) {
+ if (ctx->Texture.Unit[unit]._ReallyEnabled) {
+ MEMCPY( span->array->texcoords[unit], span->array->texcoords[0],
+ span->end * 4 * sizeof(GLfloat) );
}
}
+
+ /* apply texture mapping */
+ _swrast_texture_span( ctx, span );
+
+ /* this is a work-around to be fixed by initializing again span */
+ span->arrayMask &= ~SPAN_TEXTURE;
}
diff --git a/xc/extras/Mesa/src/swrast/s_pixeltex.h b/xc/extras/Mesa/src/swrast/s_pixeltex.h
index 7d1d8047c..6ef7a44df 100644
--- a/xc/extras/Mesa/src/swrast/s_pixeltex.h
+++ b/xc/extras/Mesa/src/swrast/s_pixeltex.h
@@ -1,10 +1,9 @@
-/* $Id: s_pixeltex.h,v 1.1.1.1 2002/10/22 13:06:56 alanh Exp $ */
/*
* Mesa 3-D graphics library
- * Version: 3.5
+ * Version: 4.1
*
- * Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
+ * Copyright (C) 1999-2002 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -31,9 +30,9 @@
#include "mtypes.h"
#include "swrast.h"
+
extern void
-_mesa_pixeltexgen(GLcontext *ctx, GLuint n, const GLchan rgba[][4],
- GLfloat s[], GLfloat t[], GLfloat r[], GLfloat q[]);
+_swrast_pixel_texture(GLcontext *ctx, struct sw_span *span);
#endif
diff --git a/xc/extras/Mesa/src/swrast/s_points.c b/xc/extras/Mesa/src/swrast/s_points.c
index 75f4b7811..5ef41d9fb 100644
--- a/xc/extras/Mesa/src/swrast/s_points.c
+++ b/xc/extras/Mesa/src/swrast/s_points.c
@@ -1,10 +1,9 @@
-/* $Id: s_points.c,v 1.1.1.1 2002/10/22 13:06:58 alanh Exp $ */
/*
* Mesa 3-D graphics library
- * Version: 3.5
+ * Version: 4.1
*
- * Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
+ * Copyright (C) 1999-2002 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"),
@@ -33,20 +32,19 @@
#include "texstate.h"
#include "s_context.h"
#include "s_feedback.h"
-#include "s_pb.h"
#include "s_points.h"
#include "s_span.h"
-#define INDEX 0x0
#define RGBA 0x1
-#define SMOOTH 0x2
-#define TEXTURE 0x4
-#define SPECULAR 0x8
-#define LARGE 0x10
-#define ATTENUATE 0x20
-#define SPRITE 0x40
+#define INDEX 0x2
+#define SMOOTH 0x4
+#define TEXTURE 0x8
+#define SPECULAR 0x10
+#define LARGE 0x20
+#define ATTENUATE 0x40
+#define SPRITE 0x80
/*
@@ -148,12 +146,12 @@
/*
* Sprite (textured point)
*/
-#define FLAGS (RGBA | TEXTURE | SPRITE)
+#define FLAGS (RGBA | SPRITE)
#define NAME sprite_point
#include "s_pointtemp.h"
-#define FLAGS (RGBA | ATTENUATE | TEXTURE | SPRITE)
+#define FLAGS (RGBA | ATTENUATE | SPRITE)
#define NAME atten_sprite_point
#include "s_pointtemp.h"
@@ -202,7 +200,8 @@ _swrast_choose_point( GLcontext *ctx )
GLboolean rgbMode = ctx->Visual.rgbMode;
if (ctx->RenderMode==GL_RENDER) {
- if (ctx->Point.SpriteMode) {
+ if (ctx->Point.PointSprite) {
+ /* GL_NV_point_sprite */
/* XXX this might not be good enough */
if (ctx->Point._Attenuated)
USE(atten_sprite_point);
@@ -212,10 +211,10 @@ _swrast_choose_point( GLcontext *ctx )
else if (ctx->Point.SmoothFlag) {
/* Smooth points */
if (rgbMode) {
- if (ctx->Point._Attenuated) {
+ if (ctx->Point._Attenuated || ctx->VertexProgram.PointSizeEnabled) {
USE(atten_antialiased_rgba_point);
}
- else if (ctx->Texture._ReallyEnabled) {
+ else if (ctx->Texture._EnabledUnits) {
USE(antialiased_tex_rgba_point);
}
else {
@@ -226,9 +225,9 @@ _swrast_choose_point( GLcontext *ctx )
USE(antialiased_ci_point);
}
}
- else if (ctx->Point._Attenuated) {
+ else if (ctx->Point._Attenuated || ctx->VertexProgram.PointSizeEnabled) {
if (rgbMode) {
- if (ctx->Texture._ReallyEnabled) {
+ if (ctx->Texture._EnabledUnits) {
if (ctx->Point.SmoothFlag) {
USE(atten_antialiased_rgba_point);
}
@@ -245,7 +244,7 @@ _swrast_choose_point( GLcontext *ctx )
USE(atten_general_ci_point);
}
}
- else if (ctx->Texture._ReallyEnabled && rgbMode) {
+ else if (ctx->Texture._EnabledUnits && rgbMode) {
/* textured */
USE(textured_rgba_point);
}
diff --git a/xc/extras/Mesa/src/swrast/s_points.h b/xc/extras/Mesa/src/swrast/s_points.h
index 0b2ec5ba6..40b442e95 100644
--- a/xc/extras/Mesa/src/swrast/s_points.h
+++ b/xc/extras/Mesa/src/swrast/s_points.h
@@ -1,4 +1,3 @@
-/* $Id: s_points.h,v 1.1.1.1 2002/10/22 13:06:58 alanh Exp $ */
/*
* Mesa 3-D graphics library
@@ -30,10 +29,10 @@
#include "mtypes.h"
-void
+extern void
_swrast_choose_point( GLcontext *ctx );
-void
+extern void
_swrast_add_spec_terms_point( GLcontext *ctx,
const SWvertex *v0 );
diff --git a/xc/extras/Mesa/src/swrast/s_pointtemp.h b/xc/extras/Mesa/src/swrast/s_pointtemp.h
index efef56bc0..8f07fa25a 100644
--- a/xc/extras/Mesa/src/swrast/s_pointtemp.h
+++ b/xc/extras/Mesa/src/swrast/s_pointtemp.h
@@ -1,10 +1,9 @@
-/* $Id: s_pointtemp.h,v 1.1.1.1 2002/10/22 13:06:54 alanh Exp $ */
/*
* Mesa 3-D graphics library
- * Version: 3.5
+ * Version: 5.0
*
- * Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
+ * Copyright (C) 1999-2002 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -36,7 +35,7 @@
* SPECULAR = do separate specular color
* LARGE = do points with diameter > 1 pixel
* ATTENUATE = compute point size attenuation
- * SPRITE = GL_MESA_sprite_point
+ * SPRITE = GL_NV_point_sprite
*
* Notes: LARGE and ATTENUATE are exclusive of each other.
* TEXTURE requires RGBA
@@ -53,7 +52,7 @@
* else if d > rmax2 then
* fragment has 0% coverage
* else
- * fragement has % coverage = (d - rmin2) / (rmax2 - rmin2)
+ * fragment has % coverage = (d - rmin2) / (rmax2 - rmin2)
*/
@@ -61,49 +60,76 @@
static void
NAME ( GLcontext *ctx, const SWvertex *vert )
{
- SWcontext *swrast = SWRAST_CONTEXT(ctx);
- struct pixel_buffer *PB = swrast->PB;
-
- const GLint z = (GLint) (vert->win[2]);
-
+#if FLAGS & (ATTENUATE | LARGE | SMOOTH | SPRITE)
+ GLfloat size;
+#endif
+#if FLAGS & ATTENUATE
+ GLfloat alphaAtten;
+#endif
#if FLAGS & RGBA
const GLchan red = vert->color[0];
const GLchan green = vert->color[1];
const GLchan blue = vert->color[2];
- GLchan alpha = vert->color[3];
+ const GLchan alpha = vert->color[3];
+#endif
#if FLAGS & SPECULAR
- const GLchan sRed = vert->specular[0];
- const GLchan sGreen = vert->specular[1];
- const GLchan sBlue = vert->specular[2];
+ const GLchan specRed = vert->specular[0];
+ const GLchan specGreen = vert->specular[1];
+ const GLchan specBlue = vert->specular[2];
#endif
-#else
- GLint index = vert->index;
+#if FLAGS & INDEX
+ const GLuint colorIndex = vert->index;
#endif
-#if FLAGS & (ATTENUATE | LARGE | SMOOTH)
- GLfloat size;
-#endif
-#if FLAGS & ATTENUATE
- GLfloat alphaAtten;
-#endif
-
#if FLAGS & TEXTURE
GLfloat texcoord[MAX_TEXTURE_UNITS][4];
GLuint u;
+#endif
+ SWcontext *swrast = SWRAST_CONTEXT(ctx);
+ struct sw_span *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->fog = vert->fog;
+ span->fogStep = 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;
for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
if (ctx->Texture.Unit[u]._ReallyEnabled) {
- if (vert->texcoord[u][3] != 1.0 && vert->texcoord[u][3] != 0.0) {
- texcoord[u][0] = vert->texcoord[u][0] / vert->texcoord[u][3];
- texcoord[u][1] = vert->texcoord[u][1] / vert->texcoord[u][3];
- texcoord[u][2] = vert->texcoord[u][2] / vert->texcoord[u][3];
- }
- else {
- texcoord[u][0] = vert->texcoord[u][0];
- texcoord[u][1] = vert->texcoord[u][1];
- texcoord[u][2] = vert->texcoord[u][2];
- }
+ const GLfloat q = vert->texcoord[u][3];
+ const GLfloat invQ = (q == 0.0F || q == 1.0F) ? 1.0F : (1.0F / q);
+ texcoord[u][0] = vert->texcoord[u][0] * invQ;
+ texcoord[u][1] = vert->texcoord[u][1] * invQ;
+ texcoord[u][2] = vert->texcoord[u][2] * invQ;
+ texcoord[u][3] = q;
}
}
#endif
+#if FLAGS & SMOOTH
+ span->arrayMask |= SPAN_COVERAGE;
+#endif
+#if FLAGS & SPRITE
+ span->arrayMask |= SPAN_TEXTURE;
+#endif
#if FLAGS & ATTENUATE
if (vert->pointSize >= ctx->Point.Threshold) {
@@ -115,78 +141,19 @@ NAME ( GLcontext *ctx, const SWvertex *vert )
size = MAX2(ctx->Point.Threshold, ctx->Point.MinSize);
alphaAtten = dsize * dsize;
}
-#elif FLAGS & (LARGE | SMOOTH)
+#elif FLAGS & (LARGE | SMOOTH | SPRITE)
size = ctx->Point._Size;
#endif
- /* Cull primitives with malformed coordinates.
+#if FLAGS & (ATTENUATE | LARGE | SMOOTH | SPRITE)
+ /*
+ * Multi-pixel points
*/
- {
- float tmp = vert->win[0] + vert->win[1];
- if (IS_INF_OR_NAN(tmp))
- return;
- }
-
-#if FLAGS & SPRITE
- {
- SWcontext *swctx = SWRAST_CONTEXT(ctx);
- const GLfloat radius = 0.5F * vert->pointSize; /* XXX threshold, alpha */
- SWvertex v0, v1, v2, v3;
- GLuint unit;
-
- (void) red;
- (void) green;
- (void) blue;
- (void) alpha;
- (void) z;
-
- /* lower left corner */
- v0 = *vert;
- v0.win[0] -= radius;
- v0.win[1] -= radius;
-
- /* lower right corner */
- v1 = *vert;
- v1.win[0] += radius;
- v1.win[1] -= radius;
-
- /* upper right corner */
- v2 = *vert;
- v2.win[0] += radius;
- v2.win[1] += radius;
-
- /* upper left corner */
- v3 = *vert;
- v3.win[0] -= radius;
- v3.win[1] += radius;
-
- for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) {
- if (ctx->Texture.Unit[unit]._ReallyEnabled) {
- v0.texcoord[unit][0] = 0.0;
- v0.texcoord[unit][1] = 0.0;
- v1.texcoord[unit][0] = 1.0;
- v1.texcoord[unit][1] = 0.0;
- v2.texcoord[unit][0] = 1.0;
- v2.texcoord[unit][1] = 1.0;
- v3.texcoord[unit][0] = 0.0;
- v3.texcoord[unit][1] = 1.0;
- }
- }
-
- /* XXX if radius < threshold, attenuate alpha? */
-
- /* XXX need to implement clipping!!! */
-
- /* render */
- swctx->Triangle(ctx, &v0, &v1, &v2);
- swctx->Triangle(ctx, &v0, &v2, &v3);
- }
-
-#elif FLAGS & (LARGE | ATTENUATE | SMOOTH)
-
- {
+ {{
GLint x, y;
const GLfloat radius = 0.5F * size;
+ const GLint z = (GLint) (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;
@@ -218,109 +185,186 @@ NAME ( GLcontext *ctx, const SWvertex *vert )
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 FLAGS & (TEXTURE | SPRITE)
+ if (ctx->Texture._EnabledUnits)
+ _mesa_write_texture_span(ctx, span);
+ else
+ _mesa_write_rgba_span(ctx, span);
+#elif FLAGS & RGBA
+ _mesa_write_rgba_span(ctx, span);
+#else
+ _mesa_write_index_span(ctx, span);
#endif
- (void) radius;
+ span->end = 0;
+ }
+ /*
+ * OK, generate fragments
+ */
+ count = span->end;
+ (void) radius;
for (y = ymin; y <= ymax; y++) {
for (x = xmin; x <= xmax; x++) {
-#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 FLAGS & RGBA
- alpha = vert->color[3];
+#if FLAGS & (SPRITE | TEXTURE)
+ GLuint u;
#endif
- if (dist2 >= rmin2) {
- /* compute partial coverage */
- PB_COVERAGE(PB, 1.0F - (dist2 - rmin2) * cscale);
- }
- else {
- /* full coverage */
- PB_COVERAGE(PB, 1.0F);
- }
-
-#endif /* SMOOTH */
-#if ((FLAGS & (ATTENUATE | RGBA)) == (ATTENUATE | RGBA))
- alpha = (GLchan) (alpha * alphaAtten);
+#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
- PB_WRITE_MULTITEX_SPEC_PIXEL(PB, x, y, z, vert->fog,
- red, green, blue, alpha,
- sRed, sGreen, sBlue,
- texcoord);
-#elif FLAGS & TEXTURE
- if (ctx->Texture._ReallyEnabled > TEXTURE0_ANY) {
- PB_WRITE_MULTITEX_PIXEL(PB, x, y, z, vert->fog,
- red, green, blue, alpha,
- texcoord);
- }
- else if (ctx->Texture._ReallyEnabled) {
- PB_WRITE_TEX_PIXEL(PB, x,y,z, vert->fog,
- red, green, blue, alpha,
- texcoord[0][0],
- texcoord[0][1],
- texcoord[0][2]);
- }
- else {
- PB_WRITE_RGBA_PIXEL(PB, x, y, z, vert->fog,
- red, green, blue, alpha);
- }
-#elif FLAGS & RGBA
- PB_WRITE_RGBA_PIXEL(PB, x, y, z, vert->fog,
- red, green, blue, alpha);
-#else /* color index */
- PB_WRITE_CI_PIXEL(PB, x, y, z, vert->fog, index);
+ span->array->spec[count][RCOMP] = specRed;
+ span->array->spec[count][GCOMP] = specGreen;
+ span->array->spec[count][BCOMP] = specBlue;
#endif
-#if FLAGS & SMOOTH
- }
+#if FLAGS & INDEX
+ span->array->index[count] = colorIndex;
+#endif
+#if FLAGS & TEXTURE
+ for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
+ if (ctx->Texture.Unit[u]._ReallyEnabled) {
+ COPY_4V(span->array->texcoords[u][count], texcoord[u]);
+ }
+ }
#endif
- }
- }
#if FLAGS & SMOOTH
- PB->haveCoverage = GL_TRUE;
+ /* 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*/
+ }
- PB_CHECK_FLUSH(ctx,PB);
- }
+#else /*SMOOTH*/
-#else /* LARGE || ATTENUATE || SMOOTH*/
+ /* not smooth (square points) */
+ span->array->x[count] = x;
+ span->array->y[count] = y;
+ span->array->z[count] = z;
- {
- /* size == 1 */
- GLint x = (GLint) vert->win[0];
- GLint y = (GLint) vert->win[1];
-#if ((FLAGS & (SPECULAR | TEXTURE)) == (SPECULAR | TEXTURE))
- PB_WRITE_MULTITEX_SPEC_PIXEL(PB, x, y, z, vert->fog,
- red, green, blue, alpha,
- sRed, sGreen, sBlue,
- texcoord);
-#elif FLAGS & TEXTURE
- if (ctx->Texture._ReallyEnabled > TEXTURE0_ANY) {
- PB_WRITE_MULTITEX_PIXEL(PB, x, y, z, vert->fog,
- red, green, blue, alpha, texcoord );
- }
- else {
- PB_WRITE_TEX_PIXEL(PB, x, y, z, vert->fog,
- red, green, blue, alpha,
- texcoord[0][0], texcoord[0][1], texcoord[0][2]);
- }
+#if FLAGS & SPRITE
+ for (u = 0; u < ctx->Const.MaxTextureUnits; 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 = 0.5F - (y + 0.5F - vert->win[1]) / size;
+ span->array->texcoords[u][count][0] = s;
+ span->array->texcoords[u][count][1] = t;
+ span->array->texcoords[u][count][3] = 1.0F;
+ if (ctx->Point.SpriteRMode == GL_ZERO)
+ span->array->texcoords[u][count][2] = 0.0F;
+ else if (ctx->Point.SpriteRMode == GL_S)
+ span->array->texcoords[u][count][2] = vert->texcoord[u][0];
+ else /* GL_R */
+ span->array->texcoords[u][count][2] = vert->texcoord[u][2];
+ }
+ else {
+ COPY_4V(span->array->texcoords[u][count], vert->texcoord[u]);
+ }
+ }
+ }
+#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 & (TEXTURE | SPRITE)
+ if (ctx->Texture._EnabledUnits)
+ _mesa_write_texture_span(ctx, span);
+ else
+ _mesa_write_rgba_span(ctx, span);
#elif FLAGS & RGBA
- /* rgba size 1 point */
- alpha = vert->color[3];
- PB_WRITE_RGBA_PIXEL(PB, x, y, z, vert->fog, red, green, blue, alpha);
+ _mesa_write_rgba_span(ctx, span);
#else
- /* color index size 1 point */
- PB_WRITE_CI_PIXEL(PB, x, y, z, vert->fog, index);
+ _mesa_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 (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
+ if (ctx->Texture.Unit[u]._ReallyEnabled) {
+ COPY_4V(span->array->texcoords[u][count], texcoord[u]);
+ }
+ }
+#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 */
- PB_CHECK_FLUSH(ctx, PB);
+ ASSERT(span->end <= MAX_WIDTH);
}
diff --git a/xc/extras/Mesa/src/swrast/s_readpix.c b/xc/extras/Mesa/src/swrast/s_readpix.c
index 666baa286..672109982 100644
--- a/xc/extras/Mesa/src/swrast/s_readpix.c
+++ b/xc/extras/Mesa/src/swrast/s_readpix.c
@@ -1,8 +1,7 @@
-/* $Id: s_readpix.c,v 1.1.1.1 2002/10/22 13:06:56 alanh Exp $ */
/*
* Mesa 3-D graphics library
- * Version: 4.0.3
+ * Version: 4.1
*
* Copyright (C) 1999-2002 Brian Paul All Rights Reserved.
*
@@ -32,7 +31,7 @@
#include "feedback.h"
#include "image.h"
#include "macros.h"
-#include "mem.h"
+#include "imports.h"
#include "pixel.h"
#include "s_alphabuf.h"
@@ -62,9 +61,7 @@ read_index_pixels( GLcontext *ctx,
return;
}
- ASSERT(swrast->Driver.SetReadBuffer);
- (*swrast->Driver.SetReadBuffer)(ctx, ctx->ReadBuffer,
- ctx->Pixel.DriverReadBuffer);
+ _swrast_use_read_buffer(ctx);
readWidth = (width > MAX_WIDTH) ? MAX_WIDTH : width;
@@ -82,8 +79,7 @@ read_index_pixels( GLcontext *ctx,
&ctx->Pack, ctx->_ImageTransferState);
}
- (*swrast->Driver.SetReadBuffer)(ctx, ctx->DrawBuffer,
- ctx->Color.DriverDrawBuffer);
+ _swrast_use_draw_buffer(ctx);
}
@@ -282,8 +278,15 @@ read_fast_rgba_pixels( GLcontext *ctx,
if (0) {
#endif
GLchan *dest = (GLchan *) pixels
- + (skipRows * rowLength + skipPixels) * 4;
+ + (skipRows * rowLength + skipPixels) * 4;
GLint row;
+
+ if (packing->Invert) {
+ /* start at top and go down */
+ dest += (readHeight - 1) * rowLength * 4;
+ rowLength = -rowLength;
+ }
+
for (row=0; row<readHeight; row++) {
(*swrast->Driver.ReadRGBASpan)(ctx, readWidth, srcX, srcY,
(GLchan (*)[4]) dest);
@@ -318,13 +321,13 @@ read_rgba_pixels( GLcontext *ctx,
SWcontext *swrast = SWRAST_CONTEXT(ctx);
GLint readWidth;
- (*swrast->Driver.SetReadBuffer)(ctx, ctx->ReadBuffer, ctx->Pixel.DriverReadBuffer);
+ _swrast_use_read_buffer(ctx);
/* Try optimized path first */
if (read_fast_rgba_pixels( ctx, x, y, width, height,
format, type, pixels, packing )) {
- (*swrast->Driver.SetReadBuffer)(ctx, ctx->DrawBuffer, ctx->Color.DriverDrawBuffer);
+ _swrast_use_draw_buffer(ctx);
return; /* done! */
}
@@ -470,7 +473,7 @@ read_rgba_pixels( GLcontext *ctx,
}
}
- (*swrast->Driver.SetReadBuffer)(ctx, ctx->DrawBuffer, ctx->Color.DriverDrawBuffer);
+ _swrast_use_draw_buffer(ctx);
}
diff --git a/xc/extras/Mesa/src/swrast/s_scissor.c b/xc/extras/Mesa/src/swrast/s_scissor.c
deleted file mode 100644
index 3558b91d0..000000000
--- a/xc/extras/Mesa/src/swrast/s_scissor.c
+++ /dev/null
@@ -1,64 +0,0 @@
-/* $Id: s_scissor.c,v 1.1.1.1 2002/10/22 13:06:51 alanh Exp $ */
-
-/*
- * Mesa 3-D graphics library
- * Version: 3.5
- *
- * Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-
-#include "glheader.h"
-#include "macros.h"
-#include "mem.h"
-#include "s_context.h"
-#include "s_scissor.h"
-
-
-/*
- * Apply the scissor test to a span of pixels.
- * Return: 0 = all pixels in the span are outside the scissor box.
- * n = mask[n-1] is the last one to be visible
- */
-GLuint
-_mesa_scissor_span(GLcontext *ctx, GLuint n, GLint x, GLint y, GLubyte mask[])
-{
- /* first check if whole span is outside the scissor box */
- if (y < ctx->DrawBuffer->_Ymin
- || y >= ctx->DrawBuffer->_Ymax
- || x > ctx->DrawBuffer->_Xmax
- || x + (GLint) n - 1 < ctx->DrawBuffer->_Xmin) {
- return 0;
- }
- else {
- const GLint xMin = ctx->DrawBuffer->_Xmin;
- const GLint xMax = ctx->DrawBuffer->_Xmax;
-
- if (x < xMin)
- BZERO(mask, (xMin-x) * sizeof(GLubyte));
-
- if (x + (GLint) n > xMax) {
- BZERO(mask + xMax - x, (n - (xMax - x)) * sizeof(GLubyte));
- return (GLuint) (xMax - x);
- }
-
- return n;
- }
-}
diff --git a/xc/extras/Mesa/src/swrast/s_scissor.h b/xc/extras/Mesa/src/swrast/s_scissor.h
deleted file mode 100644
index ec454e4dd..000000000
--- a/xc/extras/Mesa/src/swrast/s_scissor.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/* $Id: s_scissor.h,v 1.1.1.1 2002/10/22 13:06:51 alanh Exp $ */
-
-/*
- * Mesa 3-D graphics library
- * Version: 3.5
- *
- * Copyright (C) 1999-2001 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.
- */
-
-
-#ifndef S_SCISSOR_H
-#define S_SCISSOR_H
-
-
-#include "mtypes.h"
-#include "swrast.h"
-
-
-extern GLuint
-_mesa_scissor_span(GLcontext *ctx, GLuint n, GLint x, GLint y, GLubyte mask[]);
-
-
-#endif
diff --git a/xc/extras/Mesa/src/swrast/s_span.c b/xc/extras/Mesa/src/swrast/s_span.c
index 375fe6a96..784279c7d 100644
--- a/xc/extras/Mesa/src/swrast/s_span.c
+++ b/xc/extras/Mesa/src/swrast/s_span.c
@@ -1,8 +1,7 @@
-/* $Id: s_span.c,v 1.1.1.1 2002/10/22 13:06:57 alanh Exp $ */
/*
* Mesa 3-D graphics library
- * Version: 4.0.3
+ * Version: 5.0.1
*
* Copyright (C) 1999-2002 Brian Paul All Rights Reserved.
*
@@ -25,16 +24,19 @@
*/
-/*
- * pixel span rasterization:
- * These functions implement the rasterization pipeline.
+/**
+ * \file swrast/s_span.c
+ * \brief Span processing functions used by all rasterization functions.
+ * This is where all the per-fragment tests are performed
+ * \author Brian Paul
*/
-
#include "glheader.h"
#include "colormac.h"
+#include "context.h"
#include "macros.h"
-#include "mem.h"
+#include "mmath.h"
+#include "imports.h"
#include "s_alpha.h"
#include "s_alphabuf.h"
@@ -44,743 +46,1050 @@
#include "s_fog.h"
#include "s_logic.h"
#include "s_masking.h"
-#include "s_scissor.h"
#include "s_span.h"
#include "s_stencil.h"
#include "s_texture.h"
+/**
+ * Init span's Z interpolation values to the RasterPos Z.
+ * Used during setup for glDraw/CopyPixels.
+ */
+void
+_mesa_span_default_z( GLcontext *ctx, struct sw_span *span )
+{
+ if (ctx->Visual.depthBits <= 16)
+ span->z = FloatToFixed(ctx->Current.RasterPos[2] * ctx->DepthMax + 0.5F);
+ else
+ span->z = (GLint) (ctx->Current.RasterPos[2] * ctx->DepthMax + 0.5F);
+ span->zStep = 0;
+ span->interpMask |= SPAN_Z;
+}
-/*
- * Apply the current polygon stipple pattern to a span of pixels.
+
+/**
+ * Init span's fog interpolation values to the RasterPos fog.
+ * Used during setup for glDraw/CopyPixels.
*/
-static void
-stipple_polygon_span( GLcontext *ctx, GLuint n, GLint x, GLint y,
- GLubyte mask[] )
+void
+_mesa_span_default_fog( GLcontext *ctx, struct sw_span *span )
{
- const GLuint highbit = 0x80000000;
- GLuint i, m, stipple;
+ span->fog = _mesa_z_to_fogfactor(ctx, ctx->Current.RasterDistance);
+ span->fogStep = 0;
+ span->interpMask |= SPAN_FOG;
+}
- stipple = ctx->PolygonStipple[y % 32];
- m = highbit >> (GLuint) (x % 32);
- for (i = 0; i < n; i++) {
- if ((m & stipple) == 0) {
- mask[i] = 0;
- }
- m = m >> 1;
- if (m == 0) {
- m = highbit;
- }
+/**
+ * Init span's color or index interpolation values to the RasterPos color.
+ * Used during setup for glDraw/CopyPixels.
+ */
+void
+_mesa_span_default_color( GLcontext *ctx, struct sw_span *span )
+{
+ if (ctx->Visual.rgbMode) {
+ GLchan r, g, b, a;
+ UNCLAMPED_FLOAT_TO_CHAN(r, ctx->Current.RasterColor[0]);
+ UNCLAMPED_FLOAT_TO_CHAN(g, ctx->Current.RasterColor[1]);
+ UNCLAMPED_FLOAT_TO_CHAN(b, ctx->Current.RasterColor[2]);
+ UNCLAMPED_FLOAT_TO_CHAN(a, ctx->Current.RasterColor[3]);
+#if CHAN_TYPE == GL_FLOAT
+ span->red = r;
+ span->green = g;
+ span->blue = b;
+ span->alpha = a;
+#else
+ span->red = IntToFixed(r);
+ span->green = IntToFixed(g);
+ span->blue = IntToFixed(b);
+ span->alpha = IntToFixed(a);
+#endif
+ span->redStep = 0;
+ span->greenStep = 0;
+ span->blueStep = 0;
+ span->alphaStep = 0;
+ span->interpMask |= SPAN_RGBA;
+ }
+ else {
+ span->index = IntToFixed(ctx->Current.RasterIndex);
+ span->indexStep = 0;
+ span->interpMask |= SPAN_INDEX;
}
}
-
-/*
- * Clip a pixel span to the current buffer/window boundaries.
- * Return: 'n' such that pixel 'n', 'n+1' etc. are clipped,
- * as a special case:
- * 0 = all pixels clipped
+/**
+ * Init span's texcoord interpolation values to the RasterPos texcoords.
+ * Used during setup for glDraw/CopyPixels.
*/
-static GLuint
-clip_span( GLcontext *ctx, GLint n, GLint x, GLint y, GLubyte mask[] )
+void
+_mesa_span_default_texcoords( GLcontext *ctx, struct sw_span *span )
{
- /* Clip to top and bottom */
- if (y < 0 || y >= (GLint) ctx->DrawBuffer->Height) {
- return 0;
+ GLuint i;
+ for (i = 0; i < ctx->Const.MaxTextureUnits; i++) {
+ COPY_4V(span->tex[i], ctx->Current.RasterTexCoords[i]);
+ ASSIGN_4V(span->texStepX[i], 0.0F, 0.0F, 0.0F, 0.0F);
+ ASSIGN_4V(span->texStepY[i], 0.0F, 0.0F, 0.0F, 0.0F);
}
+ span->interpMask |= SPAN_TEXTURE;
+}
+
+
+/* Fill in the span.color.rgba array from the interpolation values */
+static void
+interpolate_colors(GLcontext *ctx, struct sw_span *span)
+{
+ GLfixed r = span->red;
+ GLfixed g = span->green;
+ GLfixed b = span->blue;
+ GLfixed a = span->alpha;
+ const GLint dr = span->redStep;
+ const GLint dg = span->greenStep;
+ const GLint db = span->blueStep;
+ const GLint da = span->alphaStep;
+ const GLuint n = span->end;
+ GLchan (*rgba)[4] = span->array->rgba;
+ GLuint i;
- /* Clip to the left */
- if (x < 0) {
- if (x + n <= 0) {
- /* completely off left side */
- return 0;
+ ASSERT((span->interpMask & SPAN_RGBA) &&
+ !(span->arrayMask & SPAN_RGBA));
+
+ if (span->interpMask & SPAN_FLAT) {
+ /* constant color */
+ GLchan color[4];
+ color[RCOMP] = FixedToChan(r);
+ color[GCOMP] = FixedToChan(g);
+ color[BCOMP] = FixedToChan(b);
+ color[ACOMP] = FixedToChan(a);
+ for (i = 0; i < n; i++) {
+ COPY_CHAN4(span->array->rgba[i], color);
}
- else {
- /* partially off left side */
- BZERO(mask, -x * sizeof(GLubyte));
+ }
+ else {
+ /* interpolate */
+ for (i = 0; i < n; i++) {
+ rgba[i][RCOMP] = FixedToChan(r);
+ rgba[i][GCOMP] = FixedToChan(g);
+ rgba[i][BCOMP] = FixedToChan(b);
+ rgba[i][ACOMP] = FixedToChan(a);
+ r += dr;
+ g += dg;
+ b += db;
+ a += da;
}
}
+ span->arrayMask |= SPAN_RGBA;
+}
+
- /* Clip to right */
- if (x + n > (GLint) ctx->DrawBuffer->Width) {
- if (x >= (GLint) ctx->DrawBuffer->Width) {
- /* completely off right side */
- return 0;
+/* Fill in the span.color.index array from the interpolation values */
+static void
+interpolate_indexes(GLcontext *ctx, struct sw_span *span)
+{
+ GLfixed index = span->index;
+ const GLint indexStep = span->indexStep;
+ const GLuint n = span->end;
+ GLuint *indexes = span->array->index;
+ GLuint i;
+ ASSERT((span->interpMask & SPAN_INDEX) &&
+ !(span->arrayMask & SPAN_INDEX));
+
+ if ((span->interpMask & SPAN_FLAT) || (indexStep == 0)) {
+ /* constant color */
+ index = FixedToInt(index);
+ for (i = 0; i < n; i++) {
+ indexes[i] = index;
}
- else {
- /* partially off right side */
- return ctx->DrawBuffer->Width - x;
+ }
+ else {
+ /* interpolate */
+ for (i = 0; i < n; i++) {
+ indexes[i] = FixedToInt(index);
+ index += indexStep;
}
}
-
- return n;
+ span->arrayMask |= SPAN_INDEX;
}
-
-/*
- * Draw to more than one color buffer (or none).
- */
+/* Fill in the span.->array->spec array from the interpolation values */
static void
-multi_write_index_span( GLcontext *ctx, GLuint n, GLint x, GLint y,
- const GLuint indexes[], const GLubyte mask[] )
+interpolate_specular(GLcontext *ctx, struct sw_span *span)
{
- SWcontext *swrast = SWRAST_CONTEXT(ctx);
- GLuint bufferBit;
+ if (span->interpMask & SPAN_FLAT) {
+ /* constant color */
+ const GLchan r = FixedToChan(span->specRed);
+ const GLchan g = FixedToChan(span->specGreen);
+ const GLchan b = FixedToChan(span->specBlue);
+ GLuint i;
+ for (i = 0; i < span->end; i++) {
+ span->array->spec[i][RCOMP] = r;
+ span->array->spec[i][GCOMP] = g;
+ span->array->spec[i][BCOMP] = b;
+ }
+ }
+ else {
+ /* interpolate */
+#if CHAN_TYPE == GL_FLOAT
+ GLfloat r = span->specRed;
+ GLfloat g = span->specGreen;
+ GLfloat b = span->specBlue;
+#else
+ GLfixed r = span->specRed;
+ GLfixed g = span->specGreen;
+ GLfixed b = span->specBlue;
+#endif
+ GLuint i;
+ for (i = 0; i < span->end; i++) {
+ span->array->spec[i][RCOMP] = FixedToChan(r);
+ span->array->spec[i][GCOMP] = FixedToChan(g);
+ span->array->spec[i][BCOMP] = FixedToChan(b);
+ r += span->specRedStep;
+ g += span->specGreenStep;
+ b += span->specBlueStep;
+ }
+ }
+ span->arrayMask |= SPAN_SPEC;
+}
- if (ctx->Color.DrawBuffer == GL_NONE)
- return;
- /* loop over four possible dest color buffers */
- for (bufferBit = 1; bufferBit <= 8; bufferBit = bufferBit << 1) {
- if (bufferBit & ctx->Color.DrawDestMask) {
- GLuint indexTmp[MAX_WIDTH];
- ASSERT(n < MAX_WIDTH);
+/* Fill in the span.zArray array from the interpolation values */
+void
+_mesa_span_interpolate_z( const GLcontext *ctx, struct sw_span *span )
+{
+ const GLuint n = span->end;
+ GLuint i;
- if (bufferBit == FRONT_LEFT_BIT)
- (void) (*ctx->Driver.SetDrawBuffer)( ctx, GL_FRONT_LEFT);
- else if (bufferBit == FRONT_RIGHT_BIT)
- (void) (*ctx->Driver.SetDrawBuffer)( ctx, GL_FRONT_RIGHT);
- else if (bufferBit == BACK_LEFT_BIT)
- (void) (*ctx->Driver.SetDrawBuffer)( ctx, GL_BACK_LEFT);
- else
- (void) (*ctx->Driver.SetDrawBuffer)( ctx, GL_BACK_RIGHT);
+ ASSERT((span->interpMask & SPAN_Z) &&
+ !(span->arrayMask & SPAN_Z));
- /* make copy of incoming indexes */
- MEMCPY( indexTmp, indexes, n * sizeof(GLuint) );
- if (ctx->Color.IndexLogicOpEnabled) {
- _mesa_logicop_ci_span( ctx, n, x, y, indexTmp, mask );
- }
- if (ctx->Color.IndexMask == 0) {
- break;
- }
- else if (ctx->Color.IndexMask != 0xffffffff) {
- _mesa_mask_index_span( ctx, n, x, y, indexTmp );
- }
- (*swrast->Driver.WriteCI32Span)( ctx, n, x, y, indexTmp, mask );
+ if (ctx->Visual.depthBits <= 16) {
+ GLfixed zval = span->z;
+ GLdepth *z = span->array->z;
+ for (i = 0; i < n; i++) {
+ z[i] = FixedToInt(zval);
+ zval += span->zStep;
}
}
-
- /* restore default dest buffer */
- (void) (*ctx->Driver.SetDrawBuffer)( ctx, ctx->Color.DriverDrawBuffer);
+ else {
+ /* Deep Z buffer, no fixed->int shift */
+ GLfixed zval = span->z;
+ GLdepth *z = span->array->z;
+ for (i = 0; i < n; i++) {
+ z[i] = zval;
+ zval += span->zStep;
+ }
+ }
+ span->arrayMask |= SPAN_Z;
}
-
/*
- * Write a horizontal span of color index pixels to the frame buffer.
- * Stenciling, Depth-testing, etc. are done as needed.
- * Input: n - number of pixels in the span
- * x, y - location of leftmost pixel in the span
- * z - array of [n] z-values
- * fog - array of fog factor values in [0,1]
- * index - array of [n] color indexes
- * primitive - either GL_POINT, GL_LINE, GL_POLYGON, or GL_BITMAP
+ * This the ideal solution, as given in the OpenGL spec.
*/
-void
-_mesa_write_index_span( GLcontext *ctx, GLuint n, GLint x, GLint y,
- const GLdepth z[], const GLfloat fog[],
- GLuint indexIn[], const GLint coverage[],
- GLenum primitive )
+#if 0
+static GLfloat
+compute_lambda(GLfloat dsdx, GLfloat dsdy, GLfloat dtdx, GLfloat dtdy,
+ GLfloat dqdx, GLfloat dqdy, GLfloat texW, GLfloat texH,
+ GLfloat s, GLfloat t, GLfloat q, GLfloat invQ)
{
- const GLuint modBits = FOG_BIT | BLEND_BIT | MASKING_BIT | LOGIC_OP_BIT;
- GLubyte mask[MAX_WIDTH];
- GLuint indexBackup[MAX_WIDTH];
- GLuint *index; /* points to indexIn or indexBackup */
- SWcontext *swrast = SWRAST_CONTEXT(ctx);
+ GLfloat dudx = texW * ((s + dsdx) / (q + dqdx) - s * invQ);
+ GLfloat dvdx = texH * ((t + dtdx) / (q + dqdx) - t * invQ);
+ GLfloat dudy = texW * ((s + dsdy) / (q + dqdy) - s * invQ);
+ GLfloat dvdy = texH * ((t + dtdy) / (q + dqdy) - t * invQ);
+ GLfloat x = sqrt(dudx * dudx + dvdx * dvdx);
+ GLfloat y = sqrt(dudy * dudy + dvdy * dvdy);
+ GLfloat rho = MAX2(x, y);
+ GLfloat lambda = LOG2(rho);
+ return lambda;
+}
+#endif
- /* init mask to 1's (all pixels are to be written) */
- MEMSET(mask, 1, n);
- if ((swrast->_RasterMask & WINCLIP_BIT) || primitive==GL_BITMAP) {
- if ((n = clip_span(ctx,n,x,y,mask)) == 0) {
- return;
- }
- }
+/*
+ * This is a faster approximation
+ */
+static GLfloat
+compute_lambda(GLfloat dsdx, GLfloat dsdy, GLfloat dtdx, GLfloat dtdy,
+ GLfloat dqdx, GLfloat dqdy, GLfloat texW, GLfloat texH,
+ GLfloat s, GLfloat t, GLfloat q, GLfloat invQ)
+{
+ GLfloat dsdx2 = (s + dsdx) / (q + dqdx) - s * invQ;
+ GLfloat dtdx2 = (t + dtdx) / (q + dqdx) - t * invQ;
+ GLfloat dsdy2 = (s + dsdy) / (q + dqdy) - s * invQ;
+ GLfloat dtdy2 = (t + dtdy) / (q + dqdy) - t * invQ;
+ GLfloat maxU, maxV, rho, lambda;
+ dsdx2 = FABSF(dsdx2);
+ dsdy2 = FABSF(dsdy2);
+ dtdx2 = FABSF(dtdx2);
+ dtdy2 = FABSF(dtdy2);
+ maxU = MAX2(dsdx2, dsdy2) * texW;
+ maxV = MAX2(dtdx2, dtdy2) * texH;
+ rho = MAX2(maxU, maxV);
+ lambda = LOG2(rho);
+ return lambda;
+}
- if ((primitive==GL_BITMAP && (swrast->_RasterMask & modBits))
- || (swrast->_RasterMask & MULTI_DRAW_BIT)) {
- /* Make copy of color indexes */
- MEMCPY( indexBackup, indexIn, n * sizeof(GLuint) );
- index = indexBackup;
+/*
+ * Fill in the span.texcoords array from the interpolation values.
+ * XXX We could optimize here for the case when dq = 0. That would
+ * usually be the case when using an orthographic projection.
+ */
+static void
+interpolate_texcoords(GLcontext *ctx, struct sw_span *span)
+{
+ ASSERT(span->interpMask & SPAN_TEXTURE);
+ ASSERT(!(span->arrayMask & SPAN_TEXTURE));
+
+ if (ctx->Texture._EnabledUnits > 1) {
+ /* multitexture */
+ GLuint u;
+ span->arrayMask |= SPAN_TEXTURE;
+ for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
+ if (ctx->Texture.Unit[u]._ReallyEnabled) {
+ const struct gl_texture_object *obj =ctx->Texture.Unit[u]._Current;
+ const struct gl_texture_image *img = obj->Image[obj->BaseLevel];
+ GLboolean needLambda = (obj->MinFilter != obj->MagFilter);
+ if (needLambda) {
+ GLfloat (*texcoord)[4] = span->array->texcoords[u];
+ GLfloat *lambda = span->array->lambda[u];
+ const GLfloat texW = (GLfloat) img->WidthScale;
+ const GLfloat texH = (GLfloat) img->HeightScale;
+ const GLfloat dsdx = span->texStepX[u][0];
+ const GLfloat dsdy = span->texStepY[u][0];
+ const GLfloat dtdx = span->texStepX[u][1];
+ const GLfloat dtdy = span->texStepY[u][1];
+ const GLfloat drdx = span->texStepX[u][2];
+ const GLfloat dqdx = span->texStepX[u][3];
+ const GLfloat dqdy = span->texStepY[u][3];
+ GLfloat s = span->tex[u][0];
+ GLfloat t = span->tex[u][1];
+ GLfloat r = span->tex[u][2];
+ GLfloat q = span->tex[u][3];
+ GLuint i;
+ for (i = 0; i < span->end; i++) {
+ const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q);
+ texcoord[i][0] = s * invQ;
+ texcoord[i][1] = t * invQ;
+ texcoord[i][2] = r * invQ;
+ lambda[i] = compute_lambda(dsdx, dsdy, dtdx, dtdy,
+ dqdx, dqdy, texW, texH,
+ s, t, q, invQ);
+ s += dsdx;
+ t += dtdx;
+ r += drdx;
+ q += dqdx;
+ }
+ span->arrayMask |= SPAN_LAMBDA;
+ }
+ else {
+ GLfloat (*texcoord)[4] = span->array->texcoords[u];
+ GLfloat *lambda = span->array->lambda[u];
+ const GLfloat dsdx = span->texStepX[u][0];
+ const GLfloat dtdx = span->texStepX[u][1];
+ const GLfloat drdx = span->texStepX[u][2];
+ const GLfloat dqdx = span->texStepX[u][3];
+ GLfloat s = span->tex[u][0];
+ GLfloat t = span->tex[u][1];
+ GLfloat r = span->tex[u][2];
+ GLfloat q = span->tex[u][3];
+ GLuint i;
+ if (dqdx == 0.0) {
+ /* Ortho projection or polygon's parallel to window X axis */
+ const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q);
+ for (i = 0; i < span->end; i++) {
+ texcoord[i][0] = s * invQ;
+ texcoord[i][1] = t * invQ;
+ texcoord[i][2] = r * invQ;
+ lambda[i] = 0.0;
+ s += dsdx;
+ t += dtdx;
+ r += drdx;
+ }
+ }
+ else {
+ for (i = 0; i < span->end; i++) {
+ const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q);
+ texcoord[i][0] = s * invQ;
+ texcoord[i][1] = t * invQ;
+ texcoord[i][2] = r * invQ;
+ lambda[i] = 0.0;
+ s += dsdx;
+ t += dtdx;
+ r += drdx;
+ q += dqdx;
+ }
+ }
+ } /* lambda */
+ } /* if */
+ } /* for */
}
else {
- index = indexIn;
- }
-
-
- /* Do the scissor test */
- if (ctx->Scissor.Enabled) {
- if ((n = _mesa_scissor_span( ctx, n, x, y, mask )) == 0) {
- return;
+ /* single texture */
+ const struct gl_texture_object *obj = ctx->Texture.Unit[0]._Current;
+ const struct gl_texture_image *img = obj->Image[obj->BaseLevel];
+ GLboolean needLambda = (obj->MinFilter != obj->MagFilter);
+ span->arrayMask |= SPAN_TEXTURE;
+ if (needLambda) {
+ /* just texture unit 0, with lambda */
+ GLfloat (*texcoord)[4] = span->array->texcoords[0];
+ GLfloat *lambda = span->array->lambda[0];
+ const GLfloat texW = (GLfloat) img->WidthScale;
+ const GLfloat texH = (GLfloat) img->HeightScale;
+ const GLfloat dsdx = span->texStepX[0][0];
+ const GLfloat dsdy = span->texStepY[0][0];
+ const GLfloat dtdx = span->texStepX[0][1];
+ const GLfloat dtdy = span->texStepY[0][1];
+ const GLfloat drdx = span->texStepX[0][2];
+ const GLfloat dqdx = span->texStepX[0][3];
+ const GLfloat dqdy = span->texStepY[0][3];
+ GLfloat s = span->tex[0][0];
+ GLfloat t = span->tex[0][1];
+ GLfloat r = span->tex[0][2];
+ GLfloat q = span->tex[0][3];
+ GLuint i;
+ for (i = 0; i < span->end; i++) {
+ const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q);
+ lambda[i] = compute_lambda(dsdx, dsdy, dtdx, dtdy,
+ dqdx, dqdy, texW, texH,
+ s, t, q, invQ);
+ texcoord[i][0] = s * invQ;
+ texcoord[i][1] = t * invQ;
+ texcoord[i][2] = r * invQ;
+ s += dsdx;
+ t += dtdx;
+ r += drdx;
+ q += dqdx;
+ }
+ span->arrayMask |= SPAN_LAMBDA;
}
- }
-
- /* Polygon Stippling */
- if (ctx->Polygon.StippleFlag && primitive==GL_POLYGON) {
- stipple_polygon_span( ctx, n, x, y, mask );
- }
-
- if (ctx->Stencil.Enabled) {
- /* first stencil test */
- if (_mesa_stencil_and_ztest_span(ctx, n, x, y, z, mask) == GL_FALSE) {
- return;
+ else {
+ /* just texture 0, without lambda */
+ GLfloat (*texcoord)[4] = span->array->texcoords[0];
+ const GLfloat dsdx = span->texStepX[0][0];
+ const GLfloat dtdx = span->texStepX[0][1];
+ const GLfloat drdx = span->texStepX[0][2];
+ const GLfloat dqdx = span->texStepX[0][3];
+ GLfloat s = span->tex[0][0];
+ GLfloat t = span->tex[0][1];
+ GLfloat r = span->tex[0][2];
+ GLfloat q = span->tex[0][3];
+ GLuint i;
+ if (dqdx == 0.0) {
+ /* Ortho projection or polygon's parallel to window X axis */
+ const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q);
+ for (i = 0; i < span->end; i++) {
+ texcoord[i][0] = s * invQ;
+ texcoord[i][1] = t * invQ;
+ texcoord[i][2] = r * invQ;
+ s += dsdx;
+ t += dtdx;
+ r += drdx;
+ }
+ }
+ else {
+ for (i = 0; i < span->end; i++) {
+ const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q);
+ texcoord[i][0] = s * invQ;
+ texcoord[i][1] = t * invQ;
+ texcoord[i][2] = r * invQ;
+ s += dsdx;
+ t += dtdx;
+ r += drdx;
+ q += dqdx;
+ }
+ }
}
}
- else if (ctx->Depth.Test) {
- /* regular depth testing */
- if (_mesa_depth_test_span( ctx, n, x, y, z, mask ) == 0)
- return;
- }
+}
- /* if we get here, something passed the depth test */
- ctx->OcclusionResult = GL_TRUE;
- /* Per-pixel fog */
- if (ctx->Fog.Enabled) {
- if (fog && !swrast->_PreferPixelFog)
- _mesa_fog_ci_pixels( ctx, n, fog, index );
- else
- _mesa_depth_fog_ci_pixels( ctx, n, z, index );
- }
+/**
+ * Apply the current polygon stipple pattern to a span of pixels.
+ */
+static void
+stipple_polygon_span( GLcontext *ctx, struct sw_span *span )
+{
+ const GLuint highbit = 0x80000000;
+ const GLuint stipple = ctx->PolygonStipple[span->y % 32];
+ GLubyte *mask = span->array->mask;
+ GLuint i, m;
- /* Antialias coverage application */
- if (coverage) {
- GLuint i;
- for (i = 0; i < n; i++) {
- ASSERT(coverage[i] < 16);
- index[i] = (index[i] & ~0xf) | coverage[i];
- }
- }
+ ASSERT(ctx->Polygon.StippleFlag);
+ ASSERT((span->arrayMask & SPAN_XY) == 0);
- if (swrast->_RasterMask & MULTI_DRAW_BIT) {
- /* draw to zero or two or more buffers */
- multi_write_index_span( ctx, n, x, y, index, mask );
- }
- else {
- /* normal situation: draw to exactly one buffer */
- if (ctx->Color.IndexLogicOpEnabled) {
- _mesa_logicop_ci_span( ctx, n, x, y, index, mask );
- }
+ m = highbit >> (GLuint) (span->x % 32);
- if (ctx->Color.IndexMask == 0) {
- return;
+ for (i = 0; i < span->end; i++) {
+ if ((m & stipple) == 0) {
+ mask[i] = 0;
}
- else if (ctx->Color.IndexMask != 0xffffffff) {
- _mesa_mask_index_span( ctx, n, x, y, index );
+ m = m >> 1;
+ if (m == 0) {
+ m = highbit;
}
-
- /* write pixels */
- (*swrast->Driver.WriteCI32Span)( ctx, n, x, y, index, mask );
}
+ span->writeAll = GL_FALSE;
}
-
-
-void
-_mesa_write_monoindex_span( GLcontext *ctx, GLuint n, GLint x, GLint y,
- const GLdepth z[], const GLfloat fog[],
- GLuint index, const GLint coverage[],
- GLenum primitive )
+/**
+ * Clip a pixel span to the current buffer/window boundaries:
+ * DrawBuffer->_Xmin, _Xmax, _Ymin, _Ymax. This will accomplish
+ * window clipping and scissoring.
+ * Return: GL_TRUE some pixels still visible
+ * GL_FALSE nothing visible
+ */
+static GLuint
+clip_span( GLcontext *ctx, struct sw_span *span )
{
- SWcontext *swrast = SWRAST_CONTEXT(ctx);
- GLubyte mask[MAX_WIDTH];
- GLuint i;
-
- /* init mask to 1's (all pixels are to be written) */
- MEMSET(mask, 1, n);
-
- if ((swrast->_RasterMask & WINCLIP_BIT) || primitive==GL_BITMAP) {
- if ((n = clip_span( ctx, n, x, y, mask)) == 0) {
- return;
+ const GLint xmin = ctx->DrawBuffer->_Xmin;
+ const GLint xmax = ctx->DrawBuffer->_Xmax;
+ const GLint ymin = ctx->DrawBuffer->_Ymin;
+ const GLint ymax = ctx->DrawBuffer->_Ymax;
+
+ if (span->arrayMask & SPAN_XY) {
+ /* arrays of x/y pixel coords */
+ const GLint *x = span->array->x;
+ const GLint *y = span->array->y;
+ const GLint n = span->end;
+ GLubyte *mask = span->array->mask;
+ GLint i;
+ if (span->arrayMask & SPAN_MASK) {
+ /* note: using & intead of && to reduce branches */
+ for (i = 0; i < n; i++) {
+ mask[i] &= (x[i] >= xmin) & (x[i] < xmax)
+ & (y[i] >= ymin) & (y[i] < ymax);
+ }
+ }
+ else {
+ /* note: using & intead of && to reduce branches */
+ for (i = 0; i < n; i++) {
+ mask[i] = (x[i] >= xmin) & (x[i] < xmax)
+ & (y[i] >= ymin) & (y[i] < ymax);
+ }
}
+ return GL_TRUE; /* some pixels visible */
}
+ else {
+ /* horizontal span of pixels */
+ const GLint x = span->x;
+ const GLint y = span->y;
+ const GLint n = span->end;
- /* Do the scissor test */
- if (ctx->Scissor.Enabled) {
- if ((n = _mesa_scissor_span( ctx, n, x, y, mask )) == 0) {
- return;
+ /* Trivial rejection tests */
+ if (y < ymin || y >= ymax || x + n <= xmin || x >= xmax) {
+ span->end = 0;
+ return GL_FALSE; /* all pixels clipped */
}
- }
- /* Polygon Stippling */
- if (ctx->Polygon.StippleFlag && primitive==GL_POLYGON) {
- stipple_polygon_span( ctx, n, x, y, mask );
- }
+ /* Clip to the left */
+ if (x < xmin) {
+ ASSERT(x + n > xmin);
+ span->writeAll = GL_FALSE;
+ _mesa_bzero(span->array->mask, (xmin - x) * sizeof(GLubyte));
+ }
- if (ctx->Stencil.Enabled) {
- /* first stencil test */
- if (_mesa_stencil_and_ztest_span(ctx, n, x, y, z, mask) == GL_FALSE) {
- return;
+ /* Clip to right */
+ if (x + n > xmax) {
+ ASSERT(x < xmax);
+ span->end = xmax - x;
}
+
+ return GL_TRUE; /* some pixels visible */
}
- else if (ctx->Depth.Test) {
- /* regular depth testing */
- if (_mesa_depth_test_span( ctx, n, x, y, z, mask ) == 0)
- return;
- }
+}
- /* if we get here, something passed the depth test */
- ctx->OcclusionResult = GL_TRUE;
- if (ctx->Color.DrawBuffer == GL_NONE) {
- /* write no pixels */
- return;
- }
- if (ctx->Fog.Enabled
- || ctx->Color.IndexLogicOpEnabled
- || ctx->Color.IndexMask != 0xffffffff
- || coverage) {
- /* different index per pixel */
- GLuint indexes[MAX_WIDTH];
- for (i = 0; i < n; i++) {
- indexes[i] = index;
- }
+/**
+ * Draw to more than one color buffer (or none).
+ */
+static void
+multi_write_index_span( GLcontext *ctx, struct sw_span *span )
+{
+ SWcontext *swrast = SWRAST_CONTEXT(ctx);
+ GLuint bufferBit;
- if (ctx->Fog.Enabled) {
- if (fog && !swrast->_PreferPixelFog)
- _mesa_fog_ci_pixels( ctx, n, fog, indexes );
- else
- _mesa_depth_fog_ci_pixels( ctx, n, z, indexes );
- }
+ /* loop over four possible dest color buffers */
+ for (bufferBit = 1; bufferBit <= 8; bufferBit <<= 1) {
+ if (bufferBit & ctx->Color._DrawDestMask) {
+ GLuint indexTmp[MAX_WIDTH];
+ ASSERT(span->end < MAX_WIDTH);
- /* Antialias coverage application */
- if (coverage) {
- GLuint i;
- for (i = 0; i < n; i++) {
- ASSERT(coverage[i] < 16);
- indexes[i] = (indexes[i] & ~0xf) | coverage[i];
- }
- }
+ /* Set the current read/draw buffer */
+ swrast->CurrentBuffer = bufferBit;
+ (*swrast->Driver.SetBuffer)(ctx, ctx->DrawBuffer, bufferBit);
+
+ /* make copy of incoming indexes */
+ MEMCPY( indexTmp, span->array->index, span->end * sizeof(GLuint) );
- if (swrast->_RasterMask & MULTI_DRAW_BIT) {
- /* draw to zero or two or more buffers */
- multi_write_index_span( ctx, n, x, y, indexes, mask );
- }
- else {
- /* normal situation: draw to exactly one buffer */
if (ctx->Color.IndexLogicOpEnabled) {
- _mesa_logicop_ci_span( ctx, n, x, y, indexes, mask );
+ _mesa_logicop_ci_span(ctx, span, indexTmp);
}
- if (ctx->Color.IndexMask == 0) {
- return;
+
+ if (ctx->Color.IndexMask != 0xffffffff) {
+ _mesa_mask_index_span(ctx, span, indexTmp);
}
- else if (ctx->Color.IndexMask != 0xffffffff) {
- _mesa_mask_index_span( ctx, n, x, y, indexes );
+
+ if (span->arrayMask & SPAN_XY) {
+ /* array of pixel coords */
+ (*swrast->Driver.WriteCI32Pixels)(ctx, span->end,
+ span->array->x, span->array->y,
+ indexTmp, span->array->mask);
+ }
+ else {
+ /* horizontal run of pixels */
+ (*swrast->Driver.WriteCI32Span)(ctx, span->end, span->x, span->y,
+ indexTmp, span->array->mask);
}
- (*swrast->Driver.WriteCI32Span)( ctx, n, x, y, indexes, mask );
- }
- }
- else {
- /* same color index for all pixels */
- ASSERT(!ctx->Color.IndexLogicOpEnabled);
- ASSERT(ctx->Color.IndexMask == 0xffffffff);
- if (swrast->_RasterMask & MULTI_DRAW_BIT) {
- /* draw to zero or two or more buffers */
- GLuint indexes[MAX_WIDTH];
- for (i = 0; i < n; i++)
- indexes[i] = index;
- multi_write_index_span( ctx, n, x, y, indexes, mask );
- }
- else {
- /* normal situation: draw to exactly one buffer */
- (*swrast->Driver.WriteMonoCISpan)( ctx, n, x, y, index, mask );
}
}
-}
+ /* restore default dest buffer */
+ _swrast_use_draw_buffer(ctx);
+}
-/*
+/**
* Draw to more than one RGBA color buffer (or none).
+ * All fragment operations, up to (but not) blending/logicop should
+ * have been done first.
*/
static void
-multi_write_rgba_span( GLcontext *ctx, GLuint n, GLint x, GLint y,
- CONST GLchan rgba[][4], const GLubyte mask[] )
+multi_write_rgba_span( GLcontext *ctx, struct sw_span *span )
{
const GLuint colorMask = *((GLuint *) ctx->Color.ColorMask);
GLuint bufferBit;
SWcontext *swrast = SWRAST_CONTEXT(ctx);
+ ASSERT(colorMask != 0x0);
+
if (ctx->Color.DrawBuffer == GL_NONE)
return;
/* loop over four possible dest color buffers */
- for (bufferBit = 1; bufferBit <= 8; bufferBit = bufferBit << 1) {
- if (bufferBit & ctx->Color.DrawDestMask) {
+ for (bufferBit = 1; bufferBit <= 8; bufferBit <<= 1) {
+ if (bufferBit & ctx->Color._DrawDestMask) {
GLchan rgbaTmp[MAX_WIDTH][4];
- ASSERT(n < MAX_WIDTH);
+ ASSERT(span->end < MAX_WIDTH);
- if (bufferBit == FRONT_LEFT_BIT) {
- (void) (*ctx->Driver.SetDrawBuffer)( ctx, GL_FRONT_LEFT);
- ctx->DrawBuffer->Alpha = ctx->DrawBuffer->FrontLeftAlpha;
- }
- else if (bufferBit == FRONT_RIGHT_BIT) {
- (void) (*ctx->Driver.SetDrawBuffer)( ctx, GL_FRONT_RIGHT);
- ctx->DrawBuffer->Alpha = ctx->DrawBuffer->FrontRightAlpha;
- }
- else if (bufferBit == BACK_LEFT_BIT) {
- (void) (*ctx->Driver.SetDrawBuffer)( ctx, GL_BACK_LEFT);
- ctx->DrawBuffer->Alpha = ctx->DrawBuffer->BackLeftAlpha;
- }
- else {
- (void) (*ctx->Driver.SetDrawBuffer)( ctx, GL_BACK_RIGHT);
- ctx->DrawBuffer->Alpha = ctx->DrawBuffer->BackRightAlpha;
- }
+ /* Set the current read/draw buffer */
+ swrast->CurrentBuffer = bufferBit;
+ (*swrast->Driver.SetBuffer)(ctx, ctx->DrawBuffer, bufferBit);
/* make copy of incoming colors */
- MEMCPY( rgbaTmp, rgba, 4 * n * sizeof(GLchan) );
+ MEMCPY( rgbaTmp, span->array->rgba, 4 * span->end * sizeof(GLchan) );
if (ctx->Color.ColorLogicOpEnabled) {
- _mesa_logicop_rgba_span( ctx, n, x, y, rgbaTmp, mask );
+ _mesa_logicop_rgba_span(ctx, span, rgbaTmp);
}
else if (ctx->Color.BlendEnabled) {
- _mesa_blend_span( ctx, n, x, y, rgbaTmp, mask );
+ _mesa_blend_span(ctx, span, rgbaTmp);
}
- if (colorMask == 0x0) {
- break;
- }
- else if (colorMask != 0xffffffff) {
- _mesa_mask_rgba_span( ctx, n, x, y, rgbaTmp );
+
+ if (colorMask != 0xffffffff) {
+ _mesa_mask_rgba_span(ctx, span, rgbaTmp);
}
- (*swrast->Driver.WriteRGBASpan)( ctx, n, x, y,
- (const GLchan (*)[4]) rgbaTmp, mask );
- if (swrast->_RasterMask & ALPHABUF_BIT) {
- _mesa_write_alpha_span( ctx, n, x, y,
- (const GLchan (*)[4])rgbaTmp, mask );
+ if (span->arrayMask & SPAN_XY) {
+ /* array of pixel coords */
+ (*swrast->Driver.WriteRGBAPixels)(ctx, span->end,
+ span->array->x, span->array->y,
+ (const GLchan (*)[4]) rgbaTmp,
+ span->array->mask);
+ if (SWRAST_CONTEXT(ctx)->_RasterMask & ALPHABUF_BIT) {
+ _mesa_write_alpha_pixels(ctx, span->end,
+ span->array->x, span->array->y,
+ (const GLchan (*)[4]) rgbaTmp,
+ span->array->mask);
+ }
+ }
+ else {
+ /* horizontal run of pixels */
+ (*swrast->Driver.WriteRGBASpan)(ctx, span->end, span->x, span->y,
+ (const GLchan (*)[4]) rgbaTmp,
+ span->array->mask);
+ if (swrast->_RasterMask & ALPHABUF_BIT) {
+ _mesa_write_alpha_span(ctx, span->end, span->x, span->y,
+ (const GLchan (*)[4]) rgbaTmp,
+ span->array->mask);
+ }
}
}
}
/* restore default dest buffer */
- (void) (*ctx->Driver.SetDrawBuffer)( ctx, ctx->Color.DriverDrawBuffer );
+ _swrast_use_draw_buffer(ctx);
}
-/*
- * Apply fragment processing to a span of RGBA fragments.
- * Input:
- * n - number of fragments in the span
- * x,y - location of first (left) fragment
- * fog - array of fog factor values in [0,1]
+/**
+ * This function may modify any of the array values in the span.
+ * span->interpMask and span->arrayMask may be changed but will be restored
+ * to their original values before returning.
*/
void
-_mesa_write_rgba_span( GLcontext *ctx, GLuint n, GLint x, GLint y,
- const GLdepth z[], const GLfloat fog[],
- GLchan rgbaIn[][4], const GLfloat coverage[],
- GLenum primitive )
+_mesa_write_index_span( GLcontext *ctx, struct sw_span *span)
{
- const GLuint modBits = FOG_BIT | BLEND_BIT | MASKING_BIT |
- LOGIC_OP_BIT | TEXTURE_BIT;
- GLubyte mask[MAX_WIDTH];
- GLboolean write_all = GL_TRUE;
- GLchan rgbaBackup[MAX_WIDTH][4];
- GLchan (*rgba)[4];
- const GLubyte *Null = 0;
SWcontext *swrast = SWRAST_CONTEXT(ctx);
+ const GLuint origInterpMask = span->interpMask;
+ const GLuint origArrayMask = span->arrayMask;
- /* init mask to 1's (all pixels are to be written) */
- MEMSET(mask, 1, n);
+ ASSERT(span->end <= MAX_WIDTH);
+ 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 ((swrast->_RasterMask & WINCLIP_BIT) || primitive==GL_BITMAP) {
- if ((n = clip_span( ctx,n,x,y,mask)) == 0) {
- return;
- }
- if (mask[0] == 0)
- write_all = GL_FALSE;
- }
-
- if ((primitive==GL_BITMAP && (swrast->_RasterMask & modBits))
- || (swrast->_RasterMask & MULTI_DRAW_BIT)) {
- /* must make a copy of the colors since they may be modified */
- MEMCPY( rgbaBackup, rgbaIn, 4 * n * sizeof(GLchan) );
- rgba = rgbaBackup;
+ if (span->arrayMask & SPAN_MASK) {
+ /* mask was initialized by caller, probably glBitmap */
+ span->writeAll = GL_FALSE;
}
else {
- rgba = rgbaIn;
+ MEMSET(span->array->mask, 1, span->end);
+ span->writeAll = GL_TRUE;
}
- /* Do the scissor test */
- if (ctx->Scissor.Enabled) {
- if ((n = _mesa_scissor_span( ctx, n, x, y, mask )) == 0) {
+ /* Clipping */
+ if ((swrast->_RasterMask & CLIP_BIT) || (span->primitive != GL_POLYGON)) {
+ if (!clip_span(ctx, span)) {
return;
}
- if (mask[0] == 0)
- write_all = GL_FALSE;
- }
-
- /* Polygon Stippling */
- if (ctx->Polygon.StippleFlag && primitive==GL_POLYGON) {
- stipple_polygon_span( ctx, n, x, y, mask );
- write_all = GL_FALSE;
}
- /* Do the alpha test */
- if (ctx->Color.AlphaEnabled) {
- if (_mesa_alpha_test( ctx, n, (const GLchan (*)[4]) rgba, mask ) == 0) {
- return;
+#ifdef DEBUG
+ if (span->arrayMask & SPAN_XY) {
+ GLuint i;
+ for (i = 0; i < span->end; i++) {
+ if (span->array->mask[i]) {
+ assert(span->array->x[i] >= ctx->DrawBuffer->_Xmin);
+ assert(span->array->x[i] < ctx->DrawBuffer->_Xmax);
+ assert(span->array->y[i] >= ctx->DrawBuffer->_Ymin);
+ assert(span->array->y[i] < ctx->DrawBuffer->_Ymax);
+ }
}
- write_all = GL_FALSE;
}
+#endif
- if (ctx->Stencil.Enabled) {
- /* first stencil test */
- if (_mesa_stencil_and_ztest_span(ctx, n, x, y, z, mask) == GL_FALSE) {
- return;
- }
- write_all = GL_FALSE;
+ /* Polygon Stippling */
+ if (ctx->Polygon.StippleFlag && span->primitive == GL_POLYGON) {
+ stipple_polygon_span(ctx, span);
}
- else if (ctx->Depth.Test) {
- /* regular depth testing */
- GLuint m = _mesa_depth_test_span( ctx, n, x, y, z, mask );
- if (m == 0) {
- return;
+
+ /* Depth test and stencil */
+ if (ctx->Depth.Test || ctx->Stencil.Enabled) {
+ if (span->interpMask & SPAN_Z)
+ _mesa_span_interpolate_z(ctx, span);
+
+ if (ctx->Stencil.Enabled) {
+ if (!_mesa_stencil_and_ztest_span(ctx, span)) {
+ span->arrayMask = origArrayMask;
+ return;
+ }
}
- if (m < n) {
- write_all = GL_FALSE;
+ else {
+ ASSERT(ctx->Depth.Test);
+ if (!_mesa_depth_test_span(ctx, span)) {
+ span->arrayMask = origArrayMask;
+ return;
+ }
}
}
/* if we get here, something passed the depth test */
ctx->OcclusionResult = GL_TRUE;
- /* Per-pixel fog */
+ /* we have to wait until after occlusion to do this test */
+ if (ctx->Color.DrawBuffer == GL_NONE || ctx->Color.IndexMask == 0) {
+ /* write no pixels */
+ span->arrayMask = origArrayMask;
+ return;
+ }
+
+ /* Interpolate the color indexes if needed */
+ if (span->interpMask & SPAN_INDEX) {
+ interpolate_indexes(ctx, span);
+ /* clear the bit - this allows the WriteMonoCISpan optimization below */
+ span->interpMask &= ~SPAN_INDEX;
+ }
+
+ /* Fog */
if (ctx->Fog.Enabled) {
- if (fog && !swrast->_PreferPixelFog)
- _mesa_fog_rgba_pixels( ctx, n, fog, rgba );
- else
- _mesa_depth_fog_rgba_pixels( ctx, n, z, rgba );
+ _mesa_fog_ci_span(ctx, span);
}
/* Antialias coverage application */
- if (coverage) {
+ if (span->arrayMask & SPAN_COVERAGE) {
GLuint i;
- for (i = 0; i < n; i++) {
- rgba[i][ACOMP] = (GLchan) (rgba[i][ACOMP] * coverage[i]);
+ GLuint *index = span->array->index;
+ GLfloat *coverage = span->array->coverage;
+ for (i = 0; i < span->end; i++) {
+ ASSERT(coverage[i] < 16);
+ index[i] = (index[i] & ~0xf) | ((GLuint) coverage[i]);
}
}
if (swrast->_RasterMask & MULTI_DRAW_BIT) {
- multi_write_rgba_span( ctx, n, x, y, (const GLchan (*)[4]) rgba, mask );
+ /* draw to zero or two or more buffers */
+ multi_write_index_span(ctx, span);
}
else {
- /* normal: write to exactly one buffer */
- /* logic op or blending */
- const GLuint colorMask = *((GLuint *) ctx->Color.ColorMask);
-
- if (ctx->Color.ColorLogicOpEnabled) {
- _mesa_logicop_rgba_span( ctx, n, x, y, rgba, mask );
- }
- else if (ctx->Color.BlendEnabled) {
- _mesa_blend_span( ctx, n, x, y, rgba, mask );
+ /* normal situation: draw to exactly one buffer */
+ if (ctx->Color.IndexLogicOpEnabled) {
+ _mesa_logicop_ci_span(ctx, span, span->array->index);
}
- /* Color component masking */
- if (colorMask == 0x0) {
- return;
- }
- else if (colorMask != 0xffffffff) {
- _mesa_mask_rgba_span( ctx, n, x, y, rgba );
+ if (ctx->Color.IndexMask != 0xffffffff) {
+ _mesa_mask_index_span(ctx, span, span->array->index);
}
/* write pixels */
- (*swrast->Driver.WriteRGBASpan)( ctx, n, x, y,
- (const GLchan (*)[4]) rgba,
- write_all ? Null : mask );
-
- if (swrast->_RasterMask & ALPHABUF_BIT) {
- _mesa_write_alpha_span( ctx, n, x, y,
- (const GLchan (*)[4]) rgba,
- write_all ? Null : mask );
+ if (span->arrayMask & SPAN_XY) {
+ /* array of pixel coords */
+ if ((span->interpMask & SPAN_INDEX) && span->indexStep == 0) {
+ /* all pixels have same color index */
+ (*swrast->Driver.WriteMonoCIPixels)(ctx, span->end,
+ span->array->x, span->array->y,
+ FixedToInt(span->index),
+ span->array->mask);
+ }
+ else {
+ (*swrast->Driver.WriteCI32Pixels)(ctx, span->end, span->array->x,
+ span->array->y, span->array->index,
+ span->array->mask );
+ }
+ }
+ else {
+ /* horizontal run of pixels */
+ if ((span->interpMask & SPAN_INDEX) && span->indexStep == 0) {
+ /* all pixels have same color index */
+ (*swrast->Driver.WriteMonoCISpan)(ctx, span->end, span->x, span->y,
+ FixedToInt(span->index),
+ span->array->mask);
+ }
+ else {
+ (*swrast->Driver.WriteCI32Span)(ctx, span->end, span->x, span->y,
+ span->array->index,
+ span->array->mask);
+ }
}
}
-}
+ span->interpMask = origInterpMask;
+ span->arrayMask = origArrayMask;
+}
-/*
- * Write a horizontal span of color pixels to the frame buffer.
- * The color is initially constant for the whole span.
- * Alpha-testing, stenciling, depth-testing, and blending are done as needed.
- * Input: n - number of pixels in the span
- * x, y - location of leftmost pixel in the span
- * z - array of [n] z-values
- * fog - array of fog factor values in [0,1]
- * r, g, b, a - the color of the pixels
- * primitive - either GL_POINT, GL_LINE, GL_POLYGON or GL_BITMAP.
+/**
+ * This function may modify any of the array values in the span.
+ * span->interpMask and span->arrayMask may be changed but will be restored
+ * to their original values before returning.
*/
void
-_mesa_write_monocolor_span( GLcontext *ctx, GLuint n, GLint x, GLint y,
- const GLdepth z[], const GLfloat fog[],
- const GLchan color[4], const GLfloat coverage[],
- GLenum primitive )
+_mesa_write_rgba_span( GLcontext *ctx, struct sw_span *span)
{
- const GLuint colorMask = *((GLuint *) ctx->Color.ColorMask);
- GLuint i;
- GLubyte mask[MAX_WIDTH];
- GLboolean write_all = GL_TRUE;
- GLchan rgba[MAX_WIDTH][4];
- const GLubyte *Null = 0;
SWcontext *swrast = SWRAST_CONTEXT(ctx);
+ const GLuint colorMask = *((GLuint *) ctx->Color.ColorMask);
+ const GLuint origInterpMask = span->interpMask;
+ const GLuint origArrayMask = span->arrayMask;
+ GLboolean monoColor;
+
+ ASSERT(span->end <= MAX_WIDTH);
+ ASSERT(span->primitive == GL_POINT || span->primitive == GL_LINE ||
+ span->primitive == GL_POLYGON || span->primitive == GL_BITMAP);
+ ASSERT((span->interpMask & span->arrayMask) == 0);
+ ASSERT((span->interpMask | span->arrayMask) & SPAN_RGBA);
+#ifdef DEBUG
+ if (ctx->Fog.Enabled)
+ ASSERT((span->interpMask | span->arrayMask) & SPAN_FOG);
+ if (ctx->Depth.Test)
+ ASSERT((span->interpMask | span->arrayMask) & SPAN_Z);
+#endif
- /* init mask to 1's (all pixels are to be written) */
- MEMSET(mask, 1, n);
+ if (span->arrayMask & SPAN_MASK) {
+ /* mask was initialized by caller, probably glBitmap */
+ span->writeAll = GL_FALSE;
+ }
+ else {
+ MEMSET(span->array->mask, 1, span->end);
+ span->writeAll = GL_TRUE;
+ }
- if ((swrast->_RasterMask & WINCLIP_BIT) || primitive==GL_BITMAP) {
- if ((n = clip_span( ctx,n,x,y,mask)) == 0) {
- return;
+ /* Determine if we have mono-chromatic colors */
+ monoColor = (span->interpMask & SPAN_RGBA) &&
+ span->redStep == 0 && span->greenStep == 0 &&
+ span->blueStep == 0 && span->alphaStep == 0;
+
+ /* Clipping */
+ if ((swrast->_RasterMask & CLIP_BIT) || (span->primitive != GL_POLYGON)) {
+ if (!clip_span(ctx, span)) {
+ return;
}
- if (mask[0] == 0)
- write_all = GL_FALSE;
}
- /* Do the scissor test */
- if (ctx->Scissor.Enabled) {
- if ((n = _mesa_scissor_span( ctx, n, x, y, mask )) == 0) {
- return;
+#ifdef DEBUG
+ if (span->arrayMask & SPAN_XY) {
+ GLuint i;
+ for (i = 0; i < span->end; i++) {
+ if (span->array->mask[i]) {
+ assert(span->array->x[i] >= ctx->DrawBuffer->_Xmin);
+ assert(span->array->x[i] < ctx->DrawBuffer->_Xmax);
+ assert(span->array->y[i] >= ctx->DrawBuffer->_Ymin);
+ assert(span->array->y[i] < ctx->DrawBuffer->_Ymax);
+ }
}
- if (mask[0] == 0)
- write_all = GL_FALSE;
}
+#endif
/* Polygon Stippling */
- if (ctx->Polygon.StippleFlag && primitive==GL_POLYGON) {
- stipple_polygon_span( ctx, n, x, y, mask );
- write_all = GL_FALSE;
+ if (ctx->Polygon.StippleFlag && span->primitive == GL_POLYGON) {
+ stipple_polygon_span(ctx, span);
}
/* Do the alpha test */
if (ctx->Color.AlphaEnabled) {
- for (i = 0; i < n; i++) {
- rgba[i][ACOMP] = color[ACOMP];
- }
- if (_mesa_alpha_test( ctx, n, (const GLchan (*)[4])rgba, mask ) == 0) {
+ if (!_mesa_alpha_test(ctx, span)) {
+ span->interpMask = origInterpMask;
+ span->arrayMask = origArrayMask;
return;
}
- write_all = GL_FALSE;
}
- if (ctx->Stencil.Enabled) {
- /* first stencil test */
- if (_mesa_stencil_and_ztest_span(ctx, n, x, y, z, mask) == GL_FALSE) {
- return;
- }
- write_all = GL_FALSE;
- }
- else if (ctx->Depth.Test) {
- /* regular depth testing */
- GLuint m = _mesa_depth_test_span( ctx, n, x, y, z, mask );
- if (m == 0) {
- return;
+ /* Stencil and Z testing */
+ if (ctx->Stencil.Enabled || ctx->Depth.Test) {
+ if (span->interpMask & SPAN_Z)
+ _mesa_span_interpolate_z(ctx, span);
+
+ if (ctx->Stencil.Enabled) {
+ if (!_mesa_stencil_and_ztest_span(ctx, span)) {
+ span->interpMask = origInterpMask;
+ span->arrayMask = origArrayMask;
+ return;
+ }
}
- if (m < n) {
- write_all = GL_FALSE;
+ else {
+ ASSERT(ctx->Depth.Test);
+ ASSERT(span->arrayMask & SPAN_Z);
+ /* regular depth testing */
+ if (!_mesa_depth_test_span(ctx, span)) {
+ span->interpMask = origInterpMask;
+ span->arrayMask = origArrayMask;
+ return;
+ }
}
}
/* if we get here, something passed the depth test */
ctx->OcclusionResult = GL_TRUE;
- if (ctx->Color.DrawBuffer == GL_NONE) {
- /* write no pixels */
+ /* can't abort span-writing until after occlusion testing */
+ if (colorMask == 0x0) {
+ span->interpMask = origInterpMask;
+ span->arrayMask = origArrayMask;
return;
}
- if (ctx->Color.ColorLogicOpEnabled || colorMask != 0xffffffff ||
- (swrast->_RasterMask & (BLEND_BIT | FOG_BIT)) || coverage) {
- /* assign same color to each pixel */
- for (i = 0; i < n; i++) {
- if (mask[i]) {
- COPY_CHAN4(rgba[i], color);
- }
- }
+ /* Now we may need to interpolate the colors */
+ if ((span->interpMask & SPAN_RGBA) && (span->arrayMask & SPAN_RGBA) == 0) {
+ interpolate_colors(ctx, span);
+ /* clear the bit - this allows the WriteMonoCISpan optimization below */
+ span->interpMask &= ~SPAN_RGBA;
+ }
- /* Per-pixel fog */
- if (ctx->Fog.Enabled) {
- if (fog && !swrast->_PreferPixelFog)
- _mesa_fog_rgba_pixels( ctx, n, fog, rgba );
- else
- _mesa_depth_fog_rgba_pixels( ctx, n, z, rgba );
- }
+ /* Fog */
+ if (ctx->Fog.Enabled) {
+ _mesa_fog_rgba_span(ctx, span);
+ monoColor = GL_FALSE;
+ }
- /* Antialias coverage application */
- if (coverage) {
- GLuint i;
- for (i = 0; i < n; i++) {
- rgba[i][ACOMP] = (GLchan) (rgba[i][ACOMP] * coverage[i]);
- }
+ /* Antialias coverage application */
+ if (span->arrayMask & SPAN_COVERAGE) {
+ GLchan (*rgba)[4] = span->array->rgba;
+ GLfloat *coverage = span->array->coverage;
+ GLuint i;
+ for (i = 0; i < span->end; i++) {
+ rgba[i][ACOMP] = (GLchan) (rgba[i][ACOMP] * coverage[i]);
}
+ monoColor = GL_FALSE;
+ }
- if (swrast->_RasterMask & MULTI_DRAW_BIT) {
- multi_write_rgba_span( ctx, n, x, y,
- (const GLchan (*)[4]) rgba, mask );
+ if (swrast->_RasterMask & MULTI_DRAW_BIT) {
+ multi_write_rgba_span(ctx, span);
+ }
+ else {
+ /* normal: write to exactly one buffer */
+ if (ctx->Color.ColorLogicOpEnabled) {
+ _mesa_logicop_rgba_span(ctx, span, span->array->rgba);
+ monoColor = GL_FALSE;
+ }
+ else if (ctx->Color.BlendEnabled) {
+ _mesa_blend_span(ctx, span, span->array->rgba);
+ monoColor = GL_FALSE;
}
- else {
- /* normal: write to exactly one buffer */
- if (ctx->Color.ColorLogicOpEnabled) {
- _mesa_logicop_rgba_span( ctx, n, x, y, rgba, mask );
- }
- else if (ctx->Color.BlendEnabled) {
- _mesa_blend_span( ctx, n, x, y, rgba, mask );
- }
-
- /* Color component masking */
- if (colorMask == 0x0) {
- return;
- }
- else if (colorMask != 0xffffffff) {
- _mesa_mask_rgba_span( ctx, n, x, y, rgba );
- }
- /* write pixels */
- (*swrast->Driver.WriteRGBASpan)( ctx, n, x, y,
- (const GLchan (*)[4]) rgba,
- write_all ? Null : mask );
- if (swrast->_RasterMask & ALPHABUF_BIT) {
- _mesa_write_alpha_span( ctx, n, x, y,
- (const GLchan (*)[4]) rgba,
- write_all ? Null : mask );
- }
+ /* Color component masking */
+ if (colorMask != 0xffffffff) {
+ _mesa_mask_rgba_span(ctx, span, span->array->rgba);
+ monoColor = GL_FALSE;
}
- }
- else {
- /* same color for all pixels */
- ASSERT(!ctx->Color.BlendEnabled);
- ASSERT(!ctx->Color.ColorLogicOpEnabled);
- if (swrast->_RasterMask & MULTI_DRAW_BIT) {
- for (i = 0; i < n; i++) {
- if (mask[i]) {
- COPY_CHAN4(rgba[i], color);
- }
+ /* write pixels */
+ if (span->arrayMask & SPAN_XY) {
+ /* array of pixel coords */
+ /* XXX test for mono color */
+ (*swrast->Driver.WriteRGBAPixels)(ctx, span->end, span->array->x,
+ span->array->y, (const GLchan (*)[4]) span->array->rgba, span->array->mask);
+ if (SWRAST_CONTEXT(ctx)->_RasterMask & ALPHABUF_BIT) {
+ _mesa_write_alpha_pixels(ctx, span->end,
+ span->array->x, span->array->y,
+ (const GLchan (*)[4]) span->array->rgba,
+ span->array->mask);
}
- multi_write_rgba_span( ctx, n, x, y,
- (const GLchan (*)[4]) rgba, mask );
}
else {
- (*swrast->Driver.WriteMonoRGBASpan)( ctx, n, x, y, color, mask );
- if (swrast->_RasterMask & ALPHABUF_BIT) {
- _mesa_write_mono_alpha_span( ctx, n, x, y, (GLchan) color[ACOMP],
- write_all ? Null : mask );
+ /* horizontal run of pixels */
+ if (monoColor) {
+ /* all pixels have same color */
+ GLchan color[4];
+ color[RCOMP] = FixedToChan(span->red);
+ color[GCOMP] = FixedToChan(span->green);
+ color[BCOMP] = FixedToChan(span->blue);
+ color[ACOMP] = FixedToChan(span->alpha);
+ (*swrast->Driver.WriteMonoRGBASpan)(ctx, span->end, span->x,
+ span->y, color, span->array->mask);
+ if (swrast->_RasterMask & ALPHABUF_BIT) {
+ _mesa_write_mono_alpha_span(ctx, span->end, span->x, span->y,
+ color[ACOMP],
+ span->writeAll ? ((const GLubyte *) NULL) : span->array->mask);
+ }
+ }
+ else {
+ /* each pixel is a different color */
+ (*swrast->Driver.WriteRGBASpan)(ctx, span->end, span->x, span->y,
+ (const GLchan (*)[4]) span->array->rgba,
+ span->writeAll ? ((const GLubyte *) NULL) : span->array->mask);
+ if (swrast->_RasterMask & ALPHABUF_BIT) {
+ _mesa_write_alpha_span(ctx, span->end, span->x, span->y,
+ (const GLchan (*)[4]) span->array->rgba,
+ span->writeAll ? ((const GLubyte *) NULL) : span->array->mask);
+ }
}
}
}
-}
+ span->interpMask = origInterpMask;
+ span->arrayMask = origArrayMask;
+}
-/*
+/**
* Add specular color to base color. This is used only when
* GL_LIGHT_MODEL_COLOR_CONTROL = GL_SEPARATE_SPECULAR_COLOR.
*/
static void
-add_colors(GLuint n, GLchan rgba[][4], CONST GLchan specular[][4] )
+add_colors(GLuint n, GLchan rgba[][4], GLchan specular[][4] )
{
GLuint i;
for (i = 0; i < n; i++) {
@@ -801,330 +1110,205 @@ add_colors(GLuint n, GLchan rgba[][4], CONST GLchan specular[][4] )
}
-/*
- * Write a horizontal span of textured pixels to the frame buffer.
- * The color of each pixel is different.
- * Alpha-testing, stenciling, depth-testing, and blending are done
- * as needed.
- * Input: n - number of pixels in the span
- * x, y - location of leftmost pixel in the span
- * z - array of [n] z-values
- * fog - array of fog factor values in [0,1]
- * s, t - array of (s,t) texture coordinates for each pixel
- * lambda - array of texture lambda values
- * rgba - array of [n] color components
- * primitive - either GL_POINT, GL_LINE, GL_POLYGON or GL_BITMAP.
+/**
+ * This function may modify any of the array values in the span.
+ * span->interpMask and span->arrayMask may be changed but will be restored
+ * to their original values before returning.
*/
void
-_mesa_write_texture_span( GLcontext *ctx, GLuint n, GLint x, GLint y,
- const GLdepth z[], const GLfloat fog[],
- const GLfloat s[], const GLfloat t[],
- const GLfloat u[], GLfloat lambda[],
- GLchan rgbaIn[][4], CONST GLchan spec[][4],
- const GLfloat coverage[], GLenum primitive )
+_mesa_write_texture_span( GLcontext *ctx, struct sw_span *span)
{
const GLuint colorMask = *((GLuint *) ctx->Color.ColorMask);
- GLubyte mask[MAX_WIDTH];
- GLboolean write_all = GL_TRUE;
- GLchan rgbaBackup[MAX_WIDTH][4];
- GLchan (*rgba)[4]; /* points to either rgbaIn or rgbaBackup */
- const GLubyte *Null = 0;
SWcontext *swrast = SWRAST_CONTEXT(ctx);
+ const GLuint origArrayMask = span->arrayMask;
- /* init mask to 1's (all pixels are to be written) */
- MEMSET(mask, 1, n);
-
- if ((swrast->_RasterMask & WINCLIP_BIT) || primitive==GL_BITMAP) {
- if ((n=clip_span(ctx, n, x, y, mask)) == 0) {
- return;
- }
- if (mask[0] == 0)
- write_all = GL_FALSE;
- }
+ ASSERT(span->primitive == GL_POINT || span->primitive == GL_LINE ||
+ span->primitive == GL_POLYGON || span->primitive == GL_BITMAP);
+ ASSERT(span->end <= MAX_WIDTH);
+ ASSERT((span->interpMask & span->arrayMask) == 0);
+ ASSERT(ctx->Texture._EnabledUnits);
+ /*
+ printf("%s() interp 0x%x array 0x%x\n", __FUNCTION__, span->interpMask, span->arrayMask);
+ */
- if (primitive==GL_BITMAP || (swrast->_RasterMask & MULTI_DRAW_BIT)) {
- /* must make a copy of the colors since they may be modified */
- MEMCPY(rgbaBackup, rgbaIn, 4 * n * sizeof(GLchan));
- rgba = rgbaBackup;
+ if (span->arrayMask & SPAN_MASK) {
+ /* mask was initialized by caller, probably glBitmap */
+ span->writeAll = GL_FALSE;
}
else {
- rgba = rgbaIn;
- }
-
- /* Do the scissor test */
- if (ctx->Scissor.Enabled) {
- if ((n = _mesa_scissor_span( ctx, n, x, y, mask )) == 0) {
- return;
- }
- if (mask[0] == 0)
- write_all = GL_FALSE;
- }
-
- /* Polygon Stippling */
- if (ctx->Polygon.StippleFlag && primitive==GL_POLYGON) {
- stipple_polygon_span( ctx, n, x, y, mask );
- write_all = GL_FALSE;
+ MEMSET(span->array->mask, 1, span->end);
+ span->writeAll = GL_TRUE;
}
- /* Texture with alpha test */
- if (ctx->Color.AlphaEnabled) {
- /* Texturing without alpha is done after depth-testing which
- gives a potential speed-up. */
- ASSERT(ctx->Texture._ReallyEnabled);
- _swrast_texture_fragments( ctx, 0, n, s, t, u, lambda,
- (CONST GLchan (*)[4]) rgba, rgba );
-
- /* Do the alpha test */
- if (_mesa_alpha_test( ctx, n, (const GLchan (*)[4]) rgba, mask ) == 0) {
- return;
- }
- write_all = GL_FALSE;
- }
-
- if (ctx->Stencil.Enabled) {
- /* first stencil test */
- if (_mesa_stencil_and_ztest_span(ctx, n, x, y, z, mask) == GL_FALSE) {
+ /* Clipping */
+ if ((swrast->_RasterMask & CLIP_BIT) || (span->primitive != GL_POLYGON)) {
+ if (!clip_span(ctx, span)) {
return;
}
- write_all = GL_FALSE;
- }
- else if (ctx->Depth.Test) {
- /* regular depth testing */
- GLuint m = _mesa_depth_test_span( ctx, n, x, y, z, mask );
- if (m == 0) {
- return;
- }
- if (m < n) {
- write_all = GL_FALSE;
- }
}
- /* if we get here, something passed the depth test */
- ctx->OcclusionResult = GL_TRUE;
-
- /* Texture without alpha test */
- if (! ctx->Color.AlphaEnabled) {
- ASSERT(ctx->Texture._ReallyEnabled);
- _swrast_texture_fragments( ctx, 0, n, s, t, u, lambda,
- (CONST GLchan (*)[4]) rgba, rgba );
- }
-
- /* Add base and specular colors */
- if (spec &&
- (ctx->Fog.ColorSumEnabled ||
- (ctx->Light.Enabled &&
- ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR)))
- add_colors( n, rgba, spec ); /* rgba = rgba + spec */
-
- /* Per-pixel fog */
- if (ctx->Fog.Enabled) {
- if (fog && !swrast->_PreferPixelFog)
- _mesa_fog_rgba_pixels( ctx, n, fog, rgba );
- else
- _mesa_depth_fog_rgba_pixels( ctx, n, z, rgba );
- }
-
- /* Antialias coverage application */
- if (coverage) {
+#ifdef DEBUG
+ if (span->arrayMask & SPAN_XY) {
GLuint i;
- for (i = 0; i < n; i++) {
- rgba[i][ACOMP] = (GLchan) (rgba[i][ACOMP] * coverage[i]);
- }
- }
-
- if (swrast->_RasterMask & MULTI_DRAW_BIT) {
- multi_write_rgba_span( ctx, n, x, y, (const GLchan (*)[4]) rgba, mask );
- }
- else {
- /* normal: write to exactly one buffer */
- if (ctx->Color.ColorLogicOpEnabled) {
- _mesa_logicop_rgba_span( ctx, n, x, y, rgba, mask );
- }
- else if (ctx->Color.BlendEnabled) {
- _mesa_blend_span( ctx, n, x, y, rgba, mask );
- }
- if (colorMask == 0x0) {
- return;
- }
- else if (colorMask != 0xffffffff) {
- _mesa_mask_rgba_span( ctx, n, x, y, rgba );
- }
-
- (*swrast->Driver.WriteRGBASpan)( ctx, n, x, y, (const GLchan (*)[4])rgba,
- write_all ? Null : mask );
- if (swrast->_RasterMask & ALPHABUF_BIT) {
- _mesa_write_alpha_span( ctx, n, x, y, (const GLchan (*)[4]) rgba,
- write_all ? Null : mask );
- }
- }
-}
-
-
-
-/*
- * As above but perform multiple stages of texture application.
- */
-void
-_mesa_write_multitexture_span( GLcontext *ctx, GLuint n, GLint x, GLint y,
- const GLdepth z[], const GLfloat fog[],
- CONST GLfloat s[MAX_TEXTURE_UNITS][MAX_WIDTH],
- CONST GLfloat t[MAX_TEXTURE_UNITS][MAX_WIDTH],
- CONST GLfloat u[MAX_TEXTURE_UNITS][MAX_WIDTH],
- GLfloat lambda[][MAX_WIDTH],
- GLchan rgbaIn[MAX_TEXTURE_UNITS][4],
- CONST GLchan spec[MAX_TEXTURE_UNITS][4],
- const GLfloat coverage[],
- GLenum primitive )
-{
- GLubyte mask[MAX_WIDTH];
- GLboolean write_all = GL_TRUE;
- GLchan rgbaBackup[MAX_WIDTH][4];
- GLchan (*rgba)[4]; /* points to either rgbaIn or rgbaBackup */
- GLuint i;
- const GLubyte *Null = 0;
- const GLuint texUnits = ctx->Const.MaxTextureUnits;
- SWcontext *swrast = SWRAST_CONTEXT(ctx);
-
- /* init mask to 1's (all pixels are to be written) */
- MEMSET(mask, 1, n);
-
- if ((swrast->_RasterMask & WINCLIP_BIT) || primitive==GL_BITMAP) {
- if ((n=clip_span(ctx, n, x, y, mask)) == 0) {
- return;
- }
- if (mask[0] == 0)
- write_all = GL_FALSE;
- }
-
-
- if (primitive==GL_BITMAP || (swrast->_RasterMask & MULTI_DRAW_BIT)
- || texUnits > 1) {
- /* must make a copy of the colors since they may be modified */
- MEMCPY(rgbaBackup, rgbaIn, 4 * n * sizeof(GLchan));
- rgba = rgbaBackup;
- }
- else {
- rgba = rgbaIn;
- }
-
- /* Do the scissor test */
- if (ctx->Scissor.Enabled) {
- if ((n = _mesa_scissor_span( ctx, n, x, y, mask )) == 0) {
- return;
+ for (i = 0; i < span->end; i++) {
+ if (span->array->mask[i]) {
+ assert(span->array->x[i] >= ctx->DrawBuffer->_Xmin);
+ assert(span->array->x[i] < ctx->DrawBuffer->_Xmax);
+ assert(span->array->y[i] >= ctx->DrawBuffer->_Ymin);
+ assert(span->array->y[i] < ctx->DrawBuffer->_Ymax);
+ }
}
- if (mask[0] == 0)
- write_all = GL_FALSE;
}
+#endif
/* Polygon Stippling */
- if (ctx->Polygon.StippleFlag && primitive==GL_POLYGON) {
- stipple_polygon_span( ctx, n, x, y, mask );
- write_all = GL_FALSE;
+ if (ctx->Polygon.StippleFlag && span->primitive == GL_POLYGON) {
+ stipple_polygon_span(ctx, span);
}
+ /* Need texture coordinates now */
+ if ((span->interpMask & SPAN_TEXTURE)
+ && (span->arrayMask & SPAN_TEXTURE) == 0)
+ interpolate_texcoords(ctx, span);
+
/* Texture with alpha test */
if (ctx->Color.AlphaEnabled) {
+
+ /* Now we need the rgba array, fill it in if needed */
+ if ((span->interpMask & SPAN_RGBA) && (span->arrayMask & SPAN_RGBA) == 0)
+ interpolate_colors(ctx, span);
+
/* Texturing without alpha is done after depth-testing which
* gives a potential speed-up.
*/
- ASSERT(ctx->Texture._ReallyEnabled);
- for (i = 0; i < texUnits; i++)
- _swrast_texture_fragments( ctx, i, n, s[i], t[i], u[i], lambda[i],
- (CONST GLchan (*)[4]) rgbaIn, rgba );
+ _swrast_texture_span( ctx, span );
/* Do the alpha test */
- if (_mesa_alpha_test( ctx, n, (const GLchan (*)[4])rgba, mask ) == 0) {
- return;
- }
- write_all = GL_FALSE;
- }
-
- if (ctx->Stencil.Enabled) {
- /* first stencil test */
- if (_mesa_stencil_and_ztest_span(ctx, n, x, y, z, mask) == GL_FALSE) {
+ if (!_mesa_alpha_test(ctx, span)) {
+ span->arrayMask = origArrayMask;
return;
}
- write_all = GL_FALSE;
}
- else if (ctx->Depth.Test) {
- /* regular depth testing */
- GLuint m = _mesa_depth_test_span( ctx, n, x, y, z, mask );
- if (m == 0) {
- return;
+
+ /* Stencil and Z testing */
+ if (ctx->Stencil.Enabled || ctx->Depth.Test) {
+ if (span->interpMask & SPAN_Z)
+ _mesa_span_interpolate_z(ctx, span);
+
+ if (ctx->Stencil.Enabled) {
+ if (!_mesa_stencil_and_ztest_span(ctx, span)) {
+ span->arrayMask = origArrayMask;
+ return;
+ }
}
- if (m < n) {
- write_all = GL_FALSE;
+ else {
+ ASSERT(ctx->Depth.Test);
+ ASSERT(span->arrayMask & SPAN_Z);
+ /* regular depth testing */
+ if (!_mesa_depth_test_span(ctx, span)) {
+ span->arrayMask = origArrayMask;
+ return;
+ }
}
}
- /* if we get here, something passed the depth test */
+ /* if we get here, some fragments passed the depth test */
ctx->OcclusionResult = GL_TRUE;
+ /* We had to wait until now to check for glColorMask(F,F,F,F) because of
+ * the occlusion test.
+ */
+ if (colorMask == 0x0) {
+ span->arrayMask = origArrayMask;
+ return;
+ }
+
/* Texture without alpha test */
- if (! ctx->Color.AlphaEnabled) {
- ASSERT(ctx->Texture._ReallyEnabled);
- for (i = 0; i < texUnits; i++)
- _swrast_texture_fragments( ctx, i, n, s[i], t[i], u[i], lambda[i],
- (CONST GLchan (*)[4]) rgbaIn, rgba );
+ if (!ctx->Color.AlphaEnabled) {
+
+ /* Now we need the rgba array, fill it in if needed */
+ if ((span->interpMask & SPAN_RGBA) && (span->arrayMask & SPAN_RGBA) == 0)
+ interpolate_colors(ctx, span);
+
+ _swrast_texture_span( ctx, span );
}
+ ASSERT(span->arrayMask & SPAN_RGBA);
+
/* Add base and specular colors */
- if (spec &&
- (ctx->Fog.ColorSumEnabled ||
- (ctx->Light.Enabled &&
- ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR)))
- add_colors( n, rgba, spec ); /* rgba = rgba + spec */
+ if (ctx->Fog.ColorSumEnabled ||
+ (ctx->Light.Enabled &&
+ ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR)) {
+ if (span->interpMask & SPAN_SPEC) {
+ interpolate_specular(ctx, span);
+ }
+ ASSERT(span->arrayMask & SPAN_SPEC);
+ add_colors( span->end, span->array->rgba, span->array->spec );
+ }
- /* Per-pixel fog */
+ /* Fog */
if (ctx->Fog.Enabled) {
- if (fog && !swrast->_PreferPixelFog)
- _mesa_fog_rgba_pixels( ctx, n, fog, rgba );
- else
- _mesa_depth_fog_rgba_pixels( ctx, n, z, rgba );
+ _mesa_fog_rgba_span(ctx, span);
}
/* Antialias coverage application */
- if (coverage) {
+ if (span->arrayMask & SPAN_COVERAGE) {
+ GLchan (*rgba)[4] = span->array->rgba;
+ GLfloat *coverage = span->array->coverage;
GLuint i;
- for (i = 0; i < n; i++) {
+ for (i = 0; i < span->end; i++) {
rgba[i][ACOMP] = (GLchan) (rgba[i][ACOMP] * coverage[i]);
}
}
if (swrast->_RasterMask & MULTI_DRAW_BIT) {
- multi_write_rgba_span( ctx, n, x, y, (const GLchan (*)[4]) rgba, mask );
+ multi_write_rgba_span(ctx, span);
}
else {
/* normal: write to exactly one buffer */
- const GLuint colorMask = *((GLuint *) ctx->Color.ColorMask);
-
if (ctx->Color.ColorLogicOpEnabled) {
- _mesa_logicop_rgba_span( ctx, n, x, y, rgba, mask );
+ _mesa_logicop_rgba_span(ctx, span, span->array->rgba);
}
- else if (ctx->Color.BlendEnabled) {
- _mesa_blend_span( ctx, n, x, y, rgba, mask );
+ else if (ctx->Color.BlendEnabled) {
+ _mesa_blend_span(ctx, span, span->array->rgba);
}
- if (colorMask == 0x0) {
- return;
- }
- else if (colorMask != 0xffffffff) {
- _mesa_mask_rgba_span( ctx, n, x, y, rgba );
+ if (colorMask != 0xffffffff) {
+ _mesa_mask_rgba_span(ctx, span, span->array->rgba);
}
- (*swrast->Driver.WriteRGBASpan)( ctx, n, x, y, (const GLchan (*)[4])rgba,
- write_all ? Null : mask );
- if (swrast->_RasterMask & ALPHABUF_BIT) {
- _mesa_write_alpha_span( ctx, n, x, y, (const GLchan (*)[4])rgba,
- write_all ? Null : mask );
+
+ if (span->arrayMask & SPAN_XY) {
+ /* array of pixel coords */
+ (*swrast->Driver.WriteRGBAPixels)(ctx, span->end, span->array->x,
+ span->array->y, (const GLchan (*)[4]) span->array->rgba, span->array->mask);
+ if (SWRAST_CONTEXT(ctx)->_RasterMask & ALPHABUF_BIT) {
+ _mesa_write_alpha_pixels(ctx, span->end,
+ span->array->x, span->array->y,
+ (const GLchan (*)[4]) span->array->rgba,
+ span->array->mask);
+ }
+ }
+ else {
+ /* horizontal run of pixels */
+ (*swrast->Driver.WriteRGBASpan)(ctx, span->end, span->x, span->y,
+ (const GLchan (*)[4]) span->array->rgba,
+ span->writeAll ? NULL : span->array->mask);
+ if (swrast->_RasterMask & ALPHABUF_BIT) {
+ _mesa_write_alpha_span(ctx, span->end, span->x, span->y,
+ (const GLchan (*)[4]) span->array->rgba,
+ span->writeAll ? NULL : span->array->mask);
+ }
}
}
+
+ span->arrayMask = origArrayMask;
}
-/*
+/**
* Read RGBA pixels from frame buffer. Clipping will be done to prevent
* reading ouside the buffer's boundaries.
*/
@@ -1139,7 +1323,7 @@ _mesa_read_rgba_span( GLcontext *ctx, GLframebuffer *buffer,
if (y < 0 || y >= bufHeight || x + (GLint) n < 0 || x >= bufWidth) {
/* completely above, below, or right */
/* XXX maybe leave undefined? */
- BZERO(rgba, 4 * n * sizeof(GLchan));
+ _mesa_bzero(rgba, 4 * n * sizeof(GLchan));
}
else {
GLint skip, length;
@@ -1152,7 +1336,7 @@ _mesa_read_rgba_span( GLcontext *ctx, GLframebuffer *buffer,
return;
}
if (length > bufWidth) {
- length = buffer->Width;
+ length = bufWidth;
}
}
else if ((GLint) (x + n) > bufWidth) {
@@ -1172,15 +1356,13 @@ _mesa_read_rgba_span( GLcontext *ctx, GLframebuffer *buffer,
(*swrast->Driver.ReadRGBASpan)( ctx, length, x + skip, y, rgba + skip );
if (buffer->UseSoftwareAlphaBuffers) {
- _mesa_read_alpha_span( ctx, length, x + skip, y, rgba + skip );
+ _mesa_read_alpha_span(ctx, length, x + skip, y, rgba + skip);
}
}
}
-
-
-/*
+/**
* Read CI pixels from frame buffer. Clipping will be done to prevent
* reading ouside the buffer's boundaries.
*/
@@ -1194,7 +1376,7 @@ _mesa_read_index_span( GLcontext *ctx, GLframebuffer *buffer,
if (y < 0 || y >= bufHeight || x + (GLint) n < 0 || x >= bufWidth) {
/* completely above, below, or right */
- BZERO(indx, n * sizeof(GLuint));
+ _mesa_bzero(indx, n * sizeof(GLuint));
}
else {
GLint skip, length;
diff --git a/xc/extras/Mesa/src/swrast/s_span.h b/xc/extras/Mesa/src/swrast/s_span.h
index 063494258..d37961e98 100644
--- a/xc/extras/Mesa/src/swrast/s_span.h
+++ b/xc/extras/Mesa/src/swrast/s_span.h
@@ -1,10 +1,9 @@
-/* $Id: s_span.h,v 1.1.1.1 2002/10/22 13:06:57 alanh Exp $ */
/*
* Mesa 3-D graphics library
- * Version: 3.5
+ * Version: 4.1
*
- * Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
+ * Copyright (C) 1999-2002 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,61 +33,38 @@
extern void
-_mesa_write_index_span( GLcontext *ctx, GLuint n, GLint x, GLint y,
- const GLdepth z[], const GLfloat fog[],
- GLuint index[], const GLint coverage[],
- GLenum primitive );
-
+_mesa_span_default_z( GLcontext *ctx, struct sw_span *span );
extern void
-_mesa_write_monoindex_span( GLcontext *ctx, GLuint n, GLint x, GLint y,
- const GLdepth z[], const GLfloat fog[],
- GLuint index, const GLint coverage[],
- GLenum primitive );
+_mesa_span_interpolate_z( const GLcontext *ctx, struct sw_span *span );
+extern void
+_mesa_span_default_fog( GLcontext *ctx, struct sw_span *span );
extern void
-_mesa_write_rgba_span( GLcontext *ctx, GLuint n, GLint x, GLint y,
- const GLdepth z[], const GLfloat fog[],
- GLchan rgba[][4], const GLfloat coverage[],
- GLenum primitive );
+_mesa_span_default_color( GLcontext *ctx, struct sw_span *span );
+extern void
+_mesa_span_default_texcoords( GLcontext *ctx, struct sw_span *span );
extern void
-_mesa_write_monocolor_span( GLcontext *ctx, GLuint n, GLint x, GLint y,
- const GLdepth z[], const GLfloat fog[],
- const GLchan color[4], const GLfloat coverage[],
- GLenum primitive );
+_mesa_write_index_span( GLcontext *ctx, struct sw_span *span);
extern void
-_mesa_write_texture_span( GLcontext *ctx, GLuint n, GLint x, GLint y,
- const GLdepth z[], const GLfloat fog[],
- const GLfloat s[], const GLfloat t[],
- const GLfloat u[], GLfloat lambda[],
- GLchan rgba[][4], CONST GLchan spec[][4],
- const GLfloat coverage[], GLenum primitive );
+_mesa_write_rgba_span( GLcontext *ctx, struct sw_span *span);
extern void
-_mesa_write_multitexture_span( GLcontext *ctx, GLuint n, GLint x, GLint y,
- const GLdepth z[], const GLfloat fog[],
- CONST GLfloat s[MAX_TEXTURE_UNITS][MAX_WIDTH],
- CONST GLfloat t[MAX_TEXTURE_UNITS][MAX_WIDTH],
- CONST GLfloat u[MAX_TEXTURE_UNITS][MAX_WIDTH],
- GLfloat lambda[MAX_TEXTURE_UNITS][MAX_WIDTH],
- GLchan rgba[][4], CONST GLchan spec[][4],
- const GLfloat coverage[], GLenum primitive );
+_mesa_write_texture_span( GLcontext *ctx, struct sw_span *span);
extern void
_mesa_read_rgba_span( GLcontext *ctx, GLframebuffer *buffer,
GLuint n, GLint x, GLint y, GLchan rgba[][4] );
-
extern void
_mesa_read_index_span( GLcontext *ctx, GLframebuffer *buffer,
GLuint n, GLint x, GLint y, GLuint indx[] );
-
#endif
diff --git a/xc/extras/Mesa/src/swrast/s_stencil.c b/xc/extras/Mesa/src/swrast/s_stencil.c
index 13ecc70da..b535830fe 100644
--- a/xc/extras/Mesa/src/swrast/s_stencil.c
+++ b/xc/extras/Mesa/src/swrast/s_stencil.c
@@ -1,8 +1,7 @@
-/* $Id: s_stencil.c,v 1.1.1.1 2002/10/22 13:06:41 alanh Exp $ */
/*
* Mesa 3-D graphics library
- * Version: 4.0.3
+ * Version: 4.1
*
* Copyright (C) 1999-2002 Brian Paul All Rights Reserved.
*
@@ -28,17 +27,14 @@
#include "glheader.h"
#include "context.h"
#include "macros.h"
-#include "mem.h"
+#include "imports.h"
#include "s_context.h"
#include "s_depth.h"
-#include "s_pb.h"
#include "s_stencil.h"
-
-
/* Stencil Logic:
IF stencil test fails THEN
@@ -55,8 +51,6 @@ ENDIF
*/
-
-
/*
* Return the address of a stencil buffer value given the window coords:
*/
@@ -65,22 +59,23 @@ ENDIF
-/*
+/**
* Apply the given stencil operator to the array of stencil values.
* Don't touch stencil[i] if mask[i] is zero.
* Input: n - size of stencil array
* oper - the stencil buffer operator
+ * face - 0 or 1 for front or back face operation
* stencil - array of stencil values
* mask - array [n] of flag: 1=apply operator, 0=don't apply operator
* Output: stencil - modified values
*/
-static void apply_stencil_op( const GLcontext *ctx, GLenum oper,
- GLuint n, GLstencil stencil[],
- const GLubyte mask[] )
+static void
+apply_stencil_op( const GLcontext *ctx, GLenum oper, GLuint face,
+ GLuint n, GLstencil stencil[], const GLubyte mask[] )
{
- const GLstencil ref = ctx->Stencil.Ref;
- const GLstencil wrtmask = ctx->Stencil.WriteMask;
- const GLstencil invmask = (GLstencil) (~ctx->Stencil.WriteMask);
+ const GLstencil ref = ctx->Stencil.Ref[face];
+ const GLstencil wrtmask = ctx->Stencil.WriteMask[face];
+ const GLstencil invmask = (GLstencil) (~wrtmask);
GLuint i;
switch (oper) {
@@ -226,9 +221,10 @@ static void apply_stencil_op( const GLcontext *ctx, GLenum oper,
-/*
+/**
* Apply stencil test to an array of stencil values (before depth buffering).
- * Input: n - number of pixels in the array
+ * Input: face - 0 or 1 for front or back-face polygons
+ * n - number of pixels in the array
* stencil - array of [n] stencil values
* mask - array [n] of flag: 0=skip the pixel, 1=stencil the pixel
* Output: mask - pixels which fail the stencil test will have their
@@ -237,15 +233,16 @@ static void apply_stencil_op( const GLcontext *ctx, GLenum oper,
* Return: GL_FALSE = all pixels failed, GL_TRUE = zero or more pixels passed.
*/
static GLboolean
-do_stencil_test( GLcontext *ctx, GLuint n, GLstencil stencil[],
+do_stencil_test( GLcontext *ctx, GLuint face, GLuint n, GLstencil stencil[],
GLubyte mask[] )
{
- GLubyte fail[PB_SIZE];
+ GLubyte fail[MAX_WIDTH];
GLboolean allfail = GL_FALSE;
GLuint i;
GLstencil r, s;
+ const GLuint valueMask = ctx->Stencil.ValueMask[face];
- ASSERT(n <= PB_SIZE);
+ ASSERT(n <= MAX_WIDTH);
/*
* Perform stencil test. The results of this operation are stored
@@ -256,9 +253,9 @@ do_stencil_test( GLcontext *ctx, GLuint n, GLstencil stencil[],
* the stencil fail operator is not to be applied
* ENDIF
*/
- switch (ctx->Stencil.Function) {
+ switch (ctx->Stencil.Function[face]) {
case GL_NEVER:
- /* always fail */
+ /* never pass; always fail */
for (i=0;i<n;i++) {
if (mask[i]) {
mask[i] = 0;
@@ -271,10 +268,10 @@ do_stencil_test( GLcontext *ctx, GLuint n, GLstencil stencil[],
allfail = GL_TRUE;
break;
case GL_LESS:
- r = (GLstencil) (ctx->Stencil.Ref & ctx->Stencil.ValueMask);
+ r = (GLstencil) (ctx->Stencil.Ref[face] & valueMask);
for (i=0;i<n;i++) {
if (mask[i]) {
- s = (GLstencil) (stencil[i] & ctx->Stencil.ValueMask);
+ s = (GLstencil) (stencil[i] & valueMask);
if (r < s) {
/* passed */
fail[i] = 0;
@@ -290,10 +287,10 @@ do_stencil_test( GLcontext *ctx, GLuint n, GLstencil stencil[],
}
break;
case GL_LEQUAL:
- r = (GLstencil) (ctx->Stencil.Ref & ctx->Stencil.ValueMask);
+ r = (GLstencil) (ctx->Stencil.Ref[face] & valueMask);
for (i=0;i<n;i++) {
if (mask[i]) {
- s = (GLstencil) (stencil[i] & ctx->Stencil.ValueMask);
+ s = (GLstencil) (stencil[i] & valueMask);
if (r <= s) {
/* pass */
fail[i] = 0;
@@ -309,10 +306,10 @@ do_stencil_test( GLcontext *ctx, GLuint n, GLstencil stencil[],
}
break;
case GL_GREATER:
- r = (GLstencil) (ctx->Stencil.Ref & ctx->Stencil.ValueMask);
+ r = (GLstencil) (ctx->Stencil.Ref[face] & valueMask);
for (i=0;i<n;i++) {
if (mask[i]) {
- s = (GLstencil) (stencil[i] & ctx->Stencil.ValueMask);
+ s = (GLstencil) (stencil[i] & valueMask);
if (r > s) {
/* passed */
fail[i] = 0;
@@ -328,10 +325,10 @@ do_stencil_test( GLcontext *ctx, GLuint n, GLstencil stencil[],
}
break;
case GL_GEQUAL:
- r = (GLstencil) (ctx->Stencil.Ref & ctx->Stencil.ValueMask);
+ r = (GLstencil) (ctx->Stencil.Ref[face] & valueMask);
for (i=0;i<n;i++) {
if (mask[i]) {
- s = (GLstencil) (stencil[i] & ctx->Stencil.ValueMask);
+ s = (GLstencil) (stencil[i] & valueMask);
if (r >= s) {
/* passed */
fail[i] = 0;
@@ -347,10 +344,10 @@ do_stencil_test( GLcontext *ctx, GLuint n, GLstencil stencil[],
}
break;
case GL_EQUAL:
- r = (GLstencil) (ctx->Stencil.Ref & ctx->Stencil.ValueMask);
+ r = (GLstencil) (ctx->Stencil.Ref[face] & valueMask);
for (i=0;i<n;i++) {
if (mask[i]) {
- s = (GLstencil) (stencil[i] & ctx->Stencil.ValueMask);
+ s = (GLstencil) (stencil[i] & valueMask);
if (r == s) {
/* passed */
fail[i] = 0;
@@ -366,10 +363,10 @@ do_stencil_test( GLcontext *ctx, GLuint n, GLstencil stencil[],
}
break;
case GL_NOTEQUAL:
- r = (GLstencil) (ctx->Stencil.Ref & ctx->Stencil.ValueMask);
+ r = (GLstencil) (ctx->Stencil.Ref[face] & valueMask);
for (i=0;i<n;i++) {
if (mask[i]) {
- s = (GLstencil) (stencil[i] & ctx->Stencil.ValueMask);
+ s = (GLstencil) (stencil[i] & valueMask);
if (r != s) {
/* passed */
fail[i] = 0;
@@ -395,8 +392,8 @@ do_stencil_test( GLcontext *ctx, GLuint n, GLstencil stencil[],
return 0;
}
- if (ctx->Stencil.FailFunc != GL_KEEP) {
- apply_stencil_op( ctx, ctx->Stencil.FailFunc, n, stencil, fail );
+ if (ctx->Stencil.FailFunc[face] != GL_KEEP) {
+ apply_stencil_op( ctx, ctx->Stencil.FailFunc[face], face, n, stencil, fail );
}
return !allfail;
@@ -404,47 +401,69 @@ do_stencil_test( GLcontext *ctx, GLuint n, GLstencil stencil[],
-
-/*
- * Apply stencil and depth testing to an array of pixels.
- * Hardware or software stencil buffer acceptable.
+/**
+ * Apply stencil and depth testing to the span of pixels.
+ * Both software and hardware stencil buffers are acceptable.
* Input: n - number of pixels in the span
+ * x, y - location of leftmost pixel in span
* z - array [n] of z values
- * stencil - array [n] of stencil values
* mask - array [n] of flags (1=test this pixel, 0=skip the pixel)
- * Output: stencil - modified stencil values
- * mask - array [n] of flags (1=stencil and depth test passed)
- * Return: GL_TRUE - all fragments failed the testing
- * GL_FALSE - one or more fragments passed the testing
+ * Output: mask - array [n] of flags (1=stencil and depth test passed)
+ * Return: GL_FALSE - all fragments failed the testing
+ * GL_TRUE - one or more fragments passed the testing
*
*/
static GLboolean
-stencil_and_ztest_span( GLcontext *ctx, GLuint n, GLint x, GLint y,
- const GLdepth z[], GLstencil stencil[],
- GLubyte mask[] )
+stencil_and_ztest_span(GLcontext *ctx, struct sw_span *span, GLuint face)
{
- ASSERT(ctx->Stencil.Enabled);
- ASSERT(n <= PB_SIZE);
+ SWcontext *swrast = SWRAST_CONTEXT(ctx);
+ GLstencil stencilRow[MAX_WIDTH];
+ GLstencil *stencil;
+ const GLuint n = span->end;
+ const GLint x = span->x;
+ const GLint y = span->y;
+ GLubyte *mask = span->array->mask;
+ ASSERT((span->arrayMask & SPAN_XY) == 0);
+ ASSERT(ctx->Stencil.Enabled);
+ ASSERT(n <= MAX_WIDTH);
+#ifdef DEBUG
+ if (ctx->Depth.Test) {
+ ASSERT(span->arrayMask & SPAN_Z);
+ }
+#endif
+
+ /* Get initial stencil values */
+ if (swrast->Driver.WriteStencilSpan) {
+ /* Get stencil values from the hardware stencil buffer */
+ ASSERT(swrast->Driver.ReadStencilSpan);
+ (*swrast->Driver.ReadStencilSpan)(ctx, n, x, y, stencilRow);
+ stencil = stencilRow;
+ }
+ else {
+ /* Get pointer into software stencil buffer */
+ stencil = STENCIL_ADDRESS(x, y);
+ }
+
/*
* Apply the stencil test to the fragments.
* failMask[i] is 1 if the stencil test failed.
*/
- if (do_stencil_test( ctx, n, stencil, mask ) == GL_FALSE) {
+ if (do_stencil_test( ctx, face, n, stencil, mask ) == GL_FALSE) {
/* all fragments failed the stencil test, we're done. */
+ span->writeAll = GL_FALSE;
return GL_FALSE;
}
-
/*
* Some fragments passed the stencil test, apply depth test to them
* and apply Zpass and Zfail stencil ops.
*/
- if (ctx->Depth.Test==GL_FALSE) {
+ if (ctx->Depth.Test == GL_FALSE) {
/*
* No depth buffer, just apply zpass stencil function to active pixels.
*/
- apply_stencil_op( ctx, ctx->Stencil.ZPassFunc, n, stencil, mask );
+ apply_stencil_op( ctx, ctx->Stencil.ZPassFunc[face], face, n, stencil, mask );
}
else {
/*
@@ -457,7 +476,7 @@ stencil_and_ztest_span( GLcontext *ctx, GLuint n, GLint x, GLint y,
MEMCPY(oldmask, mask, n * sizeof(GLubyte));
/* apply the depth test */
- _mesa_depth_test_span(ctx, n, x, y, z, mask);
+ _mesa_depth_test_span(ctx, span);
/* Set the stencil pass/fail flags according to result of depth testing.
* if oldmask[i] == 0 then
@@ -476,72 +495,36 @@ stencil_and_ztest_span( GLcontext *ctx, GLuint n, GLint x, GLint y,
}
/* apply the pass and fail operations */
- if (ctx->Stencil.ZFailFunc != GL_KEEP) {
- apply_stencil_op( ctx, ctx->Stencil.ZFailFunc, n, stencil, failmask );
+ if (ctx->Stencil.ZFailFunc[face] != GL_KEEP) {
+ apply_stencil_op( ctx, ctx->Stencil.ZFailFunc[face], face,
+ n, stencil, failmask );
}
- if (ctx->Stencil.ZPassFunc != GL_KEEP) {
- apply_stencil_op( ctx, ctx->Stencil.ZPassFunc, n, stencil, passmask );
+ if (ctx->Stencil.ZPassFunc[face] != GL_KEEP) {
+ apply_stencil_op( ctx, ctx->Stencil.ZPassFunc[face], face,
+ n, stencil, passmask );
}
}
- return GL_TRUE; /* one or more fragments passed both tests */
-}
-
-
-
-/*
- * Apply stencil and depth testing to the span of pixels.
- * Both software and hardware stencil buffers are acceptable.
- * Input: n - number of pixels in the span
- * x, y - location of leftmost pixel in span
- * z - array [n] of z values
- * mask - array [n] of flags (1=test this pixel, 0=skip the pixel)
- * Output: mask - array [n] of flags (1=stencil and depth test passed)
- * Return: GL_TRUE - all fragments failed the testing
- * GL_FALSE - one or more fragments passed the testing
- *
- */
-GLboolean
-_mesa_stencil_and_ztest_span( GLcontext *ctx, GLuint n, GLint x, GLint y,
- const GLdepth z[], GLubyte mask[] )
-{
- SWcontext *swrast = SWRAST_CONTEXT(ctx);
- GLstencil stencilRow[MAX_WIDTH];
- GLstencil *stencil;
- GLboolean result;
-
- ASSERT(ctx->Stencil.Enabled);
- ASSERT(n <= MAX_WIDTH);
-
- /* Get initial stencil values */
- if (swrast->Driver.WriteStencilSpan) {
- ASSERT(swrast->Driver.ReadStencilSpan);
- /* Get stencil values from the hardware stencil buffer */
- (*swrast->Driver.ReadStencilSpan)(ctx, n, x, y, stencilRow);
- stencil = stencilRow;
- }
- else {
- /* software stencil buffer */
- stencil = STENCIL_ADDRESS(x, y);
- }
-
- /* do all the stencil/depth testing/updating */
- result = stencil_and_ztest_span( ctx, n, x, y, z, stencil, mask );
-
+ /*
+ * Write updated stencil values back into hardware stencil buffer.
+ */
if (swrast->Driver.WriteStencilSpan) {
- /* Write updated stencil values into hardware stencil buffer */
+ ASSERT(stencil == stencilRow);
(swrast->Driver.WriteStencilSpan)(ctx, n, x, y, stencil, mask );
}
-
- return result;
+
+ span->writeAll = GL_FALSE;
+
+ return GL_TRUE; /* one or more fragments passed both tests */
}
-/*
+/**
* Apply the given stencil operator for each pixel in the array whose
- * mask flag is set. This is for software stencil buffers only.
+ * mask flag is set.
+ * \note This is for software stencil buffers only.
* Input: n - number of pixels in the span
* x, y - array of [n] pixels
* operator - the stencil buffer operator
@@ -550,11 +533,11 @@ _mesa_stencil_and_ztest_span( GLcontext *ctx, GLuint n, GLint x, GLint y,
static void
apply_stencil_op_to_pixels( const GLcontext *ctx,
GLuint n, const GLint x[], const GLint y[],
- GLenum oper, const GLubyte mask[] )
+ GLenum oper, GLuint face, const GLubyte mask[] )
{
- const GLstencil ref = ctx->Stencil.Ref;
- const GLstencil wrtmask = ctx->Stencil.WriteMask;
- const GLstencil invmask = (GLstencil) (~ctx->Stencil.WriteMask);
+ const GLstencil ref = ctx->Stencil.Ref[face];
+ const GLstencil wrtmask = ctx->Stencil.WriteMask[face];
+ const GLstencil invmask = (GLstencil) (~wrtmask);
GLuint i;
ASSERT(!SWRAST_CONTEXT(ctx)->Driver.WriteStencilSpan); /* software stencil buffer only! */
@@ -704,26 +687,31 @@ apply_stencil_op_to_pixels( const GLcontext *ctx,
-/*
+/**
* Apply stencil test to an array of pixels before depth buffering.
- * Used for software stencil buffer only.
+ *
+ * \note Used for software stencil buffer only.
* Input: n - number of pixels in the span
* x, y - array of [n] pixels to stencil
* mask - array [n] of flag: 0=skip the pixel, 1=stencil the pixel
* Output: mask - pixels which fail the stencil test will have their
* mask flag set to 0.
- * Return: 0 = all pixels failed, 1 = zero or more pixels passed.
+ * \return GL_FALSE = all pixels failed, GL_TRUE = zero or more pixels passed.
*/
static GLboolean
-stencil_test_pixels( GLcontext *ctx, GLuint n,
+stencil_test_pixels( GLcontext *ctx, GLuint face, GLuint n,
const GLint x[], const GLint y[], GLubyte mask[] )
{
- GLubyte fail[PB_SIZE];
+ GLubyte fail[MAX_WIDTH];
GLstencil r, s;
GLuint i;
GLboolean allfail = GL_FALSE;
+ const GLuint valueMask = ctx->Stencil.ValueMask[face];
- ASSERT(!SWRAST_CONTEXT(ctx)->Driver.WriteStencilSpan); /* software stencil buffer only! */
+ /* software stencil buffer only! */
+ ASSERT(ctx->DrawBuffer->UseSoftwareStencilBuffer);
+ ASSERT(!SWRAST_CONTEXT(ctx)->Driver.ReadStencilSpan);
+ ASSERT(!SWRAST_CONTEXT(ctx)->Driver.WriteStencilSpan);
/*
* Perform stencil test. The results of this operation are stored
@@ -735,7 +723,7 @@ stencil_test_pixels( GLcontext *ctx, GLuint n,
* ENDIF
*/
- switch (ctx->Stencil.Function) {
+ switch (ctx->Stencil.Function[face]) {
case GL_NEVER:
/* always fail */
for (i=0;i<n;i++) {
@@ -750,11 +738,11 @@ stencil_test_pixels( GLcontext *ctx, GLuint n,
allfail = GL_TRUE;
break;
case GL_LESS:
- r = (GLstencil) (ctx->Stencil.Ref & ctx->Stencil.ValueMask);
+ r = (GLstencil) (ctx->Stencil.Ref[face] & valueMask);
for (i=0;i<n;i++) {
if (mask[i]) {
GLstencil *sptr = STENCIL_ADDRESS(x[i],y[i]);
- s = (GLstencil) (*sptr & ctx->Stencil.ValueMask);
+ s = (GLstencil) (*sptr & valueMask);
if (r < s) {
/* passed */
fail[i] = 0;
@@ -770,11 +758,11 @@ stencil_test_pixels( GLcontext *ctx, GLuint n,
}
break;
case GL_LEQUAL:
- r = (GLstencil) (ctx->Stencil.Ref & ctx->Stencil.ValueMask);
+ r = (GLstencil) (ctx->Stencil.Ref[face] & valueMask);
for (i=0;i<n;i++) {
if (mask[i]) {
GLstencil *sptr = STENCIL_ADDRESS(x[i],y[i]);
- s = (GLstencil) (*sptr & ctx->Stencil.ValueMask);
+ s = (GLstencil) (*sptr & valueMask);
if (r <= s) {
/* pass */
fail[i] = 0;
@@ -790,11 +778,11 @@ stencil_test_pixels( GLcontext *ctx, GLuint n,
}
break;
case GL_GREATER:
- r = (GLstencil) (ctx->Stencil.Ref & ctx->Stencil.ValueMask);
+ r = (GLstencil) (ctx->Stencil.Ref[face] & valueMask);
for (i=0;i<n;i++) {
if (mask[i]) {
GLstencil *sptr = STENCIL_ADDRESS(x[i],y[i]);
- s = (GLstencil) (*sptr & ctx->Stencil.ValueMask);
+ s = (GLstencil) (*sptr & valueMask);
if (r > s) {
/* passed */
fail[i] = 0;
@@ -810,11 +798,11 @@ stencil_test_pixels( GLcontext *ctx, GLuint n,
}
break;
case GL_GEQUAL:
- r = (GLstencil) (ctx->Stencil.Ref & ctx->Stencil.ValueMask);
+ r = (GLstencil) (ctx->Stencil.Ref[face] & valueMask);
for (i=0;i<n;i++) {
if (mask[i]) {
GLstencil *sptr = STENCIL_ADDRESS(x[i],y[i]);
- s = (GLstencil) (*sptr & ctx->Stencil.ValueMask);
+ s = (GLstencil) (*sptr & valueMask);
if (r >= s) {
/* passed */
fail[i] = 0;
@@ -830,11 +818,11 @@ stencil_test_pixels( GLcontext *ctx, GLuint n,
}
break;
case GL_EQUAL:
- r = (GLstencil) (ctx->Stencil.Ref & ctx->Stencil.ValueMask);
+ r = (GLstencil) (ctx->Stencil.Ref[face] & valueMask);
for (i=0;i<n;i++) {
if (mask[i]) {
GLstencil *sptr = STENCIL_ADDRESS(x[i],y[i]);
- s = (GLstencil) (*sptr & ctx->Stencil.ValueMask);
+ s = (GLstencil) (*sptr & valueMask);
if (r == s) {
/* passed */
fail[i] = 0;
@@ -850,11 +838,11 @@ stencil_test_pixels( GLcontext *ctx, GLuint n,
}
break;
case GL_NOTEQUAL:
- r = (GLstencil) (ctx->Stencil.Ref & ctx->Stencil.ValueMask);
+ r = (GLstencil) (ctx->Stencil.Ref[face] & valueMask);
for (i=0;i<n;i++) {
if (mask[i]) {
GLstencil *sptr = STENCIL_ADDRESS(x[i],y[i]);
- s = (GLstencil) (*sptr & ctx->Stencil.ValueMask);
+ s = (GLstencil) (*sptr & valueMask);
if (r != s) {
/* passed */
fail[i] = 0;
@@ -880,8 +868,9 @@ stencil_test_pixels( GLcontext *ctx, GLuint n,
return 0;
}
- if (ctx->Stencil.FailFunc != GL_KEEP) {
- apply_stencil_op_to_pixels( ctx, n, x, y, ctx->Stencil.FailFunc, fail );
+ if (ctx->Stencil.FailFunc[face] != GL_KEEP) {
+ apply_stencil_op_to_pixels( ctx, n, x, y, ctx->Stencil.FailFunc[face],
+ face, fail );
}
return !allfail;
@@ -890,7 +879,7 @@ stencil_test_pixels( GLcontext *ctx, GLuint n,
-/*
+/**
* Apply stencil and depth testing to an array of pixels.
* This is used both for software and hardware stencil buffers.
*
@@ -903,54 +892,60 @@ stencil_test_pixels( GLcontext *ctx, GLuint n,
* z - array [n] of z values
* mask - array [n] of flags (1=test this pixel, 0=skip the pixel)
* Output: mask - array [n] of flags (1=stencil and depth test passed)
- * Return: GL_TRUE - all fragments failed the testing
- * GL_FALSE - one or more fragments passed the testing
+ * Return: GL_FALSE - all fragments failed the testing
+ * GL_TRUE - one or more fragments passed the testing
*/
-GLboolean
-_mesa_stencil_and_ztest_pixels( GLcontext *ctx,
- GLuint n, const GLint x[], const GLint y[],
- const GLdepth z[], GLubyte mask[] )
+static GLboolean
+stencil_and_ztest_pixels( GLcontext *ctx, struct sw_span *span, GLuint face )
{
+ const GLuint n = span->end;
+ const GLint *x = span->array->x;
+ const GLint *y = span->array->y;
+ GLubyte *mask = span->array->mask;
SWcontext *swrast = SWRAST_CONTEXT(ctx);
+
+ ASSERT(span->arrayMask & SPAN_XY);
ASSERT(ctx->Stencil.Enabled);
- ASSERT(n <= PB_SIZE);
+ ASSERT(n <= MAX_WIDTH);
if (swrast->Driver.WriteStencilPixels) {
/*** Hardware stencil buffer ***/
- GLstencil stencil[PB_SIZE];
- GLubyte origMask[PB_SIZE];
+ GLstencil stencil[MAX_WIDTH];
+ GLubyte origMask[MAX_WIDTH];
+ ASSERT(!ctx->DrawBuffer->UseSoftwareStencilBuffer);
ASSERT(swrast->Driver.ReadStencilPixels);
(*swrast->Driver.ReadStencilPixels)(ctx, n, x, y, stencil);
MEMCPY(origMask, mask, n * sizeof(GLubyte));
- (void) do_stencil_test(ctx, n, stencil, mask);
+ (void) do_stencil_test(ctx, face, n, stencil, mask);
if (ctx->Depth.Test == GL_FALSE) {
- apply_stencil_op(ctx, ctx->Stencil.ZPassFunc, n, stencil, mask);
+ apply_stencil_op(ctx, ctx->Stencil.ZPassFunc[face], face,
+ n, stencil, mask);
}
else {
- _mesa_depth_test_pixels(ctx, n, x, y, z, mask);
+ _mesa_depth_test_span(ctx, span);
- if (ctx->Stencil.ZFailFunc != GL_KEEP) {
- GLubyte failmask[PB_SIZE];
+ if (ctx->Stencil.ZFailFunc[face] != GL_KEEP) {
+ GLubyte failmask[MAX_WIDTH];
GLuint i;
for (i = 0; i < n; i++) {
ASSERT(mask[i] == 0 || mask[i] == 1);
failmask[i] = origMask[i] & (mask[i] ^ 1);
}
- apply_stencil_op(ctx, ctx->Stencil.ZFailFunc,
+ apply_stencil_op(ctx, ctx->Stencil.ZFailFunc[face], face,
n, stencil, failmask);
}
- if (ctx->Stencil.ZPassFunc != GL_KEEP) {
- GLubyte passmask[PB_SIZE];
+ if (ctx->Stencil.ZPassFunc[face] != GL_KEEP) {
+ GLubyte passmask[MAX_WIDTH];
GLuint i;
for (i = 0; i < n; i++) {
ASSERT(mask[i] == 0 || mask[i] == 1);
passmask[i] = origMask[i] & mask[i];
}
- apply_stencil_op(ctx, ctx->Stencil.ZPassFunc,
+ apply_stencil_op(ctx, ctx->Stencil.ZPassFunc[face], face,
n, stencil, passmask);
}
}
@@ -963,22 +958,24 @@ _mesa_stencil_and_ztest_pixels( GLcontext *ctx,
else {
/*** Software stencil buffer ***/
- if (stencil_test_pixels(ctx, n, x, y, mask) == GL_FALSE) {
+ ASSERT(ctx->DrawBuffer->UseSoftwareStencilBuffer);
+
+ if (stencil_test_pixels(ctx, face, n, x, y, mask) == GL_FALSE) {
/* all fragments failed the stencil test, we're done. */
return GL_FALSE;
}
if (ctx->Depth.Test==GL_FALSE) {
apply_stencil_op_to_pixels(ctx, n, x, y,
- ctx->Stencil.ZPassFunc, mask);
+ ctx->Stencil.ZPassFunc[face], face, mask);
}
else {
- GLubyte passmask[PB_SIZE], failmask[PB_SIZE], oldmask[PB_SIZE];
+ GLubyte passmask[MAX_WIDTH], failmask[MAX_WIDTH], oldmask[MAX_WIDTH];
GLuint i;
MEMCPY(oldmask, mask, n * sizeof(GLubyte));
- _mesa_depth_test_pixels(ctx, n, x, y, z, mask);
+ _mesa_depth_test_span(ctx, span);
for (i=0;i<n;i++) {
ASSERT(mask[i] == 0 || mask[i] == 1);
@@ -986,13 +983,15 @@ _mesa_stencil_and_ztest_pixels( GLcontext *ctx,
failmask[i] = oldmask[i] & (mask[i] ^ 1);
}
- if (ctx->Stencil.ZFailFunc != GL_KEEP) {
+ if (ctx->Stencil.ZFailFunc[face] != GL_KEEP) {
apply_stencil_op_to_pixels(ctx, n, x, y,
- ctx->Stencil.ZFailFunc, failmask);
+ ctx->Stencil.ZFailFunc[face],
+ face, failmask);
}
- if (ctx->Stencil.ZPassFunc != GL_KEEP) {
+ if (ctx->Stencil.ZPassFunc[face] != GL_KEEP) {
apply_stencil_op_to_pixels(ctx, n, x, y,
- ctx->Stencil.ZPassFunc, passmask);
+ ctx->Stencil.ZPassFunc[face],
+ face, passmask);
}
}
@@ -1001,8 +1000,23 @@ _mesa_stencil_and_ztest_pixels( GLcontext *ctx,
}
+/**
+ * /return GL_TRUE = one or more fragments passed,
+ * GL_FALSE = all fragments failed.
+ */
+GLboolean
+_mesa_stencil_and_ztest_span(GLcontext *ctx, struct sw_span *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
+ return stencil_and_ztest_span(ctx, span, span->facing);
+}
-/*
+
+/**
* Return a span of stencil values from the stencil buffer.
* Used for glRead/CopyPixels
* Input: n - how many pixels
@@ -1014,8 +1028,10 @@ _mesa_read_stencil_span( GLcontext *ctx,
GLint n, GLint x, GLint y, GLstencil stencil[] )
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
- if (y < 0 || y >= (GLint) ctx->DrawBuffer->Height ||
- x + n <= 0 || x >= (GLint) ctx->DrawBuffer->Width) {
+ const GLint bufWidth = (GLint) ctx->DrawBuffer->Width;
+ const GLint bufHeight = (GLint) ctx->DrawBuffer->Height;
+
+ if (y < 0 || y >= bufHeight || x + n <= 0 || x >= bufWidth) {
/* span is completely outside framebuffer */
return; /* undefined values OK */
}
@@ -1026,8 +1042,8 @@ _mesa_read_stencil_span( GLcontext *ctx,
n -= dx;
stencil += dx;
}
- if (x + n > (GLint) ctx->DrawBuffer->Width) {
- GLint dx = x + n - (GLint) ctx->DrawBuffer->Width;
+ if (x + n > bufWidth) {
+ GLint dx = x + n - bufWidth;
n -= dx;
}
if (n <= 0) {
@@ -1053,7 +1069,7 @@ _mesa_read_stencil_span( GLcontext *ctx,
-/*
+/**
* Write a span of stencil values to the stencil buffer.
* Used for glDraw/CopyPixels
* Input: n - how many pixels
@@ -1066,9 +1082,10 @@ _mesa_write_stencil_span( GLcontext *ctx, GLint n, GLint x, GLint y,
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
const GLstencil *ssrc = stencil;
+ const GLint bufWidth = (GLint) ctx->DrawBuffer->Width;
+ const GLint bufHeight = (GLint) ctx->DrawBuffer->Height;
- if (y < 0 || y >= (GLint) ctx->DrawBuffer->Height ||
- x + n <= 0 || x >= (GLint) ctx->DrawBuffer->Width) {
+ if (y < 0 || y >= bufHeight || x + n <= 0 || x >= bufWidth) {
/* span is completely outside framebuffer */
return; /* undefined values OK */
}
@@ -1079,8 +1096,8 @@ _mesa_write_stencil_span( GLcontext *ctx, GLint n, GLint x, GLint y,
n -= dx;
ssrc += dx;
}
- if (x + n > (GLint) ctx->DrawBuffer->Width) {
- GLint dx = x + n - (GLint) ctx->DrawBuffer->Width;
+ if (x + n > bufWidth) {
+ GLint dx = x + n - bufWidth;
n -= dx;
}
if (n <= 0) {
@@ -1104,7 +1121,7 @@ _mesa_write_stencil_span( GLcontext *ctx, GLint n, GLint x, GLint y,
-/*
+/**
* Allocate a new stencil buffer. If there's an old one it will be
* deallocated first. The new stencil buffer will be uninitialized.
*/
@@ -1118,8 +1135,8 @@ _mesa_alloc_stencil_buffer( GLframebuffer *buffer )
}
/* allocate new stencil buffer */
- buffer->Stencil = (GLstencil *) MESA_PBUFFER_ALLOC(buffer->Width * buffer->Height
- * sizeof(GLstencil));
+ buffer->Stencil = (GLstencil *)
+ MESA_PBUFFER_ALLOC(buffer->Width * buffer->Height * sizeof(GLstencil));
if (!buffer->Stencil) {
/* out of memory */
_mesa_error( NULL, GL_OUT_OF_MEMORY, "_mesa_alloc_stencil_buffer" );
@@ -1128,7 +1145,7 @@ _mesa_alloc_stencil_buffer( GLframebuffer *buffer )
-/*
+/**
* Clear the software (malloc'd) stencil buffer.
*/
static void
@@ -1142,11 +1159,11 @@ clear_software_stencil_buffer( GLcontext *ctx )
if (ctx->Scissor.Enabled) {
/* clear scissor region only */
const GLint width = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin;
- if (ctx->Stencil.WriteMask != STENCIL_MAX) {
+ if (ctx->Stencil.WriteMask[0] != STENCIL_MAX) {
/* must apply mask to the clear */
GLint y;
for (y = ctx->DrawBuffer->_Ymin; y < ctx->DrawBuffer->_Ymax; y++) {
- const GLstencil mask = ctx->Stencil.WriteMask;
+ const GLstencil mask = ctx->Stencil.WriteMask[0];
const GLstencil invMask = ~mask;
const GLstencil clearVal = (ctx->Stencil.Clear & mask);
GLstencil *stencil = STENCIL_ADDRESS( ctx->DrawBuffer->_Xmin, y );
@@ -1173,11 +1190,11 @@ clear_software_stencil_buffer( GLcontext *ctx )
}
else {
/* clear whole stencil buffer */
- if (ctx->Stencil.WriteMask != STENCIL_MAX) {
+ if (ctx->Stencil.WriteMask[0] != STENCIL_MAX) {
/* must apply mask to the clear */
const GLuint n = ctx->DrawBuffer->Width * ctx->DrawBuffer->Height;
GLstencil *stencil = ctx->DrawBuffer->Stencil;
- const GLstencil mask = ctx->Stencil.WriteMask;
+ const GLstencil mask = ctx->Stencil.WriteMask[0];
const GLstencil invMask = ~mask;
const GLstencil clearVal = (ctx->Stencil.Clear & mask);
GLuint i;
@@ -1204,7 +1221,7 @@ clear_software_stencil_buffer( GLcontext *ctx )
-/*
+/**
* Clear the hardware (in graphics card) stencil buffer.
* This is done with the Driver.WriteStencilSpan() and Driver.ReadStencilSpan()
* functions.
@@ -1224,11 +1241,11 @@ clear_hardware_stencil_buffer( GLcontext *ctx )
/* clear scissor region only */
const GLint x = ctx->DrawBuffer->_Xmin;
const GLint width = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin;
- if (ctx->Stencil.WriteMask != STENCIL_MAX) {
+ if (ctx->Stencil.WriteMask[0] != STENCIL_MAX) {
/* must apply mask to the clear */
GLint y;
for (y = ctx->DrawBuffer->_Ymin; y < ctx->DrawBuffer->_Ymax; y++) {
- const GLstencil mask = ctx->Stencil.WriteMask;
+ const GLstencil mask = ctx->Stencil.WriteMask[0];
const GLstencil invMask = ~mask;
const GLstencil clearVal = (ctx->Stencil.Clear & mask);
GLstencil stencil[MAX_WIDTH];
@@ -1254,9 +1271,9 @@ clear_hardware_stencil_buffer( GLcontext *ctx )
}
else {
/* clear whole stencil buffer */
- if (ctx->Stencil.WriteMask != STENCIL_MAX) {
+ if (ctx->Stencil.WriteMask[0] != STENCIL_MAX) {
/* must apply mask to the clear */
- const GLstencil mask = ctx->Stencil.WriteMask;
+ const GLstencil mask = ctx->Stencil.WriteMask[0];
const GLstencil invMask = ~mask;
const GLstencil clearVal = (ctx->Stencil.Clear & mask);
const GLint width = ctx->DrawBuffer->Width;
@@ -1292,8 +1309,8 @@ clear_hardware_stencil_buffer( GLcontext *ctx )
-/*
- * Clear the stencil buffer.
+/**
+ * Clear the stencil buffer (hardware or software).
*/
void
_mesa_clear_stencil_buffer( GLcontext *ctx )
diff --git a/xc/extras/Mesa/src/swrast/s_stencil.h b/xc/extras/Mesa/src/swrast/s_stencil.h
index 03e0de901..30b390e1b 100644
--- a/xc/extras/Mesa/src/swrast/s_stencil.h
+++ b/xc/extras/Mesa/src/swrast/s_stencil.h
@@ -1,8 +1,7 @@
-/* $Id: s_stencil.h,v 1.1.1.1 2002/10/22 13:06:41 alanh Exp $ */
/*
* Mesa 3-D graphics library
- * Version: 4.0.2
+ * Version: 4.1
*
* Copyright (C) 1999-2002 Brian Paul All Rights Reserved.
*
@@ -33,14 +32,10 @@
#include "swrast.h"
-extern GLboolean
-_mesa_stencil_and_ztest_span( GLcontext *ctx, GLuint n, GLint x, GLint y,
- const GLdepth z[], GLubyte mask[] );
extern GLboolean
-_mesa_stencil_and_ztest_pixels( GLcontext *ctx, GLuint n,
- const GLint x[], const GLint y[],
- const GLdepth z[], GLubyte mask[] );
+_mesa_stencil_and_ztest_span(GLcontext *ctx, struct sw_span *span);
+
extern void
diff --git a/xc/extras/Mesa/src/swrast/s_texstore.c b/xc/extras/Mesa/src/swrast/s_texstore.c
index 0ec021b70..1865b22e3 100644
--- a/xc/extras/Mesa/src/swrast/s_texstore.c
+++ b/xc/extras/Mesa/src/swrast/s_texstore.c
@@ -1,10 +1,9 @@
-/* $Id: s_texstore.c,v 1.1.1.1 2002/10/22 13:06:53 alanh Exp $ */
/*
* Mesa 3-D graphics library
- * Version: 3.5
+ * Version: 4.1
*
- * Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
+ * Copyright (C) 1999-2002 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"),
@@ -42,8 +41,8 @@
#include "context.h"
#include "convolve.h"
#include "image.h"
+#include "imports.h"
#include "macros.h"
-#include "mem.h"
#include "texformat.h"
#include "teximage.h"
#include "texstore.h"
@@ -73,8 +72,7 @@ read_color_image( GLcontext *ctx, GLint x, GLint y,
return NULL;
/* Select buffer to read from */
- (*swrast->Driver.SetReadBuffer)( ctx, ctx->ReadBuffer,
- ctx->Pixel.DriverReadBuffer );
+ _swrast_use_read_buffer(ctx);
RENDER_START(swrast,ctx);
@@ -89,8 +87,7 @@ read_color_image( GLcontext *ctx, GLint x, GLint y,
RENDER_FINISH(swrast,ctx);
/* Read from draw buffer (the default) */
- (*swrast->Driver.SetReadBuffer)( ctx, ctx->DrawBuffer,
- ctx->Color.DriverDrawBuffer );
+ _swrast_use_draw_buffer(ctx);
return image;
}
@@ -146,8 +143,8 @@ is_depth_format(GLenum format)
*/
void
_swrast_copy_teximage1d( GLcontext *ctx, GLenum target, GLint level,
- GLenum internalFormat,
- GLint x, GLint y, GLsizei width, GLint border )
+ GLenum internalFormat,
+ GLint x, GLint y, GLsizei width, GLint border )
{
struct gl_texture_unit *texUnit;
struct gl_texture_object *texObj;
@@ -194,7 +191,7 @@ _swrast_copy_teximage1d( GLcontext *ctx, GLenum target, GLint level,
/* GL_SGIS_generate_mipmap */
if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
- _mesa_generate_mipmap(ctx, texUnit, texObj);
+ _mesa_generate_mipmap(ctx, target, texUnit, texObj);
}
}
@@ -204,9 +201,9 @@ _swrast_copy_teximage1d( GLcontext *ctx, GLenum target, GLint level,
*/
void
_swrast_copy_teximage2d( GLcontext *ctx, GLenum target, GLint level,
- GLenum internalFormat,
- GLint x, GLint y, GLsizei width, GLsizei height,
- GLint border )
+ GLenum internalFormat,
+ GLint x, GLint y, GLsizei width, GLsizei height,
+ GLint border )
{
struct gl_texture_unit *texUnit;
struct gl_texture_object *texObj;
@@ -253,7 +250,7 @@ _swrast_copy_teximage2d( GLcontext *ctx, GLenum target, GLint level,
/* GL_SGIS_generate_mipmap */
if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
- _mesa_generate_mipmap(ctx, texUnit, texObj);
+ _mesa_generate_mipmap(ctx, target, texUnit, texObj);
}
}
@@ -262,8 +259,8 @@ _swrast_copy_teximage2d( GLcontext *ctx, GLenum target, GLint level,
* Fallback for Driver.CopyTexSubImage1D().
*/
void
-_swrast_copy_texsubimage1d(GLcontext *ctx, GLenum target, GLint level,
- GLint xoffset, GLint x, GLint y, GLsizei width)
+_swrast_copy_texsubimage1d( GLcontext *ctx, GLenum target, GLint level,
+ GLint xoffset, GLint x, GLint y, GLsizei width )
{
struct gl_texture_unit *texUnit;
struct gl_texture_object *texObj;
@@ -277,55 +274,38 @@ _swrast_copy_texsubimage1d(GLcontext *ctx, GLenum target, GLint level,
ASSERT(ctx->Driver.TexImage1D);
- if (texImage->Format != GL_DEPTH_COMPONENT) {
- /* read RGBA image from framebuffer */
- GLchan *image = read_color_image(ctx, x, y, width, 1);
+ if (texImage->Format == GL_DEPTH_COMPONENT) {
+ /* read depth image from framebuffer */
+ GLfloat *image = read_depth_image(ctx, x, y, width, 1);
if (!image) {
- _mesa_error( ctx, GL_OUT_OF_MEMORY, "glCopyTexSubImage1D" );
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexSubImage1D");
return;
}
-#if 0
- /*
- * XXX this is a bit of a hack. We need to be sure that the alpha
- * channel is 1.0 if the internal texture format is not supposed to
- * have an alpha channel. This is because some drivers may store
- * RGB textures as RGBA and the texutil.c code isn't smart enough
- * to set the alpha channel to 1.0 in this situation.
- */
- if (texImage->Format == GL_LUMINANCE ||
- texImage->Format == GL_RGB) {
- const GLuint n = width * 4;
- GLuint i;
- for (i = 0; i < n; i += 4) {
- image[i + 3] = CHAN_MAX;
- }
- }
-#endif
- /* now call glTexSubImage1D to do the real work */
+ /* call glTexSubImage1D to redefine the texture */
(*ctx->Driver.TexSubImage1D)(ctx, target, level, xoffset, width,
- GL_RGBA, CHAN_TYPE, image,
+ GL_DEPTH_COMPONENT, GL_FLOAT, image,
&_mesa_native_packing, texObj, texImage);
FREE(image);
}
else {
- /* read depth image from framebuffer */
- GLfloat *image = read_depth_image(ctx, x, y, width, 1);
+ /* read RGBA image from framebuffer */
+ GLchan *image = read_color_image(ctx, x, y, width, 1);
if (!image) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexSubImage1D");
+ _mesa_error( ctx, GL_OUT_OF_MEMORY, "glCopyTexSubImage1D" );
return;
}
- /* call glTexSubImage1D to redefine the texture */
+ /* now call glTexSubImage1D to do the real work */
(*ctx->Driver.TexSubImage1D)(ctx, target, level, xoffset, width,
- GL_DEPTH_COMPONENT, GL_FLOAT, image,
+ GL_RGBA, CHAN_TYPE, image,
&_mesa_native_packing, texObj, texImage);
FREE(image);
}
/* GL_SGIS_generate_mipmap */
if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
- _mesa_generate_mipmap(ctx, texUnit, texObj);
+ _mesa_generate_mipmap(ctx, target, texUnit, texObj);
}
}
@@ -335,9 +315,9 @@ _swrast_copy_texsubimage1d(GLcontext *ctx, GLenum target, GLint level,
*/
void
_swrast_copy_texsubimage2d( GLcontext *ctx,
- GLenum target, GLint level,
- GLint xoffset, GLint yoffset,
- GLint x, GLint y, GLsizei width, GLsizei height )
+ GLenum target, GLint level,
+ GLint xoffset, GLint yoffset,
+ GLint x, GLint y, GLsizei width, GLsizei height )
{
struct gl_texture_unit *texUnit;
struct gl_texture_object *texObj;
@@ -351,57 +331,40 @@ _swrast_copy_texsubimage2d( GLcontext *ctx,
ASSERT(ctx->Driver.TexImage2D);
- if (texImage->Format != GL_DEPTH_COMPONENT) {
- /* read RGBA image from framebuffer */
- GLchan *image = read_color_image(ctx, x, y, width, height);
+ if (texImage->Format == GL_DEPTH_COMPONENT) {
+ /* read depth image from framebuffer */
+ GLfloat *image = read_depth_image(ctx, x, y, width, height);
if (!image) {
- _mesa_error( ctx, GL_OUT_OF_MEMORY, "glCopyTexSubImage2D" );
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexSubImage2D");
return;
}
-#if 0
- /*
- * XXX this is a bit of a hack. We need to be sure that the alpha
- * channel is 1.0 if the internal texture format is not supposed to
- * have an alpha channel. This is because some drivers may store
- * RGB textures as RGBA and the texutil.c code isn't smart enough
- * to set the alpha channel to 1.0 in this situation.
- */
- if (texImage->Format == GL_LUMINANCE ||
- texImage->Format == GL_RGB) {
- const GLuint n = width * height * 4;
- GLuint i;
- for (i = 0; i < n; i += 4) {
- image[i + 3] = CHAN_MAX;
- }
- }
-#endif
- /* now call glTexSubImage2D to do the real work */
+ /* call glTexImage1D to redefine the texture */
(*ctx->Driver.TexSubImage2D)(ctx, target, level,
xoffset, yoffset, width, height,
- GL_RGBA, CHAN_TYPE, image,
+ GL_DEPTH_COMPONENT, GL_FLOAT, image,
&_mesa_native_packing, texObj, texImage);
FREE(image);
}
else {
- /* read depth image from framebuffer */
- GLfloat *image = read_depth_image(ctx, x, y, width, height);
+ /* read RGBA image from framebuffer */
+ GLchan *image = read_color_image(ctx, x, y, width, height);
if (!image) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexSubImage2D");
+ _mesa_error( ctx, GL_OUT_OF_MEMORY, "glCopyTexSubImage2D" );
return;
}
- /* call glTexImage1D to redefine the texture */
+ /* now call glTexSubImage2D to do the real work */
(*ctx->Driver.TexSubImage2D)(ctx, target, level,
xoffset, yoffset, width, height,
- GL_DEPTH_COMPONENT, GL_FLOAT, image,
+ GL_RGBA, CHAN_TYPE, image,
&_mesa_native_packing, texObj, texImage);
FREE(image);
}
/* GL_SGIS_generate_mipmap */
if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
- _mesa_generate_mipmap(ctx, texUnit, texObj);
+ _mesa_generate_mipmap(ctx, target, texUnit, texObj);
}
}
@@ -411,9 +374,9 @@ _swrast_copy_texsubimage2d( GLcontext *ctx,
*/
void
_swrast_copy_texsubimage3d( GLcontext *ctx,
- GLenum target, GLint level,
- GLint xoffset, GLint yoffset, GLint zoffset,
- GLint x, GLint y, GLsizei width, GLsizei height )
+ GLenum target, GLint level,
+ GLint xoffset, GLint yoffset, GLint zoffset,
+ GLint x, GLint y, GLsizei width, GLsizei height )
{
struct gl_texture_unit *texUnit;
struct gl_texture_object *texObj;
@@ -427,55 +390,39 @@ _swrast_copy_texsubimage3d( GLcontext *ctx,
ASSERT(ctx->Driver.TexImage3D);
- if (texImage->Format != GL_DEPTH_COMPONENT) {
- /* read RGBA image from framebuffer */
- GLchan *image = read_color_image(ctx, x, y, width, height);
+ if (texImage->Format == GL_DEPTH_COMPONENT) {
+ /* read depth image from framebuffer */
+ GLfloat *image = read_depth_image(ctx, x, y, width, height);
if (!image) {
- _mesa_error( ctx, GL_OUT_OF_MEMORY, "glCopyTexSubImage3D" );
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexSubImage3D");
return;
}
-#if 0
- /*
- * XXX this is a bit of a hack. We need to be sure that the alpha
- * channel is 1.0 if the internal texture format is not supposed to
- * have an alpha channel. This is because some drivers may store
- * RGB textures as RGBA and the texutil.c code isn't smart enough
- * to set the alpha channel to 1.0 in this situation.
- */
- if (texImage->Format == GL_LUMINANCE ||
- texImage->Format == GL_RGB) {
- const GLuint n = width * height * 4;
- GLuint i;
- for (i = 0; i < n; i += 4) {
- image[i + 3] = CHAN_MAX;
- }
- }
-#endif
- /* now call glTexSubImage3D to do the real work */
+
+ /* call glTexImage1D to redefine the texture */
(*ctx->Driver.TexSubImage3D)(ctx, target, level,
xoffset, yoffset, zoffset, width, height, 1,
- GL_RGBA, CHAN_TYPE, image,
+ GL_DEPTH_COMPONENT, GL_FLOAT, image,
&_mesa_native_packing, texObj, texImage);
FREE(image);
}
else {
- /* read depth image from framebuffer */
- GLfloat *image = read_depth_image(ctx, x, y, width, height);
+ /* read RGBA image from framebuffer */
+ GLchan *image = read_color_image(ctx, x, y, width, height);
if (!image) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexSubImage3D");
+ _mesa_error( ctx, GL_OUT_OF_MEMORY, "glCopyTexSubImage3D" );
return;
}
- /* call glTexImage1D to redefine the texture */
+ /* now call glTexSubImage3D to do the real work */
(*ctx->Driver.TexSubImage3D)(ctx, target, level,
xoffset, yoffset, zoffset, width, height, 1,
- GL_DEPTH_COMPONENT, GL_FLOAT, image,
+ GL_RGBA, CHAN_TYPE, image,
&_mesa_native_packing, texObj, texImage);
FREE(image);
}
/* GL_SGIS_generate_mipmap */
if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
- _mesa_generate_mipmap(ctx, texUnit, texObj);
+ _mesa_generate_mipmap(ctx, target, texUnit, texObj);
}
}
diff --git a/xc/extras/Mesa/src/swrast/s_texture.c b/xc/extras/Mesa/src/swrast/s_texture.c
index 66672a94f..5286601f8 100644
--- a/xc/extras/Mesa/src/swrast/s_texture.c
+++ b/xc/extras/Mesa/src/swrast/s_texture.c
@@ -1,8 +1,6 @@
-/* $Id: s_texture.c,v 1.1.1.1 2002/10/22 13:06:51 alanh Exp $ */
-
/*
* Mesa 3-D graphics library
- * Version: 4.0.4
+ * Version: 5.0
*
* Copyright (C) 1999-2002 Brian Paul All Rights Reserved.
*
@@ -30,12 +28,11 @@
#include "colormac.h"
#include "macros.h"
#include "mmath.h"
-#include "mem.h"
+#include "imports.h"
#include "texformat.h"
#include "teximage.h"
#include "s_context.h"
-#include "s_pb.h"
#include "s_texture.h"
@@ -50,7 +47,7 @@
/*
* Used to compute texel locations for linear sampling.
* Input:
- * wrapMode = GL_REPEAT, GL_CLAMP, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_BORDER_ARB
+ * wrapMode = GL_REPEAT, GL_CLAMP, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_BORDER
* S = texcoord in [0,1]
* SIZE = width (or height or depth) of texture
* Output:
@@ -79,7 +76,7 @@
if (I1 >= (GLint) SIZE) \
I1 = SIZE - 1; \
} \
- else if (wrapMode == GL_CLAMP_TO_BORDER_ARB) { \
+ else if (wrapMode == GL_CLAMP_TO_BORDER) { \
const GLfloat min = -1.0F / (2.0F * SIZE); \
const GLfloat max = 1.0F - min; \
if (S <= min) \
@@ -92,12 +89,37 @@
I0 = IFLOOR(U); \
I1 = I0 + 1; \
} \
- else if (wrapMode == GL_MIRRORED_REPEAT_ARB) { \
+ else if (wrapMode == GL_MIRRORED_REPEAT) { \
const GLint flr = IFLOOR(S); \
if (flr & 1) \
U = 1.0F - (S - (GLfloat) flr); /* flr is odd */ \
else \
U = S - (GLfloat) flr; /* flr is even */ \
+ U = (U * SIZE) - 0.5F; \
+ I0 = IFLOOR(U); \
+ I1 = I0 + 1; \
+ if (I0 < 0) \
+ I0 = 0; \
+ if (I1 >= (GLint) SIZE) \
+ I1 = SIZE - 1; \
+ } \
+ else if (wrapMode == GL_MIRROR_CLAMP_ATI) { \
+ U = (GLfloat) fabs(S); \
+ if (U >= 1.0F) \
+ U = (GLfloat) SIZE; \
+ else \
+ U *= SIZE; \
+ U -= 0.5F; \
+ I0 = IFLOOR(U); \
+ I1 = I0 + 1; \
+ } \
+ else if (wrapMode == GL_MIRROR_CLAMP_TO_EDGE_ATI) { \
+ U = (GLfloat) fabs(S); \
+ if (U >= 1.0F) \
+ U = (GLfloat) SIZE; \
+ else \
+ U *= SIZE; \
+ U -= 0.5F; \
I0 = IFLOOR(U); \
I1 = I0 + 1; \
if (I0 < 0) \
@@ -143,7 +165,7 @@
else \
I = IFLOOR(S * SIZE); \
} \
- else if (wrapMode == GL_CLAMP_TO_BORDER_ARB) { \
+ else if (wrapMode == GL_CLAMP_TO_BORDER) { \
/* s limited to [min,max] */ \
/* i limited to [-1, size] */ \
const GLfloat min = -1.0F / (2.0F * SIZE); \
@@ -155,7 +177,7 @@
else \
I = IFLOOR(S * SIZE); \
} \
- else if (wrapMode == GL_MIRRORED_REPEAT_ARB) { \
+ else if (wrapMode == GL_MIRRORED_REPEAT) { \
const GLfloat min = 1.0F / (2.0F * SIZE); \
const GLfloat max = 1.0F - min; \
const GLint flr = IFLOOR(S); \
@@ -171,6 +193,30 @@
else \
I = IFLOOR(u * SIZE); \
} \
+ else if (wrapMode == GL_MIRROR_CLAMP_ATI) { \
+ /* s limited to [0,1] */ \
+ /* i limited to [0,size-1] */ \
+ const GLfloat u = (GLfloat) fabs(S); \
+ if (u <= 0.0F) \
+ I = 0; \
+ else if (u >= 1.0F) \
+ I = SIZE - 1; \
+ else \
+ I = IFLOOR(u * SIZE); \
+ } \
+ else if (wrapMode == GL_MIRROR_CLAMP_TO_EDGE_ATI) { \
+ /* s limited to [min,max] */ \
+ /* i limited to [0, size-1] */ \
+ const GLfloat min = 1.0F / (2.0F * SIZE); \
+ const GLfloat max = 1.0F - min; \
+ const GLfloat u = (GLfloat) fabs(S); \
+ if (u < min) \
+ I = 0; \
+ else if (u > max) \
+ I = SIZE - 1; \
+ else \
+ I = IFLOOR(u * SIZE); \
+ } \
else { \
ASSERT(wrapMode == GL_CLAMP); \
/* s limited to [0,1] */ \
@@ -185,16 +231,25 @@
}
+#define COMPUTE_LINEAR_REPEAT_TEXEL_LOCATION(S, U, SIZE, I0, I1) \
+{ \
+ U = S * SIZE - 0.5F; \
+ I0 = IFLOOR(U) & (SIZE - 1); \
+ I1 = (I0 + 1) & (SIZE - 1); \
+}
+
+
/*
* Compute linear mipmap levels for given lambda.
*/
#define COMPUTE_LINEAR_MIPMAP_LEVEL(tObj, lambda, level) \
{ \
if (lambda < 0.0F) \
- lambda = 0.0F; \
+ level = tObj->BaseLevel; \
else if (lambda > tObj->_MaxLambda) \
- lambda = tObj->_MaxLambda; \
- level = (GLint) (tObj->BaseLevel + lambda); \
+ level = (GLint) (tObj->BaseLevel + tObj->_MaxLambda); \
+ else \
+ level = (GLint) (tObj->BaseLevel + lambda); \
}
@@ -203,11 +258,14 @@
*/
#define COMPUTE_NEAREST_MIPMAP_LEVEL(tObj, lambda, level) \
{ \
+ GLfloat l; \
if (lambda <= 0.5F) \
- lambda = 0.0F; \
+ l = 0.0F; \
else if (lambda > tObj->_MaxLambda + 0.4999F) \
- lambda = tObj->_MaxLambda + 0.4999F; \
- level = (GLint) (tObj->BaseLevel + lambda + 0.5F); \
+ l = tObj->_MaxLambda + 0.4999F; \
+ else \
+ l = lambda; \
+ level = (GLint) (tObj->BaseLevel + l + 0.5F); \
if (level > tObj->_MaxLevel) \
level = tObj->_MaxLevel; \
}
@@ -236,7 +294,6 @@
#define K1BIT 32
-
/*
* Get texture palette entry.
*/
@@ -288,6 +345,100 @@ palette_sample(const GLcontext *ctx,
}
+/*
+ * The lambda[] array values are always monotonic. Either the whole span
+ * will be minified, magnified, or split between the two. This function
+ * determines the subranges in [0, n-1] that are to be minified or magnified.
+ */
+static INLINE void
+compute_min_mag_ranges( GLfloat minMagThresh, GLuint n, const GLfloat lambda[],
+ GLuint *minStart, GLuint *minEnd,
+ GLuint *magStart, GLuint *magEnd )
+{
+ ASSERT(lambda != NULL);
+#if 0
+ /* Verify that lambda[] is monotonous.
+ * We can't really use this because the inaccuracy in the LOG2 function
+ * causes this test to fail, yet the resulting texturing is correct.
+ */
+ if (n > 1) {
+ GLuint i;
+ printf("lambda delta = %g\n", lambda[0] - lambda[n-1]);
+ if (lambda[0] >= lambda[n-1]) { /* decreasing */
+ for (i = 0; i < n - 1; i++) {
+ ASSERT((GLint) (lambda[i] * 10) >= (GLint) (lambda[i+1] * 10));
+ }
+ }
+ else { /* increasing */
+ for (i = 0; i < n - 1; i++) {
+ ASSERT((GLint) (lambda[i] * 10) <= (GLint) (lambda[i+1] * 10));
+ }
+ }
+ }
+#endif /* DEBUG */
+
+ /* since lambda is monotonous-array use this check first */
+ if (lambda[0] <= minMagThresh && lambda[n-1] <= minMagThresh) {
+ /* magnification for whole span */
+ *magStart = 0;
+ *magEnd = n;
+ *minStart = *minEnd = 0;
+ }
+ else if (lambda[0] > minMagThresh && lambda[n-1] > minMagThresh) {
+ /* minification for whole span */
+ *minStart = 0;
+ *minEnd = n;
+ *magStart = *magEnd = 0;
+ }
+ else {
+ /* a mix of minification and magnification */
+ GLuint i;
+ if (lambda[0] > minMagThresh) {
+ /* start with minification */
+ for (i = 1; i < n; i++) {
+ if (lambda[i] <= minMagThresh)
+ break;
+ }
+ *minStart = 0;
+ *minEnd = i;
+ *magStart = i;
+ *magEnd = n;
+ }
+ else {
+ /* start with magnification */
+ for (i = 1; i < n; i++) {
+ if (lambda[i] > minMagThresh)
+ break;
+ }
+ *magStart = 0;
+ *magEnd = i;
+ *minStart = i;
+ *minEnd = n;
+ }
+ }
+
+#if 0
+ /* Verify the min/mag Start/End values
+ * We don't use this either (see above)
+ */
+ {
+ GLint i;
+ for (i = 0; i < n; i++) {
+ if (lambda[i] > minMagThresh) {
+ /* minification */
+ ASSERT(i >= *minStart);
+ ASSERT(i < *minEnd);
+ }
+ else {
+ /* magnification */
+ ASSERT(i >= *magStart);
+ ASSERT(i < *magEnd);
+ }
+ }
+ }
+#endif
+}
+
/**********************************************************************/
/* 1-D Texture Sampling Functions */
@@ -300,19 +451,19 @@ static void
sample_1d_nearest(GLcontext *ctx,
const struct gl_texture_object *tObj,
const struct gl_texture_image *img,
- GLfloat s, GLchan rgba[4])
+ const GLfloat texcoord[4], GLchan rgba[4])
{
const GLint width = img->Width2; /* without border, power of two */
GLint i;
- COMPUTE_NEAREST_TEXEL_LOCATION(tObj->WrapS, s, width, i);
+ COMPUTE_NEAREST_TEXEL_LOCATION(tObj->WrapS, texcoord[0], width, i);
/* skip over the border, if any */
i += img->Border;
if (i < 0 || i >= (GLint) img->Width) {
- /* Need this test for GL_CLAMP_TO_BORDER_ARB mode */
- COPY_CHAN4(rgba, tObj->BorderColor);
+ /* Need this test for GL_CLAMP_TO_BORDER mode */
+ COPY_CHAN4(rgba, tObj->_BorderChan);
}
else {
(*img->FetchTexel)(img, i, 0, 0, (GLvoid *) rgba);
@@ -331,14 +482,14 @@ static void
sample_1d_linear(GLcontext *ctx,
const struct gl_texture_object *tObj,
const struct gl_texture_image *img,
- GLfloat s, GLchan rgba[4])
+ const GLfloat texcoord[4], GLchan rgba[4])
{
const GLint width = img->Width2;
GLint i0, i1;
GLfloat u;
GLuint useBorderColor;
- COMPUTE_LINEAR_TEXEL_LOCATIONS(tObj->WrapS, s, u, width, i0, i1);
+ COMPUTE_LINEAR_TEXEL_LOCATIONS(tObj->WrapS, texcoord[0], u, width, i0, i1);
useBorderColor = 0;
if (img->Border) {
@@ -364,7 +515,7 @@ sample_1d_linear(GLcontext *ctx,
GLchan t0[4], t1[4]; /* texels */
if (useBorderColor & I0BIT) {
- COPY_CHAN4(t0, tObj->BorderColor);
+ COPY_CHAN4(t0, tObj->_BorderChan);
}
else {
(*img->FetchTexel)(img, i0, 0, 0, (GLvoid *) t0);
@@ -373,7 +524,7 @@ sample_1d_linear(GLcontext *ctx,
}
}
if (useBorderColor & I1BIT) {
- COPY_CHAN4(t1, tObj->BorderColor);
+ COPY_CHAN4(t1, tObj->_BorderChan);
}
else {
(*img->FetchTexel)(img, i1, 0, 0, (GLvoid *) t1);
@@ -406,24 +557,32 @@ sample_1d_linear(GLcontext *ctx,
static void
sample_1d_nearest_mipmap_nearest(GLcontext *ctx,
const struct gl_texture_object *tObj,
- GLfloat s, GLfloat lambda,
- GLchan rgba[4])
+ GLuint n, GLfloat texcoord[][4],
+ const GLfloat lambda[], GLchan rgba[][4])
{
- GLint level;
- COMPUTE_NEAREST_MIPMAP_LEVEL(tObj, lambda, level);
- sample_1d_nearest(ctx, tObj, tObj->Image[level], s, rgba);
+ GLuint i;
+ ASSERT(lambda != NULL);
+ for (i = 0; i < n; i++) {
+ GLint level;
+ COMPUTE_NEAREST_MIPMAP_LEVEL(tObj, lambda[i], level);
+ sample_1d_nearest(ctx, tObj, tObj->Image[level], texcoord[i], rgba[i]);
+ }
}
static void
sample_1d_linear_mipmap_nearest(GLcontext *ctx,
const struct gl_texture_object *tObj,
- GLfloat s, GLfloat lambda,
- GLchan rgba[4])
+ GLuint n, GLfloat texcoord[][4],
+ const GLfloat lambda[], GLchan rgba[][4])
{
- GLint level;
- COMPUTE_NEAREST_MIPMAP_LEVEL(tObj, lambda, level);
- sample_1d_linear(ctx, tObj, tObj->Image[level], s, rgba);
+ GLuint i;
+ ASSERT(lambda != NULL);
+ for (i = 0; i < n; i++) {
+ GLint level;
+ COMPUTE_NEAREST_MIPMAP_LEVEL(tObj, lambda[i], level);
+ sample_1d_linear(ctx, tObj, tObj->Image[level], texcoord[i], rgba[i]);
+ }
}
@@ -432,34 +591,37 @@ sample_1d_linear_mipmap_nearest(GLcontext *ctx,
* This is really just needed in order to prevent warnings with some compilers.
*/
#if CHAN_TYPE == GL_FLOAT
-#define INTCAST
+#define CHAN_CAST
#else
-#define INTCAST (GLint)
+#define CHAN_CAST (GLchan) (GLint)
#endif
static void
sample_1d_nearest_mipmap_linear(GLcontext *ctx,
const struct gl_texture_object *tObj,
- GLfloat s, GLfloat lambda,
- GLchan rgba[4])
+ GLuint n, GLfloat texcoord[][4],
+ const GLfloat lambda[], GLchan rgba[][4])
{
- GLint level;
-
- COMPUTE_LINEAR_MIPMAP_LEVEL(tObj, lambda, level);
-
- if (level >= tObj->_MaxLevel) {
- sample_1d_nearest(ctx, tObj, tObj->Image[tObj->_MaxLevel], s, rgba);
- }
- else {
- GLchan t0[4], t1[4];
- const GLfloat f = FRAC(lambda);
- sample_1d_nearest(ctx, tObj, tObj->Image[level ], s, t0);
- sample_1d_nearest(ctx, tObj, tObj->Image[level+1], s, t1);
- rgba[RCOMP] = (GLchan) INTCAST ((1.0F-f) * t0[RCOMP] + f * t1[RCOMP]);
- rgba[GCOMP] = (GLchan) INTCAST ((1.0F-f) * t0[GCOMP] + f * t1[GCOMP]);
- rgba[BCOMP] = (GLchan) INTCAST ((1.0F-f) * t0[BCOMP] + f * t1[BCOMP]);
- rgba[ACOMP] = (GLchan) INTCAST ((1.0F-f) * t0[ACOMP] + f * t1[ACOMP]);
+ GLuint i;
+ ASSERT(lambda != NULL);
+ for (i = 0; i < n; i++) {
+ GLint level;
+ COMPUTE_LINEAR_MIPMAP_LEVEL(tObj, lambda[i], level);
+ if (level >= tObj->_MaxLevel) {
+ sample_1d_nearest(ctx, tObj, tObj->Image[tObj->_MaxLevel],
+ texcoord[i], rgba[i]);
+ }
+ else {
+ GLchan t0[4], t1[4];
+ const GLfloat f = FRAC(lambda[i]);
+ sample_1d_nearest(ctx, tObj, tObj->Image[level ], texcoord[i], t0);
+ sample_1d_nearest(ctx, tObj, tObj->Image[level+1], texcoord[i], t1);
+ rgba[i][RCOMP] = CHAN_CAST ((1.0F-f) * t0[RCOMP] + f * t1[RCOMP]);
+ rgba[i][GCOMP] = CHAN_CAST ((1.0F-f) * t0[GCOMP] + f * t1[GCOMP]);
+ rgba[i][BCOMP] = CHAN_CAST ((1.0F-f) * t0[BCOMP] + f * t1[BCOMP]);
+ rgba[i][ACOMP] = CHAN_CAST ((1.0F-f) * t0[ACOMP] + f * t1[ACOMP]);
+ }
}
}
@@ -468,25 +630,28 @@ sample_1d_nearest_mipmap_linear(GLcontext *ctx,
static void
sample_1d_linear_mipmap_linear(GLcontext *ctx,
const struct gl_texture_object *tObj,
- GLfloat s, GLfloat lambda,
- GLchan rgba[4])
+ GLuint n, GLfloat texcoord[][4],
+ const GLfloat lambda[], GLchan rgba[][4])
{
- GLint level;
-
- COMPUTE_LINEAR_MIPMAP_LEVEL(tObj, lambda, level);
-
- if (level >= tObj->_MaxLevel) {
- sample_1d_linear(ctx, tObj, tObj->Image[tObj->_MaxLevel], s, rgba);
- }
- else {
- GLchan t0[4], t1[4];
- const GLfloat f = FRAC(lambda);
- sample_1d_linear(ctx, tObj, tObj->Image[level ], s, t0);
- sample_1d_linear(ctx, tObj, tObj->Image[level+1], s, t1);
- rgba[RCOMP] = (GLchan) INTCAST ((1.0F-f) * t0[RCOMP] + f * t1[RCOMP]);
- rgba[GCOMP] = (GLchan) INTCAST ((1.0F-f) * t0[GCOMP] + f * t1[GCOMP]);
- rgba[BCOMP] = (GLchan) INTCAST ((1.0F-f) * t0[BCOMP] + f * t1[BCOMP]);
- rgba[ACOMP] = (GLchan) INTCAST ((1.0F-f) * t0[ACOMP] + f * t1[ACOMP]);
+ GLuint i;
+ ASSERT(lambda != NULL);
+ for (i = 0; i < n; i++) {
+ GLint level;
+ COMPUTE_LINEAR_MIPMAP_LEVEL(tObj, lambda[i], level);
+ if (level >= tObj->_MaxLevel) {
+ sample_1d_linear(ctx, tObj, tObj->Image[tObj->_MaxLevel],
+ texcoord[i], rgba[i]);
+ }
+ else {
+ GLchan t0[4], t1[4];
+ const GLfloat f = FRAC(lambda[i]);
+ sample_1d_linear(ctx, tObj, tObj->Image[level ], texcoord[i], t0);
+ sample_1d_linear(ctx, tObj, tObj->Image[level+1], texcoord[i], t1);
+ rgba[i][RCOMP] = CHAN_CAST ((1.0F-f) * t0[RCOMP] + f * t1[RCOMP]);
+ rgba[i][GCOMP] = CHAN_CAST ((1.0F-f) * t0[GCOMP] + f * t1[GCOMP]);
+ rgba[i][BCOMP] = CHAN_CAST ((1.0F-f) * t0[BCOMP] + f * t1[BCOMP]);
+ rgba[i][ACOMP] = CHAN_CAST ((1.0F-f) * t0[ACOMP] + f * t1[ACOMP]);
+ }
}
}
@@ -495,17 +660,14 @@ sample_1d_linear_mipmap_linear(GLcontext *ctx,
static void
sample_nearest_1d( GLcontext *ctx, GLuint texUnit,
const struct gl_texture_object *tObj, GLuint n,
- const GLfloat s[], const GLfloat t[],
- const GLfloat u[], const GLfloat lambda[],
+ GLfloat texcoords[][4], const GLfloat lambda[],
GLchan rgba[][4] )
{
GLuint i;
struct gl_texture_image *image = tObj->Image[tObj->BaseLevel];
- (void) t;
- (void) u;
(void) lambda;
for (i=0;i<n;i++) {
- sample_1d_nearest(ctx, tObj, image, s[i], rgba[i]);
+ sample_1d_nearest(ctx, tObj, image, texcoords[i], rgba[i]);
}
}
@@ -514,17 +676,14 @@ sample_nearest_1d( GLcontext *ctx, GLuint texUnit,
static void
sample_linear_1d( GLcontext *ctx, GLuint texUnit,
const struct gl_texture_object *tObj, GLuint n,
- const GLfloat s[], const GLfloat t[],
- const GLfloat u[], const GLfloat lambda[],
+ GLfloat texcoords[][4], const GLfloat lambda[],
GLchan rgba[][4] )
{
GLuint i;
struct gl_texture_image *image = tObj->Image[tObj->BaseLevel];
- (void) t;
- (void) u;
(void) lambda;
for (i=0;i<n;i++) {
- sample_1d_linear(ctx, tObj, image, s[i], rgba[i]);
+ sample_1d_linear(ctx, tObj, image, texcoords[i], rgba[i]);
}
}
@@ -537,71 +696,74 @@ sample_linear_1d( GLcontext *ctx, GLuint texUnit,
static void
sample_lambda_1d( GLcontext *ctx, GLuint texUnit,
const struct gl_texture_object *tObj, GLuint n,
- const GLfloat s[], const GLfloat t[],
- const GLfloat u[], const GLfloat lambda[],
- GLchan rgba[][4] )
+ GLfloat texcoords[][4],
+ const GLfloat lambda[], GLchan rgba[][4] )
{
- GLfloat MinMagThresh = SWRAST_CONTEXT(ctx)->_MinMagThresh[texUnit];
+ GLuint minStart, minEnd; /* texels with minification */
+ GLuint magStart, magEnd; /* texels with magnification */
GLuint i;
- (void) t;
- (void) u;
+ ASSERT(lambda != NULL);
+ compute_min_mag_ranges(SWRAST_CONTEXT(ctx)->_MinMagThresh[texUnit],
+ n, lambda, &minStart, &minEnd, &magStart, &magEnd);
- for (i=0;i<n;i++) {
- if (lambda[i] > MinMagThresh) {
- /* minification */
- switch (tObj->MinFilter) {
- case GL_NEAREST:
- sample_1d_nearest(ctx, tObj, tObj->Image[tObj->BaseLevel],
- s[i], rgba[i]);
- break;
- case GL_LINEAR:
- sample_1d_linear(ctx, tObj, tObj->Image[tObj->BaseLevel],
- s[i], rgba[i]);
- break;
- case GL_NEAREST_MIPMAP_NEAREST:
- sample_1d_nearest_mipmap_nearest(ctx, tObj, lambda[i], s[i],
- rgba[i]);
- break;
- case GL_LINEAR_MIPMAP_NEAREST:
- sample_1d_linear_mipmap_nearest(ctx, tObj, s[i], lambda[i],
- rgba[i]);
- break;
- case GL_NEAREST_MIPMAP_LINEAR:
- sample_1d_nearest_mipmap_linear(ctx, tObj, s[i], lambda[i],
- rgba[i]);
- break;
- case GL_LINEAR_MIPMAP_LINEAR:
- sample_1d_linear_mipmap_linear(ctx, tObj, s[i], lambda[i],
- rgba[i]);
- break;
- default:
- _mesa_problem(NULL, "Bad min filter in sample_1d_texture");
- return;
- }
+ if (minStart < minEnd) {
+ /* do the minified texels */
+ const GLuint m = minEnd - minStart;
+ switch (tObj->MinFilter) {
+ case GL_NEAREST:
+ for (i = minStart; i < minEnd; i++)
+ sample_1d_nearest(ctx, tObj, tObj->Image[tObj->BaseLevel],
+ texcoords[i], rgba[i]);
+ break;
+ case GL_LINEAR:
+ for (i = minStart; i < minEnd; i++)
+ sample_1d_linear(ctx, tObj, tObj->Image[tObj->BaseLevel],
+ texcoords[i], rgba[i]);
+ break;
+ case GL_NEAREST_MIPMAP_NEAREST:
+ sample_1d_nearest_mipmap_nearest(ctx, tObj, m, texcoords + minStart,
+ lambda + minStart, rgba + minStart);
+ break;
+ case GL_LINEAR_MIPMAP_NEAREST:
+ sample_1d_linear_mipmap_nearest(ctx, tObj, m, texcoords + minStart,
+ lambda + minStart, rgba + minStart);
+ break;
+ case GL_NEAREST_MIPMAP_LINEAR:
+ sample_1d_nearest_mipmap_linear(ctx, tObj, m, texcoords + minStart,
+ lambda + minStart, rgba + minStart);
+ break;
+ case GL_LINEAR_MIPMAP_LINEAR:
+ sample_1d_linear_mipmap_linear(ctx, tObj, m, texcoords + minStart,
+ lambda + minStart, rgba + minStart);
+ break;
+ default:
+ _mesa_problem(ctx, "Bad min filter in sample_1d_texture");
+ return;
}
- else {
- /* magnification */
- switch (tObj->MagFilter) {
- case GL_NEAREST:
- sample_1d_nearest(ctx, tObj, tObj->Image[tObj->BaseLevel],
- s[i], rgba[i]);
- break;
- case GL_LINEAR:
- sample_1d_linear(ctx, tObj, tObj->Image[tObj->BaseLevel],
- s[i], rgba[i]);
- break;
- default:
- _mesa_problem(NULL, "Bad mag filter in sample_1d_texture");
- return;
- }
+ }
+
+ if (magStart < magEnd) {
+ /* do the magnified texels */
+ switch (tObj->MagFilter) {
+ case GL_NEAREST:
+ for (i = magStart; i < magEnd; i++)
+ sample_1d_nearest(ctx, tObj, tObj->Image[tObj->BaseLevel],
+ texcoords[i], rgba[i]);
+ break;
+ case GL_LINEAR:
+ for (i = magStart; i < magEnd; i++)
+ sample_1d_linear(ctx, tObj, tObj->Image[tObj->BaseLevel],
+ texcoords[i], rgba[i]);
+ break;
+ default:
+ _mesa_problem(ctx, "Bad mag filter in sample_1d_texture");
+ return;
}
}
}
-
-
/**********************************************************************/
/* 2-D Texture Sampling Functions */
/**********************************************************************/
@@ -610,27 +772,27 @@ sample_lambda_1d( GLcontext *ctx, GLuint texUnit,
/*
* Return the texture sample for coordinate (s,t) using GL_NEAREST filter.
*/
-static void
+static INLINE void
sample_2d_nearest(GLcontext *ctx,
const struct gl_texture_object *tObj,
const struct gl_texture_image *img,
- GLfloat s, GLfloat t,
+ const GLfloat texcoord[4],
GLchan rgba[])
{
const GLint width = img->Width2; /* without border, power of two */
const GLint height = img->Height2; /* without border, power of two */
GLint i, j;
- COMPUTE_NEAREST_TEXEL_LOCATION(tObj->WrapS, s, width, i);
- COMPUTE_NEAREST_TEXEL_LOCATION(tObj->WrapT, t, height, j);
+ COMPUTE_NEAREST_TEXEL_LOCATION(tObj->WrapS, texcoord[0], width, i);
+ COMPUTE_NEAREST_TEXEL_LOCATION(tObj->WrapT, texcoord[1], height, j);
/* skip over the border, if any */
i += img->Border;
j += img->Border;
if (i < 0 || i >= (GLint) img->Width || j < 0 || j >= (GLint) img->Height) {
- /* Need this test for GL_CLAMP_TO_BORDER_ARB mode */
- COPY_CHAN4(rgba, tObj->BorderColor);
+ /* Need this test for GL_CLAMP_TO_BORDER mode */
+ COPY_CHAN4(rgba, tObj->_BorderChan);
}
else {
(*img->FetchTexel)(img, i, j, 0, (GLvoid *) rgba);
@@ -646,11 +808,11 @@ sample_2d_nearest(GLcontext *ctx,
* Return the texture sample for coordinate (s,t) using GL_LINEAR filter.
* New sampling code contributed by Lynn Quam <quam@ai.sri.com>.
*/
-static void
+static INLINE void
sample_2d_linear(GLcontext *ctx,
const struct gl_texture_object *tObj,
const struct gl_texture_image *img,
- GLfloat s, GLfloat t,
+ const GLfloat texcoord[4],
GLchan rgba[])
{
const GLint width = img->Width2;
@@ -659,8 +821,8 @@ sample_2d_linear(GLcontext *ctx,
GLuint useBorderColor;
GLfloat u, v;
- COMPUTE_LINEAR_TEXEL_LOCATIONS(tObj->WrapS, s, u, width, i0, i1);
- COMPUTE_LINEAR_TEXEL_LOCATIONS(tObj->WrapT, t, v, height, j0, j1);
+ COMPUTE_LINEAR_TEXEL_LOCATIONS(tObj->WrapS, texcoord[0], u, width, i0, i1);
+ COMPUTE_LINEAR_TEXEL_LOCATIONS(tObj->WrapT, texcoord[1], v, height, j0, j1);
useBorderColor = 0;
if (img->Border) {
@@ -698,7 +860,7 @@ sample_2d_linear(GLcontext *ctx,
GLchan t11[4];
if (useBorderColor & (I0BIT | J0BIT)) {
- COPY_CHAN4(t00, tObj->BorderColor);
+ COPY_CHAN4(t00, tObj->_BorderChan);
}
else {
(*img->FetchTexel)(img, i0, j0, 0, (GLvoid *) t00);
@@ -707,7 +869,7 @@ sample_2d_linear(GLcontext *ctx,
}
}
if (useBorderColor & (I1BIT | J0BIT)) {
- COPY_CHAN4(t10, tObj->BorderColor);
+ COPY_CHAN4(t10, tObj->_BorderChan);
}
else {
(*img->FetchTexel)(img, i1, j0, 0, (GLvoid *) t10);
@@ -716,7 +878,7 @@ sample_2d_linear(GLcontext *ctx,
}
}
if (useBorderColor & (I0BIT | J1BIT)) {
- COPY_CHAN4(t01, tObj->BorderColor);
+ COPY_CHAN4(t01, tObj->_BorderChan);
}
else {
(*img->FetchTexel)(img, i0, j1, 0, (GLvoid *) t01);
@@ -725,7 +887,7 @@ sample_2d_linear(GLcontext *ctx,
}
}
if (useBorderColor & (I1BIT | J1BIT)) {
- COPY_CHAN4(t11, tObj->BorderColor);
+ COPY_CHAN4(t11, tObj->_BorderChan);
}
else {
(*img->FetchTexel)(img, i1, j1, 0, (GLvoid *) t11);
@@ -763,16 +925,99 @@ sample_2d_linear(GLcontext *ctx,
}
+/*
+ * As above, but we know WRAP_S == REPEAT and WRAP_T == REPEAT
+ * and we're not using a paletted texture.
+ */
+static INLINE void
+sample_2d_linear_repeat(GLcontext *ctx,
+ const struct gl_texture_object *tObj,
+ const struct gl_texture_image *img,
+ const GLfloat texcoord[4],
+ GLchan rgba[])
+{
+ const GLint width = img->Width2;
+ const GLint height = img->Height2;
+ GLint i0, j0, i1, j1;
+ GLfloat u, v;
+
+ ASSERT(tObj->WrapS == GL_REPEAT);
+ ASSERT(tObj->WrapT == GL_REPEAT);
+ ASSERT(img->Border == 0);
+ ASSERT(img->Format != GL_COLOR_INDEX);
+
+ COMPUTE_LINEAR_REPEAT_TEXEL_LOCATION(texcoord[0], u, width, i0, i1);
+ COMPUTE_LINEAR_REPEAT_TEXEL_LOCATION(texcoord[1], v, height, j0, j1);
+
+ {
+ const GLfloat a = FRAC(u);
+ const GLfloat b = FRAC(v);
+
+#if CHAN_TYPE == GL_FLOAT || CHAN_TYPE == GL_UNSIGNED_SHORT
+ const GLfloat w00 = (1.0F-a) * (1.0F-b);
+ const GLfloat w10 = a * (1.0F-b);
+ const GLfloat w01 = (1.0F-a) * b ;
+ const GLfloat w11 = a * b ;
+#else /* CHAN_BITS == 8 */
+ /* compute sample weights in fixed point in [0,WEIGHT_SCALE] */
+ const GLint w00 = IROUND_POS((1.0F-a) * (1.0F-b) * WEIGHT_SCALE);
+ const GLint w10 = IROUND_POS( a * (1.0F-b) * WEIGHT_SCALE);
+ const GLint w01 = IROUND_POS((1.0F-a) * b * WEIGHT_SCALE);
+ const GLint w11 = IROUND_POS( a * b * WEIGHT_SCALE);
+#endif
+ GLchan t00[4];
+ GLchan t10[4];
+ GLchan t01[4];
+ GLchan t11[4];
+
+ (*img->FetchTexel)(img, i0, j0, 0, (GLvoid *) t00);
+ (*img->FetchTexel)(img, i1, j0, 0, (GLvoid *) t10);
+ (*img->FetchTexel)(img, i0, j1, 0, (GLvoid *) t01);
+ (*img->FetchTexel)(img, i1, j1, 0, (GLvoid *) t11);
+
+#if CHAN_TYPE == GL_FLOAT
+ rgba[0] = w00 * t00[0] + w10 * t10[0] + w01 * t01[0] + w11 * t11[0];
+ rgba[1] = w00 * t00[1] + w10 * t10[1] + w01 * t01[1] + w11 * t11[1];
+ rgba[2] = w00 * t00[2] + w10 * t10[2] + w01 * t01[2] + w11 * t11[2];
+ rgba[3] = w00 * t00[3] + w10 * t10[3] + w01 * t01[3] + w11 * t11[3];
+#elif CHAN_TYPE == GL_UNSIGNED_SHORT
+ rgba[0] = (GLchan) (w00 * t00[0] + w10 * t10[0] +
+ w01 * t01[0] + w11 * t11[0] + 0.5);
+ rgba[1] = (GLchan) (w00 * t00[1] + w10 * t10[1] +
+ w01 * t01[1] + w11 * t11[1] + 0.5);
+ rgba[2] = (GLchan) (w00 * t00[2] + w10 * t10[2] +
+ w01 * t01[2] + w11 * t11[2] + 0.5);
+ rgba[3] = (GLchan) (w00 * t00[3] + w10 * t10[3] +
+ w01 * t01[3] + w11 * t11[3] + 0.5);
+#else /* CHAN_BITS == 8 */
+ rgba[0] = (GLchan) ((w00 * t00[0] + w10 * t10[0] +
+ w01 * t01[0] + w11 * t11[0]) >> WEIGHT_SHIFT);
+ rgba[1] = (GLchan) ((w00 * t00[1] + w10 * t10[1] +
+ w01 * t01[1] + w11 * t11[1]) >> WEIGHT_SHIFT);
+ rgba[2] = (GLchan) ((w00 * t00[2] + w10 * t10[2] +
+ w01 * t01[2] + w11 * t11[2]) >> WEIGHT_SHIFT);
+ rgba[3] = (GLchan) ((w00 * t00[3] + w10 * t10[3] +
+ w01 * t01[3] + w11 * t11[3]) >> WEIGHT_SHIFT);
+#endif
+
+ }
+
+}
+
+
static void
sample_2d_nearest_mipmap_nearest(GLcontext *ctx,
const struct gl_texture_object *tObj,
- GLfloat s, GLfloat t, GLfloat lambda,
- GLchan rgba[4])
+ GLuint n, GLfloat texcoord[][4],
+ const GLfloat lambda[], GLchan rgba[][4])
{
- GLint level;
- COMPUTE_NEAREST_MIPMAP_LEVEL(tObj, lambda, level);
- sample_2d_nearest(ctx, tObj, tObj->Image[level], s, t, rgba);
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ GLint level;
+ COMPUTE_NEAREST_MIPMAP_LEVEL(tObj, lambda[i], level);
+ sample_2d_nearest(ctx, tObj, tObj->Image[level], texcoord[i], rgba[i]);
+ }
}
@@ -780,12 +1025,16 @@ sample_2d_nearest_mipmap_nearest(GLcontext *ctx,
static void
sample_2d_linear_mipmap_nearest(GLcontext *ctx,
const struct gl_texture_object *tObj,
- GLfloat s, GLfloat t, GLfloat lambda,
- GLchan rgba[4])
+ GLuint n, GLfloat texcoord[][4],
+ const GLfloat lambda[], GLchan rgba[][4])
{
- GLint level;
- COMPUTE_NEAREST_MIPMAP_LEVEL(tObj, lambda, level);
- sample_2d_linear(ctx, tObj, tObj->Image[level], s, t, rgba);
+ GLuint i;
+ ASSERT(lambda != NULL);
+ for (i = 0; i < n; i++) {
+ GLint level;
+ COMPUTE_NEAREST_MIPMAP_LEVEL(tObj, lambda[i], level);
+ sample_2d_linear(ctx, tObj, tObj->Image[level], texcoord[i], rgba[i]);
+ }
}
@@ -793,70 +1042,105 @@ sample_2d_linear_mipmap_nearest(GLcontext *ctx,
static void
sample_2d_nearest_mipmap_linear(GLcontext *ctx,
const struct gl_texture_object *tObj,
- GLfloat s, GLfloat t, GLfloat lambda,
- GLchan rgba[4])
+ GLuint n, GLfloat texcoord[][4],
+ const GLfloat lambda[], GLchan rgba[][4])
{
- GLint level;
-
- COMPUTE_LINEAR_MIPMAP_LEVEL(tObj, lambda, level);
-
- if (level >= tObj->_MaxLevel) {
- sample_2d_nearest(ctx, tObj, tObj->Image[tObj->_MaxLevel], s, t, rgba);
- }
- else {
- GLchan t0[4], t1[4]; /* texels */
- const GLfloat f = FRAC(lambda);
- sample_2d_nearest(ctx, tObj, tObj->Image[level ], s, t, t0);
- sample_2d_nearest(ctx, tObj, tObj->Image[level+1], s, t, t1);
- rgba[RCOMP] = (GLchan) INTCAST ((1.0F-f) * t0[RCOMP] + f * t1[RCOMP]);
- rgba[GCOMP] = (GLchan) INTCAST ((1.0F-f) * t0[GCOMP] + f * t1[GCOMP]);
- rgba[BCOMP] = (GLchan) INTCAST ((1.0F-f) * t0[BCOMP] + f * t1[BCOMP]);
- rgba[ACOMP] = (GLchan) INTCAST ((1.0F-f) * t0[ACOMP] + f * t1[ACOMP]);
+ GLuint i;
+ ASSERT(lambda != NULL);
+ for (i = 0; i < n; i++) {
+ GLint level;
+ COMPUTE_LINEAR_MIPMAP_LEVEL(tObj, lambda[i], level);
+ if (level >= tObj->_MaxLevel) {
+ sample_2d_nearest(ctx, tObj, tObj->Image[tObj->_MaxLevel],
+ texcoord[i], rgba[i]);
+ }
+ else {
+ GLchan t0[4], t1[4]; /* texels */
+ const GLfloat f = FRAC(lambda[i]);
+ sample_2d_nearest(ctx, tObj, tObj->Image[level ], texcoord[i], t0);
+ sample_2d_nearest(ctx, tObj, tObj->Image[level+1], texcoord[i], t1);
+ rgba[i][RCOMP] = CHAN_CAST ((1.0F-f) * t0[RCOMP] + f * t1[RCOMP]);
+ rgba[i][GCOMP] = CHAN_CAST ((1.0F-f) * t0[GCOMP] + f * t1[GCOMP]);
+ rgba[i][BCOMP] = CHAN_CAST ((1.0F-f) * t0[BCOMP] + f * t1[BCOMP]);
+ rgba[i][ACOMP] = CHAN_CAST ((1.0F-f) * t0[ACOMP] + f * t1[ACOMP]);
+ }
}
}
+/* Trilinear filtering */
static void
-sample_2d_linear_mipmap_linear(GLcontext *ctx,
- const struct gl_texture_object *tObj,
- GLfloat s, GLfloat t, GLfloat lambda,
- GLchan rgba[4])
+sample_2d_linear_mipmap_linear( GLcontext *ctx,
+ const struct gl_texture_object *tObj,
+ GLuint n, GLfloat texcoord[][4],
+ const GLfloat lambda[], GLchan rgba[][4] )
{
- GLint level;
+ GLuint i;
+ ASSERT(lambda != NULL);
+ for (i = 0; i < n; i++) {
+ GLint level;
+ COMPUTE_LINEAR_MIPMAP_LEVEL(tObj, lambda[i], level);
+ if (level >= tObj->_MaxLevel) {
+ sample_2d_linear(ctx, tObj, tObj->Image[tObj->_MaxLevel],
+ texcoord[i], rgba[i]);
+ }
+ else {
+ GLchan t0[4], t1[4]; /* texels */
+ const GLfloat f = FRAC(lambda[i]);
+ sample_2d_linear(ctx, tObj, tObj->Image[level ], texcoord[i], t0);
+ sample_2d_linear(ctx, tObj, tObj->Image[level+1], texcoord[i], t1);
+ rgba[i][RCOMP] = CHAN_CAST ((1.0F-f) * t0[RCOMP] + f * t1[RCOMP]);
+ rgba[i][GCOMP] = CHAN_CAST ((1.0F-f) * t0[GCOMP] + f * t1[GCOMP]);
+ rgba[i][BCOMP] = CHAN_CAST ((1.0F-f) * t0[BCOMP] + f * t1[BCOMP]);
+ rgba[i][ACOMP] = CHAN_CAST ((1.0F-f) * t0[ACOMP] + f * t1[ACOMP]);
+ }
+ }
+}
- COMPUTE_LINEAR_MIPMAP_LEVEL(tObj, lambda, level);
- if (level >= tObj->_MaxLevel) {
- sample_2d_linear(ctx, tObj, tObj->Image[tObj->_MaxLevel], s, t, rgba);
- }
- else {
- GLchan t0[4], t1[4]; /* texels */
- const GLfloat f = FRAC(lambda);
- sample_2d_linear(ctx, tObj, tObj->Image[level ], s, t, t0);
- sample_2d_linear(ctx, tObj, tObj->Image[level+1], s, t, t1);
- rgba[RCOMP] = (GLchan) INTCAST ((1.0F-f) * t0[RCOMP] + f * t1[RCOMP]);
- rgba[GCOMP] = (GLchan) INTCAST ((1.0F-f) * t0[GCOMP] + f * t1[GCOMP]);
- rgba[BCOMP] = (GLchan) INTCAST ((1.0F-f) * t0[BCOMP] + f * t1[BCOMP]);
- rgba[ACOMP] = (GLchan) INTCAST ((1.0F-f) * t0[ACOMP] + f * t1[ACOMP]);
+static void
+sample_2d_linear_mipmap_linear_repeat( GLcontext *ctx,
+ const struct gl_texture_object *tObj,
+ GLuint n, GLfloat texcoord[][4],
+ const GLfloat lambda[], GLchan rgba[][4] )
+{
+ GLuint i;
+ ASSERT(lambda != NULL);
+ ASSERT(tObj->WrapS == GL_REPEAT);
+ ASSERT(tObj->WrapT == GL_REPEAT);
+ for (i = 0; i < n; i++) {
+ GLint level;
+ COMPUTE_LINEAR_MIPMAP_LEVEL(tObj, lambda[i], level);
+ if (level >= tObj->_MaxLevel) {
+ sample_2d_linear_repeat(ctx, tObj, tObj->Image[tObj->_MaxLevel],
+ texcoord[i], rgba[i]);
+ }
+ else {
+ GLchan t0[4], t1[4]; /* texels */
+ const GLfloat f = FRAC(lambda[i]);
+ sample_2d_linear_repeat(ctx, tObj, tObj->Image[level ], texcoord[i], t0);
+ sample_2d_linear_repeat(ctx, tObj, tObj->Image[level+1], texcoord[i], t1);
+ rgba[i][RCOMP] = CHAN_CAST ((1.0F-f) * t0[RCOMP] + f * t1[RCOMP]);
+ rgba[i][GCOMP] = CHAN_CAST ((1.0F-f) * t0[GCOMP] + f * t1[GCOMP]);
+ rgba[i][BCOMP] = CHAN_CAST ((1.0F-f) * t0[BCOMP] + f * t1[BCOMP]);
+ rgba[i][ACOMP] = CHAN_CAST ((1.0F-f) * t0[ACOMP] + f * t1[ACOMP]);
+ }
}
}
-
static void
sample_nearest_2d( GLcontext *ctx, GLuint texUnit,
const struct gl_texture_object *tObj, GLuint n,
- const GLfloat s[], const GLfloat t[],
- const GLfloat u[], const GLfloat lambda[],
- GLchan rgba[][4] )
+ GLfloat texcoords[][4],
+ const GLfloat lambda[], GLchan rgba[][4] )
{
GLuint i;
struct gl_texture_image *image = tObj->Image[tObj->BaseLevel];
- (void) u;
(void) lambda;
for (i=0;i<n;i++) {
- sample_2d_nearest(ctx, tObj, image, s[i], t[i], rgba[i]);
+ sample_2d_nearest(ctx, tObj, image, texcoords[i], rgba[i]);
}
}
@@ -865,16 +1149,14 @@ sample_nearest_2d( GLcontext *ctx, GLuint texUnit,
static void
sample_linear_2d( GLcontext *ctx, GLuint texUnit,
const struct gl_texture_object *tObj, GLuint n,
- const GLfloat s[], const GLfloat t[],
- const GLfloat u[], const GLfloat lambda[],
- GLchan rgba[][4] )
+ GLfloat texcoords[][4],
+ const GLfloat lambda[], GLchan rgba[][4] )
{
GLuint i;
struct gl_texture_image *image = tObj->Image[tObj->BaseLevel];
- (void) u;
(void) lambda;
for (i=0;i<n;i++) {
- sample_2d_linear(ctx, tObj, image, s[i], t[i], rgba[i]);
+ sample_2d_linear(ctx, tObj, image, texcoords[i], rgba[i]);
}
}
@@ -883,15 +1165,15 @@ sample_linear_2d( GLcontext *ctx, GLuint texUnit,
* Optimized 2-D texture sampling:
* S and T wrap mode == GL_REPEAT
* GL_NEAREST min/mag filter
- * No border
+ * No border,
+ * RowStride == Width,
* Format = GL_RGB
*/
static void
opt_sample_rgb_2d( GLcontext *ctx, GLuint texUnit,
const struct gl_texture_object *tObj,
- GLuint n, const GLfloat s[], const GLfloat t[],
- const GLfloat u[], const GLfloat lambda[],
- GLchan rgba[][4] )
+ GLuint n, GLfloat texcoords[][4],
+ const GLfloat lambda[], GLchan rgba[][4] )
{
const struct gl_texture_image *img = tObj->Image[tObj->BaseLevel];
const GLfloat width = (GLfloat) img->Width;
@@ -900,7 +1182,6 @@ opt_sample_rgb_2d( GLcontext *ctx, GLuint texUnit,
const GLint rowMask = img->Height - 1;
const GLint shift = img->WidthLog2;
GLuint k;
- (void) u;
(void) lambda;
ASSERT(tObj->WrapS==GL_REPEAT);
ASSERT(tObj->WrapT==GL_REPEAT);
@@ -908,8 +1189,8 @@ opt_sample_rgb_2d( GLcontext *ctx, GLuint texUnit,
ASSERT(img->Format==GL_RGB);
for (k=0; k<n; k++) {
- GLint i = IFLOOR(s[k] * width) & colMask;
- GLint j = IFLOOR(t[k] * height) & rowMask;
+ GLint i = IFLOOR(texcoords[k][0] * width) & colMask;
+ GLint j = IFLOOR(texcoords[k][1] * height) & rowMask;
GLint pos = (j << shift) | i;
GLchan *texel = ((GLchan *) img->Data) + 3*pos;
rgba[k][RCOMP] = texel[0];
@@ -924,14 +1205,14 @@ opt_sample_rgb_2d( GLcontext *ctx, GLuint texUnit,
* S and T wrap mode == GL_REPEAT
* GL_NEAREST min/mag filter
* No border
+ * RowStride == Width,
* Format = GL_RGBA
*/
static void
opt_sample_rgba_2d( GLcontext *ctx, GLuint texUnit,
const struct gl_texture_object *tObj,
- GLuint n, const GLfloat s[], const GLfloat t[],
- const GLfloat u[], const GLfloat lambda[],
- GLchan rgba[][4] )
+ GLuint n, GLfloat texcoords[][4],
+ const GLfloat lambda[], GLchan rgba[][4] )
{
const struct gl_texture_image *img = tObj->Image[tObj->BaseLevel];
const GLfloat width = (GLfloat) img->Width;
@@ -940,7 +1221,6 @@ opt_sample_rgba_2d( GLcontext *ctx, GLuint texUnit,
const GLint rowMask = img->Height - 1;
const GLint shift = img->WidthLog2;
GLuint i;
- (void) u;
(void) lambda;
ASSERT(tObj->WrapS==GL_REPEAT);
ASSERT(tObj->WrapT==GL_REPEAT);
@@ -948,8 +1228,8 @@ opt_sample_rgba_2d( GLcontext *ctx, GLuint texUnit,
ASSERT(img->Format==GL_RGBA);
for (i = 0; i < n; i++) {
- const GLint col = IFLOOR(s[i] * width) & colMask;
- const GLint row = IFLOOR(t[i] * height) & rowMask;
+ const GLint col = IFLOOR(texcoords[i][0] * width) & colMask;
+ const GLint row = IFLOOR(texcoords[i][1] * height) & rowMask;
const GLint pos = (row << shift) | col;
const GLchan *texel = ((GLchan *) img->Data) + (pos << 2); /* pos*4 */
COPY_CHAN4(rgba[i], texel);
@@ -958,105 +1238,115 @@ opt_sample_rgba_2d( GLcontext *ctx, GLuint texUnit,
/*
- * Given an array of (s,t) texture coordinate and lambda (level of detail)
+ * Given an array of texture coordinate and lambda (level of detail)
* values, return an array of texture sample.
*/
static void
sample_lambda_2d( GLcontext *ctx, GLuint texUnit,
const struct gl_texture_object *tObj,
- GLuint n,
- const GLfloat s[], const GLfloat t[],
- const GLfloat u[], const GLfloat lambda[],
- GLchan rgba[][4] )
+ GLuint n, GLfloat texcoords[][4],
+ const GLfloat lambda[], GLchan rgba[][4] )
{
- const GLfloat minMagThresh = SWRAST_CONTEXT(ctx)->_MinMagThresh[texUnit];
- GLuint i;
- (void) u;
-
- /* since lambda is monotonous-array use this check first */
- if (lambda[0] <= minMagThresh && lambda[n-1] <= minMagThresh) {
- /* magnification for whole span */
- const struct gl_texture_image *img = tObj->Image[tObj->BaseLevel];
- switch (tObj->MagFilter) {
+ const struct gl_texture_image *tImg = tObj->Image[tObj->BaseLevel];
+ GLuint minStart, minEnd; /* texels with minification */
+ GLuint magStart, magEnd; /* texels with magnification */
+
+ const GLboolean repeatNoBorder = (tObj->WrapS == GL_REPEAT)
+ && (tObj->WrapT == GL_REPEAT)
+ && (tImg->Border == 0 && (tImg->Width == tImg->RowStride))
+ && (tImg->Format != GL_COLOR_INDEX);
+
+ ASSERT(lambda != NULL);
+ compute_min_mag_ranges(SWRAST_CONTEXT(ctx)->_MinMagThresh[texUnit],
+ n, lambda, &minStart, &minEnd, &magStart, &magEnd);
+
+ if (minStart < minEnd) {
+ /* do the minified texels */
+ const GLuint m = minEnd - minStart;
+ switch (tObj->MinFilter) {
case GL_NEAREST:
- if (tObj->WrapS == GL_REPEAT && tObj->WrapT == GL_REPEAT &&
- img->Border == 0) {
- switch (img->Format) {
+ if (repeatNoBorder) {
+ switch (tImg->Format) {
case GL_RGB:
- opt_sample_rgb_2d(ctx, texUnit, tObj, n, s, t, NULL,
- NULL, rgba);
+ opt_sample_rgb_2d(ctx, texUnit, tObj, m, texcoords + minStart,
+ NULL, rgba + minStart);
break;
case GL_RGBA:
- opt_sample_rgba_2d(ctx, texUnit, tObj, n, s, t, NULL,
- NULL, rgba);
+ opt_sample_rgba_2d(ctx, texUnit, tObj, m, texcoords + minStart,
+ NULL, rgba + minStart);
break;
default:
- sample_nearest_2d(ctx, texUnit, tObj, n, s, t, NULL,
- NULL, rgba);
+ sample_nearest_2d(ctx, texUnit, tObj, m, texcoords + minStart,
+ NULL, rgba + minStart );
}
}
else {
- sample_nearest_2d(ctx, texUnit, tObj, n, s, t, NULL,
- NULL, rgba);
+ sample_nearest_2d(ctx, texUnit, tObj, m, texcoords + minStart,
+ NULL, rgba + minStart);
}
break;
case GL_LINEAR:
- sample_linear_2d(ctx, texUnit, tObj, n, s, t, NULL,
- NULL, rgba);
+ sample_linear_2d(ctx, texUnit, tObj, m, texcoords + minStart,
+ NULL, rgba + minStart);
+ break;
+ case GL_NEAREST_MIPMAP_NEAREST:
+ sample_2d_nearest_mipmap_nearest(ctx, tObj, m, texcoords + minStart,
+ lambda + minStart, rgba + minStart);
+ break;
+ case GL_LINEAR_MIPMAP_NEAREST:
+ sample_2d_linear_mipmap_nearest(ctx, tObj, m, texcoords + minStart,
+ lambda + minStart, rgba + minStart);
+ break;
+ case GL_NEAREST_MIPMAP_LINEAR:
+ sample_2d_nearest_mipmap_linear(ctx, tObj, m, texcoords + minStart,
+ lambda + minStart, rgba + minStart);
+ break;
+ case GL_LINEAR_MIPMAP_LINEAR:
+ if (repeatNoBorder)
+ sample_2d_linear_mipmap_linear_repeat(ctx, tObj, m,
+ texcoords + minStart, lambda + minStart, rgba + minStart);
+ else
+ sample_2d_linear_mipmap_linear(ctx, tObj, m, texcoords + minStart,
+ lambda + minStart, rgba + minStart);
break;
default:
- _mesa_problem(NULL, "Bad mag filter in sample_lambda_2d");
+ _mesa_problem(ctx, "Bad min filter in sample_2d_texture");
+ return;
}
}
- else {
- for (i = 0; i < n; i++) {
- if (lambda[i] > minMagThresh) {
- /* minification */
- switch (tObj->MinFilter) {
- case GL_NEAREST:
- sample_2d_nearest(ctx, tObj, tObj->Image[tObj->BaseLevel],
- s[i], t[i], rgba[i]);
- break;
- case GL_LINEAR:
- sample_2d_linear(ctx, tObj, tObj->Image[tObj->BaseLevel],
- s[i], t[i], rgba[i]);
- break;
- case GL_NEAREST_MIPMAP_NEAREST:
- sample_2d_nearest_mipmap_nearest(ctx, tObj, s[i], t[i],
- lambda[i], rgba[i]);
- break;
- case GL_LINEAR_MIPMAP_NEAREST:
- sample_2d_linear_mipmap_nearest(ctx,tObj, s[i], t[i],
- lambda[i], rgba[i]);
- break;
- case GL_NEAREST_MIPMAP_LINEAR:
- sample_2d_nearest_mipmap_linear(ctx,tObj, s[i], t[i],
- lambda[i], rgba[i]);
- break;
- case GL_LINEAR_MIPMAP_LINEAR:
- sample_2d_linear_mipmap_linear(ctx,tObj, s[i], t[i],
- lambda[i], rgba[i] );
- break;
- default:
- _mesa_problem(NULL, "Bad min filter in sample_2d_texture");
- return;
+
+ if (magStart < magEnd) {
+ /* do the magnified texels */
+ const GLuint m = magEnd - magStart;
+
+ switch (tObj->MagFilter) {
+ case GL_NEAREST:
+ if (repeatNoBorder) {
+ switch (tImg->Format) {
+ case GL_RGB:
+ opt_sample_rgb_2d(ctx, texUnit, tObj, m, texcoords + magStart,
+ NULL, rgba + magStart);
+ break;
+ case GL_RGBA:
+ opt_sample_rgba_2d(ctx, texUnit, tObj, m, texcoords + magStart,
+ NULL, rgba + magStart);
+ break;
+ default:
+ sample_nearest_2d(ctx, texUnit, tObj, m, texcoords + magStart,
+ NULL, rgba + magStart );
}
}
else {
- /* magnification */
- switch (tObj->MagFilter) {
- case GL_NEAREST:
- sample_2d_nearest(ctx, tObj, tObj->Image[tObj->BaseLevel],
- s[i], t[i], rgba[i]);
- break;
- case GL_LINEAR:
- sample_2d_linear(ctx, tObj, tObj->Image[tObj->BaseLevel],
- s[i], t[i], rgba[i] );
- break;
- default:
- _mesa_problem(NULL, "Bad mag filter in sample_2d_texture");
- }
+ sample_nearest_2d(ctx, texUnit, tObj, m, texcoords + magStart,
+ NULL, rgba + magStart);
}
+ break;
+ case GL_LINEAR:
+ sample_linear_2d(ctx, texUnit, tObj, m, texcoords + magStart,
+ NULL, rgba + magStart);
+ break;
+ default:
+ _mesa_problem(ctx, "Bad mag filter in sample_lambda_2d");
}
}
}
@@ -1074,7 +1364,7 @@ static void
sample_3d_nearest(GLcontext *ctx,
const struct gl_texture_object *tObj,
const struct gl_texture_image *img,
- GLfloat s, GLfloat t, GLfloat r,
+ const GLfloat texcoord[4],
GLchan rgba[4])
{
const GLint width = img->Width2; /* without border, power of two */
@@ -1082,15 +1372,15 @@ sample_3d_nearest(GLcontext *ctx,
const GLint depth = img->Depth2; /* without border, power of two */
GLint i, j, k;
- COMPUTE_NEAREST_TEXEL_LOCATION(tObj->WrapS, s, width, i);
- COMPUTE_NEAREST_TEXEL_LOCATION(tObj->WrapT, t, height, j);
- COMPUTE_NEAREST_TEXEL_LOCATION(tObj->WrapR, r, depth, k);
+ COMPUTE_NEAREST_TEXEL_LOCATION(tObj->WrapS, texcoord[0], width, i);
+ COMPUTE_NEAREST_TEXEL_LOCATION(tObj->WrapT, texcoord[1], height, j);
+ COMPUTE_NEAREST_TEXEL_LOCATION(tObj->WrapR, texcoord[2], depth, k);
if (i < 0 || i >= (GLint) img->Width ||
j < 0 || j >= (GLint) img->Height ||
k < 0 || k >= (GLint) img->Depth) {
- /* Need this test for GL_CLAMP_TO_BORDER_ARB mode */
- COPY_CHAN4(rgba, tObj->BorderColor);
+ /* Need this test for GL_CLAMP_TO_BORDER mode */
+ COPY_CHAN4(rgba, tObj->_BorderChan);
}
else {
(*img->FetchTexel)(img, i, j, k, (GLvoid *) rgba);
@@ -1109,7 +1399,7 @@ static void
sample_3d_linear(GLcontext *ctx,
const struct gl_texture_object *tObj,
const struct gl_texture_image *img,
- GLfloat s, GLfloat t, GLfloat r,
+ const GLfloat texcoord[4],
GLchan rgba[4])
{
const GLint width = img->Width2;
@@ -1119,9 +1409,9 @@ sample_3d_linear(GLcontext *ctx,
GLuint useBorderColor;
GLfloat u, v, w;
- COMPUTE_LINEAR_TEXEL_LOCATIONS(tObj->WrapS, s, u, width, i0, i1);
- COMPUTE_LINEAR_TEXEL_LOCATIONS(tObj->WrapT, t, v, height, j0, j1);
- COMPUTE_LINEAR_TEXEL_LOCATIONS(tObj->WrapR, r, w, depth, k0, k1);
+ COMPUTE_LINEAR_TEXEL_LOCATIONS(tObj->WrapS, texcoord[0], u, width, i0, i1);
+ COMPUTE_LINEAR_TEXEL_LOCATIONS(tObj->WrapT, texcoord[1], v, height, j0, j1);
+ COMPUTE_LINEAR_TEXEL_LOCATIONS(tObj->WrapR, texcoord[2], w, depth, k0, k1);
useBorderColor = 0;
if (img->Border) {
@@ -1173,7 +1463,7 @@ sample_3d_linear(GLcontext *ctx,
GLchan t100[4], t110[4], t101[4], t111[4];
if (useBorderColor & (I0BIT | J0BIT | K0BIT)) {
- COPY_CHAN4(t000, tObj->BorderColor);
+ COPY_CHAN4(t000, tObj->_BorderChan);
}
else {
(*img->FetchTexel)(img, i0, j0, k0, (GLvoid *) t000);
@@ -1182,7 +1472,7 @@ sample_3d_linear(GLcontext *ctx,
}
}
if (useBorderColor & (I1BIT | J0BIT | K0BIT)) {
- COPY_CHAN4(t100, tObj->BorderColor);
+ COPY_CHAN4(t100, tObj->_BorderChan);
}
else {
(*img->FetchTexel)(img, i1, j0, k0, (GLvoid *) t100);
@@ -1191,7 +1481,7 @@ sample_3d_linear(GLcontext *ctx,
}
}
if (useBorderColor & (I0BIT | J1BIT | K0BIT)) {
- COPY_CHAN4(t010, tObj->BorderColor);
+ COPY_CHAN4(t010, tObj->_BorderChan);
}
else {
(*img->FetchTexel)(img, i0, j1, k0, (GLvoid *) t010);
@@ -1200,7 +1490,7 @@ sample_3d_linear(GLcontext *ctx,
}
}
if (useBorderColor & (I1BIT | J1BIT | K0BIT)) {
- COPY_CHAN4(t110, tObj->BorderColor);
+ COPY_CHAN4(t110, tObj->_BorderChan);
}
else {
(*img->FetchTexel)(img, i1, j1, k0, (GLvoid *) t110);
@@ -1210,7 +1500,7 @@ sample_3d_linear(GLcontext *ctx,
}
if (useBorderColor & (I0BIT | J0BIT | K1BIT)) {
- COPY_CHAN4(t001, tObj->BorderColor);
+ COPY_CHAN4(t001, tObj->_BorderChan);
}
else {
(*img->FetchTexel)(img, i0, j0, k1, (GLvoid *) t001);
@@ -1219,7 +1509,7 @@ sample_3d_linear(GLcontext *ctx,
}
}
if (useBorderColor & (I1BIT | J0BIT | K1BIT)) {
- COPY_CHAN4(t101, tObj->BorderColor);
+ COPY_CHAN4(t101, tObj->_BorderChan);
}
else {
(*img->FetchTexel)(img, i1, j0, k1, (GLvoid *) t101);
@@ -1228,7 +1518,7 @@ sample_3d_linear(GLcontext *ctx,
}
}
if (useBorderColor & (I0BIT | J1BIT | K1BIT)) {
- COPY_CHAN4(t011, tObj->BorderColor);
+ COPY_CHAN4(t011, tObj->_BorderChan);
}
else {
(*img->FetchTexel)(img, i0, j1, k1, (GLvoid *) t011);
@@ -1237,7 +1527,7 @@ sample_3d_linear(GLcontext *ctx,
}
}
if (useBorderColor & (I1BIT | J1BIT | K1BIT)) {
- COPY_CHAN4(t111, tObj->BorderColor);
+ COPY_CHAN4(t111, tObj->_BorderChan);
}
else {
(*img->FetchTexel)(img, i1, j1, k1, (GLvoid *) t111);
@@ -1299,50 +1589,59 @@ sample_3d_linear(GLcontext *ctx,
static void
sample_3d_nearest_mipmap_nearest(GLcontext *ctx,
const struct gl_texture_object *tObj,
- GLfloat s, GLfloat t, GLfloat r,
- GLfloat lambda, GLchan rgba[4] )
+ GLuint n, GLfloat texcoord[][4],
+ const GLfloat lambda[], GLchan rgba[][4] )
{
- GLint level;
- COMPUTE_NEAREST_MIPMAP_LEVEL(tObj, lambda, level);
- sample_3d_nearest(ctx, tObj, tObj->Image[level], s, t, r, rgba);
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ GLint level;
+ COMPUTE_NEAREST_MIPMAP_LEVEL(tObj, lambda[i], level);
+ sample_3d_nearest(ctx, tObj, tObj->Image[level], texcoord[i], rgba[i]);
+ }
}
static void
sample_3d_linear_mipmap_nearest(GLcontext *ctx,
const struct gl_texture_object *tObj,
- GLfloat s, GLfloat t, GLfloat r,
- GLfloat lambda, GLchan rgba[4])
+ GLuint n, GLfloat texcoord[][4],
+ const GLfloat lambda[], GLchan rgba[][4])
{
- GLint level;
- COMPUTE_NEAREST_MIPMAP_LEVEL(tObj, lambda, level);
- sample_3d_linear(ctx, tObj, tObj->Image[level], s, t, r, rgba);
+ GLuint i;
+ ASSERT(lambda != NULL);
+ for (i = 0; i < n; i++) {
+ GLint level;
+ COMPUTE_NEAREST_MIPMAP_LEVEL(tObj, lambda[i], level);
+ sample_3d_linear(ctx, tObj, tObj->Image[level], texcoord[i], rgba[i]);
+ }
}
static void
sample_3d_nearest_mipmap_linear(GLcontext *ctx,
const struct gl_texture_object *tObj,
- GLfloat s, GLfloat t, GLfloat r,
- GLfloat lambda, GLchan rgba[4])
+ GLuint n, GLfloat texcoord[][4],
+ const GLfloat lambda[], GLchan rgba[][4])
{
- GLint level;
-
- COMPUTE_LINEAR_MIPMAP_LEVEL(tObj, lambda, level);
-
- if (level >= tObj->_MaxLevel) {
- sample_3d_nearest(ctx, tObj, tObj->Image[tObj->_MaxLevel],
- s, t, r, rgba);
- }
- else {
- GLchan t0[4], t1[4]; /* texels */
- const GLfloat f = FRAC(lambda);
- sample_3d_nearest(ctx, tObj, tObj->Image[level ], s, t, r, t0);
- sample_3d_nearest(ctx, tObj, tObj->Image[level+1], s, t, r, t1);
- rgba[RCOMP] = (GLchan) INTCAST ((1.0F-f) * t0[RCOMP] + f * t1[RCOMP]);
- rgba[GCOMP] = (GLchan) INTCAST ((1.0F-f) * t0[GCOMP] + f * t1[GCOMP]);
- rgba[BCOMP] = (GLchan) INTCAST ((1.0F-f) * t0[BCOMP] + f * t1[BCOMP]);
- rgba[ACOMP] = (GLchan) INTCAST ((1.0F-f) * t0[ACOMP] + f * t1[ACOMP]);
+ GLuint i;
+ ASSERT(lambda != NULL);
+ for (i = 0; i < n; i++) {
+ GLint level;
+ COMPUTE_LINEAR_MIPMAP_LEVEL(tObj, lambda[i], level);
+ if (level >= tObj->_MaxLevel) {
+ sample_3d_nearest(ctx, tObj, tObj->Image[tObj->_MaxLevel],
+ texcoord[i], rgba[i]);
+ }
+ else {
+ GLchan t0[4], t1[4]; /* texels */
+ const GLfloat f = FRAC(lambda[i]);
+ sample_3d_nearest(ctx, tObj, tObj->Image[level ], texcoord[i], t0);
+ sample_3d_nearest(ctx, tObj, tObj->Image[level+1], texcoord[i], t1);
+ rgba[i][RCOMP] = CHAN_CAST ((1.0F-f) * t0[RCOMP] + f * t1[RCOMP]);
+ rgba[i][GCOMP] = CHAN_CAST ((1.0F-f) * t0[GCOMP] + f * t1[GCOMP]);
+ rgba[i][BCOMP] = CHAN_CAST ((1.0F-f) * t0[BCOMP] + f * t1[BCOMP]);
+ rgba[i][ACOMP] = CHAN_CAST ((1.0F-f) * t0[ACOMP] + f * t1[ACOMP]);
+ }
}
}
@@ -1350,25 +1649,28 @@ sample_3d_nearest_mipmap_linear(GLcontext *ctx,
static void
sample_3d_linear_mipmap_linear(GLcontext *ctx,
const struct gl_texture_object *tObj,
- GLfloat s, GLfloat t, GLfloat r,
- GLfloat lambda, GLchan rgba[4] )
+ GLuint n, GLfloat texcoord[][4],
+ const GLfloat lambda[], GLchan rgba[][4])
{
- GLint level;
-
- COMPUTE_LINEAR_MIPMAP_LEVEL(tObj, lambda, level);
-
- if (level >= tObj->_MaxLevel) {
- sample_3d_linear(ctx, tObj, tObj->Image[tObj->_MaxLevel], s, t, r, rgba);
- }
- else {
- GLchan t0[4], t1[4]; /* texels */
- const GLfloat f = FRAC(lambda);
- sample_3d_linear(ctx, tObj, tObj->Image[level ], s, t, r, t0);
- sample_3d_linear(ctx, tObj, tObj->Image[level+1], s, t, r, t1);
- rgba[RCOMP] = (GLchan) INTCAST ((1.0F-f) * t0[RCOMP] + f * t1[RCOMP]);
- rgba[GCOMP] = (GLchan) INTCAST ((1.0F-f) * t0[GCOMP] + f * t1[GCOMP]);
- rgba[BCOMP] = (GLchan) INTCAST ((1.0F-f) * t0[BCOMP] + f * t1[BCOMP]);
- rgba[ACOMP] = (GLchan) INTCAST ((1.0F-f) * t0[ACOMP] + f * t1[ACOMP]);
+ GLuint i;
+ ASSERT(lambda != NULL);
+ for (i = 0; i < n; i++) {
+ GLint level;
+ COMPUTE_LINEAR_MIPMAP_LEVEL(tObj, lambda[i], level);
+ if (level >= tObj->_MaxLevel) {
+ sample_3d_linear(ctx, tObj, tObj->Image[tObj->_MaxLevel],
+ texcoord[i], rgba[i]);
+ }
+ else {
+ GLchan t0[4], t1[4]; /* texels */
+ const GLfloat f = FRAC(lambda[i]);
+ sample_3d_linear(ctx, tObj, tObj->Image[level ], texcoord[i], t0);
+ sample_3d_linear(ctx, tObj, tObj->Image[level+1], texcoord[i], t1);
+ rgba[i][RCOMP] = CHAN_CAST ((1.0F-f) * t0[RCOMP] + f * t1[RCOMP]);
+ rgba[i][GCOMP] = CHAN_CAST ((1.0F-f) * t0[GCOMP] + f * t1[GCOMP]);
+ rgba[i][BCOMP] = CHAN_CAST ((1.0F-f) * t0[BCOMP] + f * t1[BCOMP]);
+ rgba[i][ACOMP] = CHAN_CAST ((1.0F-f) * t0[ACOMP] + f * t1[ACOMP]);
+ }
}
}
@@ -1376,15 +1678,14 @@ sample_3d_linear_mipmap_linear(GLcontext *ctx,
static void
sample_nearest_3d(GLcontext *ctx, GLuint texUnit,
const struct gl_texture_object *tObj, GLuint n,
- const GLfloat s[], const GLfloat t[],
- const GLfloat u[], const GLfloat lambda[],
+ GLfloat texcoords[][4], const GLfloat lambda[],
GLchan rgba[][4])
{
GLuint i;
struct gl_texture_image *image = tObj->Image[tObj->BaseLevel];
(void) lambda;
for (i=0;i<n;i++) {
- sample_3d_nearest(ctx, tObj, image, s[i], t[i], u[i], rgba[i]);
+ sample_3d_nearest(ctx, tObj, image, texcoords[i], rgba[i]);
}
}
@@ -1393,15 +1694,14 @@ sample_nearest_3d(GLcontext *ctx, GLuint texUnit,
static void
sample_linear_3d( GLcontext *ctx, GLuint texUnit,
const struct gl_texture_object *tObj, GLuint n,
- const GLfloat s[], const GLfloat t[],
- const GLfloat u[], const GLfloat lambda[],
- GLchan rgba[][4] )
+ GLfloat texcoords[][4],
+ const GLfloat lambda[], GLchan rgba[][4] )
{
GLuint i;
struct gl_texture_image *image = tObj->Image[tObj->BaseLevel];
(void) lambda;
for (i=0;i<n;i++) {
- sample_3d_linear(ctx, tObj, image, s[i], t[i], u[i], rgba[i]);
+ sample_3d_linear(ctx, tObj, image, texcoords[i], rgba[i]);
}
}
@@ -1413,60 +1713,69 @@ sample_linear_3d( GLcontext *ctx, GLuint texUnit,
static void
sample_lambda_3d( GLcontext *ctx, GLuint texUnit,
const struct gl_texture_object *tObj, GLuint n,
- const GLfloat s[], const GLfloat t[],
- const GLfloat u[], const GLfloat lambda[],
+ GLfloat texcoords[][4], const GLfloat lambda[],
GLchan rgba[][4] )
{
+ GLuint minStart, minEnd; /* texels with minification */
+ GLuint magStart, magEnd; /* texels with magnification */
GLuint i;
- GLfloat MinMagThresh = SWRAST_CONTEXT(ctx)->_MinMagThresh[texUnit];
- for (i=0;i<n;i++) {
+ ASSERT(lambda != NULL);
+ compute_min_mag_ranges(SWRAST_CONTEXT(ctx)->_MinMagThresh[texUnit],
+ n, lambda, &minStart, &minEnd, &magStart, &magEnd);
- if (lambda[i] > MinMagThresh) {
- /* minification */
- switch (tObj->MinFilter) {
- case GL_NEAREST:
- sample_3d_nearest(ctx, tObj, tObj->Image[tObj->BaseLevel],
- s[i], t[i], u[i], rgba[i]);
- break;
- case GL_LINEAR:
- sample_3d_linear(ctx, tObj, tObj->Image[tObj->BaseLevel],
- s[i], t[i], u[i], rgba[i]);
- break;
- case GL_NEAREST_MIPMAP_NEAREST:
- sample_3d_nearest_mipmap_nearest(ctx, tObj, s[i], t[i], u[i],
- lambda[i], rgba[i]);
- break;
- case GL_LINEAR_MIPMAP_NEAREST:
- sample_3d_linear_mipmap_nearest(ctx, tObj, s[i], t[i], u[i],
- lambda[i], rgba[i]);
- break;
- case GL_NEAREST_MIPMAP_LINEAR:
- sample_3d_nearest_mipmap_linear(ctx, tObj, s[i], t[i], u[i],
- lambda[i], rgba[i]);
- break;
- case GL_LINEAR_MIPMAP_LINEAR:
- sample_3d_linear_mipmap_linear(ctx, tObj, s[i], t[i], u[i],
- lambda[i], rgba[i]);
- break;
- default:
- _mesa_problem(NULL, "Bad min filterin sample_3d_texture");
- }
+ if (minStart < minEnd) {
+ /* do the minified texels */
+ GLuint m = minEnd - minStart;
+ switch (tObj->MinFilter) {
+ case GL_NEAREST:
+ for (i = minStart; i < minEnd; i++)
+ sample_3d_nearest(ctx, tObj, tObj->Image[tObj->BaseLevel],
+ texcoords[i], rgba[i]);
+ break;
+ case GL_LINEAR:
+ for (i = minStart; i < minEnd; i++)
+ sample_3d_linear(ctx, tObj, tObj->Image[tObj->BaseLevel],
+ texcoords[i], rgba[i]);
+ break;
+ case GL_NEAREST_MIPMAP_NEAREST:
+ sample_3d_nearest_mipmap_nearest(ctx, tObj, m, texcoords + minStart,
+ lambda + minStart, rgba + minStart);
+ break;
+ case GL_LINEAR_MIPMAP_NEAREST:
+ sample_3d_linear_mipmap_nearest(ctx, tObj, m, texcoords + minStart,
+ lambda + minStart, rgba + minStart);
+ break;
+ case GL_NEAREST_MIPMAP_LINEAR:
+ sample_3d_nearest_mipmap_linear(ctx, tObj, m, texcoords + minStart,
+ lambda + minStart, rgba + minStart);
+ break;
+ case GL_LINEAR_MIPMAP_LINEAR:
+ sample_3d_linear_mipmap_linear(ctx, tObj, m, texcoords + minStart,
+ lambda + minStart, rgba + minStart);
+ break;
+ default:
+ _mesa_problem(ctx, "Bad min filter in sample_3d_texture");
+ return;
}
- else {
- /* magnification */
- switch (tObj->MagFilter) {
- case GL_NEAREST:
- sample_3d_nearest(ctx, tObj, tObj->Image[tObj->BaseLevel],
- s[i], t[i], u[i], rgba[i]);
- break;
- case GL_LINEAR:
- sample_3d_linear(ctx, tObj, tObj->Image[tObj->BaseLevel],
- s[i], t[i], u[i], rgba[i]);
- break;
- default:
- _mesa_problem(NULL, "Bad mag filter in sample_3d_texture");
- }
+ }
+
+ if (magStart < magEnd) {
+ /* do the magnified texels */
+ switch (tObj->MagFilter) {
+ case GL_NEAREST:
+ for (i = magStart; i < magEnd; i++)
+ sample_3d_nearest(ctx, tObj, tObj->Image[tObj->BaseLevel],
+ texcoords[i], rgba[i]);
+ break;
+ case GL_LINEAR:
+ for (i = magStart; i < magEnd; i++)
+ sample_3d_linear(ctx, tObj, tObj->Image[tObj->BaseLevel],
+ texcoords[i], rgba[i]);
+ break;
+ default:
+ _mesa_problem(ctx, "Bad mag filter in sample_3d_texture");
+ return;
}
}
}
@@ -1483,8 +1792,7 @@ sample_lambda_3d( GLcontext *ctx, GLuint texUnit,
*/
static const struct gl_texture_image **
choose_cube_face(const struct gl_texture_object *texObj,
- GLfloat rx, GLfloat ry, GLfloat rz,
- GLfloat *newS, GLfloat *newT)
+ const GLfloat texcoord[4], GLfloat newCoord[4])
{
/*
major axis
@@ -1497,6 +1805,9 @@ choose_cube_face(const struct gl_texture_object *texObj,
+rz TEXTURE_CUBE_MAP_POSITIVE_Z_EXT +rx -ry rz
-rz TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT -rx -ry rz
*/
+ const GLfloat rx = texcoord[0];
+ const GLfloat ry = texcoord[1];
+ const GLfloat rz = texcoord[2];
const struct gl_texture_image **imgArray;
const GLfloat arx = ABSF(rx), ary = ABSF(ry), arz = ABSF(rz);
GLfloat sc, tc, ma;
@@ -1544,8 +1855,8 @@ choose_cube_face(const struct gl_texture_object *texObj,
}
}
- *newS = ( sc / ma + 1.0F ) * 0.5F;
- *newT = ( tc / ma + 1.0F ) * 0.5F;
+ newCoord[0] = ( sc / ma + 1.0F ) * 0.5F;
+ newCoord[1] = ( tc / ma + 1.0F ) * 0.5F;
return imgArray;
}
@@ -1553,18 +1864,17 @@ choose_cube_face(const struct gl_texture_object *texObj,
static void
sample_nearest_cube(GLcontext *ctx, GLuint texUnit,
const struct gl_texture_object *tObj, GLuint n,
- const GLfloat s[], const GLfloat t[],
- const GLfloat u[], const GLfloat lambda[],
+ GLfloat texcoords[][4], const GLfloat lambda[],
GLchan rgba[][4])
{
GLuint i;
(void) lambda;
for (i = 0; i < n; i++) {
const struct gl_texture_image **images;
- GLfloat newS, newT;
- images = choose_cube_face(tObj, s[i], t[i], u[i], &newS, &newT);
+ GLfloat newCoord[4];
+ images = choose_cube_face(tObj, texcoords[i], newCoord);
sample_2d_nearest(ctx, tObj, images[tObj->BaseLevel],
- newS, newT, rgba[i]);
+ newCoord, rgba[i]);
}
}
@@ -1572,112 +1882,119 @@ sample_nearest_cube(GLcontext *ctx, GLuint texUnit,
static void
sample_linear_cube(GLcontext *ctx, GLuint texUnit,
const struct gl_texture_object *tObj, GLuint n,
- const GLfloat s[], const GLfloat t[],
- const GLfloat u[], const GLfloat lambda[],
- GLchan rgba[][4])
+ GLfloat texcoords[][4],
+ const GLfloat lambda[], GLchan rgba[][4])
{
GLuint i;
(void) lambda;
for (i = 0; i < n; i++) {
const struct gl_texture_image **images;
- GLfloat newS, newT;
- images = choose_cube_face(tObj, s[i], t[i], u[i], &newS, &newT);
+ GLfloat newCoord[4];
+ images = choose_cube_face(tObj, texcoords[i], newCoord);
sample_2d_linear(ctx, tObj, images[tObj->BaseLevel],
- newS, newT, rgba[i]);
+ newCoord, rgba[i]);
}
}
static void
-sample_cube_nearest_mipmap_nearest(GLcontext *ctx,
+sample_cube_nearest_mipmap_nearest(GLcontext *ctx, GLuint texUnit,
const struct gl_texture_object *tObj,
- GLfloat s, GLfloat t, GLfloat u,
- GLfloat lambda, GLchan rgba[4])
+ GLuint n, GLfloat texcoord[][4],
+ const GLfloat lambda[], GLchan rgba[][4])
{
- const struct gl_texture_image **images;
- GLfloat newS, newT;
- GLint level;
-
- COMPUTE_NEAREST_MIPMAP_LEVEL(tObj, lambda, level);
-
- images = choose_cube_face(tObj, s, t, u, &newS, &newT);
- sample_2d_nearest(ctx, tObj, images[level], newS, newT, rgba);
+ GLuint i;
+ ASSERT(lambda != NULL);
+ for (i = 0; i < n; i++) {
+ const struct gl_texture_image **images;
+ GLfloat newCoord[4];
+ GLint level;
+ COMPUTE_NEAREST_MIPMAP_LEVEL(tObj, lambda[i], level);
+ images = choose_cube_face(tObj, texcoord[i], newCoord);
+ sample_2d_nearest(ctx, tObj, images[level], newCoord, rgba[i]);
+ }
}
static void
-sample_cube_linear_mipmap_nearest(GLcontext *ctx,
+sample_cube_linear_mipmap_nearest(GLcontext *ctx, GLuint texUnit,
const struct gl_texture_object *tObj,
- GLfloat s, GLfloat t, GLfloat u,
- GLfloat lambda, GLchan rgba[4])
+ GLuint n, GLfloat texcoord[][4],
+ const GLfloat lambda[], GLchan rgba[][4])
{
- const struct gl_texture_image **images;
- GLfloat newS, newT;
- GLint level;
-
- COMPUTE_NEAREST_MIPMAP_LEVEL(tObj, lambda, level);
-
- images = choose_cube_face(tObj, s, t, u, &newS, &newT);
- sample_2d_linear(ctx, tObj, images[level], newS, newT, rgba);
+ GLuint i;
+ ASSERT(lambda != NULL);
+ for (i = 0; i < n; i++) {
+ const struct gl_texture_image **images;
+ GLfloat newCoord[4];
+ GLint level;
+ COMPUTE_NEAREST_MIPMAP_LEVEL(tObj, lambda[i], level);
+ images = choose_cube_face(tObj, texcoord[i], newCoord);
+ sample_2d_linear(ctx, tObj, images[level], newCoord, rgba[i]);
+ }
}
static void
-sample_cube_nearest_mipmap_linear(GLcontext *ctx,
+sample_cube_nearest_mipmap_linear(GLcontext *ctx, GLuint texUnit,
const struct gl_texture_object *tObj,
- GLfloat s, GLfloat t, GLfloat u,
- GLfloat lambda, GLchan rgba[4])
+ GLuint n, GLfloat texcoord[][4],
+ const GLfloat lambda[], GLchan rgba[][4])
{
- const struct gl_texture_image **images;
- GLfloat newS, newT;
- GLint level;
-
- COMPUTE_LINEAR_MIPMAP_LEVEL(tObj, lambda, level);
-
- images = choose_cube_face(tObj, s, t, u, &newS, &newT);
-
- if (level >= tObj->_MaxLevel) {
- sample_2d_nearest(ctx, tObj, images[tObj->_MaxLevel], newS, newT, rgba);
- }
- else {
- GLchan t0[4], t1[4]; /* texels */
- const GLfloat f = FRAC(lambda);
- sample_2d_nearest(ctx, tObj, images[level ], newS, newT, t0);
- sample_2d_nearest(ctx, tObj, images[level+1], newS, newT, t1);
- rgba[RCOMP] = (GLchan) INTCAST ((1.0F-f) * t0[RCOMP] + f * t1[RCOMP]);
- rgba[GCOMP] = (GLchan) INTCAST ((1.0F-f) * t0[GCOMP] + f * t1[GCOMP]);
- rgba[BCOMP] = (GLchan) INTCAST ((1.0F-f) * t0[BCOMP] + f * t1[BCOMP]);
- rgba[ACOMP] = (GLchan) INTCAST ((1.0F-f) * t0[ACOMP] + f * t1[ACOMP]);
+ GLuint i;
+ ASSERT(lambda != NULL);
+ for (i = 0; i < n; i++) {
+ const struct gl_texture_image **images;
+ GLfloat newCoord[4];
+ GLint level;
+ COMPUTE_LINEAR_MIPMAP_LEVEL(tObj, lambda[i], level);
+ images = choose_cube_face(tObj, texcoord[i], newCoord);
+ if (level >= tObj->_MaxLevel) {
+ sample_2d_nearest(ctx, tObj, images[tObj->_MaxLevel],
+ newCoord, rgba[i]);
+ }
+ else {
+ GLchan t0[4], t1[4]; /* texels */
+ const GLfloat f = FRAC(lambda[i]);
+ sample_2d_nearest(ctx, tObj, images[level ], newCoord, t0);
+ sample_2d_nearest(ctx, tObj, images[level+1], newCoord, t1);
+ rgba[i][RCOMP] = CHAN_CAST ((1.0F-f) * t0[RCOMP] + f * t1[RCOMP]);
+ rgba[i][GCOMP] = CHAN_CAST ((1.0F-f) * t0[GCOMP] + f * t1[GCOMP]);
+ rgba[i][BCOMP] = CHAN_CAST ((1.0F-f) * t0[BCOMP] + f * t1[BCOMP]);
+ rgba[i][ACOMP] = CHAN_CAST ((1.0F-f) * t0[ACOMP] + f * t1[ACOMP]);
+ }
}
}
static void
-sample_cube_linear_mipmap_linear(GLcontext *ctx,
+sample_cube_linear_mipmap_linear(GLcontext *ctx, GLuint texUnit,
const struct gl_texture_object *tObj,
- GLfloat s, GLfloat t, GLfloat u,
- GLfloat lambda, GLchan rgba[4])
+ GLuint n, GLfloat texcoord[][4],
+ const GLfloat lambda[], GLchan rgba[][4])
{
- const struct gl_texture_image **images;
- GLfloat newS, newT;
- GLint level;
-
- COMPUTE_LINEAR_MIPMAP_LEVEL(tObj, lambda, level);
-
- images = choose_cube_face(tObj, s, t, u, &newS, &newT);
-
- if (level >= tObj->_MaxLevel) {
- sample_2d_linear(ctx, tObj, images[tObj->_MaxLevel], newS, newT, rgba);
- }
- else {
- GLchan t0[4], t1[4];
- const GLfloat f = FRAC(lambda);
- sample_2d_linear(ctx, tObj, images[level ], newS, newT, t0);
- sample_2d_linear(ctx, tObj, images[level+1], newS, newT, t1);
- rgba[RCOMP] = (GLchan) INTCAST ((1.0F-f) * t0[RCOMP] + f * t1[RCOMP]);
- rgba[GCOMP] = (GLchan) INTCAST ((1.0F-f) * t0[GCOMP] + f * t1[GCOMP]);
- rgba[BCOMP] = (GLchan) INTCAST ((1.0F-f) * t0[BCOMP] + f * t1[BCOMP]);
- rgba[ACOMP] = (GLchan) INTCAST ((1.0F-f) * t0[ACOMP] + f * t1[ACOMP]);
+ GLuint i;
+ ASSERT(lambda != NULL);
+ for (i = 0; i < n; i++) {
+ const struct gl_texture_image **images;
+ GLfloat newCoord[4];
+ GLint level;
+ COMPUTE_LINEAR_MIPMAP_LEVEL(tObj, lambda[i], level);
+ images = choose_cube_face(tObj, texcoord[i], newCoord);
+ if (level >= tObj->_MaxLevel) {
+ sample_2d_linear(ctx, tObj, images[tObj->_MaxLevel],
+ newCoord, rgba[i]);
+ }
+ else {
+ GLchan t0[4], t1[4];
+ const GLfloat f = FRAC(lambda[i]);
+ sample_2d_linear(ctx, tObj, images[level ], newCoord, t0);
+ sample_2d_linear(ctx, tObj, images[level+1], newCoord, t1);
+ rgba[i][RCOMP] = CHAN_CAST ((1.0F-f) * t0[RCOMP] + f * t1[RCOMP]);
+ rgba[i][GCOMP] = CHAN_CAST ((1.0F-f) * t0[GCOMP] + f * t1[GCOMP]);
+ rgba[i][BCOMP] = CHAN_CAST ((1.0F-f) * t0[BCOMP] + f * t1[BCOMP]);
+ rgba[i][ACOMP] = CHAN_CAST ((1.0F-f) * t0[ACOMP] + f * t1[ACOMP]);
+ }
}
}
@@ -1685,81 +2002,72 @@ sample_cube_linear_mipmap_linear(GLcontext *ctx,
static void
sample_lambda_cube( GLcontext *ctx, GLuint texUnit,
const struct gl_texture_object *tObj, GLuint n,
- const GLfloat s[], const GLfloat t[],
- const GLfloat u[], const GLfloat lambda[],
+ GLfloat texcoords[][4], const GLfloat lambda[],
GLchan rgba[][4])
{
- GLfloat MinMagThresh = SWRAST_CONTEXT(ctx)->_MinMagThresh[texUnit];
- GLuint i;
+ GLuint minStart, minEnd; /* texels with minification */
+ GLuint magStart, magEnd; /* texels with magnification */
- for (i = 0; i < n; i++) {
- if (lambda[i] > MinMagThresh) {
- /* minification */
- switch (tObj->MinFilter) {
- case GL_NEAREST:
- {
- const struct gl_texture_image **images;
- GLfloat newS, newT;
- images = choose_cube_face(tObj, s[i], t[i], u[i],
- &newS, &newT);
- sample_2d_nearest(ctx, tObj, images[tObj->BaseLevel],
- newS, newT, rgba[i]);
- }
- break;
- case GL_LINEAR:
- {
- const struct gl_texture_image **images;
- GLfloat newS, newT;
- images = choose_cube_face(tObj, s[i], t[i], u[i],
- &newS, &newT);
- sample_2d_linear(ctx, tObj, images[tObj->BaseLevel],
- newS, newT, rgba[i]);
- }
- break;
- case GL_NEAREST_MIPMAP_NEAREST:
- sample_cube_nearest_mipmap_nearest(ctx, tObj, s[i], t[i], u[i],
- lambda[i], rgba[i]);
- break;
- case GL_LINEAR_MIPMAP_NEAREST:
- sample_cube_linear_mipmap_nearest(ctx, tObj, s[i], t[i], u[i],
- lambda[i], rgba[i]);
- break;
- case GL_NEAREST_MIPMAP_LINEAR:
- sample_cube_nearest_mipmap_linear(ctx, tObj, s[i], t[i], u[i],
- lambda[i], rgba[i]);
- break;
- case GL_LINEAR_MIPMAP_LINEAR:
- sample_cube_linear_mipmap_linear(ctx, tObj, s[i], t[i], u[i],
- lambda[i], rgba[i]);
- break;
- default:
- _mesa_problem(NULL, "Bad min filter in sample_lambda_cube");
- }
+ ASSERT(lambda != NULL);
+ compute_min_mag_ranges(SWRAST_CONTEXT(ctx)->_MinMagThresh[texUnit],
+ n, lambda, &minStart, &minEnd, &magStart, &magEnd);
+
+ if (minStart < minEnd) {
+ /* do the minified texels */
+ const GLuint m = minEnd - minStart;
+ switch (tObj->MinFilter) {
+ case GL_NEAREST:
+ sample_nearest_cube(ctx, texUnit, tObj, m, texcoords + minStart,
+ lambda + minStart, rgba + minStart);
+ break;
+ case GL_LINEAR:
+ sample_linear_cube(ctx, texUnit, tObj, m, texcoords + minStart,
+ lambda + minStart, rgba + minStart);
+ break;
+ case GL_NEAREST_MIPMAP_NEAREST:
+ sample_cube_nearest_mipmap_nearest(ctx, texUnit, tObj, m,
+ texcoords + minStart,
+ lambda + minStart, rgba + minStart);
+ break;
+ case GL_LINEAR_MIPMAP_NEAREST:
+ sample_cube_linear_mipmap_nearest(ctx, texUnit, tObj, m,
+ texcoords + minStart,
+ lambda + minStart, rgba + minStart);
+ break;
+ case GL_NEAREST_MIPMAP_LINEAR:
+ sample_cube_nearest_mipmap_linear(ctx, texUnit, tObj, m,
+ texcoords + minStart,
+ lambda + minStart, rgba + minStart);
+ break;
+ case GL_LINEAR_MIPMAP_LINEAR:
+ sample_cube_linear_mipmap_linear(ctx, texUnit, tObj, m,
+ texcoords + minStart,
+ lambda + minStart, rgba + minStart);
+ break;
+ default:
+ _mesa_problem(ctx, "Bad min filter in sample_lambda_cube");
}
- else {
- /* magnification */
- const struct gl_texture_image **images;
- GLfloat newS, newT;
- images = choose_cube_face(tObj, s[i], t[i], u[i],
- &newS, &newT);
- switch (tObj->MagFilter) {
- case GL_NEAREST:
- sample_2d_nearest(ctx, tObj, images[tObj->BaseLevel],
- newS, newT, rgba[i]);
- break;
- case GL_LINEAR:
- sample_2d_linear(ctx, tObj, images[tObj->BaseLevel],
- newS, newT, rgba[i]);
- break;
- default:
- _mesa_problem(NULL, "Bad mag filter in sample_lambda_cube");
- }
+ }
+
+ if (magStart < magEnd) {
+ /* do the magnified texels */
+ const GLuint m = magEnd - magStart;
+ switch (tObj->MagFilter) {
+ case GL_NEAREST:
+ sample_nearest_cube(ctx, texUnit, tObj, m, texcoords + magStart,
+ lambda + magStart, rgba + magStart);
+ break;
+ case GL_LINEAR:
+ sample_linear_cube(ctx, texUnit, tObj, m, texcoords + magStart,
+ lambda + magStart, rgba + magStart);
+ break;
+ default:
+ _mesa_problem(ctx, "Bad mag filter in sample_lambda_cube");
}
}
}
-
/**********************************************************************/
/* Texture Rectangle Sampling Functions */
/**********************************************************************/
@@ -1767,8 +2075,7 @@ sample_lambda_cube( GLcontext *ctx, GLuint texUnit,
static void
sample_nearest_rect(GLcontext *ctx, GLuint texUnit,
const struct gl_texture_object *tObj, GLuint n,
- const GLfloat s[], const GLfloat t[],
- const GLfloat u[], const GLfloat lambda[],
+ GLfloat texcoords[][4], const GLfloat lambda[],
GLchan rgba[][4])
{
const struct gl_texture_image *img = tObj->Image[0];
@@ -1783,10 +2090,10 @@ sample_nearest_rect(GLcontext *ctx, GLuint texUnit,
ASSERT(tObj->WrapS == GL_CLAMP ||
tObj->WrapS == GL_CLAMP_TO_EDGE ||
- tObj->WrapS == GL_CLAMP_TO_BORDER_ARB);
+ tObj->WrapS == GL_CLAMP_TO_BORDER);
ASSERT(tObj->WrapT == GL_CLAMP ||
tObj->WrapT == GL_CLAMP_TO_EDGE ||
- tObj->WrapT == GL_CLAMP_TO_BORDER_ARB);
+ tObj->WrapT == GL_CLAMP_TO_BORDER);
ASSERT(img->Format != GL_COLOR_INDEX);
/* XXX move Wrap mode tests outside of loops for common cases */
@@ -1794,22 +2101,22 @@ sample_nearest_rect(GLcontext *ctx, GLuint texUnit,
GLint row, col;
/* NOTE: we DO NOT use [0, 1] texture coordinates! */
if (tObj->WrapS == GL_CLAMP) {
- col = IFLOOR( CLAMP(s[i], 0.0F, width) );
+ col = IFLOOR( CLAMP(texcoords[i][0], 0.0F, width) );
}
else if (tObj->WrapS == GL_CLAMP_TO_EDGE) {
- col = IFLOOR( CLAMP(s[i], 0.5F, width - 0.5F) );
+ col = IFLOOR( CLAMP(texcoords[i][0], 0.5F, width - 0.5F) );
}
else {
- col = IFLOOR( CLAMP(s[i], -0.5F, width + 0.5F) );
+ col = IFLOOR( CLAMP(texcoords[i][0], -0.5F, width + 0.5F) );
}
if (tObj->WrapT == GL_CLAMP) {
- row = IFLOOR( CLAMP(t[i], 0.0F, height) );
+ row = IFLOOR( CLAMP(texcoords[i][1], 0.0F, height) );
}
else if (tObj->WrapT == GL_CLAMP_TO_EDGE) {
- row = IFLOOR( CLAMP(t[i], 0.5F, height - 0.5F) );
+ row = IFLOOR( CLAMP(texcoords[i][1], 0.5F, height - 0.5F) );
}
else {
- row = IFLOOR( CLAMP(t[i], -0.5F, height + 0.5F) );
+ row = IFLOOR( CLAMP(texcoords[i][1], -0.5F, height + 0.5F) );
}
col = CLAMP(col, 0, width_minus_1);
@@ -1823,9 +2130,8 @@ sample_nearest_rect(GLcontext *ctx, GLuint texUnit,
static void
sample_linear_rect(GLcontext *ctx, GLuint texUnit,
const struct gl_texture_object *tObj, GLuint n,
- const GLfloat s[], const GLfloat t[],
- const GLfloat u[], const GLfloat lambda[],
- GLchan rgba[][4])
+ GLfloat texcoords[][4],
+ const GLfloat lambda[], GLchan rgba[][4])
{
const struct gl_texture_image *img = tObj->Image[0];
const GLfloat width = (GLfloat) img->Width;
@@ -1839,10 +2145,10 @@ sample_linear_rect(GLcontext *ctx, GLuint texUnit,
ASSERT(tObj->WrapS == GL_CLAMP ||
tObj->WrapS == GL_CLAMP_TO_EDGE ||
- tObj->WrapS == GL_CLAMP_TO_BORDER_ARB);
+ tObj->WrapS == GL_CLAMP_TO_BORDER);
ASSERT(tObj->WrapT == GL_CLAMP ||
tObj->WrapT == GL_CLAMP_TO_EDGE ||
- tObj->WrapT == GL_CLAMP_TO_BORDER_ARB);
+ tObj->WrapT == GL_CLAMP_TO_BORDER);
ASSERT(img->Format != GL_COLOR_INDEX);
/* XXX lots of opportunity for optimization in this loop */
@@ -1854,22 +2160,22 @@ sample_linear_rect(GLcontext *ctx, GLuint texUnit,
/* NOTE: we DO NOT use [0, 1] texture coordinates! */
if (tObj->WrapS == GL_CLAMP) {
- fcol = CLAMP(s[i], 0.0F, width);
+ fcol = CLAMP(texcoords[i][0], 0.0F, width);
}
else if (tObj->WrapS == GL_CLAMP_TO_EDGE) {
- fcol = CLAMP(s[i], 0.5F, width - 0.5F);
+ fcol = CLAMP(texcoords[i][0], 0.5F, width - 0.5F);
}
else {
- fcol = CLAMP(s[i], -0.5F, width + 0.5F);
+ fcol = CLAMP(texcoords[i][0], -0.5F, width + 0.5F);
}
if (tObj->WrapT == GL_CLAMP) {
- frow = CLAMP(t[i], 0.0F, height);
+ frow = CLAMP(texcoords[i][1], 0.0F, height);
}
else if (tObj->WrapT == GL_CLAMP_TO_EDGE) {
- frow = CLAMP(t[i], 0.5F, height - 0.5F);
+ frow = CLAMP(texcoords[i][1], 0.5F, height - 0.5F);
}
else {
- frow = CLAMP(t[i], -0.5F, height + 0.5F);
+ frow = CLAMP(texcoords[i][1], -0.5F, height + 0.5F);
}
/* compute integer rows/columns */
@@ -1897,92 +2203,456 @@ sample_linear_rect(GLcontext *ctx, GLuint texUnit,
w11 = a * b ;
/* compute weighted average of samples */
- rgba[i][0] = w00 * t00[0] + w10 * t10[0] + w01 * t01[0] + w11 * t11[0];
- rgba[i][1] = w00 * t00[1] + w10 * t10[1] + w01 * t01[1] + w11 * t11[1];
- rgba[i][2] = w00 * t00[2] + w10 * t10[2] + w01 * t01[2] + w11 * t11[2];
- rgba[i][3] = w00 * t00[3] + w10 * t10[3] + w01 * t01[3] + w11 * t11[3];
+ rgba[i][0] =
+ (GLchan) (w00 * t00[0] + w10 * t10[0] + w01 * t01[0] + w11 * t11[0]);
+ rgba[i][1] =
+ (GLchan) (w00 * t00[1] + w10 * t10[1] + w01 * t01[1] + w11 * t11[1]);
+ rgba[i][2] =
+ (GLchan) (w00 * t00[2] + w10 * t10[2] + w01 * t01[2] + w11 * t11[2]);
+ rgba[i][3] =
+ (GLchan) (w00 * t00[3] + w10 * t10[3] + w01 * t01[3] + w11 * t11[3]);
}
}
-
static void
sample_lambda_rect( GLcontext *ctx, GLuint texUnit,
const struct gl_texture_object *tObj, GLuint n,
- const GLfloat s[], const GLfloat t[],
- const GLfloat u[], const GLfloat lambda[],
+ GLfloat texcoords[][4], const GLfloat lambda[],
GLchan rgba[][4])
{
- const GLfloat minMagThresh = SWRAST_CONTEXT(ctx)->_MinMagThresh[texUnit];
- GLuint i;
+ GLuint minStart, minEnd, magStart, magEnd;
- {
+ /* We only need lambda to decide between minification and magnification.
+ * There is no mipmapping with rectangular textures.
+ */
+ compute_min_mag_ranges(SWRAST_CONTEXT(ctx)->_MinMagThresh[texUnit],
+ n, lambda, &minStart, &minEnd, &magStart, &magEnd);
+
+ if (minStart < minEnd) {
+ if (tObj->MinFilter == GL_NEAREST) {
+ sample_nearest_rect( ctx, texUnit, tObj, minEnd - minStart,
+ texcoords + minStart, NULL, rgba + minStart);
+ }
+ else {
+ sample_linear_rect( ctx, texUnit, tObj, minEnd - minStart,
+ texcoords + minStart, NULL, rgba + minStart);
+ }
+ }
+ if (magStart < magEnd) {
+ if (tObj->MagFilter == GL_NEAREST) {
+ sample_nearest_rect( ctx, texUnit, tObj, magEnd - magStart,
+ texcoords + magStart, NULL, rgba + magStart);
+ }
+ else {
+ sample_linear_rect( ctx, texUnit, tObj, magEnd - magStart,
+ texcoords + magStart, NULL, rgba + magStart);
+ }
+ }
+}
+
+
+
+/*
+ * Sample a shadow/depth texture.
+ */
+static void
+sample_depth_texture( GLcontext *ctx, GLuint unit,
+ const struct gl_texture_object *tObj, GLuint n,
+ GLfloat texcoords[][4], const GLfloat lambda[],
+ GLchan texel[][4] )
+{
+ const GLint baseLevel = tObj->BaseLevel;
+ const struct gl_texture_image *texImage = tObj->Image[baseLevel];
+ const GLuint width = texImage->Width;
+ const GLuint height = texImage->Height;
+ GLchan ambient;
+ GLenum function;
+ GLchan result;
+
+ (void) unit;
+
+ ASSERT(tObj->Image[tObj->BaseLevel]->Format == GL_DEPTH_COMPONENT);
+ ASSERT(tObj->Target == GL_TEXTURE_1D ||
+ tObj->Target == GL_TEXTURE_2D ||
+ tObj->Target == GL_TEXTURE_RECTANGLE_NV);
+
+ 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 */
+ }
+
+ if (tObj->MagFilter == GL_NEAREST) {
+ GLuint i;
for (i = 0; i < n; i++) {
- GLfloat coord[4];
- coord[0] = s[i];
- coord[1] = t[i];
- coord[2] = u[i];
- coord[3] = 1.0;
- if (lambda[i] > minMagThresh) {
- /* minification */
- switch (tObj->MinFilter) {
- case GL_NEAREST:
- sample_nearest_rect(ctx, texUnit, tObj, 1,
- s + i, t + i, u + i, lambda + i,
- rgba + i );
- break;
- case GL_LINEAR:
- sample_linear_rect(ctx, texUnit, tObj, 1,
- s + i, t + i, u + i, lambda + i,
- rgba + i );
- break;
- default:
- _mesa_problem(NULL, "Bad min filter in sample_lambda_rect");
- return;
+ 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);
+ depthSample = *((const GLfloat *) texImage->Data + row * width + col);
+
+ switch (function) {
+ case GL_LEQUAL:
+ result = (texcoords[i][2] <= depthSample) ? CHAN_MAX : ambient;
+ break;
+ case GL_GEQUAL:
+ result = (texcoords[i][2] >= depthSample) ? CHAN_MAX : ambient;
+ break;
+ case GL_LESS:
+ result = (texcoords[i][2] < depthSample) ? CHAN_MAX : ambient;
+ break;
+ case GL_GREATER:
+ result = (texcoords[i][2] > depthSample) ? CHAN_MAX : ambient;
+ break;
+ case GL_EQUAL:
+ result = (texcoords[i][2] == depthSample) ? CHAN_MAX : ambient;
+ break;
+ case GL_NOTEQUAL:
+ result = (texcoords[i][2] != depthSample) ? CHAN_MAX : ambient;
+ break;
+ case GL_ALWAYS:
+ result = CHAN_MAX;
+ break;
+ case GL_NEVER:
+ result = ambient;
+ break;
+ case GL_NONE:
+ CLAMPED_FLOAT_TO_CHAN(result, depthSample);
+ break;
+ default:
+ _mesa_problem(ctx, "Bad compare func in sample_depth_texture");
+ return;
+ }
+
+ switch (tObj->DepthMode) {
+ case GL_LUMINANCE:
+ texel[i][RCOMP] = result;
+ texel[i][GCOMP] = result;
+ texel[i][BCOMP] = result;
+ texel[i][ACOMP] = CHAN_MAX;
+ break;
+ case GL_INTENSITY:
+ texel[i][RCOMP] = result;
+ texel[i][GCOMP] = result;
+ texel[i][BCOMP] = result;
+ texel[i][ACOMP] = result;
+ break;
+ case GL_ALPHA:
+ texel[i][RCOMP] = 0;
+ texel[i][GCOMP] = 0;
+ texel[i][BCOMP] = 0;
+ texel[i][ACOMP] = result;
+ break;
+ default:
+ _mesa_problem(ctx, "Bad depth texture mode");
+ }
+ }
+ }
+ else {
+ GLuint i;
+ ASSERT(tObj->MagFilter == GL_LINEAR);
+ for (i = 0; i < n; i++) {
+ GLfloat depth00, depth01, depth10, depth11;
+ GLint i0, i1, j0, j1;
+ 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);
+
+ useBorderTexel = 0;
+ if (texImage->Border) {
+ i0 += texImage->Border;
+ i1 += texImage->Border;
+ j0 += texImage->Border;
+ j1 += texImage->Border;
+ }
+ else {
+ if (i0 < 0 || i0 >= (GLint) width) useBorderTexel |= I0BIT;
+ if (i1 < 0 || i1 >= (GLint) width) useBorderTexel |= I1BIT;
+ if (j0 < 0 || j0 >= (GLint) height) useBorderTexel |= J0BIT;
+ if (j1 < 0 || j1 >= (GLint) height) useBorderTexel |= J1BIT;
+ }
+
+ /* get four depth samples from the texture */
+ if (useBorderTexel & (I0BIT | J0BIT)) {
+ depth00 = 1.0;
+ }
+ else {
+ depth00 = *((const GLfloat *) texImage->Data + j0 * width + i0);
+ }
+ if (useBorderTexel & (I1BIT | J0BIT)) {
+ depth10 = 1.0;
+ }
+ else {
+ depth10 = *((const GLfloat *) texImage->Data + j0 * width + i1);
+ }
+ if (useBorderTexel & (I0BIT | J1BIT)) {
+ depth01 = 1.0;
+ }
+ else {
+ depth01 = *((const GLfloat *) texImage->Data + j1 * width + i0);
+ }
+ if (useBorderTexel & (I1BIT | J1BIT)) {
+ depth11 = 1.0;
+ }
+ else {
+ depth11 = *((const GLfloat *) texImage->Data + j1 * width + i1);
+ }
+
+ if (0) {
+ /* compute a single weighted depth sample and do one comparison */
+ const GLfloat a = FRAC(u + 1.0F);
+ const GLfloat b = FRAC(v + 1.0F);
+ const GLfloat w00 = (1.0F - a) * (1.0F - b);
+ const GLfloat w10 = ( a) * (1.0F - b);
+ const GLfloat w01 = (1.0F - a) * ( b);
+ const GLfloat w11 = ( a) * ( b);
+ const GLfloat depthSample = w00 * depth00 + w10 * depth10
+ + w01 * depth01 + w11 * depth11;
+ if ((depthSample <= texcoords[i][2] && function == GL_LEQUAL) ||
+ (depthSample >= texcoords[i][2] && function == GL_GEQUAL)) {
+ result = ambient;
+ }
+ else {
+ result = CHAN_MAX;
}
}
else {
- /* magnification */
- switch (tObj->MagFilter) {
- case GL_NEAREST:
- sample_nearest_rect(ctx, texUnit, tObj, 1,
- s + i, t + i, u + i, lambda + i,
- rgba + i );
- break;
- case GL_LINEAR:
- sample_linear_rect(ctx, texUnit, tObj, 1,
- s + i, t + i, u + i, lambda + i,
- rgba + i );
- break;
- default:
- _mesa_problem(NULL, "Bad mag filter in sample_lambda_rect");
- return;
+ /* Do four depth/R comparisons and compute a weighted result.
+ * If this touches on somebody's I.P., I'll remove this code
+ * upon request.
+ */
+ const GLfloat d = (CHAN_MAXF - (GLfloat) ambient) * 0.25F;
+ GLfloat luminance = CHAN_MAXF;
+
+ 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;
+ 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;
+ 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;
+ 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;
+ 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;
+ 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;
+ result = (GLchan) luminance;
+ break;
+ case GL_ALWAYS:
+ result = 0;
+ break;
+ case GL_NEVER:
+ result = CHAN_MAX;
+ break;
+ case GL_NONE:
+ /* ordinary bilinear filtering */
+ {
+ const GLfloat a = FRAC(u + 1.0F);
+ const GLfloat b = FRAC(v + 1.0F);
+ const GLfloat w00 = (1.0F - a) * (1.0F - b);
+ const GLfloat w10 = ( a) * (1.0F - b);
+ const GLfloat w01 = (1.0F - a) * ( b);
+ const GLfloat w11 = ( a) * ( b);
+ const GLfloat depthSample = w00 * depth00 + w10 * depth10
+ + w01 * depth01 + w11 * depth11;
+ CLAMPED_FLOAT_TO_CHAN(result, depthSample);
+ }
+ break;
+ default:
+ _mesa_problem(ctx, "Bad compare func in sample_depth_texture");
+ return;
}
}
- }
- }
+ switch (tObj->DepthMode) {
+ case GL_LUMINANCE:
+ texel[i][RCOMP] = result;
+ texel[i][GCOMP] = result;
+ texel[i][BCOMP] = result;
+ texel[i][ACOMP] = CHAN_MAX;
+ break;
+ case GL_INTENSITY:
+ texel[i][RCOMP] = result;
+ texel[i][GCOMP] = result;
+ texel[i][BCOMP] = result;
+ texel[i][ACOMP] = result;
+ break;
+ case GL_ALPHA:
+ texel[i][RCOMP] = 0;
+ texel[i][GCOMP] = 0;
+ texel[i][BCOMP] = 0;
+ texel[i][ACOMP] = result;
+ break;
+ default:
+ _mesa_problem(ctx, "Bad depth texture mode");
+ }
+ } /* for */
+ } /* if filter */
}
+#if 0
+/*
+ * Experimental depth texture sampling function.
+ */
+static void
+sample_depth_texture2(const GLcontext *ctx,
+ const struct gl_texture_unit *texUnit,
+ GLuint n, GLfloat texcoords[][4],
+ GLchan texel[][4])
+{
+ const struct gl_texture_object *texObj = texUnit->_Current;
+ const GLint baseLevel = texObj->BaseLevel;
+ const struct gl_texture_image *texImage = texObj->Image[baseLevel];
+ const GLuint width = texImage->Width;
+ const GLuint height = texImage->Height;
+ GLchan ambient;
+ GLboolean lequal, gequal;
+
+ if (texObj->Target != GL_TEXTURE_2D) {
+ _mesa_problem(ctx, "only 2-D depth textures supported at this time");
+ return;
+ }
+
+ if (texObj->MinFilter != texObj->MagFilter) {
+ _mesa_problem(ctx, "mipmapped depth textures not supported at this time");
+ return;
+ }
+
+ /* XXX the GL_SGIX_shadow extension spec doesn't say what to do if
+ * GL_TEXTURE_COMPARE_SGIX == GL_TRUE but the current texture object
+ * isn't a depth texture.
+ */
+ if (texImage->Format != GL_DEPTH_COMPONENT) {
+ _mesa_problem(ctx,"GL_TEXTURE_COMPARE_SGIX enabled with non-depth texture");
+ return;
+ }
+ UNCLAMPED_FLOAT_TO_CHAN(ambient, tObj->ShadowAmbient);
+
+ if (texObj->CompareOperator == GL_TEXTURE_LEQUAL_R_SGIX) {
+ lequal = GL_TRUE;
+ gequal = GL_FALSE;
+ }
+ else {
+ lequal = GL_FALSE;
+ gequal = GL_TRUE;
+ }
+
+ {
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ const GLint K = 3;
+ GLint col, row, ii, jj, imin, imax, jmin, jmax, samples, count;
+ GLfloat w;
+ GLchan lum;
+ COMPUTE_NEAREST_TEXEL_LOCATION(texObj->WrapS, texcoords[i][0],
+ width, col);
+ COMPUTE_NEAREST_TEXEL_LOCATION(texObj->WrapT, texcoords[i][1],
+ height, row);
+
+ imin = col - K;
+ imax = col + K;
+ jmin = row - K;
+ jmax = row + K;
+
+ if (imin < 0) imin = 0;
+ if (imax >= width) imax = width - 1;
+ if (jmin < 0) jmin = 0;
+ if (jmax >= height) jmax = height - 1;
+
+ samples = (imax - imin + 1) * (jmax - jmin + 1);
+ count = 0;
+ for (jj = jmin; jj <= jmax; jj++) {
+ for (ii = imin; ii <= imax; ii++) {
+ GLfloat depthSample = *((const GLfloat *) texImage->Data
+ + jj * width + ii);
+ if ((depthSample <= r[i] && lequal) ||
+ (depthSample >= r[i] && gequal)) {
+ count++;
+ }
+ }
+ }
+
+ w = (GLfloat) count / (GLfloat) samples;
+ w = CHAN_MAXF - w * (CHAN_MAXF - (GLfloat) ambient);
+ lum = (GLint) w;
+
+ texel[i][RCOMP] = lum;
+ texel[i][GCOMP] = lum;
+ texel[i][BCOMP] = lum;
+ texel[i][ACOMP] = CHAN_MAX;
+ }
+ }
+}
+#endif
+
+
+/**
+ * We use this function when a texture object is in an "incomplete" state.
+ */
static void
null_sample_func( GLcontext *ctx, GLuint texUnit,
const struct gl_texture_object *tObj, GLuint n,
- const GLfloat s[], const GLfloat t[],
- const GLfloat u[], const GLfloat lambda[],
+ GLfloat texcoords[][4], const GLfloat lambda[],
GLchan rgba[][4])
{
}
-/**********************************************************************/
-/* Texture Sampling Setup */
-/**********************************************************************/
-
-
-/*
+/**
* Setup the texture sampling function for this texture object.
*/
void
@@ -1991,11 +2661,12 @@ _swrast_choose_texture_sample_func( GLcontext *ctx, GLuint texUnit,
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
- if (!t->Complete) {
- swrast->TextureSample[texUnit] = null_sample_func;
+ if (!t->Complete) {
+ swrast->TextureSample[texUnit] = null_sample_func;
}
else {
- GLboolean needLambda = (GLboolean) (t->MinFilter != t->MagFilter);
+ const GLboolean needLambda = (GLboolean) (t->MinFilter != t->MagFilter);
+ const GLenum format = t->Image[t->BaseLevel]->Format;
if (needLambda) {
/* Compute min/mag filter threshold */
@@ -2011,27 +2682,33 @@ _swrast_choose_texture_sample_func( GLcontext *ctx, GLuint texUnit,
switch (t->Target) {
case GL_TEXTURE_1D:
- if (needLambda) {
+ if (format == GL_DEPTH_COMPONENT) {
+ swrast->TextureSample[texUnit] = sample_depth_texture;
+ }
+ else if (needLambda) {
swrast->TextureSample[texUnit] = sample_lambda_1d;
}
- else if (t->MinFilter==GL_LINEAR) {
+ else if (t->MinFilter == GL_LINEAR) {
swrast->TextureSample[texUnit] = sample_linear_1d;
}
else {
- ASSERT(t->MinFilter==GL_NEAREST);
+ ASSERT(t->MinFilter == GL_NEAREST);
swrast->TextureSample[texUnit] = sample_nearest_1d;
}
break;
case GL_TEXTURE_2D:
- if (needLambda) {
+ if (format == GL_DEPTH_COMPONENT) {
+ swrast->TextureSample[texUnit] = sample_depth_texture;
+ }
+ else if (needLambda) {
swrast->TextureSample[texUnit] = sample_lambda_2d;
}
- else if (t->MinFilter==GL_LINEAR) {
+ else if (t->MinFilter == GL_LINEAR) {
swrast->TextureSample[texUnit] = sample_linear_2d;
}
else {
GLint baseLevel = t->BaseLevel;
- ASSERT(t->MinFilter==GL_NEAREST);
+ ASSERT(t->MinFilter == GL_NEAREST);
if (t->WrapS == GL_REPEAT &&
t->WrapT == GL_REPEAT &&
t->Image[baseLevel]->Border == 0 &&
@@ -2052,23 +2729,23 @@ _swrast_choose_texture_sample_func( GLcontext *ctx, GLuint texUnit,
if (needLambda) {
swrast->TextureSample[texUnit] = sample_lambda_3d;
}
- else if (t->MinFilter==GL_LINEAR) {
+ else if (t->MinFilter == GL_LINEAR) {
swrast->TextureSample[texUnit] = sample_linear_3d;
}
else {
- ASSERT(t->MinFilter==GL_NEAREST);
+ ASSERT(t->MinFilter == GL_NEAREST);
swrast->TextureSample[texUnit] = sample_nearest_3d;
}
break;
- case GL_TEXTURE_CUBE_MAP_ARB:
+ case GL_TEXTURE_CUBE_MAP:
if (needLambda) {
swrast->TextureSample[texUnit] = sample_lambda_cube;
}
- else if (t->MinFilter==GL_LINEAR) {
+ else if (t->MinFilter == GL_LINEAR) {
swrast->TextureSample[texUnit] = sample_linear_cube;
}
else {
- ASSERT(t->MinFilter==GL_NEAREST);
+ ASSERT(t->MinFilter == GL_NEAREST);
swrast->TextureSample[texUnit] = sample_nearest_cube;
}
break;
@@ -2085,7 +2762,7 @@ _swrast_choose_texture_sample_func( GLcontext *ctx, GLuint texUnit,
}
break;
default:
- _mesa_problem(NULL, "invalid dimensions in _mesa_set_texture_sampler");
+ _mesa_problem(ctx, "invalid target in _swrast_choose_texture_sample_func");
}
}
}
@@ -2094,70 +2771,131 @@ _swrast_choose_texture_sample_func( GLcontext *ctx, GLuint texUnit,
#define PROD(A,B) ( (GLuint)(A) * ((GLuint)(B)+1) )
#define S_PROD(A,B) ( (GLint)(A) * ((GLint)(B)+1) )
+
+/**
+ * Do texture application for GL_ARB/EXT_texture_env_combine.
+ * This function also supports GL_{EXT,ARB}_texture_env_dot3 and
+ * GL_ATI_texture_env_combine3
+ *
+ * \param ctx rendering context
+ * \param textureUnit the texture unit to apply
+ * \param n number of fragments to process (span width)
+ * \param primary_rgba incoming fragment color array
+ * \param texelBuffer pointer to texel colors for all texture units
+ *
+ * \param rgba incoming colors, which get modified here
+ */
static INLINE void
-texture_combine(const GLcontext *ctx,
- const struct gl_texture_unit *textureUnit,
- GLuint n,
- CONST GLchan (*primary_rgba)[4],
- CONST GLchan (*texel)[4],
- GLchan (*rgba)[4])
+texture_combine( const GLcontext *ctx, GLuint unit, GLuint n,
+ CONST GLchan (*primary_rgba)[4],
+ CONST GLchan *texelBuffer,
+ GLchan (*rgba)[4] )
{
+ const struct gl_texture_unit *textureUnit = &(ctx->Texture.Unit[unit]);
const GLchan (*argRGB [3])[4];
const GLchan (*argA [3])[4];
- GLuint i, j;
const GLuint RGBshift = textureUnit->CombineScaleShiftRGB;
const GLuint Ashift = textureUnit->CombineScaleShiftA;
#if CHAN_TYPE == GL_FLOAT
const GLchan RGBmult = (GLfloat) (1 << RGBshift);
const GLchan Amult = (GLfloat) (1 << Ashift);
+ static const GLchan one[4] = { 1.0, 1.0, 1.0, 1.0 };
+ static const GLchan zero[4] = { 0.0, 0.0, 0.0, 0.0 };
#else
const GLint half = (CHAN_MAX + 1) / 2;
+ static const GLchan one[4] = { CHAN_MAX, CHAN_MAX, CHAN_MAX, CHAN_MAX };
+ static const GLchan zero[4] = { 0, 0, 0, 0 };
#endif
+ GLuint i, j;
+ GLuint numColorArgs;
+ GLuint numAlphaArgs;
+ /* GLchan ccolor[3][4]; */
DEFMNARRAY(GLchan, ccolor, 3, 3 * MAX_WIDTH, 4); /* mac 32k limitation */
CHECKARRAY(ccolor, return); /* mac 32k limitation */
ASSERT(ctx->Extensions.EXT_texture_env_combine ||
ctx->Extensions.ARB_texture_env_combine);
+ ASSERT(SWRAST_CONTEXT(ctx)->_AnyTextureCombine);
+
+
+ /*
+ printf("modeRGB 0x%x modeA 0x%x srcRGB1 0x%x srcA1 0x%x srcRGB2 0x%x srcA2 0x%x\n",
+ textureUnit->CombineModeRGB,
+ textureUnit->CombineModeA,
+ textureUnit->CombineSourceRGB[0],
+ textureUnit->CombineSourceA[0],
+ textureUnit->CombineSourceRGB[1],
+ textureUnit->CombineSourceA[1]);
+ */
/*
* Do operand setup for up to 3 operands. Loop over the terms.
*/
- for (j = 0; j < 3; j++) {
- switch (textureUnit->CombineSourceA[j]) {
- case GL_TEXTURE:
- argA[j] = texel;
- break;
- case GL_PRIMARY_COLOR_EXT:
- argA[j] = primary_rgba;
- break;
- case GL_PREVIOUS_EXT:
- argA[j] = (const GLchan (*)[4]) rgba;
- break;
- case GL_CONSTANT_EXT:
- {
- GLchan alpha, (*c)[4] = ccolor[j];
- UNCLAMPED_FLOAT_TO_CHAN(alpha, textureUnit->EnvColor[3]);
- for (i = 0; i < n; i++)
- c[i][ACOMP] = alpha;
- argA[j] = (const GLchan (*)[4]) ccolor[j];
- }
- break;
- default:
- _mesa_problem(ctx, "invalid combine source");
- }
+ switch (textureUnit->CombineModeRGB) {
+ case GL_REPLACE:
+ numColorArgs = 1;
+ break;
+ case GL_MODULATE:
+ case GL_ADD:
+ case GL_ADD_SIGNED:
+ case GL_SUBTRACT:
+ case GL_DOT3_RGB:
+ case GL_DOT3_RGBA:
+ case GL_DOT3_RGB_EXT:
+ case GL_DOT3_RGBA_EXT:
+ numColorArgs = 2;
+ break;
+ case GL_INTERPOLATE:
+ case GL_MODULATE_ADD_ATI:
+ case GL_MODULATE_SIGNED_ADD_ATI:
+ case GL_MODULATE_SUBTRACT_ATI:
+ numColorArgs = 3;
+ break;
+ default:
+ numColorArgs = 0;
+ ASSERT(0);
+ break;
+ }
+
+ switch (textureUnit->CombineModeA) {
+ case GL_REPLACE:
+ numAlphaArgs = 1;
+ break;
+ case GL_MODULATE:
+ case GL_ADD:
+ case GL_ADD_SIGNED:
+ case GL_SUBTRACT:
+ numAlphaArgs = 2;
+ break;
+ case GL_INTERPOLATE:
+ case GL_MODULATE_ADD_ATI:
+ case GL_MODULATE_SIGNED_ADD_ATI:
+ case GL_MODULATE_SUBTRACT_ATI:
+ numAlphaArgs = 3;
+ break;
+ default:
+ numAlphaArgs = 0;
+ ASSERT(0);
+ break;
+ }
+
+ for (j = 0; j < numColorArgs; j++) {
+ const GLenum srcRGB = textureUnit->CombineSourceRGB[j];
- switch (textureUnit->CombineSourceRGB[j]) {
+
+ switch (srcRGB) {
case GL_TEXTURE:
- argRGB[j] = texel;
+ argRGB[j] = (const GLchan (*)[4])
+ (texelBuffer + unit * (n * 4 * sizeof(GLchan)));
break;
- case GL_PRIMARY_COLOR_EXT:
+ case GL_PRIMARY_COLOR:
argRGB[j] = primary_rgba;
break;
- case GL_PREVIOUS_EXT:
+ case GL_PREVIOUS:
argRGB[j] = (const GLchan (*)[4]) rgba;
break;
- case GL_CONSTANT_EXT:
+ case GL_CONSTANT:
{
GLchan (*c)[4] = ccolor[j];
GLchan red, green, blue, alpha;
@@ -2174,8 +2912,24 @@ texture_combine(const GLcontext *ctx,
argRGB[j] = (const GLchan (*)[4]) ccolor[j];
}
break;
+ /* GL_ATI_texture_env_combine3 allows GL_ZERO & GL_ONE as sources.
+ */
+ case GL_ZERO:
+ argRGB[j] = & zero;
+ break;
+ case GL_ONE:
+ argRGB[j] = & one;
+ break;
default:
- _mesa_problem(ctx, "invalid combine source");
+ /* ARB_texture_env_crossbar source */
+ {
+ const GLuint srcUnit = srcRGB - GL_TEXTURE0;
+ ASSERT(srcUnit < ctx->Const.MaxTextureUnits);
+ if (!ctx->Texture.Unit[srcUnit]._ReallyEnabled)
+ return;
+ argRGB[j] = (const GLchan (*)[4])
+ (texelBuffer + srcUnit * (n * 4 * sizeof(GLchan)));
+ }
}
if (textureUnit->CombineOperandRGB[j] != GL_SRC_COLOR) {
@@ -2208,6 +2962,51 @@ texture_combine(const GLcontext *ctx,
}
}
}
+ }
+
+
+ for (j = 0; j < numAlphaArgs; j++) {
+ const GLenum srcA = textureUnit->CombineSourceA[j];
+
+ switch (srcA) {
+ case GL_TEXTURE:
+ argA[j] = (const GLchan (*)[4])
+ (texelBuffer + unit * (n * 4 * sizeof(GLchan)));
+ break;
+ case GL_PRIMARY_COLOR:
+ argA[j] = primary_rgba;
+ break;
+ case GL_PREVIOUS:
+ argA[j] = (const GLchan (*)[4]) rgba;
+ break;
+ case GL_CONSTANT:
+ {
+ GLchan alpha, (*c)[4] = ccolor[j];
+ UNCLAMPED_FLOAT_TO_CHAN(alpha, textureUnit->EnvColor[3]);
+ for (i = 0; i < n; i++)
+ c[i][ACOMP] = alpha;
+ argA[j] = (const GLchan (*)[4]) ccolor[j];
+ }
+ break;
+ /* GL_ATI_texture_env_combine3 allows GL_ZERO & GL_ONE as sources.
+ */
+ case GL_ZERO:
+ argA[j] = & zero;
+ break;
+ case GL_ONE:
+ argA[j] = & one;
+ break;
+ default:
+ /* ARB_texture_env_crossbar source */
+ {
+ const GLuint srcUnit = srcA - GL_TEXTURE0;
+ ASSERT(srcUnit < ctx->Const.MaxTextureUnits);
+ if (!ctx->Texture.Unit[srcUnit]._ReallyEnabled)
+ return;
+ argA[j] = (const GLchan (*)[4])
+ (texelBuffer + srcUnit * (n * 4 * sizeof(GLchan)));
+ }
+ }
if (textureUnit->CombineOperandA[j] == GL_ONE_MINUS_SRC_ALPHA) {
const GLchan (*src)[4] = argA[j];
@@ -2217,17 +3016,6 @@ texture_combine(const GLcontext *ctx,
dst[i][ACOMP] = CHAN_MAX - src[i][ACOMP];
}
}
-
- if (textureUnit->CombineModeRGB == GL_REPLACE &&
- textureUnit->CombineModeA == GL_REPLACE) {
- break; /* done, we need only arg0 */
- }
-
- if (j == 1 &&
- textureUnit->CombineModeRGB != GL_INTERPOLATE_EXT &&
- textureUnit->CombineModeA != GL_INTERPOLATE_EXT) {
- break; /* arg0 and arg1 are done. we don't need arg2. */
- }
}
/*
@@ -2305,7 +3093,7 @@ texture_combine(const GLcontext *ctx,
}
}
break;
- case GL_ADD_SIGNED_EXT:
+ case GL_ADD_SIGNED:
{
const GLchan (*arg0)[4] = (const GLchan (*)[4]) argRGB[0];
const GLchan (*arg1)[4] = (const GLchan (*)[4]) argRGB[1];
@@ -2328,7 +3116,7 @@ texture_combine(const GLcontext *ctx,
}
}
break;
- case GL_INTERPOLATE_EXT:
+ case GL_INTERPOLATE:
{
const GLchan (*arg0)[4] = (const GLchan (*)[4]) argRGB[0];
const GLchan (*arg1)[4] = (const GLchan (*)[4]) argRGB[1];
@@ -2361,7 +3149,7 @@ texture_combine(const GLcontext *ctx,
}
}
break;
- case GL_SUBTRACT_ARB:
+ case GL_SUBTRACT:
{
const GLchan (*arg0)[4] = (const GLchan (*)[4]) argRGB[0];
const GLchan (*arg1)[4] = (const GLchan (*)[4]) argRGB[1];
@@ -2407,8 +3195,8 @@ texture_combine(const GLcontext *ctx,
}
}
break;
- case GL_DOT3_RGB_ARB:
- case GL_DOT3_RGBA_ARB:
+ case GL_DOT3_RGB:
+ case GL_DOT3_RGBA:
{
/* DO scale the result by 1 2 or 4 */
const GLchan (*arg0)[4] = (const GLchan (*)[4]) argRGB[0];
@@ -2418,8 +3206,8 @@ texture_combine(const GLcontext *ctx,
GLchan dot = ((arg0[i][RCOMP]-0.5F) * (arg1[i][RCOMP]-0.5F) +
(arg0[i][GCOMP]-0.5F) * (arg1[i][GCOMP]-0.5F) +
(arg0[i][BCOMP]-0.5F) * (arg1[i][BCOMP]-0.5F))
- * 4.0F;
- dot = CLAMP(dot, 0.0, CHAN_MAXF) * RGBmult;
+ * 4.0F * RGBmult;
+ dot = CLAMP(dot, 0.0, CHAN_MAXF);
#else
GLint dot = (S_PROD((GLint)arg0[i][RCOMP] - half,
(GLint)arg1[i][RCOMP] - half) +
@@ -2427,12 +3215,100 @@ texture_combine(const GLcontext *ctx,
(GLint)arg1[i][GCOMP] - half) +
S_PROD((GLint)arg0[i][BCOMP] - half,
(GLint)arg1[i][BCOMP] - half)) >> 6;
- dot = CLAMP(dot, 0, CHAN_MAX) << RGBshift;
+ dot <<= RGBshift;
+ dot = CLAMP(dot, 0, CHAN_MAX);
#endif
rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = (GLchan) dot;
}
}
break;
+ case GL_MODULATE_ADD_ATI:
+ {
+ const GLchan (*arg0)[4] = (const GLchan (*)[4]) argRGB[0];
+ const GLchan (*arg1)[4] = (const GLchan (*)[4]) argRGB[1];
+ const GLchan (*arg2)[4] = (const GLchan (*)[4]) argRGB[2];
+#if CHAN_TYPE != GL_FLOAT
+ const GLint shift = CHAN_BITS - RGBshift;
+#endif
+ for (i = 0; i < n; i++) {
+#if CHAN_TYPE == GL_FLOAT
+ rgba[i][RCOMP] = ((arg0[i][RCOMP] * arg2[i][RCOMP]) + arg1[i][RCOMP]) * RGBmult;
+ rgba[i][GCOMP] = ((arg0[i][GCOMP] * arg2[i][GCOMP]) + arg1[i][GCOMP]) * RGBmult;
+ rgba[i][BCOMP] = ((arg0[i][BCOMP] * arg2[i][BCOMP]) + arg1[i][BCOMP]) * RGBmult;
+#else
+ GLuint r = (PROD(arg0[i][RCOMP], arg2[i][RCOMP])
+ + ((GLuint) arg1[i][RCOMP] << CHAN_BITS)) >> shift;
+ GLuint g = (PROD(arg0[i][GCOMP], arg2[i][GCOMP])
+ + ((GLuint) arg1[i][GCOMP] << CHAN_BITS)) >> shift;
+ GLuint b = (PROD(arg0[i][BCOMP], arg2[i][BCOMP])
+ + ((GLuint) arg1[i][BCOMP] << CHAN_BITS)) >> shift;
+ rgba[i][RCOMP] = (GLchan) MIN2(r, CHAN_MAX);
+ rgba[i][GCOMP] = (GLchan) MIN2(g, CHAN_MAX);
+ rgba[i][BCOMP] = (GLchan) MIN2(b, CHAN_MAX);
+#endif
+ }
+ }
+ break;
+ case GL_MODULATE_SIGNED_ADD_ATI:
+ {
+ const GLchan (*arg0)[4] = (const GLchan (*)[4]) argRGB[0];
+ const GLchan (*arg1)[4] = (const GLchan (*)[4]) argRGB[1];
+ const GLchan (*arg2)[4] = (const GLchan (*)[4]) argRGB[2];
+#if CHAN_TYPE != GL_FLOAT
+ const GLint shift = CHAN_BITS - RGBshift;
+#endif
+ for (i = 0; i < n; i++) {
+#if CHAN_TYPE == GL_FLOAT
+ rgba[i][RCOMP] = ((arg0[i][RCOMP] * arg2[i][RCOMP]) + arg1[i][RCOMP] - 0.5) * RGBmult;
+ rgba[i][GCOMP] = ((arg0[i][GCOMP] * arg2[i][GCOMP]) + arg1[i][GCOMP] - 0.5) * RGBmult;
+ rgba[i][BCOMP] = ((arg0[i][BCOMP] * arg2[i][BCOMP]) + arg1[i][BCOMP] - 0.5) * RGBmult;
+#else
+ GLint r = (S_PROD(arg0[i][RCOMP], arg2[i][RCOMP])
+ + (((GLint) arg1[i][RCOMP] - half) << CHAN_BITS))
+ >> shift;
+ GLint g = (S_PROD(arg0[i][GCOMP], arg2[i][GCOMP])
+ + (((GLint) arg1[i][GCOMP] - half) << CHAN_BITS))
+ >> shift;
+ GLint b = (S_PROD(arg0[i][BCOMP], arg2[i][BCOMP])
+ + (((GLint) arg1[i][BCOMP] - half) << CHAN_BITS))
+ >> shift;
+ rgba[i][RCOMP] = (GLchan) CLAMP(r, 0, CHAN_MAX);
+ rgba[i][GCOMP] = (GLchan) CLAMP(g, 0, CHAN_MAX);
+ rgba[i][BCOMP] = (GLchan) CLAMP(b, 0, CHAN_MAX);
+#endif
+ }
+ }
+ break;
+ case GL_MODULATE_SUBTRACT_ATI:
+ {
+ const GLchan (*arg0)[4] = (const GLchan (*)[4]) argRGB[0];
+ const GLchan (*arg1)[4] = (const GLchan (*)[4]) argRGB[1];
+ const GLchan (*arg2)[4] = (const GLchan (*)[4]) argRGB[2];
+#if CHAN_TYPE != GL_FLOAT
+ const GLint shift = CHAN_BITS - RGBshift;
+#endif
+ for (i = 0; i < n; i++) {
+#if CHAN_TYPE == GL_FLOAT
+ rgba[i][RCOMP] = ((arg0[i][RCOMP] * arg2[i][RCOMP]) - arg1[i][RCOMP]) * RGBmult;
+ rgba[i][GCOMP] = ((arg0[i][GCOMP] * arg2[i][GCOMP]) - arg1[i][GCOMP]) * RGBmult;
+ rgba[i][BCOMP] = ((arg0[i][BCOMP] * arg2[i][BCOMP]) - arg1[i][BCOMP]) * RGBmult;
+#else
+ GLint r = (S_PROD(arg0[i][RCOMP], arg2[i][RCOMP])
+ - ((GLint) arg1[i][RCOMP] << CHAN_BITS))
+ >> shift;
+ GLint g = (S_PROD(arg0[i][GCOMP], arg2[i][GCOMP])
+ - ((GLint) arg1[i][GCOMP] << CHAN_BITS))
+ >> shift;
+ GLint b = (S_PROD(arg0[i][BCOMP], arg2[i][BCOMP])
+ - ((GLint) arg1[i][BCOMP] << CHAN_BITS))
+ >> shift;
+ rgba[i][RCOMP] = (GLchan) CLAMP(r, 0, CHAN_MAX);
+ rgba[i][GCOMP] = (GLchan) CLAMP(g, 0, CHAN_MAX);
+ rgba[i][BCOMP] = (GLchan) CLAMP(b, 0, CHAN_MAX);
+#endif
+ }
+ }
+ break;
default:
_mesa_problem(ctx, "invalid combine mode");
}
@@ -2489,7 +3365,7 @@ texture_combine(const GLcontext *ctx,
}
}
break;
- case GL_ADD_SIGNED_EXT:
+ case GL_ADD_SIGNED:
{
const GLchan (*arg0)[4] = (const GLchan (*)[4]) argA[0];
const GLchan (*arg1)[4] = (const GLchan (*)[4]) argA[1];
@@ -2504,7 +3380,7 @@ texture_combine(const GLcontext *ctx,
}
}
break;
- case GL_INTERPOLATE_EXT:
+ case GL_INTERPOLATE:
{
const GLchan (*arg0)[4] = (const GLchan (*)[4]) argA[0];
const GLchan (*arg1)[4] = (const GLchan (*)[4]) argA[1];
@@ -2526,7 +3402,7 @@ texture_combine(const GLcontext *ctx,
}
}
break;
- case GL_SUBTRACT_ARB:
+ case GL_SUBTRACT:
{
const GLchan (*arg0)[4] = (const GLchan (*)[4]) argA[0];
const GLchan (*arg1)[4] = (const GLchan (*)[4]) argA[1];
@@ -2540,7 +3416,66 @@ texture_combine(const GLcontext *ctx,
}
}
break;
-
+ case GL_MODULATE_ADD_ATI:
+ {
+ const GLchan (*arg0)[4] = (const GLchan (*)[4]) argA[0];
+ const GLchan (*arg1)[4] = (const GLchan (*)[4]) argA[1];
+ const GLchan (*arg2)[4] = (const GLchan (*)[4]) argA[2];
+#if CHAN_TYPE != GL_FLOAT
+ const GLint shift = CHAN_BITS - Ashift;
+#endif
+ for (i = 0; i < n; i++) {
+#if CHAN_TYPE == GL_FLOAT
+ rgba[i][ACOMP] = ((arg0[i][ACOMP] * arg2[i][ACOMP]) + arg1[i][ACOMP]) * Amult;
+#else
+ GLuint a = (PROD(arg0[i][ACOMP], arg2[i][ACOMP])
+ + ((GLuint) arg1[i][ACOMP] << CHAN_BITS))
+ >> shift;
+ rgba[i][ACOMP] = (GLchan) CLAMP(a, 0, CHAN_MAX);
+#endif
+ }
+ }
+ break;
+ case GL_MODULATE_SIGNED_ADD_ATI:
+ {
+ const GLchan (*arg0)[4] = (const GLchan (*)[4]) argA[0];
+ const GLchan (*arg1)[4] = (const GLchan (*)[4]) argA[1];
+ const GLchan (*arg2)[4] = (const GLchan (*)[4]) argA[2];
+#if CHAN_TYPE != GL_FLOAT
+ const GLint shift = CHAN_BITS - Ashift;
+#endif
+ for (i = 0; i < n; i++) {
+#if CHAN_TYPE == GL_FLOAT
+ rgba[i][ACOMP] = ((arg0[i][ACOMP] * arg2[i][ACOMP]) + arg1[i][ACOMP] - 0.5F) * Amult;
+#else
+ GLint a = (S_PROD(arg0[i][ACOMP], arg2[i][ACOMP])
+ + (((GLint) arg1[i][ACOMP] - half) << CHAN_BITS))
+ >> shift;
+ rgba[i][ACOMP] = (GLchan) CLAMP(a, 0, CHAN_MAX);
+#endif
+ }
+ }
+ break;
+ case GL_MODULATE_SUBTRACT_ATI:
+ {
+ const GLchan (*arg0)[4] = (const GLchan (*)[4]) argA[0];
+ const GLchan (*arg1)[4] = (const GLchan (*)[4]) argA[1];
+ const GLchan (*arg2)[4] = (const GLchan (*)[4]) argA[2];
+#if CHAN_TYPE != GL_FLOAT
+ const GLint shift = CHAN_BITS - Ashift;
+#endif
+ for (i = 0; i < n; i++) {
+#if CHAN_TYPE == GL_FLOAT
+ rgba[i][ACOMP] = ((arg0[i][ACOMP] * arg2[i][ACOMP]) - arg1[i][ACOMP]) * Amult;
+#else
+ GLint a = (S_PROD(arg0[i][ACOMP], arg2[i][ACOMP])
+ - ((GLint) arg1[i][ACOMP] << CHAN_BITS))
+ >> shift;
+ rgba[i][ACOMP] = (GLchan) CLAMP(a, 0, CHAN_MAX);
+#endif
+ }
+ }
+ break;
default:
_mesa_problem(ctx, "invalid combine mode");
}
@@ -2551,7 +3486,7 @@ texture_combine(const GLcontext *ctx,
* GL_DOT3.
*/
if (textureUnit->CombineModeRGB == GL_DOT3_RGBA_EXT ||
- textureUnit->CombineModeRGB == GL_DOT3_RGBA_ARB) {
+ textureUnit->CombineModeRGB == GL_DOT3_RGBA) {
for (i = 0; i < n; i++) {
rgba[i][ACOMP] = rgba[i][RCOMP];
}
@@ -2561,14 +3496,23 @@ texture_combine(const GLcontext *ctx,
#undef PROD
+/**
+ * Implement NVIDIA's GL_NV_texture_env_combine4 extension when
+ * texUnit->EnvMode == GL_COMBINE4_NV.
+ */
+static INLINE void
+texture_combine4( const GLcontext *ctx, GLuint unit, GLuint n,
+ CONST GLchan (*primary_rgba)[4],
+ CONST GLchan *texelBuffer,
+ GLchan (*rgba)[4] )
+{
+}
-/**********************************************************************/
-/* Texture Application */
-/**********************************************************************/
-/*
- * Combine incoming fragment color with texel color to produce output color.
+/**
+ * Apply a conventional OpenGL texture env mode (REPLACE, ADD, BLEND,
+ * MODULATE, or DECAL) to an array of fragments.
* Input: textureUnit - pointer to texture unit to apply
* format - base internal texture format
* n - number of fragments
@@ -2578,7 +3522,7 @@ texture_combine(const GLcontext *ctx,
* according to the texture environment mode.
*/
static void
-apply_texture( const GLcontext *ctx,
+texture_apply( const GLcontext *ctx,
const struct gl_texture_unit *texUnit,
GLuint n,
CONST GLchan primary_rgba[][4], CONST GLchan texel[][4],
@@ -2597,8 +3541,9 @@ apply_texture( const GLcontext *ctx,
format = texUnit->_Current->Image[baseLevel]->Format;
- if (format==GL_COLOR_INDEX || format==GL_DEPTH_COMPONENT) {
- format = GL_RGBA; /* XXXX a hack! */
+ if (format == GL_COLOR_INDEX || format == GL_DEPTH_COMPONENT
+ || format == GL_YCBCR_MESA) {
+ format = GL_RGBA; /* a bit of a hack */
}
switch (texUnit->EnvMode) {
@@ -2657,7 +3602,7 @@ apply_texture( const GLcontext *ctx,
}
break;
default:
- _mesa_problem(ctx, "Bad format (GL_REPLACE) in apply_texture");
+ _mesa_problem(ctx, "Bad format (GL_REPLACE) in texture_apply");
return;
}
break;
@@ -2723,7 +3668,7 @@ apply_texture( const GLcontext *ctx,
}
break;
default:
- _mesa_problem(ctx, "Bad format (GL_MODULATE) in apply_texture");
+ _mesa_problem(ctx, "Bad format (GL_MODULATE) in texture_apply");
return;
}
break;
@@ -2756,7 +3701,7 @@ apply_texture( const GLcontext *ctx,
}
break;
default:
- _mesa_problem(ctx, "Bad format (GL_DECAL) in apply_texture");
+ _mesa_problem(ctx, "Bad format (GL_DECAL) in texture_apply");
return;
}
break;
@@ -2826,7 +3771,7 @@ apply_texture( const GLcontext *ctx,
}
break;
default:
- _mesa_problem(ctx, "Bad format (GL_BLEND) in apply_texture");
+ _mesa_problem(ctx, "Bad format (GL_BLEND) in texture_apply");
return;
}
break;
@@ -2903,351 +3848,109 @@ apply_texture( const GLcontext *ctx,
}
break;
default:
- _mesa_problem(ctx, "Bad format (GL_ADD) in apply_texture");
+ _mesa_problem(ctx, "Bad format (GL_ADD) in texture_apply");
return;
}
break;
- case GL_COMBINE_EXT:
- texture_combine(ctx, texUnit, n, primary_rgba, texel, rgba);
- break;
-
default:
- _mesa_problem(ctx, "Bad env mode in apply_texture");
+ _mesa_problem(ctx, "Bad env mode in texture_apply");
return;
}
}
-/*
- * Sample a shadow/depth texture.
- * Input: ctx - context
- * texUnit - the texture unit
- * n - number of samples
- * s,t,r - array [n] of texture coordinates
- * In/Out: rgba - array [n] of texel colors.
+/**
+ * Apply texture mapping to a span of fragments.
*/
-static void
-sample_depth_texture(const GLcontext *ctx,
- const struct gl_texture_unit *texUnit,
- GLuint n,
- const GLfloat s[], const GLfloat t[], const GLfloat r[],
- GLchan texel[][4])
+void
+_swrast_texture_span( GLcontext *ctx, struct sw_span *span )
{
- const struct gl_texture_object *texObj = texUnit->_Current;
- const GLint baseLevel = texObj->BaseLevel;
- const struct gl_texture_image *texImage = texObj->Image[baseLevel];
- const GLuint width = texImage->Width;
- const GLuint height = texImage->Height;
- const GLchan ambient = texObj->ShadowAmbient;
- GLboolean lequal, gequal;
+ SWcontext *swrast = SWRAST_CONTEXT(ctx);
+ GLchan primary_rgba[MAX_WIDTH][4];
+ GLuint unit;
- if (texObj->Target != GL_TEXTURE_2D) {
- _mesa_problem(ctx, "only 2-D depth textures supported at this time");
- return;
- }
+ ASSERT(span->end < MAX_WIDTH);
+ ASSERT(span->arrayMask & SPAN_TEXTURE);
- if (texObj->MinFilter != texObj->MagFilter) {
- _mesa_problem(ctx, "mipmapped depth textures not supported at this time");
- return;
- }
-
- /* XXX the GL_SGIX_shadow extension spec doesn't say what to do if
- * GL_TEXTURE_COMPARE_SGIX == GL_TRUE but the current texture object
- * isn't a depth texture.
+ /*
+ * Save copy of the incoming fragment colors (the GL_PRIMARY_COLOR)
*/
- if (texImage->Format != GL_DEPTH_COMPONENT) {
- _mesa_problem(ctx,"GL_TEXTURE_COMPARE_SGIX enabled with non-depth texture");
- return;
- }
-
- if (texObj->CompareOperator == GL_TEXTURE_LEQUAL_R_SGIX) {
- lequal = GL_TRUE;
- gequal = GL_FALSE;
- }
- else {
- lequal = GL_FALSE;
- gequal = GL_TRUE;
- }
+ if (swrast->_AnyTextureCombine)
+ MEMCPY(primary_rgba, span->array->rgba, 4 * span->end * sizeof(GLchan));
- if (texObj->MagFilter == GL_NEAREST) {
- GLuint i;
- for (i = 0; i < n; i++) {
- GLfloat depthSample;
- GLint col, row;
- COMPUTE_NEAREST_TEXEL_LOCATION(texObj->WrapS, s[i], width, col);
- COMPUTE_NEAREST_TEXEL_LOCATION(texObj->WrapT, t[i], height, row);
- depthSample = *((const GLfloat *) texImage->Data + row * width + col);
- if ((r[i] <= depthSample && lequal) ||
- (r[i] >= depthSample && gequal)) {
- texel[i][RCOMP] = CHAN_MAX;
- texel[i][GCOMP] = CHAN_MAX;
- texel[i][BCOMP] = CHAN_MAX;
- texel[i][ACOMP] = CHAN_MAX;
- }
- else {
- texel[i][RCOMP] = ambient;
- texel[i][GCOMP] = ambient;
- texel[i][BCOMP] = ambient;
- texel[i][ACOMP] = CHAN_MAX;
- }
- }
- }
- else {
- GLuint i;
- ASSERT(texObj->MagFilter == GL_LINEAR);
- for (i = 0; i < n; i++) {
- GLfloat depth00, depth01, depth10, depth11;
- GLint i0, i1, j0, j1;
- GLfloat u, v;
- GLuint useBorderTexel;
-
- COMPUTE_LINEAR_TEXEL_LOCATIONS(texObj->WrapS, s[i], u, width, i0, i1);
- COMPUTE_LINEAR_TEXEL_LOCATIONS(texObj->WrapT, t[i], v, height,j0, j1);
-
- useBorderTexel = 0;
- if (texImage->Border) {
- i0 += texImage->Border;
- i1 += texImage->Border;
- j0 += texImage->Border;
- j1 += texImage->Border;
- }
- else {
- if (i0 < 0 || i0 >= (GLint) width) useBorderTexel |= I0BIT;
- if (i1 < 0 || i1 >= (GLint) width) useBorderTexel |= I1BIT;
- if (j0 < 0 || j0 >= (GLint) height) useBorderTexel |= J0BIT;
- if (j1 < 0 || j1 >= (GLint) height) useBorderTexel |= J1BIT;
- }
-
- /* get four depth samples from the texture */
- if (useBorderTexel & (I0BIT | J0BIT)) {
- depth00 = 1.0;
- }
- else {
- depth00 = *((const GLfloat *) texImage->Data + j0 * width + i0);
- }
- if (useBorderTexel & (I1BIT | J0BIT)) {
- depth10 = 1.0;
- }
- else {
- depth10 = *((const GLfloat *) texImage->Data + j0 * width + i1);
- }
- if (useBorderTexel & (I0BIT | J1BIT)) {
- depth01 = 1.0;
- }
- else {
- depth01 = *((const GLfloat *) texImage->Data + j1 * width + i0);
- }
- if (useBorderTexel & (I1BIT | J1BIT)) {
- depth11 = 1.0;
- }
- else {
- depth11 = *((const GLfloat *) texImage->Data + j1 * width + i1);
- }
-
- if (0) {
- /* compute a single weighted depth sample and do one comparison */
- const GLfloat a = FRAC(u + 1.0F);
- const GLfloat b = FRAC(v + 1.0F);
- const GLfloat w00 = (1.0F - a) * (1.0F - b);
- const GLfloat w10 = ( a) * (1.0F - b);
- const GLfloat w01 = (1.0F - a) * ( b);
- const GLfloat w11 = ( a) * ( b);
- const GLfloat depthSample = w00 * depth00 + w10 * depth10
- + w01 * depth01 + w11 * depth11;
- if ((depthSample <= r[i] && lequal) ||
- (depthSample >= r[i] && gequal)) {
- texel[i][RCOMP] = ambient;
- texel[i][GCOMP] = ambient;
- texel[i][BCOMP] = ambient;
- texel[i][ACOMP] = CHAN_MAX;
- }
- else {
- texel[i][RCOMP] = CHAN_MAX;
- texel[i][GCOMP] = CHAN_MAX;
- texel[i][BCOMP] = CHAN_MAX;
- texel[i][ACOMP] = CHAN_MAX;
- }
- }
- else {
- /* Do four depth/R comparisons and compute a weighted result.
- * If this touches on somebody's I.P., I'll remove this code
- * upon request.
- */
- const GLfloat d = (CHAN_MAXF - (GLfloat) ambient) * 0.25F;
- GLfloat luminance = CHAN_MAXF;
- GLchan lum;
- if (lequal) {
- if (depth00 <= r[i]) luminance -= d;
- if (depth01 <= r[i]) luminance -= d;
- if (depth10 <= r[i]) luminance -= d;
- if (depth11 <= r[i]) luminance -= d;
- }
- else {
- if (depth00 >= r[i]) luminance -= d;
- if (depth01 >= r[i]) luminance -= d;
- if (depth10 >= r[i]) luminance -= d;
- if (depth11 >= r[i]) luminance -= d;
- }
- lum = (GLchan) luminance;
- texel[i][RCOMP] = lum;
- texel[i][GCOMP] = lum;
- texel[i][BCOMP] = lum;
- texel[i][ACOMP] = CHAN_MAX;
- }
- }
- }
-}
-
-
-#if 0
-/*
- * Experimental depth texture sampling function.
- */
-static void
-sample_depth_texture2(const GLcontext *ctx,
- const struct gl_texture_unit *texUnit,
- GLuint n,
- const GLfloat s[], const GLfloat t[], const GLfloat r[],
- GLchan texel[][4])
-{
- const struct gl_texture_object *texObj = texUnit->_Current;
- const GLint baseLevel = texObj->BaseLevel;
- const struct gl_texture_image *texImage = texObj->Image[baseLevel];
- const GLuint width = texImage->Width;
- const GLuint height = texImage->Height;
- const GLchan ambient = texObj->ShadowAmbient;
- GLboolean lequal, gequal;
-
- if (texObj->Dimensions != 2) {
- _mesa_problem(ctx, "only 2-D depth textures supported at this time");
- return;
- }
-
- if (texObj->MinFilter != texObj->MagFilter) {
- _mesa_problem(ctx, "mipmapped depth textures not supported at this time");
- return;
- }
-
- /* XXX the GL_SGIX_shadow extension spec doesn't say what to do if
- * GL_TEXTURE_COMPARE_SGIX == GL_TRUE but the current texture object
- * isn't a depth texture.
+ /*
+ * Must do all texture sampling before combining in order to
+ * accomodate GL_ARB_texture_env_crossbar.
*/
- if (texImage->Format != GL_DEPTH_COMPONENT) {
- _mesa_problem(ctx,"GL_TEXTURE_COMPARE_SGIX enabled with non-depth texture");
- return;
- }
-
- if (texObj->CompareOperator == GL_TEXTURE_LEQUAL_R_SGIX) {
- lequal = GL_TRUE;
- gequal = GL_FALSE;
- }
- else {
- lequal = GL_FALSE;
- gequal = GL_TRUE;
- }
-
- {
- GLuint i;
- for (i = 0; i < n; i++) {
- const GLint K = 3;
- GLint col, row, ii, jj, imin, imax, jmin, jmax, samples, count;
- GLfloat w;
- GLchan lum;
- COMPUTE_NEAREST_TEXEL_LOCATION(texObj->WrapS, s[i], width, col);
- COMPUTE_NEAREST_TEXEL_LOCATION(texObj->WrapT, t[i], height, row);
-
- imin = col - K;
- imax = col + K;
- jmin = row - K;
- jmax = row + K;
-
- if (imin < 0) imin = 0;
- if (imax >= width) imax = width - 1;
- if (jmin < 0) jmin = 0;
- if (jmax >= height) jmax = height - 1;
-
- samples = (imax - imin + 1) * (jmax - jmin + 1);
- count = 0;
- for (jj = jmin; jj <= jmax; jj++) {
- for (ii = imin; ii <= imax; ii++) {
- GLfloat depthSample = *((const GLfloat *) texImage->Data
- + jj * width + ii);
- if ((depthSample <= r[i] && lequal) ||
- (depthSample >= r[i] && gequal)) {
- count++;
- }
- }
- }
-
- w = (GLfloat) count / (GLfloat) samples;
- w = CHAN_MAXF - w * (CHAN_MAXF - (GLfloat) ambient);
- lum = (GLint) w;
-
- texel[i][RCOMP] = lum;
- texel[i][GCOMP] = lum;
- texel[i][BCOMP] = lum;
- texel[i][ACOMP] = CHAN_MAX;
- }
- }
-}
-#endif
-
-
-/*
- * Apply a unit of texture mapping to the incoming fragments.
- */
-void
-_swrast_texture_fragments( GLcontext *ctx, GLuint texUnit, GLuint n,
- const GLfloat s[], const GLfloat t[],
- const GLfloat r[], GLfloat lambda[],
- CONST GLchan primary_rgba[][4], GLchan rgba[][4] )
-{
- const GLuint mask = TEXTURE0_ANY << (texUnit * NUM_TEXTURE_TARGETS);
-
- if (ctx->Texture._ReallyEnabled & mask) {
- const struct gl_texture_unit *textureUnit = &ctx->Texture.Unit[texUnit];
-
- if (textureUnit->_Current) { /* XXX need this? */
- GLchan texel[PB_SIZE][4];
-
- if (lambda) {
- if (textureUnit->LodBias != 0.0F) {
+ for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) {
+ if (ctx->Texture.Unit[unit]._ReallyEnabled) {
+ const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
+ const struct gl_texture_object *curObj = texUnit->_Current;
+ GLfloat *lambda = span->array->lambda[unit];
+ GLchan (*texels)[4] = (GLchan (*)[4])
+ (swrast->TexelBuffer + unit * (span->end * 4 * sizeof(GLchan)));
+
+ /* adjust texture lod (lambda) */
+ if (span->arrayMask | SPAN_LAMBDA) {
+ if (texUnit->LodBias != 0.0F) {
/* apply LOD bias, but don't clamp yet */
GLuint i;
- for (i=0;i<n;i++) {
- lambda[i] += textureUnit->LodBias;
+ for (i = 0; i < span->end; i++) {
+ lambda[i] += texUnit->LodBias;
}
}
- if (textureUnit->_Current->MinLod != -1000.0 ||
- textureUnit->_Current->MaxLod != 1000.0) {
+ if (curObj->MinLod != -1000.0 || curObj->MaxLod != 1000.0) {
/* apply LOD clamping to lambda */
- const GLfloat min = textureUnit->_Current->MinLod;
- const GLfloat max = textureUnit->_Current->MaxLod;
+ const GLfloat min = curObj->MinLod;
+ const GLfloat max = curObj->MaxLod;
GLuint i;
- for (i=0;i<n;i++) {
+ for (i = 0; i < span->end; i++) {
GLfloat l = lambda[i];
lambda[i] = CLAMP(l, min, max);
}
}
}
- /* Sample the texture. */
- if (textureUnit->_Current->CompareFlag) {
- /* depth texture */
- sample_depth_texture(ctx, textureUnit, n, s, t, r, texel);
+ /* Sample the texture (span->end fragments) */
+ swrast->TextureSample[unit]( ctx, unit, texUnit->_Current,
+ span->end, span->array->texcoords[unit],
+ lambda, texels );
+ }
+ }
+
+ /*
+ * OK, now apply the texture (aka texture combine/blend).
+ * We modify the span->color.rgba values.
+ */
+ for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) {
+ if (ctx->Texture.Unit[unit]._ReallyEnabled) {
+ const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
+ if (texUnit->EnvMode == GL_COMBINE) {
+ /* GL_ARB/EXT_texture_env_combine */
+ texture_combine( ctx, unit, span->end,
+ (CONST GLchan (*)[4]) primary_rgba,
+ swrast->TexelBuffer,
+ span->array->rgba );
+ }
+ else if (texUnit->EnvMode == GL_COMBINE4_NV) {
+ /* GL_NV_texture_env_combine4 */
+ texture_combine4( ctx, unit, span->end,
+ (CONST GLchan (*)[4]) primary_rgba,
+ swrast->TexelBuffer,
+ span->array->rgba );
}
else {
- /* color texture */
- SWRAST_CONTEXT(ctx)->TextureSample[texUnit]( ctx, texUnit,
- textureUnit->_Current,
- n, s, t, r,
- lambda, texel );
- }
- apply_texture( ctx, textureUnit, n, primary_rgba,
- (const GLchan (*)[4]) texel, rgba );
+ /* conventional texture blend */
+ const GLchan (*texels)[4] = (const GLchan (*)[4])
+ (swrast->TexelBuffer + unit *
+ (span->end * 4 * sizeof(GLchan)));
+ texture_apply( ctx, texUnit, span->end,
+ (CONST GLchan (*)[4]) primary_rgba, texels,
+ span->array->rgba );
+ }
}
}
}
diff --git a/xc/extras/Mesa/src/swrast/s_texture.h b/xc/extras/Mesa/src/swrast/s_texture.h
index c1b792094..0157071f1 100644
--- a/xc/extras/Mesa/src/swrast/s_texture.h
+++ b/xc/extras/Mesa/src/swrast/s_texture.h
@@ -1,10 +1,9 @@
-/* $Id: s_texture.h,v 1.1.1.1 2002/10/22 13:06:51 alanh Exp $ */
/*
* Mesa 3-D graphics library
- * Version: 3.5
+ * Version: 4.1
*
- * Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
+ * Copyright (C) 1999-2002 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"),
@@ -40,10 +39,6 @@ _swrast_choose_texture_sample_func( GLcontext *ctx,
extern void
-_swrast_texture_fragments( GLcontext *ctx, GLuint texSet, GLuint n,
- const GLfloat s[], const GLfloat t[],
- const GLfloat r[], GLfloat lambda[],
- CONST GLchan primary_rgba[][4], GLchan rgba[][4] );
-
+_swrast_texture_span( GLcontext *ctx, struct sw_span *span );
#endif
diff --git a/xc/extras/Mesa/src/swrast/s_triangle.c b/xc/extras/Mesa/src/swrast/s_triangle.c
index ad9e77926..a4efb679f 100644
--- a/xc/extras/Mesa/src/swrast/s_triangle.c
+++ b/xc/extras/Mesa/src/swrast/s_triangle.c
@@ -1,10 +1,9 @@
-/* $Id: s_triangle.c,v 1.1.1.1 2002/10/22 13:06:48 alanh Exp $ */
/*
* Mesa 3-D graphics library
- * Version: 4.0.2
+ * Version: 5.0
*
- * Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
+ * Copyright (C) 1999-2002 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,8 +33,8 @@
#include "glheader.h"
#include "context.h"
#include "colormac.h"
+#include "imports.h"
#include "macros.h"
-#include "mem.h"
#include "mmath.h"
#include "texformat.h"
#include "teximage.h"
@@ -47,10 +46,11 @@
#include "s_feedback.h"
#include "s_span.h"
#include "s_triangle.h"
-#include "s_trispan.h"
-
+/*
+ * Just used for feedback mode.
+ */
GLboolean _mesa_cull_triangle( GLcontext *ctx,
const SWvertex *v0,
const SWvertex *v1,
@@ -81,18 +81,12 @@ static void flat_ci_triangle( GLcontext *ctx,
#define INTERP_Z 1
#define INTERP_FOG 1
-#define RENDER_SPAN( span ) \
- GLdepth zSpan[MAX_WIDTH]; \
- GLfloat fogSpan[MAX_WIDTH]; \
- GLuint i; \
- for (i = 0; i < span.count; i++) { \
- zSpan[i] = FixedToDepth(span.z); \
- span.z += span.zStep; \
- fogSpan[i] = span.fog; \
- span.fog += span.fogStep; \
- } \
- _mesa_write_monoindex_span(ctx, span.count, span.x, span.y, \
- zSpan, fogSpan, v2->index, NULL, GL_POLYGON );
+#define SETUP_CODE \
+ span.interpMask |= SPAN_INDEX; \
+ span.index = IntToFixed(v2->index); \
+ span.indexStep = 0;
+
+#define RENDER_SPAN( span ) _mesa_write_index_span(ctx, &span);
#include "s_tritemp.h"
}
@@ -111,21 +105,7 @@ static void smooth_ci_triangle( GLcontext *ctx,
#define INTERP_FOG 1
#define INTERP_INDEX 1
-#define RENDER_SPAN( span ) \
- GLdepth zSpan[MAX_WIDTH]; \
- GLfloat fogSpan[MAX_WIDTH]; \
- GLuint indexSpan[MAX_WIDTH]; \
- GLuint i; \
- for (i = 0; i < span.count; i++) { \
- zSpan[i] = FixedToDepth(span.z); \
- span.z += span.zStep; \
- indexSpan[i] = FixedToInt(span.index); \
- span.index += span.indexStep; \
- fogSpan[i] = span.fog; \
- span.fog += span.fogStep; \
- } \
- _mesa_write_index_span(ctx, span.count, span.x, span.y, \
- zSpan, fogSpan, indexSpan, NULL, GL_POLYGON);
+#define RENDER_SPAN( span ) _mesa_write_index_span(ctx, &span);
#include "s_tritemp.h"
}
@@ -144,23 +124,22 @@ static void flat_rgba_triangle( GLcontext *ctx,
#define INTERP_FOG 1
#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
-#define RENDER_SPAN( span ) \
- GLdepth zSpan[MAX_WIDTH]; \
- GLfloat fogSpan[MAX_WIDTH]; \
- GLuint i; \
- for (i = 0; i < span.count; i++) { \
- zSpan[i] = FixedToDepth(span.z); \
- span.z += span.zStep; \
- fogSpan[i] = span.fog; \
- span.fog += span.fogStep; \
- } \
- _mesa_write_monocolor_span(ctx, span.count, span.x, span.y, zSpan, \
- fogSpan, v2->color, NULL, GL_POLYGON );
+#define SETUP_CODE \
+ ASSERT(ctx->Texture._EnabledUnits == 0); \
+ ASSERT(ctx->Light.ShadeModel==GL_FLAT); \
+ span.interpMask |= SPAN_RGBA; \
+ span.red = ChanToFixed(v2->color[0]); \
+ span.green = ChanToFixed(v2->color[1]); \
+ span.blue = ChanToFixed(v2->color[2]); \
+ span.alpha = ChanToFixed(v2->color[3]); \
+ span.redStep = 0; \
+ span.greenStep = 0; \
+ span.blueStep = 0; \
+ span.alphaStep = 0;
+
+#define RENDER_SPAN( span ) _mesa_write_rgba_span(ctx, &span);
#include "s_tritemp.h"
-
- ASSERT(!ctx->Texture._ReallyEnabled); /* texturing must be off */
- ASSERT(ctx->Light.ShadeModel==GL_FLAT);
}
@@ -180,33 +159,17 @@ static void smooth_rgba_triangle( GLcontext *ctx,
#define INTERP_RGB 1
#define INTERP_ALPHA 1
-#define RENDER_SPAN( span ) \
- GLdepth zSpan[MAX_WIDTH]; \
- GLchan rgbaSpan[MAX_WIDTH][4]; \
- GLfloat fogSpan[MAX_WIDTH]; \
- GLuint i; \
- for (i = 0; i < span.count; i++) { \
- rgbaSpan[i][RCOMP] = FixedToChan(span.red); \
- rgbaSpan[i][GCOMP] = FixedToChan(span.green); \
- rgbaSpan[i][BCOMP] = FixedToChan(span.blue); \
- rgbaSpan[i][ACOMP] = FixedToChan(span.alpha); \
- span.red += span.redStep; \
- span.green += span.greenStep; \
- span.blue += span.blueStep; \
- span.alpha += span.alphaStep; \
- zSpan[i] = FixedToDepth(span.z); \
- span.z += span.zStep; \
- fogSpan[i] = span.fog; \
- span.fog += span.fogStep; \
- } \
- _mesa_write_rgba_span(ctx, span.count, span.x, span.y, \
- (CONST GLdepth *) zSpan, \
- fogSpan, rgbaSpan, NULL, GL_POLYGON);
+#define SETUP_CODE \
+ { \
+ /* texturing must be off */ \
+ ASSERT(ctx->Texture._EnabledUnits == 0); \
+ ASSERT(ctx->Light.ShadeModel==GL_SMOOTH); \
+ }
+
+#define RENDER_SPAN( span ) _mesa_write_rgba_span(ctx, &span);
#include "s_tritemp.h"
- ASSERT(!ctx->Texture._ReallyEnabled); /* texturing must be off */
- ASSERT(ctx->Light.ShadeModel==GL_SMOOTH);
}
@@ -228,7 +191,7 @@ static void simple_textured_triangle( GLcontext *ctx,
#define SETUP_CODE \
SWcontext *swrast = SWRAST_CONTEXT(ctx); \
struct gl_texture_object *obj = ctx->Texture.Unit[0].Current2D; \
- GLint b = obj->BaseLevel; \
+ const GLint b = obj->BaseLevel; \
const GLfloat twidth = (GLfloat) obj->Image[b]->Width; \
const GLfloat theight = (GLfloat) obj->Image[b]->Height; \
const GLint twidth_log2 = obj->Image[b]->WidthLog2; \
@@ -241,23 +204,23 @@ static void simple_textured_triangle( GLcontext *ctx,
}
#define RENDER_SPAN( span ) \
- GLchan rgbSpan[MAX_WIDTH][3]; \
GLuint i; \
span.intTex[0] -= FIXED_HALF; /* off-by-one error? */ \
span.intTex[1] -= FIXED_HALF; \
- for (i = 0; i < span.count; i++) { \
+ for (i = 0; i < span.end; i++) { \
GLint s = FixedToInt(span.intTex[0]) & smask; \
GLint t = FixedToInt(span.intTex[1]) & tmask; \
GLint pos = (t << twidth_log2) + s; \
pos = pos + pos + pos; /* multiply by 3 */ \
- rgbSpan[i][RCOMP] = texture[pos]; \
- rgbSpan[i][GCOMP] = texture[pos+1]; \
- rgbSpan[i][BCOMP] = texture[pos+2]; \
+ span.array->rgb[i][RCOMP] = texture[pos]; \
+ span.array->rgb[i][GCOMP] = texture[pos+1]; \
+ span.array->rgb[i][BCOMP] = texture[pos+2]; \
span.intTex[0] += span.intTexStep[0]; \
span.intTex[1] += span.intTexStep[1]; \
} \
- (*swrast->Driver.WriteRGBSpan)(ctx, span.count, span.x, span.y, \
- (CONST GLchan (*)[3]) rgbSpan, NULL );
+ (*swrast->Driver.WriteRGBSpan)(ctx, span.end, span.x, span.y, \
+ (CONST GLchan (*)[3]) span.array->rgb,\
+ NULL );
#include "s_tritemp.h"
}
@@ -284,46 +247,45 @@ static void simple_z_textured_triangle( GLcontext *ctx,
#define SETUP_CODE \
SWcontext *swrast = SWRAST_CONTEXT(ctx); \
struct gl_texture_object *obj = ctx->Texture.Unit[0].Current2D; \
- GLint b = obj->BaseLevel; \
- GLfloat twidth = (GLfloat) obj->Image[b]->Width; \
- GLfloat theight = (GLfloat) obj->Image[b]->Height; \
- GLint twidth_log2 = obj->Image[b]->WidthLog2; \
+ const GLint b = obj->BaseLevel; \
+ const GLfloat twidth = (GLfloat) obj->Image[b]->Width; \
+ const GLfloat theight = (GLfloat) obj->Image[b]->Height; \
+ const GLint twidth_log2 = obj->Image[b]->WidthLog2; \
const GLchan *texture = (const GLchan *) obj->Image[b]->Data; \
- GLint smask = obj->Image[b]->Width - 1; \
- GLint tmask = obj->Image[b]->Height - 1; \
+ const GLint smask = obj->Image[b]->Width - 1; \
+ const GLint tmask = obj->Image[b]->Height - 1; \
if (!texture) { \
/* this shouldn't happen */ \
return; \
}
#define RENDER_SPAN( span ) \
- GLchan rgbSpan[MAX_WIDTH][3]; \
- GLubyte mask[MAX_WIDTH]; \
GLuint i; \
span.intTex[0] -= FIXED_HALF; /* off-by-one error? */ \
span.intTex[1] -= FIXED_HALF; \
- for (i = 0; i < span.count; i++) { \
+ for (i = 0; i < span.end; i++) { \
const GLdepth z = FixedToDepth(span.z); \
if (z < zRow[i]) { \
GLint s = FixedToInt(span.intTex[0]) & smask; \
GLint t = FixedToInt(span.intTex[1]) & tmask; \
GLint pos = (t << twidth_log2) + s; \
pos = pos + pos + pos; /* multiply by 3 */ \
- rgbSpan[i][RCOMP] = texture[pos]; \
- rgbSpan[i][GCOMP] = texture[pos+1]; \
- rgbSpan[i][BCOMP] = texture[pos+2]; \
+ span.array->rgb[i][RCOMP] = texture[pos]; \
+ span.array->rgb[i][GCOMP] = texture[pos+1]; \
+ span.array->rgb[i][BCOMP] = texture[pos+2]; \
zRow[i] = z; \
- mask[i] = 1; \
+ span.array->mask[i] = 1; \
} \
else { \
- mask[i] = 0; \
+ span.array->mask[i] = 0; \
} \
span.intTex[0] += span.intTexStep[0]; \
span.intTex[1] += span.intTexStep[1]; \
span.z += span.zStep; \
} \
- (*swrast->Driver.WriteRGBSpan)(ctx, span.count, span.x, span.y, \
- (CONST GLchan (*)[3]) rgbSpan, mask );
+ (*swrast->Driver.WriteRGBSpan)(ctx, span.end, span.x, span.y, \
+ (CONST GLchan (*)[3]) span.array->rgb,\
+ span.array->mask );
#include "s_tritemp.h"
}
@@ -341,7 +303,6 @@ struct affine_info
const GLchan *texture;
GLfixed er, eg, eb, ea;
GLint tbytesline, tsize;
- GLint fixedToDepthShift;
};
@@ -349,8 +310,8 @@ struct affine_info
* textures with GL_REPLACE, GL_MODULATE, GL_BLEND, GL_DECAL or GL_ADD
* texture env modes.
*/
-static void
-affine_span(GLcontext *ctx, struct triangle_span *span,
+static INLINE void
+affine_span(GLcontext *ctx, struct sw_span *span,
struct affine_info *info)
{
GLchan sample[4]; /* the filtered texture sample */
@@ -388,7 +349,7 @@ affine_span(GLcontext *ctx, struct triangle_span *span,
sample[ACOMP] = (ti * (si * tex00[3] + sf * tex01[3]) + \
tf * (si * tex10[3] + sf * tex11[3])) >> 2 * FIXED_SHIFT
-#define MODULATE \
+#define MODULATE \
dest[RCOMP] = span->red * (sample[RCOMP] + 1u) >> (FIXED_SHIFT + 8); \
dest[GCOMP] = span->green * (sample[GCOMP] + 1u) >> (FIXED_SHIFT + 8); \
dest[BCOMP] = span->blue * (sample[BCOMP] + 1u) >> (FIXED_SHIFT + 8); \
@@ -440,17 +401,13 @@ affine_span(GLcontext *ctx, struct triangle_span *span,
#define NEAREST_RGBA_REPLACE COPY_CHAN4(dest, tex00)
#define SPAN_NEAREST(DO_TEX,COMP) \
- for (i = 0; i < span->count; i++) { \
+ for (i = 0; i < span->end; i++) { \
/* Isn't it necessary to use FixedFloor below?? */ \
GLint s = FixedToInt(span->intTex[0]) & info->smask; \
GLint t = FixedToInt(span->intTex[1]) & info->tmask; \
GLint pos = (t << info->twidth_log2) + s; \
const GLchan *tex00 = info->texture + COMP * pos; \
- zspan[i] = FixedToDepth(span->z); \
- fogspan[i] = span->fog; \
DO_TEX; \
- span->fog += span->fogStep; \
- span->z += span->zStep; \
span->red += span->redStep; \
span->green += span->greenStep; \
span->blue += span->blueStep; \
@@ -461,7 +418,7 @@ affine_span(GLcontext *ctx, struct triangle_span *span,
}
#define SPAN_LINEAR(DO_TEX,COMP) \
- for (i = 0; i < span->count; i++) { \
+ for (i = 0; i < span->end; i++) { \
/* Isn't it necessary to use FixedFloor below?? */ \
GLint s = FixedToInt(span->intTex[0]) & info->smask; \
GLint t = FixedToInt(span->intTex[1]) & info->tmask; \
@@ -484,11 +441,7 @@ affine_span(GLcontext *ctx, struct triangle_span *span,
tex01 -= info->tbytesline; \
tex11 -= info->tbytesline; \
} \
- zspan[i] = FixedToDepth(span->z); \
- fogspan[i] = span->fog; \
DO_TEX; \
- span->fog += span->fogStep; \
- span->z += span->zStep; \
span->red += span->redStep; \
span->green += span->greenStep; \
span->blue += span->blueStep; \
@@ -498,14 +451,9 @@ affine_span(GLcontext *ctx, struct triangle_span *span,
dest += 4; \
}
-#define FixedToDepth(F) ((F) >> fixedToDepthShift)
GLuint i;
- GLdepth zspan[MAX_WIDTH];
- GLfloat fogspan[MAX_WIDTH];
- GLchan rgba[MAX_WIDTH][4];
- GLchan *dest = rgba[0];
- const GLint fixedToDepthShift = info->fixedToDepthShift;
+ GLchan *dest = span->array->rgba[0];
span->intTex[0] -= FIXED_HALF;
span->intTex[1] -= FIXED_HALF;
@@ -528,7 +476,8 @@ affine_span(GLcontext *ctx, struct triangle_span *span,
SPAN_NEAREST(NEAREST_RGB;ADD,3);
break;
default:
- abort();
+ _mesa_problem(ctx, "bad tex env mode in SPAN_LINEAR");
+ return;
}
break;
case GL_RGBA:
@@ -549,7 +498,8 @@ affine_span(GLcontext *ctx, struct triangle_span *span,
SPAN_NEAREST(NEAREST_RGBA_REPLACE,4);
break;
default:
- abort();
+ _mesa_problem(ctx, "bad tex env mode (2) in SPAN_LINEAR");
+ return;
}
break;
}
@@ -575,7 +525,8 @@ affine_span(GLcontext *ctx, struct triangle_span *span,
SPAN_LINEAR(LINEAR_RGB;ADD,3);
break;
default:
- abort();
+ _mesa_problem(ctx, "bad tex env mode (3) in SPAN_LINEAR");
+ return;
}
break;
case GL_RGBA:
@@ -596,17 +547,19 @@ affine_span(GLcontext *ctx, struct triangle_span *span,
SPAN_LINEAR(LINEAR_RGBA;REPLACE,4);
break;
default:
- abort();
- } break;
+ _mesa_problem(ctx, "bad tex env mode (4) in SPAN_LINEAR");
+ return;
+ }
+ break;
}
break;
}
- _mesa_write_rgba_span(ctx, span->count, span->x, span->y,
- zspan, fogspan, rgba, NULL, GL_POLYGON);
+ span->interpMask &= ~SPAN_RGBA;
+ ASSERT(span->arrayMask & SPAN_RGBA);
+ _mesa_write_rgba_span(ctx, span);
#undef SPAN_NEAREST
#undef SPAN_LINEAR
-#undef FixedToDepth
}
@@ -632,10 +585,9 @@ static void affine_textured_triangle( GLcontext *ctx,
struct affine_info info; \
struct gl_texture_unit *unit = ctx->Texture.Unit+0; \
struct gl_texture_object *obj = unit->Current2D; \
- GLint b = obj->BaseLevel; \
- GLfloat twidth = (GLfloat) obj->Image[b]->Width; \
- GLfloat theight = (GLfloat) obj->Image[b]->Height; \
- info.fixedToDepthShift = ctx->Visual.depthBits <= 16 ? FIXED_SHIFT : 0;\
+ const GLint b = obj->BaseLevel; \
+ const GLfloat twidth = (GLfloat) obj->Image[b]->Width; \
+ const GLfloat theight = (GLfloat) obj->Image[b]->Height; \
info.texture = (const GLchan *) obj->Image[b]->Data; \
info.twidth_log2 = obj->Image[b]->WidthLog2; \
info.smask = obj->Image[b]->Width - 1; \
@@ -643,6 +595,7 @@ static void affine_textured_triangle( GLcontext *ctx,
info.format = obj->Image[b]->Format; \
info.filter = obj->MinFilter; \
info.envmode = unit->EnvMode; \
+ span.arrayMask |= SPAN_RGBA; \
\
if (info.envmode == GL_BLEND) { \
/* potential off-by-one error here? (1.0f -> 2048 -> 0) */ \
@@ -695,12 +648,11 @@ struct persp_info
const GLchan *texture;
GLfixed er, eg, eb, ea; /* texture env color */
GLint tbytesline, tsize;
- GLint fixedToDepthShift;
};
-static void
-fast_persp_span(GLcontext *ctx, struct triangle_span *span,
+static INLINE void
+fast_persp_span(GLcontext *ctx, struct sw_span *span,
struct persp_info *info)
{
GLchan sample[4]; /* the filtered texture sample */
@@ -711,7 +663,7 @@ fast_persp_span(GLcontext *ctx, struct triangle_span *span,
* unused variables (for instance tf,sf,ti,si in case of GL_NEAREST).
*/
#define SPAN_NEAREST(DO_TEX,COMP) \
- for (i = 0; i < span->count; i++) { \
+ for (i = 0; i < span->end; i++) { \
GLdouble invQ = tex_coord[2] ? \
(1.0 / tex_coord[2]) : 1.0; \
GLfloat s_tmp = (GLfloat) (tex_coord[0] * invQ); \
@@ -720,11 +672,7 @@ fast_persp_span(GLcontext *ctx, struct triangle_span *span,
GLint t = IFLOOR(t_tmp) & info->tmask; \
GLint pos = (t << info->twidth_log2) + s; \
const GLchan *tex00 = info->texture + COMP * pos; \
- zspan[i] = FixedToDepth(span->z); \
- fogspan[i] = span->fog; \
DO_TEX; \
- span->fog += span->fogStep; \
- span->z += span->zStep; \
span->red += span->redStep; \
span->green += span->greenStep; \
span->blue += span->blueStep; \
@@ -736,7 +684,7 @@ fast_persp_span(GLcontext *ctx, struct triangle_span *span,
}
#define SPAN_LINEAR(DO_TEX,COMP) \
- for (i = 0; i < span->count; i++) { \
+ for (i = 0; i < span->end; i++) { \
GLdouble invQ = tex_coord[2] ? \
(1.0 / tex_coord[2]) : 1.0; \
GLfloat s_tmp = (GLfloat) (tex_coord[0] * invQ); \
@@ -764,11 +712,7 @@ fast_persp_span(GLcontext *ctx, struct triangle_span *span,
tex01 -= info->tbytesline; \
tex11 -= info->tbytesline; \
} \
- zspan[i] = FixedToDepth(span->z); \
- fogspan[i] = span->fog; \
DO_TEX; \
- span->fog += span->fogStep; \
- span->z += span->zStep; \
span->red += span->redStep; \
span->green += span->greenStep; \
span->blue += span->blueStep; \
@@ -779,23 +723,17 @@ fast_persp_span(GLcontext *ctx, struct triangle_span *span,
dest += 4; \
}
-#define FixedToDepth(F) ((F) >> fixedToDepthShift)
-
GLuint i;
- GLdepth zspan[MAX_WIDTH];
GLfloat tex_coord[3], tex_step[3];
- GLfloat fogspan[MAX_WIDTH];
- GLchan rgba[MAX_WIDTH][4];
- GLchan *dest = rgba[0];
- const GLint fixedToDepthShift = info->fixedToDepthShift;
-
- tex_coord[0] = span->tex[0][0] * (info->smask + 1),
- tex_step[0] = span->texStep[0][0] * (info->smask + 1);
- tex_coord[1] = span->tex[0][1] * (info->tmask + 1),
- tex_step[1] = span->texStep[0][1] * (info->tmask + 1);
+ GLchan *dest = span->array->rgba[0];
+
+ tex_coord[0] = span->tex[0][0] * (info->smask + 1);
+ tex_step[0] = span->texStepX[0][0] * (info->smask + 1);
+ tex_coord[1] = span->tex[0][1] * (info->tmask + 1);
+ tex_step[1] = span->texStepX[0][1] * (info->tmask + 1);
/* span->tex[0][2] only if 3D-texturing, here only 2D */
- tex_coord[2] = span->tex[0][3],
- tex_step[2] = span->texStep[0][3];
+ tex_coord[2] = span->tex[0][3];
+ tex_step[2] = span->texStepX[0][3];
switch (info->filter) {
case GL_NEAREST:
@@ -816,7 +754,8 @@ fast_persp_span(GLcontext *ctx, struct triangle_span *span,
SPAN_NEAREST(NEAREST_RGB;ADD,3);
break;
default:
- abort();
+ _mesa_problem(ctx, "bad tex env mode (5) in SPAN_LINEAR");
+ return;
}
break;
case GL_RGBA:
@@ -837,7 +776,8 @@ fast_persp_span(GLcontext *ctx, struct triangle_span *span,
SPAN_NEAREST(NEAREST_RGBA_REPLACE,4);
break;
default:
- abort();
+ _mesa_problem(ctx, "bad tex env mode (6) in SPAN_LINEAR");
+ return;
}
break;
}
@@ -861,7 +801,8 @@ fast_persp_span(GLcontext *ctx, struct triangle_span *span,
SPAN_LINEAR(LINEAR_RGB;ADD,3);
break;
default:
- abort();
+ _mesa_problem(ctx, "bad tex env mode (7) in SPAN_LINEAR");
+ return;
}
break;
case GL_RGBA:
@@ -882,25 +823,19 @@ fast_persp_span(GLcontext *ctx, struct triangle_span *span,
SPAN_LINEAR(LINEAR_RGBA;REPLACE,4);
break;
default:
- abort();
+ _mesa_problem(ctx, "bad tex env mode (8) in SPAN_LINEAR");
+ return;
}
break;
}
break;
}
- /* This does not seem to be necessary, but I don't know !! */
- /* span->tex[0][0] = tex_coord[0] / (info->smask + 1),
- span->tex[0][1] = tex_coord[1] / (info->tmask + 1),*/
- /* span->tex[0][2] only if 3D-texturing, here only 2D */
- /* span->tex[0][3] = tex_coord[2]; */
- _mesa_write_rgba_span(ctx, span->count, span->x, span->y,
- zspan, fogspan, rgba, NULL, GL_POLYGON);
-
+ ASSERT(span->arrayMask & SPAN_RGBA);
+ _mesa_write_rgba_span(ctx, span);
#undef SPAN_NEAREST
#undef SPAN_LINEAR
-#undef FixedToDepth
}
@@ -924,10 +859,9 @@ static void persp_textured_triangle( GLcontext *ctx,
#define SETUP_CODE \
struct persp_info info; \
- struct gl_texture_unit *unit = ctx->Texture.Unit+0; \
- struct gl_texture_object *obj = unit->Current2D; \
- GLint b = obj->BaseLevel; \
- info.fixedToDepthShift = ctx->Visual.depthBits <= 16 ? FIXED_SHIFT : 0;\
+ const struct gl_texture_unit *unit = ctx->Texture.Unit+0; \
+ const struct gl_texture_object *obj = unit->Current2D; \
+ const GLint b = obj->BaseLevel; \
info.texture = (const GLchan *) obj->Image[b]->Data; \
info.twidth_log2 = obj->Image[b]->WidthLog2; \
info.smask = obj->Image[b]->Width - 1; \
@@ -969,7 +903,10 @@ static void persp_textured_triangle( GLcontext *ctx,
} \
info.tsize = obj->Image[b]->Height * info.tbytesline;
-#define RENDER_SPAN( span ) fast_persp_span(ctx, &span, &info);
+#define RENDER_SPAN( span ) \
+ span.interpMask &= ~SPAN_RGBA; \
+ span.arrayMask |= SPAN_RGBA; \
+ fast_persp_span(ctx, &span, &info);
#include "s_tritemp.h"
@@ -978,335 +915,6 @@ static void persp_textured_triangle( GLcontext *ctx,
#endif /* CHAN_BITS != GL_FLOAT */
-
-/*
- * Generate arrays of fragment colors, z, fog, texcoords, etc from a
- * triangle span object. Then call the span/fragment processsing
- * functions in s_span.[ch]. This is used by a bunch of the textured
- * triangle functions.
- */
-static void
-rasterize_span(GLcontext *ctx, const struct triangle_span *span)
-{
- DEFMARRAY(GLchan, rgba, MAX_WIDTH, 4);
- DEFMARRAY(GLchan, spec, MAX_WIDTH, 4);
- DEFARRAY(GLuint, index, MAX_WIDTH);
- DEFARRAY(GLuint, z, MAX_WIDTH);
- DEFARRAY(GLfloat, fog, MAX_WIDTH);
- DEFARRAY(GLfloat, sTex, MAX_WIDTH);
- DEFARRAY(GLfloat, tTex, MAX_WIDTH);
- DEFARRAY(GLfloat, rTex, MAX_WIDTH);
- DEFARRAY(GLfloat, lambda, MAX_WIDTH);
- DEFMARRAY(GLfloat, msTex, MAX_TEXTURE_UNITS, MAX_WIDTH);
- DEFMARRAY(GLfloat, mtTex, MAX_TEXTURE_UNITS, MAX_WIDTH);
- DEFMARRAY(GLfloat, mrTex, MAX_TEXTURE_UNITS, MAX_WIDTH);
- DEFMARRAY(GLfloat, mLambda, MAX_TEXTURE_UNITS, MAX_WIDTH);
-
- CHECKARRAY(rgba, return);
- CHECKARRAY(spec, return);
- CHECKARRAY(index, return);
- CHECKARRAY(z, return);
- CHECKARRAY(fog, return);
- CHECKARRAY(sTex, return);
- CHECKARRAY(tTex, return);
- CHECKARRAY(rTex, return);
- CHECKARRAY(lambda, return);
- CHECKARRAY(msTex, return);
- CHECKARRAY(mtTex, return);
- CHECKARRAY(mrTex, return);
- CHECKARRAY(mLambda, return);
-
- if (span->activeMask & SPAN_RGBA) {
- if (span->activeMask & SPAN_FLAT) {
- GLuint i;
- GLchan color[4];
- color[RCOMP] = FixedToChan(span->red);
- color[GCOMP] = FixedToChan(span->green);
- color[BCOMP] = FixedToChan(span->blue);
- color[ACOMP] = FixedToChan(span->alpha);
- for (i = 0; i < span->count; i++) {
- COPY_CHAN4(rgba[i], color);
- }
- }
- else {
- /* smooth interpolation */
-#if CHAN_TYPE == GL_FLOAT
- GLfloat r = span->red;
- GLfloat g = span->green;
- GLfloat b = span->blue;
- GLfloat a = span->alpha;
-#else
- GLfixed r = span->red;
- GLfixed g = span->green;
- GLfixed b = span->blue;
- GLfixed a = span->alpha;
-#endif
- GLuint i;
- for (i = 0; i < span->count; i++) {
- rgba[i][RCOMP] = FixedToChan(r);
- rgba[i][GCOMP] = FixedToChan(g);
- rgba[i][BCOMP] = FixedToChan(b);
- rgba[i][ACOMP] = FixedToChan(a);
- r += span->redStep;
- g += span->greenStep;
- b += span->blueStep;
- a += span->alphaStep;
- }
- }
- }
-
- if (span->activeMask & SPAN_SPEC) {
- if (span->activeMask & SPAN_FLAT) {
- const GLchan r = FixedToChan(span->specRed);
- const GLchan g = FixedToChan(span->specGreen);
- const GLchan b = FixedToChan(span->specBlue);
- GLuint i;
- for (i = 0; i < span->count; i++) {
- spec[i][RCOMP] = r;
- spec[i][GCOMP] = g;
- spec[i][BCOMP] = b;
- }
- }
- else {
- /* smooth interpolation */
-#if CHAN_TYPE == GL_FLOAT
- GLfloat r = span->specRed;
- GLfloat g = span->specGreen;
- GLfloat b = span->specBlue;
-#else
- GLfixed r = span->specRed;
- GLfixed g = span->specGreen;
- GLfixed b = span->specBlue;
-#endif
- GLuint i;
- for (i = 0; i < span->count; i++) {
- spec[i][RCOMP] = FixedToChan(r);
- spec[i][GCOMP] = FixedToChan(g);
- spec[i][BCOMP] = FixedToChan(b);
- r += span->specRedStep;
- g += span->specGreenStep;
- b += span->specBlueStep;
- }
- }
- }
-
- if (span->activeMask & SPAN_INDEX) {
- if (span->activeMask & SPAN_FLAT) {
- GLuint i;
- const GLint indx = FixedToInt(span->index);
- for (i = 0; i < span->count; i++) {
- index[i] = indx;
- }
- }
- else {
- /* smooth interpolation */
- GLuint i;
- GLfixed ind = span->index;
- for (i = 0; i < span->count; i++) {
- index[i] = FixedToInt(ind);
- ind += span->indexStep;
- }
- }
- }
-
- if (span->activeMask & SPAN_Z) {
- if (ctx->Visual.depthBits <= 16) {
- GLuint i;
- GLfixed zval = span->z;
- for (i = 0; i < span->count; i++) {
- z[i] = FixedToInt(zval);
- zval += span->zStep;
- }
- }
- else {
- /* Deep Z buffer, no fixed->int shift */
- GLuint i;
- GLfixed zval = span->z;
- for (i = 0; i < span->count; i++) {
- z[i] = zval;
- zval += span->zStep;
- }
- }
- }
- if (span->activeMask & SPAN_FOG) {
- GLuint i;
- GLfloat f = span->fog;
- for (i = 0; i < span->count; i++) {
- fog[i] = f;
- f += span->fogStep;
- }
- }
- if (span->activeMask & SPAN_TEXTURE) {
- if (ctx->Texture._ReallyEnabled & ~TEXTURE0_ANY) {
- /* multitexture */
- if (span->activeMask & SPAN_LAMBDA) {
- /* with lambda */
- GLuint u;
- for (u = 0; u < MAX_TEXTURE_UNITS; u++) {
- if (ctx->Texture.Unit[u]._ReallyEnabled) {
- GLfloat s = span->tex[u][0];
- GLfloat t = span->tex[u][1];
- GLfloat r = span->tex[u][2];
- GLfloat q = span->tex[u][3];
- GLuint i;
- for (i = 0; i < span->count; i++) {
- const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q);
- msTex[u][i] = s * invQ;
- mtTex[u][i] = t * invQ;
- mrTex[u][i] = r * invQ;
- mLambda[u][i] = (GLfloat)
- (log(span->rho[u] * invQ * invQ) * 1.442695F * 0.5F);
- s += span->texStep[u][0];
- t += span->texStep[u][1];
- r += span->texStep[u][2];
- q += span->texStep[u][3];
- }
- }
- }
- }
- else {
- /* without lambda */
- GLuint u;
- for (u = 0; u < MAX_TEXTURE_UNITS; u++) {
- if (ctx->Texture.Unit[u]._ReallyEnabled) {
- GLfloat s = span->tex[u][0];
- GLfloat t = span->tex[u][1];
- GLfloat r = span->tex[u][2];
- GLfloat q = span->tex[u][3];
- GLuint i;
- for (i = 0; i < span->count; i++) {
- const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q);
- msTex[u][i] = s * invQ;
- mtTex[u][i] = t * invQ;
- mrTex[u][i] = r * invQ;
- s += span->texStep[u][0];
- t += span->texStep[u][1];
- r += span->texStep[u][2];
- q += span->texStep[u][3];
- }
- }
- }
- }
- }
- else {
- /* just texture unit 0 */
- if (span->activeMask & SPAN_LAMBDA) {
- /* with lambda */
- GLfloat s = span->tex[0][0];
- GLfloat t = span->tex[0][1];
- GLfloat r = span->tex[0][2];
- GLfloat q = span->tex[0][3];
- GLuint i;
- for (i = 0; i < span->count; i++) {
- const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q);
- sTex[i] = s * invQ;
- tTex[i] = t * invQ;
- rTex[i] = r * invQ;
- lambda[i] = (GLfloat)
- (log(span->rho[0] * invQ * invQ) * 1.442695F * 0.5F);
- s += span->texStep[0][0];
- t += span->texStep[0][1];
- r += span->texStep[0][2];
- q += span->texStep[0][3];
- }
- }
- else {
- /* without lambda */
- GLfloat s = span->tex[0][0];
- GLfloat t = span->tex[0][1];
- GLfloat r = span->tex[0][2];
- GLfloat q = span->tex[0][3];
- GLuint i;
- for (i = 0; i < span->count; i++) {
- const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q);
- sTex[i] = s * invQ;
- tTex[i] = t * invQ;
- rTex[i] = r * invQ;
- s += span->texStep[0][0];
- t += span->texStep[0][1];
- r += span->texStep[0][2];
- q += span->texStep[0][3];
- }
- }
- }
- }
- /* XXX keep this? */
- if (span->activeMask & SPAN_INT_TEXTURE) {
- GLint intTexcoord[MAX_WIDTH][2];
- GLfixed s = span->intTex[0];
- GLfixed t = span->intTex[1];
- GLuint i;
- for (i = 0; i < span->count; i++) {
- intTexcoord[i][0] = FixedToInt(s);
- intTexcoord[i][1] = FixedToInt(t);
- s += span->intTexStep[0];
- t += span->intTexStep[1];
- }
- }
-
- /* examine activeMask and call a s_span.c function */
- if (span->activeMask & SPAN_TEXTURE) {
- const GLfloat *fogPtr;
- if (span->activeMask & SPAN_FOG)
- fogPtr = fog;
- else
- fogPtr = NULL;
-
- if (ctx->Texture._ReallyEnabled & ~TEXTURE0_ANY) {
- if (span->activeMask & SPAN_SPEC) {
- _mesa_write_multitexture_span(ctx, span->count, span->x, span->y,
- z, fogPtr,
- (const GLfloat (*)[MAX_WIDTH]) msTex,
- (const GLfloat (*)[MAX_WIDTH]) mtTex,
- (const GLfloat (*)[MAX_WIDTH]) mrTex,
- (GLfloat (*)[MAX_WIDTH]) mLambda,
- rgba, (CONST GLchan (*)[4]) spec,
- NULL, GL_POLYGON );
- }
- else {
- _mesa_write_multitexture_span(ctx, span->count, span->x, span->y,
- z, fogPtr,
- (const GLfloat (*)[MAX_WIDTH]) msTex,
- (const GLfloat (*)[MAX_WIDTH]) mtTex,
- (const GLfloat (*)[MAX_WIDTH]) mrTex,
- (GLfloat (*)[MAX_WIDTH]) mLambda,
- rgba, NULL, NULL, GL_POLYGON);
- }
- }
- else {
- /* single texture */
- if (span->activeMask & SPAN_SPEC) {
- _mesa_write_texture_span(ctx, span->count, span->x, span->y,
- z, fogPtr, sTex, tTex, rTex, lambda,
- rgba, (CONST GLchan (*)[4]) spec,
- NULL, GL_POLYGON);
- }
- else {
- _mesa_write_texture_span(ctx, span->count, span->x, span->y,
- z, fogPtr, sTex, tTex, rTex, lambda,
- rgba, NULL, NULL, GL_POLYGON);
- }
- }
- }
- else {
- _mesa_problem(ctx, "rasterize_span() should only be used for texturing");
- }
-
- UNDEFARRAY(rgba);
- UNDEFARRAY(spec);
- UNDEFARRAY(index);
- UNDEFARRAY(z);
- UNDEFARRAY(fog);
- UNDEFARRAY(sTex);
- UNDEFARRAY(tTex);
- UNDEFARRAY(rTex);
- UNDEFARRAY(lambda);
- UNDEFARRAY(msTex);
- UNDEFARRAY(mtTex);
- UNDEFARRAY(mrTex);
- UNDEFARRAY(mLambda);
-}
-
@@ -1323,173 +931,27 @@ static void general_textured_triangle( GLcontext *ctx,
#define INTERP_FOG 1
#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
#define INTERP_RGB 1
-#define INTERP_ALPHA 1
-#define INTERP_TEX 1
-
-#define SETUP_CODE \
- const struct gl_texture_object *obj = ctx->Texture.Unit[0]._Current; \
- const struct gl_texture_image *texImage = obj->Image[obj->BaseLevel];\
- DEFARRAY(GLfloat, sSpan, MAX_WIDTH); /* mac 32k limitation */ \
- DEFARRAY(GLfloat, tSpan, MAX_WIDTH); /* mac 32k limitation */ \
- DEFARRAY(GLfloat, uSpan, MAX_WIDTH); /* mac 32k limitation */ \
- CHECKARRAY(sSpan, return); /* mac 32k limitation */ \
- CHECKARRAY(tSpan, return); /* mac 32k limitation */ \
- CHECKARRAY(uSpan, return); /* mac 32k limitation */ \
- span.texWidth[0] = (GLfloat) texImage->Width; \
- span.texHeight[0] = (GLfloat) texImage->Height; \
- (void) fixedToDepthShift;
-
-#define RENDER_SPAN( span ) \
- GLdepth zSpan[MAX_WIDTH]; \
- GLfloat fogSpan[MAX_WIDTH]; \
- GLchan rgbaSpan[MAX_WIDTH][4]; \
- GLuint i; \
- /* NOTE: we could just call rasterize_span() here instead */ \
- for (i = 0; i < span.count; i++) { \
- GLdouble invQ = span.tex[0][3] ? (1.0 / span.tex[0][3]) : 1.0; \
- zSpan[i] = FixedToDepth(span.z); \
- span.z += span.zStep; \
- fogSpan[i] = span.fog; \
- span.fog += span.fogStep; \
- rgbaSpan[i][RCOMP] = FixedToChan(span.red); \
- rgbaSpan[i][GCOMP] = FixedToChan(span.green); \
- rgbaSpan[i][BCOMP] = FixedToChan(span.blue); \
- rgbaSpan[i][ACOMP] = FixedToChan(span.alpha); \
- span.red += span.redStep; \
- span.green += span.greenStep; \
- span.blue += span.blueStep; \
- span.alpha += span.alphaStep; \
- sSpan[i] = (GLfloat) (span.tex[0][0] * invQ); \
- tSpan[i] = (GLfloat) (span.tex[0][1] * invQ); \
- uSpan[i] = (GLfloat) (span.tex[0][2] * invQ); \
- span.tex[0][0] += span.texStep[0][0]; \
- span.tex[0][1] += span.texStep[0][1]; \
- span.tex[0][2] += span.texStep[0][2]; \
- span.tex[0][3] += span.texStep[0][3]; \
- } \
- _mesa_write_texture_span(ctx, span.count, span.x, span.y, \
- zSpan, fogSpan, sSpan, tSpan, uSpan, \
- NULL, rgbaSpan, NULL, NULL, GL_POLYGON );
-
-#define CLEANUP_CODE \
- UNDEFARRAY(sSpan); /* mac 32k limitation */ \
- UNDEFARRAY(tSpan); \
- UNDEFARRAY(uSpan);
-
-#include "s_tritemp.h"
-}
-
-
-/*
- * Render a smooth-shaded, textured, RGBA triangle with separate specular
- * color interpolation.
- * Interpolate texcoords with perspective correction, w/out mipmapping.
- */
-static void general_textured_spec_triangle( GLcontext *ctx,
- const SWvertex *v0,
- const SWvertex *v1,
- const SWvertex *v2 )
-{
-#define INTERP_Z 1
-#define INTERP_FOG 1
-#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
-#define INTERP_RGB 1
#define INTERP_SPEC 1
#define INTERP_ALPHA 1
#define INTERP_TEX 1
-#define SETUP_CODE \
- const struct gl_texture_object *obj = ctx->Texture.Unit[0]._Current; \
- const struct gl_texture_image *texImage = obj->Image[obj->BaseLevel];\
- span.texWidth[0] = (GLfloat) texImage->Width; \
- span.texHeight[0] = (GLfloat) texImage->Height; \
- (void) fixedToDepthShift;
-
-#define RENDER_SPAN( span ) rasterize_span(ctx, &span);
-
-#include "s_tritemp.h"
-}
-
-
-/*
- * Render a smooth-shaded, textured, RGBA triangle.
- * Interpolate S,T,R with perspective correction and compute lambda for
- * each fragment. Lambda is used to determine whether to use the
- * minification or magnification filter. If minification and using
- * mipmaps, lambda is also used to select the texture level of detail.
- */
-static void lambda_textured_triangle( GLcontext *ctx,
- const SWvertex *v0,
- const SWvertex *v1,
- const SWvertex *v2 )
-{
-#define INTERP_Z 1
-#define INTERP_FOG 1
-#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
-#define INTERP_RGB 1
-#define INTERP_ALPHA 1
-#define INTERP_TEX 1
-#define INTERP_LAMBDA 1
-
-#define SETUP_CODE \
- const struct gl_texture_object *obj = ctx->Texture.Unit[0]._Current; \
- const struct gl_texture_image *texImage = obj->Image[obj->BaseLevel];\
- span.texWidth[0] = (GLfloat) texImage->Width; \
- span.texHeight[0] = (GLfloat) texImage->Height; \
- (void) fixedToDepthShift;
-
-#define RENDER_SPAN( span ) rasterize_span(ctx, &span);
+#define RENDER_SPAN( span ) _mesa_write_texture_span(ctx, &span);
#include "s_tritemp.h"
}
-/*
- * Render a smooth-shaded, textured, RGBA triangle with separate specular
- * interpolation.
- * Interpolate S,T,R with perspective correction and compute lambda for
- * each fragment. Lambda is used to determine whether to use the
- * minification or magnification filter. If minification and using
- * mipmaps, lambda is also used to select the texture level of detail.
- */
-static void lambda_textured_spec_triangle( GLcontext *ctx,
- const SWvertex *v0,
- const SWvertex *v1,
- const SWvertex *v2 )
-{
-#define INTERP_Z 1
-#define INTERP_FOG 1
-#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
-#define INTERP_RGB 1
-#define INTERP_SPEC 1
-#define INTERP_ALPHA 1
-#define INTERP_TEX 1
-#define INTERP_LAMBDA 1
-
-#define SETUP_CODE \
- const struct gl_texture_object *obj = ctx->Texture.Unit[0]._Current; \
- const struct gl_texture_image *texImage = obj->Image[obj->BaseLevel];\
- span.texWidth[0] = (GLfloat) texImage->Width; \
- span.texHeight[0] = (GLfloat) texImage->Height; \
- (void) fixedToDepthShift;
-
-#define RENDER_SPAN( span ) rasterize_span(ctx, &span);
-
-#include "s_tritemp.h"
-}
-
/*
* This is the big one!
- * Interpolate Z, RGB, Alpha, specular, fog, and N sets of texture coordinates
- * with lambda (LOD).
+ * Interpolate Z, RGB, Alpha, specular, fog, and N sets of texture coordinates.
* Yup, it's slow.
*/
static void
-lambda_multitextured_triangle( GLcontext *ctx,
- const SWvertex *v0,
- const SWvertex *v1,
- const SWvertex *v2 )
+multitextured_triangle( GLcontext *ctx,
+ const SWvertex *v0,
+ const SWvertex *v1,
+ const SWvertex *v2 )
{
#define INTERP_Z 1
@@ -1499,23 +961,8 @@ lambda_multitextured_triangle( GLcontext *ctx,
#define INTERP_ALPHA 1
#define INTERP_SPEC 1
#define INTERP_MULTITEX 1
-#define INTERP_LAMBDA 1
-#define SETUP_CODE \
- GLuint u; \
- for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { \
- if (ctx->Texture.Unit[u]._ReallyEnabled) { \
- const struct gl_texture_object *texObj; \
- const struct gl_texture_image *texImage; \
- texObj = ctx->Texture.Unit[u]._Current; \
- texImage = texObj->Image[texObj->BaseLevel]; \
- span.texWidth[u] = (GLfloat) texImage->Width; \
- span.texHeight[u] = (GLfloat) texImage->Height; \
- } \
- } \
- (void) fixedToDepthShift;
-
-#define RENDER_SPAN( span ) rasterize_span(ctx, &span);
+#define RENDER_SPAN( span ) _mesa_write_texture_span(ctx, &span);
#include "s_tritemp.h"
@@ -1537,7 +984,7 @@ static void occlusion_zless_triangle( GLcontext *ctx,
#define RENDER_SPAN( span ) \
GLuint i; \
- for (i = 0; i < span.count; i++) { \
+ for (i = 0; i < span.end; i++) { \
GLdepth z = FixedToDepth(span.z); \
if (z < zRow[i]) { \
ctx->OcclusionResult = GL_TRUE; \
@@ -1616,13 +1063,13 @@ void _swrast_add_spec_terms_triangle( GLcontext *ctx,
#ifdef DEBUG
/* record the current triangle function name */
-static const char *triFuncName = NULL;
+const char *_mesa_triFuncName = NULL;
-#define USE(triFunc) \
-do { \
- triFuncName = #triFunc; \
- /*printf("%s\n", triFuncName);*/ \
- swrast->Triangle = triFunc; \
+#define USE(triFunc) \
+do { \
+ _mesa_triFuncName = #triFunc; \
+ /*printf("%s\n", _mesa_triFuncName);*/ \
+ swrast->Triangle = triFunc; \
} while (0)
#else
@@ -1678,7 +1125,7 @@ _swrast_choose_triangle( GLcontext *ctx )
}
}
- if (ctx->Texture._ReallyEnabled) {
+ if (ctx->Texture._EnabledUnits) {
/* 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;
@@ -1692,10 +1139,12 @@ _swrast_choose_triangle( GLcontext *ctx )
envMode = ctx->Texture.Unit[0].EnvMode;
/* First see if we can used an optimized 2-D texture function */
- if (ctx->Texture._ReallyEnabled==TEXTURE0_2D
+ if (ctx->Texture._EnabledUnits == 1
+ && ctx->Texture.Unit[0]._ReallyEnabled == TEXTURE_2D_BIT
&& texObj2D->WrapS==GL_REPEAT
&& texObj2D->WrapT==GL_REPEAT
&& texImg->Border==0
+ && texImg->Width == texImg->RowStride
&& (format == MESA_FORMAT_RGB || format == MESA_FORMAT_RGBA)
&& minFilter == magFilter
&& ctx->Light.Model.ColorControl == GL_SINGLE_COLOR
@@ -1733,38 +1182,17 @@ _swrast_choose_triangle( GLcontext *ctx )
}
}
else {
- /* More complicated textures (mipmap, multi-tex, sep specular) */
- GLboolean needLambda;
- /* if mag filter != min filter we need to compute lambda */
- const struct gl_texture_object *obj = ctx->Texture.Unit[0]._Current;
- if (obj && obj->MinFilter != obj->MagFilter)
- needLambda = GL_TRUE;
- else
- needLambda = GL_FALSE;
- if (ctx->Texture._ReallyEnabled > TEXTURE0_ANY) {
- USE(lambda_multitextured_triangle);
- }
- else if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR) {
- /* separate specular color interpolation */
- if (needLambda) {
- USE(lambda_textured_spec_triangle);
- }
- else {
- USE(general_textured_spec_triangle);
- }
+ /* general case textured triangles */
+ if (ctx->Texture._EnabledUnits > 1) {
+ USE(multitextured_triangle);
}
else {
- if (needLambda) {
- USE(lambda_textured_triangle);
- }
- else {
- USE(general_textured_triangle);
- }
+ USE(general_textured_triangle);
}
}
}
else {
- ASSERT(!ctx->Texture._ReallyEnabled);
+ ASSERT(!ctx->Texture._EnabledUnits);
if (ctx->Light.ShadeModel==GL_SMOOTH) {
/* smooth shaded, no texturing, stippled or some raster ops */
if (rgbmode) {
diff --git a/xc/extras/Mesa/src/swrast/s_trispan.h b/xc/extras/Mesa/src/swrast/s_trispan.h
index 9a85132fe..15207e863 100644
--- a/xc/extras/Mesa/src/swrast/s_trispan.h
+++ b/xc/extras/Mesa/src/swrast/s_trispan.h
@@ -1,4 +1,3 @@
-/* $Id: s_trispan.h,v 1.1.1.1 2002/10/22 13:06:42 alanh Exp $ */
/*
* Mesa 3-D graphics library
@@ -29,65 +28,4 @@
#define S_TRISPAN_H
-/*
- * The triangle_span structure is used by the triangle template code in
- * s_tritemp.h. It describes how colors, Z, texcoords, etc are to be
- * interpolated across each scanline of triangle.
- * With this structure it's easy to hand-off span rasterization to a
- * subroutine instead of doing it all inline like we used to do.
- * It also cleans up the local variable namespace a great deal.
- *
- * It would be interesting to experiment with multiprocessor rasterization
- * with this structure. The triangle rasterizer could simply emit a
- * stream of these structures which would be consumed by one or more
- * span-processing threads which could run in parallel.
- */
-
-
-/* When the triangle_span struct is initialized, these flags indicates
- * which values are needed for rendering the triangle.
- */
-#define SPAN_RGBA 0x001
-#define SPAN_SPEC 0x002
-#define SPAN_INDEX 0x004
-#define SPAN_Z 0x008
-#define SPAN_FOG 0x010
-#define SPAN_TEXTURE 0x020
-#define SPAN_INT_TEXTURE 0x040
-#define SPAN_LAMBDA 0x080
-#define SPAN_FLAT 0x100 /* flat shading? */
-
-
-struct triangle_span {
- GLint x, y;
- GLuint count;
- GLuint activeMask; /* OR of the SPAN_* flags */
-#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
- 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;
- GLfloat fog, fogStep;
- GLfloat tex[MAX_TEXTURE_UNITS][4], texStep[MAX_TEXTURE_UNITS][4];
- GLfixed intTex[2], intTexStep[2];
- /* Needed for texture lambda (LOD) computation */
- GLfloat rho[MAX_TEXTURE_UNITS];
- GLfloat texWidth[MAX_TEXTURE_UNITS], texHeight[MAX_TEXTURE_UNITS];
-};
-
-
#endif /* S_TRISPAN_H */
diff --git a/xc/extras/Mesa/src/swrast/s_tritemp.h b/xc/extras/Mesa/src/swrast/s_tritemp.h
index 41306fc03..2feeb8b13 100644
--- a/xc/extras/Mesa/src/swrast/s_tritemp.h
+++ b/xc/extras/Mesa/src/swrast/s_tritemp.h
@@ -1,3 +1,4 @@
+
/*
* Mesa 3-D graphics library
* Version: 3.5
@@ -21,7 +22,7 @@
* 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.
*/
-/* $XFree86: xc/extras/Mesa/src/swrast/s_tritemp.h,v 1.3 2002/09/09 21:07:37 dawes Exp $ */
+/* $XFree86: xc/extras/Mesa/src/swrast/s_tritemp.h,v 1.2 2002/02/27 21:07:54 tsi Exp $ */
/*
* Triangle Rasterizer Template
@@ -41,8 +42,6 @@
* INTERP_TEX - if defined, interpolate set 0 float STRQ texcoords
* NOTE: OpenGL STRQ = Mesa STUV (R was taken for red)
* INTERP_MULTITEX - if defined, interpolate N units of STRQ texcoords
- * INTERP_LAMBDA - if defined, compute lambda value (for mipmapping)
- * a lambda value for every texture unit
* INTERP_FLOAT_RGBA - if defined, interpolate RGBA with floating point
* INTERP_FLOAT_SPEC - if defined, interpolate specular with floating point
*
@@ -115,10 +114,12 @@
GLfloat oneOverArea;
const SWvertex *vMin, *vMid, *vMax; /* Y(vMin)<=Y(vMid)<=Y(vMax) */
float bf = SWRAST_CONTEXT(ctx)->_backface_sign;
- const GLint snapMask = ~((FIXED_ONE / 16) - 1); /* for x/y coord snapping */
+ const GLint snapMask = ~((FIXED_ONE / (1 << SUB_PIXEL_BITS)) - 1); /* for x/y coord snapping */
GLfixed vMin_fx, vMin_fy, vMid_fx, vMid_fy, vMax_fx, vMax_fy;
- struct triangle_span span;
+ struct sw_span span;
+
+ INIT_SPAN(span, GL_POLYGON, 0, 0, 0);
#ifdef INTERP_Z
(void) fixedToDepthShift;
@@ -127,14 +128,8 @@
/*
printf("%s()\n", __FUNCTION__);
printf(" %g, %g, %g\n", v0->win[0], v0->win[1], v0->win[2]);
- printf(" %d, %d, %d, %d\n",
- v0->color[0], v0->color[1], v0->color[2], v0->color[3]);
printf(" %g, %g, %g\n", v1->win[0], v1->win[1], v1->win[2]);
- printf(" %d, %d, %d, %d\n",
- v1->color[0], v1->color[1], v1->color[2], v1->color[3]);
printf(" %g, %g, %g\n", v2->win[0], v2->win[1], v2->win[2]);
- printf(" %d, %d, %d, %d\n",
- v2->color[0], v2->color[1], v2->color[2], v2->color[3]);
*/
/* Compute fixed point x,y coords w/ half-pixel offsets and snapping.
@@ -210,7 +205,7 @@
if (area * bf < 0.0)
return;
- if (area == 0.0F || IS_INF_OR_NAN(area))
+ if (IS_INF_OR_NAN(area) || area == 0.0F)
return;
oneOverArea = 1.0F / area;
@@ -219,6 +214,7 @@
#ifndef DO_OCCLUSION_TEST
ctx->OcclusionResult = GL_TRUE;
#endif
+ span.facing = ctx->_Facing; /* for 2-sided stencil test */
/* Edge setup. For a triangle strip these could be reused... */
{
@@ -319,20 +315,16 @@
GLfloat dtdx, dtdy;
#endif
#ifdef INTERP_TEX
- GLfloat dsdy;
- GLfloat dtdy;
- GLfloat dudy;
- GLfloat dvdy;
+ GLfloat dsdx, dsdy;
+ GLfloat dtdx, dtdy;
+ GLfloat dudx, dudy;
+ GLfloat dvdx, dvdy;
#endif
#ifdef INTERP_MULTITEX
- GLfloat dsdy[MAX_TEXTURE_UNITS];
- GLfloat dtdy[MAX_TEXTURE_UNITS];
- GLfloat dudy[MAX_TEXTURE_UNITS];
- GLfloat dvdy[MAX_TEXTURE_UNITS];
-#endif
-
-#if defined(INTERP_LAMBDA) && !defined(INTERP_TEX) && !defined(INTERP_MULTITEX)
-#error "Mipmapping without texturing doesn't make sense."
+ GLfloat dsdx[MAX_TEXTURE_UNITS], dsdy[MAX_TEXTURE_UNITS];
+ GLfloat dtdx[MAX_TEXTURE_UNITS], dtdy[MAX_TEXTURE_UNITS];
+ GLfloat dudx[MAX_TEXTURE_UNITS], dudy[MAX_TEXTURE_UNITS];
+ GLfloat dvdx[MAX_TEXTURE_UNITS], dvdy[MAX_TEXTURE_UNITS];
#endif
/*
@@ -344,11 +336,10 @@
scan_from_left_to_right = (oneOverArea < 0.0F);
- span.activeMask = 0;
/* compute d?/dx and d?/dy derivatives */
#ifdef INTERP_Z
- span.activeMask |= SPAN_Z;
+ span.interpMask |= SPAN_Z;
{
GLfloat eMaj_dz, eBot_dz;
eMaj_dz = vMax->win[2] - vMin->win[2];
@@ -369,7 +360,7 @@
}
#endif
#ifdef INTERP_FOG
- span.activeMask |= SPAN_FOG;
+ span.interpMask |= SPAN_FOG;
{
const GLfloat eMaj_dfog = vMax->fog - vMin->fog;
const GLfloat eBot_dfog = vMid->fog - vMin->fog;
@@ -378,7 +369,7 @@
}
#endif
#ifdef INTERP_RGB
- span.activeMask |= SPAN_RGBA;
+ span.interpMask |= SPAN_RGBA;
if (ctx->Light.ShadeModel == GL_SMOOTH) {
GLfloat eMaj_dr, eBot_dr;
GLfloat eMaj_dg, eBot_dg;
@@ -419,7 +410,7 @@
}
else {
ASSERT (ctx->Light.ShadeModel == GL_FLAT);
- span.activeMask |= SPAN_FLAT;
+ span.interpMask |= SPAN_FLAT;
drdx = drdy = 0.0F;
dgdx = dgdy = 0.0F;
dbdx = dbdy = 0.0F;
@@ -433,7 +424,7 @@
}
#endif
#ifdef INTERP_FLOAT_RGBA
- span.activeMask |= SPAN_RGBA;
+ span.interpMask |= SPAN_RGBA;
if (ctx->Light.ShadeModel == GL_SMOOTH) {
GLfloat eMaj_dr, eBot_dr;
GLfloat eMaj_dg, eBot_dg;
@@ -468,7 +459,7 @@
}
#endif
#ifdef INTERP_SPEC
- span.activeMask |= SPAN_SPEC;
+ span.interpMask |= SPAN_SPEC;
if (ctx->Light.ShadeModel == GL_SMOOTH) {
GLfloat eMaj_dsr, eBot_dsr;
GLfloat eMaj_dsg, eBot_dsg;
@@ -505,7 +496,7 @@
}
#endif
#ifdef INTERP_FLOAT_SPEC
- span.activeMask |= SPAN_SPEC;
+ span.interpMask |= SPAN_SPEC;
if (ctx->Light.ShadeModel == GL_SMOOTH) {
GLfloat eMaj_dsr, eBot_dsr;
GLfloat eMaj_dsg, eBot_dsg;
@@ -533,7 +524,7 @@
}
#endif
#ifdef INTERP_INDEX
- span.activeMask |= SPAN_INDEX;
+ span.interpMask |= SPAN_INDEX;
if (ctx->Light.ShadeModel == GL_SMOOTH) {
GLfloat eMaj_di, eBot_di;
eMaj_di = (GLfloat) ((GLint) vMax->index - (GLint) vMin->index);
@@ -543,13 +534,13 @@
didy = oneOverArea * (eMaj.dx * eBot_di - eMaj_di * eBot.dx);
}
else {
- span.activeMask |= SPAN_FLAT;
+ span.interpMask |= SPAN_FLAT;
didx = didy = 0.0F;
span.indexStep = 0;
}
#endif
#ifdef INTERP_INT_TEX
- span.activeMask |= SPAN_INT_TEXTURE;
+ span.interpMask |= SPAN_INT_TEXTURE;
{
GLfloat eMaj_ds, eBot_ds;
eMaj_ds = (vMax->texcoord[0][0] - vMin->texcoord[0][0]) * S_SCALE;
@@ -569,7 +560,7 @@
#endif
#ifdef INTERP_TEX
- span.activeMask |= SPAN_TEXTURE;
+ span.interpMask |= SPAN_TEXTURE;
{
GLfloat wMax = vMax->win[3];
GLfloat wMin = vMin->win[3];
@@ -581,46 +572,35 @@
eMaj_ds = vMax->texcoord[0][0] * wMax - vMin->texcoord[0][0] * wMin;
eBot_ds = vMid->texcoord[0][0] * wMid - vMin->texcoord[0][0] * wMin;
- span.texStep[0][0] = oneOverArea * (eMaj_ds * eBot.dy
- - eMaj.dy * eBot_ds);
+ dsdx = oneOverArea * (eMaj_ds * eBot.dy - eMaj.dy * eBot_ds);
dsdy = oneOverArea * (eMaj.dx * eBot_ds - eMaj_ds * eBot.dx);
+ span.texStepX[0][0] = dsdx;
+ span.texStepY[0][0] = dsdy;
eMaj_dt = vMax->texcoord[0][1] * wMax - vMin->texcoord[0][1] * wMin;
eBot_dt = vMid->texcoord[0][1] * wMid - vMin->texcoord[0][1] * wMin;
- span.texStep[0][1] = oneOverArea * (eMaj_dt * eBot.dy
- - eMaj.dy * eBot_dt);
+ dtdx = oneOverArea * (eMaj_dt * eBot.dy - eMaj.dy * eBot_dt);
dtdy = oneOverArea * (eMaj.dx * eBot_dt - eMaj_dt * eBot.dx);
+ span.texStepX[0][1] = dtdx;
+ span.texStepY[0][1] = dtdy;
eMaj_du = vMax->texcoord[0][2] * wMax - vMin->texcoord[0][2] * wMin;
eBot_du = vMid->texcoord[0][2] * wMid - vMin->texcoord[0][2] * wMin;
- span.texStep[0][2] = oneOverArea * (eMaj_du * eBot.dy
- - eMaj.dy * eBot_du);
+ dudx = oneOverArea * (eMaj_du * eBot.dy - eMaj.dy * eBot_du);
dudy = oneOverArea * (eMaj.dx * eBot_du - eMaj_du * eBot.dx);
+ span.texStepX[0][2] = dudx;
+ span.texStepY[0][2] = dudy;
eMaj_dv = vMax->texcoord[0][3] * wMax - vMin->texcoord[0][3] * wMin;
eBot_dv = vMid->texcoord[0][3] * wMid - vMin->texcoord[0][3] * wMin;
- span.texStep[0][3] = oneOverArea * (eMaj_dv * eBot.dy
- - eMaj.dy * eBot_dv);
+ dvdx = oneOverArea * (eMaj_dv * eBot.dy - eMaj.dy * eBot_dv);
dvdy = oneOverArea * (eMaj.dx * eBot_dv - eMaj_dv * eBot.dx);
+ span.texStepX[0][3] = dvdx;
+ span.texStepY[0][3] = dvdy;
}
-# ifdef INTERP_LAMBDA
- {
- GLfloat dudx = span.texStep[0][0] * span.texWidth[0];
- GLfloat dudy = dsdy * span.texWidth[0];
- GLfloat dvdx = span.texStep[0][1] * span.texHeight[0];
- GLfloat dvdy = dtdy * span.texHeight[0];
- GLfloat r1 = dudx * dudx + dudy * dudy;
- GLfloat r2 = dvdx * dvdx + dvdy * dvdy;
- span.rho[0] = r1 + r2; /* was rho2 = MAX2(r1,r2) */
- span.activeMask |= SPAN_LAMBDA;
- }
-# endif
#endif
#ifdef INTERP_MULTITEX
- span.activeMask |= SPAN_TEXTURE;
-# ifdef INTERP_LAMBDA
- span.activeMask |= SPAN_LAMBDA;
-# endif
+ span.interpMask |= SPAN_TEXTURE;
{
GLfloat wMax = vMax->win[3];
GLfloat wMin = vMin->win[3];
@@ -636,44 +616,37 @@
- vMin->texcoord[u][0] * wMin;
eBot_ds = vMid->texcoord[u][0] * wMid
- vMin->texcoord[u][0] * wMin;
- span.texStep[u][0] = oneOverArea * (eMaj_ds * eBot.dy
- - eMaj.dy * eBot_ds);
+ dsdx[u] = oneOverArea * (eMaj_ds * eBot.dy - eMaj.dy * eBot_ds);
dsdy[u] = oneOverArea * (eMaj.dx * eBot_ds - eMaj_ds * eBot.dx);
+ span.texStepX[u][0] = dsdx[u];
+ span.texStepY[u][0] = dsdy[u];
eMaj_dt = vMax->texcoord[u][1] * wMax
- vMin->texcoord[u][1] * wMin;
eBot_dt = vMid->texcoord[u][1] * wMid
- vMin->texcoord[u][1] * wMin;
- span.texStep[u][1] = oneOverArea * (eMaj_dt * eBot.dy
- - eMaj.dy * eBot_dt);
+ dtdx[u] = oneOverArea * (eMaj_dt * eBot.dy - eMaj.dy * eBot_dt);
dtdy[u] = oneOverArea * (eMaj.dx * eBot_dt - eMaj_dt * eBot.dx);
+ span.texStepX[u][1] = dtdx[u];
+ span.texStepY[u][1] = dtdy[u];
eMaj_du = vMax->texcoord[u][2] * wMax
- vMin->texcoord[u][2] * wMin;
eBot_du = vMid->texcoord[u][2] * wMid
- vMin->texcoord[u][2] * wMin;
- span.texStep[u][2] = oneOverArea * (eMaj_du * eBot.dy
- - eMaj.dy * eBot_du);
+ dudx[u] = oneOverArea * (eMaj_du * eBot.dy - eMaj.dy * eBot_du);
dudy[u] = oneOverArea * (eMaj.dx * eBot_du - eMaj_du * eBot.dx);
+ span.texStepX[u][2] = dudx[u];
+ span.texStepY[u][2] = dudy[u];
eMaj_dv = vMax->texcoord[u][3] * wMax
- vMin->texcoord[u][3] * wMin;
eBot_dv = vMid->texcoord[u][3] * wMid
- vMin->texcoord[u][3] * wMin;
- span.texStep[u][3] = oneOverArea * (eMaj_dv * eBot.dy
- - eMaj.dy * eBot_dv);
+ dvdx[u] = oneOverArea * (eMaj_dv * eBot.dy - eMaj.dy * eBot_dv);
dvdy[u] = oneOverArea * (eMaj.dx * eBot_dv - eMaj_dv * eBot.dx);
-# ifdef INTERP_LAMBDA
- {
- GLfloat dudx = span.texStep[u][0] * span.texWidth[u];
- GLfloat dudy = dsdy[u] * span.texWidth[u];
- GLfloat dvdx = span.texStep[u][1] * span.texHeight[u];
- GLfloat dvdy = dtdy[u] * span.texHeight[u];
- GLfloat r1 = dudx * dudx + dudy * dudy;
- GLfloat r2 = dvdx * dvdx + dvdy * dvdy;
- span.rho[u] = r1 + r2; /* was rho2 = MAX2(r1,r2) */
- }
-# endif
+ span.texStepX[u][3] = dvdx[u];
+ span.texStepY[u][3] = dvdy[u];
}
}
}
@@ -1033,21 +1006,21 @@
GLfloat invW = vLower->win[3];
GLfloat s0, t0, u0, v0;
s0 = vLower->texcoord[0][0] * invW;
- sLeft = s0 + (span.texStep[0][0] * adjx + dsdy * adjy)
+ sLeft = s0 + (span.texStepX[0][0] * adjx + dsdy * adjy)
* (1.0F/FIXED_SCALE);
- dsOuter = dsdy + dxOuter * span.texStep[0][0];
+ dsOuter = dsdy + dxOuter * span.texStepX[0][0];
t0 = vLower->texcoord[0][1] * invW;
- tLeft = t0 + (span.texStep[0][1] * adjx + dtdy * adjy)
+ tLeft = t0 + (span.texStepX[0][1] * adjx + dtdy * adjy)
* (1.0F/FIXED_SCALE);
- dtOuter = dtdy + dxOuter * span.texStep[0][1];
+ dtOuter = dtdy + dxOuter * span.texStepX[0][1];
u0 = vLower->texcoord[0][2] * invW;
- uLeft = u0 + (span.texStep[0][2] * adjx + dudy * adjy)
+ uLeft = u0 + (span.texStepX[0][2] * adjx + dudy * adjy)
* (1.0F/FIXED_SCALE);
- duOuter = dudy + dxOuter * span.texStep[0][2];
+ duOuter = dudy + dxOuter * span.texStepX[0][2];
v0 = vLower->texcoord[0][3] * invW;
- vLeft = v0 + (span.texStep[0][3] * adjx + dvdy * adjy)
+ vLeft = v0 + (span.texStepX[0][3] * adjx + dvdy * adjy)
* (1.0F/FIXED_SCALE);
- dvOuter = dvdy + dxOuter * span.texStep[0][3];
+ dvOuter = dvdy + dxOuter * span.texStepX[0][3];
}
#endif
#ifdef INTERP_MULTITEX
@@ -1058,21 +1031,21 @@
GLfloat invW = vLower->win[3];
GLfloat s0, t0, u0, v0;
s0 = vLower->texcoord[u][0] * invW;
- sLeft[u] = s0 + (span.texStep[u][0] * adjx + dsdy[u]
+ sLeft[u] = s0 + (span.texStepX[u][0] * adjx + dsdy[u]
* adjy) * (1.0F/FIXED_SCALE);
- dsOuter[u] = dsdy[u] + dxOuter * span.texStep[u][0];
+ dsOuter[u] = dsdy[u] + dxOuter * span.texStepX[u][0];
t0 = vLower->texcoord[u][1] * invW;
- tLeft[u] = t0 + (span.texStep[u][1] * adjx + dtdy[u]
+ tLeft[u] = t0 + (span.texStepX[u][1] * adjx + dtdy[u]
* adjy) * (1.0F/FIXED_SCALE);
- dtOuter[u] = dtdy[u] + dxOuter * span.texStep[u][1];
+ dtOuter[u] = dtdy[u] + dxOuter * span.texStepX[u][1];
u0 = vLower->texcoord[u][2] * invW;
- uLeft[u] = u0 + (span.texStep[u][2] * adjx + dudy[u]
+ uLeft[u] = u0 + (span.texStepX[u][2] * adjx + dudy[u]
* adjy) * (1.0F/FIXED_SCALE);
- duOuter[u] = dudy[u] + dxOuter * span.texStep[u][2];
+ duOuter[u] = dudy[u] + dxOuter * span.texStepX[u][2];
v0 = vLower->texcoord[u][3] * invW;
- vLeft[u] = v0 + (span.texStep[u][3] * adjx + dvdy[u]
+ vLeft[u] = v0 + (span.texStepX[u][3] * adjx + dvdy[u]
* adjy) * (1.0F/FIXED_SCALE);
- dvOuter[u] = dvdy[u] + dxOuter * span.texStep[u][3];
+ dvOuter[u] = dvdy[u] + dxOuter * span.texStepX[u][3];
}
}
}
@@ -1125,20 +1098,20 @@
fdtInner = fdtOuter + span.intTexStep[1];
#endif
#ifdef INTERP_TEX
- dsInner = dsOuter + span.texStep[0][0];
- dtInner = dtOuter + span.texStep[0][1];
- duInner = duOuter + span.texStep[0][2];
- dvInner = dvOuter + span.texStep[0][3];
+ dsInner = dsOuter + span.texStepX[0][0];
+ dtInner = dtOuter + span.texStepX[0][1];
+ duInner = duOuter + span.texStepX[0][2];
+ dvInner = dvOuter + span.texStepX[0][3];
#endif
#ifdef INTERP_MULTITEX
{
GLuint u;
for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
if (ctx->Texture.Unit[u]._ReallyEnabled) {
- dsInner[u] = dsOuter[u] + span.texStep[u][0];
- dtInner[u] = dtOuter[u] + span.texStep[u][1];
- duInner[u] = duOuter[u] + span.texStep[u][2];
- dvInner[u] = dvOuter[u] + span.texStep[u][3];
+ dsInner[u] = dsOuter[u] + span.texStepX[u][0];
+ dtInner[u] = dtOuter[u] + span.texStepX[u][1];
+ duInner[u] = duOuter[u] + span.texStepX[u][2];
+ dvInner[u] = dvOuter[u] + span.texStepX[u][3];
}
}
}
@@ -1148,11 +1121,13 @@
/* initialize the span interpolants to the leftmost value */
/* ff = fixed-pt fragment */
const GLint right = FixedToInt(fxRightEdge);
+
span.x = FixedToInt(fxLeftEdge);
+
if (right <= span.x)
- span.count = 0;
+ span.end = 0;
else
- span.count = right - span.x;
+ span.end = right - span.x;
#ifdef INTERP_Z
span.z = fz;
@@ -1266,7 +1241,7 @@
#endif
/* This is where we actually generate fragments */
- if (span.count > 0) {
+ if (span.end > 0) {
RENDER_SPAN( span );
}
@@ -1276,7 +1251,7 @@
* pixel-center x coordinate so that it stays
* on or inside the major edge.
*/
- span.y++;
+ (span.y)++;
lines--;
fxLeftEdge += fdxLeftEdge;
@@ -1419,7 +1394,6 @@
#undef INTERP_INT_TEX
#undef INTERP_TEX
#undef INTERP_MULTITEX
-#undef INTERP_LAMBDA
#undef INTERP_FLOAT_RGBA
#undef INTERP_FLOAT_SPEC
diff --git a/xc/extras/Mesa/src/swrast/s_zoom.c b/xc/extras/Mesa/src/swrast/s_zoom.c
index b56128147..0d1f08458 100644
--- a/xc/extras/Mesa/src/swrast/s_zoom.c
+++ b/xc/extras/Mesa/src/swrast/s_zoom.c
@@ -1,8 +1,7 @@
-/* $Id: s_zoom.c,v 1.1.1.1 2002/10/22 13:06:58 alanh Exp $ */
/*
* Mesa 3-D graphics library
- * Version: 4.0.3
+ * Version: 4.1
*
* Copyright (C) 1999-2002 Brian Paul All Rights Reserved.
*
@@ -26,6 +25,8 @@
#include "glheader.h"
#include "macros.h"
+#include "imports.h"
+#include "colormac.h"
#include "s_context.h"
#include "s_span.h"
@@ -33,342 +34,229 @@
#include "s_zoom.h"
-
/*
- * Write a span of pixels to the frame buffer while applying a pixel zoom.
- * This is only used by glDrawPixels and glCopyPixels.
- * Input: n - number of pixels in input row
- * x, y - destination of the span
- * z - depth values for the span
- * red, green, blue, alpha - array of colors
- * y0 - location of first row in the image we're drawing.
+ * Helper function called from _mesa_write_zoomed_rgba/rgb/index_span().
*/
-void
-_mesa_write_zoomed_rgba_span( GLcontext *ctx,
- GLuint n, GLint x, GLint y, const GLdepth z[],
- const GLfloat *fog,
- CONST GLchan rgba[][4], GLint y0 )
+static void
+zoom_span( GLcontext *ctx, const struct sw_span *span,
+ const GLvoid *src, GLint y0, GLenum format )
{
- GLint m;
- GLint r0, r1, row, r;
- GLint i, j, skipcol;
- GLchan zrgba[MAX_WIDTH][4]; /* zoomed pixel colors */
- GLdepth zdepth[MAX_WIDTH]; /* zoomed depth values */
- GLfloat zfog[MAX_WIDTH]; /* zoomed fog values */
- GLint maxwidth = MIN2( ctx->DrawBuffer->Width, MAX_WIDTH );
- const GLuint *srcRGBA32 = (const GLuint *) rgba;
- GLuint *dstRGBA32 = (GLuint *) zrgba;
-
- /* compute width of output row */
- m = (GLint) ABSF( n * ctx->Pixel.ZoomX );
- if (m==0) {
+ GLint r0, r1, row;
+ GLint c0, c1, skipCol;
+ GLint i, j;
+ const GLuint maxWidth = MIN2( ctx->DrawBuffer->Width, MAX_WIDTH );
+ GLchan rgbaSave[MAX_WIDTH][4];
+ GLuint indexSave[MAX_WIDTH];
+ const GLchan (*rgba)[4] = (const GLchan (*)[4]) src;
+ const GLchan (*rgb)[3] = (const GLchan (*)[3]) src;
+ const GLuint *indexes = (const GLuint *) src;
+ struct sw_span zoomed;
+ struct span_arrays zoomed_arrays; /* this is big! */
+
+ /* no pixel arrays! */
+ ASSERT((span->arrayMask & SPAN_XY) == 0);
+ ASSERT(span->primitive == GL_BITMAP);
+
+ INIT_SPAN(zoomed, GL_BITMAP, 0, 0, 0);
+ zoomed.array = &zoomed_arrays;
+
+ if (format == GL_RGBA || format == GL_RGB) {
+ zoomed.z = span->z;
+ zoomed.zStep = span->z;
+ zoomed.fog = span->fog;
+ zoomed.fogStep = span->fogStep;
+ zoomed.interpMask = span->interpMask & ~SPAN_RGBA;
+ zoomed.arrayMask |= SPAN_RGBA;
+ }
+ else if (format == GL_COLOR_INDEX) {
+ zoomed.z = span->z;
+ zoomed.zStep = span->z;
+ zoomed.fog = span->fog;
+ zoomed.fogStep = span->fogStep;
+ zoomed.interpMask = span->interpMask & ~SPAN_INDEX;
+ zoomed.arrayMask |= SPAN_INDEX;
+ }
+
+ /*
+ * Compute which columns to draw: [c0, c1)
+ */
+ c0 = (GLint) span->x;
+ c1 = (GLint) (span->x + span->end * ctx->Pixel.ZoomX);
+ if (c0 == c1) {
return;
}
- if (ctx->Pixel.ZoomX<0.0) {
- /* adjust x coordinate for left/right mirroring */
- x = x - m;
+ else if (c1 < c0) {
+ /* swap */
+ GLint ctmp = c1;
+ c1 = c0;
+ c0 = ctmp;
}
-
- /* compute which rows to draw */
- row = y-y0;
+ if (c0 < 0) {
+ zoomed.x = 0;
+ zoomed.start = 0;
+ zoomed.end = c1;
+ skipCol = -c0;
+ }
+ else {
+ zoomed.x = c0;
+ zoomed.start = 0;
+ zoomed.end = c1 - c0;
+ skipCol = 0;
+ }
+ if (zoomed.end > maxWidth)
+ zoomed.end = maxWidth;
+
+ /*
+ * Compute which rows to draw: [r0, r1)
+ */
+ row = span->y - y0;
r0 = y0 + (GLint) (row * ctx->Pixel.ZoomY);
r1 = y0 + (GLint) ((row+1) * ctx->Pixel.ZoomY);
- if (r0==r1) {
+ if (r0 == r1) {
return;
}
- else if (r1<r0) {
+ else if (r1 < r0) {
+ /* swap */
GLint rtmp = r1;
r1 = r0;
r0 = rtmp;
}
- /* return early if r0...r1 is above or below window */
- if (r0<0 && r1<0) {
- /* below window */
+ ASSERT(r0 < r1);
+ ASSERT(c0 < c1);
+
+ /*
+ * Trivial clip rejection testing.
+ */
+ if (r1 < 0) /* below window */
return;
- }
- if (r0 >= (GLint) ctx->DrawBuffer->Height &&
- r1 >= (GLint) ctx->DrawBuffer->Height) {
- /* above window */
+ if (r0 >= (GLint) ctx->DrawBuffer->Height) /* above window */
return;
- }
-
- /* check if left edge is outside window */
- skipcol = 0;
- if (x<0) {
- skipcol = -x;
- m += x;
- }
- /* make sure span isn't too long or short */
- if (m>maxwidth) {
- m = maxwidth;
- }
- else if (m<=0) {
+ if (c1 < 0) /* left of window */
+ return;
+ if (c0 >= (GLint) ctx->DrawBuffer->Width) /* right of window */
return;
- }
-
- assert( m <= MAX_WIDTH );
/* zoom the span horizontally */
- if (ctx->Pixel.ZoomX==-1.0F) {
- /* n==m */
- for (j=0;j<m;j++) {
- i = n - (j+skipcol) - 1;
- dstRGBA32[j] = srcRGBA32[i];
- zdepth[j] = z[i];
+ if (format == GL_RGBA) {
+ if (ctx->Pixel.ZoomX == -1.0F) {
+ /* common case */
+ for (j = (GLint) zoomed.start; j < (GLint) zoomed.end; j++) {
+ i = span->end - (j + skipCol) - 1;
+ COPY_CHAN4(zoomed.array->rgba[j], rgba[i]);
+ }
}
- if (fog && ctx->Fog.Enabled) {
- for (j=0;j<m;j++) {
- i = n - (j+skipcol) - 1;
- zfog[j] = fog[i];
- }
+ else {
+ /* general solution */
+ const GLfloat xscale = 1.0F / ctx->Pixel.ZoomX;
+ for (j = (GLint) zoomed.start; j < (GLint) zoomed.end; j++) {
+ i = (GLint) ((j + skipCol) * xscale);
+ if (i < 0)
+ i = span->end + i - 1;
+ COPY_CHAN4(zoomed.array->rgba[j], rgba[i]);
+ }
}
}
- else {
- GLfloat xscale = 1.0F / ctx->Pixel.ZoomX;
- for (j=0;j<m;j++) {
- i = (GLint) ((j+skipcol) * xscale);
- if (i<0) i = n + i - 1;
- dstRGBA32[j] = srcRGBA32[i];
- zdepth[j] = z[i];
+ else if (format == GL_RGB) {
+ if (ctx->Pixel.ZoomX == -1.0F) {
+ /* common case */
+ for (j = (GLint) zoomed.start; j < (GLint) zoomed.end; j++) {
+ i = span->end - (j + skipCol) - 1;
+ zoomed.array->rgba[j][0] = rgb[i][0];
+ zoomed.array->rgba[j][1] = rgb[i][1];
+ zoomed.array->rgba[j][2] = rgb[i][2];
+ zoomed.array->rgba[j][3] = CHAN_MAX;
+ }
}
- if (fog && ctx->Fog.Enabled) {
- for (j=0;j<m;j++) {
- i = (GLint) ((j+skipcol) * xscale);
- if (i<0) i = n + i - 1;
- zfog[j] = fog[i];
- }
+ else {
+ /* general solution */
+ const GLfloat xscale = 1.0F / ctx->Pixel.ZoomX;
+ for (j = (GLint) zoomed.start; j < (GLint) zoomed.end; j++) {
+ i = (GLint) ((j + skipCol) * xscale);
+ if (i < 0)
+ i = span->end + i - 1;
+ zoomed.array->rgba[j][0] = rgb[i][0];
+ zoomed.array->rgba[j][1] = rgb[i][1];
+ zoomed.array->rgba[j][2] = rgb[i][2];
+ zoomed.array->rgba[j][3] = CHAN_MAX;
+ }
}
}
-
- /* write the span */
- for (r=r0; r<r1; r++) {
- _mesa_write_rgba_span( ctx, m, x+skipcol, r, zdepth,
- (fog ? zfog : 0), zrgba, NULL, GL_BITMAP );
- }
-}
-
-
-
-void
-_mesa_write_zoomed_rgb_span( GLcontext *ctx,
- GLuint n, GLint x, GLint y, const GLdepth z[],
- const GLfloat *fog,
- CONST GLchan rgb[][3], GLint y0 )
-{
- GLint m;
- GLint r0, r1, row, r;
- GLint i, j, skipcol;
- GLchan zrgba[MAX_WIDTH][4]; /* zoomed pixel colors */
- GLdepth zdepth[MAX_WIDTH]; /* zoomed depth values */
- GLfloat zfog[MAX_WIDTH]; /* zoomed fog values */
- GLint maxwidth = MIN2( ctx->DrawBuffer->Width, MAX_WIDTH );
-
- /* compute width of output row */
- m = (GLint) ABSF( n * ctx->Pixel.ZoomX );
- if (m==0) {
- return;
- }
- if (ctx->Pixel.ZoomX<0.0) {
- /* adjust x coordinate for left/right mirroring */
- x = x - m;
- }
-
- /* compute which rows to draw */
- row = y-y0;
- r0 = y0 + (GLint) (row * ctx->Pixel.ZoomY);
- r1 = y0 + (GLint) ((row+1) * ctx->Pixel.ZoomY);
- if (r0==r1) {
- return;
- }
- else if (r1<r0) {
- GLint rtmp = r1;
- r1 = r0;
- r0 = rtmp;
- }
-
- /* return early if r0...r1 is above or below window */
- if (r0<0 && r1<0) {
- /* below window */
- return;
- }
- if (r0 >= (GLint) ctx->DrawBuffer->Height &&
- r1 >= (GLint) ctx->DrawBuffer->Height) {
- /* above window */
- return;
- }
-
- /* check if left edge is outside window */
- skipcol = 0;
- if (x<0) {
- skipcol = -x;
- m += x;
- }
- /* make sure span isn't too long or short */
- if (m>maxwidth) {
- m = maxwidth;
- }
- else if (m<=0) {
- return;
+ else if (format == GL_COLOR_INDEX) {
+ if (ctx->Pixel.ZoomX == -1.0F) {
+ /* common case */
+ for (j = (GLint) zoomed.start; j < (GLint) zoomed.end; j++) {
+ i = span->end - (j + skipCol) - 1;
+ zoomed.array->index[j] = indexes[i];
+ }
+ }
+ else {
+ /* general solution */
+ const GLfloat xscale = 1.0F / ctx->Pixel.ZoomX;
+ for (j = (GLint) zoomed.start; j < (GLint) zoomed.end; j++) {
+ i = (GLint) ((j + skipCol) * xscale);
+ if (i < 0)
+ i = span->end + i - 1;
+ zoomed.array->index[j] = indexes[i];
+ }
+ }
}
- assert( m <= MAX_WIDTH );
-
- /* zoom the span horizontally */
- if (ctx->Pixel.ZoomX==-1.0F) {
- /* n==m */
- for (j=0;j<m;j++) {
- i = n - (j+skipcol) - 1;
- zrgba[j][0] = rgb[i][0];
- zrgba[j][1] = rgb[i][1];
- zrgba[j][2] = rgb[i][2];
- zrgba[j][3] = CHAN_MAX;
- zdepth[j] = z[i];
+ /* write the span in rows [r0, r1) */
+ if (format == GL_RGBA || format == GL_RGB) {
+ /* Writing the span may modify the colors, so make a backup now if we're
+ * going to call _mesa_write_zoomed_span() more than once.
+ */
+ if (r1 - r0 > 1) {
+ MEMCPY(rgbaSave, zoomed.array->rgba, zoomed.end * 4 * sizeof(GLchan));
}
- if (fog && ctx->Fog.Enabled) {
- for (j=0;j<m;j++) {
- i = n - (j+skipcol) - 1;
- zfog[j] = fog[i];
- }
+ for (zoomed.y = r0; zoomed.y < r1; zoomed.y++) {
+ _mesa_write_rgba_span(ctx, &zoomed);
+ if (r1 - r0 > 1) {
+ /* restore the colors */
+ MEMCPY(zoomed.array->rgba, rgbaSave, zoomed.end*4 * sizeof(GLchan));
+ }
}
}
- else {
- GLfloat xscale = 1.0F / ctx->Pixel.ZoomX;
- for (j=0;j<m;j++) {
- i = (GLint) ((j+skipcol) * xscale);
- if (i<0) i = n + i - 1;
- zrgba[j][0] = rgb[i][0];
- zrgba[j][1] = rgb[i][1];
- zrgba[j][2] = rgb[i][2];
- zrgba[j][3] = CHAN_MAX;
- zdepth[j] = z[i];
+ else if (format == GL_COLOR_INDEX) {
+ if (r1 - r0 > 1) {
+ MEMCPY(indexSave, zoomed.array->index, zoomed.end * sizeof(GLuint));
}
- if (fog && ctx->Fog.Enabled) {
- for (j=0;j<m;j++) {
- i = (GLint) ((j+skipcol) * xscale);
- if (i<0) i = n + i - 1;
- zfog[j] = fog[i];
- }
+ for (zoomed.y = r0; zoomed.y < r1; zoomed.y++) {
+ _mesa_write_index_span(ctx, &zoomed);
+ if (r1 - r0 > 1) {
+ /* restore the colors */
+ MEMCPY(zoomed.array->index, indexSave, zoomed.end * sizeof(GLuint));
+ }
}
}
-
- /* write the span */
- for (r=r0; r<r1; r++) {
- _mesa_write_rgba_span( ctx, m, x+skipcol, r, zdepth,
- (fog ? zfog : 0), zrgba, NULL, GL_BITMAP );
- }
}
-
-/*
- * As above, but write CI pixels.
- */
void
-_mesa_write_zoomed_index_span( GLcontext *ctx,
- GLuint n, GLint x, GLint y, const GLdepth z[],
- const GLfloat *fog,
- const GLuint indexes[], GLint y0 )
+_mesa_write_zoomed_rgba_span( GLcontext *ctx, const struct sw_span *span,
+ CONST GLchan rgba[][4], GLint y0 )
{
- GLint m;
- GLint r0, r1, row, r;
- GLint i, j, skipcol;
- GLuint zindexes[MAX_WIDTH]; /* zoomed color indexes */
- GLdepth zdepth[MAX_WIDTH]; /* zoomed depth values */
- GLfloat zfog[MAX_WIDTH]; /* zoomed fog values */
- GLint maxwidth = MIN2( ctx->DrawBuffer->Width, MAX_WIDTH );
-
- /* compute width of output row */
- m = (GLint) ABSF( n * ctx->Pixel.ZoomX );
- if (m==0) {
- return;
- }
- if (ctx->Pixel.ZoomX<0.0) {
- /* adjust x coordinate for left/right mirroring */
- x = x - m;
- }
-
- /* compute which rows to draw */
- row = y-y0;
- r0 = y0 + (GLint) (row * ctx->Pixel.ZoomY);
- r1 = y0 + (GLint) ((row+1) * ctx->Pixel.ZoomY);
- if (r0==r1) {
- return;
- }
- else if (r1<r0) {
- GLint rtmp = r1;
- r1 = r0;
- r0 = rtmp;
- }
-
- /* return early if r0...r1 is above or below window */
- if (r0<0 && r1<0) {
- /* below window */
- return;
- }
- if (r0 >= (GLint) ctx->DrawBuffer->Height &&
- r1 >= (GLint) ctx->DrawBuffer->Height) {
- /* above window */
- return;
- }
+ zoom_span(ctx, span, (const GLvoid *) rgba, y0, GL_RGBA);
+}
- /* check if left edge is outside window */
- skipcol = 0;
- if (x<0) {
- skipcol = -x;
- m += x;
- }
- /* make sure span isn't too long or short */
- if (m>maxwidth) {
- m = maxwidth;
- }
- else if (m<=0) {
- return;
- }
- assert( m <= MAX_WIDTH );
+void
+_mesa_write_zoomed_rgb_span( GLcontext *ctx, const struct sw_span *span,
+ CONST GLchan rgb[][3], GLint y0 )
+{
+ zoom_span(ctx, span, (const GLvoid *) rgb, y0, GL_RGB);
+}
- /* zoom the span horizontally */
- if (ctx->Pixel.ZoomX==-1.0F) {
- /* n==m */
- for (j=0;j<m;j++) {
- i = n - (j+skipcol) - 1;
- zindexes[j] = indexes[i];
- zdepth[j] = z[i];
- }
- if (fog && ctx->Fog.Enabled) {
- for (j=0;j<m;j++) {
- i = n - (j+skipcol) - 1;
- zfog[j] = fog[i];
- }
- }
- }
- else {
- GLfloat xscale = 1.0F / ctx->Pixel.ZoomX;
- for (j=0;j<m;j++) {
- i = (GLint) ((j+skipcol) * xscale);
- if (i<0) i = n + i - 1;
- zindexes[j] = indexes[i];
- zdepth[j] = z[i];
- }
- if (fog && ctx->Fog.Enabled) {
- for (j=0;j<m;j++) {
- i = (GLint) ((j+skipcol) * xscale);
- if (i<0) i = n + i - 1;
- zfog[j] = fog[i];
- }
- }
- }
- /* write the span */
- for (r=r0; r<r1; r++) {
- _mesa_write_index_span( ctx, m, x+skipcol, r, zdepth,
- (fog ? zfog : 0), zindexes, NULL, GL_BITMAP );
- }
+void
+_mesa_write_zoomed_index_span( GLcontext *ctx, const struct sw_span *span,
+ GLint y0 )
+{
+ zoom_span(ctx, span, (const GLvoid *) span->array->index, y0, GL_COLOR_INDEX);
}
-
/*
* As above, but write stencil values.
*/
@@ -431,7 +319,7 @@ _mesa_write_zoomed_stencil_span( GLcontext *ctx,
return;
}
- assert( m <= MAX_WIDTH );
+ ASSERT( m <= MAX_WIDTH );
/* zoom the span horizontally */
if (ctx->Pixel.ZoomX==-1.0F) {
diff --git a/xc/extras/Mesa/src/swrast/s_zoom.h b/xc/extras/Mesa/src/swrast/s_zoom.h
index a55223607..bdc7013e0 100644
--- a/xc/extras/Mesa/src/swrast/s_zoom.h
+++ b/xc/extras/Mesa/src/swrast/s_zoom.h
@@ -1,10 +1,9 @@
-/* $Id: s_zoom.h,v 1.1.1.1 2002/10/22 13:06:58 alanh Exp $ */
/*
* Mesa 3-D graphics library
- * Version: 3.5
+ * Version: 4.1
*
- * Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
+ * Copyright (C) 1999-2002 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"),
@@ -24,39 +23,26 @@
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
-
#ifndef S_ZOOM_H
#define S_ZOOM_H
-
#include "mtypes.h"
-
+#include "swrast.h"
extern void
-_mesa_write_zoomed_rgba_span( GLcontext *ctx,
- GLuint n, GLint x, GLint y, const GLdepth z[],
- const GLfloat *fog,
- CONST GLchan rgba[][4], GLint y0 );
-
+_mesa_write_zoomed_rgba_span( GLcontext *ctx, const struct sw_span *span,
+ CONST GLchan rgb[][4], GLint y0 );
extern void
-_mesa_write_zoomed_rgb_span( GLcontext *ctx,
- GLuint n, GLint x, GLint y, const GLdepth z[],
- const GLfloat *fog,
+_mesa_write_zoomed_rgb_span( GLcontext *ctx, const struct sw_span *span,
CONST GLchan rgb[][3], GLint y0 );
-
extern void
-_mesa_write_zoomed_index_span( GLcontext *ctx,
- GLuint n, GLint x, GLint y, const GLdepth z[],
- const GLfloat *fog,
- const GLuint indexes[], GLint y0 );
-
+_mesa_write_zoomed_index_span( GLcontext *ctx, const struct sw_span *span,
+ GLint y0 );
extern void
-_mesa_write_zoomed_stencil_span( GLcontext *ctx,
- GLuint n, GLint x, GLint y,
+_mesa_write_zoomed_stencil_span( GLcontext *ctx, GLuint n, GLint x, GLint y,
const GLstencil stencil[], GLint y0 );
-
#endif
diff --git a/xc/extras/Mesa/src/swrast/swrast.h b/xc/extras/Mesa/src/swrast/swrast.h
index 7149be8fb..76e9ca24d 100644
--- a/xc/extras/Mesa/src/swrast/swrast.h
+++ b/xc/extras/Mesa/src/swrast/swrast.h
@@ -1,10 +1,9 @@
-/* $Id: swrast.h,v 1.1.1.1 2002/10/22 13:06:46 alanh Exp $ */
/*
* Mesa 3-D graphics library
- * Version: 3.5
+ * Version: 4.1
*
- * Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
+ * Copyright (C) 1999-2002 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -23,8 +22,12 @@
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
- * Authors:
- * Keith Whitwell <keithw@valinux.com>
+ */
+
+/**
+ * \file swrast/swrast.h
+ * \brief Defines basic structures for sw_rasterizer.
+ * \author Keith Whitwell <keith@tungstengraphics.com>
*/
#ifndef SWRAST_H
@@ -32,9 +35,11 @@
#include "mtypes.h"
-
-
-/* The software rasterizer now uses this format for vertices. Thus a
+/**
+ * \struct SWvertex
+ * \brief Data-structure to handle vertices in the software rasterizer.
+ *
+ * The software rasterizer now uses this format for vertices. Thus a
* 'RasterSetup' stage or other translation is required between the
* tnl module and the swrast rasterization functions. This serves to
* isolate the swrast module from the internals of the tnl module, and
@@ -57,6 +62,8 @@
* primitives unaccelerated), hook in swrast_setup instead.
*/
typedef struct {
+ /** win[0], win[1] are the screen-coords of SWvertex. win[2] is the
+ * z-coord. what is win[3]? */
GLfloat win[4];
GLfloat texcoord[MAX_TEXTURE_UNITS][4];
GLchan color[4];
@@ -67,6 +74,154 @@ typedef struct {
} SWvertex;
+/**
+ * \struct sw_span
+ * \brief Contains data for either a horizontal line or a set of
+ * pixels that are passed through a pipeline of functions before being
+ * drawn.
+ *
+ * The sw_span structure describes the colors, Z, fogcoord, texcoords,
+ * etc for either a horizontal run or a set of independent pixels. We
+ * can either specify a base/step to indicate interpolated values, or
+ * fill in arrays of values. The interpMask and arrayMask bitfields
+ * indicate which are active.
+ *
+ * With this structure it's easy to hand-off span rasterization to
+ * subroutines instead of doing it all inline in the triangle functions
+ * like we used to do.
+ * It also cleans up the local variable namespace a great deal.
+ *
+ * It would be interesting to experiment with multiprocessor rasterization
+ * with this structure. The triangle rasterizer could simply emit a
+ * stream of these structures which would be consumed by one or more
+ * span-processing threads which could run in parallel.
+ */
+
+
+/**
+ * \defgroup SpanFlags SPAN_XXX-flags
+ * Bitmasks to indicate which span_arrays need to be computed
+ * (sw_span::interpMask) or have already been filled
+ * (sw_span::arrayMask)
+ */
+/*@{*/
+#define SPAN_RGBA 0x001
+#define SPAN_SPEC 0x002
+#define SPAN_INDEX 0x004
+#define SPAN_Z 0x008
+#define SPAN_FOG 0x010
+#define SPAN_TEXTURE 0x020
+#define SPAN_INT_TEXTURE 0x040
+#define SPAN_LAMBDA 0x080
+#define SPAN_COVERAGE 0x100
+#define SPAN_FLAT 0x200 /**< flat shading? */
+/** sw_span::arrayMask only - for span_arrays::x, span_arrays::y */
+#define SPAN_XY 0x400
+#define SPAN_MASK 0x800 /**< sw_span::arrayMask only */
+/*@}*/
+
+
+/**
+ * \struct span_arrays
+ * \brief Arrays of fragment values.
+ *
+ * These will either be computed from the x/xStep values above or
+ * filled in by glDraw/CopyPixels, etc.
+ */
+struct span_arrays {
+ GLchan rgb[MAX_WIDTH][3];
+ GLchan rgba[MAX_WIDTH][4];
+ GLuint index[MAX_WIDTH];
+ GLchan spec[MAX_WIDTH][4]; /* specular color */
+ GLint x[MAX_WIDTH]; /**< X/Y used for point/line rendering only */
+ GLint y[MAX_WIDTH]; /**< X/Y used for point/line rendering only */
+ GLdepth z[MAX_WIDTH];
+ GLfloat fog[MAX_WIDTH];
+ GLfloat texcoords[MAX_TEXTURE_UNITS][MAX_WIDTH][4];
+ GLfloat lambda[MAX_TEXTURE_UNITS][MAX_WIDTH];
+ GLfloat coverage[MAX_WIDTH];
+
+ /** This mask indicates if fragment is alive or culled */
+ GLubyte mask[MAX_WIDTH];
+};
+
+
+struct sw_span {
+ GLint x, y;
+
+ /** Only need to process pixels between start <= i < end */
+ /** At this time, start is always zero. */
+ GLuint start, end;
+
+ /** This flag indicates that mask[] array is effectively filled with ones */
+ GLboolean writeAll;
+
+ /** either GL_POLYGON, GL_LINE, GL_POLYGON, GL_BITMAP */
+ GLenum primitive;
+
+ /** 0 = front-facing span, 1 = back-facing span (for two-sided stencil) */
+ GLuint facing;
+
+ /**
+ * This bitmask (of \link SpanFlags SPAN_* flags\endlink) indicates
+ * which of the x/xStep variables are relevant.
+ */
+ GLuint interpMask;
+
+#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;
+ GLfloat fog, fogStep;
+ GLfloat tex[MAX_TEXTURE_UNITS][4];
+ GLfloat texStepX[MAX_TEXTURE_UNITS][4];
+ GLfloat texStepY[MAX_TEXTURE_UNITS][4];
+ GLfixed intTex[2], intTexStep[2];
+
+ /**
+ * This bitmask (of \link SpanFlags SPAN_* flags\endlink) indicates
+ * which of the fragment arrays in the span_arrays struct are relevant.
+ */
+ GLuint arrayMask;
+
+ /**
+ * We store the arrays of fragment values in a separate struct so
+ * that we can allocate sw_span structs on the stack without using
+ * a lot of memory. The span_arrays struct is about 400KB while the
+ * sw_span struct is only about 512 bytes.
+ */
+ struct span_arrays *array;
+};
+
+
+#define INIT_SPAN(S, PRIMITIVE, END, INTERP_MASK, ARRAY_MASK) \
+do { \
+ (S).primitive = (PRIMITIVE); \
+ (S).interpMask = (INTERP_MASK); \
+ (S).arrayMask = (ARRAY_MASK); \
+ (S).start = 0; \
+ (S).end = (END); \
+ (S).facing = 0; \
+ (S).array = SWRAST_CONTEXT(ctx)->SpanArrays; \
+} while (0)
+
+
+
struct swrast_device_driver;
@@ -75,6 +230,12 @@ struct swrast_device_driver;
extern void
_swrast_alloc_buffers( GLframebuffer *buffer );
+extern void
+_swrast_use_read_buffer( GLcontext *ctx );
+
+extern void
+_swrast_use_draw_buffer( GLcontext *ctx );
+
extern GLboolean
_swrast_CreateContext( GLcontext *ctx );
@@ -125,6 +286,10 @@ _swrast_Accum( GLcontext *ctx, GLenum op,
GLint width, GLint height );
+extern void
+_swrast_DrawBuffer( GLcontext *ctx, GLenum mode );
+
+
/* Reset the stipple counter
*/
extern void
@@ -153,6 +318,14 @@ _swrast_Quad( GLcontext *ctx,
extern void
_swrast_flush( GLcontext *ctx );
+extern void
+_swrast_render_primitive( GLcontext *ctx, GLenum mode );
+
+extern void
+_swrast_render_start( GLcontext *ctx );
+
+extern void
+_swrast_render_finish( GLcontext *ctx );
/* Tell the software rasterizer about core state changes.
*/
@@ -177,19 +350,19 @@ _swrast_print_vertex( GLcontext *ctx, const SWvertex *v );
* Imaging fallbacks (a better solution should be found, perhaps
* moving all the imaging fallback code to a new module)
*/
-void
+extern void
_swrast_CopyConvolutionFilter2D(GLcontext *ctx, GLenum target,
GLenum internalFormat,
GLint x, GLint y, GLsizei width,
GLsizei height);
-void
+extern void
_swrast_CopyConvolutionFilter1D(GLcontext *ctx, GLenum target,
GLenum internalFormat,
GLint x, GLint y, GLsizei width);
-void
+extern void
_swrast_CopyColorSubTable( GLcontext *ctx,GLenum target, GLsizei start,
GLint x, GLint y, GLsizei width);
-void
+extern void
_swrast_CopyColorTable( GLcontext *ctx,
GLenum target, GLenum internalformat,
GLint x, GLint y, GLsizei width);
@@ -201,48 +374,51 @@ _swrast_CopyColorTable( GLcontext *ctx,
*/
extern void
_swrast_copy_teximage1d(GLcontext *ctx, GLenum target, GLint level,
- GLenum internalFormat,
- GLint x, GLint y, GLsizei width, GLint border);
+ GLenum internalFormat,
+ GLint x, GLint y, GLsizei width, GLint border);
extern void
_swrast_copy_teximage2d(GLcontext *ctx, GLenum target, GLint level,
- GLenum internalFormat,
- GLint x, GLint y, GLsizei width, GLsizei height,
- GLint border);
+ GLenum internalFormat,
+ GLint x, GLint y, GLsizei width, GLsizei height,
+ GLint border);
extern void
_swrast_copy_texsubimage1d(GLcontext *ctx, GLenum target, GLint level,
- GLint xoffset, GLint x, GLint y, GLsizei width);
+ GLint xoffset, GLint x, GLint y, GLsizei width);
extern void
_swrast_copy_texsubimage2d(GLcontext *ctx,
- GLenum target, GLint level,
- GLint xoffset, GLint yoffset,
- GLint x, GLint y, GLsizei width, GLsizei height);
+ GLenum target, GLint level,
+ GLint xoffset, GLint yoffset,
+ GLint x, GLint y, GLsizei width, GLsizei height);
extern void
_swrast_copy_texsubimage3d(GLcontext *ctx,
- GLenum target, GLint level,
- GLint xoffset, GLint yoffset, GLint zoffset,
- GLint x, GLint y, GLsizei width, GLsizei height);
+ GLenum target, GLint level,
+ GLint xoffset, GLint yoffset, GLint zoffset,
+ GLint x, GLint y, GLsizei width, GLsizei height);
-/* The driver interface for the software rasterizer. Unless otherwise
- * noted, all functions are mandatory.
+/* The driver interface for the software rasterizer.
+ * Unless otherwise noted, all functions are mandatory.
*/
struct swrast_device_driver {
- void (*SetReadBuffer)( GLcontext *ctx, GLframebuffer *colorBuffer,
- GLenum buffer );
+ void (*SetBuffer)( GLcontext *ctx, GLframebuffer *buffer, GLuint bufferBit);
/*
- * Specifies the current buffer for span/pixel reading.
- * colorBuffer will be one of:
- * GL_FRONT_LEFT - this buffer always exists
- * GL_BACK_LEFT - when double buffering
- * GL_FRONT_RIGHT - when using stereo
- * GL_BACK_RIGHT - when using stereo and double buffering
+ * Specifies the current buffer for span/pixel writing/reading.
+ * buffer indicates which window to write to / read from. Normally,
+ * this'll be the buffer currently bound to the context, but it doesn't
+ * have to be!
+ * bufferBit indicates which color buffer, one of:
+ * FRONT_LEFT_BIT - this buffer always exists
+ * BACK_LEFT_BIT - when double buffering
+ * FRONT_RIGHT_BIT - when using stereo
+ * BACK_RIGHT_BIT - when using stereo and double buffering
+ * AUXn_BIT - if aux buffers are implemented
*/