s_span.c revision bcb148de9201c7f90a68c7c46434e7ebf7204000
1bcb148de9201c7f90a68c7c46434e7ebf7204000Brian Paul/* $Id: s_span.c,v 1.32 2002/02/06 03:22:47 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
2879c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/**
29bcb148de9201c7f90a68c7c46434e7ebf7204000Brian Paul * \file swrast/s_span.c
3079c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul * \brief Span processing functions used by all rasterization functions.
3179c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul * This is where all the per-fragment tests are performed
3279c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul * \author Brian Paul
33e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */
34e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
35e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "glheader.h"
36e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "colormac.h"
3771340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul#include "context.h"
38e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "macros.h"
39e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "mem.h"
40e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
41e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_alpha.h"
42e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_alphabuf.h"
43e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_blend.h"
44cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell#include "s_context.h"
45e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_depth.h"
46e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_fog.h"
47e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_logic.h"
48e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_masking.h"
49e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_span.h"
50e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_stencil.h"
51e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_texture.h"
52e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
532a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul
5479c2f534916046fab91f53ebd37f705bd25f7dcbBrian 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
7079c2f534916046fab91f53ebd37f705bd25f7dcbBrian 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
8679c2f534916046fab91f53ebd37f705bd25f7dcbBrian 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 {
361733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul         /* just texture 0, without 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
38679c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/**
387e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Apply the current polygon stipple pattern to a span of pixels.
388e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */
3895071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paulstatic void
390733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paulstipple_polygon_span( GLcontext *ctx, struct sw_span *span )
39110f30eb43835c57c00783390a02d72daf4f78e26Brian Paul{
39210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul   const GLuint highbit = 0x80000000;
393733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul   const GLuint stipple = ctx->PolygonStipple[span->y % 32];
394733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul   GLuint i, m;
395733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul
396733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul   ASSERT(ctx->Polygon.StippleFlag);
397733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul   ASSERT((span->arrayMask & SPAN_XY) == 0);
39810f30eb43835c57c00783390a02d72daf4f78e26Brian Paul
39910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul   m = highbit >> (GLuint) (span->x % 32);
40010f30eb43835c57c00783390a02d72daf4f78e26Brian Paul
40110f30eb43835c57c00783390a02d72daf4f78e26Brian Paul   for (i = 0; i < span->end; i++) {
40210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul      if ((m & stipple) == 0) {
40310f30eb43835c57c00783390a02d72daf4f78e26Brian Paul	 span->mask[i] = 0;
40410f30eb43835c57c00783390a02d72daf4f78e26Brian Paul      }
40510f30eb43835c57c00783390a02d72daf4f78e26Brian Paul      m = m >> 1;
40610f30eb43835c57c00783390a02d72daf4f78e26Brian Paul      if (m == 0) {
40710f30eb43835c57c00783390a02d72daf4f78e26Brian Paul         m = highbit;
40810f30eb43835c57c00783390a02d72daf4f78e26Brian Paul      }
40910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul   }
4102ef866d1fc0a5cc5ef8543d65744dfd4da4dbbafBrian Paul   span->writeAll = GL_FALSE;
41110f30eb43835c57c00783390a02d72daf4f78e26Brian Paul}
41210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul
413e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
41479c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/**
415733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul * Clip a pixel span to the current buffer/window boundaries:
416733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul * DrawBuffer->_Xmin, _Xmax, _Ymin, _Ymax.  This will accomplish
417733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul * window clipping and scissoring.
418733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul * Return:   GL_TRUE   some pixels still visible
41910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul *           GL_FALSE  nothing visible
42010f30eb43835c57c00783390a02d72daf4f78e26Brian Paul */
42110f30eb43835c57c00783390a02d72daf4f78e26Brian Paulstatic GLuint
422733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paulclip_span( GLcontext *ctx, struct sw_span *span )
42310f30eb43835c57c00783390a02d72daf4f78e26Brian Paul{
424733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul   const GLint xmin = ctx->DrawBuffer->_Xmin;
425733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul   const GLint xmax = ctx->DrawBuffer->_Xmax;
426733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul   const GLint ymin = ctx->DrawBuffer->_Ymin;
427733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul   const GLint ymax = ctx->DrawBuffer->_Ymax;
428733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul
429733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul   if (span->arrayMask & SPAN_XY) {
430733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      /* arrays of x/y pixel coords */
431733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      const GLint *x = span->xArray;
432733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      const GLint *y = span->yArray;
433733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      const GLint n = span->end;
434733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      GLubyte *mask = span->mask;
435733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      GLint i;
436b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul      if (span->arrayMask & SPAN_MASK) {
437b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul         /* note: using & intead of && to reduce branches */
438b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul         for (i = 0; i < n; i++) {
439b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul            mask[i] &= (x[i] >= xmin) & (x[i] < xmax)
440b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul                     & (y[i] >= ymin) & (y[i] < ymax);
441b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul         }
442b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul      }
443b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul      else {
444b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul         /* note: using & intead of && to reduce branches */
445b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul         for (i = 0; i < n; i++) {
446b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul            mask[i] = (x[i] >= xmin) & (x[i] < xmax)
447b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul                    & (y[i] >= ymin) & (y[i] < ymax);
448b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul         }
44910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul      }
450733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      return GL_TRUE;  /* some pixels visible */
45110f30eb43835c57c00783390a02d72daf4f78e26Brian Paul   }
452733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul   else {
453733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      /* horizontal span of pixels */
454733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      const GLint x = span->x;
455733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      const GLint y = span->y;
456733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      const GLint n = span->end;
457733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul
458733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      /* Trivial rejection tests */
459733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      if (y < ymin || y >= ymax || x + n <= xmin || x >= xmax) {
460733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul         span->end = 0;
461733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul         return GL_FALSE;  /* all pixels clipped */
462733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      }
46310f30eb43835c57c00783390a02d72daf4f78e26Brian Paul
464733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      /* Clip to the left */
465733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      if (x < xmin) {
466733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul         ASSERT(x + n > xmin);
467733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul         span->writeAll = GL_FALSE;
468733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul         BZERO(span->mask, (xmin - x) * sizeof(GLubyte));
46910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul      }
470733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul
471733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      /* Clip to right */
472733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      if (x + n > xmax) {
473733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul         ASSERT(x < xmax);
474733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul         span->end = xmax - x;
47510f30eb43835c57c00783390a02d72daf4f78e26Brian Paul      }
47610f30eb43835c57c00783390a02d72daf4f78e26Brian Paul
477733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      return GL_TRUE;  /* some pixels visible */
478733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul   }
47910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul}
48010f30eb43835c57c00783390a02d72daf4f78e26Brian Paul
48110f30eb43835c57c00783390a02d72daf4f78e26Brian Paul
482e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
48379c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/**
484e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Draw to more than one color buffer (or none).
485e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */
4865071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paulstatic void
487733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paulmulti_write_index_span( GLcontext *ctx, struct sw_span *span )
488e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell{
489709892459922a32096fe9dd8261d0d92337bb02fKeith Whitwell   SWcontext *swrast = SWRAST_CONTEXT(ctx);
490e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   GLuint bufferBit;
491e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
492e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   /* loop over four possible dest color buffers */
493e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   for (bufferBit = 1; bufferBit <= 8; bufferBit = bufferBit << 1) {
494e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      if (bufferBit & ctx->Color.DrawDestMask) {
495e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         GLuint indexTmp[MAX_WIDTH];
496733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul         ASSERT(span->end < MAX_WIDTH);
497e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
498e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         if (bufferBit == FRONT_LEFT_BIT)
499e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            (void) (*ctx->Driver.SetDrawBuffer)( ctx, GL_FRONT_LEFT);
500e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         else if (bufferBit == FRONT_RIGHT_BIT)
501e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            (void) (*ctx->Driver.SetDrawBuffer)( ctx, GL_FRONT_RIGHT);
502e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         else if (bufferBit == BACK_LEFT_BIT)
503e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            (void) (*ctx->Driver.SetDrawBuffer)( ctx, GL_BACK_LEFT);
504e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         else
505e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            (void) (*ctx->Driver.SetDrawBuffer)( ctx, GL_BACK_RIGHT);
506e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
507e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         /* make copy of incoming indexes */
508733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul         MEMCPY( indexTmp, span->color.index, span->end * sizeof(GLuint) );
509733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul
510e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         if (ctx->Color.IndexLogicOpEnabled) {
511733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul            _mesa_logicop_ci_span(ctx, span, indexTmp);
512e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         }
513733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul
5147956292a765910077f50352d7cd0174e1e66d26cBrian Paul         if (ctx->Color.IndexMask != 0xffffffff) {
515733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul            _mesa_mask_index_span(ctx, span, indexTmp);
516733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul         }
517733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul
518733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul         if (span->arrayMask & SPAN_XY) {
519733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul            /* array of pixel coords */
520733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul            (*swrast->Driver.WriteCI32Pixels)(ctx, span->end,
521733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul                                              span->xArray, span->yArray,
522733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul                                              indexTmp, span->mask);
523733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul         }
524733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul         else {
525733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul            /* horizontal run of pixels */
526733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul            (*swrast->Driver.WriteCI32Span)(ctx, span->end, span->x, span->y,
527733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul                                            indexTmp, span->mask);
528e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         }
529e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
530e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
531e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
532e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   /* restore default dest buffer */
533e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   (void) (*ctx->Driver.SetDrawBuffer)( ctx, ctx->Color.DriverDrawBuffer);
534e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell}
535e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
536e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
53779c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/**
53810f30eb43835c57c00783390a02d72daf4f78e26Brian Paul * Draw to more than one RGBA color buffer (or none).
539f1e236987829393c81dc86ea19cb49eefe190317Brian Paul * All fragment operations, up to (but not) blending/logicop should
540f1e236987829393c81dc86ea19cb49eefe190317Brian Paul * have been done first.
54110f30eb43835c57c00783390a02d72daf4f78e26Brian Paul */
54210f30eb43835c57c00783390a02d72daf4f78e26Brian Paulstatic void
543733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paulmulti_write_rgba_span( GLcontext *ctx, struct sw_span *span )
54410f30eb43835c57c00783390a02d72daf4f78e26Brian Paul{
54510f30eb43835c57c00783390a02d72daf4f78e26Brian Paul   const GLuint colorMask = *((GLuint *) ctx->Color.ColorMask);
54610f30eb43835c57c00783390a02d72daf4f78e26Brian Paul   GLuint bufferBit;
54710f30eb43835c57c00783390a02d72daf4f78e26Brian Paul   SWcontext *swrast = SWRAST_CONTEXT(ctx);
54810f30eb43835c57c00783390a02d72daf4f78e26Brian Paul
549733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul   ASSERT(colorMask != 0x0);
550733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul
55110f30eb43835c57c00783390a02d72daf4f78e26Brian Paul   if (ctx->Color.DrawBuffer == GL_NONE)
55210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul      return;
55310f30eb43835c57c00783390a02d72daf4f78e26Brian Paul
55410f30eb43835c57c00783390a02d72daf4f78e26Brian Paul   /* loop over four possible dest color buffers */
55510f30eb43835c57c00783390a02d72daf4f78e26Brian Paul   for (bufferBit = 1; bufferBit <= 8; bufferBit = bufferBit << 1) {
55610f30eb43835c57c00783390a02d72daf4f78e26Brian Paul      if (bufferBit & ctx->Color.DrawDestMask) {
55710f30eb43835c57c00783390a02d72daf4f78e26Brian Paul         GLchan rgbaTmp[MAX_WIDTH][4];
558733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul         ASSERT(span->end < MAX_WIDTH);
55910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul
56010f30eb43835c57c00783390a02d72daf4f78e26Brian Paul         if (bufferBit == FRONT_LEFT_BIT) {
56110f30eb43835c57c00783390a02d72daf4f78e26Brian Paul            (void) (*ctx->Driver.SetDrawBuffer)( ctx, GL_FRONT_LEFT);
56210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul            ctx->DrawBuffer->Alpha = ctx->DrawBuffer->FrontLeftAlpha;
56310f30eb43835c57c00783390a02d72daf4f78e26Brian Paul         }
56410f30eb43835c57c00783390a02d72daf4f78e26Brian Paul         else if (bufferBit == FRONT_RIGHT_BIT) {
56510f30eb43835c57c00783390a02d72daf4f78e26Brian Paul            (void) (*ctx->Driver.SetDrawBuffer)( ctx, GL_FRONT_RIGHT);
56610f30eb43835c57c00783390a02d72daf4f78e26Brian Paul            ctx->DrawBuffer->Alpha = ctx->DrawBuffer->FrontRightAlpha;
56710f30eb43835c57c00783390a02d72daf4f78e26Brian Paul         }
56810f30eb43835c57c00783390a02d72daf4f78e26Brian Paul         else if (bufferBit == BACK_LEFT_BIT) {
56910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul            (void) (*ctx->Driver.SetDrawBuffer)( ctx, GL_BACK_LEFT);
57010f30eb43835c57c00783390a02d72daf4f78e26Brian Paul            ctx->DrawBuffer->Alpha = ctx->DrawBuffer->BackLeftAlpha;
57110f30eb43835c57c00783390a02d72daf4f78e26Brian Paul         }
57210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul         else {
57310f30eb43835c57c00783390a02d72daf4f78e26Brian Paul            (void) (*ctx->Driver.SetDrawBuffer)( ctx, GL_BACK_RIGHT);
57410f30eb43835c57c00783390a02d72daf4f78e26Brian Paul            ctx->DrawBuffer->Alpha = ctx->DrawBuffer->BackRightAlpha;
57510f30eb43835c57c00783390a02d72daf4f78e26Brian Paul         }
57610f30eb43835c57c00783390a02d72daf4f78e26Brian Paul
57710f30eb43835c57c00783390a02d72daf4f78e26Brian Paul         /* make copy of incoming colors */
578733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul         MEMCPY( rgbaTmp, span->color.rgba, 4 * span->end * sizeof(GLchan) );
57910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul
58010f30eb43835c57c00783390a02d72daf4f78e26Brian Paul         if (ctx->Color.ColorLogicOpEnabled) {
581733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul            _mesa_logicop_rgba_span(ctx, span, rgbaTmp);
58210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul         }
58310f30eb43835c57c00783390a02d72daf4f78e26Brian Paul         else if (ctx->Color.BlendEnabled) {
584733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul            _mesa_blend_span(ctx, span, rgbaTmp);
58510f30eb43835c57c00783390a02d72daf4f78e26Brian Paul         }
586733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul
587733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul         if (colorMask != 0xffffffff) {
588733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul            _mesa_mask_rgba_span(ctx, span, rgbaTmp);
58910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul         }
59010f30eb43835c57c00783390a02d72daf4f78e26Brian Paul
591733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul         if (span->arrayMask & SPAN_XY) {
592733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul            /* array of pixel coords */
593733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul            (*swrast->Driver.WriteRGBAPixels)(ctx, span->end,
594733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul                                              span->xArray, span->yArray,
595733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul                                              (const GLchan (*)[4]) rgbaTmp,
596733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul                                              span->mask);
597733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul            if (SWRAST_CONTEXT(ctx)->_RasterMask & ALPHABUF_BIT) {
598733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul               _mesa_write_alpha_pixels(ctx, span->end,
599733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul                                        span->xArray, span->yArray,
600733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul                                        (const GLchan (*)[4]) rgbaTmp,
601733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul                                        span->mask);
602733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul            }
603733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul         }
604733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul         else {
605733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul            /* horizontal run of pixels */
606733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul            (*swrast->Driver.WriteRGBASpan)(ctx, span->end, span->x, span->y,
607733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul                                            (const GLchan (*)[4]) rgbaTmp,
608733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul                                            span->mask);
609733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul            if (swrast->_RasterMask & ALPHABUF_BIT) {
610733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul               _mesa_write_alpha_span(ctx, span->end, span->x, span->y,
611733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul                                      (const GLchan (*)[4]) rgbaTmp,
612733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul                                      span->mask);
613733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul            }
61410f30eb43835c57c00783390a02d72daf4f78e26Brian Paul         }
61510f30eb43835c57c00783390a02d72daf4f78e26Brian Paul      }
61610f30eb43835c57c00783390a02d72daf4f78e26Brian Paul   }
61710f30eb43835c57c00783390a02d72daf4f78e26Brian Paul
61810f30eb43835c57c00783390a02d72daf4f78e26Brian Paul   /* restore default dest buffer */
61910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul   (void) (*ctx->Driver.SetDrawBuffer)( ctx, ctx->Color.DriverDrawBuffer );
62010f30eb43835c57c00783390a02d72daf4f78e26Brian Paul}
62110f30eb43835c57c00783390a02d72daf4f78e26Brian Paul
62210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul
623e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
62479c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/**
6257956292a765910077f50352d7cd0174e1e66d26cBrian Paul * This function may modify any of the array values in the span.
6267956292a765910077f50352d7cd0174e1e66d26cBrian Paul * span->interpMask and span->arrayMask may be changed but will be restored
6277956292a765910077f50352d7cd0174e1e66d26cBrian Paul * to their original values before returning.
62810f30eb43835c57c00783390a02d72daf4f78e26Brian Paul */
62910f30eb43835c57c00783390a02d72daf4f78e26Brian Paulvoid
6302a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul_mesa_write_index_span( GLcontext *ctx, struct sw_span *span,
6312a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul			GLenum primitive)
63210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul{
63310f30eb43835c57c00783390a02d72daf4f78e26Brian Paul   SWcontext *swrast = SWRAST_CONTEXT(ctx);
6347956292a765910077f50352d7cd0174e1e66d26cBrian Paul   const GLuint origInterpMask = span->interpMask;
6352a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   const GLuint origArrayMask = span->arrayMask;
63610f30eb43835c57c00783390a02d72daf4f78e26Brian Paul
637733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul   ASSERT(span->end <= MAX_WIDTH);
638733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul   ASSERT((span->interpMask | span->arrayMask) & SPAN_INDEX);
6397956292a765910077f50352d7cd0174e1e66d26cBrian Paul   ASSERT((span->interpMask & span->arrayMask) == 0);
6407956292a765910077f50352d7cd0174e1e66d26cBrian Paul
641733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul   if (span->arrayMask & SPAN_MASK) {
642733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      /* mask was initialized by caller, probably glBitmap */
643733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      span->writeAll = GL_FALSE;
644733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul   }
645733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul   else {
646733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      MEMSET(span->mask, 1, span->end);
647733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      span->writeAll = GL_TRUE;
64810f30eb43835c57c00783390a02d72daf4f78e26Brian Paul   }
64910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul
650733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul   /* Clipping */
651733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul   if ((swrast->_RasterMask & CLIP_BIT) || (primitive == GL_BITMAP)
652b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul       || (primitive == GL_POINT) || (primitive == GL_LINE)) {
653733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      if (!clip_span(ctx, span)) {
65486ca15ece74ccb5a8f4d566a4b2c8024b178d73bBrian Paul         return;
655e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
656e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
657e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
658b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul#ifdef DEBUG
659b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul   if (span->arrayMask & SPAN_XY) {
660b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul      int i;
661b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul      for (i = 0; i < span->end; i++) {
662b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul         if (span->mask[i]) {
663b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul            assert(span->xArray[i] >= ctx->DrawBuffer->_Xmin);
664b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul            assert(span->xArray[i] < ctx->DrawBuffer->_Xmax);
665b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul            assert(span->yArray[i] >= ctx->DrawBuffer->_Ymin);
666b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul            assert(span->yArray[i] < ctx->DrawBuffer->_Ymax);
667b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul         }
668b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul      }
669b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul   }
670b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul#endif
671b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul
672e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   /* Polygon Stippling */
673733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul   if (ctx->Polygon.StippleFlag && primitive == GL_POLYGON) {
67410f30eb43835c57c00783390a02d72daf4f78e26Brian Paul      stipple_polygon_span(ctx, span);
675e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
676e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
6777956292a765910077f50352d7cd0174e1e66d26cBrian Paul   /* Depth test and stencil */
6787956292a765910077f50352d7cd0174e1e66d26cBrian Paul   if (ctx->Depth.Test || ctx->Stencil.Enabled) {
6797956292a765910077f50352d7cd0174e1e66d26cBrian Paul      if (span->interpMask & SPAN_Z)
6807956292a765910077f50352d7cd0174e1e66d26cBrian Paul         interpolate_z(ctx, span);
68110f30eb43835c57c00783390a02d72daf4f78e26Brian Paul
6827956292a765910077f50352d7cd0174e1e66d26cBrian Paul      if (ctx->Stencil.Enabled) {
68379c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul         if (!_mesa_stencil_and_ztest_span(ctx, span)) {
6847956292a765910077f50352d7cd0174e1e66d26cBrian Paul            span->arrayMask = origArrayMask;
6857956292a765910077f50352d7cd0174e1e66d26cBrian Paul            return;
6867956292a765910077f50352d7cd0174e1e66d26cBrian Paul         }
6872a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      }
6887956292a765910077f50352d7cd0174e1e66d26cBrian Paul      else {
6897956292a765910077f50352d7cd0174e1e66d26cBrian Paul         ASSERT(ctx->Depth.Test);
69079c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul         if (!_mesa_depth_test_span(ctx, span)) {
6917956292a765910077f50352d7cd0174e1e66d26cBrian Paul            span->arrayMask = origArrayMask;
6927956292a765910077f50352d7cd0174e1e66d26cBrian Paul            return;
6937956292a765910077f50352d7cd0174e1e66d26cBrian Paul         }
6942a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      }
69510f30eb43835c57c00783390a02d72daf4f78e26Brian Paul   }
69610f30eb43835c57c00783390a02d72daf4f78e26Brian Paul
69710f30eb43835c57c00783390a02d72daf4f78e26Brian Paul   /* if we get here, something passed the depth test */
69810f30eb43835c57c00783390a02d72daf4f78e26Brian Paul   ctx->OcclusionResult = GL_TRUE;
69910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul
7007956292a765910077f50352d7cd0174e1e66d26cBrian Paul   /* we have to wait until after occlusion to do this test */
7017956292a765910077f50352d7cd0174e1e66d26cBrian Paul   if (ctx->Color.DrawBuffer == GL_NONE || ctx->Color.IndexMask == 0) {
70210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul      /* write no pixels */
7032a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      span->arrayMask = origArrayMask;
70410f30eb43835c57c00783390a02d72daf4f78e26Brian Paul      return;
70510f30eb43835c57c00783390a02d72daf4f78e26Brian Paul   }
70610f30eb43835c57c00783390a02d72daf4f78e26Brian Paul
7077956292a765910077f50352d7cd0174e1e66d26cBrian Paul   /* Interpolate the color indexes if needed */
7087956292a765910077f50352d7cd0174e1e66d26cBrian Paul   if (span->interpMask & SPAN_INDEX) {
7092a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      interpolate_indexes(ctx, span);
7107956292a765910077f50352d7cd0174e1e66d26cBrian Paul      /* clear the bit - this allows the WriteMonoCISpan optimization below */
7117956292a765910077f50352d7cd0174e1e66d26cBrian Paul      span->interpMask &= ~SPAN_INDEX;
7127956292a765910077f50352d7cd0174e1e66d26cBrian Paul   }
71310f30eb43835c57c00783390a02d72daf4f78e26Brian Paul
7147956292a765910077f50352d7cd0174e1e66d26cBrian Paul   /* Fog */
7156e1666437ea091ecc50ab2b56d87129318f641d2Brian Paul   /* XXX try to simplify the fog code! */
7162a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   if (ctx->Fog.Enabled) {
7172a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      if ((span->arrayMask & SPAN_FOG) && !swrast->_PreferPixelFog)
7187956292a765910077f50352d7cd0174e1e66d26cBrian Paul         _mesa_fog_ci_pixels_with_array( ctx, span, span->fogArray,
7197956292a765910077f50352d7cd0174e1e66d26cBrian Paul                                         span->color.index);
7202a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      else if ((span->interpMask & SPAN_FOG) && !swrast->_PreferPixelFog)
7217956292a765910077f50352d7cd0174e1e66d26cBrian Paul         _mesa_fog_ci_pixels( ctx, span, span->color.index);
7222a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      else
7237956292a765910077f50352d7cd0174e1e66d26cBrian Paul         _mesa_depth_fog_ci_pixels( ctx, span, span->color.index);
724e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
725e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
7262a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   /* Antialias coverage application */
7272a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   if (span->arrayMask & SPAN_COVERAGE) {
7282a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      GLuint i;
7297956292a765910077f50352d7cd0174e1e66d26cBrian Paul      GLuint *index = span->color.index;
73010f30eb43835c57c00783390a02d72daf4f78e26Brian Paul      for (i = 0; i < span->end; i++) {
7312a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         ASSERT(span->coverage[i] < 16);
7322a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         index[i] = (index[i] & ~0xf) | ((GLuint) (span->coverage[i]));
7335071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paul      }
7342a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   }
7355071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paul
7362a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   if (swrast->_RasterMask & MULTI_DRAW_BIT) {
7372a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      /* draw to zero or two or more buffers */
738733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      multi_write_index_span(ctx, span);
739e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
740e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   else {
7412a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      /* normal situation: draw to exactly one buffer */
7422a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      if (ctx->Color.IndexLogicOpEnabled) {
743733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul         _mesa_logicop_ci_span(ctx, span, span->color.index);
74410f30eb43835c57c00783390a02d72daf4f78e26Brian Paul      }
7452a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul
7467956292a765910077f50352d7cd0174e1e66d26cBrian Paul      if (ctx->Color.IndexMask != 0xffffffff) {
747733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul         _mesa_mask_index_span(ctx, span, span->color.index);
748e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
7492a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul
7502a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      /* write pixels */
751733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      if (span->arrayMask & SPAN_XY) {
752733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul         /* array of pixel coords */
753733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul         if ((span->interpMask & SPAN_INDEX) && span->indexStep == 0) {
754733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul            /* all pixels have same color index */
755733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul            (*swrast->Driver.WriteMonoCIPixels)(ctx, span->end,
756733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul                                                span->xArray, span->yArray,
757733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul                                                FixedToInt(span->index),
758733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul                                                span->mask);
759733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul         }
760733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul         else {
761733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul            (*swrast->Driver.WriteCI32Pixels)(ctx, span->end, span->xArray,
762733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul                                              span->yArray, span->color.index,
763733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul                                              span->mask );
764733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul         }
7657956292a765910077f50352d7cd0174e1e66d26cBrian Paul      }
7667956292a765910077f50352d7cd0174e1e66d26cBrian Paul      else {
767733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul         /* horizontal run of pixels */
768733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul         if ((span->interpMask & SPAN_INDEX) && span->indexStep == 0) {
769733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul            /* all pixels have same color index */
770733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul            (*swrast->Driver.WriteMonoCISpan)(ctx, span->end, span->x, span->y,
771733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul                                              FixedToInt(span->index),
772733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul                                              span->mask);
773733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul         }
774733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul         else {
775733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul            (*swrast->Driver.WriteCI32Span)(ctx, span->end, span->x, span->y,
776733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul                                            span->color.index, span->mask);
777733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul         }
7787956292a765910077f50352d7cd0174e1e66d26cBrian Paul      }
779e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
7802a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul
7817956292a765910077f50352d7cd0174e1e66d26cBrian Paul   span->interpMask = origInterpMask;
7822a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   span->arrayMask = origArrayMask;
783e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell}
784e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
785e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
78679c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/**
7877956292a765910077f50352d7cd0174e1e66d26cBrian Paul * This function may modify any of the array values in the span.
7887956292a765910077f50352d7cd0174e1e66d26cBrian Paul * span->interpMask and span->arrayMask may be changed but will be restored
7897956292a765910077f50352d7cd0174e1e66d26cBrian Paul * to their original values before returning.
7905d2621928823a06006c1586efe78fe8bf65a7e1fBrian Paul */
7915071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paulvoid
79210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul_mesa_write_rgba_span( GLcontext *ctx, struct sw_span *span,
7932a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul		       GLenum primitive)
794e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell{
795cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell   SWcontext *swrast = SWRAST_CONTEXT(ctx);
7967956292a765910077f50352d7cd0174e1e66d26cBrian Paul   const GLuint colorMask = *((GLuint *) ctx->Color.ColorMask);
7977956292a765910077f50352d7cd0174e1e66d26cBrian Paul   const GLuint origInterpMask = span->interpMask;
7982a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   const GLuint origArrayMask = span->arrayMask;
7997956292a765910077f50352d7cd0174e1e66d26cBrian Paul   GLboolean monoColor;
8007956292a765910077f50352d7cd0174e1e66d26cBrian Paul
801733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul   ASSERT(span->end <= MAX_WIDTH);
8027956292a765910077f50352d7cd0174e1e66d26cBrian Paul   ASSERT((span->interpMask & span->arrayMask) == 0);
803ceb39f4f8dc4863fde17d668c752533a2184476eBrian Paul   ASSERT((span->interpMask | span->arrayMask) & SPAN_RGBA);
804bcb148de9201c7f90a68c7c46434e7ebf7204000Brian Paul#ifdef DEBUG
805733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul   if (ctx->Fog.Enabled)
806733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      ASSERT((span->interpMask | span->arrayMask) & SPAN_FOG);
807bcb148de9201c7f90a68c7c46434e7ebf7204000Brian Paul   if (ctx->Depth.Test)
808bcb148de9201c7f90a68c7c46434e7ebf7204000Brian Paul      ASSERT((span->interpMask | span->arrayMask) & SPAN_Z);
809bcb148de9201c7f90a68c7c46434e7ebf7204000Brian Paul#endif
810733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul
811733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul   /*
812bcb148de9201c7f90a68c7c46434e7ebf7204000Brian Paul   printf("%s()  interp 0x%x  array 0x%x  p=0x%x\n", __FUNCTION__, span->interpMask, span->arrayMask, primitive);
813733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul   */
814e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
815733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul   if (span->arrayMask & SPAN_MASK) {
816733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      /* mask was initialized by caller, probably glBitmap */
817733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      span->writeAll = GL_FALSE;
818733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul   }
819733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul   else {
820733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      MEMSET(span->mask, 1, span->end);
821733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      span->writeAll = GL_TRUE;
822733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul   }
823e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
8247956292a765910077f50352d7cd0174e1e66d26cBrian Paul   /* Determine if we have mono-chromatic colors */
8257956292a765910077f50352d7cd0174e1e66d26cBrian Paul   monoColor = (span->interpMask & SPAN_RGBA) &&
8267956292a765910077f50352d7cd0174e1e66d26cBrian Paul      span->redStep == 0 && span->greenStep == 0 &&
8277956292a765910077f50352d7cd0174e1e66d26cBrian Paul      span->blueStep == 0 && span->alphaStep == 0;
8287956292a765910077f50352d7cd0174e1e66d26cBrian Paul
829733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul   /* Clipping */
830733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul   if ((swrast->_RasterMask & CLIP_BIT) || (primitive == GL_BITMAP)
831b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul       || (primitive == GL_POINT) || (primitive == GL_LINE)) {
832733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      if (!clip_span(ctx, span)) {
83386ca15ece74ccb5a8f4d566a4b2c8024b178d73bBrian Paul         return;
834e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
835e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
836e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
837b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul#ifdef DEBUG
838b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul   if (span->arrayMask & SPAN_XY) {
839b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul      int i;
840b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul      for (i = 0; i < span->end; i++) {
841b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul         if (span->mask[i]) {
842b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul            assert(span->xArray[i] >= ctx->DrawBuffer->_Xmin);
843b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul            assert(span->xArray[i] < ctx->DrawBuffer->_Xmax);
844b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul            assert(span->yArray[i] >= ctx->DrawBuffer->_Ymin);
845b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul            assert(span->yArray[i] < ctx->DrawBuffer->_Ymax);
846b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul         }
847b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul      }
848b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul   }
849b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul#endif
850b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul
851e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   /* Polygon Stippling */
8527956292a765910077f50352d7cd0174e1e66d26cBrian Paul   if (ctx->Polygon.StippleFlag && primitive == GL_POLYGON) {
8537956292a765910077f50352d7cd0174e1e66d26cBrian Paul      stipple_polygon_span(ctx, span);
85410f30eb43835c57c00783390a02d72daf4f78e26Brian Paul   }
85510f30eb43835c57c00783390a02d72daf4f78e26Brian Paul
856e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   /* Do the alpha test */
857e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   if (ctx->Color.AlphaEnabled) {
858ceb39f4f8dc4863fde17d668c752533a2184476eBrian Paul      if (!_mesa_alpha_test(ctx, span)) {
8597956292a765910077f50352d7cd0174e1e66d26cBrian Paul         span->interpMask = origInterpMask;
8602a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         span->arrayMask = origArrayMask;
861e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell	 return;
862e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
86310f30eb43835c57c00783390a02d72daf4f78e26Brian Paul   }
86410f30eb43835c57c00783390a02d72daf4f78e26Brian Paul
865f1e236987829393c81dc86ea19cb49eefe190317Brian Paul   /* Stencil and Z testing */
866f1e236987829393c81dc86ea19cb49eefe190317Brian Paul   if (ctx->Stencil.Enabled || ctx->Depth.Test) {
867f1e236987829393c81dc86ea19cb49eefe190317Brian Paul      if (span->interpMask & SPAN_Z)
868f1e236987829393c81dc86ea19cb49eefe190317Brian Paul         interpolate_z(ctx, span);
869f1e236987829393c81dc86ea19cb49eefe190317Brian Paul
870f1e236987829393c81dc86ea19cb49eefe190317Brian Paul      if (ctx->Stencil.Enabled) {
871f1e236987829393c81dc86ea19cb49eefe190317Brian Paul         if (!_mesa_stencil_and_ztest_span(ctx, span)) {
8727956292a765910077f50352d7cd0174e1e66d26cBrian Paul            span->interpMask = origInterpMask;
873f1e236987829393c81dc86ea19cb49eefe190317Brian Paul            span->arrayMask = origArrayMask;
874f1e236987829393c81dc86ea19cb49eefe190317Brian Paul            return;
87510f30eb43835c57c00783390a02d72daf4f78e26Brian Paul         }
87610f30eb43835c57c00783390a02d72daf4f78e26Brian Paul      }
87710f30eb43835c57c00783390a02d72daf4f78e26Brian Paul      else {
878f1e236987829393c81dc86ea19cb49eefe190317Brian Paul         ASSERT(ctx->Depth.Test);
879f1e236987829393c81dc86ea19cb49eefe190317Brian Paul         ASSERT(span->arrayMask & SPAN_Z);
880f1e236987829393c81dc86ea19cb49eefe190317Brian Paul         /* regular depth testing */
881f1e236987829393c81dc86ea19cb49eefe190317Brian Paul         if (!_mesa_depth_test_span(ctx, span)) {
8827956292a765910077f50352d7cd0174e1e66d26cBrian Paul            span->interpMask = origInterpMask;
883f1e236987829393c81dc86ea19cb49eefe190317Brian Paul            span->arrayMask = origArrayMask;
884f1e236987829393c81dc86ea19cb49eefe190317Brian Paul            return;
88510f30eb43835c57c00783390a02d72daf4f78e26Brian Paul         }
88610f30eb43835c57c00783390a02d72daf4f78e26Brian Paul      }
887e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
888e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
889e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   /* if we get here, something passed the depth test */
890e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   ctx->OcclusionResult = GL_TRUE;
891e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
8927956292a765910077f50352d7cd0174e1e66d26cBrian Paul   /* can't abort span-writing until after occlusion testing */
8937956292a765910077f50352d7cd0174e1e66d26cBrian Paul   if (colorMask == 0x0) {
8947956292a765910077f50352d7cd0174e1e66d26cBrian Paul      span->interpMask = origInterpMask;
8957956292a765910077f50352d7cd0174e1e66d26cBrian Paul      span->arrayMask = origArrayMask;
8967956292a765910077f50352d7cd0174e1e66d26cBrian Paul      return;
8977956292a765910077f50352d7cd0174e1e66d26cBrian Paul   }
8987956292a765910077f50352d7cd0174e1e66d26cBrian Paul
899ceb39f4f8dc4863fde17d668c752533a2184476eBrian Paul   /* Now we may need to interpolate the colors */
900ceb39f4f8dc4863fde17d668c752533a2184476eBrian Paul   if ((span->interpMask & SPAN_RGBA) && (span->arrayMask & SPAN_RGBA) == 0) {
901ceb39f4f8dc4863fde17d668c752533a2184476eBrian Paul      interpolate_colors(ctx, span);
902ceb39f4f8dc4863fde17d668c752533a2184476eBrian Paul      /* clear the bit - this allows the WriteMonoCISpan optimization below */
903ceb39f4f8dc4863fde17d668c752533a2184476eBrian Paul      span->interpMask &= ~SPAN_RGBA;
904ceb39f4f8dc4863fde17d668c752533a2184476eBrian Paul   }
905ceb39f4f8dc4863fde17d668c752533a2184476eBrian Paul
9066e1666437ea091ecc50ab2b56d87129318f641d2Brian Paul   /* Fog */
9076e1666437ea091ecc50ab2b56d87129318f641d2Brian Paul   /* XXX try to simplify the fog code! */
908b38ad54c41aec2d08fdd26a4a8ea4dcdca8b1dfdBrian Paul   if (ctx->Fog.Enabled) {
909733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      if ((span->arrayMask & SPAN_FOG) && !swrast->_PreferPixelFog) {
9107956292a765910077f50352d7cd0174e1e66d26cBrian Paul	 _mesa_fog_rgba_pixels_with_array(ctx, span, span->fogArray,
9117956292a765910077f50352d7cd0174e1e66d26cBrian Paul                                          span->color.rgba);
912733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      }
913733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      else if ((span->interpMask & SPAN_FOG) && !swrast->_PreferPixelFog) {
9147956292a765910077f50352d7cd0174e1e66d26cBrian Paul         _mesa_fog_rgba_pixels(ctx, span, span->color.rgba);
915733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      }
916f1e236987829393c81dc86ea19cb49eefe190317Brian Paul      else {
917f1e236987829393c81dc86ea19cb49eefe190317Brian Paul         if ((span->interpMask & SPAN_Z) && (span->arrayMask & SPAN_Z) == 0)
918f1e236987829393c81dc86ea19cb49eefe190317Brian Paul            interpolate_z(ctx, span);
9197956292a765910077f50352d7cd0174e1e66d26cBrian Paul         _mesa_depth_fog_rgba_pixels(ctx, span, span->color.rgba);
920f1e236987829393c81dc86ea19cb49eefe190317Brian Paul      }
9217956292a765910077f50352d7cd0174e1e66d26cBrian Paul      monoColor = GL_FALSE;
922b38ad54c41aec2d08fdd26a4a8ea4dcdca8b1dfdBrian Paul   }
923b38ad54c41aec2d08fdd26a4a8ea4dcdca8b1dfdBrian Paul
9245071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paul   /* Antialias coverage application */
9252a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   if (span->arrayMask & SPAN_COVERAGE) {
9267956292a765910077f50352d7cd0174e1e66d26cBrian Paul      GLchan (*rgba)[4] = span->color.rgba;
9275071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paul      GLuint i;
92810f30eb43835c57c00783390a02d72daf4f78e26Brian Paul      for (i = 0; i < span->end; i++) {
92910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul         rgba[i][ACOMP] = (GLchan) (rgba[i][ACOMP] * span->coverage[i]);
9305071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paul      }
9317956292a765910077f50352d7cd0174e1e66d26cBrian Paul      monoColor = GL_FALSE;
9325071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paul   }
9335071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paul
934cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell   if (swrast->_RasterMask & MULTI_DRAW_BIT) {
935733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      multi_write_rgba_span(ctx, span);
936e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
937e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   else {
938e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      /* normal: write to exactly one buffer */
939733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul#if 1
940e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      if (ctx->Color.ColorLogicOpEnabled) {
941733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul         _mesa_logicop_rgba_span(ctx, span, span->color.rgba);
9427956292a765910077f50352d7cd0174e1e66d26cBrian Paul         monoColor = GL_FALSE;
943e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
944e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      else if (ctx->Color.BlendEnabled) {
945733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul         _mesa_blend_span(ctx, span, span->color.rgba);
9467956292a765910077f50352d7cd0174e1e66d26cBrian Paul         monoColor = GL_FALSE;
947e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
948733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul#endif
949e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      /* Color component masking */
9507956292a765910077f50352d7cd0174e1e66d26cBrian Paul      if (colorMask != 0xffffffff) {
951733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul         _mesa_mask_rgba_span(ctx, span, span->color.rgba);
9527956292a765910077f50352d7cd0174e1e66d26cBrian Paul         monoColor = GL_FALSE;
953e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
954e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
955e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      /* write pixels */
956733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      if (span->arrayMask & SPAN_XY) {
957733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul         /* array of pixel coords */
958733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul         /* XXX test for mono color */
959733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul         (*swrast->Driver.WriteRGBAPixels)(ctx, span->end, span->xArray,
960733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul             span->yArray, (const GLchan (*)[4]) span->color.rgba, span->mask);
961733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul         if (SWRAST_CONTEXT(ctx)->_RasterMask & ALPHABUF_BIT) {
962733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul            _mesa_write_alpha_pixels(ctx, span->end,
963733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul                                     span->xArray, span->yArray,
964733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul                                     (const GLchan (*)[4]) span->color.rgba,
965733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul                                     span->mask);
966733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul         }
967e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
968e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      else {
969733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul         /* horizontal run of pixels */
970733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul         if (monoColor) {
971733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul            /* all pixels have same color */
972733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul            GLchan color[4];
973733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul            color[RCOMP] = FixedToChan(span->red);
974733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul            color[GCOMP] = FixedToChan(span->green);
975733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul            color[BCOMP] = FixedToChan(span->blue);
976733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul            color[ACOMP] = FixedToChan(span->alpha);
977733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul            (*swrast->Driver.WriteMonoRGBASpan)(ctx, span->end, span->x,
978733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul                                                span->y, color, span->mask);
979733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul            /* XXX software alpha buffer writes! */
980733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul         }
981733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul         else {
982733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul            /* each pixel is a different color */
983733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul            (*swrast->Driver.WriteRGBASpan)(ctx, span->end, span->x, span->y,
9847956292a765910077f50352d7cd0174e1e66d26cBrian Paul                      (const GLchan (*)[4]) span->color.rgba,
985733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul                      span->writeAll ? ((const GLubyte *) NULL) : span->mask);
986733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul            if (swrast->_RasterMask & ALPHABUF_BIT) {
987733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul               _mesa_write_alpha_span(ctx, span->end, span->x, span->y,
9887956292a765910077f50352d7cd0174e1e66d26cBrian Paul                      (const GLchan (*)[4]) span->color.rgba,
989733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul                      span->writeAll ? ((const GLubyte *) NULL) : span->mask);
990733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul            }
991733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul         }
992e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
993e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
994e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
9957956292a765910077f50352d7cd0174e1e66d26cBrian Paul   span->interpMask = origInterpMask;
9967956292a765910077f50352d7cd0174e1e66d26cBrian Paul   span->arrayMask = origArrayMask;
9977956292a765910077f50352d7cd0174e1e66d26cBrian Paul}
998e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
999e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
100079c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/**
1001e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Add specular color to base color.  This is used only when
1002f1e236987829393c81dc86ea19cb49eefe190317Brian Paul * GL_LIGHT_MODEL_COLOR_CONTROL = GL_SEPARATE_SPECULAR_COLOR.
1003e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */
10045071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paulstatic void
1005f1e236987829393c81dc86ea19cb49eefe190317Brian Pauladd_colors(GLuint n, GLchan rgba[][4], GLchan specular[][4] )
1006e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell{
1007e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   GLuint i;
1008f1e236987829393c81dc86ea19cb49eefe190317Brian Paul   for (i = 0; i < n; i++) {
10094fa5c1966a985f81c615a9f5ef2f64dd466b252aBrian Paul#if CHAN_TYPE == GL_FLOAT
10104fa5c1966a985f81c615a9f5ef2f64dd466b252aBrian Paul      /* no clamping */
1011f1e236987829393c81dc86ea19cb49eefe190317Brian Paul      rgba[i][RCOMP] += specular[i][RCOMP];
1012f1e236987829393c81dc86ea19cb49eefe190317Brian Paul      rgba[i][GCOMP] += specular[i][GCOMP];
1013f1e236987829393c81dc86ea19cb49eefe190317Brian Paul      rgba[i][BCOMP] += specular[i][BCOMP];
10144fa5c1966a985f81c615a9f5ef2f64dd466b252aBrian Paul#else
1015f1e236987829393c81dc86ea19cb49eefe190317Brian Paul      GLint r = rgba[i][RCOMP] + specular[i][RCOMP];
1016f1e236987829393c81dc86ea19cb49eefe190317Brian Paul      GLint g = rgba[i][GCOMP] + specular[i][GCOMP];
1017f1e236987829393c81dc86ea19cb49eefe190317Brian Paul      GLint b = rgba[i][BCOMP] + specular[i][BCOMP];
1018e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      rgba[i][RCOMP] = (GLchan) MIN2(r, CHAN_MAX);
1019e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      rgba[i][GCOMP] = (GLchan) MIN2(g, CHAN_MAX);
1020e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      rgba[i][BCOMP] = (GLchan) MIN2(b, CHAN_MAX);
10214fa5c1966a985f81c615a9f5ef2f64dd466b252aBrian Paul#endif
1022e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
1023e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell}
1024e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
1025e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
102679c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/**
1027f1e236987829393c81dc86ea19cb49eefe190317Brian Paul * This function may modify any of the array values in the span.
10287956292a765910077f50352d7cd0174e1e66d26cBrian Paul * span->interpMask and span->arrayMask may be changed but will be restored
10297956292a765910077f50352d7cd0174e1e66d26cBrian Paul * to their original values before returning.
103078940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul */
103178940758e90069ceaca2b6cddb6438488fbad5ccBrian Paulvoid
103278940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul_mesa_write_texture_span( GLcontext *ctx, struct sw_span *span,
1033f1e236987829393c81dc86ea19cb49eefe190317Brian Paul                          GLenum primitive )
103478940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul{
103578940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul   const GLuint colorMask = *((GLuint *) ctx->Color.ColorMask);
103678940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul   SWcontext *swrast = SWRAST_CONTEXT(ctx);
1037f1e236987829393c81dc86ea19cb49eefe190317Brian Paul   const GLuint origArrayMask = span->arrayMask;
1038f1e236987829393c81dc86ea19cb49eefe190317Brian Paul
1039733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul   ASSERT(span->end <= MAX_WIDTH);
10407956292a765910077f50352d7cd0174e1e66d26cBrian Paul   ASSERT((span->interpMask & span->arrayMask) == 0);
1041f1e236987829393c81dc86ea19cb49eefe190317Brian Paul   ASSERT(ctx->Texture._ReallyEnabled);
104278940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul
1043ceb39f4f8dc4863fde17d668c752533a2184476eBrian Paul   /*
1044ceb39f4f8dc4863fde17d668c752533a2184476eBrian Paul   printf("%s()  interp 0x%x  array 0x%x\n", __FUNCTION__, span->interpMask, span->arrayMask);
1045ceb39f4f8dc4863fde17d668c752533a2184476eBrian Paul   */
1046ceb39f4f8dc4863fde17d668c752533a2184476eBrian Paul
1047733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul   if (span->arrayMask & SPAN_MASK) {
1048733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      /* mask was initialized by caller, probably glBitmap */
1049733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      span->writeAll = GL_FALSE;
1050733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul   }
1051733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul   else {
1052733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      MEMSET(span->mask, 1, span->end);
1053733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      span->writeAll = GL_TRUE;
105478940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul   }
105578940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul
1056733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul   /* Clipping */
1057733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul   if ((swrast->_RasterMask & CLIP_BIT) || (primitive == GL_BITMAP)
1058b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul       || (primitive == GL_POINT) || (primitive == GL_LINE)) {
1059733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      if (!clip_span(ctx, span)) {
1060733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul	 return;
106178940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul      }
106278940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul   }
106378940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul
1064b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul#ifdef DEBUG
1065b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul   if (span->arrayMask & SPAN_XY) {
1066b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul      int i;
1067b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul      for (i = 0; i < span->end; i++) {
1068b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul         if (span->mask[i]) {
1069b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul            assert(span->xArray[i] >= ctx->DrawBuffer->_Xmin);
1070b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul            assert(span->xArray[i] < ctx->DrawBuffer->_Xmax);
1071b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul            assert(span->yArray[i] >= ctx->DrawBuffer->_Ymin);
1072b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul            assert(span->yArray[i] < ctx->DrawBuffer->_Ymax);
1073b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul         }
1074b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul      }
1075b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul   }
1076b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul#endif
1077b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul
107878940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul   /* Polygon Stippling */
1079733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul   if (ctx->Polygon.StippleFlag && primitive == GL_POLYGON) {
1080733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      stipple_polygon_span(ctx, span);
108178940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul   }
108278940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul
1083f1e236987829393c81dc86ea19cb49eefe190317Brian Paul   /* Need texture coordinates now */
1084f1e236987829393c81dc86ea19cb49eefe190317Brian Paul   if ((span->interpMask & SPAN_TEXTURE)
1085f1e236987829393c81dc86ea19cb49eefe190317Brian Paul       && (span->arrayMask & SPAN_TEXTURE) == 0)
1086f1e236987829393c81dc86ea19cb49eefe190317Brian Paul      interpolate_texcoords(ctx, span);
108778940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul
108878940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul   /* Texture with alpha test */
108978940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul   if (ctx->Color.AlphaEnabled) {
1090f1e236987829393c81dc86ea19cb49eefe190317Brian Paul
1091f1e236987829393c81dc86ea19cb49eefe190317Brian Paul      /* Now we need the rgba array, fill it in if needed */
1092f1e236987829393c81dc86ea19cb49eefe190317Brian Paul      if ((span->interpMask & SPAN_RGBA) && (span->arrayMask & SPAN_RGBA) == 0)
1093f1e236987829393c81dc86ea19cb49eefe190317Brian Paul         interpolate_colors(ctx, span);
1094f1e236987829393c81dc86ea19cb49eefe190317Brian Paul
109578940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul      /* Texturing without alpha is done after depth-testing which
1096f1e236987829393c81dc86ea19cb49eefe190317Brian Paul       * gives a potential speed-up.
1097f1e236987829393c81dc86ea19cb49eefe190317Brian Paul       */
1098f1e236987829393c81dc86ea19cb49eefe190317Brian Paul      _swrast_multitexture_fragments( ctx, span );
109978940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul
110078940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul      /* Do the alpha test */
1101ceb39f4f8dc4863fde17d668c752533a2184476eBrian Paul      if (!_mesa_alpha_test(ctx, span)) {
1102f1e236987829393c81dc86ea19cb49eefe190317Brian Paul         span->arrayMask = origArrayMask;
1103ceb39f4f8dc4863fde17d668c752533a2184476eBrian Paul	 return;
110478940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul      }
110578940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul   }
110678940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul
1107f1e236987829393c81dc86ea19cb49eefe190317Brian Paul   /* Stencil and Z testing */
1108f1e236987829393c81dc86ea19cb49eefe190317Brian Paul   if (ctx->Stencil.Enabled || ctx->Depth.Test) {
1109f1e236987829393c81dc86ea19cb49eefe190317Brian Paul      if (span->interpMask & SPAN_Z)
1110f1e236987829393c81dc86ea19cb49eefe190317Brian Paul         interpolate_z(ctx, span);
111178940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul
111271340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul      if (ctx->Stencil.Enabled) {
1113f1e236987829393c81dc86ea19cb49eefe190317Brian Paul         if (!_mesa_stencil_and_ztest_span(ctx, span)) {
1114f1e236987829393c81dc86ea19cb49eefe190317Brian Paul            span->arrayMask = origArrayMask;
111510f30eb43835c57c00783390a02d72daf4f78e26Brian Paul            return;
1116f1e236987829393c81dc86ea19cb49eefe190317Brian Paul         }
111771340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul      }
1118f1e236987829393c81dc86ea19cb49eefe190317Brian Paul      else {
1119f1e236987829393c81dc86ea19cb49eefe190317Brian Paul         ASSERT(ctx->Depth.Test);
1120f1e236987829393c81dc86ea19cb49eefe190317Brian Paul         ASSERT(span->arrayMask & SPAN_Z);
112110f30eb43835c57c00783390a02d72daf4f78e26Brian Paul         /* regular depth testing */
1122f1e236987829393c81dc86ea19cb49eefe190317Brian Paul         if (!_mesa_depth_test_span(ctx, span)) {
1123f1e236987829393c81dc86ea19cb49eefe190317Brian Paul            span->arrayMask = origArrayMask;
112410f30eb43835c57c00783390a02d72daf4f78e26Brian Paul            return;
1125f1e236987829393c81dc86ea19cb49eefe190317Brian Paul         }
112671340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul      }
112771340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul   }
112871340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul
1129f1e236987829393c81dc86ea19cb49eefe190317Brian Paul   /* if we get here, some fragments passed the depth test */
113071340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul   ctx->OcclusionResult = GL_TRUE;
113171340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul
1132f1e236987829393c81dc86ea19cb49eefe190317Brian Paul   /* We had to wait until now to check for glColorMask(F,F,F,F) because of
1133f1e236987829393c81dc86ea19cb49eefe190317Brian Paul    * the occlusion test.
1134f1e236987829393c81dc86ea19cb49eefe190317Brian Paul    */
1135f1e236987829393c81dc86ea19cb49eefe190317Brian Paul   if (colorMask == 0x0) {
1136f1e236987829393c81dc86ea19cb49eefe190317Brian Paul      span->arrayMask = origArrayMask;
1137f1e236987829393c81dc86ea19cb49eefe190317Brian Paul      return;
113871340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul   }
113971340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul
1140f1e236987829393c81dc86ea19cb49eefe190317Brian Paul   /* Texture without alpha test */
1141f1e236987829393c81dc86ea19cb49eefe190317Brian Paul   if (!ctx->Color.AlphaEnabled) {
114271340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul
1143f1e236987829393c81dc86ea19cb49eefe190317Brian Paul      /* Now we need the rgba array, fill it in if needed */
1144f1e236987829393c81dc86ea19cb49eefe190317Brian Paul      if ((span->interpMask & SPAN_RGBA) && (span->arrayMask & SPAN_RGBA) == 0)
1145f1e236987829393c81dc86ea19cb49eefe190317Brian Paul         interpolate_colors(ctx, span);
114671340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul
1147f1e236987829393c81dc86ea19cb49eefe190317Brian Paul      _swrast_multitexture_fragments( ctx, span );
114871340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul   }
114971340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul
1150f1e236987829393c81dc86ea19cb49eefe190317Brian Paul   ASSERT(span->arrayMask & SPAN_RGBA);
11512ef866d1fc0a5cc5ef8543d65744dfd4da4dbbafBrian Paul
1152f1e236987829393c81dc86ea19cb49eefe190317Brian Paul   /* Add base and specular colors */
1153f1e236987829393c81dc86ea19cb49eefe190317Brian Paul   if (ctx->Fog.ColorSumEnabled ||
1154f1e236987829393c81dc86ea19cb49eefe190317Brian Paul       (ctx->Light.Enabled &&
1155f1e236987829393c81dc86ea19cb49eefe190317Brian Paul        ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR)) {
1156f1e236987829393c81dc86ea19cb49eefe190317Brian Paul      if (span->interpMask & SPAN_SPEC) {
1157f1e236987829393c81dc86ea19cb49eefe190317Brian Paul         interpolate_specular(ctx, span);
115871340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul      }
1159f1e236987829393c81dc86ea19cb49eefe190317Brian Paul      ASSERT(span->arrayMask & SPAN_SPEC);
1160f1e236987829393c81dc86ea19cb49eefe190317Brian Paul      add_colors( span->end, span->color.rgba, span->specArray );
116171340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul   }
116271340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul
11636e1666437ea091ecc50ab2b56d87129318f641d2Brian Paul   /* Fog */
11646e1666437ea091ecc50ab2b56d87129318f641d2Brian Paul   /* XXX try to simplify the fog code! */
116571340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul   if (ctx->Fog.Enabled) {
1166f1e236987829393c81dc86ea19cb49eefe190317Brian Paul      if ((span->arrayMask & SPAN_FOG) && !swrast->_PreferPixelFog)
1167f1e236987829393c81dc86ea19cb49eefe190317Brian Paul	 _mesa_fog_rgba_pixels_with_array( ctx, span, span->fogArray,
1168f1e236987829393c81dc86ea19cb49eefe190317Brian Paul                                           span->color.rgba);
1169f1e236987829393c81dc86ea19cb49eefe190317Brian Paul      else if ((span->interpMask & SPAN_FOG)  &&  !swrast->_PreferPixelFog)
1170f1e236987829393c81dc86ea19cb49eefe190317Brian Paul	 _mesa_fog_rgba_pixels( ctx, span, span->color.rgba );
1171f1e236987829393c81dc86ea19cb49eefe190317Brian Paul      else {
1172f1e236987829393c81dc86ea19cb49eefe190317Brian Paul         if ((span->interpMask & SPAN_Z) && (span->arrayMask & SPAN_Z) == 0)
1173f1e236987829393c81dc86ea19cb49eefe190317Brian Paul            interpolate_z(ctx, span);
1174f1e236987829393c81dc86ea19cb49eefe190317Brian Paul	 _mesa_depth_fog_rgba_pixels(ctx, span, span->color.rgba);
1175f1e236987829393c81dc86ea19cb49eefe190317Brian Paul      }
117671340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul   }
1177f1e236987829393c81dc86ea19cb49eefe190317Brian Paul
117871340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul   /* Antialias coverage application */
11792a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   if (span->arrayMask & SPAN_COVERAGE) {
1180f1e236987829393c81dc86ea19cb49eefe190317Brian Paul      GLchan (*rgba)[4] = span->color.rgba;
118171340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul      GLuint i;
118210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul      for (i = 0; i < span->end; i++) {
118310f30eb43835c57c00783390a02d72daf4f78e26Brian Paul         rgba[i][ACOMP] = (GLchan) (rgba[i][ACOMP] * span->coverage[i]);
118471340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul      }
118571340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul   }
118671340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul
118771340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul   if (swrast->_RasterMask & MULTI_DRAW_BIT) {
1188733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      multi_write_rgba_span(ctx, span);
118971340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul   }
119071340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul   else {
119171340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul      /* normal: write to exactly one buffer */
119271340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul      if (ctx->Color.ColorLogicOpEnabled) {
1193733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul         _mesa_logicop_rgba_span(ctx, span, span->color.rgba);
119471340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul      }
119571340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul      else  if (ctx->Color.BlendEnabled) {
1196733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul         _mesa_blend_span(ctx, span, span->color.rgba);
119771340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul      }
119871340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul
1199f1e236987829393c81dc86ea19cb49eefe190317Brian Paul      if (colorMask != 0xffffffff) {
1200733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul         _mesa_mask_rgba_span(ctx, span, span->color.rgba);
120171340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul      }
120271340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul
1203733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul
1204733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      if (span->arrayMask & SPAN_XY) {
1205733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul         /* array of pixel coords */
1206733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul         (*swrast->Driver.WriteRGBAPixels)(ctx, span->end, span->xArray,
1207733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul             span->yArray, (const GLchan (*)[4]) span->color.rgba, span->mask);
1208733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul         if (SWRAST_CONTEXT(ctx)->_RasterMask & ALPHABUF_BIT) {
1209733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul            _mesa_write_alpha_pixels(ctx, span->end,
1210733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul                                     span->xArray, span->yArray,
1211733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul                                     (const GLchan (*)[4]) span->color.rgba,
1212733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul                                     span->mask);
1213733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul         }
1214733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      }
1215733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      else {
1216733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul         /* horizontal run of pixels */
1217733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul         (*swrast->Driver.WriteRGBASpan)(ctx, span->end, span->x, span->y,
1218f1e236987829393c81dc86ea19cb49eefe190317Brian Paul                                       (const GLchan (*)[4]) span->color.rgba,
1219733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul                                       span->writeAll ? NULL : span->mask);
1220733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul         if (swrast->_RasterMask & ALPHABUF_BIT) {
1221733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul            _mesa_write_alpha_span(ctx, span->end, span->x, span->y,
1222733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul                                   (const GLchan (*)[4]) span->color.rgba,
1223733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul                                   span->writeAll ? NULL : span->mask);
1224733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul         }
122571340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul      }
122671340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul   }
122771340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul
1228f1e236987829393c81dc86ea19cb49eefe190317Brian Paul   span->arrayMask = origArrayMask;
122910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul}
123010f30eb43835c57c00783390a02d72daf4f78e26Brian Paul
1231e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
1232e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
123379c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/**
1234e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Read RGBA pixels from frame buffer.  Clipping will be done to prevent
1235e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * reading ouside the buffer's boundaries.
1236e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */
12375071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paulvoid
12385071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paul_mesa_read_rgba_span( GLcontext *ctx, GLframebuffer *buffer,
12395071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paul                      GLuint n, GLint x, GLint y, GLchan rgba[][4] )
1240e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell{
1241709892459922a32096fe9dd8261d0d92337bb02fKeith Whitwell   SWcontext *swrast = SWRAST_CONTEXT(ctx);
1242e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   if (y < 0 || y >= buffer->Height
1243e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell       || x + (GLint) n < 0 || x >= buffer->Width) {
1244e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      /* completely above, below, or right */
1245e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      /* XXX maybe leave undefined? */
1246e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      BZERO(rgba, 4 * n * sizeof(GLchan));
1247e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
1248e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   else {
1249e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      GLint skip, length;
1250e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      if (x < 0) {
1251e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         /* left edge clippping */
1252e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         skip = -x;
1253e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         length = (GLint) n - skip;
1254e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         if (length < 0) {
1255e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            /* completely left of window */
1256e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            return;
1257e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         }
1258e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         if (length > buffer->Width) {
1259e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            length = buffer->Width;
1260e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         }
1261e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
1262e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      else if ((GLint) (x + n) > buffer->Width) {
1263e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         /* right edge clipping */
1264e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         skip = 0;
1265e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         length = buffer->Width - x;
1266e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         if (length < 0) {
1267e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            /* completely to right of window */
1268e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            return;
1269e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         }
1270e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
1271e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      else {
1272e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         /* no clipping */
1273e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         skip = 0;
1274e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         length = (GLint) n;
1275e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
1276e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
1277709892459922a32096fe9dd8261d0d92337bb02fKeith Whitwell      (*swrast->Driver.ReadRGBASpan)( ctx, length, x + skip, y, rgba + skip );
1278e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      if (buffer->UseSoftwareAlphaBuffers) {
1279733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul         _mesa_read_alpha_span(ctx, length, x + skip, y, rgba + skip);
1280e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
1281e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
1282e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell}
1283e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
1284e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
128579c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/**
1286e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Read CI pixels from frame buffer.  Clipping will be done to prevent
1287e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * reading ouside the buffer's boundaries.
1288e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */
12895071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paulvoid
12905071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paul_mesa_read_index_span( GLcontext *ctx, GLframebuffer *buffer,
12915071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paul                       GLuint n, GLint x, GLint y, GLuint indx[] )
1292e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell{
1293709892459922a32096fe9dd8261d0d92337bb02fKeith Whitwell   SWcontext *swrast = SWRAST_CONTEXT(ctx);
1294e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   if (y < 0 || y >= buffer->Height
1295e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell       || x + (GLint) n < 0 || x >= buffer->Width) {
1296e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      /* completely above, below, or right */
1297e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      BZERO(indx, n * sizeof(GLuint));
1298e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
1299e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   else {
1300e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      GLint skip, length;
1301e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      if (x < 0) {
1302e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         /* left edge clippping */
1303e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         skip = -x;
1304e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         length = (GLint) n - skip;
1305e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         if (length < 0) {
1306e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            /* completely left of window */
1307e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            return;
1308e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         }
1309e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         if (length > buffer->Width) {
1310e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            length = buffer->Width;
1311e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         }
1312e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
1313e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      else if ((GLint) (x + n) > buffer->Width) {
1314e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         /* right edge clipping */
1315e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         skip = 0;
1316e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         length = buffer->Width - x;
1317e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         if (length < 0) {
1318e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            /* completely to right of window */
1319e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            return;
1320e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         }
1321e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
1322e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      else {
1323e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         /* no clipping */
1324e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         skip = 0;
1325e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         length = (GLint) n;
1326e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
1327e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
1328709892459922a32096fe9dd8261d0d92337bb02fKeith Whitwell      (*swrast->Driver.ReadCI32Span)( ctx, length, skip + x, y, indx + skip );
1329e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
1330e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell}
1331