ditch the pb (pixel buffer) code. Converted point drawing, bitmaps and aa lines to use new span functions.tags/mesa_4_1
@@ -1,10 +1,10 @@ | |||
/* $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"), | |||
@@ -27,8 +27,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 +75,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 +328,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 +340,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 +409,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 +455,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 +488,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 +496,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 |
@@ -1,10 +1,10 @@ | |||
/* $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"), | |||
@@ -34,107 +34,80 @@ | |||
* 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); | |||
} | |||
} | |||
@@ -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,24 @@ 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); | |||
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); | |||
@@ -195,6 +173,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 +189,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 +212,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 +223,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 +273,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 +285,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); | |||
} | |||
#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 | |||
} | |||
@@ -1,10 +1,10 @@ | |||
/* $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"), | |||
@@ -474,7 +474,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 ); | |||
@@ -509,7 +509,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 ); |
@@ -1,10 +1,10 @@ | |||
/* $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"), | |||
@@ -28,11 +28,12 @@ | |||
#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 +47,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,41 +59,40 @@ _swrast_Bitmap( GLcontext *ctx, GLint px, GLint py, | |||
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++; | |||
@@ -104,8 +103,6 @@ _swrast_Bitmap( GLcontext *ctx, GLint px, GLint py, | |||
} | |||
} | |||
PB_CHECK_FLUSH( ctx, PB ); | |||
/* get ready for next row */ | |||
if (mask != 1) | |||
src++; | |||
@@ -113,9 +110,11 @@ _swrast_Bitmap( GLcontext *ctx, GLint px, GLint py, | |||
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++; | |||
@@ -126,15 +125,22 @@ _swrast_Bitmap( GLcontext *ctx, GLint px, GLint py, | |||
} | |||
} | |||
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); | |||
} |
@@ -1,10 +1,10 @@ | |||
/* $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"), | |||
@@ -668,28 +668,39 @@ 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 ); | |||
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 ); | |||
} | |||
@@ -709,11 +720,7 @@ _mesa_blend_pixels( GLcontext *ctx, | |||
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 ); |
@@ -1,4 +1,4 @@ | |||
/* $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 | |||
@@ -35,8 +35,8 @@ | |||
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 |
@@ -1,10 +1,10 @@ | |||
/* $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"), | |||
@@ -67,7 +67,7 @@ clear_color_buffer_with_masking( GLcontext *ctx ) | |||
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 ); | |||
} | |||
@@ -82,7 +82,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 ); | |||
} | |||
} |
@@ -1,4 +1,4 @@ | |||
/* $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 | |||
@@ -56,7 +56,7 @@ _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); | |||
@@ -78,7 +78,7 @@ _swrast_update_rasterflags( GLcontext *ctx ) | |||
|| 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) |
@@ -1,4 +1,4 @@ | |||
/* $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 | |||
@@ -73,11 +73,10 @@ typedef void (*swrast_tri_func)( GLcontext *ctx, const SWvertex *, | |||
#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 */ |
@@ -1,4 +1,4 @@ | |||
/* $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 | |||
@@ -44,9 +44,11 @@ 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 +75,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; | |||
@@ -302,7 +304,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; | |||
@@ -544,7 +546,7 @@ _old_depth_test_span( GLcontext *ctx, GLuint n, GLint x, GLint y, | |||
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; | |||
@@ -553,22 +555,23 @@ _old_depth_test_span( GLcontext *ctx, GLuint n, GLint x, GLint y, | |||
/* 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); | |||
@@ -579,7 +582,7 @@ _mesa_depth_test_span( GLcontext *ctx, struct sw_span *span) | |||
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); | |||
@@ -592,11 +595,11 @@ _mesa_depth_test_span( GLcontext *ctx, struct sw_span *span) | |||
/* 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; | |||
@@ -1361,6 +1364,20 @@ _mesa_depth_test_pixels( GLcontext *ctx, | |||
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); | |||
} | |||
} | |||
/**********************************************************************/ |
@@ -1,4 +1,4 @@ | |||
/* $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 | |||
@@ -117,7 +117,7 @@ fast_draw_pixels(GLcontext *ctx, GLint x, GLint y, | |||
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 | |||
@@ -740,27 +740,10 @@ 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++) { | |||
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 |
@@ -1,10 +1,10 @@ | |||
/* $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"), | |||
@@ -40,9 +40,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,14 +166,24 @@ 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]; | |||
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 ); | |||
} | |||
@@ -207,9 +217,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 +342,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,20 +476,39 @@ 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 ); | |||
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); | |||
} | |||
} |
@@ -1,10 +1,10 @@ | |||
/* $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"), | |||
@@ -34,9 +34,8 @@ | |||
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 | |||
@@ -46,8 +45,8 @@ _mesa_logicop_ci_pixels( GLcontext *ctx, | |||
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 |
@@ -1,10 +1,10 @@ | |||
/* $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"), | |||
@@ -41,12 +41,65 @@ | |||
#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; | |||
@@ -135,12 +188,46 @@ _mesa_mask_rgba_pixels( GLcontext *ctx, | |||
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]; | |||
@@ -180,3 +267,4 @@ _mesa_mask_index_pixels( GLcontext *ctx, | |||
index[i] = (index[i] & msrc) | (fbindexes[i] & mdest); | |||
} | |||
} | |||
@@ -1,10 +1,10 @@ | |||
/* $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"), | |||
@@ -37,11 +37,14 @@ | |||
* 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. | |||
@@ -57,8 +60,17 @@ _mesa_mask_rgba_pixels( GLcontext *ctx, | |||
* 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[] ); | |||
@@ -1,10 +1,10 @@ | |||
/* $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"), | |||
@@ -33,20 +33,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 | |||
/* |
@@ -1,10 +1,10 @@ | |||
/* $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"), | |||
@@ -53,7 +53,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,23 +61,8 @@ | |||
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; | |||
@@ -85,25 +70,76 @@ NAME ( GLcontext *ctx, const SWvertex *vert ) | |||
#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) { | |||
@@ -119,14 +155,6 @@ NAME ( GLcontext *ctx, const SWvertex *vert ) | |||
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); | |||
@@ -134,11 +162,12 @@ NAME ( GLcontext *ctx, const SWvertex *vert ) | |||
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; | |||
@@ -187,6 +216,8 @@ NAME ( GLcontext *ctx, const SWvertex *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; | |||
@@ -218,9 +249,9 @@ NAME ( GLcontext *ctx, const SWvertex *vert ) | |||
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 | |||
@@ -229,98 +260,70 @@ NAME ( GLcontext *ctx, const SWvertex *vert ) | |||
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 | |||
} | |||
@@ -1,4 +1,4 @@ | |||
/* $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 | |||
@@ -358,7 +358,7 @@ interpolate_texcoords(GLcontext *ctx, struct sw_span *span) | |||
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]; | |||
@@ -387,12 +387,15 @@ interpolate_texcoords(GLcontext *ctx, struct sw_span *span) | |||
* 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++) { | |||
@@ -409,51 +412,61 @@ stipple_polygon_span( GLcontext *ctx, struct sw_span *span) | |||
/* | |||
* 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 */ | |||
} | |||
} | |||
@@ -462,20 +475,16 @@ clip_span( GLcontext *ctx, struct sw_span *span) | |||
* 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); | |||
@@ -487,14 +496,27 @@ multi_write_index_span( GLcontext *ctx, GLuint n, GLint x, GLint y, | |||
(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 ); | |||
} | |||
} | |||
@@ -509,13 +531,14 @@ multi_write_index_span( GLcontext *ctx, GLuint n, GLint x, GLint y, | |||
* 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; | |||
@@ -523,7 +546,7 @@ multi_write_rgba_span( GLcontext *ctx, GLuint n, GLint x, GLint y, | |||
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); | |||
@@ -543,26 +566,42 @@ multi_write_rgba_span( GLcontext *ctx, GLuint n, GLint x, GLint y, | |||
} | |||
/* 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); | |||
} | |||
} | |||
} | |||
} | |||
@@ -586,27 +625,29 @@ _mesa_write_index_span( GLcontext *ctx, struct sw_span *span, | |||
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); | |||
} | |||
@@ -671,31 +712,46 @@ _mesa_write_index_span( GLcontext *ctx, struct sw_span *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); | |||
} | |||
} | |||
} | |||
@@ -719,27 +775,34 @@ _mesa_write_rgba_span( GLcontext *ctx, struct sw_span *span, | |||
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; | |||
} | |||
} | |||
@@ -802,11 +865,13 @@ _mesa_write_rgba_span( GLcontext *ctx, struct sw_span *span, | |||
/* 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); | |||
@@ -826,51 +891,63 @@ _mesa_write_rgba_span( GLcontext *ctx, struct sw_span *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); | |||
} | |||
} | |||
} | |||
} | |||
@@ -918,6 +995,7 @@ _mesa_write_texture_span( GLcontext *ctx, struct sw_span *span, | |||
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); | |||
@@ -925,26 +1003,26 @@ _mesa_write_texture_span( GLcontext *ctx, struct sw_span *span, | |||
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 */ | |||
@@ -1052,33 +1130,43 @@ _mesa_write_texture_span( GLcontext *ctx, struct sw_span *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 (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); | |||
} | |||
} | |||
} | |||
@@ -1133,7 +1221,7 @@ _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); | |||
} | |||
} | |||
} |
@@ -1,4 +1,4 @@ | |||
/* $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 | |||
@@ -37,8 +37,6 @@ | |||
/* Stencil Logic: | |||
IF stencil test fails THEN | |||
@@ -55,8 +53,6 @@ ENDIF | |||
*/ | |||
/* | |||
* Return the address of a stencil buffer value given the window coords: | |||
*/ | |||
@@ -488,7 +484,6 @@ stencil_and_ztest_span( GLcontext *ctx, GLuint n, GLint x, GLint y, | |||
} | |||
/* | |||
* Apply stencil and depth testing to the span of pixels. | |||
* Both software and hardware stencil buffers are acceptable. | |||
@@ -501,55 +496,8 @@ stencil_and_ztest_span( GLcontext *ctx, GLuint n, GLint x, GLint y, | |||
* 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); | |||
@@ -1058,6 +1006,20 @@ _mesa_stencil_and_ztest_pixels( GLcontext *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 |
@@ -1,10 +1,10 @@ | |||
/* $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"), | |||
@@ -33,9 +33,7 @@ | |||
#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); | |||
@@ -1,4 +1,4 @@ | |||
/* $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 | |||
@@ -158,14 +158,17 @@ static void smooth_rgba_triangle( GLcontext *ctx, | |||
#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); | |||
} | |||
@@ -545,7 +548,8 @@ affine_span(GLcontext *ctx, struct sw_span *span, | |||
} | |||
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); | |||
@@ -1,4 +1,4 @@ | |||
/* $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 | |||
@@ -53,6 +53,9 @@ zoom_span( GLcontext *ctx, const struct sw_span *span, | |||
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; |
@@ -1,4 +1,4 @@ | |||
/* $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 | |||
@@ -95,6 +95,8 @@ typedef struct { | |||
#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 { | |||
@@ -152,6 +154,8 @@ 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]; |