diff options
author | Keith Whitwell <[email protected]> | 2000-10-31 18:09:44 +0000 |
---|---|---|
committer | Keith Whitwell <[email protected]> | 2000-10-31 18:09:44 +0000 |
commit | 724abeb058ca9372c5a9b9e38ee43dde1accaa41 (patch) | |
tree | 964fba63d45d79ff38dab32f8e8614e68d46e4bc /src/mesa/main | |
parent | e3a051e0538a605551f4d58294c94f5eb00ed07f (diff) |
Moved the software rasterizer to a new directory.
Diffstat (limited to 'src/mesa/main')
-rw-r--r-- | src/mesa/main/Makefile.X11 | 42 | ||||
-rw-r--r-- | src/mesa/main/accum.c | 459 | ||||
-rw-r--r-- | src/mesa/main/accum.h | 10 | ||||
-rw-r--r-- | src/mesa/main/blend.c | 634 | ||||
-rw-r--r-- | src/mesa/main/blend.h | 15 | ||||
-rw-r--r-- | src/mesa/main/buffers.c | 204 | ||||
-rw-r--r-- | src/mesa/main/colortab.c | 3 | ||||
-rw-r--r-- | src/mesa/main/context.c | 22 | ||||
-rw-r--r-- | src/mesa/main/convolve.c | 3 | ||||
-rw-r--r-- | src/mesa/main/dd.h | 7 | ||||
-rw-r--r-- | src/mesa/main/depth.c | 1602 | ||||
-rw-r--r-- | src/mesa/main/depth.h | 38 | ||||
-rw-r--r-- | src/mesa/main/drawpix.c | 844 | ||||
-rw-r--r-- | src/mesa/main/drawpix.h | 10 | ||||
-rw-r--r-- | src/mesa/main/feedback.c | 25 | ||||
-rw-r--r-- | src/mesa/main/fog.c | 160 | ||||
-rw-r--r-- | src/mesa/main/fog.h | 33 | ||||
-rw-r--r-- | src/mesa/main/lines.c | 1138 | ||||
-rw-r--r-- | src/mesa/main/lines.h | 5 | ||||
-rw-r--r-- | src/mesa/main/points.c | 1158 | ||||
-rw-r--r-- | src/mesa/main/points.h | 4 | ||||
-rw-r--r-- | src/mesa/main/state.c | 13 | ||||
-rw-r--r-- | src/mesa/main/stencil.c | 1268 | ||||
-rw-r--r-- | src/mesa/main/stencil.h | 30 | ||||
-rw-r--r-- | src/mesa/main/teximage.c | 3 | ||||
-rw-r--r-- | src/mesa/main/texstate.c | 5 |
26 files changed, 116 insertions, 7619 deletions
diff --git a/src/mesa/main/Makefile.X11 b/src/mesa/main/Makefile.X11 index fb8d0b2b14d..32326d6d5ed 100644 --- a/src/mesa/main/Makefile.X11 +++ b/src/mesa/main/Makefile.X11 @@ -1,4 +1,4 @@ -# $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 @@ -20,10 +20,8 @@ LIBDIR = ../lib CORE_SOURCES = \ - aatriangle.c \ accum.c \ alpha.c \ - alphabuf.c \ attrib.c \ bbox.c \ bitmap.c \ @@ -52,6 +50,7 @@ CORE_SOURCES = \ glapinoop.c \ glthread.c \ hash.c \ + highpc.c \ hint.c \ image.c \ imaging.c \ @@ -59,23 +58,21 @@ CORE_SOURCES = \ 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 \ @@ -85,7 +82,6 @@ CORE_SOURCES = \ texture.c \ texutil.c \ translate.c \ - triangle.c \ varray.c \ vb.c \ vbcull.c \ @@ -97,11 +93,39 @@ CORE_SOURCES = \ 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 \ diff --git a/src/mesa/main/accum.c b/src/mesa/main/accum.c index a2c8d048804..a43472fb595 100644 --- a/src/mesa/main/accum.c +++ b/src/mesa/main/accum.c @@ -1,4 +1,4 @@ -/* $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 @@ -33,68 +33,12 @@ #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 @@ -111,42 +55,11 @@ _mesa_ClearAccum( GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha ) } - -/* - * 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"); @@ -155,22 +68,6 @@ _mesa_Accum( GLenum op, GLfloat value ) 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 ); @@ -189,351 +86,7 @@ _mesa_Accum( GLenum op, GLfloat value ) 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 ); } diff --git a/src/mesa/main/accum.h b/src/mesa/main/accum.h index a2ff4803116..18865849566 100644 --- a/src/mesa/main/accum.h +++ b/src/mesa/main/accum.h @@ -1,4 +1,4 @@ -/* $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 @@ -33,14 +33,6 @@ extern void -_mesa_alloc_accum_buffer( GLcontext *ctx ); - - -extern void -_mesa_clear_accum_buffer( GLcontext *ctx ); - - -extern void _mesa_Accum( GLenum op, GLfloat value ); diff --git a/src/mesa/main/blend.c b/src/mesa/main/blend.c index 4f20d269ac2..91267cda7f0 100644 --- a/src/mesa/main/blend.c +++ b/src/mesa/main/blend.c @@ -1,4 +1,4 @@ -/* $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 @@ -30,13 +30,10 @@ #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 @@ -322,632 +319,3 @@ _mesa_BlendColor( GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha ) 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 ); -} diff --git a/src/mesa/main/blend.h b/src/mesa/main/blend.h index 7df8845668e..f495673b4f5 100644 --- a/src/mesa/main/blend.h +++ b/src/mesa/main/blend.h @@ -1,4 +1,4 @@ -/* $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 @@ -31,19 +31,6 @@ #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 ); diff --git a/src/mesa/main/buffers.c b/src/mesa/main/buffers.c index c50590f6123..fe0382dfe9a 100644 --- a/src/mesa/main/buffers.c +++ b/src/mesa/main/buffers.c @@ -1,4 +1,4 @@ -/* $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 @@ -30,7 +30,6 @@ #else #include "glheader.h" #include "accum.h" -#include "alphabuf.h" #include "buffers.h" #include "context.h" #include "depth.h" @@ -41,6 +40,7 @@ #include "stencil.h" #include "state.h" #include "types.h" +#include "swrast/swrast.h" #endif @@ -86,172 +86,12 @@ _mesa_ClearColor( GLclampf red, GLclampf green, -/* - * 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) @@ -298,29 +138,9 @@ _mesa_Clear( GLbitfield mask ) } #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 ); } } @@ -561,17 +381,5 @@ _mesa_ResizeBuffersMESA( void ) 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 ); } diff --git a/src/mesa/main/colortab.c b/src/mesa/main/colortab.c index c629c76de5e..18f50766c65 100644 --- a/src/mesa/main/colortab.c +++ b/src/mesa/main/colortab.c @@ -1,4 +1,4 @@ -/* $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 @@ -35,7 +35,6 @@ #include "macros.h" #include "mem.h" #include "mmath.h" -#include "span.h" #endif diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c index 998ebeeb058..047858af1d0 100644 --- a/src/mesa/main/context.c +++ b/src/mesa/main/context.c @@ -1,4 +1,4 @@ -/* $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 @@ -49,7 +49,6 @@ #include "matrix.h" #include "mem.h" #include "mmath.h" -#include "pb.h" #include "pipeline.h" #include "shade.h" #include "simple_list.h" @@ -66,6 +65,7 @@ #include "vbxform.h" #include "vertices.h" #include "xform.h" +#include "swrast/swrast.h" #endif #if defined(MESA_TRACE) @@ -445,7 +445,6 @@ one_time_init( void ) gl_init_clip(); gl_init_eval(); - _mesa_init_fog(); _mesa_init_math(); gl_init_lists(); gl_init_shade(); @@ -1470,9 +1469,8 @@ _mesa_initialize_context( GLcontext *ctx, 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; } @@ -1486,7 +1484,7 @@ _mesa_initialize_context( GLcontext *ctx, ctx->Shared = alloc_shared_state(); if (!ctx->Shared) { ALIGN_FREE( ctx->VB ); - FREE( ctx->PB ); + _swrast_destroy_context( ctx ); return GL_FALSE; } } @@ -1517,7 +1515,7 @@ _mesa_initialize_context( GLcontext *ctx, 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; } @@ -1545,7 +1543,7 @@ _mesa_initialize_context( GLcontext *ctx, 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 ); } @@ -1561,7 +1559,7 @@ _mesa_initialize_context( GLcontext *ctx, 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; @@ -1575,7 +1573,7 @@ _mesa_initialize_context( GLcontext *ctx, 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 ); @@ -1649,7 +1647,7 @@ _mesa_free_context_data( GLcontext *ctx ) } } - FREE( ctx->PB ); + _swrast_destroy_context( ctx ); if (ctx->input != ctx->VB->IM) gl_immediate_free( ctx->input ); diff --git a/src/mesa/main/convolve.c b/src/mesa/main/convolve.c index 2a5f5f9b2d2..6b24600f31d 100644 --- a/src/mesa/main/convolve.c +++ b/src/mesa/main/convolve.c @@ -1,4 +1,4 @@ -/* $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 @@ -41,7 +41,6 @@ #include "convolve.h" #include "context.h" #include "image.h" -#include "span.h" #include "types.h" #endif diff --git a/src/mesa/main/dd.h b/src/mesa/main/dd.h index e196a241aba..1b0aa8bc9c8 100644 --- a/src/mesa/main/dd.h +++ b/src/mesa/main/dd.h @@ -1,4 +1,4 @@ -/* $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 @@ -474,6 +474,11 @@ struct dd_function_table { /* 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: diff --git a/src/mesa/main/depth.c b/src/mesa/main/depth.c index a5d9c34efc7..9689b795f12 100644 --- a/src/mesa/main/depth.c +++ b/src/mesa/main/depth.c @@ -1,4 +1,4 @@ -/* $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 @@ -34,7 +34,6 @@ #include "depth.h" #include "macros.h" #include "mem.h" -#include "pb.h" #include "types.h" #endif @@ -125,1602 +124,3 @@ _mesa_DepthMask( GLboolean flag ) } - -/**********************************************************************/ -/***** 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--; - } - } - } - } -} diff --git a/src/mesa/main/depth.h b/src/mesa/main/depth.h index ef176005d4e..152d355caf2 100644 --- a/src/mesa/main/depth.h +++ b/src/mesa/main/depth.h @@ -1,4 +1,4 @@ -/* $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 @@ -49,41 +49,5 @@ _mesa_DepthMask( GLboolean flag ); -/* - * 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 diff --git a/src/mesa/main/drawpix.c b/src/mesa/main/drawpix.c index 3e030ede61a..afdc5952734 100644 --- a/src/mesa/main/drawpix.c +++ b/src/mesa/main/drawpix.c @@ -1,4 +1,4 @@ -/* $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 @@ -31,819 +31,17 @@ #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); - } -} - /* @@ -872,42 +70,16 @@ _mesa_DrawPixels( GLsizei width, GLsizei height, 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) { diff --git a/src/mesa/main/drawpix.h b/src/mesa/main/drawpix.h index 3a0fd57bc17..b67731a831a 100644 --- a/src/mesa/main/drawpix.h +++ b/src/mesa/main/drawpix.h @@ -1,4 +1,4 @@ -/* $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 @@ -31,14 +31,6 @@ #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 ); diff --git a/src/mesa/main/feedback.c b/src/mesa/main/feedback.c index 7f911cddddf..438fbae4699 100644 --- a/src/mesa/main/feedback.c +++ b/src/mesa/main/feedback.c @@ -1,4 +1,4 @@ -/* $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 @@ -36,7 +36,6 @@ #include "macros.h" #include "mmath.h" #include "types.h" -#include "triangle.h" #endif @@ -205,6 +204,24 @@ static void feedback_vertex( GLcontext *ctx, GLuint v, GLuint pv ) } +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. @@ -212,7 +229,7 @@ static void feedback_vertex( GLcontext *ctx, GLuint v, GLuint pv ) 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 */ @@ -308,7 +325,7 @@ void gl_select_triangle( GLcontext *ctx, { 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 ); diff --git a/src/mesa/main/fog.c b/src/mesa/main/fog.c index 72c0ff48492..b7795759f55 100644 --- a/src/mesa/main/fog.c +++ b/src/mesa/main/fog.c @@ -1,4 +1,4 @@ -/* $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 @@ -148,10 +148,6 @@ _mesa_Fogfv( GLenum pname, const GLfloat *params ) -void -_mesa_init_fog( void ) -{ -} static GLvector1f *get_fogcoord_ptr( GLcontext *ctx, GLvector1f *tmp ) { @@ -249,157 +245,3 @@ _mesa_make_win_fog_coords( struct vertex_buffer *VB ) 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 ); -} - diff --git a/src/mesa/main/fog.h b/src/mesa/main/fog.h index 5841d750bee..15ccbc9966c 100644 --- a/src/mesa/main/fog.h +++ b/src/mesa/main/fog.h @@ -1,4 +1,4 @@ -/* $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 @@ -49,39 +49,8 @@ extern void _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 diff --git a/src/mesa/main/lines.c b/src/mesa/main/lines.c index f3255601ca8..a3c49f1d121 100644 --- a/src/mesa/main/lines.c +++ b/src/mesa/main/lines.c @@ -1,4 +1,4 @@ -/* $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 @@ -35,7 +35,6 @@ #include "lines.h" #include "macros.h" #include "mmath.h" -#include "pb.h" #include "texstate.h" #include "types.h" #include "vb.h" @@ -82,1138 +81,3 @@ _mesa_LineStipple( GLint factor, GLushort pattern ) } - -/**********************************************************************/ -/***** 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);*/ -} diff --git a/src/mesa/main/lines.h b/src/mesa/main/lines.h index 36a6bed1f75..60437c447a3 100644 --- a/src/mesa/main/lines.h +++ b/src/mesa/main/lines.h @@ -1,4 +1,4 @@ -/* $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 @@ -38,8 +38,5 @@ _mesa_LineWidth( GLfloat width ); extern void _mesa_LineStipple( GLint factor, GLushort pattern ); -extern void -gl_set_line_function( GLcontext *ctx ); - #endif diff --git a/src/mesa/main/points.c b/src/mesa/main/points.c index 5f42cd0371c..ccac502ab16 100644 --- a/src/mesa/main/points.c +++ b/src/mesa/main/points.c @@ -1,4 +1,4 @@ -/* $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 @@ -33,9 +33,7 @@ #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" @@ -123,1157 +121,3 @@ _mesa_PointParameterfvEXT( GLenum pname, const GLfloat *params) 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);*/ -} - diff --git a/src/mesa/main/points.h b/src/mesa/main/points.h index b024ffbdf85..0da8c11ba1a 100644 --- a/src/mesa/main/points.h +++ b/src/mesa/main/points.h @@ -1,4 +1,4 @@ -/* $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 @@ -47,7 +47,5 @@ extern void _mesa_PointParameterfvEXT( GLenum pname, const GLfloat *params ); -extern void gl_set_point_function( GLcontext *ctx ); - #endif diff --git a/src/mesa/main/state.c b/src/mesa/main/state.c index 32727d09864..600d4a2c5a1 100644 --- a/src/mesa/main/state.c +++ b/src/mesa/main/state.c @@ -1,4 +1,4 @@ -/* $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 @@ -68,7 +68,6 @@ #include "pixeltex.h" #include "points.h" #include "polygon.h" -#include "quads.h" #include "rastpos.h" #include "readpix.h" #include "rect.h" @@ -80,12 +79,12 @@ #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 @@ -1002,10 +1001,10 @@ void gl_update_state( GLcontext *ctx ) * 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)) == diff --git a/src/mesa/main/stencil.c b/src/mesa/main/stencil.c index 2dcecced563..93a83034922 100644 --- a/src/mesa/main/stencil.c +++ b/src/mesa/main/stencil.c @@ -1,4 +1,4 @@ -/* $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 @@ -33,7 +33,6 @@ #include "depth.h" #include "macros.h" #include "mem.h" -#include "pb.h" #include "stencil.h" #include "types.h" #include "enable.h" @@ -181,1268 +180,3 @@ _mesa_StencilOp(GLenum fail, GLenum zfail, GLenum zpass) } } - - -/* 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); - } -} - diff --git a/src/mesa/main/stencil.h b/src/mesa/main/stencil.h index 5aac9db9a13..e85a2bdc4af 100644 --- a/src/mesa/main/stencil.h +++ b/src/mesa/main/stencil.h @@ -1,4 +1,4 @@ -/* $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 @@ -49,32 +49,4 @@ _mesa_StencilOp( GLenum fail, GLenum zfail, GLenum zpass ); -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 diff --git a/src/mesa/main/teximage.c b/src/mesa/main/teximage.c index e47387fcb5b..c3ca132f408 100644 --- a/src/mesa/main/teximage.c +++ b/src/mesa/main/teximage.c @@ -1,4 +1,4 @@ -/* $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 @@ -35,7 +35,6 @@ #include "macros.h" #include "mem.h" #include "mmath.h" -#include "span.h" #include "state.h" #include "teximage.h" #include "texstate.h" diff --git a/src/mesa/main/texstate.c b/src/mesa/main/texstate.c index 61dd4a20168..ed254e7fb83 100644 --- a/src/mesa/main/texstate.c +++ b/src/mesa/main/texstate.c @@ -1,4 +1,4 @@ -/* $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 @@ -41,6 +41,7 @@ #include "texture.h" #include "types.h" #include "xform.h" +#include "swrast/swrast.h" #endif @@ -1683,7 +1684,7 @@ void gl_update_dirty_texobjs( GLcontext *ctx ) 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; } |