ditch the pb (pixel buffer) code.
Converted point drawing, bitmaps and aa lines to use new span functions.
-/* $Id: s_aaline.c,v 1.12 2001/09/18 23:06:14 kschultz Exp $ */
+/* $Id: s_aaline.c,v 1.13 2002/02/02 17:24:11 brianp 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"),
#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"
GLfloat vPlane[MAX_TEXTURE_UNITS][4];
GLfloat lambda[MAX_TEXTURE_UNITS];
GLfloat texWidth[MAX_TEXTURE_UNITS], texHeight[MAX_TEXTURE_UNITS];
+
+ struct sw_span span;
};
-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);
+
/*
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;
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;
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;
#define NAME(x) aa_multitex_rgba_##x
#define DO_Z
+#define DO_FOG
#define DO_RGBA
#define DO_MULTITEX
#include "s_aalinetemp.h"
#define NAME(x) aa_multitex_spec_##x
#define DO_Z
+#define DO_FOG
#define DO_RGBA
#define DO_MULTITEX
#define DO_SPEC
-/* $Id: s_aalinetemp.h,v 1.15 2001/12/05 10:24:31 keithw Exp $ */
+/* $Id: s_aalinetemp.h,v 1.16 2002/02/02 17:24:11 brianp 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"),
* 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.coverage[i] = coverage;
+ line->span.xArray[i] = ix;
+ line->span.yArray[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.zArray[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.fogArray[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.color.rgba[i][RCOMP] = solve_plane_chan(fx, fy, line->rPlane);
+ line->span.color.rgba[i][GCOMP] = solve_plane_chan(fx, fy, line->gPlane);
+ line->span.color.rgba[i][BCOMP] = solve_plane_chan(fx, fy, line->bPlane);
+ line->span.color.rgba[i][ACOMP] = solve_plane_chan(fx, fy, line->aPlane);
#endif
#ifdef DO_INDEX
- index = (GLint) solve_plane(fx, fy, line->iPlane);
+ line->span.color.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.specArray[i][RCOMP] = solve_plane_chan(fx, fy, line->srPlane);
+ line->span.specArray[i][GCOMP] = solve_plane_chan(fx, fy, line->sgPlane);
+ line->span.specArray[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.texcoords[0][i][0] = solve_plane(fx, fy, line->sPlane[0]) * invQ;
+ line->span.texcoords[0][i][1] = solve_plane(fx, fy, line->tPlane[0]) * invQ;
+ line->span.texcoords[0][i][2] = solve_plane(fx, fy, line->uPlane[0]) * invQ;
+ line->span.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.texcoords[unit][i][0] = solve_plane(fx, fy, line->sPlane[unit]) * invQ;
+ line->span.texcoords[unit][i][1] = solve_plane(fx, fy, line->tPlane[unit]) * invQ;
+ line->span.texcoords[unit][i][2] = solve_plane(fx, fy, line->uPlane[unit]) * invQ;
+ line->span.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) {
+#ifdef DO_TEX
+ _mesa_write_texture_span(ctx, &line->span, GL_LINE);
#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, GL_LINE);
+#else
+ _mesa_write_index_span(ctx, &line->span, GL_LINE);
#endif
-
- pb->haveCoverage = GL_TRUE;
- PB_CHECK_FLUSH(ctx, pb);
+ }
}
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;
if (line.len == 0.0 || IS_INF_OR_NAN(line.len))
return;
+ INIT_SPAN(line.span);
+ line.span.arrayMask |= (SPAN_XY | SPAN_COVERAGE);
+
line.xAdj = line.dx / line.len * line.halfWidth;
line.yAdj = line.dy / line.len * line.halfWidth;
#ifdef DO_Z
+ line.span.arrayMask |= SPAN_Z;
compute_plane(line.x0, line.y0, line.x1, line.y1,
v0->win[2], v1->win[2], line.zPlane);
#endif
#ifdef DO_FOG
+ line.span.arrayMask |= SPAN_FOG;
compute_plane(line.x0, line.y0, line.x1, line.y1,
v0->fog, v1->fog, line.fPlane);
#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);
}
#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);
}
#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);
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]);
#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;
/* 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 {
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);
}
+
+#ifdef DO_TEX
+ _mesa_write_texture_span(ctx, &line.span, GL_LINE);
+#elif defined(DO_RGBA)
+ _mesa_write_rgba_span(ctx, &line.span, GL_LINE);
+#else
+ _mesa_write_index_span(ctx, &line.span, GL_LINE);
+#endif
}
-/* $Id: s_accum.c,v 1.13 2001/09/19 20:30:44 kschultz Exp $ */
+/* $Id: s_accum.c,v 1.14 2002/02/02 17:24:11 brianp 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"),
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 );
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 );
-/* $Id: s_bitmap.c,v 1.13 2001/12/14 02:50:57 brianp Exp $ */
+/* $Id: s_bitmap.c,v 1.14 2002/02/02 17:24:11 brianp 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"),
#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"
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);
if (SWRAST_CONTEXT(ctx)->NewState)
_swrast_validate_derived( ctx );
- /* Set bitmap drawing color */
+ INIT_SPAN(span);
+ span.arrayMask |= SPAN_XY;
+ span.end = width;
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;
}
- fragZ = (GLdepth) ( ctx->Current.RasterPos[2] * ctx->DepthMaxF);
+ if (ctx->Depth.Test)
+ _mesa_span_default_z(ctx, &span);
+ if (ctx->Fog.Enabled)
+ _mesa_span_default_fog(ctx, &span);
- if (ctx->Fog.Enabled) {
- if (ctx->Fog.FogCoordinateSource == GL_FOG_COORDINATE_EXT)
- fog = _mesa_z_to_fogfactor(ctx, ctx->Current.Attrib[VERT_ATTRIB_FOG][0]);
- else
- fog = _mesa_z_to_fogfactor(ctx, ctx->Current.RasterDistance);
- }
- else {
- fog = 0.0;
- }
-
- for (row=0; row<height; row++) {
+ 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++) {
+ for (col = 0; col < width; col++) {
if (*src & mask) {
- PB_WRITE_PIXEL( PB, px+col, py+row, fragZ, fog );
+ span.xArray[count] = px + col;
+ span.yArray[count] = py + row;
+ count++;
}
if (mask == 128U) {
src++;
}
}
- PB_CHECK_FLUSH( ctx, PB );
-
/* get ready for next row */
if (mask != 1)
src++;
else {
/* Msb first */
GLubyte mask = 128U >> (unpack->SkipPixels & 0x7);
- for (col=0; col<width; col++) {
+ for (col = 0; col < width; col++) {
if (*src & mask) {
- PB_WRITE_PIXEL( PB, px+col, py+row, fragZ, fog );
+ span.xArray[count] = px + col;
+ span.yArray[count] = py + row;
+ count++;
}
if (mask == 1U) {
src++;
}
}
- PB_CHECK_FLUSH( ctx, PB );
-
/* get ready for next row */
if (mask != 128)
src++;
}
- }
- _mesa_flush_pb(ctx);
+ if (count + width >= MAX_WIDTH || row + 1 == height) {
+ /* flush the span */
+ span.end = count;
+ if (ctx->Visual.rgbMode)
+ _mesa_write_rgba_span(ctx, &span, GL_BITMAP);
+ else
+ _mesa_write_index_span(ctx, &span, GL_BITMAP);
+ span.end = 0;
+ count = 0;
+ }
+ }
RENDER_FINISH(swrast,ctx);
}
-/* $Id: s_blend.c,v 1.10 2001/12/13 16:14:26 brianp Exp $ */
+/* $Id: s_blend.c,v 1.11 2002/02/02 17:24:11 brianp Exp $ */
/*
* Mesa 3-D graphics library
* 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"),
/*
* 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 );
+ if (span->arrayMask & SPAN_XY) {
+ /* array of x/y pixel coords */
+ (*swrast->Driver.ReadRGBAPixels)( ctx, span->end,
+ span->xArray, span->yArray,
+ framebuffer, span->mask );
+ if (swrast->_RasterMask & ALPHABUF_BIT) {
+ _mesa_read_alpha_pixels( ctx, span->end, span->xArray, span->yArray,
+ framebuffer, span->mask );
+ }
+ }
+ else {
+ /* horizontal run of pixels */
+ _mesa_read_rgba_span( ctx, ctx->DrawBuffer, span->end,
+ span->x, span->y, framebuffer );
+ }
- SWRAST_CONTEXT(ctx)->BlendFunc( ctx, n, mask, rgba,
- (const GLchan (*)[4]) dest );
+ SWRAST_CONTEXT(ctx)->BlendFunc( ctx, span->end, span->mask, rgba,
+ (const GLchan (*)[4]) framebuffer );
}
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;
- }
+ ASSERT(!ctx->Color.ColorLogicOpEnabled);
/* Read pixels from current color buffer */
(*swrast->Driver.ReadRGBAPixels)( ctx, n, x, y, dest, mask );
-/* $Id: s_blend.h,v 1.4 2001/03/12 00:48:41 gareth Exp $ */
+/* $Id: s_blend.h,v 1.5 2002/02/02 17:24:11 brianp Exp $ */
/*
* Mesa 3-D graphics library
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
-/* $Id: s_buffers.c,v 1.8 2001/03/19 02:25:36 keithw Exp $ */
+/* $Id: s_buffers.c,v 1.9 2002/02/02 17:24:11 brianp 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"),
rgba[j][BCOMP] = b;
rgba[j][ACOMP] = a;
}
- _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 );
}
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 );
}
}
-/* $Id: s_context.c,v 1.27 2002/01/10 16:54:28 brianp Exp $ */
+/* $Id: s_context.c,v 1.28 2002/02/02 17:24:11 brianp Exp $ */
/*
* Mesa 3-D graphics library
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);
|| ctx->Viewport.X + ctx->Viewport.Width > ctx->DrawBuffer->Width
|| ctx->Viewport.Y < 0
|| ctx->Viewport.Y + ctx->Viewport.Height > ctx->DrawBuffer->Height) {
- RasterMask |= WINCLIP_BIT;
+ RasterMask |= CLIP_BIT;
}
if (ctx->Depth.OcclusionTest)
-/* $Id: s_context.h,v 1.14 2002/01/10 16:54:29 brianp Exp $ */
+/* $Id: s_context.h,v 1.15 2002/02/02 17:24:11 brianp Exp $ */
/*
* Mesa 3-D graphics library
#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 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 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 */
-/* $Id: s_depth.c,v 1.13 2002/01/28 00:07:33 brianp Exp $ */
+/* $Id: s_depth.c,v 1.14 2002/02/02 17:24:11 brianp Exp $ */
/*
* Mesa 3-D graphics library
_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;
}
* 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;
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;
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);
+ passed = depth_test_span32(ctx, n, zbuffer, z, mask);
assert(swrast->Driver.WriteDepthSpan);
(*swrast->Driver.WriteDepthSpan)(ctx, n, x, y, zbuffer, mask);
return 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);
+ GLuint passed = depth_test_span16(ctx, n, zptr, z, mask);
return passed;
}
else {
GLuint *zptr = (GLuint *) Z_ADDRESS32(ctx, x, y);
- GLuint passed = depth_test_span32(ctx, n, x, y, zptr, z, mask);
+ GLuint passed = depth_test_span32(ctx, n, zptr, z, mask);
return passed;
}
}
}
+
/*
* Apply depth test to span of fragments. Hardware or software z buffer.
*/
-GLuint
-_mesa_depth_test_span( GLcontext *ctx, struct sw_span *span)
+static GLuint
+depth_test_span( GLcontext *ctx, struct sw_span *span)
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
GLdepth zbuffer[MAX_WIDTH];
GLuint passed;
(*swrast->Driver.ReadDepthSpan)(ctx, span->end, span->x, span->y, zbuffer);
- passed = depth_test_span32(ctx, span->end, span->x, span->y,
+ passed = depth_test_span32(ctx, span->end,
zbuffer, span->zArray, span->mask);
ASSERT(swrast->Driver.WriteDepthSpan);
(*swrast->Driver.WriteDepthSpan)(ctx, span->end, span->x, span->y, zbuffer, span->mask);
/* software depth buffer */
if (ctx->Visual.depthBits <= 16) {
GLushort *zptr = (GLushort *) Z_ADDRESS16(ctx, span->x, span->y);
- passed = depth_test_span16(ctx, span->end, span->x, span->y, zptr, span->zArray, span->mask);
+ passed = depth_test_span16(ctx, span->end, zptr, span->zArray, span->mask);
}
else {
GLuint *zptr = (GLuint *) Z_ADDRESS32(ctx, span->x, span->y);
- passed = depth_test_span32(ctx, span->end, span->x, span->y, zptr, span->zArray, span->mask);
+ passed = depth_test_span32(ctx, span->end, zptr, span->zArray, span->mask);
}
if (passed < span->end)
span->writeAll = GL_FALSE;
+GLuint
+_mesa_depth_test_span( GLcontext *ctx, struct sw_span *span)
+{
+ if (span->arrayMask & SPAN_XY) {
+ _mesa_depth_test_pixels(ctx, span->end,
+ span->xArray, span->yArray,
+ span->zArray, span->mask);
+ return 1;
+ }
+ else {
+ return depth_test_span(ctx, span);
+ }
+}
+
/**********************************************************************/
-/* $Id: s_drawpix.c,v 1.28 2002/01/31 00:27:43 brianp Exp $ */
+/* $Id: s_drawpix.c,v 1.29 2002/02/02 17:24:11 brianp Exp $ */
/*
* Mesa 3-D graphics library
if (ctx->Fog.Enabled)
_mesa_span_default_fog(ctx, &span);
- if ((SWRAST_CONTEXT(ctx)->_RasterMask&(~(SCISSOR_BIT|WINCLIP_BIT)))==0
+ if ((SWRAST_CONTEXT(ctx)->_RasterMask & ~CLIP_BIT) == 0
&& ctx->Texture._ReallyEnabled == 0
&& unpack->Alignment == 1
&& !unpack->SwapBytes
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++) {
- span.zArray[i] = z;
- span.fogArray[i] = fog;
- }
- }
-
+ if (ctx->Depth.Test)
+ _mesa_span_default_z(ctx, &span);
if (ctx->Fog.Enabled)
_mesa_span_default_fog(ctx, &span);
- span.arrayMask |= SPAN_Z;
if (SWRAST_CONTEXT(ctx)->_RasterMask == 0 && !zoom && x >= 0 && y >= 0
&& x + width <= ctx->DrawBuffer->Width
-/* $Id: s_logic.c,v 1.8 2001/07/13 20:07:37 brianp Exp $ */
+/* $Id: s_logic.c,v 1.9 2002/02/02 17:24:11 brianp 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"),
/*
* 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) {
* 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];
+
+ ASSERT(span->end < MAX_WIDTH);
+
/* Read dest values from frame buffer */
- (*swrast->Driver.ReadCI32Span)( ctx, n, x, y, dest );
- index_logicop( ctx, n, index, dest, mask );
+ if (span->arrayMask & SPAN_XY) {
+ (*swrast->Driver.ReadCI32Pixels)( ctx, span->end, span->xArray,
+ span->yArray, dest, span->mask );
+ }
+ else {
+ (*swrast->Driver.ReadCI32Span)( ctx, span->end, span->x, span->y, dest );
+ }
+
+ index_logicop( ctx, span->end, index, dest, span->mask );
}
* 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) {
* 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;
/*
* 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 );
+
+ ASSERT(span->end < MAX_WIDTH);
+ ASSERT(span->arrayMask & SPAN_RGBA);
+
+ if (span->arrayMask & SPAN_XY) {
+ (*swrast->Driver.ReadRGBAPixels)(ctx, span->end,
+ span->xArray, span->yArray,
+ dest, span->mask);
+ if (SWRAST_CONTEXT(ctx)->_RasterMask & ALPHABUF_BIT) {
+ _mesa_read_alpha_pixels(ctx, span->end, span->xArray, span->yArray,
+ dest, span->mask);
+ }
+ }
+ else {
+ _mesa_read_rgba_span(ctx, ctx->DrawBuffer, span->end,
+ span->x, span->y, dest);
+ }
+
if (sizeof(GLchan) * 4 == sizeof(GLuint)) {
- rgba_logicop_ui(ctx, n, mask, (GLuint *) rgba, (const GLuint *) dest);
+ rgba_logicop_ui(ctx, span->end, span->mask,
+ (GLuint *) rgba, (const GLuint *) dest);
}
else {
- rgba_logicop_chan(ctx, 4 * n, mask,
+ rgba_logicop_chan(ctx, 4 * span->end, span->mask,
(GLchan *) rgba, (const GLchan *) dest);
}
}
-/* $Id: s_logic.h,v 1.3 2001/03/12 00:48:42 gareth Exp $ */
+/* $Id: s_logic.h,v 1.4 2002/02/02 17:24:11 brianp 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"),
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
extern 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] );
extern void
-/* $Id: s_masking.c,v 1.5 2001/03/19 02:25:36 keithw Exp $ */
+/* $Id: s_masking.c,v 1.6 2002/02/02 17:24:11 brianp 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"),
#include "s_span.h"
+
+void
+_mesa_mask_rgba_span( GLcontext *ctx, const struct sw_span *span,
+ GLchan rgba[][4] )
+{
+ SWcontext *swrast = SWRAST_CONTEXT(ctx);
+ GLchan dest[MAX_WIDTH][4];
+#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;
+
+ ASSERT(n < MAX_WIDTH);
+ ASSERT(span->arrayMask & SPAN_RGBA);
+
+ if (span->arrayMask & SPAN_XY) {
+ (*swrast->Driver.ReadRGBAPixels)(ctx, n, span->xArray, span->yArray,
+ dest, span->mask);
+ if (SWRAST_CONTEXT(ctx)->_RasterMask & ALPHABUF_BIT) {
+ _mesa_read_alpha_pixels(ctx, n, span->xArray, span->yArray,
+ dest, span->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
+ 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 a span of RGBA pixels.
*/
void
-_mesa_mask_rgba_span( GLcontext *ctx,
- GLuint n, GLint x, GLint y, GLchan rgba[][4] )
+_mesa_mask_rgba_array( GLcontext *ctx,
+ GLuint n, GLint x, GLint y, GLchan rgba[][4] )
{
GLchan dest[MAX_WIDTH][4];
GLuint i;
+void
+_mesa_mask_index_span( GLcontext *ctx, const struct sw_span *span,
+ GLuint index[] )
+{
+ SWcontext *swrast = SWRAST_CONTEXT(ctx);
+ const GLuint msrc = ctx->Color.IndexMask;
+ const GLuint mdest = ~msrc;
+ GLuint fbindexes[MAX_WIDTH];
+ GLuint i;
+
+ ASSERT(span->arrayMask & SPAN_INDEX);
+ ASSERT(span->end < MAX_WIDTH);
+
+ if (span->arrayMask & SPAN_XY) {
+
+ (*swrast->Driver.ReadCI32Pixels)(ctx, span->end, span->xArray,
+ span->yArray, fbindexes, span->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 a span of CI pixels.
*/
void
-_mesa_mask_index_span( GLcontext *ctx,
- GLuint n, GLint x, GLint y, GLuint index[] )
+_mesa_mask_index_array( GLcontext *ctx,
+ GLuint n, GLint x, GLint y, GLuint index[] )
{
GLuint i;
GLuint fbindexes[MAX_WIDTH];
index[i] = (index[i] & msrc) | (fbindexes[i] & mdest);
}
}
+
-/* $Id: s_masking.h,v 1.3 2001/03/12 00:48:42 gareth Exp $ */
+/* $Id: s_masking.h,v 1.4 2002/02/02 17:24:11 brianp 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"),
* 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] );
+extern void
+_mesa_mask_rgba_array( GLcontext *ctx, GLuint n, GLint x, GLint y,
+ GLchan rgba[][4] );
+
/*
* Implement glColorMask for an array of RGBA pixels.
* 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 a span of CI pixels.
+ */
+extern void
+_mesa_mask_index_array( GLcontext *ctx,
+ GLuint n, GLint x, GLint y, GLuint index[] );
-/* $Id: s_points.c,v 1.16 2002/01/06 20:39:19 brianp Exp $ */
+/* $Id: s_points.c,v 1.17 2002/02/02 17:24:11 brianp 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"),
#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
/*
-/* $Id: s_pointtemp.h,v 1.11 2001/12/05 10:24:31 keithw Exp $ */
+/* $Id: s_pointtemp.h,v 1.12 2002/02/02 17:24:11 brianp 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"),
* else if d > rmax2 then
* fragment has 0% coverage
* else
- * fragement has % coverage = (d - rmin2) / (rmax2 - rmin2)
+ * fragment has % coverage = (d - rmin2) / (rmax2 - rmin2)
*/
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 & RGBA
- const GLchan red = vert->color[0];
- const GLchan green = vert->color[1];
- const GLchan blue = vert->color[2];
- GLchan alpha = vert->color[3];
-#if FLAGS & SPECULAR
- const GLchan sRed = vert->specular[0];
- const GLchan sGreen = vert->specular[1];
- const GLchan sBlue = vert->specular[2];
-#endif
-#else
- GLint index = vert->index;
+#if FLAGS & TEXTURE
+ GLuint u;
#endif
#if FLAGS & (ATTENUATE | LARGE | SMOOTH)
GLfloat size;
#if FLAGS & ATTENUATE
GLfloat alphaAtten;
#endif
+#if (FLAGS & RGBA) && (FLAGS & SMOOTH)
+ const GLchan red = vert->color[0];
+ const GLchan green = vert->color[1];
+ const GLchan blue = vert->color[2];
+ const GLchan alpha = vert->color[3];
+#endif
+
+ struct sw_span span;
+
+ /* Cull primitives with malformed coordinates.
+ */
+ {
+ float tmp = vert->win[0] + vert->win[1];
+ if (IS_INF_OR_NAN(tmp))
+ return;
+ }
+
+ INIT_SPAN(span);
+ span.arrayMask |= (SPAN_XY | SPAN_Z);
+ span.interpMask |= SPAN_FOG;
+ span.fog = vert->fog;
+ span.fogStep = 0.0;
+
+#if (FLAGS & RGBA)
+#if (FLAGS & SMOOTH)
+ span.arrayMask |= SPAN_RGBA;
+#else
+ span.interpMask |= SPAN_RGBA;
+ span.red = ChanToFixed(vert->color[0]);
+ span.green = ChanToFixed(vert->color[1]);
+ span.blue = ChanToFixed(vert->color[2]);
+ span.alpha = ChanToFixed(vert->color[3]);
+ span.redStep = span.greenStep = span.blueStep = span.alphaStep = 0;
+#endif /*SMOOTH*/
+#endif /*RGBA*/
+#if FLAGS & SPECULAR
+ span.interpMask |= SPAN_SPEC;
+ span.specRed = ChanToFixed(vert->specular[0]);
+ span.specGreen = ChanToFixed(vert->specular[1]);
+ span.specBlue = ChanToFixed(vert->specular[2]);
+ span.specRedStep = span.specGreenStep = span.specBlueStep = 0;
+#endif
+#if FLAGS & INDEX
+ span.interpMask |= SPAN_INDEX;
+ span.index = IntToFixed(vert->index);
+ span.indexStep = 0;
+#endif
#if FLAGS & TEXTURE
- GLfloat texcoord[MAX_TEXTURE_UNITS][4];
- GLuint u;
+ span.interpMask |= SPAN_TEXTURE;
+ span.arrayMask |= SPAN_LAMBDA;
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.0 || q == 1.0) ? 1.0 : (1.0 / q);
+ span.tex[u][0] = vert->texcoord[u][0] * invQ;
+ span.tex[u][1] = vert->texcoord[u][1] * invQ;
+ span.tex[u][2] = vert->texcoord[u][2] * invQ;
+ span.tex[u][3] = q;
+ span.texStep[u][0] = 0.0;
+ span.texStep[u][1] = 0.0;
+ span.texStep[u][2] = 0.0;
+ span.texStep[u][3] = 0.0;
+ span.rho[u] = 0.0;
}
}
#endif
+#if FLAGS & SMOOTH
+ span.arrayMask |= SPAN_COVERAGE;
+#endif
#if FLAGS & ATTENUATE
if (vert->pointSize >= ctx->Point.Threshold) {
size = ctx->Point._Size;
#endif
- /* Cull primitives with malformed coordinates.
- */
- {
- float tmp = vert->win[0] + vert->win[1];
- if (IS_INF_OR_NAN(tmp))
- return;
- }
-
#if FLAGS & SPRITE
{
SWcontext *swctx = SWRAST_CONTEXT(ctx);
SWvertex v0, v1, v2, v3;
GLuint unit;
+#if (FLAGS & RGBA) && (FLAGS & SMOOTH)
(void) red;
(void) green;
(void) blue;
(void) alpha;
- (void) z;
+#endif
/* lower left corner */
v0 = *vert;
{
GLint x, y;
const GLfloat radius = 0.5F * size;
+ const GLint z = (GLint) (vert->win[2]);
+ GLuint count = 0;
#if FLAGS & SMOOTH
const GLfloat rmin = radius - 0.7071F; /* 0.7071 = sqrt(2)/2 */
const GLfloat rmax = radius + 0.7071F;
ymin = (GLint) vert->win[1] - iRadius + 1;
ymax = ymin + iSize - 1;
}
-#endif
- (void) radius;
+#endif /*SMOOTH*/
+ (void) radius;
for (y = ymin; y <= ymax; y++) {
for (x = xmin; x <= xmax; x++) {
#if FLAGS & SMOOTH
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];
-#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);
+ span.coverage[count] = 1.0F - (dist2 - rmin2) * cscale;
+#if FLAGS & INDEX
+ span.coverage[count] *= 15.0; /* coverage in [0,15] */
#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);
+ /* full coverage */
+ span.coverage[count] = 1.0F;
}
-#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);
-#endif
-#if FLAGS & SMOOTH
- }
-#endif
- }
- }
-#if FLAGS & SMOOTH
- PB->haveCoverage = GL_TRUE;
-#endif
+ span.xArray[count] = x;
+ span.yArray[count] = y;
+ span.zArray[count] = z;
- PB_CHECK_FLUSH(ctx,PB);
+#if FLAGS & RGBA
+ span.color.rgba[count][RCOMP] = red;
+ span.color.rgba[count][GCOMP] = green;
+ span.color.rgba[count][BCOMP] = blue;
+#if FLAGS & ATTENUATE
+ span.color.rgba[count][ACOMP] = (GLchan) (alpha * alphaAtten);
+#else
+ span.color.rgba[count][ACOMP] = alpha;
+#endif /*ATTENUATE*/
+#endif /*RGBA*/
+ count++;
+ } /*if*/
+#else /*SMOOTH*/
+ /* not smooth (square points */
+ span.xArray[count] = x;
+ span.yArray[count] = y;
+ span.zArray[count] = z;
+ count++;
+#endif /*SMOOTH*/
+ } /*for x*/
+ } /*for y*/
+ span.end = count;
}
#else /* LARGE || ATTENUATE || SMOOTH*/
{
/* 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]);
- }
-#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);
-#else
- /* color index size 1 point */
- PB_WRITE_CI_PIXEL(PB, x, y, z, vert->fog, index);
-#endif
+ span.xArray[0] = (GLint) vert->win[0];
+ span.yArray[0] = (GLint) vert->win[1];
+ span.zArray[0] = (GLint) vert->win[2];
+ span.end = 1;
}
+
#endif /* LARGE || ATTENUATE || SMOOTH */
- PB_CHECK_FLUSH(ctx, PB);
+ ASSERT(span.end > 0);
+
+#if FLAGS & TEXTURE
+ if (ctx->Texture._ReallyEnabled)
+ _mesa_write_texture_span(ctx, &span, GL_POINT);
+ else
+ _mesa_write_rgba_span(ctx, &span, GL_POINT);
+#elif FLAGS & RGBA
+ _mesa_write_rgba_span(ctx, &span, GL_POINT);
+#else
+ _mesa_write_index_span(ctx, &span, GL_POINT);
+#endif
}
-/* $Id: s_span.c,v 1.28 2002/01/31 00:27:43 brianp Exp $ */
+/* $Id: s_span.c,v 1.29 2002/02/02 17:24:11 brianp Exp $ */
/*
* Mesa 3-D graphics library
span->arrayMask |= SPAN_LAMBDA;
}
else {
- /* just texture 0, witout lambda */
+ /* just texture 0, without lambda */
const GLfloat ds = span->texStep[0][0];
const GLfloat dt = span->texStep[0][1];
const GLfloat dr = span->texStep[0][2];
* Apply the current polygon stipple pattern to a span of pixels.
*/
static void
-stipple_polygon_span( GLcontext *ctx, struct sw_span *span)
+stipple_polygon_span( GLcontext *ctx, struct sw_span *span )
{
const GLuint highbit = 0x80000000;
- GLuint i, m, stipple;
+ const GLuint stipple = ctx->PolygonStipple[span->y % 32];
+ GLuint i, m;
+
+ ASSERT(ctx->Polygon.StippleFlag);
+ ASSERT((span->arrayMask & SPAN_XY) == 0);
- stipple = ctx->PolygonStipple[span->y % 32];
m = highbit >> (GLuint) (span->x % 32);
for (i = 0; i < span->end; i++) {
/*
- * Clip a pixel span to the current buffer/window boundaries.
- * Return: GL_TRUE some pixel still visible
+ * 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)
+clip_span( GLcontext *ctx, struct sw_span *span )
{
- GLint x = span->x, y = span->y, n = span->end;
-
- /* Clip to top and bottom */
- if (y < 0 || y >= ctx->DrawBuffer->Height) {
- span->end = 0;
- return GL_FALSE;
- }
-
- /* Clip to the left */
- if (x < 0) {
- if (x + n <= 0) {
- /* completely off left side */
- span->end = 0;
- return GL_FALSE;
- }
- else {
- /* partially off left side */
- span->writeAll = GL_FALSE;
- BZERO(span->mask, -x * sizeof(GLubyte));
- return GL_TRUE;
+ 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->xArray;
+ const GLint *y = span->yArray;
+ const GLint n = span->end;
+ GLubyte *mask = span->mask;
+ GLint i;
+ /* 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;
+
+ /* Trivial rejection tests */
+ if (y < ymin || y >= ymax || x + n <= xmin || x >= xmax) {
+ span->end = 0;
+ return GL_FALSE; /* all pixels clipped */
+ }
- /* Clip to right */
- if (x + n > ctx->DrawBuffer->Width) {
- if (x >= ctx->DrawBuffer->Width) {
- /* completely off right side */
- span->end = 0;
- return GL_FALSE;
+ /* Clip to the left */
+ if (x < xmin) {
+ ASSERT(x + n > xmin);
+ span->writeAll = GL_FALSE;
+ BZERO(span->mask, (xmin - x) * sizeof(GLubyte));
}
- else {
- /* partially off right side */
- span->end = ctx->DrawBuffer->Width - x;
- return GL_TRUE;
+
+ /* Clip to right */
+ if (x + n > xmax) {
+ ASSERT(x < xmax);
+ span->end = xmax - x;
}
- }
- return GL_TRUE;
+ return GL_TRUE; /* some pixels visible */
+ }
}
* Draw to more than one color buffer (or none).
*/
static void
-multi_write_index_span( GLcontext *ctx, GLuint n, GLint x, GLint y,
- const GLuint indexes[], const GLubyte mask[] )
+multi_write_index_span( GLcontext *ctx, struct sw_span *span )
{
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[MAX_WIDTH];
- ASSERT(n < MAX_WIDTH);
+ ASSERT(span->end < MAX_WIDTH);
if (bufferBit == FRONT_LEFT_BIT)
(void) (*ctx->Driver.SetDrawBuffer)( ctx, GL_FRONT_LEFT);
(void) (*ctx->Driver.SetDrawBuffer)( ctx, GL_BACK_RIGHT);
/* make copy of incoming indexes */
- MEMCPY( indexTmp, indexes, n * sizeof(GLuint) );
+ MEMCPY( indexTmp, span->color.index, span->end * sizeof(GLuint) );
+
if (ctx->Color.IndexLogicOpEnabled) {
- _mesa_logicop_ci_span( ctx, n, x, y, indexTmp, mask );
+ _mesa_logicop_ci_span(ctx, span, indexTmp);
}
+
if (ctx->Color.IndexMask != 0xffffffff) {
- _mesa_mask_index_span( ctx, n, x, y, indexTmp );
+ _mesa_mask_index_span(ctx, span, indexTmp);
+ }
+
+ if (span->arrayMask & SPAN_XY) {
+ /* array of pixel coords */
+ (*swrast->Driver.WriteCI32Pixels)(ctx, span->end,
+ span->xArray, span->yArray,
+ indexTmp, span->mask);
+ }
+ else {
+ /* horizontal run of pixels */
+ (*swrast->Driver.WriteCI32Span)(ctx, span->end, span->x, span->y,
+ indexTmp, span->mask);
}
- (*swrast->Driver.WriteCI32Span)( ctx, n, x, y, indexTmp, mask );
}
}
* 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;
for (bufferBit = 1; bufferBit <= 8; bufferBit = 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);
}
/* make copy of incoming colors */
- MEMCPY( rgbaTmp, rgba, 4 * n * sizeof(GLchan) );
+ MEMCPY( rgbaTmp, span->color.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->xArray, span->yArray,
+ (const GLchan (*)[4]) rgbaTmp,
+ span->mask);
+ if (SWRAST_CONTEXT(ctx)->_RasterMask & ALPHABUF_BIT) {
+ _mesa_write_alpha_pixels(ctx, span->end,
+ span->xArray, span->yArray,
+ (const GLchan (*)[4]) rgbaTmp,
+ span->mask);
+ }
+ }
+ else {
+ /* horizontal run of pixels */
+ (*swrast->Driver.WriteRGBASpan)(ctx, span->end, span->x, span->y,
+ (const GLchan (*)[4]) rgbaTmp,
+ span->mask);
+ if (swrast->_RasterMask & ALPHABUF_BIT) {
+ _mesa_write_alpha_span(ctx, span->end, span->x, span->y,
+ (const GLchan (*)[4]) rgbaTmp,
+ span->mask);
+ }
}
}
}
const GLuint origInterpMask = span->interpMask;
const GLuint origArrayMask = span->arrayMask;
+ ASSERT(span->end <= MAX_WIDTH);
+ ASSERT((span->interpMask | span->arrayMask) & SPAN_INDEX);
ASSERT((span->interpMask & span->arrayMask) == 0);
- MEMSET(span->mask, 1, span->end);
- span->writeAll = GL_TRUE;
-
- /* Window clipping */
- if ((swrast->_RasterMask & WINCLIP_BIT) || primitive==GL_BITMAP) {
- if (clip_span(ctx,span) == GL_FALSE) {
- return;
- }
+ if (span->arrayMask & SPAN_MASK) {
+ /* mask was initialized by caller, probably glBitmap */
+ span->writeAll = GL_FALSE;
+ }
+ else {
+ MEMSET(span->mask, 1, span->end);
+ span->writeAll = GL_TRUE;
}
- /* Scissor test */
- if (ctx->Scissor.Enabled) {
- if (_mesa_scissor_span( ctx, span ) == GL_FALSE) {
+ /* Clipping */
+ if ((swrast->_RasterMask & CLIP_BIT) || (primitive == GL_BITMAP)
+ || (primitive == GL_POINT)) {
+ if (!clip_span(ctx, span)) {
return;
}
}
/* Polygon Stippling */
- if (ctx->Polygon.StippleFlag && primitive==GL_POLYGON) {
+ if (ctx->Polygon.StippleFlag && primitive == GL_POLYGON) {
stipple_polygon_span(ctx, span);
}
if (swrast->_RasterMask & MULTI_DRAW_BIT) {
/* draw to zero or two or more buffers */
- multi_write_index_span( ctx, span->end, span->x, span->y,
- span->color.index, span->mask );
+ multi_write_index_span(ctx, span);
}
else {
/* normal situation: draw to exactly one buffer */
if (ctx->Color.IndexLogicOpEnabled) {
- _mesa_logicop_ci_span( ctx, span->end, span->x, span->y,
- span->color.index, span->mask );
+ _mesa_logicop_ci_span(ctx, span, span->color.index);
}
if (ctx->Color.IndexMask != 0xffffffff) {
- _mesa_mask_index_span( ctx, span->end, span->x, span->y,
- span->color.index );
+ _mesa_mask_index_span(ctx, span, span->color.index);
}
/* write 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->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->xArray, span->yArray,
+ FixedToInt(span->index),
+ span->mask);
+ }
+ else {
+ (*swrast->Driver.WriteCI32Pixels)(ctx, span->end, span->xArray,
+ span->yArray, span->color.index,
+ span->mask );
+ }
}
else {
- (*swrast->Driver.WriteCI32Span)( ctx, span->end, span->x, span->y,
- span->color.index, span->mask );
+ /* 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->mask);
+ }
+ else {
+ (*swrast->Driver.WriteCI32Span)(ctx, span->end, span->x, span->y,
+ span->color.index, span->mask);
+ }
}
}
const GLuint origArrayMask = span->arrayMask;
GLboolean monoColor;
+ ASSERT(span->end <= MAX_WIDTH);
ASSERT((span->interpMask & span->arrayMask) == 0);
ASSERT((span->interpMask | span->arrayMask) & SPAN_RGBA);
+ if (ctx->Fog.Enabled)
+ ASSERT((span->interpMask | span->arrayMask) & SPAN_FOG);
+
+ /*
+ printf("%s() interp 0x%x array 0x%x p=0x%x\n", __FUNCTION__, span->interpMask, span->arrayMask, primitive);
+ */
- MEMSET(span->mask, 1, span->end);
- span->writeAll = GL_TRUE;
+ if (span->arrayMask & SPAN_MASK) {
+ /* mask was initialized by caller, probably glBitmap */
+ span->writeAll = GL_FALSE;
+ }
+ else {
+ MEMSET(span->mask, 1, span->end);
+ span->writeAll = GL_TRUE;
+ }
/* Determine if we have mono-chromatic colors */
monoColor = (span->interpMask & SPAN_RGBA) &&
span->redStep == 0 && span->greenStep == 0 &&
span->blueStep == 0 && span->alphaStep == 0;
- /* Window clipping */
- if ((swrast->_RasterMask & WINCLIP_BIT) || primitive == GL_BITMAP) {
- if (clip_span(ctx, span) == GL_FALSE) {
- return;
- }
- }
-
- /* Scissor test */
- if (ctx->Scissor.Enabled) {
- if (!_mesa_scissor_span(ctx, span)) {
+ /* Clipping */
+ if ((swrast->_RasterMask & CLIP_BIT) || (primitive == GL_BITMAP)
+ || (primitive == GL_POINT)) {
+ if (!clip_span(ctx, span)) {
return;
}
}
/* Fog */
/* XXX try to simplify the fog code! */
if (ctx->Fog.Enabled) {
- if ((span->arrayMask & SPAN_FOG) && !swrast->_PreferPixelFog)
+ if ((span->arrayMask & SPAN_FOG) && !swrast->_PreferPixelFog) {
_mesa_fog_rgba_pixels_with_array(ctx, span, span->fogArray,
span->color.rgba);
- else if ((span->interpMask & SPAN_FOG) && !swrast->_PreferPixelFog)
+ }
+ else if ((span->interpMask & SPAN_FOG) && !swrast->_PreferPixelFog) {
_mesa_fog_rgba_pixels(ctx, span, span->color.rgba);
+ }
else {
if ((span->interpMask & SPAN_Z) && (span->arrayMask & SPAN_Z) == 0)
interpolate_z(ctx, span);
}
if (swrast->_RasterMask & MULTI_DRAW_BIT) {
- multi_write_rgba_span( ctx, span->end, span->x, span->y,
- (const GLchan (*)[4]) span->color.rgba,
- span->mask );
+ multi_write_rgba_span(ctx, span);
}
else {
/* normal: write to exactly one buffer */
+#if 1
if (ctx->Color.ColorLogicOpEnabled) {
- _mesa_logicop_rgba_span( ctx, span->end, span->x, span->y,
- span->color.rgba, span->mask );
+ _mesa_logicop_rgba_span(ctx, span, span->color.rgba);
monoColor = GL_FALSE;
}
else if (ctx->Color.BlendEnabled) {
- _mesa_blend_span( ctx, span->end, span->x, span->y,
- span->color.rgba, span->mask );
+ _mesa_blend_span(ctx, span, span->color.rgba);
monoColor = GL_FALSE;
}
-
+#endif
/* Color component masking */
if (colorMask != 0xffffffff) {
- _mesa_mask_rgba_span( ctx, span->end, span->x, span->y,
- span->color.rgba );
+ _mesa_mask_rgba_span(ctx, span, span->color.rgba);
monoColor = GL_FALSE;
}
/* write 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->mask);
+ if (span->arrayMask & SPAN_XY) {
+ /* array of pixel coords */
+ /* XXX test for mono color */
+ (*swrast->Driver.WriteRGBAPixels)(ctx, span->end, span->xArray,
+ span->yArray, (const GLchan (*)[4]) span->color.rgba, span->mask);
+ if (SWRAST_CONTEXT(ctx)->_RasterMask & ALPHABUF_BIT) {
+ _mesa_write_alpha_pixels(ctx, span->end,
+ span->xArray, span->yArray,
+ (const GLchan (*)[4]) span->color.rgba,
+ span->mask);
+ }
}
else {
- (*swrast->Driver.WriteRGBASpan)( ctx, span->end, span->x, span->y,
+ /* 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->mask);
+ /* XXX software alpha buffer writes! */
+ }
+ else {
+ /* each pixel is a different color */
+ (*swrast->Driver.WriteRGBASpan)(ctx, span->end, span->x, span->y,
(const GLchan (*)[4]) span->color.rgba,
- span->writeAll ? ((const GLubyte *) NULL) : span->mask );
- }
-
- if (swrast->_RasterMask & ALPHABUF_BIT) {
- _mesa_write_alpha_span( ctx, span->end, span->x, span->y,
+ span->writeAll ? ((const GLubyte *) NULL) : span->mask);
+ if (swrast->_RasterMask & ALPHABUF_BIT) {
+ _mesa_write_alpha_span(ctx, span->end, span->x, span->y,
(const GLchan (*)[4]) span->color.rgba,
- span->writeAll ? ((const GLubyte *) NULL) : span->mask );
+ span->writeAll ? ((const GLubyte *) NULL) : span->mask);
+ }
+ }
}
}
SWcontext *swrast = SWRAST_CONTEXT(ctx);
const GLuint origArrayMask = span->arrayMask;
+ ASSERT(span->end <= MAX_WIDTH);
ASSERT((span->interpMask & span->arrayMask) == 0);
ASSERT(ctx->Texture._ReallyEnabled);
printf("%s() interp 0x%x array 0x%x\n", __FUNCTION__, span->interpMask, span->arrayMask);
*/
- MEMSET(span->mask, 1, span->end);
- span->writeAll = GL_TRUE;
-
- /* clip against window bounds */
- if ((swrast->_RasterMask & WINCLIP_BIT) || primitive==GL_BITMAP) {
- if (clip_span(ctx,span) == GL_FALSE) {
- return;
- }
+ if (span->arrayMask & SPAN_MASK) {
+ /* mask was initialized by caller, probably glBitmap */
+ span->writeAll = GL_FALSE;
+ }
+ else {
+ MEMSET(span->mask, 1, span->end);
+ span->writeAll = GL_TRUE;
}
- /* Scissor test */
- if (ctx->Scissor.Enabled) {
- if (_mesa_scissor_span( ctx, span ) == GL_FALSE) {
- return;
+ /* Clipping */
+ if ((swrast->_RasterMask & CLIP_BIT) || (primitive == GL_BITMAP)
+ || (primitive == GL_POINT)) {
+ if (!clip_span(ctx, span)) {
+ return;
}
}
/* Polygon Stippling */
- if (ctx->Polygon.StippleFlag && primitive==GL_POLYGON) {
- stipple_polygon_span( ctx, span);
+ if (ctx->Polygon.StippleFlag && primitive == GL_POLYGON) {
+ stipple_polygon_span(ctx, span);
}
/* Need texture coordinates now */
}
if (swrast->_RasterMask & MULTI_DRAW_BIT) {
- multi_write_rgba_span( ctx, span->end, span->x, span->y,
- (const GLchan (*)[4]) span->color.rgba,
- span->mask );
+ multi_write_rgba_span(ctx, span);
}
else {
/* normal: write to exactly one buffer */
if (ctx->Color.ColorLogicOpEnabled) {
- _mesa_logicop_rgba_span( ctx, span->end, span->x, span->y,
- span->color.rgba, span->mask );
+ _mesa_logicop_rgba_span(ctx, span, span->color.rgba);
}
else if (ctx->Color.BlendEnabled) {
- _mesa_blend_span( ctx, span->end, span->x, span->y,
- span->color.rgba, span->mask);
+ _mesa_blend_span(ctx, span, span->color.rgba);
}
if (colorMask != 0xffffffff) {
- _mesa_mask_rgba_span( ctx, span->end, span->x, span->y,
- span->color.rgba );
+ _mesa_mask_rgba_span(ctx, span, span->color.rgba);
}
- (*swrast->Driver.WriteRGBASpan)( ctx, span->end, span->x, span->y,
+
+ if (span->arrayMask & SPAN_XY) {
+ /* array of pixel coords */
+ (*swrast->Driver.WriteRGBAPixels)(ctx, span->end, span->xArray,
+ span->yArray, (const GLchan (*)[4]) span->color.rgba, span->mask);
+ if (SWRAST_CONTEXT(ctx)->_RasterMask & ALPHABUF_BIT) {
+ _mesa_write_alpha_pixels(ctx, span->end,
+ span->xArray, span->yArray,
+ (const GLchan (*)[4]) span->color.rgba,
+ span->mask);
+ }
+ }
+ else {
+ /* horizontal run of pixels */
+ (*swrast->Driver.WriteRGBASpan)(ctx, span->end, span->x, span->y,
(const GLchan (*)[4]) span->color.rgba,
- span->writeAll ? NULL : span->mask );
- if (swrast->_RasterMask & ALPHABUF_BIT) {
- _mesa_write_alpha_span( ctx, span->end, span->x, span->y,
- (const GLchan (*)[4]) span->color.rgba,
- span->writeAll ? NULL : span->mask );
+ span->writeAll ? NULL : span->mask);
+ if (swrast->_RasterMask & ALPHABUF_BIT) {
+ _mesa_write_alpha_span(ctx, span->end, span->x, span->y,
+ (const GLchan (*)[4]) span->color.rgba,
+ span->writeAll ? NULL : span->mask);
+ }
}
}
(*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);
}
}
}
-/* $Id: s_stencil.c,v 1.17 2002/01/28 00:07:33 brianp Exp $ */
+/* $Id: s_stencil.c,v 1.18 2002/02/02 17:24:11 brianp Exp $ */
/*
* Mesa 3-D graphics library
-
-
/* Stencil Logic:
IF stencil test fails THEN
*/
-
-
/*
* Return the address of a stencil buffer value given the window coords:
*/
}
-
/*
* Apply stencil and depth testing to the span of pixels.
* Both software and hardware stencil buffers are acceptable.
* GL_FALSE - one or more fragments passed the testing
*
*/
-GLboolean
-_old_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 );
-
- if (swrast->Driver.WriteStencilSpan) {
- /* Write updated stencil values into hardware stencil buffer */
- (swrast->Driver.WriteStencilSpan)(ctx, n, x, y, stencil, mask );
- }
-
- return result;
-}
-
-/*
- * 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, struct sw_span *span)
+static GLboolean
+stencil_and_ztest_span2(GLcontext *ctx, struct sw_span *span)
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
+GLboolean
+_mesa_stencil_and_ztest_span(GLcontext *ctx, struct sw_span *span)
+{
+ if (span->arrayMask & SPAN_XY) {
+ return _mesa_stencil_and_ztest_pixels(ctx, span->end,
+ span->xArray, span->yArray,
+ span->zArray, span->mask);
+ }
+ else {
+ return stencil_and_ztest_span2(ctx, span);
+ }
+}
+
+
/*
* Return a span of stencil values from the stencil buffer.
* Used for glRead/CopyPixels
-/* $Id: s_stencil.h,v 1.4 2001/12/17 04:54:35 brianp Exp $ */
+/* $Id: s_stencil.h,v 1.5 2002/02/02 17:24:11 brianp 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"),
#include "swrast.h"
-extern GLboolean
-_old_stencil_and_ztest_span( GLcontext *ctx, GLuint n, GLint x, GLint y,
- const GLdepth z[], GLubyte mask[] );
+
extern GLboolean
_mesa_stencil_and_ztest_span(GLcontext *ctx, struct sw_span *span);
-/* $Id: s_triangle.c,v 1.53 2002/01/30 16:54:02 brianp Exp $ */
+/* $Id: s_triangle.c,v 1.54 2002/02/02 17:24:11 brianp Exp $ */
/*
* Mesa 3-D graphics library
#define INTERP_RGB 1
#define INTERP_ALPHA 1
-#define RENDER_SPAN( span ) \
- ASSERT(span.interpMask & SPAN_RGBA); \
- _mesa_write_rgba_span(ctx, &span, GL_POLYGON);
+#define SETUP_CODE \
+ { \
+ /* texturing must be off */ \
+ ASSERT(!ctx->Texture._ReallyEnabled); \
+ ASSERT(ctx->Light.ShadeModel==GL_SMOOTH); \
+ }
+
+#define RENDER_SPAN( span ) _mesa_write_rgba_span(ctx, &span, GL_POLYGON)
#include "s_tritemp.h"
- ASSERT(!ctx->Texture._ReallyEnabled); /* texturing must be off */
- ASSERT(ctx->Light.ShadeModel==GL_SMOOTH);
}
}
break;
}
- ASSERT(span->interpMask & SPAN_RGBA);
+ ASSERT(span->interpMask & SPAN_RGBA); /* XXXX unset */
+ span->interpMask &= ~SPAN_RGBA;
ASSERT(span->arrayMask & SPAN_RGBA);
_mesa_write_rgba_span(ctx, span, GL_POLYGON);
-/* $Id: s_zoom.c,v 1.12 2002/01/31 00:27:43 brianp Exp $ */
+/* $Id: s_zoom.c,v 1.13 2002/02/02 17:24:11 brianp Exp $ */
/*
* Mesa 3-D graphics library
const GLchan (*rgb)[3] = (const GLchan (*)[3]) src;
const GLuint *indexes = (const GLuint *) src;
+ /* no pixel arrays! */
+ ASSERT((span->arrayMask & SPAN_XY) == 0);
+
INIT_SPAN(zoomed);
if (format == GL_RGBA || format == GL_RGB) {
zoomed.z = span->z;
-/* $Id: swrast.h,v 1.19 2002/01/28 04:25:56 brianp Exp $ */
+/* $Id: swrast.h,v 1.20 2002/02/02 17:24:11 brianp Exp $ */
/*
* Mesa 3-D graphics library
#define SPAN_LAMBDA 0x080
#define SPAN_COVERAGE 0x100
#define SPAN_FLAT 0x200 /* flat shading? */
+#define SPAN_XY 0x400 /* arrayMask only - for xArray, yArray */
+#define SPAN_MASK 0x800 /* arrayMask only */
struct sw_span {
GLuint index[MAX_WIDTH];
} color;
GLchan specArray[MAX_WIDTH][4];
+ GLint xArray[MAX_WIDTH]; /* X/Y used for point/line rendering only */
+ GLint yArray[MAX_WIDTH];
GLdepth zArray[MAX_WIDTH];
GLfloat fogArray[MAX_WIDTH];
GLfloat texcoords[MAX_TEXTURE_UNITS][MAX_WIDTH][4];