-# $Id: Makefile.X11,v 1.26 2000/10/31 12:40:57 keithw Exp $
+# $Id: Makefile.X11,v 1.27 2000/10/31 18:09:44 keithw Exp $
# Mesa 3-D graphics library
# Version: 3.5
CORE_SOURCES = \
- aatriangle.c \
accum.c \
alpha.c \
- alphabuf.c \
attrib.c \
bbox.c \
bitmap.c \
glapinoop.c \
glthread.c \
hash.c \
+ highpc.c \
hint.c \
image.c \
imaging.c \
light.c \
lines.c \
logic.c \
+ lowpc.c \
masking.c \
matrix.c \
mem.c \
mmath.c \
- pb.c \
pipeline.c \
pixel.c \
pixeltex.c \
points.c \
polygon.c \
- quads.c \
rastpos.c \
readpix.c \
rect.c \
scissor.c \
shade.c \
- span.c \
stages.c \
state.c \
stencil.c \
texture.c \
texutil.c \
translate.c \
- triangle.c \
varray.c \
vb.c \
vbcull.c \
vertices.c \
winpos.c \
xform.c \
- zoom.c \
X86/x86.c \
X86/common_x86.c \
X86/3dnow.c \
- X86/katmai.c
+ X86/katmai.c \
+ swrast/s_aatriangle.c \
+ swrast/s_accum.c \
+ swrast/s_alpha.c \
+ swrast/s_alphabuf.c \
+ swrast/s_bitmap.c \
+ swrast/s_blend.c \
+ swrast/s_buffers.c \
+ swrast/s_copypix.c \
+ swrast/s_context.c \
+ swrast/s_depth.c \
+ swrast/s_drawpix.c \
+ swrast/s_fog.c \
+ swrast/s_imaging.c \
+ swrast/s_lines.c \
+ swrast/s_logic.c \
+ swrast/s_masking.c \
+ swrast/s_pb.c \
+ swrast/s_pixeltex.c \
+ swrast/s_points.c \
+ swrast/s_quads.c \
+ swrast/s_readpix.c \
+ swrast/s_scissor.c \
+ swrast/s_span.c \
+ swrast/s_stencil.c \
+ swrast/s_texture.c \
+ swrast/s_triangle.c \
+ swrast/s_zoom.c
+
+
DRIVER_SOURCES = \
X/glxapi.c \
#include "fxdrv.h"
#include "enums.h"
#include "extensions.h"
-#include "pb.h"
+#include "swrast/swrast.h"
/* These lookup table are used to extract RGB values in [0,255] from
* 16-bit pixel values.
static void fxDDReducedPrimitiveChange(GLcontext *ctx, GLenum prim)
{
if (ctx->Polygon.CullFlag) {
- if (ctx->PB->primitive != GL_POLYGON) { /* Lines or Points */
+ if (ctx->ReducedPrimitive != GL_POLYGON) { /* Lines or Points */
FX_grCullMode(GR_CULL_DISABLE);
FX_CONTEXT(ctx)->cullMode=GR_CULL_DISABLE;
}
-/* $Id: osmesa.c,v 1.24 2000/10/30 16:32:43 brianp Exp $ */
+/* $Id: osmesa.c,v 1.25 2000/10/31 18:09:46 keithw Exp $ */
/*
* Mesa 3-D graphics library
#include "types.h"
#include "vb.h"
#include "extensions.h"
+#include "swrast/s_depth.h"
#endif
+
+
/*
* This is the OS/Mesa context struct.
* Notice how it includes a GLcontext. By doing this we're mimicking
#define PLOT(X,Y) { GLuint *ptr4 = PIXELADDR4(X,Y); *ptr4 = pixel; }
#ifdef WIN32
-#include "..\linetemp.h"
+#include "..\swrast\s_linetemp.h"
#else
-#include "linetemp.h"
+#include "swrast/s_linetemp.h"
#endif
}
}
#ifdef WIN32
-#include "..\linetemp.h"
+#include "..\swrast\s_linetemp.h"
#else
-#include "linetemp.h"
+#include "swrast/s_linetemp.h"
#endif
}
}
#ifdef WIN32
-#include "..\linetemp.h"
+#include "..\swrast\s_linetemp.h"
#else
-#include "linetemp.h"
+#include "swrast/s_linetemp.h"
#endif
}
}
#ifdef WIN32
-#include "..\linetemp.h"
+#include "..\swrast\s_linetemp.h"
#else
-#include "linetemp.h"
+#include "swrast/s_linetemp.h"
#endif
}
}
#ifdef WIN32
-#include "..\linetemp.h"
+#include "..\swrast\s_linetemp.h"
#else
-#include "linetemp.h"
+#include "swrast/s_linetemp.h"
#endif
}
{ \
GLint i, len = RIGHT-LEFT; \
GLuint *img = PIXELADDR4(LEFT,Y); \
+ (void) fffog; \
for (i=0;i<len;i++,img++) { \
GLdepth z = FixedToDepth(ffz); \
if (z < zRow[i]) { \
} \
}
#ifdef WIN32
-#include "..\tritemp.h"
+#include "..\swrast\s_tritemp.h"
#else
-#include "tritemp.h"
+#include "swrast/s_tritemp.h"
#endif
}
{ \
GLint i, len = RIGHT-LEFT; \
GLuint *img = PIXELADDR4(LEFT,Y); \
+ (void) fffog; \
for (i=0;i<len;i++,img++) { \
GLdepth z = FixedToDepth(ffz); \
if (z < zRow[i]) { \
} \
}
#ifdef WIN32
-#include "..\tritemp.h"
+#include "..\swrast\s_tritemp.h"
#else
-#include "tritemp.h"
+#include "swrast/s_tritemp.h"
#endif
}
-/* $Id: xm_api.c,v 1.4 2000/10/30 13:32:03 keithw Exp $ */
+/* $Id: xm_api.c,v 1.5 2000/10/31 18:09:46 keithw Exp $ */
/*
* Mesa 3-D graphics library
#include "conf.h"
#endif
#include "macros.h"
+#include "swrast/swrast.h"
#ifndef GLX_NONE_EXT
#define GLX_NONE_EXT 0x8000
-/* $Id: xm_line.c,v 1.4 2000/09/28 22:44:32 brianp Exp $ */
+/* $Id: xm_line.c,v 1.5 2000/10/31 18:09:46 keithw Exp $ */
/*
* Mesa 3-D graphics library
#include "types.h"
#include "xmesaP.h"
+/* Internal swrast includes:
+ */
+#include "swrast/s_depth.h"
/**********************************************************************/
#define CLIP_HACK 1
#define PLOT(X,Y) XMesaPutPixel( img, X, FLIP(xmesa->xm_buffer, Y), pixel );
-#include "linetemp.h"
+#include "swrast/s_linetemp.h"
}
#define CLIP_HACK 1
#define PLOT(X,Y) *pixelPtr = pixel;
-#include "linetemp.h"
+#include "swrast/s_linetemp.h"
}
#define CLIP_HACK 1
#define PLOT(X,Y) *pixelPtr = pixel;
-#include "linetemp.h"
+#include "swrast/s_linetemp.h"
}
pixelPtr->b = color[BCOMP]; \
}
-#include "linetemp.h"
+#include "swrast/s_linetemp.h"
}
#define CLIP_HACK 1
#define PLOT(X,Y) *pixelPtr = pixel;
-#include "linetemp.h"
+#include "swrast/s_linetemp.h"
}
#define CLIP_HACK 1
#define PLOT(X,Y) PACK_TRUEDITHER( *pixelPtr, X, Y, color[0], color[1], color[2] );
-#include "linetemp.h"
+#include "swrast/s_linetemp.h"
}
#define CLIP_HACK 1
#define PLOT(X,Y) *pixelPtr = DITHER(X,Y,r,g,b);
-#include "linetemp.h"
+#include "swrast/s_linetemp.h"
}
#define CLIP_HACK 1
#define PLOT(X,Y) *pixelPtr = pixel;
-#include "linetemp.h"
+#include "swrast/s_linetemp.h"
}
#define CLIP_HACK 1
#define PLOT(X,Y) *pixelPtr = (GLubyte) DITHER_HPCR(X,Y,r,g,b);
-#include "linetemp.h"
+#include "swrast/s_linetemp.h"
}
XMesaPutPixel( img, X, FLIP(xmesa->xm_buffer, Y), pixel ); \
}
-#include "linetemp.h"
+#include "swrast/s_linetemp.h"
}
*pixelPtr = pixel; \
}
-#include "linetemp.h"
+#include "swrast/s_linetemp.h"
}
*pixelPtr = pixel; \
}
-#include "linetemp.h"
+#include "swrast/s_linetemp.h"
}
pixelPtr->b = color[BCOMP]; \
}
-#include "linetemp.h"
+#include "swrast/s_linetemp.h"
}
*zPtr = Z; \
*pixelPtr = pixel; \
}
-#include "linetemp.h"
+#include "swrast/s_linetemp.h"
}
*zPtr = Z; \
PACK_TRUEDITHER(*pixelPtr, X, Y, color[0], color[1], color[2]); \
}
-#include "linetemp.h"
+#include "swrast/s_linetemp.h"
}
*zPtr = Z; \
*pixelPtr = (GLubyte) DITHER( X, Y, r, g, b); \
}
-#include "linetemp.h"
+#include "swrast/s_linetemp.h"
}
*pixelPtr = pixel; \
}
-#include "linetemp.h"
+#include "swrast/s_linetemp.h"
}
*pixelPtr = (GLubyte) DITHER_HPCR( X, Y, r, g, b); \
}
-#include "linetemp.h"
+#include "swrast/s_linetemp.h"
}
-/* $Id: xm_tri.c,v 1.5 2000/10/30 13:32:03 keithw Exp $ */
+/* $Id: xm_tri.c,v 1.6 2000/10/31 18:09:47 keithw Exp $ */
/*
* Mesa 3-D graphics library
#include "types.h"
#include "xmesaP.h"
+/* Internal swrast includes:
+ */
+#include "swrast/s_depth.h"
+
ffz += fdzdx; \
} \
}
-#include "tritemp.h"
+#include "swrast/s_tritemp.h"
}
ffz += fdzdx; \
} \
}
-#include "tritemp.h"
+#include "swrast/s_tritemp.h"
}
ffz += fdzdx; \
} \
}
-#include "tritemp.h"
+#include "swrast/s_tritemp.h"
}
ffz += fdzdx; \
} \
}
-#include "tritemp.h"
+#include "swrast/s_tritemp.h"
}
ffz += fdzdx; \
} \
}
-#include "tritemp.h"
+#include "swrast/s_tritemp.h"
}
ffz += fdzdx; \
} \
}
-#include "tritemp.h"
+#include "swrast/s_tritemp.h"
}
ffz += fdzdx; \
} \
}
-#include "tritemp.h"
+#include "swrast/s_tritemp.h"
}
ffz += fdzdx; \
} \
}
-#include "tritemp.h"
+#include "swrast/s_tritemp.h"
}
ffz += fdzdx; \
} \
}
-#include "tritemp.h"
+#include "swrast/s_tritemp.h"
}
ffz += fdzdx; \
} \
}
-#include "tritemp.h"
+#include "swrast/s_tritemp.h"
}
ffz += fdzdx; \
} \
}
-#include "tritemp.h"
+#include "swrast/s_tritemp.h"
}
ffz += fdzdx; \
} \
}
-#include "tritemp.h"
+#include "swrast/s_tritemp.h"
}
ffz += fdzdx; \
} \
}
-#include "tritemp.h"
+#include "swrast/s_tritemp.h"
}
ffz += fdzdx; \
} \
}
-#include "tritemp.h"
+#include "swrast/s_tritemp.h"
}
ffz += fdzdx; \
} \
}
-#include "tritemp.h"
+#include "swrast/s_tritemp.h"
}
ffz += fdzdx; \
} \
}
-#include "tritemp.h"
+#include "swrast/s_tritemp.h"
}
ffz += fdzdx; \
} \
}
-#include "tritemp.h"
+#include "swrast/s_tritemp.h"
}
ffz += fdzdx; \
} \
}
-#include "tritemp.h"
+#include "swrast/s_tritemp.h"
}
ffz += fdzdx; \
} \
}
-#include "tritemp.h"
+#include "swrast/s_tritemp.h"
}
ffz += fdzdx; \
} \
}
-#include "tritemp.h"
+#include "swrast/s_tritemp.h"
}
ffz += fdzdx; \
} \
}
-#include "tritemp.h"
+#include "swrast/s_tritemp.h"
}
ffz += fdzdx; \
} \
}
-#include "tritemp.h"
+#include "swrast/s_tritemp.h"
}
ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
} \
}
-#include "tritemp.h"
+#include "swrast/s_tritemp.h"
}
ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
} \
}
-#include "tritemp.h"
+#include "swrast/s_tritemp.h"
}
ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
} \
}
-#include "tritemp.h"
+#include "swrast/s_tritemp.h"
}
pixel++; \
} \
}
-#include "tritemp.h"
+#include "swrast/s_tritemp.h"
}
ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
} \
}
-#include "tritemp.h"
+#include "swrast/s_tritemp.h"
}
ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
} \
}
-#include "tritemp.h"
+#include "swrast/s_tritemp.h"
}
ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
} \
}
-#include "tritemp.h"
+#include "swrast/s_tritemp.h"
}
ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
} \
}
-#include "tritemp.h"
+#include "swrast/s_tritemp.h"
}
ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
} \
}
-#include "tritemp.h"
+#include "swrast/s_tritemp.h"
}
ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
} \
}
-#include "tritemp.h"
+#include "swrast/s_tritemp.h"
}
ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
} \
}
-#include "tritemp.h"
+#include "swrast/s_tritemp.h"
}
XMesaPutPixel( img, xx, yy, pixel ); \
} \
}
-#include "tritemp.h"
+#include "swrast/s_tritemp.h"
}
*pixel = (PIXEL_TYPE) p; \
} \
}
-#include "tritemp.h"
+#include "swrast/s_tritemp.h"
}
*pixel = (PIXEL_TYPE) p; \
} \
}
-#include "tritemp.h"
+#include "swrast/s_tritemp.h"
}
pixel++; \
} \
}
-#include "tritemp.h"
+#include "swrast/s_tritemp.h"
}
/*
XMesaPutPixel( img, xx, yy, p ); \
} \
}
-#include "tritemp.h"
+#include "swrast/s_tritemp.h"
}
*pixel = (PIXEL_TYPE) p; \
} \
}
-#include "tritemp.h"
+#include "swrast/s_tritemp.h"
}
color[GCOMP], color[BCOMP]); \
} \
}
-#include "tritemp.h"
+#include "swrast/s_tritemp.h"
}
*pixel = (PIXEL_TYPE) FLAT_DITHER(xx); \
} \
}
-#include "tritemp.h"
+#include "swrast/s_tritemp.h"
}
XMesaPutPixel( img, xx, yy, p ); \
} \
}
-#include "tritemp.h"
+#include "swrast/s_tritemp.h"
}
*pixel = (PIXEL_TYPE) DITHER_HPCR( xx, yy, r, g, b ); \
} \
}
-#include "tritemp.h"
+#include "swrast/s_tritemp.h"
}
*pixel = p; \
} \
}
-#include "tritemp.h"
+#include "swrast/s_tritemp.h"
}
-# $Id: Makefile.X11,v 1.26 2000/10/31 12:40:57 keithw Exp $
+# $Id: Makefile.X11,v 1.27 2000/10/31 18:09:44 keithw Exp $
# Mesa 3-D graphics library
# Version: 3.5
CORE_SOURCES = \
- aatriangle.c \
accum.c \
alpha.c \
- alphabuf.c \
attrib.c \
bbox.c \
bitmap.c \
glapinoop.c \
glthread.c \
hash.c \
+ highpc.c \
hint.c \
image.c \
imaging.c \
light.c \
lines.c \
logic.c \
+ lowpc.c \
masking.c \
matrix.c \
mem.c \
mmath.c \
- pb.c \
pipeline.c \
pixel.c \
pixeltex.c \
points.c \
polygon.c \
- quads.c \
rastpos.c \
readpix.c \
rect.c \
scissor.c \
shade.c \
- span.c \
stages.c \
state.c \
stencil.c \
texture.c \
texutil.c \
translate.c \
- triangle.c \
varray.c \
vb.c \
vbcull.c \
vertices.c \
winpos.c \
xform.c \
- zoom.c \
X86/x86.c \
X86/common_x86.c \
X86/3dnow.c \
- X86/katmai.c
+ X86/katmai.c \
+ swrast/s_aatriangle.c \
+ swrast/s_accum.c \
+ swrast/s_alpha.c \
+ swrast/s_alphabuf.c \
+ swrast/s_bitmap.c \
+ swrast/s_blend.c \
+ swrast/s_buffers.c \
+ swrast/s_copypix.c \
+ swrast/s_context.c \
+ swrast/s_depth.c \
+ swrast/s_drawpix.c \
+ swrast/s_fog.c \
+ swrast/s_imaging.c \
+ swrast/s_lines.c \
+ swrast/s_logic.c \
+ swrast/s_masking.c \
+ swrast/s_pb.c \
+ swrast/s_pixeltex.c \
+ swrast/s_points.c \
+ swrast/s_quads.c \
+ swrast/s_readpix.c \
+ swrast/s_scissor.c \
+ swrast/s_span.c \
+ swrast/s_stencil.c \
+ swrast/s_texture.c \
+ swrast/s_triangle.c \
+ swrast/s_zoom.c
+
+
DRIVER_SOURCES = \
X/glxapi.c \
-/* $Id: accum.c,v 1.30 2000/10/30 13:31:59 keithw Exp $ */
+/* $Id: accum.c,v 1.31 2000/10/31 18:09:44 keithw Exp $ */
/*
* Mesa 3-D graphics library
#include "context.h"
#include "macros.h"
#include "mem.h"
-#include "masking.h"
-#include "span.h"
#include "state.h"
#include "types.h"
+#include "swrast/swrast.h"
#endif
-/*
- * Accumulation buffer notes
- *
- * Normally, accumulation buffer values are GLshorts with values in
- * [-32767, 32767] which represent floating point colors in [-1, 1],
- * as suggested by the OpenGL specification.
- *
- * We optimize for the common case used for full-scene antialiasing:
- * // start with accum buffer cleared to zero
- * glAccum(GL_LOAD, w); // or GL_ACCUM the first image
- * glAccum(GL_ACCUM, w);
- * ...
- * glAccum(GL_ACCUM, w);
- * glAccum(GL_RETURN, 1.0);
- * That is, we start with an empty accumulation buffer and accumulate
- * n images, each with weight w = 1/n.
- * In this scenario, we can simply store unscaled integer values in
- * the accum buffer instead of scaled integers. We'll also keep track
- * of the w value so when we do GL_RETURN we simply divide the accumulated
- * values by n (=1/w).
- * This lets us avoid _many_ int->float->int conversions.
- */
-
-
-#if CHAN_BITS == 8
-#define USE_OPTIMIZED_ACCUM /* enable the optimization */
-#endif
-
-
-
-void
-_mesa_alloc_accum_buffer( GLcontext *ctx )
-{
- GLint n;
-
- if (ctx->DrawBuffer->Accum) {
- FREE( ctx->DrawBuffer->Accum );
- ctx->DrawBuffer->Accum = NULL;
- }
-
- /* allocate accumulation buffer if not already present */
- n = ctx->DrawBuffer->Width * ctx->DrawBuffer->Height * 4 * sizeof(GLaccum);
- ctx->DrawBuffer->Accum = (GLaccum *) MALLOC( n );
- if (!ctx->DrawBuffer->Accum) {
- /* unable to setup accumulation buffer */
- gl_error( ctx, GL_OUT_OF_MEMORY, "glAccum" );
- }
-#ifdef USE_OPTIMIZED_ACCUM
- ctx->IntegerAccumMode = GL_TRUE;
-#else
- ctx->IntegerAccumMode = GL_FALSE;
-#endif
- ctx->IntegerAccumScaler = 0.0;
-}
-
void
}
-
-/*
- * This is called when we fall out of optimized/unscaled accum buffer mode.
- * That is, we convert each unscaled accum buffer value into a scaled value
- * representing the range[-1, 1].
- */
-static void rescale_accum( GLcontext *ctx )
-{
- const GLuint n = ctx->DrawBuffer->Width * ctx->DrawBuffer->Height * 4;
- const GLfloat fChanMax = (1 << (sizeof(GLchan) * 8)) - 1;
- const GLfloat s = ctx->IntegerAccumScaler * (32767.0 / fChanMax);
- GLaccum *accum = ctx->DrawBuffer->Accum;
- GLuint i;
-
- assert(ctx->IntegerAccumMode);
- assert(accum);
-
- for (i = 0; i < n; i++) {
- accum[i] = (GLaccum) (accum[i] * s);
- }
-
- ctx->IntegerAccumMode = GL_FALSE;
-}
-
-
-
void
_mesa_Accum( GLenum op, GLfloat value )
{
GET_CURRENT_CONTEXT(ctx);
- GLuint xpos, ypos, width, height, width4;
- GLfloat acc_scale;
- GLchan rgba[MAX_WIDTH][4];
- const GLuint colorMask = *((GLuint *) &ctx->Color.ColorMask);
- const GLint iChanMax = (1 << (sizeof(GLchan) * 8)) - 1;
- const GLfloat fChanMax = (1 << (sizeof(GLchan) * 8)) - 1;
+ GLuint xpos, ypos, width, height;
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glAccum");
return;
}
- if (!ctx->DrawBuffer->Accum) {
- _mesa_warning(ctx, "Calling glAccum() without an accumulation buffer (low memory?)");
- return;
- }
-
- if (sizeof(GLaccum)==1) {
- acc_scale = 127.0;
- }
- else if (sizeof(GLaccum)==2) {
- acc_scale = 32767.0;
- }
- else {
- /* sizeof(GLaccum) > 2 (Cray) */
- acc_scale = (float) SHRT_MAX;
- }
-
if (ctx->NewState)
gl_update_state( ctx );
height = ctx->DrawBuffer->Height;
}
- width4 = 4 * width;
-
- switch (op) {
- case GL_ADD:
- if (value != 0.0F) {
- const GLaccum intVal = (GLaccum) (value * acc_scale);
- GLuint j;
- /* Leave optimized accum buffer mode */
- if (ctx->IntegerAccumMode)
- rescale_accum(ctx);
- for (j = 0; j < height; j++) {
- GLaccum * acc = ctx->DrawBuffer->Accum + ypos * width4 + 4 * xpos;
- GLuint i;
- for (i = 0; i < width4; i++) {
- acc[i] += intVal;
- }
- ypos++;
- }
- }
- break;
-
- case GL_MULT:
- if (value != 1.0F) {
- GLuint j;
- /* Leave optimized accum buffer mode */
- if (ctx->IntegerAccumMode)
- rescale_accum(ctx);
- for (j = 0; j < height; j++) {
- GLaccum *acc = ctx->DrawBuffer->Accum + ypos * width4 + 4 * xpos;
- GLuint i;
- for (i = 0; i < width4; i++) {
- acc[i] = (GLaccum) ( (GLfloat) acc[i] * value );
- }
- ypos++;
- }
- }
- break;
-
- case GL_ACCUM:
- if (value == 0.0F)
- return;
-
- (*ctx->Driver.SetReadBuffer)( ctx, ctx->ReadBuffer,
- ctx->Pixel.DriverReadBuffer );
-
- /* May have to leave optimized accum buffer mode */
- if (ctx->IntegerAccumScaler == 0.0 && value > 0.0 && value <= 1.0)
- ctx->IntegerAccumScaler = value;
- if (ctx->IntegerAccumMode && value != ctx->IntegerAccumScaler)
- rescale_accum(ctx);
-
- RENDER_START(ctx);
-
- if (ctx->IntegerAccumMode) {
- /* simply add integer color values into accum buffer */
- GLuint j;
- GLaccum *acc = ctx->DrawBuffer->Accum + ypos * width4 + xpos * 4;
- assert(ctx->IntegerAccumScaler > 0.0);
- assert(ctx->IntegerAccumScaler <= 1.0);
- for (j = 0; j < height; j++) {
-
- GLuint i, i4;
- gl_read_rgba_span(ctx, ctx->DrawBuffer, width, xpos, ypos, rgba);
- for (i = i4 = 0; i < width; i++, i4+=4) {
- acc[i4+0] += rgba[i][RCOMP];
- acc[i4+1] += rgba[i][GCOMP];
- acc[i4+2] += rgba[i][BCOMP];
- acc[i4+3] += rgba[i][ACOMP];
- }
- acc += width4;
- ypos++;
- }
- }
- else {
- /* scaled integer accum buffer */
- const GLfloat rscale = value * acc_scale / fChanMax;
- const GLfloat gscale = value * acc_scale / fChanMax;
- const GLfloat bscale = value * acc_scale / fChanMax;
- const GLfloat ascale = value * acc_scale / fChanMax;
- GLuint j;
- for (j=0;j<height;j++) {
- GLaccum *acc = ctx->DrawBuffer->Accum + ypos * width4 + xpos * 4;
- GLuint i;
- gl_read_rgba_span(ctx, ctx->DrawBuffer, width, xpos, ypos, rgba);
- for (i=0;i<width;i++) {
- *acc += (GLaccum) ( (GLfloat) rgba[i][RCOMP] * rscale ); acc++;
- *acc += (GLaccum) ( (GLfloat) rgba[i][GCOMP] * gscale ); acc++;
- *acc += (GLaccum) ( (GLfloat) rgba[i][BCOMP] * bscale ); acc++;
- *acc += (GLaccum) ( (GLfloat) rgba[i][ACOMP] * ascale ); acc++;
- }
- ypos++;
- }
- }
- /* restore read buffer = draw buffer (the default) */
- (*ctx->Driver.SetReadBuffer)( ctx, ctx->DrawBuffer,
- ctx->Color.DriverDrawBuffer );
- RENDER_FINISH(ctx);
- break;
-
- case GL_LOAD:
- (*ctx->Driver.SetReadBuffer)( ctx, ctx->ReadBuffer,
- ctx->Pixel.DriverReadBuffer );
-
- /* This is a change to go into optimized accum buffer mode */
- if (value > 0.0 && value <= 1.0) {
-#ifdef USE_OPTIMIZED_ACCUM
- ctx->IntegerAccumMode = GL_TRUE;
-#else
- ctx->IntegerAccumMode = GL_FALSE;
-#endif
- ctx->IntegerAccumScaler = value;
- }
- else {
- ctx->IntegerAccumMode = GL_FALSE;
- ctx->IntegerAccumScaler = 0.0;
- }
-
- RENDER_START(ctx);
- if (ctx->IntegerAccumMode) {
- /* just copy values into accum buffer */
- GLuint j;
- GLaccum *acc = ctx->DrawBuffer->Accum + ypos * width4 + xpos * 4;
- assert(ctx->IntegerAccumScaler > 0.0);
- assert(ctx->IntegerAccumScaler <= 1.0);
- for (j = 0; j < height; j++) {
- GLuint i, i4;
- gl_read_rgba_span(ctx, ctx->DrawBuffer, width, xpos, ypos, rgba);
- for (i = i4 = 0; i < width; i++, i4 += 4) {
- acc[i4+0] = rgba[i][RCOMP];
- acc[i4+1] = rgba[i][GCOMP];
- acc[i4+2] = rgba[i][BCOMP];
- acc[i4+3] = rgba[i][ACOMP];
- }
- acc += width4;
- ypos++;
- }
- }
- else {
- /* scaled integer accum buffer */
- const GLfloat rscale = value * acc_scale / fChanMax;
- const GLfloat gscale = value * acc_scale / fChanMax;
- const GLfloat bscale = value * acc_scale / fChanMax;
- const GLfloat ascale = value * acc_scale / fChanMax;
- const GLfloat d = 3.0 / acc_scale;
- GLuint i, j;
- for (j = 0; j < height; j++) {
- GLaccum *acc = ctx->DrawBuffer->Accum + ypos * width4 + xpos * 4;
- gl_read_rgba_span(ctx, ctx->DrawBuffer, width, xpos, ypos, rgba);
- for (i=0;i<width;i++) {
- *acc++ = (GLaccum) ((GLfloat) rgba[i][RCOMP] * rscale + d);
- *acc++ = (GLaccum) ((GLfloat) rgba[i][GCOMP] * gscale + d);
- *acc++ = (GLaccum) ((GLfloat) rgba[i][BCOMP] * bscale + d);
- *acc++ = (GLaccum) ((GLfloat) rgba[i][ACOMP] * ascale + d);
- }
- ypos++;
- }
- }
-
- /* restore read buffer = draw buffer (the default) */
- (*ctx->Driver.SetReadBuffer)( ctx, ctx->DrawBuffer,
- ctx->Color.DriverDrawBuffer );
- RENDER_FINISH(ctx);
- break;
-
- case GL_RETURN:
- /* May have to leave optimized accum buffer mode */
- if (ctx->IntegerAccumMode && value != 1.0)
- rescale_accum(ctx);
-
- RENDER_START(ctx);
- if (ctx->IntegerAccumMode && ctx->IntegerAccumScaler > 0) {
- /* build lookup table to avoid many floating point multiplies */
- static GLchan multTable[32768];
- static GLfloat prevMult = 0.0;
- const GLfloat mult = ctx->IntegerAccumScaler;
- const GLint max = MIN2((GLint) (256 / mult), 32767);
- GLuint j;
- if (mult != prevMult) {
- for (j = 0; j < max; j++)
- multTable[j] = (GLint) ((GLfloat) j * mult + 0.5F);
- prevMult = mult;
- }
-
- assert(ctx->IntegerAccumScaler > 0.0);
- assert(ctx->IntegerAccumScaler <= 1.0);
- for (j = 0; j < height; j++) {
- const GLaccum *acc = ctx->DrawBuffer->Accum + ypos * width4 + xpos*4;
- GLuint i, i4;
- for (i = i4 = 0; i < width; i++, i4 += 4) {
- ASSERT(acc[i4+0] < max);
- ASSERT(acc[i4+1] < max);
- ASSERT(acc[i4+2] < max);
- ASSERT(acc[i4+3] < max);
- rgba[i][RCOMP] = multTable[acc[i4+0]];
- rgba[i][GCOMP] = multTable[acc[i4+1]];
- rgba[i][BCOMP] = multTable[acc[i4+2]];
- rgba[i][ACOMP] = multTable[acc[i4+3]];
- }
- if (colorMask != 0xffffffff) {
- _mesa_mask_rgba_span( ctx, width, xpos, ypos, rgba );
- }
- (*ctx->Driver.WriteRGBASpan)( ctx, width, xpos, ypos,
- (const GLchan (*)[4])rgba, NULL );
- ypos++;
- }
- }
- else {
- const GLfloat rscale = value / acc_scale * fChanMax;
- const GLfloat gscale = value / acc_scale * fChanMax;
- const GLfloat bscale = value / acc_scale * fChanMax;
- const GLfloat ascale = value / acc_scale * fChanMax;
- GLuint i, j;
- for (j=0;j<height;j++) {
- const GLaccum *acc = ctx->DrawBuffer->Accum + ypos * width4 + xpos*4;
- for (i=0;i<width;i++) {
- GLint r, g, b, a;
- r = (GLint) ( (GLfloat) (*acc++) * rscale + 0.5F );
- g = (GLint) ( (GLfloat) (*acc++) * gscale + 0.5F );
- b = (GLint) ( (GLfloat) (*acc++) * bscale + 0.5F );
- a = (GLint) ( (GLfloat) (*acc++) * ascale + 0.5F );
- rgba[i][RCOMP] = CLAMP( r, 0, iChanMax );
- rgba[i][GCOMP] = CLAMP( g, 0, iChanMax );
- rgba[i][BCOMP] = CLAMP( b, 0, iChanMax );
- rgba[i][ACOMP] = CLAMP( a, 0, iChanMax );
- }
- if (colorMask != 0xffffffff) {
- _mesa_mask_rgba_span( ctx, width, xpos, ypos, rgba );
- }
- (*ctx->Driver.WriteRGBASpan)( ctx, width, xpos, ypos,
- (const GLchan (*)[4])rgba, NULL );
- ypos++;
- }
- }
- RENDER_FINISH(ctx);
- break;
-
- default:
- gl_error( ctx, GL_INVALID_ENUM, "glAccum" );
- }
-}
-
-
-
-/*
- * Clear the accumulation Buffer.
- */
-void
-_mesa_clear_accum_buffer( GLcontext *ctx )
-{
- GLuint buffersize;
- GLfloat acc_scale;
-
- if (ctx->Visual.AccumRedBits==0) {
- /* No accumulation buffer! */
- return;
- }
-
- if (sizeof(GLaccum)==1) {
- acc_scale = 127.0;
- }
- else if (sizeof(GLaccum)==2) {
- acc_scale = 32767.0;
- }
- else {
- /* sizeof(GLaccum) > 2 (Cray) */
- acc_scale = (float) SHRT_MAX;
- }
-
- /* number of pixels */
- buffersize = ctx->DrawBuffer->Width * ctx->DrawBuffer->Height;
-
- if (!ctx->DrawBuffer->Accum) {
- /* try to alloc accumulation buffer */
- ctx->DrawBuffer->Accum = (GLaccum *)
- MALLOC( buffersize * 4 * sizeof(GLaccum) );
- }
-
- if (ctx->DrawBuffer->Accum) {
- if (ctx->Scissor.Enabled) {
- /* Limit clear to scissor box */
- GLaccum r, g, b, a;
- GLint i, j;
- GLint width, height;
- GLaccum *row;
- r = (GLaccum) (ctx->Accum.ClearColor[0] * acc_scale);
- g = (GLaccum) (ctx->Accum.ClearColor[1] * acc_scale);
- b = (GLaccum) (ctx->Accum.ClearColor[2] * acc_scale);
- a = (GLaccum) (ctx->Accum.ClearColor[3] * acc_scale);
- /* size of region to clear */
- width = 4 * (ctx->DrawBuffer->Xmax - ctx->DrawBuffer->Xmin);
- height = ctx->DrawBuffer->Ymax - ctx->DrawBuffer->Ymin;
- /* ptr to first element to clear */
- row = ctx->DrawBuffer->Accum
- + 4 * (ctx->DrawBuffer->Ymin * ctx->DrawBuffer->Width
- + ctx->DrawBuffer->Xmin);
- for (j=0;j<height;j++) {
- for (i=0;i<width;i+=4) {
- row[i+0] = r;
- row[i+1] = g;
- row[i+2] = b;
- row[i+3] = a;
- }
- row += 4 * ctx->DrawBuffer->Width;
- }
- }
- else {
- /* clear whole buffer */
- if (ctx->Accum.ClearColor[0]==0.0 &&
- ctx->Accum.ClearColor[1]==0.0 &&
- ctx->Accum.ClearColor[2]==0.0 &&
- ctx->Accum.ClearColor[3]==0.0) {
- /* Black */
- BZERO( ctx->DrawBuffer->Accum, buffersize * 4 * sizeof(GLaccum) );
- }
- else {
- /* Not black */
- GLaccum *acc, r, g, b, a;
- GLuint i;
-
- acc = ctx->DrawBuffer->Accum;
- r = (GLaccum) (ctx->Accum.ClearColor[0] * acc_scale);
- g = (GLaccum) (ctx->Accum.ClearColor[1] * acc_scale);
- b = (GLaccum) (ctx->Accum.ClearColor[2] * acc_scale);
- a = (GLaccum) (ctx->Accum.ClearColor[3] * acc_scale);
- for (i=0;i<buffersize;i++) {
- *acc++ = r;
- *acc++ = g;
- *acc++ = b;
- *acc++ = a;
- }
- }
- }
-
- /* update optimized accum state vars */
- if (ctx->Accum.ClearColor[0] == 0.0 && ctx->Accum.ClearColor[1] == 0.0 &&
- ctx->Accum.ClearColor[2] == 0.0 && ctx->Accum.ClearColor[3] == 0.0) {
-#ifdef USE_OPTIMIZED_ACCUM
- ctx->IntegerAccumMode = GL_TRUE;
-#else
- ctx->IntegerAccumMode = GL_FALSE;
-#endif
- ctx->IntegerAccumScaler = 0.0; /* denotes empty accum buffer */
- }
- else {
- ctx->IntegerAccumMode = GL_FALSE;
- }
- }
+ if (!ctx->Driver.Accum ||
+ !ctx->Driver.Accum( ctx, op, value, xpos, ypos, width, height ))
+ _swrast_Accum( ctx, op, value, xpos, ypos, width, height );
}
-/* $Id: accum.h,v 1.3 2000/02/02 21:52:26 brianp Exp $ */
+/* $Id: accum.h,v 1.4 2000/10/31 18:09:44 keithw Exp $ */
/*
* Mesa 3-D graphics library
extern void
-_mesa_alloc_accum_buffer( GLcontext *ctx );
-
-
-extern void
-_mesa_clear_accum_buffer( GLcontext *ctx );
-
-
-extern void
_mesa_Accum( GLenum op, GLfloat value );
-/* $Id: blend.c,v 1.23 2000/10/30 16:32:43 brianp Exp $ */
+/* $Id: blend.c,v 1.24 2000/10/31 18:09:44 keithw Exp $ */
/*
* Mesa 3-D graphics library
#include "all.h"
#else
#include "glheader.h"
-#include "alphabuf.h"
#include "blend.h"
#include "context.h"
#include "enums.h"
#include "macros.h"
-#include "pb.h"
-#include "span.h"
#include "types.h"
#endif
ctx->NewState |= _NEW_COLOR;
}
-#ifdef USE_MMX_ASM
-#define _BLENDAPI _ASMAPI
-#else
-#define _BLENDAPI
-#endif
-
-/*
- * Common transparency blending mode.
- */
-static void _BLENDAPI
-blend_transparency( GLcontext *ctx, GLuint n, const GLubyte mask[],
- GLchan rgba[][4], CONST GLchan dest[][4] )
-{
- GLuint i;
- ASSERT(ctx->Color.BlendEquation==GL_FUNC_ADD_EXT);
- ASSERT(ctx->Color.BlendSrcRGB==GL_SRC_ALPHA);
- ASSERT(ctx->Color.BlendDstRGB==GL_ONE_MINUS_SRC_ALPHA);
- (void) ctx;
-
- for (i=0;i<n;i++) {
- if (mask[i]) {
- const GLint t = rgba[i][ACOMP]; /* t in [0, CHAN_MAX] */
- if (t == 0) {
- /* 0% alpha */
- rgba[i][RCOMP] = dest[i][RCOMP];
- rgba[i][GCOMP] = dest[i][GCOMP];
- rgba[i][BCOMP] = dest[i][BCOMP];
- rgba[i][ACOMP] = dest[i][ACOMP];
- }
- else if (t == CHAN_MAX) {
- /* 100% alpha, no-op */
- }
- else {
-#if 0
- /* This is pretty close, but Glean complains */
- const GLint s = CHAN_MAX - t;
- const GLint r = (rgba[i][RCOMP] * t + dest[i][RCOMP] * s + 1) >> 8;
- const GLint g = (rgba[i][GCOMP] * t + dest[i][GCOMP] * s + 1) >> 8;
- const GLint b = (rgba[i][BCOMP] * t + dest[i][BCOMP] * s + 1) >> 8;
- const GLint a = (rgba[i][ACOMP] * t + dest[i][ACOMP] * s + 1) >> 8;
-#elif 0
- /* This is slower but satisfies Glean */
- const GLint s = CHAN_MAX - t;
- const GLint r = (rgba[i][RCOMP] * t + dest[i][RCOMP] * s) / 255;
- const GLint g = (rgba[i][GCOMP] * t + dest[i][GCOMP] * s) / 255;
- const GLint b = (rgba[i][BCOMP] * t + dest[i][BCOMP] * s) / 255;
- const GLint a = (rgba[i][ACOMP] * t + dest[i][ACOMP] * s) / 255;
-#else
-#if CHAN_BITS == 8
- /* This satisfies Glean and should be reasonably fast */
- /* Contributed by Nathan Hand */
-#define DIV255(X) (((X) << 8) + (X) + 256) >> 16
- const GLint s = CHAN_MAX - t;
- const GLint r = DIV255(rgba[i][RCOMP] * t + dest[i][RCOMP] * s);
- const GLint g = DIV255(rgba[i][GCOMP] * t + dest[i][GCOMP] * s);
- const GLint b = DIV255(rgba[i][BCOMP] * t + dest[i][BCOMP] * s);
- const GLint a = DIV255(rgba[i][ACOMP] * t + dest[i][ACOMP] * s);
-#undef DIV255
-#else
- const GLint s = CHAN_MAX - t;
- const GLint r = (rgba[i][RCOMP] * t + dest[i][RCOMP] * s) / CHAN_MAX;
- const GLint g = (rgba[i][GCOMP] * t + dest[i][GCOMP] * s) / CHAN_MAX;
- const GLint b = (rgba[i][BCOMP] * t + dest[i][BCOMP] * s) / CHAN_MAX;
- const GLint a = (rgba[i][ACOMP] * t + dest[i][ACOMP] * s) / CHAN_MAX;
-#endif
-#endif
- ASSERT(r <= CHAN_MAX);
- ASSERT(g <= CHAN_MAX);
- ASSERT(b <= CHAN_MAX);
- ASSERT(a <= CHAN_MAX);
- rgba[i][RCOMP] = (GLchan) r;
- rgba[i][GCOMP] = (GLchan) g;
- rgba[i][BCOMP] = (GLchan) b;
- rgba[i][ACOMP] = (GLchan) a;
- }
- }
- }
-}
-
-
-
-/*
- * Add src and dest.
- */
-static void _BLENDAPI
-blend_add( GLcontext *ctx, GLuint n, const GLubyte mask[],
- GLchan rgba[][4], CONST GLchan dest[][4] )
-{
- GLuint i;
- ASSERT(ctx->Color.BlendEquation==GL_FUNC_ADD_EXT);
- ASSERT(ctx->Color.BlendSrcRGB==GL_ONE);
- ASSERT(ctx->Color.BlendDstRGB==GL_ONE);
- (void) ctx;
-
- for (i=0;i<n;i++) {
- if (mask[i]) {
- GLint r = rgba[i][RCOMP] + dest[i][RCOMP];
- GLint g = rgba[i][GCOMP] + dest[i][GCOMP];
- GLint b = rgba[i][BCOMP] + dest[i][BCOMP];
- GLint a = rgba[i][ACOMP] + dest[i][ACOMP];
- rgba[i][RCOMP] = (GLchan) MIN2( r, CHAN_MAX );
- rgba[i][GCOMP] = (GLchan) MIN2( g, CHAN_MAX );
- rgba[i][BCOMP] = (GLchan) MIN2( b, CHAN_MAX );
- rgba[i][ACOMP] = (GLchan) MIN2( a, CHAN_MAX );
- }
- }
-}
-
-
-
-/*
- * Blend min function (for GL_EXT_blend_minmax)
- */
-static void _BLENDAPI
-blend_min( GLcontext *ctx, GLuint n, const GLubyte mask[],
- GLchan rgba[][4], CONST GLchan dest[][4] )
-{
- GLuint i;
- ASSERT(ctx->Color.BlendEquation==GL_MIN_EXT);
- (void) ctx;
-
- for (i=0;i<n;i++) {
- if (mask[i]) {
- rgba[i][RCOMP] = (GLchan) MIN2( rgba[i][RCOMP], dest[i][RCOMP] );
- rgba[i][GCOMP] = (GLchan) MIN2( rgba[i][GCOMP], dest[i][GCOMP] );
- rgba[i][BCOMP] = (GLchan) MIN2( rgba[i][BCOMP], dest[i][BCOMP] );
- rgba[i][ACOMP] = (GLchan) MIN2( rgba[i][ACOMP], dest[i][ACOMP] );
- }
- }
-}
-
-
-
-/*
- * Blend max function (for GL_EXT_blend_minmax)
- */
-static void _BLENDAPI
-blend_max( GLcontext *ctx, GLuint n, const GLubyte mask[],
- GLchan rgba[][4], CONST GLchan dest[][4] )
-{
- GLuint i;
- ASSERT(ctx->Color.BlendEquation==GL_MAX_EXT);
- (void) ctx;
-
- for (i=0;i<n;i++) {
- if (mask[i]) {
- rgba[i][RCOMP] = (GLchan) MAX2( rgba[i][RCOMP], dest[i][RCOMP] );
- rgba[i][GCOMP] = (GLchan) MAX2( rgba[i][GCOMP], dest[i][GCOMP] );
- rgba[i][BCOMP] = (GLchan) MAX2( rgba[i][BCOMP], dest[i][BCOMP] );
- rgba[i][ACOMP] = (GLchan) MAX2( rgba[i][ACOMP], dest[i][ACOMP] );
- }
- }
-}
-
-
-
-/*
- * Modulate: result = src * dest
- */
-static void _BLENDAPI
-blend_modulate( GLcontext *ctx, GLuint n, const GLubyte mask[],
- GLchan rgba[][4], CONST GLchan dest[][4] )
-{
- GLuint i;
- (void) ctx;
-
- for (i=0;i<n;i++) {
- if (mask[i]) {
- GLint r = (rgba[i][RCOMP] * dest[i][RCOMP]) >> 8;
- GLint g = (rgba[i][GCOMP] * dest[i][GCOMP]) >> 8;
- GLint b = (rgba[i][BCOMP] * dest[i][BCOMP]) >> 8;
- GLint a = (rgba[i][ACOMP] * dest[i][ACOMP]) >> 8;
- rgba[i][RCOMP] = (GLchan) r;
- rgba[i][GCOMP] = (GLchan) g;
- rgba[i][BCOMP] = (GLchan) b;
- rgba[i][ACOMP] = (GLchan) a;
- }
- }
-}
-
-
-
-/*
- * General case blend pixels.
- * Input: n - number of pixels
- * mask - the usual write mask
- * In/Out: rgba - the incoming and modified pixels
- * Input: dest - the pixels from the dest color buffer
- */
-static void _BLENDAPI
-blend_general( GLcontext *ctx, GLuint n, const GLubyte mask[],
- GLchan rgba[][4], CONST GLchan dest[][4] )
-{
- GLfloat rscale = 1.0F / CHAN_MAXF;
- GLfloat gscale = 1.0F / CHAN_MAXF;
- GLfloat bscale = 1.0F / CHAN_MAXF;
- GLfloat ascale = 1.0F / CHAN_MAXF;
- GLuint i;
-
- for (i=0;i<n;i++) {
- if (mask[i]) {
- GLint Rs, Gs, Bs, As; /* Source colors */
- GLint Rd, Gd, Bd, Ad; /* Dest colors */
- GLfloat sR, sG, sB, sA; /* Source scaling */
- GLfloat dR, dG, dB, dA; /* Dest scaling */
- GLfloat r, g, b, a;
-
- /* Source Color */
- Rs = rgba[i][RCOMP];
- Gs = rgba[i][GCOMP];
- Bs = rgba[i][BCOMP];
- As = rgba[i][ACOMP];
-
- /* Frame buffer color */
- Rd = dest[i][RCOMP];
- Gd = dest[i][GCOMP];
- Bd = dest[i][BCOMP];
- Ad = dest[i][ACOMP];
-
- /* Source RGB factor */
- switch (ctx->Color.BlendSrcRGB) {
- case GL_ZERO:
- sR = sG = sB = 0.0F;
- break;
- case GL_ONE:
- sR = sG = sB = 1.0F;
- break;
- case GL_DST_COLOR:
- sR = (GLfloat) Rd * rscale;
- sG = (GLfloat) Gd * gscale;
- sB = (GLfloat) Bd * bscale;
- break;
- case GL_ONE_MINUS_DST_COLOR:
- sR = 1.0F - (GLfloat) Rd * rscale;
- sG = 1.0F - (GLfloat) Gd * gscale;
- sB = 1.0F - (GLfloat) Bd * bscale;
- break;
- case GL_SRC_ALPHA:
- sR = sG = sB = (GLfloat) As * ascale;
- break;
- case GL_ONE_MINUS_SRC_ALPHA:
- sR = sG = sB = (GLfloat) 1.0F - (GLfloat) As * ascale;
- break;
- case GL_DST_ALPHA:
- sR = sG = sB = (GLfloat) Ad * ascale;
- break;
- case GL_ONE_MINUS_DST_ALPHA:
- sR = sG = sB = 1.0F - (GLfloat) Ad * ascale;
- break;
- case GL_SRC_ALPHA_SATURATE:
- if (As < CHAN_MAX - Ad) {
- sR = sG = sB = (GLfloat) As * ascale;
- }
- else {
- sR = sG = sB = 1.0F - (GLfloat) Ad * ascale;
- }
- break;
- case GL_CONSTANT_COLOR:
- sR = ctx->Color.BlendColor[0];
- sG = ctx->Color.BlendColor[1];
- sB = ctx->Color.BlendColor[2];
- break;
- case GL_ONE_MINUS_CONSTANT_COLOR:
- sR = 1.0F - ctx->Color.BlendColor[0];
- sG = 1.0F - ctx->Color.BlendColor[1];
- sB = 1.0F - ctx->Color.BlendColor[2];
- break;
- case GL_CONSTANT_ALPHA:
- sR = sG = sB = ctx->Color.BlendColor[3];
- break;
- case GL_ONE_MINUS_CONSTANT_ALPHA:
- sR = sG = sB = 1.0F - ctx->Color.BlendColor[3];
- break;
- case GL_SRC_COLOR: /* GL_NV_blend_square */
- sR = (GLfloat) Rs * rscale;
- sG = (GLfloat) Gs * gscale;
- sB = (GLfloat) Bs * bscale;
- break;
- case GL_ONE_MINUS_SRC_COLOR: /* GL_NV_blend_square */
- sR = 1.0F - (GLfloat) Rs * rscale;
- sG = 1.0F - (GLfloat) Gs * gscale;
- sB = 1.0F - (GLfloat) Bs * bscale;
- break;
- default:
- /* this should never happen */
- gl_problem(ctx, "Bad blend source RGB factor in do_blend");
- return;
- }
-
- /* Source Alpha factor */
- switch (ctx->Color.BlendSrcA) {
- case GL_ZERO:
- sA = 0.0F;
- break;
- case GL_ONE:
- sA = 1.0F;
- break;
- case GL_DST_COLOR:
- sA = (GLfloat) Ad * ascale;
- break;
- case GL_ONE_MINUS_DST_COLOR:
- sA = 1.0F - (GLfloat) Ad * ascale;
- break;
- case GL_SRC_ALPHA:
- sA = (GLfloat) As * ascale;
- break;
- case GL_ONE_MINUS_SRC_ALPHA:
- sA = (GLfloat) 1.0F - (GLfloat) As * ascale;
- break;
- case GL_DST_ALPHA:
- sA =(GLfloat) Ad * ascale;
- break;
- case GL_ONE_MINUS_DST_ALPHA:
- sA = 1.0F - (GLfloat) Ad * ascale;
- break;
- case GL_SRC_ALPHA_SATURATE:
- sA = 1.0;
- break;
- case GL_CONSTANT_COLOR:
- sA = ctx->Color.BlendColor[3];
- break;
- case GL_ONE_MINUS_CONSTANT_COLOR:
- sA = 1.0F - ctx->Color.BlendColor[3];
- break;
- case GL_CONSTANT_ALPHA:
- sA = ctx->Color.BlendColor[3];
- break;
- case GL_ONE_MINUS_CONSTANT_ALPHA:
- sA = 1.0F - ctx->Color.BlendColor[3];
- break;
- case GL_SRC_COLOR: /* GL_NV_blend_square */
- sA = (GLfloat) As * ascale;
- break;
- case GL_ONE_MINUS_SRC_COLOR: /* GL_NV_blend_square */
- sA = 1.0F - (GLfloat) As * ascale;
- break;
- default:
- /* this should never happen */
- sA = 0.0F;
- gl_problem(ctx, "Bad blend source A factor in do_blend");
- }
-
- /* Dest RGB factor */
- switch (ctx->Color.BlendDstRGB) {
- case GL_ZERO:
- dR = dG = dB = 0.0F;
- break;
- case GL_ONE:
- dR = dG = dB = 1.0F;
- break;
- case GL_SRC_COLOR:
- dR = (GLfloat) Rs * rscale;
- dG = (GLfloat) Gs * gscale;
- dB = (GLfloat) Bs * bscale;
- break;
- case GL_ONE_MINUS_SRC_COLOR:
- dR = 1.0F - (GLfloat) Rs * rscale;
- dG = 1.0F - (GLfloat) Gs * gscale;
- dB = 1.0F - (GLfloat) Bs * bscale;
- break;
- case GL_SRC_ALPHA:
- dR = dG = dB = (GLfloat) As * ascale;
- break;
- case GL_ONE_MINUS_SRC_ALPHA:
- dR = dG = dB = (GLfloat) 1.0F - (GLfloat) As * ascale;
- break;
- case GL_DST_ALPHA:
- dR = dG = dB = (GLfloat) Ad * ascale;
- break;
- case GL_ONE_MINUS_DST_ALPHA:
- dR = dG = dB = 1.0F - (GLfloat) Ad * ascale;
- break;
- case GL_CONSTANT_COLOR:
- dR = ctx->Color.BlendColor[0];
- dG = ctx->Color.BlendColor[1];
- dB = ctx->Color.BlendColor[2];
- break;
- case GL_ONE_MINUS_CONSTANT_COLOR:
- dR = 1.0F - ctx->Color.BlendColor[0];
- dG = 1.0F - ctx->Color.BlendColor[1];
- dB = 1.0F - ctx->Color.BlendColor[2];
- break;
- case GL_CONSTANT_ALPHA:
- dR = dG = dB = ctx->Color.BlendColor[3];
- break;
- case GL_ONE_MINUS_CONSTANT_ALPHA:
- dR = dG = dB = 1.0F - ctx->Color.BlendColor[3];
- break;
- case GL_DST_COLOR: /* GL_NV_blend_square */
- dR = (GLfloat) Rd * rscale;
- dG = (GLfloat) Gd * gscale;
- dB = (GLfloat) Bd * bscale;
- break;
- case GL_ONE_MINUS_DST_COLOR: /* GL_NV_blend_square */
- dR = 1.0F - (GLfloat) Rd * rscale;
- dG = 1.0F - (GLfloat) Gd * gscale;
- dB = 1.0F - (GLfloat) Bd * bscale;
- break;
- default:
- /* this should never happen */
- dR = dG = dB = 0.0F;
- gl_problem(ctx, "Bad blend dest RGB factor in do_blend");
- }
-
- /* Dest Alpha factor */
- switch (ctx->Color.BlendDstA) {
- case GL_ZERO:
- dA = 0.0F;
- break;
- case GL_ONE:
- dA = 1.0F;
- break;
- case GL_SRC_COLOR:
- dA = (GLfloat) As * ascale;
- break;
- case GL_ONE_MINUS_SRC_COLOR:
- dA = 1.0F - (GLfloat) As * ascale;
- break;
- case GL_SRC_ALPHA:
- dA = (GLfloat) As * ascale;
- break;
- case GL_ONE_MINUS_SRC_ALPHA:
- dA = (GLfloat) 1.0F - (GLfloat) As * ascale;
- break;
- case GL_DST_ALPHA:
- dA = (GLfloat) Ad * ascale;
- break;
- case GL_ONE_MINUS_DST_ALPHA:
- dA = 1.0F - (GLfloat) Ad * ascale;
- break;
- case GL_CONSTANT_COLOR:
- dA = ctx->Color.BlendColor[3];
- break;
- case GL_ONE_MINUS_CONSTANT_COLOR:
- dA = 1.0F - ctx->Color.BlendColor[3];
- break;
- case GL_CONSTANT_ALPHA:
- dA = ctx->Color.BlendColor[3];
- break;
- case GL_ONE_MINUS_CONSTANT_ALPHA:
- dA = 1.0F - ctx->Color.BlendColor[3];
- break;
- case GL_DST_COLOR: /* GL_NV_blend_square */
- dA = (GLfloat) Ad * ascale;
- break;
- case GL_ONE_MINUS_DST_COLOR: /* GL_NV_blend_square */
- dA = 1.0F - (GLfloat) Ad * ascale;
- break;
- default:
- /* this should never happen */
- dA = 0.0F;
- gl_problem(ctx, "Bad blend dest A factor in do_blend");
- return;
- }
-
- /* Due to round-off problems we have to clamp against zero. */
- /* Optimization: we don't have to do this for all src & dst factors */
- if (dA < 0.0F) dA = 0.0F;
- if (dR < 0.0F) dR = 0.0F;
- if (dG < 0.0F) dG = 0.0F;
- if (dB < 0.0F) dB = 0.0F;
- if (sA < 0.0F) sA = 0.0F;
- if (sR < 0.0F) sR = 0.0F;
- if (sG < 0.0F) sG = 0.0F;
- if (sB < 0.0F) sB = 0.0F;
-
- ASSERT( sR <= 1.0 );
- ASSERT( sG <= 1.0 );
- ASSERT( sB <= 1.0 );
- ASSERT( sA <= 1.0 );
- ASSERT( dR <= 1.0 );
- ASSERT( dG <= 1.0 );
- ASSERT( dB <= 1.0 );
- ASSERT( dA <= 1.0 );
-
- /* compute blended color */
- if (ctx->Color.BlendEquation==GL_FUNC_ADD_EXT) {
- r = Rs * sR + Rd * dR + 0.5F;
- g = Gs * sG + Gd * dG + 0.5F;
- b = Bs * sB + Bd * dB + 0.5F;
- a = As * sA + Ad * dA + 0.5F;
- }
- else if (ctx->Color.BlendEquation==GL_FUNC_SUBTRACT_EXT) {
- r = Rs * sR - Rd * dR + 0.5F;
- g = Gs * sG - Gd * dG + 0.5F;
- b = Bs * sB - Bd * dB + 0.5F;
- a = As * sA - Ad * dA + 0.5F;
- }
- else if (ctx->Color.BlendEquation==GL_FUNC_REVERSE_SUBTRACT_EXT) {
- r = Rd * dR - Rs * sR + 0.5F;
- g = Gd * dG - Gs * sG + 0.5F;
- b = Bd * dB - Bs * sB + 0.5F;
- a = Ad * dA - As * sA + 0.5F;
- }
- else {
- /* should never get here */
- r = g = b = a = 0.0F; /* silence uninitialized var warning */
- gl_problem(ctx, "unexpected BlendEquation in blend_general()");
- }
-
- /* final clamping */
- rgba[i][RCOMP] = (GLchan) (GLint) CLAMP( r, 0.0F, CHAN_MAXF );
- rgba[i][GCOMP] = (GLchan) (GLint) CLAMP( g, 0.0F, CHAN_MAXF );
- rgba[i][BCOMP] = (GLchan) (GLint) CLAMP( b, 0.0F, CHAN_MAXF );
- rgba[i][ACOMP] = (GLchan) (GLint) CLAMP( a, 0.0F, CHAN_MAXF );
- }
- }
-}
-
-
-
-#if defined(USE_MMX_ASM)
-#include "X86/mmx.h"
-#include "X86/common_x86_asm.h"
-#endif
-
-
-/*
- * Analyze current blending parameters to pick fastest blending function.
- * Result: the ctx->Color.BlendFunc pointer is updated.
- */
-static void set_blend_function( GLcontext *ctx )
-{
- const GLenum eq = ctx->Color.BlendEquation;
- const GLenum srcRGB = ctx->Color.BlendSrcRGB;
- const GLenum dstRGB = ctx->Color.BlendDstRGB;
- const GLenum srcA = ctx->Color.BlendSrcA;
- const GLenum dstA = ctx->Color.BlendDstA;
-
-#if defined(USE_MMX_ASM)
- /* Hmm. A table here would have 12^4 == way too many entries.
- * Provide a hook for MMX instead.
- */
- if ( cpu_has_mmx ) {
- gl_mmx_set_blend_function( ctx );
- }
- else
-#endif
- if (srcRGB != srcA || dstRGB != dstA) {
- ctx->Color.BlendFunc = blend_general;
- }
- else if (eq==GL_FUNC_ADD_EXT && srcRGB==GL_SRC_ALPHA
- && dstRGB==GL_ONE_MINUS_SRC_ALPHA) {
- ctx->Color.BlendFunc = blend_transparency;
- }
- else if (eq==GL_FUNC_ADD_EXT && srcRGB==GL_ONE && dstRGB==GL_ONE) {
- ctx->Color.BlendFunc = blend_add;
- }
- else if (((eq==GL_FUNC_ADD_EXT || eq==GL_FUNC_REVERSE_SUBTRACT_EXT)
- && (srcRGB==GL_ZERO && dstRGB==GL_SRC_COLOR))
- ||
- ((eq==GL_FUNC_ADD_EXT || eq==GL_FUNC_SUBTRACT_EXT)
- && (srcRGB==GL_DST_COLOR && dstRGB==GL_ZERO))) {
- ctx->Color.BlendFunc = blend_modulate;
- }
- else if (eq==GL_MIN_EXT) {
- ctx->Color.BlendFunc = blend_min;
- }
- else if (eq==GL_MAX_EXT) {
- ctx->Color.BlendFunc = blend_max;
- }
- else {
- ctx->Color.BlendFunc = blend_general;
- }
-}
-
-
-
-/*
- * 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
- */
-void
-_mesa_blend_span( GLcontext *ctx, GLuint n, GLint x, GLint y,
- GLchan rgba[][4], const GLubyte mask[] )
-{
- GLchan dest[MAX_WIDTH][4];
-
- /* Check if device driver can do the work */
- if (ctx->Color.BlendEquation==GL_LOGIC_OP &&
- !ctx->Color.ColorLogicOpEnabled) {
- return;
- }
-
- /* Read span of current frame buffer pixels */
- gl_read_rgba_span( ctx, ctx->DrawBuffer, n, x, y, dest );
-
- if (!ctx->Color.BlendFunc)
- set_blend_function(ctx);
-
- (*ctx->Color.BlendFunc)( ctx, n, mask, rgba, (const GLchan (*)[4])dest );
-}
-
-
-
-/*
- * Apply the blending operator to an array of pixels.
- * Input: n - number of pixels in span
- * x, y - array of pixel locations
- * mask - boolean mask indicating which pixels to blend.
- * In/Out: rgba - pixel values
- */
-void
-_mesa_blend_pixels( GLcontext *ctx,
- GLuint n, const GLint x[], const GLint y[],
- GLchan rgba[][4], const GLubyte mask[] )
-{
- GLchan dest[PB_SIZE][4];
-
- /* Check if device driver can do the work */
- if (ctx->Color.BlendEquation==GL_LOGIC_OP &&
- !ctx->Color.ColorLogicOpEnabled) {
- return;
- }
-
- /* Read pixels from current color buffer */
- (*ctx->Driver.ReadRGBAPixels)( ctx, n, x, y, dest, mask );
- if (ctx->RasterMask & ALPHABUF_BIT) {
- _mesa_read_alpha_pixels( ctx, n, x, y, dest, mask );
- }
-
- if (!ctx->Color.BlendFunc)
- set_blend_function(ctx);
-
- (*ctx->Color.BlendFunc)( ctx, n, mask, rgba, (const GLchan (*)[4])dest );
-}
-/* $Id: blend.h,v 1.5 2000/10/28 18:34:48 brianp Exp $ */
+/* $Id: blend.h,v 1.6 2000/10/31 18:09:44 keithw Exp $ */
/*
* Mesa 3-D graphics library
#include "types.h"
-
-
-extern void
-_mesa_blend_span( GLcontext *ctx, GLuint n, GLint x, GLint y,
- GLchan rgba[][4], const GLubyte mask[] );
-
-
-extern void
-_mesa_blend_pixels( GLcontext *ctx,
- GLuint n, const GLint x[], const GLint y[],
- GLchan rgba[][4], const GLubyte mask[] );
-
-
extern void
_mesa_BlendFunc( GLenum sfactor, GLenum dfactor );
-/* $Id: buffers.c,v 1.17 2000/10/30 16:32:43 brianp Exp $ */
+/* $Id: buffers.c,v 1.18 2000/10/31 18:09:44 keithw Exp $ */
/*
* Mesa 3-D graphics library
#else
#include "glheader.h"
#include "accum.h"
-#include "alphabuf.h"
#include "buffers.h"
#include "context.h"
#include "depth.h"
#include "stencil.h"
#include "state.h"
#include "types.h"
+#include "swrast/swrast.h"
#endif
-/*
- * Clear the color buffer when glColorMask or glIndexMask is in effect.
- */
-static void
-clear_color_buffer_with_masking( GLcontext *ctx )
-{
- const GLint x = ctx->DrawBuffer->Xmin;
- const GLint y = ctx->DrawBuffer->Ymin;
- const GLint height = ctx->DrawBuffer->Ymax - ctx->DrawBuffer->Ymin;
- const GLint width = ctx->DrawBuffer->Xmax - ctx->DrawBuffer->Xmin;
-
- if (ctx->Visual.RGBAflag) {
- /* RGBA mode */
- const GLchan r = (GLint) (ctx->Color.ClearColor[0] * CHAN_MAXF);
- const GLchan g = (GLint) (ctx->Color.ClearColor[1] * CHAN_MAXF);
- const GLchan b = (GLint) (ctx->Color.ClearColor[2] * CHAN_MAXF);
- const GLchan a = (GLint) (ctx->Color.ClearColor[3] * CHAN_MAXF);
- GLint i;
- for (i = 0; i < height; i++) {
- GLchan rgba[MAX_WIDTH][4];
- GLint j;
- for (j=0; j<width; j++) {
- rgba[j][RCOMP] = r;
- rgba[j][GCOMP] = g;
- rgba[j][BCOMP] = b;
- rgba[j][ACOMP] = a;
- }
- _mesa_mask_rgba_span( ctx, width, x, y + i, rgba );
- (*ctx->Driver.WriteRGBASpan)( ctx, width, x, y + i,
- (CONST GLchan (*)[4]) rgba, NULL );
- }
- }
- else {
- /* Color index mode */
- GLuint span[MAX_WIDTH];
- GLubyte mask[MAX_WIDTH];
- GLint i, j;
- MEMSET( mask, 1, width );
- for (i=0;i<height;i++) {
- for (j=0;j<width;j++) {
- span[j] = ctx->Color.ClearIndex;
- }
- _mesa_mask_index_span( ctx, width, x, y + i, span );
- (*ctx->Driver.WriteCI32Span)( ctx, width, x, y + i, span, mask );
- }
- }
-}
-
-
-
-/*
- * Clear a color buffer without index/channel masking.
- */
-static void
-clear_color_buffer(GLcontext *ctx)
-{
- const GLint x = ctx->DrawBuffer->Xmin;
- const GLint y = ctx->DrawBuffer->Ymin;
- const GLint height = ctx->DrawBuffer->Ymax - ctx->DrawBuffer->Ymin;
- const GLint width = ctx->DrawBuffer->Xmax - ctx->DrawBuffer->Xmin;
- const GLuint colorMask = *((GLuint *) &ctx->Color.ColorMask);
-
- if (ctx->Visual.RGBAflag) {
- /* RGBA mode */
- const GLchan r = (GLint) (ctx->Color.ClearColor[0] * CHAN_MAXF);
- const GLchan g = (GLint) (ctx->Color.ClearColor[1] * CHAN_MAXF);
- const GLchan b = (GLint) (ctx->Color.ClearColor[2] * CHAN_MAXF);
- const GLchan a = (GLint) (ctx->Color.ClearColor[3] * CHAN_MAXF);
- GLchan span[MAX_WIDTH][4];
- GLint i;
-
- ASSERT(colorMask == 0xffffffff);
-
- for (i = 0; i < width; i++) {
- span[i][RCOMP] = r;
- span[i][GCOMP] = g;
- span[i][BCOMP] = b;
- span[i][ACOMP] = a;
- }
- for (i = 0; i < height; i++) {
- (*ctx->Driver.WriteRGBASpan)( ctx, width, x, y + i,
- (CONST GLchan (*)[4]) span, NULL );
- }
- }
- else {
- /* Color index mode */
- ASSERT(ctx->Color.IndexMask == ~0);
- if (ctx->Visual.IndexBits == 8) {
- /* 8-bit clear */
- GLubyte span[MAX_WIDTH];
- GLint i;
- MEMSET(span, ctx->Color.ClearIndex, width);
- for (i = 0; i < height; i++) {
- (*ctx->Driver.WriteCI8Span)( ctx, width, x, y + i, span, NULL );
- }
- }
- else {
- /* non 8-bit clear */
- GLuint span[MAX_WIDTH];
- GLint i;
- for (i = 0; i < width; i++) {
- span[i] = ctx->Color.ClearIndex;
- }
- for (i = 0; i < height; i++) {
- (*ctx->Driver.WriteCI32Span)( ctx, width, x, y + i, span, NULL );
- }
- }
- }
-}
-
-
-
-/*
- * Clear the front/back/left/right color buffers.
- * This function is usually only called if we need to clear the
- * buffers with masking.
- */
-static void
-clear_color_buffers(GLcontext *ctx)
-{
- const GLuint colorMask = *((GLuint *) &ctx->Color.ColorMask);
- GLuint bufferBit;
-
- /* loop over four possible dest color buffers */
- for (bufferBit = 1; bufferBit <= 8; bufferBit = bufferBit << 1) {
- if (bufferBit & ctx->Color.DrawDestMask) {
- if (bufferBit == FRONT_LEFT_BIT) {
- (void) (*ctx->Driver.SetDrawBuffer)( ctx, GL_FRONT_LEFT);
- (void) (*ctx->Driver.SetReadBuffer)( ctx, ctx->DrawBuffer, GL_FRONT_LEFT);
- }
- else if (bufferBit == FRONT_RIGHT_BIT) {
- (void) (*ctx->Driver.SetDrawBuffer)( ctx, GL_FRONT_RIGHT);
- (void) (*ctx->Driver.SetReadBuffer)( ctx, ctx->DrawBuffer, GL_FRONT_RIGHT);
- }
- else if (bufferBit == BACK_LEFT_BIT) {
- (void) (*ctx->Driver.SetDrawBuffer)( ctx, GL_BACK_LEFT);
- (void) (*ctx->Driver.SetReadBuffer)( ctx, ctx->DrawBuffer, GL_BACK_LEFT);
- }
- else {
- (void) (*ctx->Driver.SetDrawBuffer)( ctx, GL_BACK_RIGHT);
- (void) (*ctx->Driver.SetReadBuffer)( ctx, ctx->DrawBuffer, GL_BACK_RIGHT);
- }
-
- if (colorMask != 0xffffffff) {
- clear_color_buffer_with_masking(ctx);
- }
- else {
- clear_color_buffer(ctx);
- }
- }
- }
-
- /* restore default read/draw buffers */
- (void) (*ctx->Driver.SetDrawBuffer)( ctx, ctx->Color.DriverDrawBuffer );
- (void) (*ctx->Driver.SetReadBuffer)( ctx, ctx->ReadBuffer, ctx->Pixel.DriverReadBuffer );
-}
-
void
_mesa_Clear( GLbitfield mask )
{
GET_CURRENT_CONTEXT(ctx);
-#ifdef PROFILE
- GLdouble t0 = gl_time();
-#endif
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glClear");
if (MESA_VERBOSE & VERBOSE_API)
}
#endif
- RENDER_START(ctx);
-
- /* do software clearing here */
- if (newMask) {
- if (newMask & ctx->Color.DrawDestMask) clear_color_buffers(ctx);
- if (newMask & GL_DEPTH_BUFFER_BIT) _mesa_clear_depth_buffer(ctx);
- if (newMask & GL_ACCUM_BUFFER_BIT) _mesa_clear_accum_buffer(ctx);
- if (newMask & GL_STENCIL_BUFFER_BIT) _mesa_clear_stencil_buffer(ctx);
- }
-
- /* clear software-based alpha buffer(s) */
- if ( (mask & GL_COLOR_BUFFER_BIT)
- && ctx->DrawBuffer->UseSoftwareAlphaBuffers
- && ctx->Color.ColorMask[ACOMP]) {
- _mesa_clear_alpha_buffers( ctx );
- }
-
- RENDER_FINISH(ctx);
-
-#ifdef PROFILE
- ctx->ClearTime += gl_time() - t0;
- ctx->ClearCount++;
-#endif
+ if (newMask)
+ _swrast_Clear( ctx, newMask, !ctx->Scissor.Enabled,
+ x, y, width, height );
}
}
ctx->DrawBuffer->Width = buf_width;
ctx->DrawBuffer->Height = buf_height;
- /* Reallocate other buffers if needed. */
- if (ctx->DrawBuffer->UseSoftwareDepthBuffer) {
- _mesa_alloc_depth_buffer( ctx );
- }
- if (ctx->DrawBuffer->UseSoftwareStencilBuffer) {
- _mesa_alloc_stencil_buffer( ctx );
- }
- if (ctx->DrawBuffer->UseSoftwareAccumBuffer) {
- _mesa_alloc_accum_buffer( ctx );
- }
- if (ctx->DrawBuffer->UseSoftwareAlphaBuffers) {
- _mesa_alloc_alpha_buffers( ctx );
- }
+ _swrast_alloc_buffers( ctx );
}
-/* $Id: colortab.c,v 1.24 2000/10/30 13:32:00 keithw Exp $ */
+/* $Id: colortab.c,v 1.25 2000/10/31 18:09:44 keithw Exp $ */
/*
* Mesa 3-D graphics library
#include "macros.h"
#include "mem.h"
#include "mmath.h"
-#include "span.h"
#endif
-/* $Id: context.c,v 1.101 2000/10/30 18:50:42 keithw Exp $ */
+/* $Id: context.c,v 1.102 2000/10/31 18:09:44 keithw Exp $ */
/*
* Mesa 3-D graphics library
#include "matrix.h"
#include "mem.h"
#include "mmath.h"
-#include "pb.h"
#include "pipeline.h"
#include "shade.h"
#include "simple_list.h"
#include "vbxform.h"
#include "vertices.h"
#include "xform.h"
+#include "swrast/swrast.h"
#endif
#if defined(MESA_TRACE)
gl_init_clip();
gl_init_eval();
- _mesa_init_fog();
_mesa_init_math();
gl_init_lists();
gl_init_shade();
return GL_FALSE;
}
ctx->input = ctx->VB->IM;
-
- ctx->PB = gl_alloc_pb();
- if (!ctx->PB) {
+
+ if (!_swrast_create_context( ctx )) {
ALIGN_FREE( ctx->VB );
return GL_FALSE;
}
ctx->Shared = alloc_shared_state();
if (!ctx->Shared) {
ALIGN_FREE( ctx->VB );
- FREE( ctx->PB );
+ _swrast_destroy_context( ctx );
return GL_FALSE;
}
}
if (!alloc_proxy_textures(ctx)) {
free_shared_state(ctx, ctx->Shared);
ALIGN_FREE( ctx->VB );
- FREE( ctx->PB );
+ _swrast_destroy_context( ctx );
return GL_FALSE;
}
if (!ctx->Exec || !ctx->Save) {
free_shared_state(ctx, ctx->Shared);
ALIGN_FREE( ctx->VB );
- FREE( ctx->PB );
+ _swrast_destroy_context( ctx );
if (ctx->Exec)
FREE( ctx->Exec );
}
if (!(ctx->TraceCtx)) {
free_shared_state(ctx, ctx->Shared);
ALIGN_FREE( ctx->VB );
- FREE( ctx->PB );
+ _swrast_destroy_context( ctx );
FREE( ctx->Exec );
FREE( ctx->Save );
return GL_FALSE;
if (!(ctx->TraceCtx)) {
free_shared_state(ctx, ctx->Shared);
ALIGN_FREE( ctx->VB );
- FREE( ctx->PB );
+ _swrast_destroy_context( ctx );
FREE( ctx->Exec );
FREE( ctx->Save );
FREE( ctx->TraceCtx );
}
}
- FREE( ctx->PB );
+ _swrast_destroy_context( ctx );
if (ctx->input != ctx->VB->IM)
gl_immediate_free( ctx->input );
-/* $Id: convolve.c,v 1.8 2000/10/30 13:32:00 keithw Exp $ */
+/* $Id: convolve.c,v 1.9 2000/10/31 18:09:44 keithw Exp $ */
/*
* Mesa 3-D graphics library
#include "convolve.h"
#include "context.h"
#include "image.h"
-#include "span.h"
#include "types.h"
#endif
-/* $Id: dd.h,v 1.36 2000/10/30 13:32:00 keithw Exp $ */
+/* $Id: dd.h,v 1.37 2000/10/31 18:09:44 keithw Exp $ */
/*
* Mesa 3-D graphics library
/* This is called by glBitmap. Works the same as DrawPixels, above.
*/
+ GLboolean (*Accum)( GLcontext *ctx, GLenum op,
+ GLfloat value, GLint xpos, GLint ypos,
+ GLint width, GLint height );
+ /* Hardware accum buffer.
+ */
/***
*** Texture mapping functions:
-/* $Id: depth.c,v 1.21 2000/10/30 13:32:00 keithw Exp $ */
+/* $Id: depth.c,v 1.22 2000/10/31 18:09:44 keithw Exp $ */
/*
* Mesa 3-D graphics library
#include "depth.h"
#include "macros.h"
#include "mem.h"
-#include "pb.h"
#include "types.h"
#endif
}
-
-/**********************************************************************/
-/***** Misc *****/
-/**********************************************************************/
-
-/*
- * Return address of depth buffer value for given window coord.
- */
-GLvoid *
-_mesa_zbuffer_address(GLcontext *ctx, GLint x, GLint y)
-{
- if (ctx->Visual.DepthBits <= 16)
- return (GLushort *) ctx->DrawBuffer->DepthBuffer + ctx->DrawBuffer->Width * y + x;
- else
- return (GLuint *) ctx->DrawBuffer->DepthBuffer + ctx->DrawBuffer->Width * y + x;
-}
-
-
-#define Z_ADDRESS16( CTX, X, Y ) \
- ( ((GLushort *) (CTX)->DrawBuffer->DepthBuffer) \
- + (CTX)->DrawBuffer->Width * (Y) + (X) )
-
-#define Z_ADDRESS32( CTX, X, Y ) \
- ( ((GLuint *) (CTX)->DrawBuffer->DepthBuffer) \
- + (CTX)->DrawBuffer->Width * (Y) + (X) )
-
-
-
-/**********************************************************************/
-/***** Depth Testing Functions *****/
-/**********************************************************************/
-
-
-/*
- * Do depth test for an array of fragments. This is used both for
- * software and hardware Z buffers.
- * Input: zbuffer - array of z values in the zbuffer
- * z - array of fragment z values
- * Return: number of fragments which pass the test.
- */
-static GLuint
-depth_test_span16( GLcontext *ctx, GLuint n, GLint x, GLint y,
- GLushort zbuffer[], const GLdepth z[], GLubyte mask[] )
-{
- GLuint passed = 0;
-
- /* switch cases ordered from most frequent to less frequent */
- switch (ctx->Depth.Func) {
- case GL_LESS:
- if (ctx->Depth.Mask) {
- /* Update Z buffer */
- GLuint i;
- for (i=0; i<n; i++) {
- if (mask[i]) {
- if (z[i] < zbuffer[i]) {
- /* pass */
- zbuffer[i] = z[i];
- passed++;
- }
- else {
- /* fail */
- mask[i] = 0;
- }
- }
- }
- }
- else {
- /* Don't update Z buffer */
- GLuint i;
- for (i=0; i<n; i++) {
- if (mask[i]) {
- if (z[i] < zbuffer[i]) {
- /* pass */
- passed++;
- }
- else {
- mask[i] = 0;
- }
- }
- }
- }
- break;
- case GL_LEQUAL:
- if (ctx->Depth.Mask) {
- /* Update Z buffer */
- GLuint i;
- for (i=0;i<n;i++) {
- if (mask[i]) {
- if (z[i] <= zbuffer[i]) {
- zbuffer[i] = z[i];
- passed++;
- }
- else {
- mask[i] = 0;
- }
- }
- }
- }
- else {
- /* Don't update Z buffer */
- GLuint i;
- for (i=0;i<n;i++) {
- if (mask[i]) {
- if (z[i] <= zbuffer[i]) {
- /* pass */
- passed++;
- }
- else {
- mask[i] = 0;
- }
- }
- }
- }
- break;
- case GL_GEQUAL:
- if (ctx->Depth.Mask) {
- /* Update Z buffer */
- GLuint i;
- for (i=0;i<n;i++) {
- if (mask[i]) {
- if (z[i] >= zbuffer[i]) {
- zbuffer[i] = z[i];
- passed++;
- }
- else {
- mask[i] = 0;
- }
- }
- }
- }
- else {
- /* Don't update Z buffer */
- GLuint i;
- for (i=0;i<n;i++) {
- if (mask[i]) {
- if (z[i] >= zbuffer[i]) {
- /* pass */
- passed++;
- }
- else {
- mask[i] = 0;
- }
- }
- }
- }
- break;
- case GL_GREATER:
- if (ctx->Depth.Mask) {
- /* Update Z buffer */
- GLuint i;
- for (i=0;i<n;i++) {
- if (mask[i]) {
- if (z[i] > zbuffer[i]) {
- zbuffer[i] = z[i];
- passed++;
- }
- else {
- mask[i] = 0;
- }
- }
- }
- }
- else {
- /* Don't update Z buffer */
- GLuint i;
- for (i=0;i<n;i++) {
- if (mask[i]) {
- if (z[i] > zbuffer[i]) {
- /* pass */
- passed++;
- }
- else {
- mask[i] = 0;
- }
- }
- }
- }
- break;
- case GL_NOTEQUAL:
- if (ctx->Depth.Mask) {
- /* Update Z buffer */
- GLuint i;
- for (i=0;i<n;i++) {
- if (mask[i]) {
- if (z[i] != zbuffer[i]) {
- zbuffer[i] = z[i];
- passed++;
- }
- else {
- mask[i] = 0;
- }
- }
- }
- }
- else {
- /* Don't update Z buffer */
- GLuint i;
- for (i=0;i<n;i++) {
- if (mask[i]) {
- if (z[i] != zbuffer[i]) {
- /* pass */
- passed++;
- }
- else {
- mask[i] = 0;
- }
- }
- }
- }
- break;
- case GL_EQUAL:
- if (ctx->Depth.Mask) {
- /* Update Z buffer */
- GLuint i;
- for (i=0;i<n;i++) {
- if (mask[i]) {
- if (z[i] == zbuffer[i]) {
- zbuffer[i] = z[i];
- passed++;
- }
- else {
- mask[i] = 0;
- }
- }
- }
- }
- else {
- /* Don't update Z buffer */
- GLuint i;
- for (i=0;i<n;i++) {
- if (mask[i]) {
- if (z[i] == zbuffer[i]) {
- /* pass */
- passed++;
- }
- else {
- mask[i] = 0;
- }
- }
- }
- }
- break;
- case GL_ALWAYS:
- if (ctx->Depth.Mask) {
- /* Update Z buffer */
- GLuint i;
- for (i=0;i<n;i++) {
- if (mask[i]) {
- zbuffer[i] = z[i];
- passed++;
- }
- }
- }
- else {
- /* Don't update Z buffer or mask */
- passed = n;
- }
- break;
- case GL_NEVER:
- BZERO(mask, n * sizeof(GLubyte));
- break;
- default:
- gl_problem(ctx, "Bad depth func in depth_test_span16");
- }
-
- return passed;
-}
-
-
-static GLuint
-depth_test_span32( GLcontext *ctx, GLuint n, GLint x, GLint y,
- GLuint zbuffer[], const GLdepth z[], GLubyte mask[] )
-{
- GLuint passed = 0;
-
- /* switch cases ordered from most frequent to less frequent */
- switch (ctx->Depth.Func) {
- case GL_LESS:
- if (ctx->Depth.Mask) {
- /* Update Z buffer */
- GLuint i;
- for (i=0; i<n; i++) {
- if (mask[i]) {
- if (z[i] < zbuffer[i]) {
- /* pass */
- zbuffer[i] = z[i];
- passed++;
- }
- else {
- /* fail */
- mask[i] = 0;
- }
- }
- }
- }
- else {
- /* Don't update Z buffer */
- GLuint i;
- for (i=0; i<n; i++) {
- if (mask[i]) {
- if (z[i] < zbuffer[i]) {
- /* pass */
- passed++;
- }
- else {
- mask[i] = 0;
- }
- }
- }
- }
- break;
- case GL_LEQUAL:
- if (ctx->Depth.Mask) {
- /* Update Z buffer */
- GLuint i;
- for (i=0;i<n;i++) {
- if (mask[i]) {
- if (z[i] <= zbuffer[i]) {
- zbuffer[i] = z[i];
- passed++;
- }
- else {
- mask[i] = 0;
- }
- }
- }
- }
- else {
- /* Don't update Z buffer */
- GLuint i;
- for (i=0;i<n;i++) {
- if (mask[i]) {
- if (z[i] <= zbuffer[i]) {
- /* pass */
- passed++;
- }
- else {
- mask[i] = 0;
- }
- }
- }
- }
- break;
- case GL_GEQUAL:
- if (ctx->Depth.Mask) {
- /* Update Z buffer */
- GLuint i;
- for (i=0;i<n;i++) {
- if (mask[i]) {
- if (z[i] >= zbuffer[i]) {
- zbuffer[i] = z[i];
- passed++;
- }
- else {
- mask[i] = 0;
- }
- }
- }
- }
- else {
- /* Don't update Z buffer */
- GLuint i;
- for (i=0;i<n;i++) {
- if (mask[i]) {
- if (z[i] >= zbuffer[i]) {
- /* pass */
- passed++;
- }
- else {
- mask[i] = 0;
- }
- }
- }
- }
- break;
- case GL_GREATER:
- if (ctx->Depth.Mask) {
- /* Update Z buffer */
- GLuint i;
- for (i=0;i<n;i++) {
- if (mask[i]) {
- if (z[i] > zbuffer[i]) {
- zbuffer[i] = z[i];
- passed++;
- }
- else {
- mask[i] = 0;
- }
- }
- }
- }
- else {
- /* Don't update Z buffer */
- GLuint i;
- for (i=0;i<n;i++) {
- if (mask[i]) {
- if (z[i] > zbuffer[i]) {
- /* pass */
- passed++;
- }
- else {
- mask[i] = 0;
- }
- }
- }
- }
- break;
- case GL_NOTEQUAL:
- if (ctx->Depth.Mask) {
- /* Update Z buffer */
- GLuint i;
- for (i=0;i<n;i++) {
- if (mask[i]) {
- if (z[i] != zbuffer[i]) {
- zbuffer[i] = z[i];
- passed++;
- }
- else {
- mask[i] = 0;
- }
- }
- }
- }
- else {
- /* Don't update Z buffer */
- GLuint i;
- for (i=0;i<n;i++) {
- if (mask[i]) {
- if (z[i] != zbuffer[i]) {
- /* pass */
- passed++;
- }
- else {
- mask[i] = 0;
- }
- }
- }
- }
- break;
- case GL_EQUAL:
- if (ctx->Depth.Mask) {
- /* Update Z buffer */
- GLuint i;
- for (i=0;i<n;i++) {
- if (mask[i]) {
- if (z[i] == zbuffer[i]) {
- zbuffer[i] = z[i];
- passed++;
- }
- else {
- mask[i] = 0;
- }
- }
- }
- }
- else {
- /* Don't update Z buffer */
- GLuint i;
- for (i=0;i<n;i++) {
- if (mask[i]) {
- if (z[i] == zbuffer[i]) {
- /* pass */
- passed++;
- }
- else {
- mask[i] = 0;
- }
- }
- }
- }
- break;
- case GL_ALWAYS:
- if (ctx->Depth.Mask) {
- /* Update Z buffer */
- GLuint i;
- for (i=0;i<n;i++) {
- if (mask[i]) {
- zbuffer[i] = z[i];
- passed++;
- }
- }
- }
- else {
- /* Don't update Z buffer or mask */
- passed = n;
- }
- break;
- case GL_NEVER:
- BZERO(mask, n * sizeof(GLubyte));
- break;
- default:
- gl_problem(ctx, "Bad depth func in depth_test_span32");
- }
-
- return passed;
-}
-
-
-
-/*
- * Apply depth test to span of fragments. Hardware or software z buffer.
- */
-GLuint
-_mesa_depth_test_span( GLcontext *ctx, GLuint n, GLint x, GLint y,
- const GLdepth z[], GLubyte mask[] )
-{
- if (ctx->Driver.ReadDepthSpan) {
- /* hardware-based depth buffer */
- GLdepth zbuffer[MAX_WIDTH];
- GLuint passed;
- (*ctx->Driver.ReadDepthSpan)(ctx, n, x, y, zbuffer);
- passed = depth_test_span32(ctx, n, x, y, zbuffer, z, mask);
- assert(ctx->Driver.WriteDepthSpan);
- (*ctx->Driver.WriteDepthSpan)(ctx, n, x, y, zbuffer, mask);
- return passed;
- }
- else {
- /* software depth buffer */
- if (ctx->Visual.DepthBits <= 16) {
- GLushort *zptr = (GLushort *) Z_ADDRESS16(ctx, x, y);
- GLuint passed = depth_test_span16(ctx, n, x, y, zptr, z, mask);
- return passed;
- }
- else {
- GLuint *zptr = (GLuint *) Z_ADDRESS32(ctx, x, y);
- GLuint passed = depth_test_span32(ctx, n, x, y, zptr, z, mask);
- return passed;
- }
- }
-}
-
-
-
-
-/*
- * Do depth testing for an array of fragments using software Z buffer.
- */
-static void
-software_depth_test_pixels16( GLcontext *ctx, GLuint n,
- const GLint x[], const GLint y[],
- const GLdepth z[], GLubyte mask[] )
-{
- /* switch cases ordered from most frequent to less frequent */
- switch (ctx->Depth.Func) {
- case GL_LESS:
- if (ctx->Depth.Mask) {
- /* Update Z buffer */
- GLuint i;
- for (i=0; i<n; i++) {
- if (mask[i]) {
- GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
- if (z[i] < *zptr) {
- /* pass */
- *zptr = z[i];
- }
- else {
- /* fail */
- mask[i] = 0;
- }
- }
- }
- }
- else {
- /* Don't update Z buffer */
- GLuint i;
- for (i=0; i<n; i++) {
- if (mask[i]) {
- GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
- if (z[i] < *zptr) {
- /* pass */
- }
- else {
- /* fail */
- mask[i] = 0;
- }
- }
- }
- }
- break;
- case GL_LEQUAL:
- if (ctx->Depth.Mask) {
- /* Update Z buffer */
- GLuint i;
- for (i=0; i<n; i++) {
- if (mask[i]) {
- GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
- if (z[i] <= *zptr) {
- /* pass */
- *zptr = z[i];
- }
- else {
- /* fail */
- mask[i] = 0;
- }
- }
- }
- }
- else {
- /* Don't update Z buffer */
- GLuint i;
- for (i=0; i<n; i++) {
- if (mask[i]) {
- GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
- if (z[i] <= *zptr) {
- /* pass */
- }
- else {
- /* fail */
- mask[i] = 0;
- }
- }
- }
- }
- break;
- case GL_GEQUAL:
- if (ctx->Depth.Mask) {
- /* Update Z buffer */
- GLuint i;
- for (i=0; i<n; i++) {
- if (mask[i]) {
- GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
- if (z[i] >= *zptr) {
- /* pass */
- *zptr = z[i];
- }
- else {
- /* fail */
- mask[i] = 0;
- }
- }
- }
- }
- else {
- /* Don't update Z buffer */
- GLuint i;
- for (i=0; i<n; i++) {
- if (mask[i]) {
- GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
- if (z[i] >= *zptr) {
- /* pass */
- }
- else {
- /* fail */
- mask[i] = 0;
- }
- }
- }
- }
- break;
- case GL_GREATER:
- if (ctx->Depth.Mask) {
- /* Update Z buffer */
- GLuint i;
- for (i=0; i<n; i++) {
- if (mask[i]) {
- GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
- if (z[i] > *zptr) {
- /* pass */
- *zptr = z[i];
- }
- else {
- /* fail */
- mask[i] = 0;
- }
- }
- }
- }
- else {
- /* Don't update Z buffer */
- GLuint i;
- for (i=0; i<n; i++) {
- if (mask[i]) {
- GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
- if (z[i] > *zptr) {
- /* pass */
- }
- else {
- /* fail */
- mask[i] = 0;
- }
- }
- }
- }
- break;
- case GL_NOTEQUAL:
- if (ctx->Depth.Mask) {
- /* Update Z buffer */
- GLuint i;
- for (i=0; i<n; i++) {
- if (mask[i]) {
- GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
- if (z[i] != *zptr) {
- /* pass */
- *zptr = z[i];
- }
- else {
- /* fail */
- mask[i] = 0;
- }
- }
- }
- }
- else {
- /* Don't update Z buffer */
- GLuint i;
- for (i=0; i<n; i++) {
- if (mask[i]) {
- GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
- if (z[i] != *zptr) {
- /* pass */
- }
- else {
- /* fail */
- mask[i] = 0;
- }
- }
- }
- }
- break;
- case GL_EQUAL:
- if (ctx->Depth.Mask) {
- /* Update Z buffer */
- GLuint i;
- for (i=0; i<n; i++) {
- if (mask[i]) {
- GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
- if (z[i] == *zptr) {
- /* pass */
- *zptr = z[i];
- }
- else {
- /* fail */
- mask[i] = 0;
- }
- }
- }
- }
- else {
- /* Don't update Z buffer */
- GLuint i;
- for (i=0; i<n; i++) {
- if (mask[i]) {
- GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
- if (z[i] == *zptr) {
- /* pass */
- }
- else {
- /* fail */
- mask[i] = 0;
- }
- }
- }
- }
- break;
- case GL_ALWAYS:
- if (ctx->Depth.Mask) {
- /* Update Z buffer */
- GLuint i;
- for (i=0; i<n; i++) {
- if (mask[i]) {
- GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
- *zptr = z[i];
- }
- }
- }
- else {
- /* Don't update Z buffer or mask */
- }
- break;
- case GL_NEVER:
- /* depth test never passes */
- BZERO(mask, n * sizeof(GLubyte));
- break;
- default:
- gl_problem(ctx, "Bad depth func in software_depth_test_pixels");
- }
-}
-
-
-
-/*
- * Do depth testing for an array of fragments using software Z buffer.
- */
-static void
-software_depth_test_pixels32( GLcontext *ctx, GLuint n,
- const GLint x[], const GLint y[],
- const GLdepth z[], GLubyte mask[] )
-{
- /* switch cases ordered from most frequent to less frequent */
- switch (ctx->Depth.Func) {
- case GL_LESS:
- if (ctx->Depth.Mask) {
- /* Update Z buffer */
- GLuint i;
- for (i=0; i<n; i++) {
- if (mask[i]) {
- GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
- if (z[i] < *zptr) {
- /* pass */
- *zptr = z[i];
- }
- else {
- /* fail */
- mask[i] = 0;
- }
- }
- }
- }
- else {
- /* Don't update Z buffer */
- GLuint i;
- for (i=0; i<n; i++) {
- if (mask[i]) {
- GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
- if (z[i] < *zptr) {
- /* pass */
- }
- else {
- /* fail */
- mask[i] = 0;
- }
- }
- }
- }
- break;
- case GL_LEQUAL:
- if (ctx->Depth.Mask) {
- /* Update Z buffer */
- GLuint i;
- for (i=0; i<n; i++) {
- if (mask[i]) {
- GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
- if (z[i] <= *zptr) {
- /* pass */
- *zptr = z[i];
- }
- else {
- /* fail */
- mask[i] = 0;
- }
- }
- }
- }
- else {
- /* Don't update Z buffer */
- GLuint i;
- for (i=0; i<n; i++) {
- if (mask[i]) {
- GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
- if (z[i] <= *zptr) {
- /* pass */
- }
- else {
- /* fail */
- mask[i] = 0;
- }
- }
- }
- }
- break;
- case GL_GEQUAL:
- if (ctx->Depth.Mask) {
- /* Update Z buffer */
- GLuint i;
- for (i=0; i<n; i++) {
- if (mask[i]) {
- GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
- if (z[i] >= *zptr) {
- /* pass */
- *zptr = z[i];
- }
- else {
- /* fail */
- mask[i] = 0;
- }
- }
- }
- }
- else {
- /* Don't update Z buffer */
- GLuint i;
- for (i=0; i<n; i++) {
- if (mask[i]) {
- GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
- if (z[i] >= *zptr) {
- /* pass */
- }
- else {
- /* fail */
- mask[i] = 0;
- }
- }
- }
- }
- break;
- case GL_GREATER:
- if (ctx->Depth.Mask) {
- /* Update Z buffer */
- GLuint i;
- for (i=0; i<n; i++) {
- if (mask[i]) {
- GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
- if (z[i] > *zptr) {
- /* pass */
- *zptr = z[i];
- }
- else {
- /* fail */
- mask[i] = 0;
- }
- }
- }
- }
- else {
- /* Don't update Z buffer */
- GLuint i;
- for (i=0; i<n; i++) {
- if (mask[i]) {
- GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
- if (z[i] > *zptr) {
- /* pass */
- }
- else {
- /* fail */
- mask[i] = 0;
- }
- }
- }
- }
- break;
- case GL_NOTEQUAL:
- if (ctx->Depth.Mask) {
- /* Update Z buffer */
- GLuint i;
- for (i=0; i<n; i++) {
- if (mask[i]) {
- GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
- if (z[i] != *zptr) {
- /* pass */
- *zptr = z[i];
- }
- else {
- /* fail */
- mask[i] = 0;
- }
- }
- }
- }
- else {
- /* Don't update Z buffer */
- GLuint i;
- for (i=0; i<n; i++) {
- if (mask[i]) {
- GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
- if (z[i] != *zptr) {
- /* pass */
- }
- else {
- /* fail */
- mask[i] = 0;
- }
- }
- }
- }
- break;
- case GL_EQUAL:
- if (ctx->Depth.Mask) {
- /* Update Z buffer */
- GLuint i;
- for (i=0; i<n; i++) {
- if (mask[i]) {
- GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
- if (z[i] == *zptr) {
- /* pass */
- *zptr = z[i];
- }
- else {
- /* fail */
- mask[i] = 0;
- }
- }
- }
- }
- else {
- /* Don't update Z buffer */
- GLuint i;
- for (i=0; i<n; i++) {
- if (mask[i]) {
- GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
- if (z[i] == *zptr) {
- /* pass */
- }
- else {
- /* fail */
- mask[i] = 0;
- }
- }
- }
- }
- break;
- case GL_ALWAYS:
- if (ctx->Depth.Mask) {
- /* Update Z buffer */
- GLuint i;
- for (i=0; i<n; i++) {
- if (mask[i]) {
- GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
- *zptr = z[i];
- }
- }
- }
- else {
- /* Don't update Z buffer or mask */
- }
- break;
- case GL_NEVER:
- /* depth test never passes */
- BZERO(mask, n * sizeof(GLubyte));
- break;
- default:
- gl_problem(ctx, "Bad depth func in software_depth_test_pixels");
- }
-}
-
-
-
-/*
- * Do depth testing for an array of pixels using hardware Z buffer.
- * Input/output: zbuffer - array of depth values from Z buffer
- * Input: z - array of fragment z values.
- */
-static void
-hardware_depth_test_pixels( GLcontext *ctx, GLuint n, GLdepth zbuffer[],
- const GLdepth z[], GLubyte mask[] )
-{
- /* switch cases ordered from most frequent to less frequent */
- switch (ctx->Depth.Func) {
- case GL_LESS:
- if (ctx->Depth.Mask) {
- /* Update Z buffer */
- GLuint i;
- for (i=0; i<n; i++) {
- if (mask[i]) {
- if (z[i] < zbuffer[i]) {
- /* pass */
- zbuffer[i] = z[i];
- }
- else {
- /* fail */
- mask[i] = 0;
- }
- }
- }
- }
- else {
- /* Don't update Z buffer */
- GLuint i;
- for (i=0; i<n; i++) {
- if (mask[i]) {
- if (z[i] < zbuffer[i]) {
- /* pass */
- }
- else {
- /* fail */
- mask[i] = 0;
- }
- }
- }
- }
- break;
- case GL_LEQUAL:
- if (ctx->Depth.Mask) {
- /* Update Z buffer */
- GLuint i;
- for (i=0; i<n; i++) {
- if (mask[i]) {
- if (z[i] <= zbuffer[i]) {
- /* pass */
- zbuffer[i] = z[i];
- }
- else {
- /* fail */
- mask[i] = 0;
- }
- }
- }
- }
- else {
- /* Don't update Z buffer */
- GLuint i;
- for (i=0; i<n; i++) {
- if (mask[i]) {
- if (z[i] <= zbuffer[i]) {
- /* pass */
- }
- else {
- /* fail */
- mask[i] = 0;
- }
- }
- }
- }
- break;
- case GL_GEQUAL:
- if (ctx->Depth.Mask) {
- /* Update Z buffer */
- GLuint i;
- for (i=0; i<n; i++) {
- if (mask[i]) {
- if (z[i] >= zbuffer[i]) {
- /* pass */
- zbuffer[i] = z[i];
- }
- else {
- /* fail */
- mask[i] = 0;
- }
- }
- }
- }
- else {
- /* Don't update Z buffer */
- GLuint i;
- for (i=0; i<n; i++) {
- if (mask[i]) {
- if (z[i] >= zbuffer[i]) {
- /* pass */
- }
- else {
- /* fail */
- mask[i] = 0;
- }
- }
- }
- }
- break;
- case GL_GREATER:
- if (ctx->Depth.Mask) {
- /* Update Z buffer */
- GLuint i;
- for (i=0; i<n; i++) {
- if (mask[i]) {
- if (z[i] > zbuffer[i]) {
- /* pass */
- zbuffer[i] = z[i];
- }
- else {
- /* fail */
- mask[i] = 0;
- }
- }
- }
- }
- else {
- /* Don't update Z buffer */
- GLuint i;
- for (i=0; i<n; i++) {
- if (mask[i]) {
- if (z[i] > zbuffer[i]) {
- /* pass */
- }
- else {
- /* fail */
- mask[i] = 0;
- }
- }
- }
- }
- break;
- case GL_NOTEQUAL:
- if (ctx->Depth.Mask) {
- /* Update Z buffer */
- GLuint i;
- for (i=0; i<n; i++) {
- if (mask[i]) {
- if (z[i] != zbuffer[i]) {
- /* pass */
- zbuffer[i] = z[i];
- }
- else {
- /* fail */
- mask[i] = 0;
- }
- }
- }
- }
- else {
- /* Don't update Z buffer */
- GLuint i;
- for (i=0; i<n; i++) {
- if (mask[i]) {
- if (z[i] != zbuffer[i]) {
- /* pass */
- }
- else {
- /* fail */
- mask[i] = 0;
- }
- }
- }
- }
- break;
- case GL_EQUAL:
- if (ctx->Depth.Mask) {
- /* Update Z buffer */
- GLuint i;
- for (i=0; i<n; i++) {
- if (mask[i]) {
- if (z[i] == zbuffer[i]) {
- /* pass */
- zbuffer[i] = z[i];
- }
- else {
- /* fail */
- mask[i] = 0;
- }
- }
- }
- }
- else {
- /* Don't update Z buffer */
- GLuint i;
- for (i=0; i<n; i++) {
- if (mask[i]) {
- if (z[i] == zbuffer[i]) {
- /* pass */
- }
- else {
- /* fail */
- mask[i] = 0;
- }
- }
- }
- }
- break;
- case GL_ALWAYS:
- if (ctx->Depth.Mask) {
- /* Update Z buffer */
- GLuint i;
- for (i=0; i<n; i++) {
- if (mask[i]) {
- zbuffer[i] = z[i];
- }
- }
- }
- else {
- /* Don't update Z buffer or mask */
- }
- break;
- case GL_NEVER:
- /* depth test never passes */
- BZERO(mask, n * sizeof(GLubyte));
- break;
- default:
- gl_problem(ctx, "Bad depth func in hardware_depth_test_pixels");
- }
-}
-
-
-
-void
-_mesa_depth_test_pixels( GLcontext *ctx,
- GLuint n, const GLint x[], const GLint y[],
- const GLdepth z[], GLubyte mask[] )
-{
- if (ctx->Driver.ReadDepthPixels) {
- /* read depth values from hardware Z buffer */
- GLdepth zbuffer[PB_SIZE];
- (*ctx->Driver.ReadDepthPixels)(ctx, n, x, y, zbuffer);
-
- hardware_depth_test_pixels( ctx, n, zbuffer, z, mask );
-
- /* update hardware Z buffer with new values */
- assert(ctx->Driver.WriteDepthPixels);
- (*ctx->Driver.WriteDepthPixels)(ctx, n, x, y, zbuffer, mask );
- }
- else {
- /* software depth testing */
- if (ctx->Visual.DepthBits <= 16)
- software_depth_test_pixels16(ctx, n, x, y, z, mask);
- else
- software_depth_test_pixels32(ctx, n, x, y, z, mask);
- }
-}
-
-
-
-
-
-/**********************************************************************/
-/***** Read Depth Buffer *****/
-/**********************************************************************/
-
-
-/*
- * Read a span of depth values from the depth buffer.
- * This function does clipping before calling the device driver function.
- */
-void
-_mesa_read_depth_span( GLcontext *ctx,
- GLint n, GLint x, GLint y, GLdepth depth[] )
-{
- if (y < 0 || y >= ctx->DrawBuffer->Height ||
- x + (GLint) n <= 0 || x >= ctx->DrawBuffer->Width) {
- /* span is completely outside framebuffer */
- GLint i;
- for (i = 0; i < n; i++)
- depth[i] = 0;
- return;
- }
-
- if (x < 0) {
- GLint dx = -x;
- GLint i;
- for (i = 0; i < dx; i++)
- depth[i] = 0;
- x = 0;
- n -= dx;
- depth += dx;
- }
- if (x + n > ctx->DrawBuffer->Width) {
- GLint dx = x + n - ctx->DrawBuffer->Width;
- GLint i;
- for (i = 0; i < dx; i++)
- depth[n - i - 1] = 0;
- n -= dx;
- }
- if (n <= 0) {
- return;
- }
-
- if (ctx->DrawBuffer->DepthBuffer) {
- /* read from software depth buffer */
- if (ctx->Visual.DepthBits <= 16) {
- const GLushort *zptr = Z_ADDRESS16( ctx, x, y );
- GLuint i;
- for (i = 0; i < n; i++) {
- depth[i] = zptr[i];
- }
- }
- else {
- const GLuint *zptr = Z_ADDRESS32( ctx, x, y );
- GLuint i;
- for (i = 0; i < n; i++) {
- depth[i] = zptr[i];
- }
- }
- }
- else if (ctx->Driver.ReadDepthSpan) {
- /* read from hardware depth buffer */
- (*ctx->Driver.ReadDepthSpan)( ctx, n, x, y, depth );
- }
- else {
- /* no depth buffer */
- BZERO(depth, n * sizeof(GLfloat));
- }
-
-}
-
-
-
-
-/*
- * Return a span of depth values from the depth buffer as floats in [0,1].
- * This is used for both hardware and software depth buffers.
- * Input: n - how many pixels
- * x,y - location of first pixel
- * Output: depth - the array of depth values
- */
-void
-_mesa_read_depth_span_float( GLcontext *ctx,
- GLint n, GLint x, GLint y, GLfloat depth[] )
-{
- const GLfloat scale = 1.0F / ctx->Visual.DepthMaxF;
-
- if (y < 0 || y >= ctx->DrawBuffer->Height ||
- x + (GLint) n <= 0 || x >= ctx->DrawBuffer->Width) {
- /* span is completely outside framebuffer */
- GLint i;
- for (i = 0; i < n; i++)
- depth[i] = 0.0F;
- return;
- }
-
- if (x < 0) {
- GLint dx = -x;
- GLint i;
- for (i = 0; i < dx; i++)
- depth[i] = 0.0F;
- n -= dx;
- x = 0;
- }
- if (x + n > ctx->DrawBuffer->Width) {
- GLint dx = x + n - ctx->DrawBuffer->Width;
- GLint i;
- for (i = 0; i < dx; i++)
- depth[n - i - 1] = 0.0F;
- n -= dx;
- }
- if (n <= 0) {
- return;
- }
-
- if (ctx->DrawBuffer->DepthBuffer) {
- /* read from software depth buffer */
- if (ctx->Visual.DepthBits <= 16) {
- const GLushort *zptr = Z_ADDRESS16( ctx, x, y );
- GLuint i;
- for (i = 0; i < n; i++) {
- depth[i] = (GLfloat) zptr[i] * scale;
- }
- }
- else {
- const GLuint *zptr = Z_ADDRESS32( ctx, x, y );
- GLuint i;
- for (i = 0; i < n; i++) {
- depth[i] = (GLfloat) zptr[i] * scale;
- }
- }
- }
- else if (ctx->Driver.ReadDepthSpan) {
- /* read from hardware depth buffer */
- GLdepth d[MAX_WIDTH];
- GLuint i;
- assert(n <= MAX_WIDTH);
- (*ctx->Driver.ReadDepthSpan)( ctx, n, x, y, d );
- for (i = 0; i < n; i++) {
- depth[i] = d[i] * scale;
- }
- }
- else {
- /* no depth buffer */
- BZERO(depth, n * sizeof(GLfloat));
- }
-}
-
-
-
-/**********************************************************************/
-/***** Allocate and Clear Depth Buffer *****/
-/**********************************************************************/
-
-
-
-/*
- * Allocate a new depth buffer. If there's already a depth buffer allocated
- * it will be free()'d. The new depth buffer will be uniniitalized.
- * This function is only called through Driver.alloc_depth_buffer.
- */
-void
-_mesa_alloc_depth_buffer( GLcontext *ctx )
-{
- /* deallocate current depth buffer if present */
- if (ctx->DrawBuffer->UseSoftwareDepthBuffer) {
- GLint bytesPerValue;
-
- if (ctx->DrawBuffer->DepthBuffer) {
- FREE(ctx->DrawBuffer->DepthBuffer);
- ctx->DrawBuffer->DepthBuffer = NULL;
- }
-
- /* allocate new depth buffer, but don't initialize it */
- if (ctx->Visual.DepthBits <= 16)
- bytesPerValue = sizeof(GLushort);
- else
- bytesPerValue = sizeof(GLuint);
-
- ctx->DrawBuffer->DepthBuffer = MALLOC( ctx->DrawBuffer->Width
- * ctx->DrawBuffer->Height
- * bytesPerValue );
-
- if (!ctx->DrawBuffer->DepthBuffer) {
- /* out of memory */
- ctx->Depth.Test = GL_FALSE;
- ctx->NewState |= _NEW_DEPTH;
- gl_error( ctx, GL_OUT_OF_MEMORY, "Couldn't allocate depth buffer" );
- }
- }
-}
-
-
-
-
-/*
- * Clear the depth buffer. If the depth buffer doesn't exist yet we'll
- * allocate it now.
- * This function is only called through Driver.clear_depth_buffer.
- */
-void
-_mesa_clear_depth_buffer( GLcontext *ctx )
-{
- if (ctx->Visual.DepthBits == 0
- || !ctx->DrawBuffer->DepthBuffer
- || !ctx->Depth.Mask) {
- /* no depth buffer, or writing to it is disabled */
- return;
- }
-
- /* The loops in this function have been written so the IRIX 5.3
- * C compiler can unroll them. Hopefully other compilers can too!
- */
-
- if (ctx->Scissor.Enabled) {
- /* only clear scissor region */
- if (ctx->Visual.DepthBits <= 16) {
- const GLushort clearValue = (GLushort) (ctx->Depth.Clear * ctx->Visual.DepthMax);
- const GLint rows = ctx->DrawBuffer->Ymax - ctx->DrawBuffer->Ymin;
- const GLint width = ctx->DrawBuffer->Width;
- GLushort *dRow = (GLushort *) ctx->DrawBuffer->DepthBuffer
- + ctx->DrawBuffer->Ymin * width + ctx->DrawBuffer->Xmin;
- GLint i, j;
- for (i = 0; i < rows; i++) {
- for (j = 0; j < width; j++) {
- dRow[j] = clearValue;
- }
- dRow += width;
- }
- }
- else {
- const GLuint clearValue = (GLuint) (ctx->Depth.Clear * ctx->Visual.DepthMax);
- const GLint rows = ctx->DrawBuffer->Ymax - ctx->DrawBuffer->Ymin;
- const GLint width = ctx->DrawBuffer->Width;
- GLuint *dRow = (GLuint *) ctx->DrawBuffer->DepthBuffer
- + ctx->DrawBuffer->Ymin * width + ctx->DrawBuffer->Xmin;
- GLint i, j;
- for (i = 0; i < rows; i++) {
- for (j = 0; j < width; j++) {
- dRow[j] = clearValue;
- }
- dRow += width;
- }
- }
- }
- else {
- /* clear whole buffer */
- if (ctx->Visual.DepthBits <= 16) {
- const GLushort clearValue = (GLushort) (ctx->Depth.Clear * ctx->Visual.DepthMax);
- if ((clearValue & 0xff) == (clearValue >> 8)) {
- if (clearValue == 0) {
- BZERO(ctx->DrawBuffer->DepthBuffer,
- 2*ctx->DrawBuffer->Width*ctx->DrawBuffer->Height);
- }
- else {
- /* lower and upper bytes of clear_value are same, use MEMSET */
- MEMSET( ctx->DrawBuffer->DepthBuffer, clearValue & 0xff,
- 2 * ctx->DrawBuffer->Width * ctx->DrawBuffer->Height);
- }
- }
- else {
- GLushort *d = (GLushort *) ctx->DrawBuffer->DepthBuffer;
- GLint n = ctx->DrawBuffer->Width * ctx->DrawBuffer->Height;
- while (n >= 16) {
- d[0] = clearValue; d[1] = clearValue;
- d[2] = clearValue; d[3] = clearValue;
- d[4] = clearValue; d[5] = clearValue;
- d[6] = clearValue; d[7] = clearValue;
- d[8] = clearValue; d[9] = clearValue;
- d[10] = clearValue; d[11] = clearValue;
- d[12] = clearValue; d[13] = clearValue;
- d[14] = clearValue; d[15] = clearValue;
- d += 16;
- n -= 16;
- }
- while (n > 0) {
- *d++ = clearValue;
- n--;
- }
- }
- }
- else {
- /* >16 bit depth buffer */
- const GLuint clearValue = (GLuint) (ctx->Depth.Clear * ctx->Visual.DepthMax);
- if (clearValue == 0) {
- BZERO(ctx->DrawBuffer->DepthBuffer,
- ctx->DrawBuffer->Width*ctx->DrawBuffer->Height*sizeof(GLuint));
- }
- else {
- GLint n = ctx->DrawBuffer->Width * ctx->DrawBuffer->Height;
- GLuint *d = (GLuint *) ctx->DrawBuffer->DepthBuffer;
- while (n >= 16) {
- d[0] = clearValue; d[1] = clearValue;
- d[2] = clearValue; d[3] = clearValue;
- d[4] = clearValue; d[5] = clearValue;
- d[6] = clearValue; d[7] = clearValue;
- d[8] = clearValue; d[9] = clearValue;
- d[10] = clearValue; d[11] = clearValue;
- d[12] = clearValue; d[13] = clearValue;
- d[14] = clearValue; d[15] = clearValue;
- d += 16;
- n -= 16;
- }
- while (n > 0) {
- *d++ = clearValue;
- n--;
- }
- }
- }
- }
-}
-/* $Id: depth.h,v 1.8 2000/04/11 20:42:22 brianp Exp $ */
+/* $Id: depth.h,v 1.9 2000/10/31 18:09:44 keithw Exp $ */
/*
* Mesa 3-D graphics library
-/*
- * Internal functions
- */
-
-extern GLvoid *
-_mesa_zbuffer_address(GLcontext *ctx, GLint x, GLint y);
-
-
-extern GLuint
-_mesa_depth_test_span( GLcontext *ctx, GLuint n, GLint x, GLint y,
- const GLdepth z[], GLubyte mask[] );
-
-extern void
-_mesa_depth_test_pixels( GLcontext *ctx,
- GLuint n, const GLint x[], const GLint y[],
- const GLdepth z[], GLubyte mask[] );
-
-
-extern void
-_mesa_read_depth_span( GLcontext *ctx,
- GLint n, GLint x, GLint y, GLdepth depth[] );
-
-
-extern void
-_mesa_read_depth_span_float( GLcontext *ctx, GLint n, GLint x, GLint y,
- GLfloat depth[] );
-
-
-extern void
-_mesa_alloc_depth_buffer( GLcontext* ctx );
-
-
-extern void
-_mesa_clear_depth_buffer( GLcontext* ctx );
-
-
#endif
-/* $Id: drawpix.c,v 1.43 2000/10/30 16:32:43 brianp Exp $ */
+/* $Id: drawpix.c,v 1.44 2000/10/31 18:09:44 keithw Exp $ */
/*
* Mesa 3-D graphics library
#include "glheader.h"
#include "colormac.h"
#include "context.h"
-#include "convolve.h"
-#include "drawpix.h"
#include "feedback.h"
-#include "image.h"
#include "macros.h"
#include "mem.h"
#include "mmath.h"
-#include "pixel.h"
-#include "pixeltex.h"
-#include "span.h"
#include "state.h"
-#include "stencil.h"
-#include "texture.h"
#include "types.h"
-#include "zoom.h"
+#include "swrast/swrast.h"
#endif
-/*
- * Given the dest position, size and skipPixels and skipRows values
- * for a glDrawPixels command, perform clipping of the image bounds
- * so the result lies withing the context's buffer bounds.
- * Return: GL_TRUE if image is ready for drawing
- * GL_FALSE if image was completely clipped away (draw nothing)
- */
-GLboolean
-_mesa_clip_pixelrect(const GLcontext *ctx,
- GLint *destX, GLint *destY,
- GLsizei *width, GLsizei *height,
- GLint *skipPixels, GLint *skipRows)
-{
- const GLframebuffer *buffer = ctx->DrawBuffer;
-
- /* left clipping */
- if (*destX < buffer->Xmin) {
- *skipPixels += (buffer->Xmin - *destX);
- *width -= (buffer->Xmin - *destX);
- *destX = buffer->Xmin;
- }
- /* right clipping */
- if (*destX + *width > buffer->Xmax)
- *width -= (*destX + *width - buffer->Xmax);
-
- if (*width <= 0)
- return GL_FALSE;
-
- /* bottom clipping */
- if (*destY < buffer->Ymin) {
- *skipRows += (buffer->Ymin - *destY);
- *height -= (buffer->Ymin - *destY);
- *destY = buffer->Ymin;
- }
- /* top clipping */
- if (*destY + *height > buffer->Ymax)
- *height -= (*destY + *height - buffer->Ymax);
-
- if (*height <= 0)
- return GL_TRUE;
-
- return GL_TRUE;
-}
-
-
-
-/*
- * Try to do a fast and simple RGB(a) glDrawPixels.
- * Return: GL_TRUE if success, GL_FALSE if slow path must be used instead
- */
-static GLboolean
-fast_draw_pixels(GLcontext *ctx, GLint x, GLint y,
- GLsizei width, GLsizei height,
- GLenum format, GLenum type, const GLvoid *pixels)
-{
- const struct gl_pixelstore_attrib *unpack = &ctx->Unpack;
- GLchan rgb[MAX_WIDTH][3];
- GLchan rgba[MAX_WIDTH][4];
-
- ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH_WITH_RETVAL(ctx, "glDrawPixels",
- GL_FALSE);
-
-
- if (!ctx->Current.RasterPosValid) {
- return GL_TRUE; /* no-op */
- }
-
- if ((ctx->RasterMask&(~(SCISSOR_BIT|WINCLIP_BIT)))==0
- && ctx->Texture.ReallyEnabled == 0
- && unpack->Alignment == 1
- && !unpack->SwapBytes
- && !unpack->LsbFirst) {
-
- GLint destX = x;
- GLint destY = y;
- GLint drawWidth = width; /* actual width drawn */
- GLint drawHeight = height; /* actual height drawn */
- GLint skipPixels = unpack->SkipPixels;
- GLint skipRows = unpack->SkipRows;
- GLint rowLength;
- GLdepth zSpan[MAX_WIDTH]; /* only used when zooming */
- GLint zoomY0 = 0;
-
- if (unpack->RowLength > 0)
- rowLength = unpack->RowLength;
- else
- rowLength = width;
-
- /* If we're not using pixel zoom then do all clipping calculations
- * now. Otherwise, we'll let the gl_write_zoomed_*_span() functions
- * handle the clipping.
- */
- if (ctx->Pixel.ZoomX==1.0F && ctx->Pixel.ZoomY==1.0F) {
- /* horizontal clipping */
- if (destX < ctx->DrawBuffer->Xmin) {
- skipPixels += (ctx->DrawBuffer->Xmin - destX);
- drawWidth -= (ctx->DrawBuffer->Xmin - destX);
- destX = ctx->DrawBuffer->Xmin;
- }
- if (destX + drawWidth > ctx->DrawBuffer->Xmax)
- drawWidth -= (destX + drawWidth - ctx->DrawBuffer->Xmax);
- if (drawWidth <= 0)
- return GL_TRUE;
-
- /* vertical clipping */
- if (destY < ctx->DrawBuffer->Ymin) {
- skipRows += (ctx->DrawBuffer->Ymin - destY);
- drawHeight -= (ctx->DrawBuffer->Ymin - destY);
- destY = ctx->DrawBuffer->Ymin;
- }
- if (destY + drawHeight > ctx->DrawBuffer->Ymax)
- drawHeight -= (destY + drawHeight - ctx->DrawBuffer->Ymax);
- if (drawHeight <= 0)
- return GL_TRUE;
- }
- else if (ctx->Pixel.ZoomX==1.0F && ctx->Pixel.ZoomY==-1.0F) {
- /* upside-down image */
- /* horizontal clipping */
- if (destX < ctx->DrawBuffer->Xmin) {
- skipPixels += (ctx->DrawBuffer->Xmin - destX);
- drawWidth -= (ctx->DrawBuffer->Xmin - destX);
- destX = ctx->DrawBuffer->Xmin;
- }
- if (destX + drawWidth > ctx->DrawBuffer->Xmax)
- drawWidth -= (destX + drawWidth - ctx->DrawBuffer->Xmax);
- if (drawWidth <= 0)
- return GL_TRUE;
-
- /* vertical clipping */
- if (destY > ctx->DrawBuffer->Ymax) {
- skipRows += (destY - ctx->DrawBuffer->Ymax);
- drawHeight -= (destY - ctx->DrawBuffer->Ymax);
- destY = ctx->DrawBuffer->Ymax;
- }
- if (destY - drawHeight < ctx->DrawBuffer->Ymin)
- drawHeight -= (ctx->DrawBuffer->Ymin - (destY - drawHeight));
- if (drawHeight <= 0)
- return GL_TRUE;
- }
- else {
- /* setup array of fragment Z value to pass to zoom function */
- GLdepth z = (GLdepth) (ctx->Current.RasterPos[2] * ctx->Visual.DepthMaxF);
- GLint i;
- ASSERT(drawWidth < MAX_WIDTH);
- for (i=0; i<drawWidth; i++)
- zSpan[i] = z;
-
- /* save Y value of first row */
- zoomY0 = (GLint) (ctx->Current.RasterPos[1] + 0.5F);
- }
-
-
- /*
- * Ready to draw!
- * The window region at (destX, destY) of size (drawWidth, drawHeight)
- * will be written to.
- * We'll take pixel data from buffer pointed to by "pixels" but we'll
- * skip "skipRows" rows and skip "skipPixels" pixels/row.
- */
-
- if (format == GL_RGBA && type == CHAN_TYPE
- && ctx->ImageTransferState==0) {
- if (ctx->Visual.RGBAflag) {
- GLchan *src = (GLchan *) pixels
- + (skipRows * rowLength + skipPixels) * 4;
- if (ctx->Pixel.ZoomX==1.0F && ctx->Pixel.ZoomY==1.0F) {
- /* no zooming */
- GLint row;
- for (row=0; row<drawHeight; row++) {
- (*ctx->Driver.WriteRGBASpan)(ctx, drawWidth, destX, destY,
- (void *) src, NULL);
- src += rowLength * 4;
- destY++;
- }
- }
- else if (ctx->Pixel.ZoomX==1.0F && ctx->Pixel.ZoomY==-1.0F) {
- /* upside-down */
- GLint row;
- for (row=0; row<drawHeight; row++) {
- destY--;
- (*ctx->Driver.WriteRGBASpan)(ctx, drawWidth, destX, destY,
- (void *) src, NULL);
- src += rowLength * 4;
- }
- }
- else {
- /* with zooming */
- GLint row;
- for (row=0; row<drawHeight; row++) {
- gl_write_zoomed_rgba_span(ctx, drawWidth, destX, destY,
- zSpan, 0, (void *) src, zoomY0);
- src += rowLength * 4;
- destY++;
- }
- }
- }
- return GL_TRUE;
- }
- else if (format == GL_RGB && type == CHAN_TYPE
- && ctx->ImageTransferState == 0) {
- if (ctx->Visual.RGBAflag) {
- GLchan *src = (GLchan *) pixels
- + (skipRows * rowLength + skipPixels) * 3;
- if (ctx->Pixel.ZoomX==1.0F && ctx->Pixel.ZoomY==1.0F) {
- GLint row;
- for (row=0; row<drawHeight; row++) {
- (*ctx->Driver.WriteRGBSpan)(ctx, drawWidth, destX, destY,
- (void *) src, NULL);
- src += rowLength * 3;
- destY++;
- }
- }
- else if (ctx->Pixel.ZoomX==1.0F && ctx->Pixel.ZoomY==-1.0F) {
- /* upside-down */
- GLint row;
- for (row=0; row<drawHeight; row++) {
- destY--;
- (*ctx->Driver.WriteRGBSpan)(ctx, drawWidth, destX, destY,
- (void *) src, NULL);
- src += rowLength * 3;
- }
- }
- else {
- /* with zooming */
- GLint row;
- for (row=0; row<drawHeight; row++) {
- gl_write_zoomed_rgb_span(ctx, drawWidth, destX, destY,
- zSpan, 0, (void *) src, zoomY0);
- src += rowLength * 3;
- destY++;
- }
- }
- }
- return GL_TRUE;
- }
- else if (format == GL_LUMINANCE && type == CHAN_TYPE
- && ctx->ImageTransferState==0) {
- if (ctx->Visual.RGBAflag) {
- GLchan *src = (GLchan *) pixels
- + (skipRows * rowLength + skipPixels);
- if (ctx->Pixel.ZoomX==1.0F && ctx->Pixel.ZoomY==1.0F) {
- /* no zooming */
- GLint row;
- ASSERT(drawWidth < MAX_WIDTH);
- for (row=0; row<drawHeight; row++) {
- GLint i;
- for (i=0;i<drawWidth;i++) {
- rgb[i][0] = src[i];
- rgb[i][1] = src[i];
- rgb[i][2] = src[i];
- }
- (*ctx->Driver.WriteRGBSpan)(ctx, drawWidth, destX, destY,
- (void *) rgb, NULL);
- src += rowLength;
- destY++;
- }
- }
- else if (ctx->Pixel.ZoomX==1.0F && ctx->Pixel.ZoomY==-1.0F) {
- /* upside-down */
- GLint row;
- ASSERT(drawWidth < MAX_WIDTH);
- for (row=0; row<drawHeight; row++) {
- GLint i;
- for (i=0;i<drawWidth;i++) {
- rgb[i][0] = src[i];
- rgb[i][1] = src[i];
- rgb[i][2] = src[i];
- }
- destY--;
- (*ctx->Driver.WriteRGBSpan)(ctx, drawWidth, destX, destY,
- (void *) rgb, NULL);
- src += rowLength;
- }
- }
- else {
- /* with zooming */
- GLint row;
- ASSERT(drawWidth < MAX_WIDTH);
- for (row=0; row<drawHeight; row++) {
- GLint i;
- for (i=0;i<drawWidth;i++) {
- rgb[i][0] = src[i];
- rgb[i][1] = src[i];
- rgb[i][2] = src[i];
- }
- gl_write_zoomed_rgb_span(ctx, drawWidth, destX, destY,
- zSpan, 0, (void *) rgb, zoomY0);
- src += rowLength;
- destY++;
- }
- }
- }
- return GL_TRUE;
- }
- else if (format == GL_LUMINANCE_ALPHA && type == CHAN_TYPE
- && ctx->ImageTransferState == 0) {
- if (ctx->Visual.RGBAflag) {
- GLchan *src = (GLchan *) pixels
- + (skipRows * rowLength + skipPixels)*2;
- if (ctx->Pixel.ZoomX==1.0F && ctx->Pixel.ZoomY==1.0F) {
- /* no zooming */
- GLint row;
- ASSERT(drawWidth < MAX_WIDTH);
- for (row=0; row<drawHeight; row++) {
- GLint i;
- GLchan *ptr = src;
- for (i=0;i<drawWidth;i++) {
- rgba[i][0] = *ptr;
- rgba[i][1] = *ptr;
- rgba[i][2] = *ptr++;
- rgba[i][3] = *ptr++;
- }
- (*ctx->Driver.WriteRGBASpan)(ctx, drawWidth, destX, destY,
- (void *) rgba, NULL);
- src += rowLength*2;
- destY++;
- }
- }
- else if (ctx->Pixel.ZoomX==1.0F && ctx->Pixel.ZoomY==-1.0F) {
- /* upside-down */
- GLint row;
- ASSERT(drawWidth < MAX_WIDTH);
- for (row=0; row<drawHeight; row++) {
- GLint i;
- GLchan *ptr = src;
- for (i=0;i<drawWidth;i++) {
- rgba[i][0] = *ptr;
- rgba[i][1] = *ptr;
- rgba[i][2] = *ptr++;
- rgba[i][3] = *ptr++;
- }
- destY--;
- (*ctx->Driver.WriteRGBASpan)(ctx, drawWidth, destX, destY,
- (void *) rgba, NULL);
- src += rowLength*2;
- }
- }
- else {
- /* with zooming */
- GLint row;
- ASSERT(drawWidth < MAX_WIDTH);
- for (row=0; row<drawHeight; row++) {
- GLchan *ptr = src;
- GLint i;
- for (i=0;i<drawWidth;i++) {
- rgba[i][0] = *ptr;
- rgba[i][1] = *ptr;
- rgba[i][2] = *ptr++;
- rgba[i][3] = *ptr++;
- }
- gl_write_zoomed_rgba_span(ctx, drawWidth, destX, destY,
- zSpan, 0, (void *) rgba, zoomY0);
- src += rowLength*2;
- destY++;
- }
- }
- }
- return GL_TRUE;
- }
- else if (format==GL_COLOR_INDEX && type==GL_UNSIGNED_BYTE) {
- GLubyte *src = (GLubyte *) pixels + skipRows * rowLength + skipPixels;
- if (ctx->Visual.RGBAflag) {
- /* convert CI data to RGBA */
- if (ctx->Pixel.ZoomX==1.0F && ctx->Pixel.ZoomY==1.0F) {
- /* no zooming */
- GLint row;
- for (row=0; row<drawHeight; row++) {
- ASSERT(drawWidth < MAX_WIDTH);
- _mesa_map_ci8_to_rgba(ctx, drawWidth, src, rgba);
- (*ctx->Driver.WriteRGBASpan)(ctx, drawWidth, destX, destY,
- (const GLchan (*)[4]) rgba,
- NULL);
- src += rowLength;
- destY++;
- }
- return GL_TRUE;
- }
- else if (ctx->Pixel.ZoomX==1.0F && ctx->Pixel.ZoomY==-1.0F) {
- /* upside-down */
- GLint row;
- for (row=0; row<drawHeight; row++) {
- ASSERT(drawWidth < MAX_WIDTH);
- _mesa_map_ci8_to_rgba(ctx, drawWidth, src, rgba);
- destY--;
- (*ctx->Driver.WriteRGBASpan)(ctx, drawWidth, destX, destY,
- (const GLchan (*)[4]) rgba,
- NULL);
- src += rowLength;
- }
- return GL_TRUE;
- }
- else {
- /* with zooming */
- GLint row;
- for (row=0; row<drawHeight; row++) {
- ASSERT(drawWidth < MAX_WIDTH);
- _mesa_map_ci8_to_rgba(ctx, drawWidth, src, rgba);
- gl_write_zoomed_rgba_span(ctx, drawWidth, destX, destY,
- zSpan, 0, (void *) rgba, zoomY0);
- src += rowLength;
- destY++;
- }
- return GL_TRUE;
- }
- }
- else if (ctx->ImageTransferState==0) {
- /* write CI data to CI frame buffer */
- GLint row;
- if (ctx->Pixel.ZoomX==1.0F && ctx->Pixel.ZoomY==1.0F) {
- /* no zooming */
- for (row=0; row<drawHeight; row++) {
- (*ctx->Driver.WriteCI8Span)(ctx, drawWidth, destX, destY,
- src, NULL);
- src += rowLength;
- destY++;
- }
- return GL_TRUE;
- }
- else {
- /* with zooming */
- return GL_FALSE;
- }
- }
- }
- else {
- /* can't handle this pixel format and/or data type here */
- return GL_FALSE;
- }
- }
-
- /* can't do a simple draw, have to use slow path */
- return GL_FALSE;
-}
-
-
-
-/*
- * Do glDrawPixels of index pixels.
- */
-static void
-draw_index_pixels( GLcontext *ctx, GLint x, GLint y,
- GLsizei width, GLsizei height,
- GLenum type, const GLvoid *pixels )
-{
- const GLboolean zoom = ctx->Pixel.ZoomX!=1.0 || ctx->Pixel.ZoomY!=1.0;
- const GLint desty = y;
- GLint row, drawWidth;
- GLdepth zspan[MAX_WIDTH];
-
- drawWidth = (width > MAX_WIDTH) ? MAX_WIDTH : width;
-
- /* Fragment depth values */
- if (ctx->Depth.Test || ctx->Fog.Enabled) {
- GLdepth zval = (GLdepth) (ctx->Current.RasterPos[2] * ctx->Visual.DepthMaxF);
- GLint i;
- for (i = 0; i < drawWidth; i++) {
- zspan[i] = zval;
- }
- }
-
- /*
- * General solution
- */
- for (row = 0; row < height; row++, y++) {
- GLuint indexes[MAX_WIDTH];
- const GLvoid *source = _mesa_image_address(&ctx->Unpack,
- pixels, width, height, GL_COLOR_INDEX, type, 0, row, 0);
- _mesa_unpack_index_span(ctx, drawWidth, GL_UNSIGNED_INT, indexes,
- type, source, &ctx->Unpack,
- ctx->ImageTransferState);
- if (zoom) {
- gl_write_zoomed_index_span(ctx, drawWidth, x, y, zspan, 0, indexes, desty);
- }
- else {
- gl_write_index_span(ctx, drawWidth, x, y, zspan, 0, indexes, GL_BITMAP);
- }
- }
-}
-
-
-
-/*
- * Do glDrawPixels of stencil image. The image datatype may either
- * be GLubyte or GLbitmap.
- */
-static void
-draw_stencil_pixels( GLcontext *ctx, GLint x, GLint y,
- GLsizei width, GLsizei height,
- GLenum type, const GLvoid *pixels )
-{
- const GLboolean zoom = ctx->Pixel.ZoomX!=1.0 || ctx->Pixel.ZoomY!=1.0;
- const GLint desty = y;
- GLint row, drawWidth;
-
- if (type != GL_BYTE &&
- type != GL_UNSIGNED_BYTE &&
- type != GL_SHORT &&
- type != GL_UNSIGNED_SHORT &&
- type != GL_INT &&
- type != GL_UNSIGNED_INT &&
- type != GL_FLOAT &&
- type != GL_BITMAP) {
- gl_error( ctx, GL_INVALID_ENUM, "glDrawPixels(stencil type)");
- return;
- }
-
- drawWidth = (width > MAX_WIDTH) ? MAX_WIDTH : width;
-
- for (row = 0; row < height; row++, y++) {
- GLstencil values[MAX_WIDTH];
- GLenum destType = (sizeof(GLstencil) == sizeof(GLubyte))
- ? GL_UNSIGNED_BYTE : GL_UNSIGNED_SHORT;
- const GLvoid *source = _mesa_image_address(&ctx->Unpack,
- pixels, width, height, GL_COLOR_INDEX, type, 0, row, 0);
- _mesa_unpack_index_span(ctx, drawWidth, destType, values,
- type, source, &ctx->Unpack,
- ctx->ImageTransferState);
- if (ctx->ImageTransferState & IMAGE_SHIFT_OFFSET_BIT) {
- _mesa_shift_and_offset_stencil( ctx, drawWidth, values );
- }
- if (ctx->Pixel.MapStencilFlag) {
- _mesa_map_stencil( ctx, drawWidth, values );
- }
-
- if (zoom) {
- gl_write_zoomed_stencil_span( ctx, (GLuint) drawWidth, x, y,
- values, desty );
- }
- else {
- _mesa_write_stencil_span( ctx, (GLuint) drawWidth, x, y, values );
- }
- }
-}
-
-
-
-/*
- * Do a glDrawPixels of depth values.
- */
-static void
-draw_depth_pixels( GLcontext *ctx, GLint x, GLint y,
- GLsizei width, GLsizei height,
- GLenum type, const GLvoid *pixels )
-{
- const GLboolean bias_or_scale = ctx->Pixel.DepthBias!=0.0 || ctx->Pixel.DepthScale!=1.0;
- const GLboolean zoom = ctx->Pixel.ZoomX!=1.0 || ctx->Pixel.ZoomY!=1.0;
- const GLint desty = y;
- GLchan rgba[MAX_WIDTH][4];
- GLuint ispan[MAX_WIDTH];
- GLint drawWidth = (width > MAX_WIDTH) ? MAX_WIDTH : width;
-
- if (type != GL_BYTE
- && type != GL_UNSIGNED_BYTE
- && type != GL_SHORT
- && type != GL_UNSIGNED_SHORT
- && type != GL_INT
- && type != GL_UNSIGNED_INT
- && type != GL_FLOAT) {
- gl_error(ctx, GL_INVALID_ENUM, "glDrawPixels(type)");
- return;
- }
-
- /* Colors or indexes */
- if (ctx->Visual.RGBAflag) {
- GLint r = FLOAT_TO_CHAN(ctx->Current.RasterColor[0]);
- GLint g = FLOAT_TO_CHAN(ctx->Current.RasterColor[1]);
- GLint b = FLOAT_TO_CHAN(ctx->Current.RasterColor[2]);
- GLint a = FLOAT_TO_CHAN(ctx->Current.RasterColor[3]);
- GLint i;
- for (i = 0; i < drawWidth; i++) {
- rgba[i][RCOMP] = r;
- rgba[i][GCOMP] = g;
- rgba[i][BCOMP] = b;
- rgba[i][ACOMP] = a;
- }
- }
- else {
- GLint i;
- for (i = 0; i < drawWidth; i++) {
- ispan[i] = ctx->Current.RasterIndex;
- }
- }
-
- if (type==GL_UNSIGNED_SHORT && sizeof(GLdepth)==sizeof(GLushort)
- && !bias_or_scale && !zoom && ctx->Visual.RGBAflag) {
- /* Special case: directly write 16-bit depth values */
- GLint row;
- for (row = 0; row < height; row++, y++) {
- GLdepth zspan[MAX_WIDTH];
- const GLushort *zptr = _mesa_image_address(&ctx->Unpack,
- pixels, width, height, GL_DEPTH_COMPONENT, type, 0, row, 0);
- GLint i;
- for (i = 0; i < width; i++)
- zspan[i] = zptr[i];
- gl_write_rgba_span( ctx, width, x, y, zspan, 0, rgba, GL_BITMAP );
- }
- }
- else if (type==GL_UNSIGNED_INT && ctx->Visual.DepthBits == 32
- && !bias_or_scale && !zoom && ctx->Visual.RGBAflag) {
- /* Special case: directly write 32-bit depth values */
- GLint row;
- for (row = 0; row < height; row++, y++) {
- const GLuint *zptr = _mesa_image_address(&ctx->Unpack,
- pixels, width, height, GL_DEPTH_COMPONENT, type, 0, row, 0);
- gl_write_rgba_span( ctx, width, x, y, zptr, 0, rgba, GL_BITMAP );
- }
- }
- else {
- /* General case */
- GLint row;
- for (row = 0; row < height; row++, y++) {
- GLdepth zspan[MAX_WIDTH];
- const GLvoid *src = _mesa_image_address(&ctx->Unpack,
- pixels, width, height, GL_DEPTH_COMPONENT, type, 0, row, 0);
- _mesa_unpack_depth_span( ctx, drawWidth, zspan, type, src,
- &ctx->Unpack, ctx->ImageTransferState );
- if (ctx->Visual.RGBAflag) {
- if (zoom) {
- gl_write_zoomed_rgba_span(ctx, width, x, y, zspan, 0,
- (const GLchan (*)[4]) rgba, desty);
- }
- else {
- gl_write_rgba_span(ctx, width, x, y, zspan, 0, rgba, GL_BITMAP);
- }
- }
- else {
- if (zoom) {
- gl_write_zoomed_index_span(ctx, width, x, y, zspan, 0,
- ispan, GL_BITMAP);
- }
- else {
- gl_write_index_span(ctx, width, x, y, zspan, 0,
- ispan, GL_BITMAP);
- }
- }
-
- }
- }
-}
-
-
-/*
- * Do glDrawPixels of RGBA pixels.
- */
-static void
-draw_rgba_pixels( GLcontext *ctx, GLint x, GLint y,
- GLsizei width, GLsizei height,
- GLenum format, GLenum type, const GLvoid *pixels )
-{
- const struct gl_pixelstore_attrib *unpack = &ctx->Unpack;
- const GLboolean zoom = ctx->Pixel.ZoomX!=1.0 || ctx->Pixel.ZoomY!=1.0;
- const GLint desty = y;
- GLdepth zspan[MAX_WIDTH];
- GLboolean quickDraw;
- GLfloat *convImage = NULL;
- GLuint transferOps = ctx->ImageTransferState;
-
- if (!_mesa_is_legal_format_and_type(format, type)) {
- gl_error(ctx, GL_INVALID_ENUM, "glDrawPixels(format or type)");
- return;
- }
-
- /* Try an optimized glDrawPixels first */
- 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->Visual.DepthMaxF);
- GLint i;
- for (i=0;i<width;i++) {
- zspan[i] = z;
- }
- }
-
-
- if (ctx->RasterMask == 0 && !zoom && x >= 0 && y >= 0
- && x + width <= ctx->DrawBuffer->Width
- && y + height <= ctx->DrawBuffer->Height) {
- quickDraw = GL_TRUE;
- }
- else {
- quickDraw = GL_FALSE;
- }
-
- if (ctx->Pixel.Convolution2DEnabled || ctx->Pixel.Separable2DEnabled) {
- /* Convolution has to be handled specially. We'll create an
- * intermediate image, applying all pixel transfer operations
- * up to convolution. Then we'll convolve the image. Then
- * we'll proceed with the rest of the transfer operations and
- * rasterize the image.
- */
- GLint row;
- GLfloat *dest, *tmpImage;
-
- tmpImage = (GLfloat *) MALLOC(width * height * 4 * sizeof(GLfloat));
- if (!tmpImage) {
- gl_error(ctx, GL_OUT_OF_MEMORY, "glDrawPixels");
- return;
- }
- convImage = (GLfloat *) MALLOC(width * height * 4 * sizeof(GLfloat));
- if (!convImage) {
- FREE(tmpImage);
- gl_error(ctx, GL_OUT_OF_MEMORY, "glDrawPixels");
- return;
- }
-
- /* Unpack the image and apply transfer ops up to convolution */
- dest = tmpImage;
- for (row = 0; row < height; row++) {
- const GLvoid *source = _mesa_image_address(unpack,
- pixels, width, height, format, type, 0, row, 0);
- _mesa_unpack_float_color_span(ctx, width, GL_RGBA, (void *) dest,
- format, type, source, unpack,
- transferOps & IMAGE_PRE_CONVOLUTION_BITS,
- GL_FALSE);
- dest += width * 4;
- }
-
- /* do convolution */
- if (ctx->Pixel.Convolution2DEnabled) {
- _mesa_convolve_2d_image(ctx, &width, &height, tmpImage, convImage);
- }
- else {
- ASSERT(ctx->Pixel.Separable2DEnabled);
- _mesa_convolve_sep_image(ctx, &width, &height, tmpImage, convImage);
- }
- FREE(tmpImage);
-
- /* continue transfer ops and draw the convolved image */
- unpack = &_mesa_native_packing;
- pixels = convImage;
- format = GL_RGBA;
- type = GL_FLOAT;
- transferOps &= IMAGE_POST_CONVOLUTION_BITS;
- }
-
- /*
- * General solution
- */
- {
- GLchan rgba[MAX_WIDTH][4];
- GLint row;
- if (width > MAX_WIDTH)
- width = MAX_WIDTH;
- for (row = 0; row < height; row++, y++) {
- const GLvoid *source = _mesa_image_address(unpack,
- pixels, width, height, format, type, 0, row, 0);
- _mesa_unpack_chan_color_span(ctx, width, GL_RGBA, (void*) rgba,
- format, type, source, unpack,
- transferOps);
- if ((ctx->Pixel.MinMaxEnabled && ctx->MinMax.Sink) ||
- (ctx->Pixel.HistogramEnabled && ctx->Histogram.Sink))
- continue;
-
- if (ctx->Texture.ReallyEnabled && ctx->Pixel.PixelTextureEnabled) {
- GLfloat s[MAX_WIDTH], t[MAX_WIDTH], r[MAX_WIDTH], q[MAX_WIDTH];
- GLchan primary_rgba[MAX_WIDTH][4];
- GLuint unit;
- /* XXX not sure how multitexture is supposed to work here */
-
- MEMCPY(primary_rgba, rgba, 4 * width * sizeof(GLchan));
-
- for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) {
- if (ctx->Texture.Unit[unit].ReallyEnabled) {
- _mesa_pixeltexgen(ctx, width, (const GLchan (*)[4]) rgba,
- s, t, r, q);
- gl_texture_pixels(ctx, unit, width, s, t, r, NULL,
- primary_rgba, rgba);
- }
- }
- }
-
- if (quickDraw) {
- (*ctx->Driver.WriteRGBASpan)( ctx, width, x, y,
- (CONST GLchan (*)[]) rgba, NULL);
- }
- else if (zoom) {
- gl_write_zoomed_rgba_span( ctx, width, x, y, zspan, 0,
- (CONST GLchan (*)[]) rgba, desty );
- }
- else {
- gl_write_rgba_span( ctx, (GLuint) width, x, y, zspan, 0,
- rgba, GL_BITMAP);
- }
- }
- }
-
- if (convImage) {
- FREE(convImage);
- }
-}
-
/*
ctx->OcclusionResult = GL_TRUE;
/* see if device driver can do the drawpix */
+ RENDER_START(ctx);
+
if (ctx->Driver.DrawPixels
&& (*ctx->Driver.DrawPixels)(ctx, x, y, width, height, format, type,
&ctx->Unpack, pixels)) {
- return;
- }
+ /* finished */
+ } else
+ _swrast_DrawPixels( ctx, x, y, width, height, format, type,
+ &ctx->Unpack, pixels );
- RENDER_START(ctx);
- switch (format) {
- case GL_STENCIL_INDEX:
- draw_stencil_pixels( ctx, x, y, width, height, type, pixels );
- break;
- case GL_DEPTH_COMPONENT:
- draw_depth_pixels( ctx, x, y, width, height, type, pixels );
- break;
- case GL_COLOR_INDEX:
- if (ctx->Visual.RGBAflag)
- draw_rgba_pixels(ctx, x,y, width, height, format, type, pixels);
- else
- draw_index_pixels(ctx, x, y, width, height, type, pixels);
- break;
- case GL_RED:
- case GL_GREEN:
- case GL_BLUE:
- case GL_ALPHA:
- case GL_LUMINANCE:
- case GL_LUMINANCE_ALPHA:
- case GL_RGB:
- case GL_BGR:
- case GL_RGBA:
- case GL_BGRA:
- case GL_ABGR_EXT:
- draw_rgba_pixels(ctx, x, y, width, height, format, type, pixels);
- break;
- default:
- gl_error( ctx, GL_INVALID_ENUM, "glDrawPixels(format)" );
- }
RENDER_FINISH(ctx);
}
else if (ctx->RenderMode==GL_FEEDBACK) {
-/* $Id: drawpix.h,v 1.3 1999/11/22 22:21:38 brianp Exp $ */
+/* $Id: drawpix.h,v 1.4 2000/10/31 18:09:44 keithw Exp $ */
/*
* Mesa 3-D graphics library
#include "types.h"
-
-extern GLboolean
-_mesa_clip_pixelrect(const GLcontext *ctx,
- GLint *destX, GLint *destY,
- GLsizei *width, GLsizei *height,
- GLint *skipPixels, GLint *skipRows);
-
-
extern void
_mesa_DrawPixels( GLsizei width, GLsizei height,
GLenum format, GLenum type, const GLvoid *pixels );
-/* $Id: feedback.c,v 1.14 2000/10/30 13:32:00 keithw Exp $ */
+/* $Id: feedback.c,v 1.15 2000/10/31 18:09:44 keithw Exp $ */
/*
* Mesa 3-D graphics library
#include "macros.h"
#include "mmath.h"
#include "types.h"
-#include "triangle.h"
#endif
}
+static GLboolean cull_triangle( GLcontext *ctx,
+ GLuint v0, GLuint v1, GLuint v2, GLuint pv )
+{
+ struct vertex_buffer *VB = ctx->VB;
+ GLfloat (*win)[4] = VB->Win.data;
+ GLfloat ex = win[v1][0] - win[v0][0];
+ GLfloat ey = win[v1][1] - win[v0][1];
+ GLfloat fx = win[v2][0] - win[v0][0];
+ GLfloat fy = win[v2][1] - win[v0][1];
+ GLfloat c = ex*fy-ey*fx;
+
+ if (c * ctx->backface_sign > 0)
+ return 0;
+
+ return 1;
+}
+
+
/*
* Put triangle in feedback buffer.
void gl_feedback_triangle( GLcontext *ctx,
GLuint v0, GLuint v1, GLuint v2, GLuint pv )
{
- if (gl_cull_triangle( ctx, v0, v1, v2, 0 )) {
+ if (cull_triangle( ctx, v0, v1, v2, 0 )) {
FEEDBACK_TOKEN( ctx, (GLfloat) (GLint) GL_POLYGON_TOKEN );
FEEDBACK_TOKEN( ctx, (GLfloat) 3 ); /* three vertices */
{
const struct vertex_buffer *VB = ctx->VB;
- if (gl_cull_triangle( ctx, v0, v1, v2, 0 )) {
+ if (cull_triangle( ctx, v0, v1, v2, 0 )) {
const GLfloat zs = 1.0F / ctx->Visual.DepthMaxF;
gl_update_hitflag( ctx, VB->Win.data[v0][2] * zs );
gl_update_hitflag( ctx, VB->Win.data[v1][2] * zs );
-/* $Id: fog.c,v 1.26 2000/10/30 13:32:00 keithw Exp $ */
+/* $Id: fog.c,v 1.27 2000/10/31 18:09:44 keithw Exp $ */
/*
* Mesa 3-D graphics library
-void
-_mesa_init_fog( void )
-{
-}
static GLvector1f *get_fogcoord_ptr( GLcontext *ctx, GLvector1f *tmp )
{
make_win_fog_coords( VB, get_fogcoord_ptr( VB->ctx, &tmp ) );
}
-
-
-/*
- * Apply fog to an array of RGBA pixels.
- * Input: n - number of pixels
- * fog - array of interpolated screen-space fog coordinates in [0..1]
- * red, green, blue, alpha - pixel colors
- * Output: red, green, blue, alpha - fogged pixel colors
- */
-void
-_mesa_fog_rgba_pixels( const GLcontext *ctx,
- GLuint n,
- const GLfixed fog[],
- GLchan rgba[][4] )
-{
- GLfixed rFog = ctx->Fog.Color[0] * CHAN_MAXF;
- GLfixed gFog = ctx->Fog.Color[1] * CHAN_MAXF;
- GLfixed bFog = ctx->Fog.Color[2] * CHAN_MAXF;
- GLuint i;
-
- for (i=0;i<n;i++) {
- GLfixed f = CLAMP(fog[i], 0, FIXED_ONE);
- GLfixed g = FIXED_ONE - f;
- rgba[i][0] = (f*rgba[i][0] + g*rFog) >> FIXED_SHIFT;
- rgba[i][1] = (f*rgba[i][1] + g*gFog) >> FIXED_SHIFT;
- rgba[i][2] = (f*rgba[i][2] + g*bFog) >> FIXED_SHIFT;
- }
-}
-
-
-
-
-/*
- * Apply fog to an array of color index pixels.
- * Input: n - number of pixels
- * z - array of integer depth values
- * index - pixel color indexes
- * Output: index - fogged pixel color indexes
- */
-void
-_mesa_fog_ci_pixels( const GLcontext *ctx,
- GLuint n, const GLfixed fog[], GLuint index[] )
-{
- GLuint idx = ctx->Fog.Index;
- GLuint i;
-
- for (i=0;i<n;i++) {
- GLfixed f = FixedToFloat(CLAMP(fog[i], 0, FIXED_ONE));
- index[i] = (GLuint) ((GLfloat) index[i] + (1.0F-f) * idx);
- }
-}
-
-
-
-/*
- * Calculate fog coords from window z values
- * Input: n - number of pixels
- * z - array of integer depth values
- * red, green, blue, alpha - pixel colors
- * Output: red, green, blue, alpha - fogged pixel colors
- *
- * Use lookup table & interpolation?
- */
-void
-_mesa_win_fog_coords_from_z( const GLcontext *ctx,
- GLuint n,
- const GLdepth z[],
- GLfixed fogcoord[] )
-{
- GLfloat c = ctx->ProjectionMatrix.m[10];
- GLfloat d = ctx->ProjectionMatrix.m[14];
- GLuint i;
-
- GLfloat tz = ctx->Viewport.WindowMap.m[MAT_TZ];
- GLfloat szInv = 1.0F / ctx->Viewport.WindowMap.m[MAT_SZ];
-
- switch (ctx->Fog.Mode) {
- case GL_LINEAR:
- {
- GLfloat fogEnd = ctx->Fog.End;
- GLfloat fogScale = (GLfloat) FIXED_ONE / (ctx->Fog.End -
- ctx->Fog.Start);
- for (i=0;i<n;i++) {
- GLfloat ndcz = ((GLfloat) z[i] - tz) * szInv;
- GLfloat eyez = -d / (c+ndcz);
- if (eyez < 0.0) eyez = -eyez;
- fogcoord[i] = (GLint)(fogEnd - eyez) * fogScale;
- }
- }
- break;
- case GL_EXP:
- for (i=0;i<n;i++) {
- GLfloat ndcz = ((GLfloat) z[i] - tz) * szInv;
- GLfloat eyez = d / (c+ndcz);
- if (eyez < 0.0) eyez = -eyez;
- fogcoord[i] = FloatToFixed(exp( -ctx->Fog.Density * eyez ));
- }
- break;
- case GL_EXP2:
- {
- GLfloat negDensitySquared = -ctx->Fog.Density * ctx->Fog.Density;
- for (i=0;i<n;i++) {
- GLfloat ndcz = ((GLfloat) z[i] - tz) * szInv;
- GLfloat eyez = d / (c+ndcz);
- GLfloat tmp = negDensitySquared * eyez * eyez;
-#if defined(__alpha__) || defined(__alpha)
- /* XXX this underflow check may be needed for other systems */
- if (tmp < FLT_MIN_10_EXP)
- tmp = FLT_MIN_10_EXP;
-#endif
- fogcoord[i] = FloatToFixed(exp( tmp ));
- }
- }
- break;
- default:
- gl_problem(ctx, "Bad fog mode in _mesa_win_fog_coords_from_z");
- return;
- }
-}
-
-
-/*
- * Apply fog to an array of RGBA pixels.
- * Input: n - number of pixels
- * z - array of integer depth values
- * red, green, blue, alpha - pixel colors
- * Output: red, green, blue, alpha - fogged pixel colors
- */
-void
-_mesa_depth_fog_rgba_pixels( const GLcontext *ctx,
- GLuint n, const GLdepth z[], GLchan rgba[][4] )
-{
- GLfixed fog[MAX_WIDTH];
- _mesa_win_fog_coords_from_z( ctx, n, z, fog );
- _mesa_fog_rgba_pixels( ctx, n, fog, rgba );
-}
-
-
-/*
- * Apply fog to an array of color index pixels.
- * Input: n - number of pixels
- * z - array of integer depth values
- * index - pixel color indexes
- * Output: index - fogged pixel color indexes
- */
-void
-_mesa_depth_fog_ci_pixels( const GLcontext *ctx,
- GLuint n, const GLdepth z[], GLuint index[] )
-{
- GLfixed fog[MAX_WIDTH];
- _mesa_win_fog_coords_from_z( ctx, n, z, fog );
- _mesa_fog_ci_pixels( ctx, n, fog, index );
-}
-
-/* $Id: fog.h,v 1.8 2000/10/30 16:32:43 brianp Exp $ */
+/* $Id: fog.h,v 1.9 2000/10/31 18:09:44 keithw Exp $ */
/*
* Mesa 3-D graphics library
_mesa_Fogiv(GLenum pname, const GLint *params );
-
-extern void
-_mesa_fog_rgba_pixels( const GLcontext *ctx,
- GLuint n, const GLfixed fog[],
- GLchan rgba[][4] );
-
-extern void
-_mesa_fog_ci_pixels( const GLcontext *ctx,
- GLuint n, const GLfixed fog[], GLuint indx[] );
-
-
extern void
_mesa_make_win_fog_coords( struct vertex_buffer *VB );
-extern void
-_mesa_win_fog_coords_from_z( const GLcontext *ctx,
- GLuint n,
- const GLdepth z[],
- GLfixed fogcoord[] );
-
-extern void
-_mesa_depth_fog_rgba_pixels( const GLcontext *ctx,
- GLuint n, const GLdepth z[], GLchan rgba[][4] );
-
-extern void
-_mesa_depth_fog_ci_pixels( const GLcontext *ctx,
- GLuint n, const GLdepth z[], GLuint index[] );
-
-
-
-extern void
-_mesa_init_fog( void );
-
-
#endif
-/* $Id: lines.c,v 1.19 2000/10/30 13:32:00 keithw Exp $ */
+/* $Id: lines.c,v 1.20 2000/10/31 18:09:44 keithw Exp $ */
/*
* Mesa 3-D graphics library
#include "lines.h"
#include "macros.h"
#include "mmath.h"
-#include "pb.h"
#include "texstate.h"
#include "types.h"
#include "vb.h"
}
-
-/**********************************************************************/
-/***** Rasterization *****/
-/**********************************************************************/
-
-
-/*
- * There are 4 pairs (RGBA, CI) of line drawing functions:
- * 1. simple: width=1 and no special rasterization functions (fastest)
- * 2. flat: width=1, non-stippled, flat-shaded, any raster operations
- * 3. smooth: width=1, non-stippled, smooth-shaded, any raster operations
- * 4. general: any other kind of line (slowest)
- */
-
-
-/*
- * All line drawing functions have the same arguments:
- * v1, v2 - indexes of first and second endpoints into vertex buffer arrays
- * pv - provoking vertex: which vertex color/index to use for flat shading.
- */
-
-
-
-
-
-
-#if MAX_WIDTH > MAX_HEIGHT
-# define MAXPOINTS MAX_WIDTH
-#else
-# define MAXPOINTS MAX_HEIGHT
-#endif
-
-
-/* Flat, color index line */
-static void flat_ci_line( GLcontext *ctx,
- GLuint vert0, GLuint vert1, GLuint pvert )
-{
- PB_SET_INDEX( ctx->PB, ctx->VB->IndexPtr->data[pvert] );
-
-#define INTERP_XY 1
-#define PLOT(X,Y) PB_WRITE_PIXEL(ctx->PB, X, Y, 0, 0);
-
-#include "linetemp.h"
-
- gl_flush_pb(ctx);
-}
-
-
-
-/* Flat, color index line with Z interpolation/testing */
-static void flat_ci_z_line( GLcontext *ctx,
- GLuint vert0, GLuint vert1, GLuint pvert )
-{
- PB_SET_INDEX( ctx->PB, ctx->VB->IndexPtr->data[pvert] );
-
-#define INTERP_XY 1
-#define INTERP_Z 1
-#define PLOT(X,Y) PB_WRITE_PIXEL(ctx->PB, X, Y, Z, fog0);
-
-#include "linetemp.h"
-
- gl_flush_pb(ctx);
-}
-
-
-
-/* Flat-shaded, RGBA line */
-static void flat_rgba_line( GLcontext *ctx,
- GLuint vert0, GLuint vert1, GLuint pvert )
-{
- const GLchan *color = ctx->VB->ColorPtr->data[pvert];
- PB_SET_COLOR( ctx->PB, color[0], color[1], color[2], color[3] );
-
-#define INTERP_XY 1
-#define PLOT(X,Y) PB_WRITE_PIXEL(ctx->PB, X, Y, 0, 0);
-
-#include "linetemp.h"
-
- gl_flush_pb(ctx);
-}
-
-
-
-/* Flat-shaded, RGBA line with Z interpolation/testing */
-static void flat_rgba_z_line( GLcontext *ctx,
- GLuint vert0, GLuint vert1, GLuint pvert )
-{
- const GLchan *color = ctx->VB->ColorPtr->data[pvert];
- PB_SET_COLOR( ctx->PB, color[0], color[1], color[2], color[3] );
-
-#define INTERP_XY 1
-#define INTERP_Z 1
-#define PLOT(X,Y) PB_WRITE_PIXEL(ctx->PB, X, Y, Z, fog0);
-
-#include "linetemp.h"
-
- gl_flush_pb(ctx);
-}
-
-
-
-/* Smooth shaded, color index line */
-static void smooth_ci_line( GLcontext *ctx,
- GLuint vert0, GLuint vert1, GLuint pvert )
-{
- GLint count = ctx->PB->count;
- GLint *pbx = ctx->PB->x;
- GLint *pby = ctx->PB->y;
- GLuint *pbi = ctx->PB->index;
- (void) pvert;
-
- ctx->PB->mono = GL_FALSE;
-
-#define INTERP_XY 1
-#define INTERP_INDEX 1
-
-#define PLOT(X,Y) \
- pbx[count] = X; \
- pby[count] = Y; \
- pbi[count] = I; \
- count++;
-
-#include "linetemp.h"
-
- ctx->PB->count = count;
- gl_flush_pb(ctx);
-}
-
-
-
-/* Smooth shaded, color index line with Z interpolation/testing */
-static void smooth_ci_z_line( GLcontext *ctx,
- GLuint vert0, GLuint vert1, GLuint pvert )
-{
- GLint count = ctx->PB->count;
- GLint *pbx = ctx->PB->x;
- GLint *pby = ctx->PB->y;
- GLdepth *pbz = ctx->PB->z;
- GLuint *pbi = ctx->PB->index;
- (void) pvert;
-
- ctx->PB->mono = GL_FALSE;
-
-#define INTERP_XY 1
-#define INTERP_Z 1
-#define INTERP_INDEX 1
-
-#define PLOT(X,Y) \
- pbx[count] = X; \
- pby[count] = Y; \
- pbz[count] = Z; \
- pbi[count] = I; \
- count++;
-
-#include "linetemp.h"
-
- ctx->PB->count = count;
- gl_flush_pb(ctx);
-}
-
-
-
-/* Smooth-shaded, RGBA line */
-static void smooth_rgba_line( GLcontext *ctx,
- GLuint vert0, GLuint vert1, GLuint pvert )
-{
- GLint count = ctx->PB->count;
- GLint *pbx = ctx->PB->x;
- GLint *pby = ctx->PB->y;
- GLchan (*pbrgba)[4] = ctx->PB->rgba;
- (void) pvert;
-
- ctx->PB->mono = GL_FALSE;
-
-#define INTERP_XY 1
-#define INTERP_RGB 1
-#define INTERP_ALPHA 1
-
-#define PLOT(X,Y) \
- pbx[count] = X; \
- pby[count] = Y; \
- pbrgba[count][RCOMP] = FixedToInt(r0); \
- pbrgba[count][GCOMP] = FixedToInt(g0); \
- pbrgba[count][BCOMP] = FixedToInt(b0); \
- pbrgba[count][ACOMP] = FixedToInt(a0); \
- count++;
-
-#include "linetemp.h"
-
- ctx->PB->count = count;
- gl_flush_pb(ctx);
-}
-
-
-
-/* Smooth-shaded, RGBA line with Z interpolation/testing */
-static void smooth_rgba_z_line( GLcontext *ctx,
- GLuint vert0, GLuint vert1, GLuint pvert )
-{
- GLint count = ctx->PB->count;
- GLint *pbx = ctx->PB->x;
- GLint *pby = ctx->PB->y;
- GLdepth *pbz = ctx->PB->z;
- GLfixed *pbfog = ctx->PB->fog;
- GLchan (*pbrgba)[4] = ctx->PB->rgba;
-
- (void) pvert;
-
- ctx->PB->mono = GL_FALSE;
-
-#define INTERP_XY 1
-#define INTERP_Z 1
-#define INTERP_RGB 1
-#define INTERP_ALPHA 1
-
-#define PLOT(X,Y) \
- pbx[count] = X; \
- pby[count] = Y; \
- pbz[count] = Z; \
- pbfog[count] = fog0; \
- pbrgba[count][RCOMP] = FixedToInt(r0); \
- pbrgba[count][GCOMP] = FixedToInt(g0); \
- pbrgba[count][BCOMP] = FixedToInt(b0); \
- pbrgba[count][ACOMP] = FixedToInt(a0); \
- count++;
-
-#include "linetemp.h"
-
- ctx->PB->count = count;
- gl_flush_pb(ctx);
-}
-
-
-#define CHECK_FULL(count) \
- if (count >= PB_SIZE-MAX_WIDTH) { \
- ctx->PB->count = count; \
- gl_flush_pb(ctx); \
- count = ctx->PB->count; \
- }
-
-
-
-/* Smooth shaded, color index, any width, maybe stippled */
-static void general_smooth_ci_line( GLcontext *ctx,
- GLuint vert0, GLuint vert1, GLuint pvert )
-{
- GLint count = ctx->PB->count;
- GLint *pbx = ctx->PB->x;
- GLint *pby = ctx->PB->y;
- GLdepth *pbz = ctx->PB->z;
- GLfixed *pbfog = ctx->PB->fog;
- GLuint *pbi = ctx->PB->index;
- (void) pvert;
-
- ctx->PB->mono = GL_FALSE;
-
- if (ctx->Line.StippleFlag) {
- /* stippled */
-#define INTERP_XY 1
-#define INTERP_Z 1
-#define INTERP_INDEX 1
-#define WIDE 1
-#define STIPPLE 1
-#define PLOT(X,Y) \
- pbx[count] = X; \
- pby[count] = Y; \
- pbz[count] = Z; \
- pbfog[count] = fog0; \
- pbi[count] = I; \
- count++; \
- CHECK_FULL(count);
-#include "linetemp.h"
- }
- else {
- /* unstippled */
- if (ctx->Line.Width==2.0F) {
- /* special case: unstippled and width=2 */
-#define INTERP_XY 1
-#define INTERP_Z 1
-#define INTERP_INDEX 1
-#define XMAJOR_PLOT(X,Y) \
- pbx[count] = X; pbx[count+1] = X; \
- pby[count] = Y; pby[count+1] = Y+1; \
- pbz[count] = Z; pbz[count+1] = Z; \
- pbfog[count] = fog0; pbfog[count+1] = fog0; \
- pbi[count] = I; pbi[count+1] = I; \
- count += 2; \
- CHECK_FULL(count);
-#define YMAJOR_PLOT(X,Y) \
- pbx[count] = X; pbx[count+1] = X+1; \
- pby[count] = Y; pby[count+1] = Y; \
- pbz[count] = Z; pbz[count+1] = Z; \
- pbfog[count] = fog0; pbfog[count+1] = fog0; \
- pbi[count] = I; pbi[count+1] = I; \
- count += 2; \
- CHECK_FULL(count);
-#include "linetemp.h"
- }
- else {
- /* unstippled, any width */
-#define INTERP_XY 1
-#define INTERP_Z 1
-#define INTERP_INDEX 1
-#define WIDE 1
-#define PLOT(X,Y) \
- pbx[count] = X; \
- pby[count] = Y; \
- pbz[count] = Z; \
- pbi[count] = I; \
- pbfog[count] = fog0; \
- count++; \
- CHECK_FULL(count);
-#include "linetemp.h"
- }
- }
-
- ctx->PB->count = count;
- gl_flush_pb(ctx);
-}
-
-
-/* Flat shaded, color index, any width, maybe stippled */
-static void general_flat_ci_line( GLcontext *ctx,
- GLuint vert0, GLuint vert1, GLuint pvert )
-{
- GLint count;
- GLint *pbx = ctx->PB->x;
- GLint *pby = ctx->PB->y;
- GLdepth *pbz = ctx->PB->z;
- GLfixed *pbfog = ctx->PB->fog;
- PB_SET_INDEX( ctx->PB, ctx->VB->IndexPtr->data[pvert] );
- count = ctx->PB->count;
-
- if (ctx->Line.StippleFlag) {
- /* stippled, any width */
-#define INTERP_XY 1
-#define INTERP_Z 1
-#define WIDE 1
-#define STIPPLE 1
-#define PLOT(X,Y) \
- pbx[count] = X; \
- pby[count] = Y; \
- pbz[count] = Z; \
- pbfog[count] = fog0; \
- count++; \
- CHECK_FULL(count);
-#include "linetemp.h"
- }
- else {
- /* unstippled */
- if (ctx->Line.Width==2.0F) {
- /* special case: unstippled and width=2 */
-#define INTERP_XY 1
-#define INTERP_Z 1
-#define XMAJOR_PLOT(X,Y) \
- pbx[count] = X; pbx[count+1] = X; \
- pby[count] = Y; pby[count+1] = Y+1; \
- pbz[count] = Z; pbz[count+1] = Z; \
- pbfog[count] = fog0; pbfog[count+1] = fog0; \
- count += 2; \
- CHECK_FULL(count);
-#define YMAJOR_PLOT(X,Y) \
- pbx[count] = X; pbx[count+1] = X+1; \
- pby[count] = Y; pby[count+1] = Y; \
- pbz[count] = Z; pbz[count+1] = Z; \
- pbfog[count] = fog0; pbfog[count+1] = fog0; \
- count += 2; \
- CHECK_FULL(count);
-#include "linetemp.h"
- }
- else {
- /* unstippled, any width */
-#define INTERP_XY 1
-#define INTERP_Z 1
-#define WIDE 1
-#define PLOT(X,Y) \
- pbx[count] = X; \
- pby[count] = Y; \
- pbz[count] = Z; \
- pbfog[count] = fog0; \
- count++; \
- CHECK_FULL(count);
-#include "linetemp.h"
- }
- }
-
- ctx->PB->count = count;
- gl_flush_pb(ctx);
-}
-
-
-
-static void general_smooth_rgba_line( GLcontext *ctx,
- GLuint vert0, GLuint vert1, GLuint pvert)
-{
- GLint count = ctx->PB->count;
- GLint *pbx = ctx->PB->x;
- GLint *pby = ctx->PB->y;
- GLdepth *pbz = ctx->PB->z;
- GLfixed *pbfog = ctx->PB->fog;
- GLchan (*pbrgba)[4] = ctx->PB->rgba;
-
- (void) pvert;
-
- ctx->PB->mono = GL_FALSE;
-
- if (ctx->Line.StippleFlag) {
- /* stippled */
-#define INTERP_XY 1
-#define INTERP_Z 1
-#define INTERP_RGB 1
-#define INTERP_ALPHA 1
-#define WIDE 1
-#define STIPPLE 1
-#define PLOT(X,Y) \
- pbx[count] = X; \
- pby[count] = Y; \
- pbz[count] = Z; \
- pbfog[count] = fog0; \
- pbrgba[count][RCOMP] = FixedToInt(r0); \
- pbrgba[count][GCOMP] = FixedToInt(g0); \
- pbrgba[count][BCOMP] = FixedToInt(b0); \
- pbrgba[count][ACOMP] = FixedToInt(a0); \
- count++; \
- CHECK_FULL(count);
-#include "linetemp.h"
- }
- else {
- /* unstippled */
- if (ctx->Line.Width==2.0F) {
- /* special case: unstippled and width=2 */
-#define INTERP_XY 1
-#define INTERP_Z 1
-#define INTERP_RGB 1
-#define INTERP_ALPHA 1
-#define XMAJOR_PLOT(X,Y) \
- pbx[count] = X; pbx[count+1] = X; \
- pby[count] = Y; pby[count+1] = Y+1; \
- pbz[count] = Z; pbz[count+1] = Z; \
- pbfog[count] = fog0; pbfog[count+1] = fog0; \
- pbrgba[count][RCOMP] = FixedToInt(r0); \
- pbrgba[count][GCOMP] = FixedToInt(g0); \
- pbrgba[count][BCOMP] = FixedToInt(b0); \
- pbrgba[count][ACOMP] = FixedToInt(a0); \
- pbrgba[count+1][RCOMP] = FixedToInt(r0); \
- pbrgba[count+1][GCOMP] = FixedToInt(g0); \
- pbrgba[count+1][BCOMP] = FixedToInt(b0); \
- pbrgba[count+1][ACOMP] = FixedToInt(a0); \
- count += 2; \
- CHECK_FULL(count);
-#define YMAJOR_PLOT(X,Y) \
- pbx[count] = X; pbx[count+1] = X+1; \
- pby[count] = Y; pby[count+1] = Y; \
- pbz[count] = Z; pbz[count+1] = Z; \
- pbfog[count] = fog0; pbfog[count+1] = fog0; \
- pbrgba[count][RCOMP] = FixedToInt(r0); \
- pbrgba[count][GCOMP] = FixedToInt(g0); \
- pbrgba[count][BCOMP] = FixedToInt(b0); \
- pbrgba[count][ACOMP] = FixedToInt(a0); \
- pbrgba[count+1][RCOMP] = FixedToInt(r0); \
- pbrgba[count+1][GCOMP] = FixedToInt(g0); \
- pbrgba[count+1][BCOMP] = FixedToInt(b0); \
- pbrgba[count+1][ACOMP] = FixedToInt(a0); \
- count += 2; \
- CHECK_FULL(count);
-#include "linetemp.h"
- }
- else {
- /* unstippled, any width */
-#define INTERP_XY 1
-#define INTERP_Z 1
-#define INTERP_RGB 1
-#define INTERP_ALPHA 1
-#define WIDE 1
-#define PLOT(X,Y) \
- pbx[count] = X; \
- pby[count] = Y; \
- pbz[count] = Z; \
- pbfog[count] = fog0; \
- pbrgba[count][RCOMP] = FixedToInt(r0); \
- pbrgba[count][GCOMP] = FixedToInt(g0); \
- pbrgba[count][BCOMP] = FixedToInt(b0); \
- pbrgba[count][ACOMP] = FixedToInt(a0); \
- count++; \
- CHECK_FULL(count);
-#include "linetemp.h"
- }
- }
-
- ctx->PB->count = count;
- gl_flush_pb(ctx);
-}
-
-
-static void general_flat_rgba_line( GLcontext *ctx,
- GLuint vert0, GLuint vert1, GLuint pvert )
-{
- const GLchan *color = ctx->VB->ColorPtr->data[pvert];
- PB_SET_COLOR( ctx->PB, color[0], color[1], color[2], color[3] );
-
- if (ctx->Line.StippleFlag) {
- /* stippled */
-#define INTERP_XY 1
-#define INTERP_Z 1
-#define WIDE 1
-#define STIPPLE 1
-#define PLOT(X,Y) PB_WRITE_PIXEL(ctx->PB, X, Y, Z, fog0);
-#include "linetemp.h"
- }
- else {
- /* unstippled */
- if (ctx->Line.Width==2.0F) {
- /* special case: unstippled and width=2 */
-#define INTERP_XY 1
-#define INTERP_Z 1
-#define XMAJOR_PLOT(X,Y) PB_WRITE_PIXEL(ctx->PB, X, Y, Z, fog0); \
- PB_WRITE_PIXEL(ctx->PB, X, Y+1, Z, fog0);
-#define YMAJOR_PLOT(X,Y) PB_WRITE_PIXEL(ctx->PB, X, Y, Z, fog0); \
- PB_WRITE_PIXEL(ctx->PB, X+1, Y, Z, fog0);
-#include "linetemp.h"
- }
- else {
- /* unstippled, any width */
-#define INTERP_XY 1
-#define INTERP_Z 1
-#define WIDE 1
-#define PLOT(X,Y) PB_WRITE_PIXEL(ctx->PB, X, Y, Z, fog0);
-#include "linetemp.h"
- }
- }
-
- gl_flush_pb(ctx);
-}
-
-
-/* Flat-shaded, textured, any width, maybe stippled */
-static void flat_textured_line( GLcontext *ctx,
- GLuint vert0, GLuint vert1, GLuint pv )
-{
- GLint count;
- GLint *pbx = ctx->PB->x;
- GLint *pby = ctx->PB->y;
- GLdepth *pbz = ctx->PB->z;
- GLfixed *pbfog = ctx->PB->fog;
- GLfloat *pbs = ctx->PB->s[0];
- GLfloat *pbt = ctx->PB->t[0];
- GLfloat *pbu = ctx->PB->u[0];
- GLchan *color = ctx->VB->ColorPtr->data[pv];
- PB_SET_COLOR( ctx->PB, color[0], color[1], color[2], color[3] );
- count = ctx->PB->count;
-
- if (ctx->Line.StippleFlag) {
- /* stippled */
-#define INTERP_XY 1
-#define INTERP_Z 1
-#define INTERP_TEX 1
-#define WIDE 1
-#define STIPPLE 1
-#define PLOT(X,Y) \
- { \
- pbx[count] = X; \
- pby[count] = Y; \
- pbz[count] = Z; \
- pbfog[count] = fog0; \
- pbs[count] = fragTexcoord[0];\
- pbt[count] = fragTexcoord[1];\
- pbu[count] = fragTexcoord[2];\
- count++; \
- CHECK_FULL(count); \
- }
-#include "linetemp.h"
- }
- else {
- /* unstippled */
-#define INTERP_XY 1
-#define INTERP_Z 1
-#define INTERP_TEX 1
-#define WIDE 1
-#define PLOT(X,Y) \
- { \
- pbx[count] = X; \
- pby[count] = Y; \
- pbz[count] = Z; \
- pbfog[count] = fog0; \
- pbs[count] = fragTexcoord[0];\
- pbt[count] = fragTexcoord[1];\
- pbu[count] = fragTexcoord[2];\
- count++; \
- CHECK_FULL(count); \
- }
-#include "linetemp.h"
- }
-
- ctx->PB->count = count;
- gl_flush_pb(ctx);
-}
-
-
-
-/* Smooth-shaded, textured, any width, maybe stippled */
-static void smooth_textured_line( GLcontext *ctx,
- GLuint vert0, GLuint vert1, GLuint pvert )
-{
- GLint count = ctx->PB->count;
- GLint *pbx = ctx->PB->x;
- GLint *pby = ctx->PB->y;
- GLdepth *pbz = ctx->PB->z;
- GLfixed *pbfog = ctx->PB->fog;
- GLfloat *pbs = ctx->PB->s[0];
- GLfloat *pbt = ctx->PB->t[0];
- GLfloat *pbu = ctx->PB->u[0];
- GLchan (*pbrgba)[4] = ctx->PB->rgba;
- (void) pvert;
-
- ctx->PB->mono = GL_FALSE;
-
- if (ctx->Line.StippleFlag) {
- /* stippled */
-#define INTERP_XY 1
-#define INTERP_Z 1
-#define INTERP_RGB 1
-#define INTERP_ALPHA 1
-#define INTERP_TEX 1
-#define WIDE 1
-#define STIPPLE 1
-#define PLOT(X,Y) \
- { \
- pbx[count] = X; \
- pby[count] = Y; \
- pbz[count] = Z; \
- pbfog[count] = fog0; \
- pbs[count] = fragTexcoord[0]; \
- pbt[count] = fragTexcoord[1]; \
- pbu[count] = fragTexcoord[2]; \
- pbrgba[count][RCOMP] = FixedToInt(r0); \
- pbrgba[count][GCOMP] = FixedToInt(g0); \
- pbrgba[count][BCOMP] = FixedToInt(b0); \
- pbrgba[count][ACOMP] = FixedToInt(a0); \
- count++; \
- CHECK_FULL(count); \
- }
-#include "linetemp.h"
- }
- else {
- /* unstippled */
-#define INTERP_XY 1
-#define INTERP_Z 1
-#define INTERP_RGB 1
-#define INTERP_ALPHA 1
-#define INTERP_TEX 1
-#define WIDE 1
-#define PLOT(X,Y) \
- { \
- pbx[count] = X; \
- pby[count] = Y; \
- pbz[count] = Z; \
- pbfog[count] = fog0; \
- pbs[count] = fragTexcoord[0]; \
- pbt[count] = fragTexcoord[1]; \
- pbu[count] = fragTexcoord[2]; \
- pbrgba[count][RCOMP] = FixedToInt(r0); \
- pbrgba[count][GCOMP] = FixedToInt(g0); \
- pbrgba[count][BCOMP] = FixedToInt(b0); \
- pbrgba[count][ACOMP] = FixedToInt(a0); \
- count++; \
- CHECK_FULL(count); \
- }
-#include "linetemp.h"
- }
-
- ctx->PB->count = count;
- gl_flush_pb(ctx);
-}
-
-
-/* Smooth-shaded, multitextured, any width, maybe stippled, separate specular
- * color interpolation.
- */
-static void smooth_multitextured_line( GLcontext *ctx,
- GLuint vert0, GLuint vert1, GLuint pvert )
-{
- GLint count = ctx->PB->count;
- GLint *pbx = ctx->PB->x;
- GLint *pby = ctx->PB->y;
- GLdepth *pbz = ctx->PB->z;
- GLfixed *pbfog = ctx->PB->fog;
- GLchan (*pbrgba)[4] = ctx->PB->rgba;
- GLchan (*pbspec)[3] = ctx->PB->spec;
-
- (void) pvert;
-
- ctx->PB->mono = GL_FALSE;
-
- if (ctx->Line.StippleFlag) {
- /* stippled */
-#define INTERP_XY 1
-#define INTERP_Z 1
-#define INTERP_RGB 1
-#define INTERP_SPEC 1
-#define INTERP_ALPHA 1
-#define INTERP_MULTITEX 1
-#define WIDE 1
-#define STIPPLE 1
-#define PLOT(X,Y) \
- { \
- GLuint u; \
- pbx[count] = X; \
- pby[count] = Y; \
- pbz[count] = Z; \
- pbfog[count] = fog0; \
- pbrgba[count][RCOMP] = FixedToInt(r0); \
- pbrgba[count][GCOMP] = FixedToInt(g0); \
- pbrgba[count][BCOMP] = FixedToInt(b0); \
- pbrgba[count][ACOMP] = FixedToInt(a0); \
- pbspec[count][RCOMP] = FixedToInt(sr0); \
- pbspec[count][GCOMP] = FixedToInt(sg0); \
- pbspec[count][BCOMP] = FixedToInt(sb0); \
- for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { \
- if (ctx->Texture.Unit[u].ReallyEnabled) { \
- ctx->PB->s[u][0] = fragTexcoord[u][0]; \
- ctx->PB->s[u][1] = fragTexcoord[u][1]; \
- ctx->PB->s[u][2] = fragTexcoord[u][2]; \
- ctx->PB->s[u][3] = fragTexcoord[u][3]; \
- } \
- } \
- count++; \
- CHECK_FULL(count); \
- }
-#include "linetemp.h"
- }
- else {
- /* unstippled */
-#define INTERP_XY 1
-#define INTERP_Z 1
-#define INTERP_RGB 1
-#define INTERP_SPEC 1
-#define INTERP_ALPHA 1
-#define INTERP_MULTITEX 1
-#define WIDE 1
-#define PLOT(X,Y) \
- { \
- GLuint u; \
- pbx[count] = X; \
- pby[count] = Y; \
- pbz[count] = Z; \
- pbfog[count] = fog0; \
- pbrgba[count][RCOMP] = FixedToInt(r0); \
- pbrgba[count][GCOMP] = FixedToInt(g0); \
- pbrgba[count][BCOMP] = FixedToInt(b0); \
- pbrgba[count][ACOMP] = FixedToInt(a0); \
- pbspec[count][RCOMP] = FixedToInt(sr0); \
- pbspec[count][GCOMP] = FixedToInt(sg0); \
- pbspec[count][BCOMP] = FixedToInt(sb0); \
- for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { \
- if (ctx->Texture.Unit[u].ReallyEnabled) { \
- ctx->PB->s[u][0] = fragTexcoord[u][0]; \
- ctx->PB->s[u][1] = fragTexcoord[u][1]; \
- ctx->PB->s[u][2] = fragTexcoord[u][2]; \
- ctx->PB->s[u][3] = fragTexcoord[u][3]; \
- } \
- } \
- count++; \
- CHECK_FULL(count); \
- }
-#include "linetemp.h"
- }
-
- ctx->PB->count = count;
- gl_flush_pb(ctx);
-}
-
-
-/* Flat-shaded, multitextured, any width, maybe stippled, separate specular
- * color interpolation.
- */
-static void flat_multitextured_line( GLcontext *ctx,
- GLuint vert0, GLuint vert1, GLuint pvert )
-{
- GLint count = ctx->PB->count;
- GLint *pbx = ctx->PB->x;
- GLint *pby = ctx->PB->y;
- GLdepth *pbz = ctx->PB->z;
- GLfixed *pbfog = ctx->PB->fog;
- GLchan (*pbrgba)[4] = ctx->PB->rgba;
- GLchan (*pbspec)[3] = ctx->PB->spec;
- GLchan *color = ctx->VB->ColorPtr->data[pvert];
- GLchan sRed = ctx->VB->SecondaryColorPtr->data ? ctx->VB->SecondaryColorPtr->data[pvert][0] : 0;
- GLchan sGreen = ctx->VB->SecondaryColorPtr->data ? ctx->VB->SecondaryColorPtr->data[pvert][1] : 0;
- GLchan sBlue = ctx->VB->SecondaryColorPtr->data ? ctx->VB->SecondaryColorPtr->data[pvert][2] : 0;
-
- (void) pvert;
-
- ctx->PB->mono = GL_FALSE;
-
- if (ctx->Line.StippleFlag) {
- /* stippled */
-#define INTERP_XY 1
-#define INTERP_Z 1
-#define INTERP_ALPHA 1
-#define INTERP_MULTITEX 1
-#define WIDE 1
-#define STIPPLE 1
-#define PLOT(X,Y) \
- { \
- GLuint u; \
- pbx[count] = X; \
- pby[count] = Y; \
- pbz[count] = Z; \
- pbfog[count] = fog0; \
- pbrgba[count][RCOMP] = color[0]; \
- pbrgba[count][GCOMP] = color[1]; \
- pbrgba[count][BCOMP] = color[2]; \
- pbrgba[count][ACOMP] = color[3]; \
- pbspec[count][RCOMP] = sRed; \
- pbspec[count][GCOMP] = sGreen; \
- pbspec[count][BCOMP] = sBlue; \
- for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { \
- if (ctx->Texture.Unit[u].ReallyEnabled) { \
- ctx->PB->s[u][0] = fragTexcoord[u][0]; \
- ctx->PB->s[u][1] = fragTexcoord[u][1]; \
- ctx->PB->s[u][2] = fragTexcoord[u][2]; \
- ctx->PB->s[u][3] = fragTexcoord[u][3]; \
- } \
- } \
- count++; \
- CHECK_FULL(count); \
- }
-#include "linetemp.h"
- }
- else {
- /* unstippled */
-#define INTERP_XY 1
-#define INTERP_Z 1
-#define INTERP_ALPHA 1
-#define INTERP_MULTITEX 1
-#define WIDE 1
-#define PLOT(X,Y) \
- { \
- GLuint u; \
- pbx[count] = X; \
- pby[count] = Y; \
- pbz[count] = Z; \
- pbfog[count] = fog0; \
- pbrgba[count][RCOMP] = color[0]; \
- pbrgba[count][GCOMP] = color[1]; \
- pbrgba[count][BCOMP] = color[2]; \
- pbrgba[count][ACOMP] = color[3]; \
- pbspec[count][RCOMP] = sRed; \
- pbspec[count][GCOMP] = sGreen; \
- pbspec[count][BCOMP] = sBlue; \
- for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { \
- if (ctx->Texture.Unit[u].ReallyEnabled) { \
- ctx->PB->s[u][0] = fragTexcoord[u][0]; \
- ctx->PB->s[u][1] = fragTexcoord[u][1]; \
- ctx->PB->s[u][2] = fragTexcoord[u][2]; \
- ctx->PB->s[u][3] = fragTexcoord[u][3]; \
- } \
- } \
- count++; \
- CHECK_FULL(count); \
- }
-#include "linetemp.h"
- }
-
- ctx->PB->count = count;
- gl_flush_pb(ctx);
-}
-
-
-
-
-/*
- * Antialiased RGBA line
- *
- * This AA line function isn't terribly efficient but it's pretty
- * straight-forward to understand. Also, it doesn't exactly conform
- * to the specification.
- */
-static void aa_rgba_line( GLcontext *ctx,
- GLuint vert0, GLuint vert1, GLuint pvert )
-{
-#define INTERP_RGBA 1
-#define PLOT(x, y) \
- { \
- PB_WRITE_RGBA_PIXEL( pb, (x), (y), z, fog0, \
- red, green, blue, coverage ); \
- }
-#include "lnaatemp.h"
-}
-
-/*
- * Antialiased Textured RGBA line
- *
- * This AA line function isn't terribly efficient but it's pretty
- * straight-forward to understand. Also, it doesn't exactly conform
- * to the specification.
- */
-static void aa_tex_rgba_line( GLcontext *ctx,
- GLuint vert0, GLuint vert1, GLuint pvert )
-{
-#define INTERP_RGBA 1
-#define INTERP_TEX 1
-#define PLOT(x, y) \
- { \
- PB_WRITE_TEX_PIXEL( pb, (x), (y), z, fog0, \
- red, green, blue, coverage, \
- fragTexcoord[0], fragTexcoord[1], fragTexcoord[2] ); \
- }
-#include "lnaatemp.h"
-}
-
-
-/*
- * Antialiased Multitextured RGBA line
- *
- * This AA line function isn't terribly efficient but it's pretty
- * straight-forward to understand. Also, it doesn't exactly conform
- * to the specification.
- */
-static void aa_multitex_rgba_line( GLcontext *ctx,
- GLuint vert0, GLuint vert1, GLuint pvert )
-{
-#define INTERP_RGBA 1
-#define INTERP_SPEC 1
-#define INTERP_MULTITEX 1
-#define PLOT(x, y) \
- { \
- PB_WRITE_MULTITEX_SPEC_PIXEL( pb, (x), (y), z, fog0, \
- red, green, blue, coverage, specRed, specGreen, specBlue, \
- fragTexcoord ); \
- }
-#include "lnaatemp.h"
-}
-
-
-/*
- * Antialiased CI line. Same comments for RGBA antialiased lines apply.
- */
-static void aa_ci_line( GLcontext *ctx,
- GLuint vert0, GLuint vert1, GLuint pvert )
-{
-#define INTERP_INDEX 1
-#define PLOT(x, y) \
- { \
- PB_WRITE_CI_PIXEL( pb, (x), (y), z, fog0, index + coverage ); \
- }
-#include "lnaatemp.h"
-}
-
-
-/*
- * Null rasterizer for measuring transformation speed.
- */
-static void null_line( GLcontext *ctx, GLuint v1, GLuint v2, GLuint pv )
-{
- (void) ctx;
- (void) v1;
- (void) v2;
- (void) pv;
-}
-
-
-
-#ifdef DEBUG
-void
-_mesa_print_line_function(GLcontext *ctx)
-{
- printf("Line Func == ");
- if (ctx->Driver.LineFunc == flat_ci_line)
- printf("flat_ci_line\n");
- else if (ctx->Driver.LineFunc == flat_ci_z_line)
- printf("flat_ci_z_line\n");
- else if (ctx->Driver.LineFunc == flat_rgba_line)
- printf("flat_rgba_line\n");
- else if (ctx->Driver.LineFunc == flat_rgba_z_line)
- printf("flat_rgba_z_line\n");
- else if (ctx->Driver.LineFunc == smooth_ci_line)
- printf("smooth_ci_line\n");
- else if (ctx->Driver.LineFunc == smooth_ci_z_line)
- printf("smooth_ci_z_line\n");
- else if (ctx->Driver.LineFunc == smooth_rgba_line)
- printf("smooth_rgba_line\n");
- else if (ctx->Driver.LineFunc == smooth_rgba_z_line)
- printf("smooth_rgba_z_line\n");
- else if (ctx->Driver.LineFunc == general_smooth_ci_line)
- printf("general_smooth_ci_line\n");
- else if (ctx->Driver.LineFunc == general_flat_ci_line)
- printf("general_flat_ci_line\n");
- else if (ctx->Driver.LineFunc == general_smooth_rgba_line)
- printf("general_smooth_rgba_line\n");
- else if (ctx->Driver.LineFunc == general_flat_rgba_line)
- printf("general_flat_rgba_line\n");
- else if (ctx->Driver.LineFunc == flat_textured_line)
- printf("flat_textured_line\n");
- else if (ctx->Driver.LineFunc == smooth_textured_line)
- printf("smooth_textured_line\n");
- else if (ctx->Driver.LineFunc == smooth_multitextured_line)
- printf("smooth_multitextured_line\n");
- else if (ctx->Driver.LineFunc == flat_multitextured_line)
- printf("flat_multitextured_line\n");
- else if (ctx->Driver.LineFunc == aa_rgba_line)
- printf("aa_rgba_line\n");
- else if (ctx->Driver.LineFunc == aa_tex_rgba_line)
- printf("aa_tex_rgba_line\n");
- else if (ctx->Driver.LineFunc == aa_multitex_rgba_line)
- printf("aa_multitex_rgba_line\n");
- else if (ctx->Driver.LineFunc == aa_ci_line)
- printf("aa_ci_line\n");
- else if (ctx->Driver.LineFunc == null_line)
- printf("null_line\n");
- else
- printf("Driver func %p\n", ctx->Driver.LineFunc);
-}
-#endif
-
-
-
-/*
- * Determine which line drawing function to use given the current
- * rendering context.
- *
- * Please update the summary flag _SWRAST_NEW_LINE if you add or remove
- * tests to this code.
- */
-void gl_set_line_function( GLcontext *ctx )
-{
- GLboolean rgbmode = ctx->Visual.RGBAflag;
- /* TODO: antialiased lines */
-
- if (ctx->RenderMode==GL_RENDER) {
- if (ctx->NoRaster) {
- ctx->Driver.LineFunc = null_line;
- return;
- }
- if (ctx->Driver.LineFunc) {
- /* Device driver will draw lines. */
- return;
- }
-
- if (ctx->Line.SmoothFlag) {
- /* antialiased lines */
- if (rgbmode) {
- if (ctx->Texture.ReallyEnabled) {
- if (ctx->Texture.MultiTextureEnabled
- || ctx->Light.Model.ColorControl==GL_SEPARATE_SPECULAR_COLOR
- || ctx->Fog.ColorSumEnabled)
- /* Multitextured! */
- ctx->Driver.LineFunc = aa_multitex_rgba_line;
- else
- ctx->Driver.LineFunc = aa_tex_rgba_line;
- } else {
- ctx->Driver.LineFunc = aa_rgba_line;
- }
- }
- else {
- ctx->Driver.LineFunc = aa_ci_line;
- }
- }
- else if (ctx->Texture.ReallyEnabled) {
- if (ctx->Texture.MultiTextureEnabled
- || ctx->Light.Model.ColorControl==GL_SEPARATE_SPECULAR_COLOR
- || ctx->Fog.ColorSumEnabled) {
- /* multi-texture and/or separate specular color */
- if (ctx->Light.ShadeModel==GL_SMOOTH)
- ctx->Driver.LineFunc = smooth_multitextured_line;
- else
- ctx->Driver.LineFunc = flat_multitextured_line;
- }
- else {
- if (ctx->Light.ShadeModel==GL_SMOOTH) {
- ctx->Driver.LineFunc = smooth_textured_line;
- }
- else {
- ctx->Driver.LineFunc = flat_textured_line;
- }
- }
- }
- else if (ctx->Line.Width!=1.0 || ctx->Line.StippleFlag
- || ctx->Line.SmoothFlag) {
- if (ctx->Light.ShadeModel==GL_SMOOTH) {
- if (rgbmode)
- ctx->Driver.LineFunc = general_smooth_rgba_line;
- else
- ctx->Driver.LineFunc = general_smooth_ci_line;
- }
- else {
- if (rgbmode)
- ctx->Driver.LineFunc = general_flat_rgba_line;
- else
- ctx->Driver.LineFunc = general_flat_ci_line;
- }
- }
- else {
- if (ctx->Light.ShadeModel==GL_SMOOTH) {
- /* Width==1, non-stippled, smooth-shaded */
- if (ctx->Depth.Test || ctx->Fog.Enabled) {
- if (rgbmode)
- ctx->Driver.LineFunc = smooth_rgba_z_line;
- else
- ctx->Driver.LineFunc = smooth_ci_z_line;
- }
- else {
- if (rgbmode)
- ctx->Driver.LineFunc = smooth_rgba_line;
- else
- ctx->Driver.LineFunc = smooth_ci_line;
- }
- }
- else {
- /* Width==1, non-stippled, flat-shaded */
- if (ctx->Depth.Test || ctx->Fog.Enabled) {
- if (rgbmode)
- ctx->Driver.LineFunc = flat_rgba_z_line;
- else
- ctx->Driver.LineFunc = flat_ci_z_line;
- }
- else {
- if (rgbmode)
- ctx->Driver.LineFunc = flat_rgba_line;
- else
- ctx->Driver.LineFunc = flat_ci_line;
- }
- }
- }
- }
- else if (ctx->RenderMode==GL_FEEDBACK) {
- ctx->Driver.LineFunc = gl_feedback_line;
- }
- else {
- /* GL_SELECT mode */
- ctx->Driver.LineFunc = gl_select_line;
- }
-
- /*_mesa_print_line_function(ctx);*/
-}
-/* $Id: lines.h,v 1.2 1999/11/11 01:22:27 brianp Exp $ */
+/* $Id: lines.h,v 1.3 2000/10/31 18:09:44 keithw Exp $ */
/*
* Mesa 3-D graphics library
extern void
_mesa_LineStipple( GLint factor, GLushort pattern );
-extern void
-gl_set_line_function( GLcontext *ctx );
-
#endif
-/* $Id: points.c,v 1.18 2000/10/30 13:32:01 keithw Exp $ */
+/* $Id: points.c,v 1.19 2000/10/31 18:09:44 keithw Exp $ */
/*
* Mesa 3-D graphics library
#include "feedback.h"
#include "macros.h"
#include "mmath.h"
-#include "pb.h"
#include "points.h"
-#include "span.h"
#include "texstate.h"
#include "types.h"
#include "vb.h"
ctx->NewState |= _NEW_POINT;
}
-
-/**********************************************************************/
-/***** Rasterization *****/
-/**********************************************************************/
-
-
-/*
- * There are 3 pairs (RGBA, CI) of point rendering functions:
- * 1. simple: size=1 and no special rasterization functions (fastest)
- * 2. size1: size=1 and any rasterization functions
- * 3. general: any size and rasterization functions (slowest)
- *
- * All point rendering functions take the same two arguments: first and
- * last which specify that the points specified by VB[first] through
- * VB[last] are to be rendered.
- */
-
-
-
-
-
-/*
- * CI points with size == 1.0
- */
-static void
-size1_ci_points( GLcontext *ctx, GLuint first, GLuint last )
-{
- struct vertex_buffer *VB = ctx->VB;
- struct pixel_buffer *PB = ctx->PB;
- GLfloat *win, *fog;
- GLint *pbx = PB->x, *pby = PB->y;
- GLdepth *pbz = PB->z;
- GLfixed *pbfog = PB->fog;
- GLuint *pbi = PB->index;
- GLuint pbcount = PB->count;
- GLuint i;
-
- win = &VB->Win.data[first][0];
- fog = &VB->FogCoordPtr->data[first];
-
- for (i = first; i <= last; i++) {
- if (VB->ClipMask[i] == 0) {
- pbx[pbcount] = (GLint) win[0];
- pby[pbcount] = (GLint) win[1];
- pbz[pbcount] = (GLint) (win[2] + ctx->PointZoffset);
- pbfog[pbcount] = FloatToFixed(fog[i]);
- pbi[pbcount] = VB->IndexPtr->data[i];
- pbcount++;
- }
- win += 3;
- }
- PB->count = pbcount;
- PB_CHECK_FLUSH(ctx, PB);
-}
-
-
-
-/*
- * RGBA points with size == 1.0
- */
-static void
-size1_rgba_points( GLcontext *ctx, GLuint first, GLuint last )
-{
- struct vertex_buffer *VB = ctx->VB;
- struct pixel_buffer *PB = ctx->PB;
- GLuint i;
-
- for (i = first; i <= last; i++) {
- if (VB->ClipMask[i] == 0) {
- GLint x, y, z;
- GLint fog;
- GLint red, green, blue, alpha;
-
- x = (GLint) VB->Win.data[i][0];
- y = (GLint) VB->Win.data[i][1];
- z = (GLint) (VB->Win.data[i][2] + ctx->PointZoffset);
-
- fog = FloatToFixed( VB->FogCoordPtr->data[i] );
-
- red = VB->ColorPtr->data[i][0];
- green = VB->ColorPtr->data[i][1];
- blue = VB->ColorPtr->data[i][2];
- alpha = VB->ColorPtr->data[i][3];
-
- PB_WRITE_RGBA_PIXEL( PB, x, y, z, fog, red, green, blue, alpha );
- }
- }
- PB_CHECK_FLUSH(ctx, PB);
-}
-
-
-
-/*
- * General CI points.
- */
-static void
-general_ci_points( GLcontext *ctx, GLuint first, GLuint last )
-{
- struct vertex_buffer *VB = ctx->VB;
- struct pixel_buffer *PB = ctx->PB;
- const GLint isize = (GLint) (ctx->Point.Size + 0.5F);
- GLint radius = isize >> 1;
- GLuint i;
-
- for (i = first; i <= last; i++) {
- if (VB->ClipMask[i] == 0) {
- GLint x0, x1, y0, y1;
- GLint ix, iy;
-
- GLint x = (GLint) VB->Win.data[i][0];
- GLint y = (GLint) VB->Win.data[i][1];
- GLint z = (GLint) (VB->Win.data[i][2] + ctx->PointZoffset);
-
- GLfixed fog = FloatToFixed( VB->FogCoordPtr->data[i] );
-
- if (isize & 1) {
- /* odd size */
- x0 = x - radius;
- x1 = x + radius;
- y0 = y - radius;
- y1 = y + radius;
- }
- else {
- /* even size */
- x0 = (GLint) (x + 1.5F) - radius;
- x1 = x0 + isize - 1;
- y0 = (GLint) (y + 1.5F) - radius;
- y1 = y0 + isize - 1;
- }
-
- PB_SET_INDEX( PB, VB->IndexPtr->data[i] );
-
- for (iy = y0; iy <= y1; iy++) {
- for (ix = x0; ix <= x1; ix++) {
- PB_WRITE_PIXEL( PB, ix, iy, z, fog );
- }
- }
- PB_CHECK_FLUSH(ctx,PB);
- }
- }
-}
-
-
-/*
- * General RGBA points.
- */
-static void
-general_rgba_points( GLcontext *ctx, GLuint first, GLuint last )
-{
- struct vertex_buffer *VB = ctx->VB;
- struct pixel_buffer *PB = ctx->PB;
- GLint isize = (GLint) (ctx->Point.Size + 0.5F);
- GLint radius = isize >> 1;
- GLuint i;
-
- for (i = first; i <= last; i++) {
- if (VB->ClipMask[i] == 0) {
- GLint x0, x1, y0, y1;
- GLint ix, iy;
-
- GLint x = (GLint) VB->Win.data[i][0];
- GLint y = (GLint) VB->Win.data[i][1];
- GLint z = (GLint) (VB->Win.data[i][2] + ctx->PointZoffset);
-
- GLfixed fog = FloatToFixed( VB->FogCoordPtr->data[i] );
-
- if (isize & 1) {
- /* odd size */
- x0 = x - radius;
- x1 = x + radius;
- y0 = y - radius;
- y1 = y + radius;
- }
- else {
- /* even size */
- x0 = (GLint) (x + 1.5F) - radius;
- x1 = x0 + isize - 1;
- y0 = (GLint) (y + 1.5F) - radius;
- y1 = y0 + isize - 1;
- }
-
- PB_SET_COLOR( PB,
- VB->ColorPtr->data[i][0],
- VB->ColorPtr->data[i][1],
- VB->ColorPtr->data[i][2],
- VB->ColorPtr->data[i][3] );
-
- for (iy = y0; iy <= y1; iy++) {
- for (ix = x0; ix <= x1; ix++) {
- PB_WRITE_PIXEL( PB, ix, iy, z, fog );
- }
- }
- PB_CHECK_FLUSH(ctx,PB);
- }
- }
-}
-
-
-
-
-/*
- * Textured RGBA points.
- */
-static void
-textured_rgba_points( GLcontext *ctx, GLuint first, GLuint last )
-{
- struct vertex_buffer *VB = ctx->VB;
- struct pixel_buffer *PB = ctx->PB;
- GLuint i;
-
- for (i = first; i <= last; i++) {
- if (VB->ClipMask[i] == 0) {
- GLint x0, x1, y0, y1;
- GLint ix, iy, radius;
- GLint red, green, blue, alpha;
- GLfloat s, t, u;
-
- GLint x = (GLint) VB->Win.data[i][0];
- GLint y = (GLint) VB->Win.data[i][1];
- GLint z = (GLint) (VB->Win.data[i][2] + ctx->PointZoffset);
- GLint isize = (GLint) (ctx->Point.Size + 0.5F);
-
- GLfixed fog = FloatToFixed( VB->FogCoordPtr->data[i] );
-
- if (isize < 1) {
- isize = 1;
- }
- radius = isize >> 1;
-
- if (isize & 1) {
- /* odd size */
- x0 = x - radius;
- x1 = x + radius;
- y0 = y - radius;
- y1 = y + radius;
- }
- else {
- /* even size */
- x0 = (GLint) (x + 1.5F) - radius;
- x1 = x0 + isize - 1;
- y0 = (GLint) (y + 1.5F) - radius;
- y1 = y0 + isize - 1;
- }
-
- red = VB->ColorPtr->data[i][0];
- green = VB->ColorPtr->data[i][1];
- blue = VB->ColorPtr->data[i][2];
- alpha = VB->ColorPtr->data[i][3];
-
- switch (VB->TexCoordPtr[0]->size) {
- case 4:
- s = VB->TexCoordPtr[0]->data[i][0]/VB->TexCoordPtr[0]->data[i][3];
- t = VB->TexCoordPtr[0]->data[i][1]/VB->TexCoordPtr[0]->data[i][3];
- u = VB->TexCoordPtr[0]->data[i][2]/VB->TexCoordPtr[0]->data[i][3];
- break;
- case 3:
- s = VB->TexCoordPtr[0]->data[i][0];
- t = VB->TexCoordPtr[0]->data[i][1];
- u = VB->TexCoordPtr[0]->data[i][2];
- break;
- case 2:
- s = VB->TexCoordPtr[0]->data[i][0];
- t = VB->TexCoordPtr[0]->data[i][1];
- u = 0.0;
- break;
- case 1:
- s = VB->TexCoordPtr[0]->data[i][0];
- t = 0.0;
- u = 0.0;
- break;
- default:
- /* should never get here */
- s = t = u = 0.0;
- gl_problem(ctx, "unexpected texcoord size in textured_rgba_points()");
- }
-
- for (iy = y0; iy <= y1; iy++) {
- for (ix = x0; ix <= x1; ix++) {
- PB_WRITE_TEX_PIXEL( PB, ix, iy, z, fog, red, green, blue, alpha,
- s, t, u );
- }
- }
-
- PB_CHECK_FLUSH(ctx, PB);
- }
- }
-}
-
-
-/*
- * Multitextured RGBA points.
- */
-static void
-multitextured_rgba_points( GLcontext *ctx, GLuint first, GLuint last )
-{
- struct vertex_buffer *VB = ctx->VB;
- struct pixel_buffer *PB = ctx->PB;
- GLuint i;
-
- for (i = first; i <= last; i++) {
- if (VB->ClipMask[i] == 0) {
- const GLint red = VB->ColorPtr->data[i][0];
- const GLint green = VB->ColorPtr->data[i][1];
- const GLint blue = VB->ColorPtr->data[i][2];
- const GLint alpha = VB->ColorPtr->data[i][3];
- const GLint sRed = VB->SecondaryColorPtr->data ? VB->SecondaryColorPtr->data[i][0] : 0;
- const GLint sGreen = VB->SecondaryColorPtr->data ? VB->SecondaryColorPtr->data[i][1] : 0;
- const GLint sBlue = VB->SecondaryColorPtr->data ? VB->SecondaryColorPtr->data[i][2] : 0;
- const GLint x = (GLint) VB->Win.data[i][0];
- const GLint y = (GLint) VB->Win.data[i][1];
- const GLint z = (GLint) (VB->Win.data[i][2] + ctx->PointZoffset);
- GLint x0, x1, y0, y1;
- GLint ix, iy;
- GLfloat texcoord[MAX_TEXTURE_UNITS][4];
- GLint radius, u;
- GLint isize = (GLint) (ctx->Point.Size + 0.5F);
-
- GLfixed fog = FloatToFixed( VB->FogCoordPtr->data[i] );
-
- if (isize < 1) {
- isize = 1;
- }
- radius = isize >> 1;
-
- if (isize & 1) {
- /* odd size */
- x0 = x - radius;
- x1 = x + radius;
- y0 = y - radius;
- y1 = y + radius;
- }
- else {
- /* even size */
- x0 = (GLint) (x + 1.5F) - radius;
- x1 = x0 + isize - 1;
- y0 = (GLint) (y + 1.5F) - radius;
- y1 = y0 + isize - 1;
- }
-
- for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
- if (ctx->Texture.Unit[u].ReallyEnabled) {
- switch (VB->TexCoordPtr[0]->size) {
- case 4:
- texcoord[u][0] = VB->TexCoordPtr[u]->data[i][0] /
- VB->TexCoordPtr[u]->data[i][3];
- texcoord[u][1] = VB->TexCoordPtr[u]->data[i][1] /
- VB->TexCoordPtr[u]->data[i][3];
- texcoord[u][2] = VB->TexCoordPtr[u]->data[i][2] /
- VB->TexCoordPtr[u]->data[i][3];
- break;
- case 3:
- texcoord[u][0] = VB->TexCoordPtr[u]->data[i][0];
- texcoord[u][1] = VB->TexCoordPtr[u]->data[i][1];
- texcoord[u][2] = VB->TexCoordPtr[u]->data[i][2];
- break;
- case 2:
- texcoord[u][0] = VB->TexCoordPtr[u]->data[i][0];
- texcoord[u][1] = VB->TexCoordPtr[u]->data[i][1];
- texcoord[u][2] = 0.0;
- break;
- case 1:
- texcoord[u][0] = VB->TexCoordPtr[u]->data[i][0];
- texcoord[u][1] = 0.0;
- texcoord[u][2] = 0.0;
- break;
- default:
- /* should never get here */
- gl_problem(ctx, "unexpected texcoord size");
- }
- }
- }
-
- for (iy = y0; iy <= y1; iy++) {
- for (ix = x0; ix <= x1; ix++) {
- PB_WRITE_MULTITEX_SPEC_PIXEL( PB, ix, iy, z, fog,
- red, green, blue, alpha,
- sRed, sGreen, sBlue,
- texcoord );
- }
- }
- PB_CHECK_FLUSH(ctx, PB);
- }
- }
-}
-
-
-/*
- * NOTES on aa point rasterization:
- *
- * Let d = distance of fragment center from vertex.
- * if d < rmin2 then
- * fragment has 100% coverage
- * else if d > rmax2 then
- * fragment has 0% coverage
- * else
- * fragement has % coverage = (d - rmin2) / (rmax2 - rmin2)
- */
-
-
-/*
- * Antialiased points with or without texture mapping.
- */
-static void
-antialiased_rgba_points( GLcontext *ctx, GLuint first, GLuint last )
-{
- struct vertex_buffer *VB = ctx->VB;
- struct pixel_buffer *PB = ctx->PB;
- const GLfloat radius = ctx->Point.Size * 0.5F;
- const GLfloat rmin = radius - 0.7071F; /* 0.7071 = sqrt(2)/2 */
- const GLfloat rmax = radius + 0.7071F;
- const GLfloat rmin2 = MAX2(0.0, rmin * rmin);
- const GLfloat rmax2 = rmax * rmax;
- const GLfloat cscale = 256.0F / (rmax2 - rmin2);
- GLuint i;
-
- if (ctx->Texture.ReallyEnabled) {
- for (i = first; i <= last; i++) {
- if (VB->ClipMask[i] == 0) {
- GLint x, y;
- GLfloat vx = VB->Win.data[i][0];
- GLfloat vy = VB->Win.data[i][1];
- const GLint xmin = (GLint) (vx - radius);
- const GLint xmax = (GLint) (vx + radius);
- const GLint ymin = (GLint) (vy - radius);
- const GLint ymax = (GLint) (vy + radius);
- const GLint z = (GLint) (VB->Win.data[i][2] + ctx->PointZoffset);
- const GLint red = VB->ColorPtr->data[i][0];
- const GLint green = VB->ColorPtr->data[i][1];
- const GLint blue = VB->ColorPtr->data[i][2];
- GLfloat texcoord[MAX_TEXTURE_UNITS][4];
- GLint u, alpha;
-
- GLfixed fog = FloatToFixed( VB->FogCoordPtr->data[i] );
-
- for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
- if (ctx->Texture.Unit[u].ReallyEnabled) {
- switch (VB->TexCoordPtr[0]->size) {
- case 4:
- texcoord[u][0] = VB->TexCoordPtr[u]->data[i][0] /
- VB->TexCoordPtr[u]->data[i][3];
- texcoord[u][1] = VB->TexCoordPtr[u]->data[i][1] /
- VB->TexCoordPtr[u]->data[i][3];
- texcoord[u][2] = VB->TexCoordPtr[u]->data[i][2] /
- VB->TexCoordPtr[u]->data[i][3];
- break;
- case 3:
- texcoord[u][0] = VB->TexCoordPtr[u]->data[i][0];
- texcoord[u][1] = VB->TexCoordPtr[u]->data[i][1];
- texcoord[u][2] = VB->TexCoordPtr[u]->data[i][2];
- break;
- case 2:
- texcoord[u][0] = VB->TexCoordPtr[u]->data[i][0];
- texcoord[u][1] = VB->TexCoordPtr[u]->data[i][1];
- texcoord[u][2] = 0.0;
- break;
- case 1:
- texcoord[u][0] = VB->TexCoordPtr[u]->data[i][0];
- texcoord[u][1] = 0.0;
- texcoord[u][2] = 0.0;
- break;
- default:
- /* should never get here */
- gl_problem(ctx, "unexpected texcoord size in antialiased_rgba_points()");
- }
- }
- }
-
- /* translate by a half pixel to simplify math below */
- vx -= 0.5F;
- vx -= 0.5F;
-
- for (y = ymin; y <= ymax; y++) {
- for (x = xmin; x <= xmax; x++) {
- const GLfloat dx = x - vx;
- const GLfloat dy = y - vy;
- const GLfloat dist2 = dx*dx + dy*dy;
- if (dist2 < rmax2) {
- alpha = VB->ColorPtr->data[i][3];
- if (dist2 >= rmin2) {
- GLint coverage = (GLint) (256.0F - (dist2 - rmin2) * cscale);
- /* coverage is in [0,256] */
- alpha = (alpha * coverage) >> 8;
- }
- if (ctx->Texture.MultiTextureEnabled) {
- PB_WRITE_MULTITEX_PIXEL( PB, x,y,z, fog,
- red, green, blue,
- alpha, texcoord );
- }
- else {
- PB_WRITE_TEX_PIXEL( PB, x,y,z, fog,
- red, green, blue, alpha,
- texcoord[0][0],
- texcoord[0][1],
- texcoord[0][2] );
- }
- }
- }
- }
-
- PB_CHECK_FLUSH(ctx,PB);
- }
- }
- }
- else {
- /* Not texture mapped */
- for (i=first;i<=last;i++) {
- if (VB->ClipMask[i]==0) {
- const GLint xmin = (GLint) (VB->Win.data[i][0] - 0.0 - radius);
- const GLint xmax = (GLint) (VB->Win.data[i][0] - 0.0 + radius);
- const GLint ymin = (GLint) (VB->Win.data[i][1] - 0.0 - radius);
- const GLint ymax = (GLint) (VB->Win.data[i][1] - 0.0 + radius);
- const GLint red = VB->ColorPtr->data[i][0];
- const GLint green = VB->ColorPtr->data[i][1];
- const GLint blue = VB->ColorPtr->data[i][2];
- const GLint z = (GLint) (VB->Win.data[i][2] + ctx->PointZoffset);
- GLint x, y;
-
- GLfixed fog = FloatToFixed( VB->FogCoordPtr->data[i] );
-
- /*
- printf("point %g, %g\n", VB->Win.data[i][0], VB->Win.data[i][1]);
- printf("%d..%d X %d..%d\n", xmin, xmax, ymin, ymax);
- */
- for (y = ymin; y <= ymax; y++) {
- for (x = xmin; x <= xmax; x++) {
- const GLfloat dx = x + 0.5F - VB->Win.data[i][0];
- const GLfloat dy = y + 0.5F - VB->Win.data[i][1];
- const GLfloat dist2 = dx*dx + dy*dy;
- if (dist2 < rmax2) {
- GLint alpha = VB->ColorPtr->data[i][3];
- if (dist2 >= rmin2) {
- GLint coverage = (GLint) (256.0F - (dist2 - rmin2) * cscale);
- /* coverage is in [0,256] */
- alpha = (alpha * coverage) >> 8;
- }
- PB_WRITE_RGBA_PIXEL(PB, x, y, z, fog,
- red, green, blue, alpha);
- }
- }
- }
- PB_CHECK_FLUSH(ctx,PB);
- }
- }
- }
-}
-
-
-
-/*
- * Null rasterizer for measuring transformation speed.
- */
-static void
-null_points( GLcontext *ctx, GLuint first, GLuint last )
-{
- (void) ctx;
- (void) first;
- (void) last;
-}
-
-
-
-/* Definition of the functions for GL_EXT_point_parameters */
-
-/* Calculates the distance attenuation formula of a vector of points in
- * eye space coordinates
- */
-static void
-dist3(GLfloat *out, GLuint first, GLuint last,
- const GLcontext *ctx, const GLvector4f *v)
-{
- GLuint stride = v->stride;
- const GLfloat *p = VEC_ELT(v, GLfloat, first);
- GLuint i;
-
- for (i = first ; i <= last ; i++, STRIDE_F(p, stride) ) {
- GLfloat dist = GL_SQRT(p[0]*p[0]+p[1]*p[1]+p[2]*p[2]);
- out[i] = 1.0F / (ctx->Point.Params[0] +
- dist * (ctx->Point.Params[1] +
- dist * ctx->Point.Params[2]));
- }
-}
-
-
-static void
-dist2(GLfloat *out, GLuint first, GLuint last,
- const GLcontext *ctx, const GLvector4f *v)
-{
- GLuint stride = v->stride;
- const GLfloat *p = VEC_ELT(v, GLfloat, first);
- GLuint i;
-
- for (i = first ; i <= last ; i++, STRIDE_F(p, stride) ) {
- GLfloat dist = GL_SQRT(p[0]*p[0]+p[1]*p[1]);
- out[i] = 1.0F / (ctx->Point.Params[0] +
- dist * (ctx->Point.Params[1] +
- dist * ctx->Point.Params[2]));
- }
-}
-
-
-typedef void (*dist_func)(GLfloat *out, GLuint first, GLuint last,
- const GLcontext *ctx, const GLvector4f *v);
-
-
-static dist_func eye_dist_tab[5] = {
- 0,
- 0,
- dist2,
- dist3,
- dist3
-};
-
-
-
-/*
- * Distance Attenuated General CI points.
- */
-static void
-dist_atten_general_ci_points( GLcontext *ctx, GLuint first, GLuint last )
-{
- struct vertex_buffer *VB = ctx->VB;
- struct pixel_buffer *PB = ctx->PB;
- GLfloat dist[VB_SIZE];
- const GLfloat psize = ctx->Point.Size;
- GLuint i;
-
- ASSERT(ctx->NeedEyeCoords);
- (eye_dist_tab[VB->EyePtr->size])( dist, first, last, ctx, VB->EyePtr );
-
-
- for (i=first;i<=last;i++) {
- if (VB->ClipMask[i]==0) {
- GLint x0, x1, y0, y1;
- GLint ix, iy;
- GLint isize, radius;
- GLint x = (GLint) VB->Win.data[i][0];
- GLint y = (GLint) VB->Win.data[i][1];
- GLint z = (GLint) (VB->Win.data[i][2] + ctx->PointZoffset);
- GLfloat dsize = psize * dist[i];
-
- GLfixed fog = FloatToFixed( VB->FogCoordPtr->data[i] );
-
- if (dsize >= ctx->Point.Threshold) {
- isize = (GLint) (MIN2(dsize, ctx->Point.MaxSize) + 0.5F);
- }
- else {
- isize = (GLint) (MAX2(ctx->Point.Threshold, ctx->Point.MinSize) + 0.5F);
- }
- radius = isize >> 1;
-
- if (isize & 1) {
- /* odd size */
- x0 = x - radius;
- x1 = x + radius;
- y0 = y - radius;
- y1 = y + radius;
- }
- else {
- /* even size */
- x0 = (GLint) (x + 1.5F) - radius;
- x1 = x0 + isize - 1;
- y0 = (GLint) (y + 1.5F) - radius;
- y1 = y0 + isize - 1;
- }
-
- PB_SET_INDEX( PB, VB->IndexPtr->data[i] );
-
- for (iy=y0;iy<=y1;iy++) {
- for (ix=x0;ix<=x1;ix++) {
- PB_WRITE_PIXEL( PB, ix, iy, z, fog );
- }
- }
- PB_CHECK_FLUSH(ctx,PB);
- }
- }
-}
-
-/*
- * Distance Attenuated General RGBA points.
- */
-static void
-dist_atten_general_rgba_points( GLcontext *ctx, GLuint first, GLuint last )
-{
- struct vertex_buffer *VB = ctx->VB;
- struct pixel_buffer *PB = ctx->PB;
- GLfloat dist[VB_SIZE];
- const GLfloat psize = ctx->Point.Size;
- GLuint i;
-
- ASSERT (ctx->NeedEyeCoords);
- (eye_dist_tab[VB->EyePtr->size])( dist, first, last, ctx, VB->EyePtr );
-
- for (i=first;i<=last;i++) {
- if (VB->ClipMask[i]==0) {
- GLint x0, x1, y0, y1;
- GLint ix, iy;
- GLint isize, radius;
- GLint x = (GLint) VB->Win.data[i][0];
- GLint y = (GLint) VB->Win.data[i][1];
- GLint z = (GLint) (VB->Win.data[i][2] + ctx->PointZoffset);
- GLfloat dsize=psize*dist[i];
- GLchan alpha;
- GLfixed fog = FloatToFixed( VB->FogCoordPtr->data[i] );
-
- if (dsize >= ctx->Point.Threshold) {
- isize = (GLint) (MIN2(dsize,ctx->Point.MaxSize)+0.5F);
- alpha = VB->ColorPtr->data[i][3];
- }
- else {
- isize = (GLint) (MAX2(ctx->Point.Threshold,ctx->Point.MinSize)+0.5F);
- dsize /= ctx->Point.Threshold;
- alpha = (GLint) (VB->ColorPtr->data[i][3]* (dsize*dsize));
- }
- radius = isize >> 1;
-
- if (isize & 1) {
- /* odd size */
- x0 = x - radius;
- x1 = x + radius;
- y0 = y - radius;
- y1 = y + radius;
- }
- else {
- /* even size */
- x0 = (GLint) (x + 1.5F) - radius;
- x1 = x0 + isize - 1;
- y0 = (GLint) (y + 1.5F) - radius;
- y1 = y0 + isize - 1;
- }
-
- PB_SET_COLOR( PB,
- VB->ColorPtr->data[i][0],
- VB->ColorPtr->data[i][1],
- VB->ColorPtr->data[i][2],
- alpha );
-
- for (iy = y0; iy <= y1; iy++) {
- for (ix = x0; ix <= x1; ix++) {
- PB_WRITE_PIXEL( PB, ix, iy, z, fog );
- }
- }
- PB_CHECK_FLUSH(ctx,PB);
- }
- }
-}
-
-/*
- * Distance Attenuated Textured RGBA points.
- */
-static void
-dist_atten_textured_rgba_points( GLcontext *ctx, GLuint first, GLuint last )
-{
- struct vertex_buffer *VB = ctx->VB;
- struct pixel_buffer *PB = ctx->PB;
- GLfloat dist[VB_SIZE];
- const GLfloat psize = ctx->Point.Size;
- GLuint i;
-
- ASSERT(ctx->NeedEyeCoords);
- (eye_dist_tab[VB->EyePtr->size])( dist, first, last, ctx, VB->EyePtr );
-
- for (i=first;i<=last;i++) {
- if (VB->ClipMask[i]==0) {
- const GLint x = (GLint) VB->Win.data[i][0];
- const GLint y = (GLint) VB->Win.data[i][1];
- const GLint z = (GLint) (VB->Win.data[i][2] + ctx->PointZoffset);
- const GLint red = VB->ColorPtr->data[i][0];
- const GLint green = VB->ColorPtr->data[i][1];
- const GLint blue = VB->ColorPtr->data[i][2];
- GLfloat texcoord[MAX_TEXTURE_UNITS][4];
- GLint x0, x1, y0, y1;
- GLint ix, iy, alpha, u;
- GLint isize, radius;
- GLfloat dsize = psize*dist[i];
-
- GLfixed fog = FloatToFixed( VB->FogCoordPtr->data[i] );
-
- /* compute point size and alpha */
- if (dsize >= ctx->Point.Threshold) {
- isize = (GLint) (MIN2(dsize, ctx->Point.MaxSize) + 0.5F);
- alpha = VB->ColorPtr->data[i][3];
- }
- else {
- isize = (GLint) (MAX2(ctx->Point.Threshold, ctx->Point.MinSize) + 0.5F);
- dsize /= ctx->Point.Threshold;
- alpha = (GLint) (VB->ColorPtr->data[i][3] * (dsize * dsize));
- }
- if (isize < 1) {
- isize = 1;
- }
- radius = isize >> 1;
-
- if (isize & 1) {
- /* odd size */
- x0 = x - radius;
- x1 = x + radius;
- y0 = y - radius;
- y1 = y + radius;
- }
- else {
- /* even size */
- x0 = (GLint) (x + 1.5F) - radius;
- x1 = x0 + isize - 1;
- y0 = (GLint) (y + 1.5F) - radius;
- y1 = y0 + isize - 1;
- }
-
- /* get texture coordinates */
- for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
- if (ctx->Texture.Unit[u].ReallyEnabled) {
- switch (VB->TexCoordPtr[0]->size) {
- case 4:
- texcoord[u][0] = VB->TexCoordPtr[u]->data[i][0] /
- VB->TexCoordPtr[u]->data[i][3];
- texcoord[u][1] = VB->TexCoordPtr[u]->data[i][1] /
- VB->TexCoordPtr[u]->data[i][3];
- texcoord[u][2] = VB->TexCoordPtr[u]->data[i][2] /
- VB->TexCoordPtr[u]->data[i][3];
- break;
- case 3:
- texcoord[u][0] = VB->TexCoordPtr[u]->data[i][0];
- texcoord[u][1] = VB->TexCoordPtr[u]->data[i][1];
- texcoord[u][2] = VB->TexCoordPtr[u]->data[i][2];
- break;
- case 2:
- texcoord[u][0] = VB->TexCoordPtr[u]->data[i][0];
- texcoord[u][1] = VB->TexCoordPtr[u]->data[i][1];
- texcoord[u][2] = 0.0;
- break;
- case 1:
- texcoord[u][0] = VB->TexCoordPtr[u]->data[i][0];
- texcoord[u][1] = 0.0;
- texcoord[u][2] = 0.0;
- break;
- default:
- /* should never get here */
- gl_problem(ctx, "unexpected texcoord size");
- }
- }
- }
-
- for (iy = y0; iy <= y1; iy++) {
- for (ix = x0; ix <= x1; ix++) {
- if (ctx->Texture.MultiTextureEnabled) {
- PB_WRITE_MULTITEX_PIXEL( PB, ix, iy, z, fog,
- red, green, blue, alpha,
- texcoord );
- }
- else {
- PB_WRITE_TEX_PIXEL( PB, ix, iy, z, fog,
- red, green, blue, alpha,
- texcoord[0][0],
- texcoord[0][1],
- texcoord[0][2] );
- }
- }
- }
- PB_CHECK_FLUSH(ctx,PB);
- }
- }
-}
-
-/*
- * Distance Attenuated Antialiased points with or without texture mapping.
- */
-static void
-dist_atten_antialiased_rgba_points( GLcontext *ctx, GLuint first, GLuint last )
-{
- struct vertex_buffer *VB = ctx->VB;
- struct pixel_buffer *PB = ctx->PB;
- GLfloat dist[VB_SIZE];
- const GLfloat psize = ctx->Point.Size;
- GLuint i;
-
- ASSERT(ctx->NeedEyeCoords);
- (eye_dist_tab[VB->EyePtr->size])( dist, first, last, ctx, VB->EyePtr );
-
- if (ctx->Texture.ReallyEnabled) {
- for (i=first;i<=last;i++) {
- if (VB->ClipMask[i]==0) {
- GLfloat radius, rmin, rmax, rmin2, rmax2, cscale, alphaf;
- GLint xmin, ymin, xmax, ymax;
- GLint x, y, z;
- GLint red, green, blue, alpha;
- GLfloat texcoord[MAX_TEXTURE_UNITS][4];
- GLfloat dsize = psize * dist[i];
- GLint u;
-
- GLfixed fog = FloatToFixed( VB->FogCoordPtr->data[i] );
-
- if (dsize >= ctx->Point.Threshold) {
- radius = MIN2(dsize, ctx->Point.MaxSize) * 0.5F;
- alphaf = 1.0F;
- }
- else {
- radius = (MAX2(ctx->Point.Threshold, ctx->Point.MinSize) * 0.5F);
- dsize /= ctx->Point.Threshold;
- alphaf = (dsize*dsize);
- }
- rmin = radius - 0.7071F; /* 0.7071 = sqrt(2)/2 */
- rmax = radius + 0.7071F;
- rmin2 = MAX2(0.0, rmin * rmin);
- rmax2 = rmax * rmax;
- cscale = 256.0F / (rmax2 - rmin2);
-
- xmin = (GLint) (VB->Win.data[i][0] - radius);
- xmax = (GLint) (VB->Win.data[i][0] + radius);
- ymin = (GLint) (VB->Win.data[i][1] - radius);
- ymax = (GLint) (VB->Win.data[i][1] + radius);
- z = (GLint) (VB->Win.data[i][2] + ctx->PointZoffset);
-
- red = VB->ColorPtr->data[i][0];
- green = VB->ColorPtr->data[i][1];
- blue = VB->ColorPtr->data[i][2];
-
- /* get texture coordinates */
- for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
- if (ctx->Texture.Unit[u].ReallyEnabled) {
- switch (VB->TexCoordPtr[0]->size) {
- case 4:
- texcoord[u][0] = VB->TexCoordPtr[u]->data[i][0] /
- VB->TexCoordPtr[u]->data[i][3];
- texcoord[u][1] = VB->TexCoordPtr[u]->data[i][1] /
- VB->TexCoordPtr[u]->data[i][3];
- texcoord[u][2] = VB->TexCoordPtr[u]->data[i][2] /
- VB->TexCoordPtr[u]->data[i][3];
- break;
- case 3:
- texcoord[u][0] = VB->TexCoordPtr[u]->data[i][0];
- texcoord[u][1] = VB->TexCoordPtr[u]->data[i][1];
- texcoord[u][2] = VB->TexCoordPtr[u]->data[i][2];
- break;
- case 2:
- texcoord[u][0] = VB->TexCoordPtr[u]->data[i][0];
- texcoord[u][1] = VB->TexCoordPtr[u]->data[i][1];
- texcoord[u][2] = 0.0;
- break;
- case 1:
- texcoord[u][0] = VB->TexCoordPtr[u]->data[i][0];
- texcoord[u][1] = 0.0;
- texcoord[u][2] = 0.0;
- break;
- default:
- /* should never get here */
- gl_problem(ctx, "unexpected texcoord size");
- }
- }
- }
-
- for (y = ymin; y <= ymax; y++) {
- for (x = xmin; x <= xmax; x++) {
- const GLfloat dx = x + 0.5F - VB->Win.data[i][0];
- const GLfloat dy = y + 0.5F - VB->Win.data[i][1];
- const GLfloat dist2 = dx*dx + dy*dy;
- if (dist2 < rmax2) {
- alpha = VB->ColorPtr->data[i][3];
- if (dist2 >= rmin2) {
- GLint coverage = (GLint) (256.0F - (dist2 - rmin2) * cscale);
- /* coverage is in [0,256] */
- alpha = (alpha * coverage) >> 8;
- }
- alpha = (GLint) (alpha * alphaf);
- if (ctx->Texture.MultiTextureEnabled) {
- PB_WRITE_MULTITEX_PIXEL( PB, x, y, z, fog,
- red, green, blue, alpha,
- texcoord );
- }
- else {
- PB_WRITE_TEX_PIXEL( PB, x,y,z, fog,
- red, green, blue, alpha,
- texcoord[0][0],
- texcoord[0][1],
- texcoord[0][2] );
- }
- }
- }
- }
- PB_CHECK_FLUSH(ctx,PB);
- }
- }
- }
- else {
- /* Not texture mapped */
- for (i = first; i <= last; i++) {
- if (VB->ClipMask[i] == 0) {
- GLfloat radius, rmin, rmax, rmin2, rmax2, cscale, alphaf;
- GLint xmin, ymin, xmax, ymax;
- GLint x, y, z;
- GLfixed fog;
- GLint red, green, blue, alpha;
- GLfloat dsize = psize * dist[i];
-
- if (dsize >= ctx->Point.Threshold) {
- radius = MIN2(dsize, ctx->Point.MaxSize) * 0.5F;
- alphaf = 1.0F;
- }
- else {
- radius = (MAX2(ctx->Point.Threshold, ctx->Point.MinSize) * 0.5F);
- dsize /= ctx->Point.Threshold;
- alphaf = dsize * dsize;
- }
- rmin = radius - 0.7071F; /* 0.7071 = sqrt(2)/2 */
- rmax = radius + 0.7071F;
- rmin2 = MAX2(0.0, rmin * rmin);
- rmax2 = rmax * rmax;
- cscale = 256.0F / (rmax2 - rmin2);
-
- xmin = (GLint) (VB->Win.data[i][0] - radius);
- xmax = (GLint) (VB->Win.data[i][0] + radius);
- ymin = (GLint) (VB->Win.data[i][1] - radius);
- ymax = (GLint) (VB->Win.data[i][1] + radius);
- z = (GLint) (VB->Win.data[i][2] + ctx->PointZoffset);
-
- fog = FloatToFixed( VB->FogCoordPtr->data[i] );
-
- red = VB->ColorPtr->data[i][0];
- green = VB->ColorPtr->data[i][1];
- blue = VB->ColorPtr->data[i][2];
-
- for (y = ymin; y <= ymax; y++) {
- for (x = xmin; x <= xmax; x++) {
- const GLfloat dx = x + 0.5F - VB->Win.data[i][0];
- const GLfloat dy = y + 0.5F - VB->Win.data[i][1];
- const GLfloat dist2 = dx * dx + dy * dy;
- if (dist2 < rmax2) {
- alpha = VB->ColorPtr->data[i][3];
- if (dist2 >= rmin2) {
- GLint coverage = (GLint) (256.0F - (dist2 - rmin2) * cscale);
- /* coverage is in [0,256] */
- alpha = (alpha * coverage) >> 8;
- }
- alpha = (GLint) (alpha * alphaf);
- PB_WRITE_RGBA_PIXEL(PB, x, y, z, fog,
- red, green, blue, alpha);
- }
- }
- }
- PB_CHECK_FLUSH(ctx,PB);
- }
- }
- }
-}
-
-
-#ifdef DEBUG
-void
-_mesa_print_points_function(GLcontext *ctx)
-{
- printf("Point Func == ");
- if (ctx->Driver.PointsFunc == size1_ci_points)
- printf("size1_ci_points\n");
- else if (ctx->Driver.PointsFunc == size1_rgba_points)
- printf("size1_rgba_points\n");
- else if (ctx->Driver.PointsFunc == general_ci_points)
- printf("general_ci_points\n");
- else if (ctx->Driver.PointsFunc == general_rgba_points)
- printf("general_rgba_points\n");
- else if (ctx->Driver.PointsFunc == textured_rgba_points)
- printf("textured_rgba_points\n");
- else if (ctx->Driver.PointsFunc == multitextured_rgba_points)
- printf("multitextured_rgba_points\n");
- else if (ctx->Driver.PointsFunc == antialiased_rgba_points)
- printf("antialiased_rgba_points\n");
- else if (ctx->Driver.PointsFunc == null_points)
- printf("null_points\n");
- else if (ctx->Driver.PointsFunc == dist_atten_general_ci_points)
- printf("dist_atten_general_ci_points\n");
- else if (ctx->Driver.PointsFunc == dist_atten_general_rgba_points)
- printf("dist_atten_general_rgba_points\n");
- else if (ctx->Driver.PointsFunc == dist_atten_textured_rgba_points)
- printf("dist_atten_textured_rgba_points\n");
- else if (ctx->Driver.PointsFunc == dist_atten_antialiased_rgba_points)
- printf("dist_atten_antialiased_rgba_points\n");
- else if (!ctx->Driver.PointsFunc)
- printf("NULL\n");
- else
- printf("Driver func %p\n", ctx->Driver.PointsFunc);
-}
-#endif
-
-
-/*
- * Examine the current context to determine which point drawing function
- * should be used.
- */
-void gl_set_point_function( GLcontext *ctx )
-{
- GLboolean rgbmode = ctx->Visual.RGBAflag;
-
- if (ctx->RenderMode==GL_RENDER) {
- if (ctx->NoRaster) {
- ctx->Driver.PointsFunc = null_points;
- return;
- }
- if (ctx->Driver.PointsFunc) {
- /* Device driver will draw points. */
- ctx->IndirectTriangles &= ~DD_POINT_SW_RASTERIZE;
- return;
- }
-
- if (!ctx->Point.Attenuated) {
- if (ctx->Point.SmoothFlag && rgbmode) {
- ctx->Driver.PointsFunc = antialiased_rgba_points;
- }
- else if (ctx->Texture.ReallyEnabled) {
- if (ctx->Texture.MultiTextureEnabled ||
- ctx->Light.Model.ColorControl==GL_SEPARATE_SPECULAR_COLOR ||
- ctx->Fog.ColorSumEnabled) {
- ctx->Driver.PointsFunc = multitextured_rgba_points;
- }
- else {
- ctx->Driver.PointsFunc = textured_rgba_points;
- }
- }
- else if (ctx->Point.Size==1.0) {
- /* size=1, any raster ops */
- if (rgbmode)
- ctx->Driver.PointsFunc = size1_rgba_points;
- else
- ctx->Driver.PointsFunc = size1_ci_points;
- }
- else {
- /* every other kind of point rendering */
- if (rgbmode)
- ctx->Driver.PointsFunc = general_rgba_points;
- else
- ctx->Driver.PointsFunc = general_ci_points;
- }
- }
- else if(ctx->Point.SmoothFlag && rgbmode) {
- ctx->Driver.PointsFunc = dist_atten_antialiased_rgba_points;
- }
- else if (ctx->Texture.ReallyEnabled) {
- ctx->Driver.PointsFunc = dist_atten_textured_rgba_points;
- }
- else {
- /* every other kind of point rendering */
- if (rgbmode)
- ctx->Driver.PointsFunc = dist_atten_general_rgba_points;
- else
- ctx->Driver.PointsFunc = dist_atten_general_ci_points;
- }
- }
- else if (ctx->RenderMode==GL_FEEDBACK) {
- ctx->Driver.PointsFunc = gl_feedback_points;
- }
- else {
- /* GL_SELECT mode */
- ctx->Driver.PointsFunc = gl_select_points;
- }
-
- /*_mesa_print_points_function(ctx);*/
-}
-
-/* $Id: points.h,v 1.2 1999/11/11 01:22:27 brianp Exp $ */
+/* $Id: points.h,v 1.3 2000/10/31 18:09:44 keithw Exp $ */
/*
* Mesa 3-D graphics library
_mesa_PointParameterfvEXT( GLenum pname, const GLfloat *params );
-extern void gl_set_point_function( GLcontext *ctx );
-
#endif
-/* $Id: state.c,v 1.38 2000/10/30 16:32:43 brianp Exp $ */
+/* $Id: state.c,v 1.39 2000/10/31 18:09:45 keithw Exp $ */
/*
* Mesa 3-D graphics library
#include "pixeltex.h"
#include "points.h"
#include "polygon.h"
-#include "quads.h"
#include "rastpos.h"
#include "readpix.h"
#include "rect.h"
#include "texobj.h"
#include "texstate.h"
#include "texture.h"
-#include "triangle.h"
#include "types.h"
#include "varray.h"
#include "vbfill.h"
#include "vbrender.h"
#include "winpos.h"
+#include "swrast/swrast.h"
#endif
* and triangle functions.
*/
if (ctx->IndirectTriangles & DD_SW_RASTERIZE) {
- gl_set_point_function(ctx);
- gl_set_line_function(ctx);
- gl_set_triangle_function(ctx);
- gl_set_quad_function(ctx);
+ _swrast_set_point_function(ctx);
+ _swrast_set_line_function(ctx);
+ _swrast_set_triangle_function(ctx);
+ _swrast_set_quad_function(ctx);
if ((ctx->IndirectTriangles &
(DD_TRI_SW_RASTERIZE|DD_QUAD_SW_RASTERIZE|DD_TRI_CULL)) ==
-/* $Id: stencil.c,v 1.21 2000/10/30 13:32:01 keithw Exp $ */
+/* $Id: stencil.c,v 1.22 2000/10/31 18:09:45 keithw Exp $ */
/*
* Mesa 3-D graphics library
#include "depth.h"
#include "macros.h"
#include "mem.h"
-#include "pb.h"
#include "stencil.h"
#include "types.h"
#include "enable.h"
}
}
-
-
-/* Stencil Logic:
-
-IF stencil test fails THEN
- Apply fail-op to stencil value
- Don't write the pixel (RGBA,Z)
-ELSE
- IF doing depth test && depth test fails THEN
- Apply zfail-op to stencil value
- Write RGBA and Z to appropriate buffers
- ELSE
- Apply zpass-op to stencil value
-ENDIF
-
-*/
-
-
-
-
-/*
- * Return the address of a stencil buffer value given the window coords:
- */
-#define STENCIL_ADDRESS(X,Y) \
- (ctx->DrawBuffer->Stencil + ctx->DrawBuffer->Width * (Y) + (X))
-
-
-
-/*
- * Apply the given stencil operator to the array of stencil values.
- * Don't touch stencil[i] if mask[i] is zero.
- * Input: n - size of stencil array
- * oper - the stencil buffer operator
- * stencil - array of stencil values
- * mask - array [n] of flag: 1=apply operator, 0=don't apply operator
- * Output: stencil - modified values
- */
-static void apply_stencil_op( const GLcontext *ctx, GLenum oper,
- GLuint n, GLstencil stencil[],
- const GLubyte mask[] )
-{
- const GLstencil ref = ctx->Stencil.Ref;
- const GLstencil wrtmask = ctx->Stencil.WriteMask;
- const GLstencil invmask = (GLstencil) (~ctx->Stencil.WriteMask);
- GLuint i;
-
- switch (oper) {
- case GL_KEEP:
- /* do nothing */
- break;
- case GL_ZERO:
- if (invmask==0) {
- for (i=0;i<n;i++) {
- if (mask[i]) {
- stencil[i] = 0;
- }
- }
- }
- else {
- for (i=0;i<n;i++) {
- if (mask[i]) {
- stencil[i] = (GLstencil) (stencil[i] & invmask);
- }
- }
- }
- break;
- case GL_REPLACE:
- if (invmask==0) {
- for (i=0;i<n;i++) {
- if (mask[i]) {
- stencil[i] = ref;
- }
- }
- }
- else {
- for (i=0;i<n;i++) {
- if (mask[i]) {
- GLstencil s = stencil[i];
- stencil[i] = (GLstencil) ((invmask & s ) | (wrtmask & ref));
- }
- }
- }
- break;
- case GL_INCR:
- if (invmask==0) {
- for (i=0;i<n;i++) {
- if (mask[i]) {
- GLstencil s = stencil[i];
- if (s < STENCIL_MAX) {
- stencil[i] = (GLstencil) (s+1);
- }
- }
- }
- }
- else {
- for (i=0;i<n;i++) {
- if (mask[i]) {
- /* VERIFY logic of adding 1 to a write-masked value */
- GLstencil s = stencil[i];
- if (s < STENCIL_MAX) {
- stencil[i] = (GLstencil) ((invmask & s) | (wrtmask & (s+1)));
- }
- }
- }
- }
- break;
- case GL_DECR:
- if (invmask==0) {
- for (i=0;i<n;i++) {
- if (mask[i]) {
- GLstencil s = stencil[i];
- if (s>0) {
- stencil[i] = (GLstencil) (s-1);
- }
- }
- }
- }
- else {
- for (i=0;i<n;i++) {
- if (mask[i]) {
- /* VERIFY logic of subtracting 1 to a write-masked value */
- GLstencil s = stencil[i];
- if (s>0) {
- stencil[i] = (GLstencil) ((invmask & s) | (wrtmask & (s-1)));
- }
- }
- }
- }
- break;
- case GL_INCR_WRAP_EXT:
- if (invmask==0) {
- for (i=0;i<n;i++) {
- if (mask[i]) {
- stencil[i]++;
- }
- }
- }
- else {
- for (i=0;i<n;i++) {
- if (mask[i]) {
- GLstencil s = stencil[i];
- stencil[i] = (GLstencil) ((invmask & s) | (wrtmask & (s+1)));
- }
- }
- }
- break;
- case GL_DECR_WRAP_EXT:
- if (invmask==0) {
- for (i=0;i<n;i++) {
- if (mask[i]) {
- stencil[i]--;
- }
- }
- }
- else {
- for (i=0;i<n;i++) {
- if (mask[i]) {
- GLstencil s = stencil[i];
- stencil[i] = (GLstencil) ((invmask & s) | (wrtmask & (s-1)));
- }
- }
- }
- break;
- case GL_INVERT:
- if (invmask==0) {
- for (i=0;i<n;i++) {
- if (mask[i]) {
- GLstencil s = stencil[i];
- stencil[i] = (GLstencil) ~s;
- }
- }
- }
- else {
- for (i=0;i<n;i++) {
- if (mask[i]) {
- GLstencil s = stencil[i];
- stencil[i] = (GLstencil) ((invmask & s) | (wrtmask & ~s));
- }
- }
- }
- break;
- default:
- gl_problem(ctx, "Bad stencil op in apply_stencil_op");
- }
-}
-
-
-
-
-/*
- * Apply stencil test to an array of stencil values (before depth buffering).
- * Input: n - number of pixels in the array
- * stencil - array of [n] stencil values
- * mask - array [n] of flag: 0=skip the pixel, 1=stencil the pixel
- * Output: mask - pixels which fail the stencil test will have their
- * mask flag set to 0.
- * stencil - updated stencil values (where the test passed)
- * Return: GL_FALSE = all pixels failed, GL_TRUE = zero or more pixels passed.
- */
-static GLboolean
-do_stencil_test( GLcontext *ctx, GLuint n, GLstencil stencil[],
- GLubyte mask[] )
-{
- GLubyte fail[PB_SIZE];
- GLboolean allfail = GL_FALSE;
- GLuint i;
- GLstencil r, s;
-
- ASSERT(n <= PB_SIZE);
-
- /*
- * Perform stencil test. The results of this operation are stored
- * in the fail[] array:
- * IF fail[i] is non-zero THEN
- * the stencil fail operator is to be applied
- * ELSE
- * the stencil fail operator is not to be applied
- * ENDIF
- */
- switch (ctx->Stencil.Function) {
- case GL_NEVER:
- /* always fail */
- for (i=0;i<n;i++) {
- if (mask[i]) {
- mask[i] = 0;
- fail[i] = 1;
- }
- else {
- fail[i] = 0;
- }
- }
- allfail = GL_TRUE;
- break;
- case GL_LESS:
- r = (GLstencil) (ctx->Stencil.Ref & ctx->Stencil.ValueMask);
- for (i=0;i<n;i++) {
- if (mask[i]) {
- s = (GLstencil) (stencil[i] & ctx->Stencil.ValueMask);
- if (r < s) {
- /* passed */
- fail[i] = 0;
- }
- else {
- fail[i] = 1;
- mask[i] = 0;
- }
- }
- else {
- fail[i] = 0;
- }
- }
- break;
- case GL_LEQUAL:
- r = (GLstencil) (ctx->Stencil.Ref & ctx->Stencil.ValueMask);
- for (i=0;i<n;i++) {
- if (mask[i]) {
- s = (GLstencil) (stencil[i] & ctx->Stencil.ValueMask);
- if (r <= s) {
- /* pass */
- fail[i] = 0;
- }
- else {
- fail[i] = 1;
- mask[i] = 0;
- }
- }
- else {
- fail[i] = 0;
- }
- }
- break;
- case GL_GREATER:
- r = (GLstencil) (ctx->Stencil.Ref & ctx->Stencil.ValueMask);
- for (i=0;i<n;i++) {
- if (mask[i]) {
- s = (GLstencil) (stencil[i] & ctx->Stencil.ValueMask);
- if (r > s) {
- /* passed */
- fail[i] = 0;
- }
- else {
- fail[i] = 1;
- mask[i] = 0;
- }
- }
- else {
- fail[i] = 0;
- }
- }
- break;
- case GL_GEQUAL:
- r = (GLstencil) (ctx->Stencil.Ref & ctx->Stencil.ValueMask);
- for (i=0;i<n;i++) {
- if (mask[i]) {
- s = (GLstencil) (stencil[i] & ctx->Stencil.ValueMask);
- if (r >= s) {
- /* passed */
- fail[i] = 0;
- }
- else {
- fail[i] = 1;
- mask[i] = 0;
- }
- }
- else {
- fail[i] = 0;
- }
- }
- break;
- case GL_EQUAL:
- r = (GLstencil) (ctx->Stencil.Ref & ctx->Stencil.ValueMask);
- for (i=0;i<n;i++) {
- if (mask[i]) {
- s = (GLstencil) (stencil[i] & ctx->Stencil.ValueMask);
- if (r == s) {
- /* passed */
- fail[i] = 0;
- }
- else {
- fail[i] = 1;
- mask[i] = 0;
- }
- }
- else {
- fail[i] = 0;
- }
- }
- break;
- case GL_NOTEQUAL:
- r = (GLstencil) (ctx->Stencil.Ref & ctx->Stencil.ValueMask);
- for (i=0;i<n;i++) {
- if (mask[i]) {
- s = (GLstencil) (stencil[i] & ctx->Stencil.ValueMask);
- if (r != s) {
- /* passed */
- fail[i] = 0;
- }
- else {
- fail[i] = 1;
- mask[i] = 0;
- }
- }
- else {
- fail[i] = 0;
- }
- }
- break;
- case GL_ALWAYS:
- /* always pass */
- for (i=0;i<n;i++) {
- fail[i] = 0;
- }
- break;
- default:
- gl_problem(ctx, "Bad stencil func in gl_stencil_span");
- return 0;
- }
-
- if (ctx->Stencil.FailFunc != GL_KEEP) {
- apply_stencil_op( ctx, ctx->Stencil.FailFunc, n, stencil, fail );
- }
-
- return !allfail;
-}
-
-
-
-
-/*
- * Apply stencil and depth testing to an array of pixels.
- * Hardware or software stencil buffer acceptable.
- * Input: n - number of pixels in the span
- * z - array [n] of z values
- * stencil - array [n] of stencil values
- * mask - array [n] of flags (1=test this pixel, 0=skip the pixel)
- * Output: stencil - modified stencil values
- * mask - array [n] of flags (1=stencil and depth test passed)
- * Return: GL_TRUE - all fragments failed the testing
- * GL_FALSE - one or more fragments passed the testing
- *
- */
-static GLboolean
-stencil_and_ztest_span( GLcontext *ctx, GLuint n, GLint x, GLint y,
- const GLdepth z[], GLstencil stencil[],
- GLubyte mask[] )
-{
- ASSERT(ctx->Stencil.Enabled);
- ASSERT(n <= PB_SIZE);
-
- /*
- * Apply the stencil test to the fragments.
- * failMask[i] is 1 if the stencil test failed.
- */
- if (do_stencil_test( ctx, n, stencil, mask ) == GL_FALSE) {
- /* all fragments failed the stencil test, we're done. */
- return GL_FALSE;
- }
-
-
- /*
- * Some fragments passed the stencil test, apply depth test to them
- * and apply Zpass and Zfail stencil ops.
- */
- if (ctx->Depth.Test==GL_FALSE) {
- /*
- * No depth buffer, just apply zpass stencil function to active pixels.
- */
- apply_stencil_op( ctx, ctx->Stencil.ZPassFunc, n, stencil, mask );
- }
- else {
- /*
- * Perform depth buffering, then apply zpass or zfail stencil function.
- */
- GLubyte passmask[MAX_WIDTH], failmask[MAX_WIDTH], oldmask[MAX_WIDTH];
- GLuint i;
-
- /* save the current mask bits */
- MEMCPY(oldmask, mask, n * sizeof(GLubyte));
-
- /* apply the depth test */
- _mesa_depth_test_span(ctx, n, x, y, z, mask);
-
- /* Set the stencil pass/fail flags according to result of depth testing.
- * if oldmask[i] == 0 then
- * Don't touch the stencil value
- * else if oldmask[i] and newmask[i] then
- * Depth test passed
- * else
- * assert(oldmask[i] && !newmask[i])
- * Depth test failed
- * endif
- */
- for (i=0;i<n;i++) {
- ASSERT(mask[i] == 0 || mask[i] == 1);
- passmask[i] = oldmask[i] & mask[i];
- failmask[i] = oldmask[i] & (mask[i] ^ 1);
- }
-
- /* apply the pass and fail operations */
- if (ctx->Stencil.ZFailFunc != GL_KEEP) {
- apply_stencil_op( ctx, ctx->Stencil.ZFailFunc, n, stencil, failmask );
- }
- if (ctx->Stencil.ZPassFunc != GL_KEEP) {
- apply_stencil_op( ctx, ctx->Stencil.ZPassFunc, n, stencil, passmask );
- }
- }
-
- return GL_TRUE; /* one or more fragments passed both tests */
-}
-
-
-
-/*
- * Apply stencil and depth testing to the span of pixels.
- * Both software and hardware stencil buffers are acceptable.
- * Input: n - number of pixels in the span
- * x, y - location of leftmost pixel in span
- * z - array [n] of z values
- * mask - array [n] of flags (1=test this pixel, 0=skip the pixel)
- * Output: mask - array [n] of flags (1=stencil and depth test passed)
- * Return: GL_TRUE - all fragments failed the testing
- * GL_FALSE - one or more fragments passed the testing
- *
- */
-GLboolean
-_mesa_stencil_and_ztest_span( GLcontext *ctx, GLuint n, GLint x, GLint y,
- const GLdepth z[], GLubyte mask[] )
-{
- GLstencil stencilRow[MAX_WIDTH];
- GLstencil *stencil;
- GLboolean result;
-
- ASSERT(ctx->Stencil.Enabled);
- ASSERT(n <= MAX_WIDTH);
-
- /* Get initial stencil values */
- if (ctx->Driver.WriteStencilSpan) {
- ASSERT(ctx->Driver.ReadStencilSpan);
- /* Get stencil values from the hardware stencil buffer */
- (*ctx->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 (ctx->Driver.WriteStencilSpan) {
- /* Write updated stencil values into hardware stencil buffer */
- (ctx->Driver.WriteStencilSpan)(ctx, n, x, y, stencil, mask );
- }
-
- return result;
-}
-
-
-
-
-/*
- * Apply the given stencil operator for each pixel in the array whose
- * mask flag is set. This is for software stencil buffers only.
- * Input: n - number of pixels in the span
- * x, y - array of [n] pixels
- * operator - the stencil buffer operator
- * mask - array [n] of flag: 1=apply operator, 0=don't apply operator
- */
-static void
-apply_stencil_op_to_pixels( const GLcontext *ctx,
- GLuint n, const GLint x[], const GLint y[],
- GLenum oper, const GLubyte mask[] )
-{
- const GLstencil ref = ctx->Stencil.Ref;
- const GLstencil wrtmask = ctx->Stencil.WriteMask;
- const GLstencil invmask = (GLstencil) (~ctx->Stencil.WriteMask);
- GLuint i;
-
- ASSERT(!ctx->Driver.WriteStencilSpan); /* software stencil buffer only! */
-
- switch (oper) {
- case GL_KEEP:
- /* do nothing */
- break;
- case GL_ZERO:
- if (invmask==0) {
- for (i=0;i<n;i++) {
- if (mask[i]) {
- GLstencil *sptr = STENCIL_ADDRESS( x[i], y[i] );
- *sptr = 0;
- }
- }
- }
- else {
- for (i=0;i<n;i++) {
- if (mask[i]) {
- GLstencil *sptr = STENCIL_ADDRESS( x[i], y[i] );
- *sptr = (GLstencil) (invmask & *sptr);
- }
- }
- }
- break;
- case GL_REPLACE:
- if (invmask==0) {
- for (i=0;i<n;i++) {
- if (mask[i]) {
- GLstencil *sptr = STENCIL_ADDRESS( x[i], y[i] );
- *sptr = ref;
- }
- }
- }
- else {
- for (i=0;i<n;i++) {
- if (mask[i]) {
- GLstencil *sptr = STENCIL_ADDRESS( x[i], y[i] );
- *sptr = (GLstencil) ((invmask & *sptr ) | (wrtmask & ref));
- }
- }
- }
- break;
- case GL_INCR:
- if (invmask==0) {
- for (i=0;i<n;i++) {
- if (mask[i]) {
- GLstencil *sptr = STENCIL_ADDRESS( x[i], y[i] );
- if (*sptr < STENCIL_MAX) {
- *sptr = (GLstencil) (*sptr + 1);
- }
- }
- }
- }
- else {
- for (i=0;i<n;i++) {
- if (mask[i]) {
- GLstencil *sptr = STENCIL_ADDRESS( x[i], y[i] );
- if (*sptr < STENCIL_MAX) {
- *sptr = (GLstencil) ((invmask & *sptr) | (wrtmask & (*sptr+1)));
- }
- }
- }
- }
- break;
- case GL_DECR:
- if (invmask==0) {
- for (i=0;i<n;i++) {
- if (mask[i]) {
- GLstencil *sptr = STENCIL_ADDRESS( x[i], y[i] );
- if (*sptr>0) {
- *sptr = (GLstencil) (*sptr - 1);
- }
- }
- }
- }
- else {
- for (i=0;i<n;i++) {
- if (mask[i]) {
- GLstencil *sptr = STENCIL_ADDRESS( x[i], y[i] );
- if (*sptr>0) {
- *sptr = (GLstencil) ((invmask & *sptr) | (wrtmask & (*sptr-1)));
- }
- }
- }
- }
- break;
- case GL_INCR_WRAP_EXT:
- if (invmask==0) {
- for (i=0;i<n;i++) {
- if (mask[i]) {
- GLstencil *sptr = STENCIL_ADDRESS( x[i], y[i] );
- *sptr = (GLstencil) (*sptr + 1);
- }
- }
- }
- else {
- for (i=0;i<n;i++) {
- if (mask[i]) {
- GLstencil *sptr = STENCIL_ADDRESS( x[i], y[i] );
- *sptr = (GLstencil) ((invmask & *sptr) | (wrtmask & (*sptr+1)));
- }
- }
- }
- break;
- case GL_DECR_WRAP_EXT:
- if (invmask==0) {
- for (i=0;i<n;i++) {
- if (mask[i]) {
- GLstencil *sptr = STENCIL_ADDRESS( x[i], y[i] );
- *sptr = (GLstencil) (*sptr - 1);
- }
- }
- }
- else {
- for (i=0;i<n;i++) {
- if (mask[i]) {
- GLstencil *sptr = STENCIL_ADDRESS( x[i], y[i] );
- *sptr = (GLstencil) ((invmask & *sptr) | (wrtmask & (*sptr-1)));
- }
- }
- }
- break;
- case GL_INVERT:
- if (invmask==0) {
- for (i=0;i<n;i++) {
- if (mask[i]) {
- GLstencil *sptr = STENCIL_ADDRESS( x[i], y[i] );
- *sptr = (GLstencil) (~*sptr);
- }
- }
- }
- else {
- for (i=0;i<n;i++) {
- if (mask[i]) {
- GLstencil *sptr = STENCIL_ADDRESS( x[i], y[i] );
- *sptr = (GLstencil) ((invmask & *sptr) | (wrtmask & ~*sptr));
- }
- }
- }
- break;
- default:
- gl_problem(ctx, "Bad stencilop in apply_stencil_op_to_pixels");
- }
-}
-
-
-
-/*
- * Apply stencil test to an array of pixels before depth buffering.
- * Used for software stencil buffer only.
- * Input: n - number of pixels in the span
- * x, y - array of [n] pixels to stencil
- * mask - array [n] of flag: 0=skip the pixel, 1=stencil the pixel
- * Output: mask - pixels which fail the stencil test will have their
- * mask flag set to 0.
- * Return: 0 = all pixels failed, 1 = zero or more pixels passed.
- */
-static GLboolean
-stencil_test_pixels( GLcontext *ctx, GLuint n,
- const GLint x[], const GLint y[], GLubyte mask[] )
-{
- GLubyte fail[PB_SIZE];
- GLstencil r, s;
- GLuint i;
- GLboolean allfail = GL_FALSE;
-
- ASSERT(!ctx->Driver.WriteStencilSpan); /* software stencil buffer only! */
-
- /*
- * Perform stencil test. The results of this operation are stored
- * in the fail[] array:
- * IF fail[i] is non-zero THEN
- * the stencil fail operator is to be applied
- * ELSE
- * the stencil fail operator is not to be applied
- * ENDIF
- */
-
- switch (ctx->Stencil.Function) {
- case GL_NEVER:
- /* always fail */
- for (i=0;i<n;i++) {
- if (mask[i]) {
- mask[i] = 0;
- fail[i] = 1;
- }
- else {
- fail[i] = 0;
- }
- }
- allfail = GL_TRUE;
- break;
- case GL_LESS:
- r = (GLstencil) (ctx->Stencil.Ref & ctx->Stencil.ValueMask);
- for (i=0;i<n;i++) {
- if (mask[i]) {
- GLstencil *sptr = STENCIL_ADDRESS(x[i],y[i]);
- s = (GLstencil) (*sptr & ctx->Stencil.ValueMask);
- if (r < s) {
- /* passed */
- fail[i] = 0;
- }
- else {
- fail[i] = 1;
- mask[i] = 0;
- }
- }
- else {
- fail[i] = 0;
- }
- }
- break;
- case GL_LEQUAL:
- r = (GLstencil) (ctx->Stencil.Ref & ctx->Stencil.ValueMask);
- for (i=0;i<n;i++) {
- if (mask[i]) {
- GLstencil *sptr = STENCIL_ADDRESS(x[i],y[i]);
- s = (GLstencil) (*sptr & ctx->Stencil.ValueMask);
- if (r <= s) {
- /* pass */
- fail[i] = 0;
- }
- else {
- fail[i] = 1;
- mask[i] = 0;
- }
- }
- else {
- fail[i] = 0;
- }
- }
- break;
- case GL_GREATER:
- r = (GLstencil) (ctx->Stencil.Ref & ctx->Stencil.ValueMask);
- for (i=0;i<n;i++) {
- if (mask[i]) {
- GLstencil *sptr = STENCIL_ADDRESS(x[i],y[i]);
- s = (GLstencil) (*sptr & ctx->Stencil.ValueMask);
- if (r > s) {
- /* passed */
- fail[i] = 0;
- }
- else {
- fail[i] = 1;
- mask[i] = 0;
- }
- }
- else {
- fail[i] = 0;
- }
- }
- break;
- case GL_GEQUAL:
- r = (GLstencil) (ctx->Stencil.Ref & ctx->Stencil.ValueMask);
- for (i=0;i<n;i++) {
- if (mask[i]) {
- GLstencil *sptr = STENCIL_ADDRESS(x[i],y[i]);
- s = (GLstencil) (*sptr & ctx->Stencil.ValueMask);
- if (r >= s) {
- /* passed */
- fail[i] = 0;
- }
- else {
- fail[i] = 1;
- mask[i] = 0;
- }
- }
- else {
- fail[i] = 0;
- }
- }
- break;
- case GL_EQUAL:
- r = (GLstencil) (ctx->Stencil.Ref & ctx->Stencil.ValueMask);
- for (i=0;i<n;i++) {
- if (mask[i]) {
- GLstencil *sptr = STENCIL_ADDRESS(x[i],y[i]);
- s = (GLstencil) (*sptr & ctx->Stencil.ValueMask);
- if (r == s) {
- /* passed */
- fail[i] = 0;
- }
- else {
- fail[i] = 1;
- mask[i] = 0;
- }
- }
- else {
- fail[i] = 0;
- }
- }
- break;
- case GL_NOTEQUAL:
- r = (GLstencil) (ctx->Stencil.Ref & ctx->Stencil.ValueMask);
- for (i=0;i<n;i++) {
- if (mask[i]) {
- GLstencil *sptr = STENCIL_ADDRESS(x[i],y[i]);
- s = (GLstencil) (*sptr & ctx->Stencil.ValueMask);
- if (r != s) {
- /* passed */
- fail[i] = 0;
- }
- else {
- fail[i] = 1;
- mask[i] = 0;
- }
- }
- else {
- fail[i] = 0;
- }
- }
- break;
- case GL_ALWAYS:
- /* always pass */
- for (i=0;i<n;i++) {
- fail[i] = 0;
- }
- break;
- default:
- gl_problem(ctx, "Bad stencil func in gl_stencil_pixels");
- return 0;
- }
-
- if (ctx->Stencil.FailFunc != GL_KEEP) {
- apply_stencil_op_to_pixels( ctx, n, x, y, ctx->Stencil.FailFunc, fail );
- }
-
- return !allfail;
-}
-
-
-
-
-/*
- * Apply stencil and depth testing to an array of pixels.
- * This is used both for software and hardware stencil buffers.
- *
- * The comments in this function are a bit sparse but the code is
- * almost identical to stencil_and_ztest_span(), which is well
- * commented.
- *
- * Input: n - number of pixels in the array
- * x, y - array of [n] pixel positions
- * 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_pixels( GLcontext *ctx,
- GLuint n, const GLint x[], const GLint y[],
- const GLdepth z[], GLubyte mask[] )
-{
- ASSERT(ctx->Stencil.Enabled);
- ASSERT(n <= PB_SIZE);
-
- if (ctx->Driver.WriteStencilPixels) {
- /*** Hardware stencil buffer ***/
- GLstencil stencil[PB_SIZE];
- GLubyte mask[PB_SIZE];
-
- ASSERT(ctx->Driver.ReadStencilPixels);
- (*ctx->Driver.ReadStencilPixels)(ctx, n, x, y, stencil);
-
-
- if (do_stencil_test( ctx, n, stencil, mask ) == GL_FALSE) {
- /* all fragments failed the stencil test, we're done. */
- return GL_FALSE;
- }
-
- if (ctx->Depth.Test == GL_FALSE) {
- apply_stencil_op( ctx, ctx->Stencil.ZPassFunc, n, stencil, mask );
- }
- else {
- GLubyte passmask[PB_SIZE], failmask[PB_SIZE], oldmask[PB_SIZE];
- GLuint i;
-
- MEMCPY(oldmask, mask, n * sizeof(GLubyte));
-
- _mesa_depth_test_pixels(ctx, n, x, y, z, mask);
-
- for (i=0;i<n;i++) {
- ASSERT(mask[i] == 0 || mask[i] == 1);
- passmask[i] = oldmask[i] & mask[i];
- failmask[i] = oldmask[i] & (mask[i] ^ 1);
- }
-
- if (ctx->Stencil.ZFailFunc != GL_KEEP) {
- apply_stencil_op( ctx, ctx->Stencil.ZFailFunc, n, stencil, failmask );
- }
- if (ctx->Stencil.ZPassFunc != GL_KEEP) {
- apply_stencil_op( ctx, ctx->Stencil.ZPassFunc, n, stencil, passmask );
- }
- }
-
- /* Write updated stencil values into hardware stencil buffer */
- (ctx->Driver.WriteStencilPixels)(ctx, n, x, y, stencil, mask );
-
- return GL_TRUE;
-
- }
- else {
- /*** Software stencil buffer ***/
-
- if (stencil_test_pixels(ctx, n, x, y, mask) == GL_FALSE) {
- /* all fragments failed the stencil test, we're done. */
- return GL_FALSE;
- }
-
-
- if (ctx->Depth.Test==GL_FALSE) {
- apply_stencil_op_to_pixels( ctx, n, x, y, ctx->Stencil.ZPassFunc, mask );
- }
- else {
- GLubyte passmask[PB_SIZE], failmask[PB_SIZE], oldmask[PB_SIZE];
- GLuint i;
-
- MEMCPY(oldmask, mask, n * sizeof(GLubyte));
-
- _mesa_depth_test_pixels(ctx, n, x, y, z, mask);
-
- for (i=0;i<n;i++) {
- ASSERT(mask[i] == 0 || mask[i] == 1);
- passmask[i] = oldmask[i] & mask[i];
- failmask[i] = oldmask[i] & (mask[i] ^ 1);
- }
-
- if (ctx->Stencil.ZFailFunc != GL_KEEP) {
- apply_stencil_op_to_pixels( ctx, n, x, y,
- ctx->Stencil.ZFailFunc, failmask );
- }
- if (ctx->Stencil.ZPassFunc != GL_KEEP) {
- apply_stencil_op_to_pixels( ctx, n, x, y,
- ctx->Stencil.ZPassFunc, passmask );
- }
- }
-
- return GL_TRUE; /* one or more fragments passed both tests */
- }
-}
-
-
-
-/*
- * Return a span of stencil values from the stencil buffer.
- * Used for glRead/CopyPixels
- * Input: n - how many pixels
- * x,y - location of first pixel
- * Output: stencil - the array of stencil values
- */
-void
-_mesa_read_stencil_span( GLcontext *ctx,
- GLint n, GLint x, GLint y, GLstencil stencil[] )
-{
- if (y < 0 || y >= ctx->DrawBuffer->Height ||
- x + n <= 0 || x >= ctx->DrawBuffer->Width) {
- /* span is completely outside framebuffer */
- return; /* undefined values OK */
- }
-
- if (x < 0) {
- GLint dx = -x;
- x = 0;
- n -= dx;
- stencil += dx;
- }
- if (x + n > ctx->DrawBuffer->Width) {
- GLint dx = x + n - ctx->DrawBuffer->Width;
- n -= dx;
- }
- if (n <= 0) {
- return;
- }
-
-
- ASSERT(n >= 0);
- if (ctx->Driver.ReadStencilSpan) {
- (*ctx->Driver.ReadStencilSpan)( ctx, (GLuint) n, x, y, stencil );
- }
- else if (ctx->DrawBuffer->Stencil) {
- const GLstencil *s = STENCIL_ADDRESS( x, y );
-#if STENCIL_BITS == 8
- MEMCPY( stencil, s, n * sizeof(GLstencil) );
-#else
- GLuint i;
- for (i=0;i<n;i++)
- stencil[i] = s[i];
-#endif
- }
-}
-
-
-
-/*
- * Write a span of stencil values to the stencil buffer.
- * Used for glDraw/CopyPixels
- * Input: n - how many pixels
- * x, y - location of first pixel
- * stencil - the array of stencil values
- */
-void
-_mesa_write_stencil_span( GLcontext *ctx, GLint n, GLint x, GLint y,
- const GLstencil stencil[] )
-{
- if (y < 0 || y >= ctx->DrawBuffer->Height ||
- x + n <= 0 || x >= ctx->DrawBuffer->Width) {
- /* span is completely outside framebuffer */
- return; /* undefined values OK */
- }
-
- if (x < 0) {
- GLint dx = -x;
- x = 0;
- n -= dx;
- stencil += dx;
- }
- if (x + n > ctx->DrawBuffer->Width) {
- GLint dx = x + n - ctx->DrawBuffer->Width;
- n -= dx;
- }
- if (n <= 0) {
- return;
- }
-
- if (ctx->Driver.WriteStencilSpan) {
- (*ctx->Driver.WriteStencilSpan)( ctx, n, x, y, stencil, NULL );
- }
- else if (ctx->DrawBuffer->Stencil) {
- GLstencil *s = STENCIL_ADDRESS( x, y );
-#if STENCIL_BITS == 8
- MEMCPY( s, stencil, n * sizeof(GLstencil) );
-#else
- GLuint i;
- for (i=0;i<n;i++)
- s[i] = stencil[i];
-#endif
- }
-}
-
-
-
-/*
- * Allocate a new stencil buffer. If there's an old one it will be
- * deallocated first. The new stencil buffer will be uninitialized.
- */
-void
-_mesa_alloc_stencil_buffer( GLcontext *ctx )
-{
- GLuint buffersize = ctx->DrawBuffer->Width * ctx->DrawBuffer->Height;
-
- /* deallocate current stencil buffer if present */
- if (ctx->DrawBuffer->Stencil) {
- FREE(ctx->DrawBuffer->Stencil);
- ctx->DrawBuffer->Stencil = NULL;
- }
-
- /* allocate new stencil buffer */
- ctx->DrawBuffer->Stencil = (GLstencil *) MALLOC(buffersize * sizeof(GLstencil));
- if (!ctx->DrawBuffer->Stencil) {
- /* out of memory */
- _mesa_set_enable( ctx, GL_STENCIL_TEST, GL_FALSE );
- gl_error( ctx, GL_OUT_OF_MEMORY, "_mesa_alloc_stencil_buffer" );
- }
-}
-
-
-
-/*
- * Clear the software (malloc'd) stencil buffer.
- */
-static void
-clear_software_stencil_buffer( GLcontext *ctx )
-{
- if (ctx->Visual.StencilBits==0 || !ctx->DrawBuffer->Stencil) {
- /* no stencil buffer */
- return;
- }
-
- if (ctx->Scissor.Enabled) {
- /* clear scissor region only */
- const GLint width = ctx->DrawBuffer->Xmax - ctx->DrawBuffer->Xmin;
- if (ctx->Stencil.WriteMask != STENCIL_MAX) {
- /* must apply mask to the clear */
- GLint y;
- for (y = ctx->DrawBuffer->Ymin; y < ctx->DrawBuffer->Ymax; y++) {
- const GLstencil mask = ctx->Stencil.WriteMask;
- const GLstencil invMask = ~mask;
- const GLstencil clearVal = (ctx->Stencil.Clear & mask);
- GLstencil *stencil = STENCIL_ADDRESS( ctx->DrawBuffer->Xmin, y );
- GLint i;
- for (i = 0; i < width; i++) {
- stencil[i] = (stencil[i] & invMask) | clearVal;
- }
- }
- }
- else {
- /* no masking */
- GLint y;
- for (y = ctx->DrawBuffer->Ymin; y < ctx->DrawBuffer->Ymax; y++) {
- GLstencil *stencil = STENCIL_ADDRESS( ctx->DrawBuffer->Xmin, y );
-#if STENCIL_BITS==8
- MEMSET( stencil, ctx->Stencil.Clear, width * sizeof(GLstencil) );
-#else
- GLint i;
- for (i = 0; i < width; i++)
- stencil[x] = ctx->Stencil.Clear;
-#endif
- }
- }
- }
- else {
- /* clear whole stencil buffer */
- if (ctx->Stencil.WriteMask != STENCIL_MAX) {
- /* must apply mask to the clear */
- const GLuint n = ctx->DrawBuffer->Width * ctx->DrawBuffer->Height;
- GLstencil *stencil = ctx->DrawBuffer->Stencil;
- const GLstencil mask = ctx->Stencil.WriteMask;
- const GLstencil invMask = ~mask;
- const GLstencil clearVal = (ctx->Stencil.Clear & mask);
- GLuint i;
- for (i = 0; i < n; i++) {
- stencil[i] = (stencil[i] & invMask) | clearVal;
- }
- }
- else {
- /* clear whole buffer without masking */
- const GLuint n = ctx->DrawBuffer->Width * ctx->DrawBuffer->Height;
- GLstencil *stencil = ctx->DrawBuffer->Stencil;
-
-#if STENCIL_BITS==8
- MEMSET(stencil, ctx->Stencil.Clear, n * sizeof(GLstencil) );
-#else
- GLuint i;
- for (i = 0; i < n; i++) {
- stencil[i] = ctx->Stencil.Clear;
- }
-#endif
- }
- }
-}
-
-
-
-/*
- * Clear the hardware (in graphics card) stencil buffer.
- * This is done with the Driver.WriteStencilSpan() and Driver.ReadStencilSpan()
- * functions.
- * Actually, if there is a hardware stencil buffer it really should have
- * been cleared in Driver.Clear()! However, if the hardware does not
- * support scissored clears or masked clears (i.e. glStencilMask) then
- * we have to use the span-based functions.
- */
-static void
-clear_hardware_stencil_buffer( GLcontext *ctx )
-{
- ASSERT(ctx->Driver.WriteStencilSpan);
- ASSERT(ctx->Driver.ReadStencilSpan);
-
- if (ctx->Scissor.Enabled) {
- /* clear scissor region only */
- const GLint x = ctx->DrawBuffer->Xmin;
- const GLint width = ctx->DrawBuffer->Xmax - ctx->DrawBuffer->Xmin;
- if (ctx->Stencil.WriteMask != STENCIL_MAX) {
- /* must apply mask to the clear */
- GLint y;
- for (y = ctx->DrawBuffer->Ymin; y < ctx->DrawBuffer->Ymax; y++) {
- const GLstencil mask = ctx->Stencil.WriteMask;
- const GLstencil invMask = ~mask;
- const GLstencil clearVal = (ctx->Stencil.Clear & mask);
- GLstencil stencil[MAX_WIDTH];
- GLint i;
- (*ctx->Driver.ReadStencilSpan)(ctx, x, y, width, stencil);
- for (i = 0; i < width; i++) {
- stencil[i] = (stencil[i] & invMask) | clearVal;
- }
- (*ctx->Driver.WriteStencilSpan)(ctx, x, y, width, stencil, NULL);
- }
- }
- else {
- /* no masking */
- GLstencil stencil[MAX_WIDTH];
- GLint y, i;
- for (i = 0; i < width; i++) {
- stencil[i] = ctx->Stencil.Clear;
- }
- for (y = ctx->DrawBuffer->Ymin; y < ctx->DrawBuffer->Ymax; y++) {
- (*ctx->Driver.WriteStencilSpan)(ctx, x, y, width, stencil, NULL);
- }
- }
- }
- else {
- /* clear whole stencil buffer */
- if (ctx->Stencil.WriteMask != STENCIL_MAX) {
- /* must apply mask to the clear */
- const GLstencil mask = ctx->Stencil.WriteMask;
- const GLstencil invMask = ~mask;
- const GLstencil clearVal = (ctx->Stencil.Clear & mask);
- const GLint width = ctx->DrawBuffer->Width;
- const GLint height = ctx->DrawBuffer->Height;
- const GLint x = ctx->DrawBuffer->Xmin;
- GLint y;
- for (y = 0; y < height; y++) {
- GLstencil stencil[MAX_WIDTH];
- GLuint i;
- (*ctx->Driver.ReadStencilSpan)(ctx, x, y, width, stencil);
- for (i = 0; i < width; i++) {
- stencil[i] = (stencil[i] & invMask) | clearVal;
- }
- (*ctx->Driver.WriteStencilSpan)(ctx, x, y, width, stencil, NULL);
- }
- }
- else {
- /* clear whole buffer without masking */
- const GLint width = ctx->DrawBuffer->Width;
- const GLint height = ctx->DrawBuffer->Width;
- const GLint x = ctx->DrawBuffer->Xmin;
- GLstencil stencil[MAX_WIDTH];
- GLint y, i;
- for (i = 0; i < width; i++) {
- stencil[i] = ctx->Stencil.Clear;
- }
- for (y = 0; y < height; y++) {
- (*ctx->Driver.WriteStencilSpan)(ctx, x, y, width, stencil, NULL);
- }
- }
- }
-}
-
-
-
-/*
- * Clear the stencil buffer.
- */
-void
-_mesa_clear_stencil_buffer( GLcontext *ctx )
-{
- if (ctx->Driver.WriteStencilSpan) {
- ASSERT(ctx->Driver.ReadStencilSpan);
- clear_hardware_stencil_buffer(ctx);
- }
- else {
- clear_software_stencil_buffer(ctx);
- }
-}
-
-/* $Id: stencil.h,v 1.6 2000/04/11 21:26:57 brianp Exp $ */
+/* $Id: stencil.h,v 1.7 2000/10/31 18:09:45 keithw Exp $ */
/*
* Mesa 3-D graphics library
-extern GLboolean
-_mesa_stencil_and_ztest_span( GLcontext *ctx, GLuint n, GLint x, GLint y,
- const GLdepth z[], GLubyte mask[] );
-
-extern GLboolean
-_mesa_stencil_and_ztest_pixels( GLcontext *ctx, GLuint n,
- const GLint x[], const GLint y[],
- const GLdepth z[], GLubyte mask[] );
-
-
-extern void
-_mesa_read_stencil_span( GLcontext *ctx, GLint n, GLint x, GLint y,
- GLstencil stencil[] );
-
-
-extern void
-_mesa_write_stencil_span( GLcontext *ctx, GLint n, GLint x, GLint y,
- const GLstencil stencil[] );
-
-
-extern void
-_mesa_alloc_stencil_buffer( GLcontext *ctx );
-
-
-extern void
-_mesa_clear_stencil_buffer( GLcontext *ctx );
-
-
#endif
-/* $Id: teximage.c,v 1.57 2000/10/30 16:32:43 brianp Exp $ */
+/* $Id: teximage.c,v 1.58 2000/10/31 18:09:45 keithw Exp $ */
/*
* Mesa 3-D graphics library
#include "macros.h"
#include "mem.h"
#include "mmath.h"
-#include "span.h"
#include "state.h"
#include "teximage.h"
#include "texstate.h"
-/* $Id: texstate.c,v 1.19 2000/10/30 13:32:01 keithw Exp $ */
+/* $Id: texstate.c,v 1.20 2000/10/31 18:09:45 keithw Exp $ */
/*
* Mesa 3-D graphics library
#include "texture.h"
#include "types.h"
#include "xform.h"
+#include "swrast/swrast.h"
#endif
for (t = ctx->Shared->DirtyTexObjList; t; t = next) {
next = t->NextDirty;
_mesa_test_texobj_completeness(ctx, t);
- _mesa_set_texture_sampler(t);
+ _swrast_set_texture_sampler(t); /* swrast should do this internally */
t->NextDirty = NULL;
t->Dirty = GL_FALSE;
}