s_span.c revision f1e236987829393c81dc86ea19cb49eefe190317
1f1e236987829393c81dc86ea19cb49eefe190317Brian Paul/* $Id: s_span.c,v 1.25 2002/01/28 00:07:33 brianp Exp $ */
2e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
3e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell/*
4e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Mesa 3-D graphics library
59927f1978da8530416f699d084dda099720e43e6Brian Paul * Version:  4.1
622144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes *
79927f1978da8530416f699d084dda099720e43e6Brian Paul * Copyright (C) 1999-2002  Brian Paul   All Rights Reserved.
822144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes *
9e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Permission is hereby granted, free of charge, to any person obtaining a
10e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * copy of this software and associated documentation files (the "Software"),
11e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * to deal in the Software without restriction, including without limitation
12e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * and/or sell copies of the Software, and to permit persons to whom the
14e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Software is furnished to do so, subject to the following conditions:
1522144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes *
16e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * The above copyright notice and this permission notice shall be included
17e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * in all copies or substantial portions of the Software.
1822144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes *
19e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
22e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
23e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */
26e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
27e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
28e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell/*
29e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * pixel span rasterization:
30e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * These functions implement the rasterization pipeline.
31e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */
32e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
33e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
34e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "glheader.h"
35e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "colormac.h"
3671340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul#include "context.h"
37e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "macros.h"
38e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "mem.h"
39e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
40e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_alpha.h"
41e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_alphabuf.h"
42e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_blend.h"
43cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell#include "s_context.h"
44e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_depth.h"
45e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_fog.h"
46e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_logic.h"
47e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_masking.h"
48e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_scissor.h"
49e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_span.h"
50e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_stencil.h"
51e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_texture.h"
52e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
532a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul
542a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul/*
552a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul * Init span's Z interpolation values to the RasterPos Z.
562a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul * Used during setup for glDraw/CopyPixels.
572a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul */
582a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paulvoid
592a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul_mesa_span_default_z( GLcontext *ctx, struct sw_span *span )
602a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul{
612a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   if (ctx->Visual.depthBits <= 16)
622a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      span->z = FloatToFixed(ctx->Current.RasterPos[2] * ctx->DepthMax);
632a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   else
642a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      span->z = (GLint) (ctx->Current.RasterPos[2] * ctx->DepthMax);
652a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   span->zStep = 0;
662a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   span->interpMask |= SPAN_Z;
672a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul}
682a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul
692a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul
702a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul/*
712a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul * Init span's fog interpolation values to the RasterPos fog.
722a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul * Used during setup for glDraw/CopyPixels.
732a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul */
742a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paulvoid
752a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul_mesa_span_default_fog( GLcontext *ctx, struct sw_span *span )
762a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul{
772a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   if (ctx->Fog.FogCoordinateSource == GL_FOG_COORDINATE_EXT)
782a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      span->fog = _mesa_z_to_fogfactor(ctx, ctx->Current.RasterFogCoord);
792a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   else
802a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      span->fog = _mesa_z_to_fogfactor(ctx, ctx->Current.RasterDistance);
812a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   span->fogStep = 0;
822a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   span->interpMask |= SPAN_FOG;
832a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul}
842a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul
852a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul
862a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul/*
872a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul * Init span's color or index interpolation values to the RasterPos color.
882a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul * Used during setup for glDraw/CopyPixels.
892a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul */
902a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paulvoid
912a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul_mesa_span_default_color( GLcontext *ctx, struct sw_span *span )
922a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul{
932a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   if (ctx->Visual.rgbMode) {
942a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      GLchan r, g, b, a;
952a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      UNCLAMPED_FLOAT_TO_CHAN(r, ctx->Current.RasterColor[0]);
962a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      UNCLAMPED_FLOAT_TO_CHAN(g, ctx->Current.RasterColor[1]);
972a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      UNCLAMPED_FLOAT_TO_CHAN(b, ctx->Current.RasterColor[2]);
982a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      UNCLAMPED_FLOAT_TO_CHAN(a, ctx->Current.RasterColor[3]);
992a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul#if CHAN_TYPE == GL_FLOAT
1002a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      span->red = r;
1012a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      span->green = g;
1022a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      span->blue = b;
1032a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      span->alpha = a;
1042a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul#else
1052a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      span->red   = IntToFixed(r);
1062a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      span->green = IntToFixed(g);
1072a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      span->blue  = IntToFixed(b);
1082a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      span->alpha = IntToFixed(a);
1092a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul#endif
1102a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      span->redStep = 0;
1112a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      span->greenStep = 0;
1122a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      span->blueStep = 0;
1132a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      span->alphaStep = 0;
1142a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      span->interpMask |= SPAN_RGBA;
1152a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   }
1162a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   else {
1172a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      span->index = IntToFixed(ctx->Current.RasterIndex);
1182a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      span->indexStep = 0;
1192a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      span->interpMask |= SPAN_INDEX;
1202a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   }
1212a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul}
1222a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul
1232a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul
1242a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul/* Fill in the span.color.rgba array from the interpolation values */
1252a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paulstatic void
1262a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paulinterpolate_colors(GLcontext *ctx, struct sw_span *span)
1272a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul{
1282a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   GLfixed r = span->red;
1292a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   GLfixed g = span->green;
1302a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   GLfixed b = span->blue;
1312a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   GLfixed a = span->alpha;
1322a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   const GLint dr = span->redStep;
1332a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   const GLint dg = span->greenStep;
1342a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   const GLint db = span->blueStep;
1352a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   const GLint da = span->alphaStep;
1362a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   const GLuint n = span->end;
1372a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   GLchan (*rgba)[4] = span->color.rgba;
1382a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   GLuint i;
1392a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul
1402a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   ASSERT(span->interpMask & SPAN_RGBA);
1412a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul
1422a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   if (span->interpMask & SPAN_FLAT) {
1432a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      /* constant color */
1442a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      GLchan color[4];
1452a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      color[RCOMP] = FixedToChan(r);
1462a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      color[GCOMP] = FixedToChan(g);
1472a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      color[BCOMP] = FixedToChan(b);
1482a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      color[ACOMP] = FixedToChan(a);
1492a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      for (i = 0; i < n; i++) {
1502a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         COPY_CHAN4(span->color.rgba[i], color);
1512a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      }
1522a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   }
1532a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   else {
1542a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      /* interpolate */
1552a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      for (i = 0; i < n; i++) {
1562a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         rgba[i][RCOMP] = FixedToChan(r);
1572a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         rgba[i][GCOMP] = FixedToChan(g);
1582a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         rgba[i][BCOMP] = FixedToChan(b);
1592a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         rgba[i][ACOMP] = FixedToChan(a);
1602a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         r += dr;
1612a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         g += dg;
1622a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         b += db;
1632a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         a += da;
1642a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      }
1652a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   }
1662a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   span->arrayMask |= SPAN_RGBA;
1672a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul}
1682a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul
1692a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul
1702a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul/* Fill in the span.color.index array from the interpolation values */
1712a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paulstatic void
1722a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paulinterpolate_indexes(GLcontext *ctx, struct sw_span *span)
1732a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul{
1742a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   GLfixed index = span->index;
1752a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   const GLint indexStep = span->indexStep;
1762a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   const GLuint n = span->end;
1772a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   GLuint *indexes = span->color.index;
1782a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   GLuint i;
1792a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   ASSERT(span->interpMask & SPAN_INDEX);
1802a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul
1812a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   if ((span->interpMask & SPAN_FLAT) || (indexStep == 0)) {
1822a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      /* constant color */
1832a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      index = FixedToInt(index);
1842a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      for (i = 0; i < n; i++) {
1852a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         indexes[i] = index;
1862a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      }
1872a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   }
1882a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   else {
1892a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      /* interpolate */
1902a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      for (i = 0; i < n; i++) {
1912a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         indexes[i] = FixedToInt(index);
1922a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         index += indexStep;
1932a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      }
1942a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   }
1952a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   span->arrayMask |= SPAN_INDEX;
1962a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul}
1972a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul
1982a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul
1992a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul/* Fill in the span.specArray array from the interpolation values */
2002a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paulstatic void
2012a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paulinterpolate_specular(GLcontext *ctx, struct sw_span *span)
2022a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul{
2032a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   if (span->interpMask & SPAN_FLAT) {
2042a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      /* constant color */
2052a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      const GLchan r = FixedToChan(span->specRed);
2062a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      const GLchan g = FixedToChan(span->specGreen);
2072a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      const GLchan b = FixedToChan(span->specBlue);
2082a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      GLuint i;
2092a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      for (i = 0; i < span->end; i++) {
2102a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         span->specArray[i][RCOMP] = r;
2112a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         span->specArray[i][GCOMP] = g;
2122a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         span->specArray[i][BCOMP] = b;
2132a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      }
2142a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   }
2152a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   else {
2162a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      /* interpolate */
2172a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul#if CHAN_TYPE == GL_FLOAT
2182a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      GLfloat r = span->specRed;
2192a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      GLfloat g = span->specGreen;
2202a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      GLfloat b = span->specBlue;
2212a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul#else
2222a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      GLfixed r = span->specRed;
2232a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      GLfixed g = span->specGreen;
2242a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      GLfixed b = span->specBlue;
2252a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul#endif
2262a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      GLuint i;
2272a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      for (i = 0; i < span->end; i++) {
2282a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         span->specArray[i][RCOMP] = FixedToChan(r);
2292a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         span->specArray[i][GCOMP] = FixedToChan(g);
2302a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         span->specArray[i][BCOMP] = FixedToChan(b);
2312a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         r += span->specRedStep;
2322a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         g += span->specGreenStep;
2332a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         b += span->specBlueStep;
2342a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      }
2352a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   }
2362a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   span->arrayMask |= SPAN_SPEC;
2372a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul}
2382a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul
2392a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul
2402a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul/* Fill in the span.zArray array from the interpolation values */
2412a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paulstatic void
2422a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paulinterpolate_z(GLcontext *ctx, struct sw_span *span)
2432a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul{
2442a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   const GLuint n = span->end;
2452a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   GLuint i;
2462a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul
2472a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   ASSERT(span->interpMask & SPAN_Z);
2482a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul
2492a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   if (ctx->Visual.depthBits <= 16) {
2502a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      GLfixed zval = span->z;
2512a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      for (i = 0; i < n; i++) {
2522a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         span->zArray[i] = FixedToInt(zval);
2532a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         zval += span->zStep;
2542a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      }
2552a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   }
2562a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   else {
2572a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      /* Deep Z buffer, no fixed->int shift */
2582a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      GLfixed zval = span->z;
2592a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      for (i = 0; i < n; i++) {
2602a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         span->zArray[i] = zval;
2612a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         zval += span->zStep;
2622a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      }
2632a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   }
2642a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   span->arrayMask |= SPAN_Z;
2652a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul}
2662a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul
2672a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul
2682a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul
2692a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul/* Fill in the span.texcoords array from the interpolation values */
2702a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paulstatic void
2712a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paulinterpolate_texcoords(GLcontext *ctx, struct sw_span *span)
2722a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul{
2732a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   ASSERT(span->interpMask & SPAN_TEXTURE);
2742a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul
2752a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   if (ctx->Texture._ReallyEnabled & ~TEXTURE0_ANY) {
2762a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      if (span->interpMask & SPAN_LAMBDA) {
2772a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         /* multitexture, lambda */
2782a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         GLuint u;
2792a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
2802a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul            if (ctx->Texture.Unit[u]._ReallyEnabled) {
2812a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul               const GLfloat ds = span->texStep[u][0];
2822a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul               const GLfloat dt = span->texStep[u][1];
2832a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul               const GLfloat dr = span->texStep[u][2];
2842a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul               const GLfloat dq = span->texStep[u][3];
2852a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul               GLfloat s = span->tex[u][0];
2862a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul               GLfloat t = span->tex[u][1];
2872a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul               GLfloat r = span->tex[u][2];
2882a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul               GLfloat q = span->tex[u][3];
2892a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul               GLuint i;
2902a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul               for (i = 0; i < span->end; i++) {
2912a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul                  const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q);
2922a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul                  span->texcoords[u][i][0] = s * invQ;
2932a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul                  span->texcoords[u][i][1] = t * invQ;
2942a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul                  span->texcoords[u][i][2] = r * invQ;
2952a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul                  span->lambda[u][i] = (GLfloat)
2962a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul                     (log(span->rho[u] * invQ * invQ) * 1.442695F * 0.5F);
2972a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul                  s += ds;
2982a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul                  t += dt;
2992a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul                  r += dr;
3002a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul                  q += dq;
3012a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul               }
3022a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul            }
3032a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         }
3042a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         span->arrayMask |= SPAN_LAMBDA;
3052a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      }
3062a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      else {
3072a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         /* multitexture, no lambda */
3082a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         GLuint u;
3092a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
3102a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul            if (ctx->Texture.Unit[u]._ReallyEnabled) {
3112a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul               const GLfloat ds = span->texStep[u][0];
3122a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul               const GLfloat dt = span->texStep[u][1];
3132a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul               const GLfloat dr = span->texStep[u][2];
3142a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul               const GLfloat dq = span->texStep[u][3];
3152a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul               GLfloat s = span->tex[u][0];
3162a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul               GLfloat t = span->tex[u][1];
3172a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul               GLfloat r = span->tex[u][2];
3182a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul               GLfloat q = span->tex[u][3];
3192a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul               GLuint i;
3202a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul               for (i = 0; i < span->end; i++) {
3212a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul                  const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q);
3222a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul                  span->texcoords[u][i][0] = s * invQ;
3232a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul                  span->texcoords[u][i][1] = t * invQ;
3242a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul                  span->texcoords[u][i][2] = r * invQ;
3252a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul                  s += ds;
3262a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul                  t += dt;
3272a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul                  r += dr;
3282a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul                  q += dq;
3292a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul               }
3302a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul            }
3312a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         }
3322a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      }
3332a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   }
3342a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   else {
3352a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      if (span->interpMask & SPAN_LAMBDA) {
3362a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         /* just texture unit 0, with lambda */
3372a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         const GLfloat ds = span->texStep[0][0];
3382a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         const GLfloat dt = span->texStep[0][1];
3392a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         const GLfloat dr = span->texStep[0][2];
3402a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         const GLfloat dq = span->texStep[0][3];
3412a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         GLfloat s = span->tex[0][0];
3422a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         GLfloat t = span->tex[0][1];
3432a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         GLfloat r = span->tex[0][2];
3442a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         GLfloat q = span->tex[0][3];
3452a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         GLuint i;
3462a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         for (i = 0; i < span->end; i++) {
3472a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul            const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q);
3482a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul            span->texcoords[0][i][0] = s * invQ;
3492a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul            span->texcoords[0][i][1] = t * invQ;
3502a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul            span->texcoords[0][i][2] = r * invQ;
3512a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul            span->lambda[0][i] = (GLfloat)
3522a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul               (log(span->rho[0] * invQ * invQ) * 1.442695F * 0.5F);
3532a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul            s += ds;
3542a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul            t += dt;
3552a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul            r += dr;
3562a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul            q += dq;
3572a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         }
3582a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         span->arrayMask |= SPAN_LAMBDA;
3592a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      }
3602a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      else {
3612a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         /* just texture 0, witout lambda */
3622a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         const GLfloat ds = span->texStep[0][0];
3632a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         const GLfloat dt = span->texStep[0][1];
3642a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         const GLfloat dr = span->texStep[0][2];
3652a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         const GLfloat dq = span->texStep[0][3];
3662a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         GLfloat s = span->tex[0][0];
3672a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         GLfloat t = span->tex[0][1];
3682a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         GLfloat r = span->tex[0][2];
3692a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         GLfloat q = span->tex[0][3];
3702a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         GLuint i;
3712a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         for (i = 0; i < span->end; i++) {
3722a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul            const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q);
3732a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul            span->texcoords[0][i][0] = s * invQ;
3742a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul            span->texcoords[0][i][1] = t * invQ;
3752a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul            span->texcoords[0][i][2] = r * invQ;
3762a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul            s += ds;
3772a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul            t += dt;
3782a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul            r += dr;
3792a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul            q += dq;
3802a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         }
3812a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      }
3822a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   }
38310f30eb43835c57c00783390a02d72daf4f78e26Brian Paul}
384e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
385e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
386e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell/*
387e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Apply the current polygon stipple pattern to a span of pixels.
388e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */
3895071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paulstatic void
39010f30eb43835c57c00783390a02d72daf4f78e26Brian Paulstipple_polygon_span( GLcontext *ctx, struct sw_span *span)
39110f30eb43835c57c00783390a02d72daf4f78e26Brian Paul{
39210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul   const GLuint highbit = 0x80000000;
39310f30eb43835c57c00783390a02d72daf4f78e26Brian Paul   GLuint i, m, stipple;
39410f30eb43835c57c00783390a02d72daf4f78e26Brian Paul
39510f30eb43835c57c00783390a02d72daf4f78e26Brian Paul   stipple = ctx->PolygonStipple[span->y % 32];
39610f30eb43835c57c00783390a02d72daf4f78e26Brian Paul   m = highbit >> (GLuint) (span->x % 32);
39710f30eb43835c57c00783390a02d72daf4f78e26Brian Paul
39810f30eb43835c57c00783390a02d72daf4f78e26Brian Paul   for (i = 0; i < span->end; i++) {
39910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul      if ((m & stipple) == 0) {
40010f30eb43835c57c00783390a02d72daf4f78e26Brian Paul	 span->mask[i] = 0;
40110f30eb43835c57c00783390a02d72daf4f78e26Brian Paul      }
40210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul      m = m >> 1;
40310f30eb43835c57c00783390a02d72daf4f78e26Brian Paul      if (m == 0) {
40410f30eb43835c57c00783390a02d72daf4f78e26Brian Paul         m = highbit;
40510f30eb43835c57c00783390a02d72daf4f78e26Brian Paul      }
40610f30eb43835c57c00783390a02d72daf4f78e26Brian Paul   }
4072ef866d1fc0a5cc5ef8543d65744dfd4da4dbbafBrian Paul   span->writeAll = GL_FALSE;
40810f30eb43835c57c00783390a02d72daf4f78e26Brian Paul}
40910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul
410e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
41110f30eb43835c57c00783390a02d72daf4f78e26Brian Paul/*
41210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul * Clip a pixel span to the current buffer/window boundaries.
41310f30eb43835c57c00783390a02d72daf4f78e26Brian Paul * Return:   GL_TRUE   some pixel still visible
41410f30eb43835c57c00783390a02d72daf4f78e26Brian Paul *           GL_FALSE  nothing visible
41510f30eb43835c57c00783390a02d72daf4f78e26Brian Paul */
41610f30eb43835c57c00783390a02d72daf4f78e26Brian Paulstatic GLuint
41710f30eb43835c57c00783390a02d72daf4f78e26Brian Paulclip_span( GLcontext *ctx, struct sw_span *span)
41810f30eb43835c57c00783390a02d72daf4f78e26Brian Paul{
41910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul   GLint x = span->x, y = span->y, n = span->end;
42010f30eb43835c57c00783390a02d72daf4f78e26Brian Paul
42110f30eb43835c57c00783390a02d72daf4f78e26Brian Paul   /* Clip to top and bottom */
42210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul   if (y < 0 || y >= ctx->DrawBuffer->Height) {
42310f30eb43835c57c00783390a02d72daf4f78e26Brian Paul      span->end = 0;
42410f30eb43835c57c00783390a02d72daf4f78e26Brian Paul      return GL_FALSE;
42510f30eb43835c57c00783390a02d72daf4f78e26Brian Paul   }
42610f30eb43835c57c00783390a02d72daf4f78e26Brian Paul
42710f30eb43835c57c00783390a02d72daf4f78e26Brian Paul   /* Clip to the left */
42810f30eb43835c57c00783390a02d72daf4f78e26Brian Paul   if (x < 0) {
42910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul      if (x + n <= 0) {
43010f30eb43835c57c00783390a02d72daf4f78e26Brian Paul         /* completely off left side */
43110f30eb43835c57c00783390a02d72daf4f78e26Brian Paul	 span->end = 0;
43210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul         return GL_FALSE;
43310f30eb43835c57c00783390a02d72daf4f78e26Brian Paul      }
43410f30eb43835c57c00783390a02d72daf4f78e26Brian Paul      else {
43510f30eb43835c57c00783390a02d72daf4f78e26Brian Paul         /* partially off left side */
4362ef866d1fc0a5cc5ef8543d65744dfd4da4dbbafBrian Paul	 span->writeAll = GL_FALSE;
43710f30eb43835c57c00783390a02d72daf4f78e26Brian Paul         BZERO(span->mask, -x * sizeof(GLubyte));
43810f30eb43835c57c00783390a02d72daf4f78e26Brian Paul	 return GL_TRUE;
43910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul      }
44010f30eb43835c57c00783390a02d72daf4f78e26Brian Paul   }
44110f30eb43835c57c00783390a02d72daf4f78e26Brian Paul
44210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul   /* Clip to right */
44310f30eb43835c57c00783390a02d72daf4f78e26Brian Paul   if (x + n > ctx->DrawBuffer->Width) {
44410f30eb43835c57c00783390a02d72daf4f78e26Brian Paul      if (x >= ctx->DrawBuffer->Width) {
44510f30eb43835c57c00783390a02d72daf4f78e26Brian Paul         /* completely off right side */
44610f30eb43835c57c00783390a02d72daf4f78e26Brian Paul	 span->end = 0;
44710f30eb43835c57c00783390a02d72daf4f78e26Brian Paul         return GL_FALSE;
44810f30eb43835c57c00783390a02d72daf4f78e26Brian Paul      }
44910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul      else {
45010f30eb43835c57c00783390a02d72daf4f78e26Brian Paul         /* partially off right side */
45110f30eb43835c57c00783390a02d72daf4f78e26Brian Paul         span->end = ctx->DrawBuffer->Width - x;
45210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul	 return GL_TRUE;
45310f30eb43835c57c00783390a02d72daf4f78e26Brian Paul      }
45410f30eb43835c57c00783390a02d72daf4f78e26Brian Paul   }
45510f30eb43835c57c00783390a02d72daf4f78e26Brian Paul
45610f30eb43835c57c00783390a02d72daf4f78e26Brian Paul   return GL_TRUE;
45710f30eb43835c57c00783390a02d72daf4f78e26Brian Paul}
45810f30eb43835c57c00783390a02d72daf4f78e26Brian Paul
45910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul
460e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
461e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell/*
462e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Draw to more than one color buffer (or none).
463e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */
4645071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paulstatic void
4655071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paulmulti_write_index_span( GLcontext *ctx, GLuint n, GLint x, GLint y,
4665071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paul                        const GLuint indexes[], const GLubyte mask[] )
467e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell{
468709892459922a32096fe9dd8261d0d92337bb02fKeith Whitwell   SWcontext *swrast = SWRAST_CONTEXT(ctx);
469e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   GLuint bufferBit;
470e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
471e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   if (ctx->Color.DrawBuffer == GL_NONE)
472e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      return;
473e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
474e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   /* loop over four possible dest color buffers */
475e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   for (bufferBit = 1; bufferBit <= 8; bufferBit = bufferBit << 1) {
476e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      if (bufferBit & ctx->Color.DrawDestMask) {
477e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         GLuint indexTmp[MAX_WIDTH];
478e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         ASSERT(n < MAX_WIDTH);
479e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
480e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         if (bufferBit == FRONT_LEFT_BIT)
481e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            (void) (*ctx->Driver.SetDrawBuffer)( ctx, GL_FRONT_LEFT);
482e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         else if (bufferBit == FRONT_RIGHT_BIT)
483e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            (void) (*ctx->Driver.SetDrawBuffer)( ctx, GL_FRONT_RIGHT);
484e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         else if (bufferBit == BACK_LEFT_BIT)
485e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            (void) (*ctx->Driver.SetDrawBuffer)( ctx, GL_BACK_LEFT);
486e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         else
487e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            (void) (*ctx->Driver.SetDrawBuffer)( ctx, GL_BACK_RIGHT);
488e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
489e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         /* make copy of incoming indexes */
490e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         MEMCPY( indexTmp, indexes, n * sizeof(GLuint) );
491e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         if (ctx->Color.IndexLogicOpEnabled) {
492e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            _mesa_logicop_ci_span( ctx, n, x, y, indexTmp, mask );
493e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         }
494e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         if (ctx->Color.IndexMask == 0) {
495e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            break;
496e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         }
497e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         else if (ctx->Color.IndexMask != 0xffffffff) {
498e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            _mesa_mask_index_span( ctx, n, x, y, indexTmp );
499e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         }
500709892459922a32096fe9dd8261d0d92337bb02fKeith Whitwell         (*swrast->Driver.WriteCI32Span)( ctx, n, x, y, indexTmp, mask );
501e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
502e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
503e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
504e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   /* restore default dest buffer */
505e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   (void) (*ctx->Driver.SetDrawBuffer)( ctx, ctx->Color.DriverDrawBuffer);
506e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell}
507e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
508e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
50910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul/*
51010f30eb43835c57c00783390a02d72daf4f78e26Brian Paul * Draw to more than one RGBA color buffer (or none).
511f1e236987829393c81dc86ea19cb49eefe190317Brian Paul * All fragment operations, up to (but not) blending/logicop should
512f1e236987829393c81dc86ea19cb49eefe190317Brian Paul * have been done first.
51310f30eb43835c57c00783390a02d72daf4f78e26Brian Paul */
51410f30eb43835c57c00783390a02d72daf4f78e26Brian Paulstatic void
51510f30eb43835c57c00783390a02d72daf4f78e26Brian Paulmulti_write_rgba_span( GLcontext *ctx, GLuint n, GLint x, GLint y,
51610f30eb43835c57c00783390a02d72daf4f78e26Brian Paul                       CONST GLchan rgba[][4], const GLubyte mask[] )
51710f30eb43835c57c00783390a02d72daf4f78e26Brian Paul{
51810f30eb43835c57c00783390a02d72daf4f78e26Brian Paul   const GLuint colorMask = *((GLuint *) ctx->Color.ColorMask);
51910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul   GLuint bufferBit;
52010f30eb43835c57c00783390a02d72daf4f78e26Brian Paul   SWcontext *swrast = SWRAST_CONTEXT(ctx);
52110f30eb43835c57c00783390a02d72daf4f78e26Brian Paul
52210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul   if (ctx->Color.DrawBuffer == GL_NONE)
52310f30eb43835c57c00783390a02d72daf4f78e26Brian Paul      return;
52410f30eb43835c57c00783390a02d72daf4f78e26Brian Paul
52510f30eb43835c57c00783390a02d72daf4f78e26Brian Paul   /* loop over four possible dest color buffers */
52610f30eb43835c57c00783390a02d72daf4f78e26Brian Paul   for (bufferBit = 1; bufferBit <= 8; bufferBit = bufferBit << 1) {
52710f30eb43835c57c00783390a02d72daf4f78e26Brian Paul      if (bufferBit & ctx->Color.DrawDestMask) {
52810f30eb43835c57c00783390a02d72daf4f78e26Brian Paul         GLchan rgbaTmp[MAX_WIDTH][4];
52910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul         ASSERT(n < MAX_WIDTH);
53010f30eb43835c57c00783390a02d72daf4f78e26Brian Paul
53110f30eb43835c57c00783390a02d72daf4f78e26Brian Paul         if (bufferBit == FRONT_LEFT_BIT) {
53210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul            (void) (*ctx->Driver.SetDrawBuffer)( ctx, GL_FRONT_LEFT);
53310f30eb43835c57c00783390a02d72daf4f78e26Brian Paul            ctx->DrawBuffer->Alpha = ctx->DrawBuffer->FrontLeftAlpha;
53410f30eb43835c57c00783390a02d72daf4f78e26Brian Paul         }
53510f30eb43835c57c00783390a02d72daf4f78e26Brian Paul         else if (bufferBit == FRONT_RIGHT_BIT) {
53610f30eb43835c57c00783390a02d72daf4f78e26Brian Paul            (void) (*ctx->Driver.SetDrawBuffer)( ctx, GL_FRONT_RIGHT);
53710f30eb43835c57c00783390a02d72daf4f78e26Brian Paul            ctx->DrawBuffer->Alpha = ctx->DrawBuffer->FrontRightAlpha;
53810f30eb43835c57c00783390a02d72daf4f78e26Brian Paul         }
53910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul         else if (bufferBit == BACK_LEFT_BIT) {
54010f30eb43835c57c00783390a02d72daf4f78e26Brian Paul            (void) (*ctx->Driver.SetDrawBuffer)( ctx, GL_BACK_LEFT);
54110f30eb43835c57c00783390a02d72daf4f78e26Brian Paul            ctx->DrawBuffer->Alpha = ctx->DrawBuffer->BackLeftAlpha;
54210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul         }
54310f30eb43835c57c00783390a02d72daf4f78e26Brian Paul         else {
54410f30eb43835c57c00783390a02d72daf4f78e26Brian Paul            (void) (*ctx->Driver.SetDrawBuffer)( ctx, GL_BACK_RIGHT);
54510f30eb43835c57c00783390a02d72daf4f78e26Brian Paul            ctx->DrawBuffer->Alpha = ctx->DrawBuffer->BackRightAlpha;
54610f30eb43835c57c00783390a02d72daf4f78e26Brian Paul         }
54710f30eb43835c57c00783390a02d72daf4f78e26Brian Paul
54810f30eb43835c57c00783390a02d72daf4f78e26Brian Paul         /* make copy of incoming colors */
54910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul         MEMCPY( rgbaTmp, rgba, 4 * n * sizeof(GLchan) );
55010f30eb43835c57c00783390a02d72daf4f78e26Brian Paul
55110f30eb43835c57c00783390a02d72daf4f78e26Brian Paul         if (ctx->Color.ColorLogicOpEnabled) {
55210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul            _mesa_logicop_rgba_span( ctx, n, x, y, rgbaTmp, mask );
55310f30eb43835c57c00783390a02d72daf4f78e26Brian Paul         }
55410f30eb43835c57c00783390a02d72daf4f78e26Brian Paul         else if (ctx->Color.BlendEnabled) {
55510f30eb43835c57c00783390a02d72daf4f78e26Brian Paul            _mesa_blend_span( ctx, n, x, y, rgbaTmp, mask );
55610f30eb43835c57c00783390a02d72daf4f78e26Brian Paul         }
55710f30eb43835c57c00783390a02d72daf4f78e26Brian Paul         if (colorMask == 0x0) {
55810f30eb43835c57c00783390a02d72daf4f78e26Brian Paul            break;
55910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul         }
56010f30eb43835c57c00783390a02d72daf4f78e26Brian Paul         else if (colorMask != 0xffffffff) {
56110f30eb43835c57c00783390a02d72daf4f78e26Brian Paul            _mesa_mask_rgba_span( ctx, n, x, y, rgbaTmp );
56210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul         }
56310f30eb43835c57c00783390a02d72daf4f78e26Brian Paul
56410f30eb43835c57c00783390a02d72daf4f78e26Brian Paul         (*swrast->Driver.WriteRGBASpan)( ctx, n, x, y,
56510f30eb43835c57c00783390a02d72daf4f78e26Brian Paul				       (const GLchan (*)[4]) rgbaTmp, mask );
56610f30eb43835c57c00783390a02d72daf4f78e26Brian Paul         if (swrast->_RasterMask & ALPHABUF_BIT) {
56710f30eb43835c57c00783390a02d72daf4f78e26Brian Paul            _mesa_write_alpha_span( ctx, n, x, y,
56810f30eb43835c57c00783390a02d72daf4f78e26Brian Paul                                    (const GLchan (*)[4])rgbaTmp, mask );
56910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul         }
57010f30eb43835c57c00783390a02d72daf4f78e26Brian Paul      }
57110f30eb43835c57c00783390a02d72daf4f78e26Brian Paul   }
57210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul
57310f30eb43835c57c00783390a02d72daf4f78e26Brian Paul   /* restore default dest buffer */
57410f30eb43835c57c00783390a02d72daf4f78e26Brian Paul   (void) (*ctx->Driver.SetDrawBuffer)( ctx, ctx->Color.DriverDrawBuffer );
57510f30eb43835c57c00783390a02d72daf4f78e26Brian Paul}
57610f30eb43835c57c00783390a02d72daf4f78e26Brian Paul
57710f30eb43835c57c00783390a02d72daf4f78e26Brian Paul
578e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
579e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell/*
580e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Write a horizontal span of color index pixels to the frame buffer.
581e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Stenciling, Depth-testing, etc. are done as needed.
58210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul * Input:  primitive - either GL_POINT, GL_LINE, GL_POLYGON, or GL_BITMAP
58310f30eb43835c57c00783390a02d72daf4f78e26Brian Paul */
58410f30eb43835c57c00783390a02d72daf4f78e26Brian Paulvoid
5852a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul_mesa_write_index_span( GLcontext *ctx, struct sw_span *span,
5862a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul			GLenum primitive)
58710f30eb43835c57c00783390a02d72daf4f78e26Brian Paul{
58810f30eb43835c57c00783390a02d72daf4f78e26Brian Paul   const GLuint modBits = FOG_BIT | BLEND_BIT | MASKING_BIT | LOGIC_OP_BIT;
58910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul   GLuint indexBackup[MAX_WIDTH];
5902a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   GLuint *index;  /* points to span->color.index or indexBackup */
59110f30eb43835c57c00783390a02d72daf4f78e26Brian Paul   SWcontext *swrast = SWRAST_CONTEXT(ctx);
5922a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   const GLuint origArrayMask = span->arrayMask;
59310f30eb43835c57c00783390a02d72daf4f78e26Brian Paul
5942a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   MEMSET(span->mask, 1, span->end);
59510f30eb43835c57c00783390a02d72daf4f78e26Brian Paul
59610f30eb43835c57c00783390a02d72daf4f78e26Brian Paul   if ((swrast->_RasterMask & WINCLIP_BIT) || primitive==GL_BITMAP) {
59710f30eb43835c57c00783390a02d72daf4f78e26Brian Paul      if (clip_span(ctx,span) == GL_FALSE) {
59810f30eb43835c57c00783390a02d72daf4f78e26Brian Paul         return;
59910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul      }
60010f30eb43835c57c00783390a02d72daf4f78e26Brian Paul   }
60110f30eb43835c57c00783390a02d72daf4f78e26Brian Paul
60210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul   if ((primitive==GL_BITMAP && (swrast->_RasterMask & modBits))
60310f30eb43835c57c00783390a02d72daf4f78e26Brian Paul       || (swrast->_RasterMask & MULTI_DRAW_BIT)) {
60410f30eb43835c57c00783390a02d72daf4f78e26Brian Paul      /* Make copy of color indexes */
60510f30eb43835c57c00783390a02d72daf4f78e26Brian Paul      MEMCPY( indexBackup, span->color.index, span->end * sizeof(GLuint) );
60610f30eb43835c57c00783390a02d72daf4f78e26Brian Paul      index = indexBackup;
60710f30eb43835c57c00783390a02d72daf4f78e26Brian Paul   }
60810f30eb43835c57c00783390a02d72daf4f78e26Brian Paul   else {
60910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul      index = span->color.index;
61010f30eb43835c57c00783390a02d72daf4f78e26Brian Paul   }
61110f30eb43835c57c00783390a02d72daf4f78e26Brian Paul
612e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
613e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   /* Do the scissor test */
614e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   if (ctx->Scissor.Enabled) {
61510f30eb43835c57c00783390a02d72daf4f78e26Brian Paul      if (_mesa_scissor_span( ctx, span ) == GL_FALSE) {
61686ca15ece74ccb5a8f4d566a4b2c8024b178d73bBrian Paul         return;
617e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
618e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
619e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
620e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   /* Polygon Stippling */
621e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   if (ctx->Polygon.StippleFlag && primitive==GL_POLYGON) {
62210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul      stipple_polygon_span(ctx, span);
623e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
624e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
62510f30eb43835c57c00783390a02d72daf4f78e26Brian Paul
62610f30eb43835c57c00783390a02d72daf4f78e26Brian Paul   /* I have to think where to put this!! */
6272a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   if (span->interpMask & SPAN_Z)
6282a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      interpolate_z(ctx, span);
62910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul
63010f30eb43835c57c00783390a02d72daf4f78e26Brian Paul
631e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   if (ctx->Stencil.Enabled) {
632e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      /* first stencil test */
6332a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      if (_mesa_stencil_and_ztest_span(ctx, span) == GL_FALSE) {
6342a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         span->arrayMask = origArrayMask;
635e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell	 return;
6362a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      }
63710f30eb43835c57c00783390a02d72daf4f78e26Brian Paul   }
63810f30eb43835c57c00783390a02d72daf4f78e26Brian Paul   else if (ctx->Depth.Test) {
63910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul      /* regular depth testing */
6402a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      if (_mesa_depth_test_span(ctx, span) == 0) {
6412a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         span->arrayMask = origArrayMask;
64210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul         return;
6432a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      }
64410f30eb43835c57c00783390a02d72daf4f78e26Brian Paul   }
64510f30eb43835c57c00783390a02d72daf4f78e26Brian Paul
64610f30eb43835c57c00783390a02d72daf4f78e26Brian Paul   /* if we get here, something passed the depth test */
64710f30eb43835c57c00783390a02d72daf4f78e26Brian Paul   ctx->OcclusionResult = GL_TRUE;
64810f30eb43835c57c00783390a02d72daf4f78e26Brian Paul
64910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul   if (ctx->Color.DrawBuffer == GL_NONE) {
65010f30eb43835c57c00783390a02d72daf4f78e26Brian Paul      /* write no pixels */
6512a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      span->arrayMask = origArrayMask;
65210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul      return;
65310f30eb43835c57c00783390a02d72daf4f78e26Brian Paul   }
65410f30eb43835c57c00783390a02d72daf4f78e26Brian Paul
6552a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   if (span->interpMask & SPAN_INDEX)
6562a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      interpolate_indexes(ctx, span);
65710f30eb43835c57c00783390a02d72daf4f78e26Brian Paul
6582a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   if (ctx->Fog.Enabled) {
6592a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      if ((span->arrayMask & SPAN_FOG) && !swrast->_PreferPixelFog)
6602a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         _mesa_fog_ci_pixels_with_array( ctx, span, span->fogArray, index);
6612a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      else if ((span->interpMask & SPAN_FOG) && !swrast->_PreferPixelFog)
6622a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         _mesa_fog_ci_pixels( ctx, span, index);
6632a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      else
6642a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         _mesa_depth_fog_ci_pixels( ctx, span, index);
665e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
666e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
6672a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   /* Antialias coverage application */
6682a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   if (span->arrayMask & SPAN_COVERAGE) {
6692a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      GLuint i;
67010f30eb43835c57c00783390a02d72daf4f78e26Brian Paul      for (i = 0; i < span->end; i++) {
6712a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         ASSERT(span->coverage[i] < 16);
6722a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         index[i] = (index[i] & ~0xf) | ((GLuint) (span->coverage[i]));
6735071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paul      }
6742a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   }
6755071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paul
6762a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   if (swrast->_RasterMask & MULTI_DRAW_BIT) {
6772a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      /* draw to zero or two or more buffers */
6782a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      multi_write_index_span( ctx, span->end, span->x, span->y,
6792a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul			      index, span->mask );
680e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
681e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   else {
6822a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      /* normal situation: draw to exactly one buffer */
6832a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      if (ctx->Color.IndexLogicOpEnabled) {
6842a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         _mesa_logicop_ci_span( ctx, span->end, span->x, span->y,
6852a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul				index, span->mask );
68610f30eb43835c57c00783390a02d72daf4f78e26Brian Paul      }
6872a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul
6882a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      if (ctx->Color.IndexMask == 0) {
6892a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         return;
6902a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      }
6912a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      else if (ctx->Color.IndexMask != 0xffffffff) {
6922a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         _mesa_mask_index_span( ctx, span->end, span->x, span->y, index );
693e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
6942a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul
6952a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      /* write pixels */
6962a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      (*swrast->Driver.WriteCI32Span)( ctx, span->end, span->x,
6972a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul				       span->y, index, span->mask );
698e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
6992a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul
7002a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   span->arrayMask = origArrayMask;
701e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell}
702e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
703e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
704e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
7055d2621928823a06006c1586efe78fe8bf65a7e1fBrian Paul/*
7065d2621928823a06006c1586efe78fe8bf65a7e1fBrian Paul * Apply fragment processing to a span of RGBA fragments.
7075d2621928823a06006c1586efe78fe8bf65a7e1fBrian Paul * Input:
7085d2621928823a06006c1586efe78fe8bf65a7e1fBrian Paul */
7095071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paulvoid
71010f30eb43835c57c00783390a02d72daf4f78e26Brian Paul_mesa_write_rgba_span( GLcontext *ctx, struct sw_span *span,
7112a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul		       GLenum primitive)
712e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell{
713e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   const GLuint modBits = FOG_BIT | BLEND_BIT | MASKING_BIT |
714e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell                          LOGIC_OP_BIT | TEXTURE_BIT;
715e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   GLchan rgbaBackup[MAX_WIDTH][4];
716e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   GLchan (*rgba)[4];
717cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell   SWcontext *swrast = SWRAST_CONTEXT(ctx);
7182a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   const GLuint origArrayMask = span->arrayMask;
719e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
7202a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   MEMSET(span->mask, 1, span->end);
721e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
722cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell   if ((swrast->_RasterMask & WINCLIP_BIT) || primitive==GL_BITMAP) {
72310f30eb43835c57c00783390a02d72daf4f78e26Brian Paul      if (clip_span( ctx,span ) == GL_FALSE) {
724b38ad54c41aec2d08fdd26a4a8ea4dcdca8b1dfdBrian Paul         return;
725e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
726e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
727e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
728e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   /* Do the scissor test */
729e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   if (ctx->Scissor.Enabled) {
73010f30eb43835c57c00783390a02d72daf4f78e26Brian Paul      if (_mesa_scissor_span( ctx, span ) == GL_FALSE) {
73186ca15ece74ccb5a8f4d566a4b2c8024b178d73bBrian Paul         return;
732e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
733e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
734e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
735e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   /* Polygon Stippling */
736e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   if (ctx->Polygon.StippleFlag && primitive==GL_POLYGON) {
73710f30eb43835c57c00783390a02d72daf4f78e26Brian Paul      stipple_polygon_span( ctx, span);
73810f30eb43835c57c00783390a02d72daf4f78e26Brian Paul   }
73910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul
7402a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   if ((span->interpMask & SPAN_RGBA) && (span->arrayMask & SPAN_RGBA) == 0) {
7412a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      interpolate_colors(ctx, span);
7422a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   }
74310f30eb43835c57c00783390a02d72daf4f78e26Brian Paul
74410f30eb43835c57c00783390a02d72daf4f78e26Brian Paul   if ((primitive==GL_BITMAP && (swrast->_RasterMask & modBits))
74510f30eb43835c57c00783390a02d72daf4f78e26Brian Paul       || (swrast->_RasterMask & MULTI_DRAW_BIT)) {
74610f30eb43835c57c00783390a02d72daf4f78e26Brian Paul      /* must make a copy of the colors since they may be modified */
74710f30eb43835c57c00783390a02d72daf4f78e26Brian Paul      MEMCPY( rgbaBackup, span->color.rgba, 4 * span->end * sizeof(GLchan) );
74810f30eb43835c57c00783390a02d72daf4f78e26Brian Paul      rgba = rgbaBackup;
74910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul   }
75010f30eb43835c57c00783390a02d72daf4f78e26Brian Paul   else {
75110f30eb43835c57c00783390a02d72daf4f78e26Brian Paul      rgba = span->color.rgba;
752e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
753e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
754e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   /* Do the alpha test */
755e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   if (ctx->Color.AlphaEnabled) {
7562ef866d1fc0a5cc5ef8543d65744dfd4da4dbbafBrian Paul      if (_mesa_alpha_test( ctx, span, (const GLchan (*)[4]) rgba) == 0) {
7572a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         span->arrayMask = origArrayMask;
758e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell	 return;
759e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
76010f30eb43835c57c00783390a02d72daf4f78e26Brian Paul   }
76110f30eb43835c57c00783390a02d72daf4f78e26Brian Paul
762f1e236987829393c81dc86ea19cb49eefe190317Brian Paul   /* Stencil and Z testing */
763f1e236987829393c81dc86ea19cb49eefe190317Brian Paul   if (ctx->Stencil.Enabled || ctx->Depth.Test) {
764f1e236987829393c81dc86ea19cb49eefe190317Brian Paul      if (span->interpMask & SPAN_Z)
765f1e236987829393c81dc86ea19cb49eefe190317Brian Paul         interpolate_z(ctx, span);
766f1e236987829393c81dc86ea19cb49eefe190317Brian Paul
767f1e236987829393c81dc86ea19cb49eefe190317Brian Paul      if (ctx->Stencil.Enabled) {
768f1e236987829393c81dc86ea19cb49eefe190317Brian Paul         if (!_mesa_stencil_and_ztest_span(ctx, span)) {
769f1e236987829393c81dc86ea19cb49eefe190317Brian Paul            span->arrayMask = origArrayMask;
770f1e236987829393c81dc86ea19cb49eefe190317Brian Paul            return;
77110f30eb43835c57c00783390a02d72daf4f78e26Brian Paul         }
77210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul      }
77310f30eb43835c57c00783390a02d72daf4f78e26Brian Paul      else {
774f1e236987829393c81dc86ea19cb49eefe190317Brian Paul         ASSERT(ctx->Depth.Test);
775f1e236987829393c81dc86ea19cb49eefe190317Brian Paul         ASSERT(span->arrayMask & SPAN_Z);
776f1e236987829393c81dc86ea19cb49eefe190317Brian Paul         /* regular depth testing */
777f1e236987829393c81dc86ea19cb49eefe190317Brian Paul         if (!_mesa_depth_test_span(ctx, span)) {
778f1e236987829393c81dc86ea19cb49eefe190317Brian Paul            span->arrayMask = origArrayMask;
779f1e236987829393c81dc86ea19cb49eefe190317Brian Paul            return;
78010f30eb43835c57c00783390a02d72daf4f78e26Brian Paul         }
78110f30eb43835c57c00783390a02d72daf4f78e26Brian Paul      }
782e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
783e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
784e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   /* if we get here, something passed the depth test */
785e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   ctx->OcclusionResult = GL_TRUE;
786e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
787b38ad54c41aec2d08fdd26a4a8ea4dcdca8b1dfdBrian Paul   /* Per-pixel fog */
788b38ad54c41aec2d08fdd26a4a8ea4dcdca8b1dfdBrian Paul   if (ctx->Fog.Enabled) {
7892a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      if ((span->arrayMask & SPAN_FOG)  &&  !swrast->_PreferPixelFog)
7902a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul	 _mesa_fog_rgba_pixels_with_array( ctx, span, span->fogArray, rgba);
7912a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      else if ((span->interpMask & SPAN_FOG)  &&  !swrast->_PreferPixelFog)
79210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul         _mesa_fog_rgba_pixels( ctx, span, rgba );
793f1e236987829393c81dc86ea19cb49eefe190317Brian Paul      else {
794f1e236987829393c81dc86ea19cb49eefe190317Brian Paul         if ((span->interpMask & SPAN_Z) && (span->arrayMask & SPAN_Z) == 0)
795f1e236987829393c81dc86ea19cb49eefe190317Brian Paul            interpolate_z(ctx, span);
79610f30eb43835c57c00783390a02d72daf4f78e26Brian Paul         _mesa_depth_fog_rgba_pixels( ctx, span, rgba );
797f1e236987829393c81dc86ea19cb49eefe190317Brian Paul      }
798b38ad54c41aec2d08fdd26a4a8ea4dcdca8b1dfdBrian Paul   }
799b38ad54c41aec2d08fdd26a4a8ea4dcdca8b1dfdBrian Paul
8005071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paul   /* Antialias coverage application */
8012a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   if (span->arrayMask & SPAN_COVERAGE) {
8025071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paul      GLuint i;
80310f30eb43835c57c00783390a02d72daf4f78e26Brian Paul      for (i = 0; i < span->end; i++) {
80410f30eb43835c57c00783390a02d72daf4f78e26Brian Paul         rgba[i][ACOMP] = (GLchan) (rgba[i][ACOMP] * span->coverage[i]);
8055071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paul      }
8065071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paul   }
8075071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paul
808cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell   if (swrast->_RasterMask & MULTI_DRAW_BIT) {
80910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul      multi_write_rgba_span( ctx, span->end, span->x, span->y, (const GLchan (*)[4]) rgba, span->mask );
810e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
811e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   else {
812e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      /* normal: write to exactly one buffer */
813e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      /* logic op or blending */
814e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      const GLuint colorMask = *((GLuint *) ctx->Color.ColorMask);
815e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
816e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      if (ctx->Color.ColorLogicOpEnabled) {
81710f30eb43835c57c00783390a02d72daf4f78e26Brian Paul         _mesa_logicop_rgba_span( ctx, span->end, span->x, span->y, rgba, span->mask );
818e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
819e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      else if (ctx->Color.BlendEnabled) {
82010f30eb43835c57c00783390a02d72daf4f78e26Brian Paul         _mesa_blend_span( ctx, span->end, span->x, span->y, rgba, span->mask );
821e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
822e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
823e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      /* Color component masking */
824e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      if (colorMask == 0x0) {
8252a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         span->arrayMask = origArrayMask;
826e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         return;
827e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
828e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      else if (colorMask != 0xffffffff) {
82910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul         _mesa_mask_rgba_span( ctx, span->end, span->x, span->y, rgba );
830e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
831e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
832e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      /* write pixels */
83310f30eb43835c57c00783390a02d72daf4f78e26Brian Paul      (*swrast->Driver.WriteRGBASpan)( ctx, span->end, span->x, span->y,
83471340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul                                 (const GLchan (*)[4]) rgba,
8352ef866d1fc0a5cc5ef8543d65744dfd4da4dbbafBrian Paul                                 span->writeAll ? ((const GLubyte *) NULL) : span->mask );
836e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
837cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell      if (swrast->_RasterMask & ALPHABUF_BIT) {
83810f30eb43835c57c00783390a02d72daf4f78e26Brian Paul         _mesa_write_alpha_span( ctx, span->end, span->x, span->y,
83922144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes                                 (const GLchan (*)[4]) rgba,
8402ef866d1fc0a5cc5ef8543d65744dfd4da4dbbafBrian Paul                                 span->writeAll ? ((const GLubyte *) NULL) : span->mask );
841e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
842e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
8432a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul
8442a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   span->arrayMask = origArrayMask;
845e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell}
846e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
847e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
848e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell/*
849e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Write a horizontal span of color pixels to the frame buffer.
850e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * The color is initially constant for the whole span.
851e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Alpha-testing, stenciling, depth-testing, and blending are done as needed.
85210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul * Input:  r, g, b, a - the color of the pixels
853e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell *         primitive - either GL_POINT, GL_LINE, GL_POLYGON or GL_BITMAP.
854e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */
8555071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paulvoid
85610f30eb43835c57c00783390a02d72daf4f78e26Brian Paul_mesa_write_monocolor_span( GLcontext *ctx, struct sw_span *span,
85710f30eb43835c57c00783390a02d72daf4f78e26Brian Paul			    const GLchan color[4], GLenum primitive )
858e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell{
859e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   const GLuint colorMask = *((GLuint *) ctx->Color.ColorMask);
860e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   GLuint i;
861e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   GLchan rgba[MAX_WIDTH][4];
862cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell   SWcontext *swrast = SWRAST_CONTEXT(ctx);
863e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
8642a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   MEMSET(span->mask, 1, span->end);
865e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
866cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell   if ((swrast->_RasterMask & WINCLIP_BIT) || primitive==GL_BITMAP) {
86710f30eb43835c57c00783390a02d72daf4f78e26Brian Paul      if (clip_span(ctx,span) == GL_FALSE) {
868e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell	 return;
869e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
870e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
871e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
872e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   /* Do the scissor test */
873e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   if (ctx->Scissor.Enabled) {
87410f30eb43835c57c00783390a02d72daf4f78e26Brian Paul      if (_mesa_scissor_span( ctx, span ) == GL_FALSE) {
87586ca15ece74ccb5a8f4d566a4b2c8024b178d73bBrian Paul         return;
876e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
877e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
878e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
879e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   /* Polygon Stippling */
880e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   if (ctx->Polygon.StippleFlag && primitive==GL_POLYGON) {
88110f30eb43835c57c00783390a02d72daf4f78e26Brian Paul      stipple_polygon_span( ctx, span);
882e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
883e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
884e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   /* Do the alpha test */
885e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   if (ctx->Color.AlphaEnabled) {
886f1e236987829393c81dc86ea19cb49eefe190317Brian Paul      if ((span->interpMask & SPAN_RGBA) && (span->arrayMask & SPAN_RGBA) == 0)
887f1e236987829393c81dc86ea19cb49eefe190317Brian Paul         interpolate_colors(ctx, span);
888f1e236987829393c81dc86ea19cb49eefe190317Brian Paul
88910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul      for (i = 0; i < span->end; i++) {
890e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         rgba[i][ACOMP] = color[ACOMP];
891e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
8922ef866d1fc0a5cc5ef8543d65744dfd4da4dbbafBrian Paul      if (_mesa_alpha_test( ctx, span, (const GLchan (*)[4])rgba) == 0) {
893e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell	 return;
894e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
89510f30eb43835c57c00783390a02d72daf4f78e26Brian Paul   }
89610f30eb43835c57c00783390a02d72daf4f78e26Brian Paul
897f1e236987829393c81dc86ea19cb49eefe190317Brian Paul   if (span->interpMask & SPAN_Z)
898f1e236987829393c81dc86ea19cb49eefe190317Brian Paul      interpolate_z(ctx, span);
899e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
900e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   if (ctx->Stencil.Enabled) {
901e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      /* first stencil test */
90210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul      if (_mesa_stencil_and_ztest_span(ctx, span) == GL_FALSE)
903e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell	 return;
904e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
905e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   else if (ctx->Depth.Test) {
906e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      /* regular depth testing */
90710f30eb43835c57c00783390a02d72daf4f78e26Brian Paul      if (_mesa_depth_test_span(ctx, span) == 0)
908e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         return;
909e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
910e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
911e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   /* if we get here, something passed the depth test */
912e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   ctx->OcclusionResult = GL_TRUE;
913e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
914e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   if (ctx->Color.DrawBuffer == GL_NONE) {
915e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      /* write no pixels */
916e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      return;
917e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
918e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
9192a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   if (ctx->Color.ColorLogicOpEnabled ||
9202a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul       colorMask != 0xffffffff ||
9212a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul       (swrast->_RasterMask & (BLEND_BIT | FOG_BIT)) ||
9222a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul       (span->arrayMask & SPAN_COVERAGE)) {
923e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      /* assign same color to each pixel */
92410f30eb43835c57c00783390a02d72daf4f78e26Brian Paul      SW_SPAN_SET_FLAG(span->filledColor);
92510f30eb43835c57c00783390a02d72daf4f78e26Brian Paul      for (i = 0; i < span->end; i++) {
92610f30eb43835c57c00783390a02d72daf4f78e26Brian Paul	 if (span->mask[i]) {
927e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            COPY_CHAN4(rgba[i], color);
928e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell	 }
929e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
930e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
931e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      /* Per-pixel fog */
932e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      if (ctx->Fog.Enabled) {
9332a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul	 if ((span->interpMask & SPAN_FOG)  &&  !swrast->_PreferPixelFog)
93410f30eb43835c57c00783390a02d72daf4f78e26Brian Paul	    _mesa_fog_rgba_pixels( ctx, span, rgba );
935e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell	 else
93610f30eb43835c57c00783390a02d72daf4f78e26Brian Paul	    _mesa_depth_fog_rgba_pixels( ctx, span, rgba );
937e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
938e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
9395071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paul      /* Antialias coverage application */
9402a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      if (span->arrayMask & SPAN_COVERAGE) {
9415071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paul         GLuint i;
94210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul         for (i = 0; i < span->end; i++) {
94310f30eb43835c57c00783390a02d72daf4f78e26Brian Paul            rgba[i][ACOMP] = (GLchan) (rgba[i][ACOMP] * span->coverage[i]);
9445071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paul         }
9455071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paul      }
9465071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paul
947cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell      if (swrast->_RasterMask & MULTI_DRAW_BIT) {
94810f30eb43835c57c00783390a02d72daf4f78e26Brian Paul         multi_write_rgba_span( ctx, span->end, span->x, span->y,
94910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul                                (const GLchan (*)[4]) rgba, span->mask );
950e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
951e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      else {
952e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         /* normal: write to exactly one buffer */
953e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         if (ctx->Color.ColorLogicOpEnabled) {
9542a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul            _mesa_logicop_rgba_span( ctx, span->end, span->x, span->y,
9552a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul                                     rgba, span->mask );
956e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         }
957e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         else if (ctx->Color.BlendEnabled) {
9582a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul            _mesa_blend_span( ctx, span->end, span->x, span->y,
9592a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul                              rgba, span->mask );
960e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         }
961e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
962e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         /* Color component masking */
963e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         if (colorMask == 0x0) {
964e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            return;
965e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         }
966e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         else if (colorMask != 0xffffffff) {
96710f30eb43835c57c00783390a02d72daf4f78e26Brian Paul            _mesa_mask_rgba_span( ctx, span->end, span->x, span->y, rgba );
968e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         }
969e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
970e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         /* write pixels */
97110f30eb43835c57c00783390a02d72daf4f78e26Brian Paul         (*swrast->Driver.WriteRGBASpan)( ctx, span->end, span->x, span->y,
9722a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul                     (const GLchan (*)[4]) rgba,
9732a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul                     span->writeAll ? ((const GLubyte *) NULL) : span->mask );
974cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell         if (swrast->_RasterMask & ALPHABUF_BIT) {
97510f30eb43835c57c00783390a02d72daf4f78e26Brian Paul            _mesa_write_alpha_span( ctx, span->end, span->x, span->y,
9762a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul                     (const GLchan (*)[4]) rgba,
9772a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul                     span->writeAll ? ((const GLubyte *) NULL) : span->mask );
978e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         }
979e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
980e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
981e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   else {
982e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      /* same color for all pixels */
983e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      ASSERT(!ctx->Color.BlendEnabled);
984e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      ASSERT(!ctx->Color.ColorLogicOpEnabled);
985e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
986cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell      if (swrast->_RasterMask & MULTI_DRAW_BIT) {
98710f30eb43835c57c00783390a02d72daf4f78e26Brian Paul	 SW_SPAN_SET_FLAG(span->filledColor);
98810f30eb43835c57c00783390a02d72daf4f78e26Brian Paul         for (i = 0; i < span->end; i++) {
98910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul            if (span->mask[i]) {
990e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               COPY_CHAN4(rgba[i], color);
991e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            }
992e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         }
99310f30eb43835c57c00783390a02d72daf4f78e26Brian Paul         multi_write_rgba_span( ctx, span->end, span->x, span->y,
99410f30eb43835c57c00783390a02d72daf4f78e26Brian Paul				(const GLchan (*)[4]) rgba, span->mask );
995e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
996e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      else {
9972a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         (*swrast->Driver.WriteMonoRGBASpan)( ctx, span->end, span->x, span->y,
9982a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul                                              color, span->mask );
999cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell         if (swrast->_RasterMask & ALPHABUF_BIT) {
10002ef866d1fc0a5cc5ef8543d65744dfd4da4dbbafBrian Paul            _mesa_write_mono_alpha_span( ctx, span->end, span->x, span->y,
10012a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul                     (GLchan) color[ACOMP],
10022a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul                     span->writeAll ? ((const GLubyte *) NULL) : span->mask );
1003e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         }
1004e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
1005e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
1006e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell}
1007e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
1008e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
1009e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
1010e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell/*
1011e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Add specular color to base color.  This is used only when
1012f1e236987829393c81dc86ea19cb49eefe190317Brian Paul * GL_LIGHT_MODEL_COLOR_CONTROL = GL_SEPARATE_SPECULAR_COLOR.
1013e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */
10145071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paulstatic void
1015f1e236987829393c81dc86ea19cb49eefe190317Brian Pauladd_colors(GLuint n, GLchan rgba[][4], GLchan specular[][4] )
1016e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell{
1017e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   GLuint i;
1018f1e236987829393c81dc86ea19cb49eefe190317Brian Paul   for (i = 0; i < n; i++) {
10194fa5c1966a985f81c615a9f5ef2f64dd466b252aBrian Paul#if CHAN_TYPE == GL_FLOAT
10204fa5c1966a985f81c615a9f5ef2f64dd466b252aBrian Paul      /* no clamping */
1021f1e236987829393c81dc86ea19cb49eefe190317Brian Paul      rgba[i][RCOMP] += specular[i][RCOMP];
1022f1e236987829393c81dc86ea19cb49eefe190317Brian Paul      rgba[i][GCOMP] += specular[i][GCOMP];
1023f1e236987829393c81dc86ea19cb49eefe190317Brian Paul      rgba[i][BCOMP] += specular[i][BCOMP];
10244fa5c1966a985f81c615a9f5ef2f64dd466b252aBrian Paul#else
1025f1e236987829393c81dc86ea19cb49eefe190317Brian Paul      GLint r = rgba[i][RCOMP] + specular[i][RCOMP];
1026f1e236987829393c81dc86ea19cb49eefe190317Brian Paul      GLint g = rgba[i][GCOMP] + specular[i][GCOMP];
1027f1e236987829393c81dc86ea19cb49eefe190317Brian Paul      GLint b = rgba[i][BCOMP] + specular[i][BCOMP];
1028e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      rgba[i][RCOMP] = (GLchan) MIN2(r, CHAN_MAX);
1029e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      rgba[i][GCOMP] = (GLchan) MIN2(g, CHAN_MAX);
1030e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      rgba[i][BCOMP] = (GLchan) MIN2(b, CHAN_MAX);
10314fa5c1966a985f81c615a9f5ef2f64dd466b252aBrian Paul#endif
1032e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
1033e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell}
1034e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
1035e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
1036e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell/*
1037f1e236987829393c81dc86ea19cb49eefe190317Brian Paul * This function may modify any of the array values in the span.
1038f1e236987829393c81dc86ea19cb49eefe190317Brian Paul * span->arrayMask, however, will not be modified (or we'll
1039f1e236987829393c81dc86ea19cb49eefe190317Brian Paul * restore it to the original incoming value before returning.
104078940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul */
104178940758e90069ceaca2b6cddb6438488fbad5ccBrian Paulvoid
104278940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul_mesa_write_texture_span( GLcontext *ctx, struct sw_span *span,
1043f1e236987829393c81dc86ea19cb49eefe190317Brian Paul                          GLenum primitive )
104478940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul{
104578940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul   const GLuint colorMask = *((GLuint *) ctx->Color.ColorMask);
104678940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul   SWcontext *swrast = SWRAST_CONTEXT(ctx);
1047f1e236987829393c81dc86ea19cb49eefe190317Brian Paul   const GLuint origArrayMask = span->arrayMask;
1048f1e236987829393c81dc86ea19cb49eefe190317Brian Paul
1049f1e236987829393c81dc86ea19cb49eefe190317Brian Paul   /*   printf("%s()  interp 0x%x  array 0x%x\n", __FUNCTION__, span->interpMask, span->arrayMask);*/
1050f1e236987829393c81dc86ea19cb49eefe190317Brian Paul
1051f1e236987829393c81dc86ea19cb49eefe190317Brian Paul   ASSERT(ctx->Texture._ReallyEnabled);
105278940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul
10532a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   MEMSET(span->mask, 1, span->end);
105478940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul
1055f1e236987829393c81dc86ea19cb49eefe190317Brian Paul   /* clip against window bounds */
105678940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul   if ((swrast->_RasterMask & WINCLIP_BIT) || primitive==GL_BITMAP) {
105778940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul      if (clip_span(ctx,span) == GL_FALSE) {
105878940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul	 return;
105978940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul      }
106078940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul   }
106178940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul
1062f1e236987829393c81dc86ea19cb49eefe190317Brian Paul   /* Scissor test */
106378940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul   if (ctx->Scissor.Enabled) {
106478940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul      if (_mesa_scissor_span( ctx, span ) == GL_FALSE) {
106578940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul         return;
106678940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul      }
106778940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul   }
106878940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul
106978940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul   /* Polygon Stippling */
107078940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul   if (ctx->Polygon.StippleFlag && primitive==GL_POLYGON) {
107178940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul      stipple_polygon_span( ctx, span);
107278940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul   }
107378940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul
1074f1e236987829393c81dc86ea19cb49eefe190317Brian Paul   /* Need texture coordinates now */
1075f1e236987829393c81dc86ea19cb49eefe190317Brian Paul   if ((span->interpMask & SPAN_TEXTURE)
1076f1e236987829393c81dc86ea19cb49eefe190317Brian Paul       && (span->arrayMask & SPAN_TEXTURE) == 0)
1077f1e236987829393c81dc86ea19cb49eefe190317Brian Paul      interpolate_texcoords(ctx, span);
107878940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul
107978940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul   /* Texture with alpha test */
108078940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul   if (ctx->Color.AlphaEnabled) {
1081f1e236987829393c81dc86ea19cb49eefe190317Brian Paul
1082f1e236987829393c81dc86ea19cb49eefe190317Brian Paul      /* Now we need the rgba array, fill it in if needed */
1083f1e236987829393c81dc86ea19cb49eefe190317Brian Paul      if ((span->interpMask & SPAN_RGBA) && (span->arrayMask & SPAN_RGBA) == 0)
1084f1e236987829393c81dc86ea19cb49eefe190317Brian Paul         interpolate_colors(ctx, span);
1085f1e236987829393c81dc86ea19cb49eefe190317Brian Paul
108678940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul      /* Texturing without alpha is done after depth-testing which
1087f1e236987829393c81dc86ea19cb49eefe190317Brian Paul       * gives a potential speed-up.
1088f1e236987829393c81dc86ea19cb49eefe190317Brian Paul       */
1089f1e236987829393c81dc86ea19cb49eefe190317Brian Paul      _swrast_multitexture_fragments( ctx, span );
109078940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul
109178940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul      /* Do the alpha test */
1092f1e236987829393c81dc86ea19cb49eefe190317Brian Paul      if (!_old_alpha_test(ctx, span->end,
1093f1e236987829393c81dc86ea19cb49eefe190317Brian Paul                           (CONST GLchan (*)[4]) span->color.rgba,
1094f1e236987829393c81dc86ea19cb49eefe190317Brian Paul                           span->mask)) {
1095f1e236987829393c81dc86ea19cb49eefe190317Brian Paul         span->arrayMask = origArrayMask;
109678940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul         return;
109778940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul      }
109878940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul   }
109978940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul
1100f1e236987829393c81dc86ea19cb49eefe190317Brian Paul   /* Stencil and Z testing */
1101f1e236987829393c81dc86ea19cb49eefe190317Brian Paul   if (ctx->Stencil.Enabled || ctx->Depth.Test) {
1102f1e236987829393c81dc86ea19cb49eefe190317Brian Paul      if (span->interpMask & SPAN_Z)
1103f1e236987829393c81dc86ea19cb49eefe190317Brian Paul         interpolate_z(ctx, span);
110478940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul
110571340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul      if (ctx->Stencil.Enabled) {
1106f1e236987829393c81dc86ea19cb49eefe190317Brian Paul         if (!_mesa_stencil_and_ztest_span(ctx, span)) {
1107f1e236987829393c81dc86ea19cb49eefe190317Brian Paul            span->arrayMask = origArrayMask;
110810f30eb43835c57c00783390a02d72daf4f78e26Brian Paul            return;
1109f1e236987829393c81dc86ea19cb49eefe190317Brian Paul         }
111071340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul      }
1111f1e236987829393c81dc86ea19cb49eefe190317Brian Paul      else {
1112f1e236987829393c81dc86ea19cb49eefe190317Brian Paul         ASSERT(ctx->Depth.Test);
1113f1e236987829393c81dc86ea19cb49eefe190317Brian Paul         ASSERT(span->arrayMask & SPAN_Z);
111410f30eb43835c57c00783390a02d72daf4f78e26Brian Paul         /* regular depth testing */
1115f1e236987829393c81dc86ea19cb49eefe190317Brian Paul         if (!_mesa_depth_test_span(ctx, span)) {
1116f1e236987829393c81dc86ea19cb49eefe190317Brian Paul            span->arrayMask = origArrayMask;
111710f30eb43835c57c00783390a02d72daf4f78e26Brian Paul            return;
1118f1e236987829393c81dc86ea19cb49eefe190317Brian Paul         }
111971340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul      }
112071340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul   }
112171340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul
1122f1e236987829393c81dc86ea19cb49eefe190317Brian Paul   /* if we get here, some fragments passed the depth test */
112371340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul   ctx->OcclusionResult = GL_TRUE;
112471340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul
1125f1e236987829393c81dc86ea19cb49eefe190317Brian Paul   /* We had to wait until now to check for glColorMask(F,F,F,F) because of
1126f1e236987829393c81dc86ea19cb49eefe190317Brian Paul    * the occlusion test.
1127f1e236987829393c81dc86ea19cb49eefe190317Brian Paul    */
1128f1e236987829393c81dc86ea19cb49eefe190317Brian Paul   if (colorMask == 0x0) {
1129f1e236987829393c81dc86ea19cb49eefe190317Brian Paul      span->arrayMask = origArrayMask;
1130f1e236987829393c81dc86ea19cb49eefe190317Brian Paul      return;
113171340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul   }
113271340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul
1133f1e236987829393c81dc86ea19cb49eefe190317Brian Paul   /* Texture without alpha test */
1134f1e236987829393c81dc86ea19cb49eefe190317Brian Paul   if (!ctx->Color.AlphaEnabled) {
113571340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul
1136f1e236987829393c81dc86ea19cb49eefe190317Brian Paul      /* Now we need the rgba array, fill it in if needed */
1137f1e236987829393c81dc86ea19cb49eefe190317Brian Paul      if ((span->interpMask & SPAN_RGBA) && (span->arrayMask & SPAN_RGBA) == 0)
1138f1e236987829393c81dc86ea19cb49eefe190317Brian Paul         interpolate_colors(ctx, span);
113971340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul
1140f1e236987829393c81dc86ea19cb49eefe190317Brian Paul      _swrast_multitexture_fragments( ctx, span );
114171340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul   }
114271340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul
1143f1e236987829393c81dc86ea19cb49eefe190317Brian Paul   ASSERT(span->arrayMask & SPAN_RGBA);
11442ef866d1fc0a5cc5ef8543d65744dfd4da4dbbafBrian Paul
1145f1e236987829393c81dc86ea19cb49eefe190317Brian Paul   /* Add base and specular colors */
1146f1e236987829393c81dc86ea19cb49eefe190317Brian Paul   if (ctx->Fog.ColorSumEnabled ||
1147f1e236987829393c81dc86ea19cb49eefe190317Brian Paul       (ctx->Light.Enabled &&
1148f1e236987829393c81dc86ea19cb49eefe190317Brian Paul        ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR)) {
1149f1e236987829393c81dc86ea19cb49eefe190317Brian Paul      if (span->interpMask & SPAN_SPEC) {
1150f1e236987829393c81dc86ea19cb49eefe190317Brian Paul         interpolate_specular(ctx, span);
115171340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul      }
1152f1e236987829393c81dc86ea19cb49eefe190317Brian Paul      ASSERT(span->arrayMask & SPAN_SPEC);
1153f1e236987829393c81dc86ea19cb49eefe190317Brian Paul      add_colors( span->end, span->color.rgba, span->specArray );
115471340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul   }
115571340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul
115671340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul   /* Per-pixel fog */
115771340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul   if (ctx->Fog.Enabled) {
1158f1e236987829393c81dc86ea19cb49eefe190317Brian Paul#if 0
1159f1e236987829393c81dc86ea19cb49eefe190317Brian Paul      if ((span->interpMask & SPAN_FOG) && (span->arrayMask & SPAN_FOG) == 0)
1160f1e236987829393c81dc86ea19cb49eefe190317Brian Paul         interpolate_fog(ctx, span);
1161f1e236987829393c81dc86ea19cb49eefe190317Brian Paul#endif
1162f1e236987829393c81dc86ea19cb49eefe190317Brian Paul      if ((span->arrayMask & SPAN_FOG) && !swrast->_PreferPixelFog)
1163f1e236987829393c81dc86ea19cb49eefe190317Brian Paul	 _mesa_fog_rgba_pixels_with_array( ctx, span, span->fogArray,
1164f1e236987829393c81dc86ea19cb49eefe190317Brian Paul                                           span->color.rgba);
1165f1e236987829393c81dc86ea19cb49eefe190317Brian Paul      else if ((span->interpMask & SPAN_FOG)  &&  !swrast->_PreferPixelFog)
1166f1e236987829393c81dc86ea19cb49eefe190317Brian Paul	 _mesa_fog_rgba_pixels( ctx, span, span->color.rgba );
1167f1e236987829393c81dc86ea19cb49eefe190317Brian Paul      else {
1168f1e236987829393c81dc86ea19cb49eefe190317Brian Paul         if ((span->interpMask & SPAN_Z) && (span->arrayMask & SPAN_Z) == 0)
1169f1e236987829393c81dc86ea19cb49eefe190317Brian Paul            interpolate_z(ctx, span);
1170f1e236987829393c81dc86ea19cb49eefe190317Brian Paul	 _mesa_depth_fog_rgba_pixels(ctx, span, span->color.rgba);
1171f1e236987829393c81dc86ea19cb49eefe190317Brian Paul      }
117271340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul   }
1173f1e236987829393c81dc86ea19cb49eefe190317Brian Paul
117471340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul   /* Antialias coverage application */
11752a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   if (span->arrayMask & SPAN_COVERAGE) {
1176f1e236987829393c81dc86ea19cb49eefe190317Brian Paul      GLchan (*rgba)[4] = span->color.rgba;
117771340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul      GLuint i;
117810f30eb43835c57c00783390a02d72daf4f78e26Brian Paul      for (i = 0; i < span->end; i++) {
117910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul         rgba[i][ACOMP] = (GLchan) (rgba[i][ACOMP] * span->coverage[i]);
118071340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul      }
118171340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul   }
118271340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul
118371340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul   if (swrast->_RasterMask & MULTI_DRAW_BIT) {
11842ef866d1fc0a5cc5ef8543d65744dfd4da4dbbafBrian Paul      multi_write_rgba_span( ctx, span->end, span->x, span->y,
1185f1e236987829393c81dc86ea19cb49eefe190317Brian Paul                             (const GLchan (*)[4]) span->color.rgba,
1186f1e236987829393c81dc86ea19cb49eefe190317Brian Paul                             span->mask );
118771340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul   }
118871340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul   else {
118971340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul      /* normal: write to exactly one buffer */
119071340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul      if (ctx->Color.ColorLogicOpEnabled) {
1191f1e236987829393c81dc86ea19cb49eefe190317Brian Paul         _mesa_logicop_rgba_span( ctx, span->end, span->x, span->y,
1192f1e236987829393c81dc86ea19cb49eefe190317Brian Paul                                  span->color.rgba, span->mask );
119371340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul      }
119471340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul      else  if (ctx->Color.BlendEnabled) {
1195f1e236987829393c81dc86ea19cb49eefe190317Brian Paul         _mesa_blend_span( ctx, span->end, span->x, span->y,
1196f1e236987829393c81dc86ea19cb49eefe190317Brian Paul                           span->color.rgba, span->mask);
119771340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul      }
119871340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul
1199f1e236987829393c81dc86ea19cb49eefe190317Brian Paul      if (colorMask != 0xffffffff) {
1200f1e236987829393c81dc86ea19cb49eefe190317Brian Paul         _mesa_mask_rgba_span( ctx, span->end, span->x, span->y,
1201f1e236987829393c81dc86ea19cb49eefe190317Brian Paul                               span->color.rgba );
120271340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul      }
120371340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul
12042ef866d1fc0a5cc5ef8543d65744dfd4da4dbbafBrian Paul      (*swrast->Driver.WriteRGBASpan)( ctx, span->end, span->x, span->y,
1205f1e236987829393c81dc86ea19cb49eefe190317Brian Paul                                       (const GLchan (*)[4]) span->color.rgba,
12062ef866d1fc0a5cc5ef8543d65744dfd4da4dbbafBrian Paul                                       span->writeAll ? NULL : span->mask );
120771340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul      if (swrast->_RasterMask & ALPHABUF_BIT) {
12082ef866d1fc0a5cc5ef8543d65744dfd4da4dbbafBrian Paul         _mesa_write_alpha_span( ctx, span->end, span->x, span->y,
1209f1e236987829393c81dc86ea19cb49eefe190317Brian Paul                                 (const GLchan (*)[4]) span->color.rgba,
12102ef866d1fc0a5cc5ef8543d65744dfd4da4dbbafBrian Paul                                 span->writeAll ? NULL : span->mask );
121171340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul      }
121271340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul   }
121371340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul
1214f1e236987829393c81dc86ea19cb49eefe190317Brian Paul   span->arrayMask = origArrayMask;
121510f30eb43835c57c00783390a02d72daf4f78e26Brian Paul}
121610f30eb43835c57c00783390a02d72daf4f78e26Brian Paul
1217e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
1218e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
1219e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell/*
1220e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Read RGBA pixels from frame buffer.  Clipping will be done to prevent
1221e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * reading ouside the buffer's boundaries.
1222e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */
12235071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paulvoid
12245071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paul_mesa_read_rgba_span( GLcontext *ctx, GLframebuffer *buffer,
12255071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paul                      GLuint n, GLint x, GLint y, GLchan rgba[][4] )
1226e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell{
1227709892459922a32096fe9dd8261d0d92337bb02fKeith Whitwell   SWcontext *swrast = SWRAST_CONTEXT(ctx);
1228e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   if (y < 0 || y >= buffer->Height
1229e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell       || x + (GLint) n < 0 || x >= buffer->Width) {
1230e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      /* completely above, below, or right */
1231e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      /* XXX maybe leave undefined? */
1232e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      BZERO(rgba, 4 * n * sizeof(GLchan));
1233e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
1234e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   else {
1235e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      GLint skip, length;
1236e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      if (x < 0) {
1237e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         /* left edge clippping */
1238e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         skip = -x;
1239e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         length = (GLint) n - skip;
1240e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         if (length < 0) {
1241e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            /* completely left of window */
1242e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            return;
1243e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         }
1244e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         if (length > buffer->Width) {
1245e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            length = buffer->Width;
1246e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         }
1247e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
1248e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      else if ((GLint) (x + n) > buffer->Width) {
1249e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         /* right edge clipping */
1250e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         skip = 0;
1251e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         length = buffer->Width - x;
1252e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         if (length < 0) {
1253e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            /* completely to right of window */
1254e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            return;
1255e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         }
1256e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
1257e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      else {
1258e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         /* no clipping */
1259e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         skip = 0;
1260e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         length = (GLint) n;
1261e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
1262e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
1263709892459922a32096fe9dd8261d0d92337bb02fKeith Whitwell      (*swrast->Driver.ReadRGBASpan)( ctx, length, x + skip, y, rgba + skip );
1264e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      if (buffer->UseSoftwareAlphaBuffers) {
1265e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         _mesa_read_alpha_span( ctx, length, x + skip, y, rgba + skip );
1266e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
1267e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
1268e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell}
1269e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
1270e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
1271e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
1272e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
1273e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell/*
1274e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Read CI pixels from frame buffer.  Clipping will be done to prevent
1275e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * reading ouside the buffer's boundaries.
1276e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */
12775071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paulvoid
12785071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paul_mesa_read_index_span( GLcontext *ctx, GLframebuffer *buffer,
12795071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paul                       GLuint n, GLint x, GLint y, GLuint indx[] )
1280e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell{
1281709892459922a32096fe9dd8261d0d92337bb02fKeith Whitwell   SWcontext *swrast = SWRAST_CONTEXT(ctx);
1282e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   if (y < 0 || y >= buffer->Height
1283e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell       || x + (GLint) n < 0 || x >= buffer->Width) {
1284e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      /* completely above, below, or right */
1285e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      BZERO(indx, n * sizeof(GLuint));
1286e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
1287e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   else {
1288e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      GLint skip, length;
1289e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      if (x < 0) {
1290e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         /* left edge clippping */
1291e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         skip = -x;
1292e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         length = (GLint) n - skip;
1293e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         if (length < 0) {
1294e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            /* completely left of window */
1295e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            return;
1296e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         }
1297e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         if (length > buffer->Width) {
1298e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            length = buffer->Width;
1299e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         }
1300e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
1301e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      else if ((GLint) (x + n) > buffer->Width) {
1302e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         /* right edge clipping */
1303e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         skip = 0;
1304e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         length = buffer->Width - x;
1305e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         if (length < 0) {
1306e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            /* completely to right of window */
1307e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            return;
1308e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         }
1309e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
1310e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      else {
1311e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         /* no clipping */
1312e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         skip = 0;
1313e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         length = (GLint) n;
1314e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
1315e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
1316709892459922a32096fe9dd8261d0d92337bb02fKeith Whitwell      (*swrast->Driver.ReadCI32Span)( ctx, length, skip + x, y, indx + skip );
1317e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
1318e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell}
1319