s_span.c revision 18fa367ac6e035341f5eb86ecc4231124b2921e3
1e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell/*
2e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Mesa 3-D graphics library
327558a160a9fe91745728d7626995cd88f8fe339Brian Paul * Version:  5.1
422144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes *
56a98bef96189fbacc326ad9e407c1d4423aa8572Brian Paul * Copyright (C) 1999-2003  Brian Paul   All Rights Reserved.
622144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes *
7e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Permission is hereby granted, free of charge, to any person obtaining a
8e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * copy of this software and associated documentation files (the "Software"),
9e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * to deal in the Software without restriction, including without limitation
10e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * and/or sell copies of the Software, and to permit persons to whom the
12e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Software is furnished to do so, subject to the following conditions:
1322144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes *
14e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * The above copyright notice and this permission notice shall be included
15e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * in all copies or substantial portions of the Software.
1622144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes *
17e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
20e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */
24e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
25e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
2679c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/**
27bcb148de9201c7f90a68c7c46434e7ebf7204000Brian Paul * \file swrast/s_span.c
2879c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul * \brief Span processing functions used by all rasterization functions.
2979c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul * This is where all the per-fragment tests are performed
3079c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul * \author Brian Paul
31e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */
32e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
33e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "glheader.h"
34e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "colormac.h"
3571340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul#include "context.h"
36e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "macros.h"
373c63452e64df7e10aa073c6c3b9492b1d7dabbb8Brian Paul#include "imports.h"
38e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
39e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_alpha.h"
40e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_alphabuf.h"
41e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_blend.h"
42cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell#include "s_context.h"
43e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_depth.h"
44e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_fog.h"
45e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_logic.h"
46e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_masking.h"
47610d59981a9f43fefe29b34ef19c184d28e2bef5Brian Paul#include "s_nvfragprog.h"
48e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_span.h"
49e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_stencil.h"
50e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_texture.h"
51e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
522a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul
5379c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/**
542a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul * Init span's Z interpolation values to the RasterPos Z.
552a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul * Used during setup for glDraw/CopyPixels.
562a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul */
572a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paulvoid
5845bc887da226403f2c41077e40ca38b6f60f1359Brian Paul_swrast_span_default_z( GLcontext *ctx, struct sw_span *span )
592a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul{
602a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   if (ctx->Visual.depthBits <= 16)
61ad8cd6111e022c90c93df106c0fde6f64d205816Brian Paul      span->z = FloatToFixed(ctx->Current.RasterPos[2] * ctx->DepthMax + 0.5F);
622a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   else
63ad8cd6111e022c90c93df106c0fde6f64d205816Brian Paul      span->z = (GLint) (ctx->Current.RasterPos[2] * ctx->DepthMax + 0.5F);
642a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   span->zStep = 0;
652a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   span->interpMask |= SPAN_Z;
662a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul}
672a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul
682a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul
6979c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/**
702a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul * Init span's fog interpolation values to the RasterPos fog.
712a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul * Used during setup for glDraw/CopyPixels.
722a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul */
732a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paulvoid
7445bc887da226403f2c41077e40ca38b6f60f1359Brian Paul_swrast_span_default_fog( GLcontext *ctx, struct sw_span *span )
752a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul{
7645bc887da226403f2c41077e40ca38b6f60f1359Brian Paul   span->fog = _swrast_z_to_fogfactor(ctx, ctx->Current.RasterDistance);
7754e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul   span->fogStep = span->dfogdx = span->dfogdy = 0.0F;
782a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   span->interpMask |= SPAN_FOG;
792a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul}
802a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul
812a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul
8279c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/**
832a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul * Init span's color or index interpolation values to the RasterPos color.
842a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul * Used during setup for glDraw/CopyPixels.
852a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul */
862a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paulvoid
8745bc887da226403f2c41077e40ca38b6f60f1359Brian Paul_swrast_span_default_color( GLcontext *ctx, struct sw_span *span )
882a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul{
892a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   if (ctx->Visual.rgbMode) {
902a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      GLchan r, g, b, a;
912a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      UNCLAMPED_FLOAT_TO_CHAN(r, ctx->Current.RasterColor[0]);
922a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      UNCLAMPED_FLOAT_TO_CHAN(g, ctx->Current.RasterColor[1]);
932a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      UNCLAMPED_FLOAT_TO_CHAN(b, ctx->Current.RasterColor[2]);
942a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      UNCLAMPED_FLOAT_TO_CHAN(a, ctx->Current.RasterColor[3]);
952a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul#if CHAN_TYPE == GL_FLOAT
962a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      span->red = r;
972a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      span->green = g;
982a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      span->blue = b;
992a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      span->alpha = a;
1002a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul#else
1012a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      span->red   = IntToFixed(r);
1022a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      span->green = IntToFixed(g);
1032a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      span->blue  = IntToFixed(b);
1042a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      span->alpha = IntToFixed(a);
1052a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul#endif
1062a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      span->redStep = 0;
1072a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      span->greenStep = 0;
1082a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      span->blueStep = 0;
1092a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      span->alphaStep = 0;
1102a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      span->interpMask |= SPAN_RGBA;
1112a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   }
1122a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   else {
1130f3cd3f894612d156de454178effa4c732f96da7Brian Paul      span->index = FloatToFixed(ctx->Current.RasterIndex);
1142a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      span->indexStep = 0;
1152a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      span->interpMask |= SPAN_INDEX;
1162a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   }
1172a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul}
1182a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul
1192a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul
1204753d60dd070bb08d0116076bcc08025c86ce857Brian Paul/**
1214753d60dd070bb08d0116076bcc08025c86ce857Brian Paul * Init span's texcoord interpolation values to the RasterPos texcoords.
1224753d60dd070bb08d0116076bcc08025c86ce857Brian Paul * Used during setup for glDraw/CopyPixels.
1234753d60dd070bb08d0116076bcc08025c86ce857Brian Paul */
1244753d60dd070bb08d0116076bcc08025c86ce857Brian Paulvoid
12545bc887da226403f2c41077e40ca38b6f60f1359Brian Paul_swrast_span_default_texcoords( GLcontext *ctx, struct sw_span *span )
1264753d60dd070bb08d0116076bcc08025c86ce857Brian Paul{
1274753d60dd070bb08d0116076bcc08025c86ce857Brian Paul   GLuint i;
1284753d60dd070bb08d0116076bcc08025c86ce857Brian Paul   for (i = 0; i < ctx->Const.MaxTextureUnits; i++) {
1295f60a0b50ada1865d4fc6a724366e8ea0cc9a72fBrian Paul      COPY_4V(span->tex[i], ctx->Current.RasterTexCoords[i]);
1305f60a0b50ada1865d4fc6a724366e8ea0cc9a72fBrian Paul      ASSIGN_4V(span->texStepX[i], 0.0F, 0.0F, 0.0F, 0.0F);
1315f60a0b50ada1865d4fc6a724366e8ea0cc9a72fBrian Paul      ASSIGN_4V(span->texStepY[i], 0.0F, 0.0F, 0.0F, 0.0F);
1324753d60dd070bb08d0116076bcc08025c86ce857Brian Paul   }
1334753d60dd070bb08d0116076bcc08025c86ce857Brian Paul   span->interpMask |= SPAN_TEXTURE;
1344753d60dd070bb08d0116076bcc08025c86ce857Brian Paul}
1354753d60dd070bb08d0116076bcc08025c86ce857Brian Paul
1364753d60dd070bb08d0116076bcc08025c86ce857Brian Paul
1372a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul/* Fill in the span.color.rgba array from the interpolation values */
1382a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paulstatic void
1392a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paulinterpolate_colors(GLcontext *ctx, struct sw_span *span)
1402a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul{
1412a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   const GLuint n = span->end;
14277df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul   GLchan (*rgba)[4] = span->array->rgba;
1432a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   GLuint i;
1442a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul
145b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul   ASSERT((span->interpMask & SPAN_RGBA)  &&
146b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul	  !(span->arrayMask & SPAN_RGBA));
1472a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul
1482a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   if (span->interpMask & SPAN_FLAT) {
1492a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      /* constant color */
1502a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      GLchan color[4];
1516a98bef96189fbacc326ad9e407c1d4423aa8572Brian Paul      color[RCOMP] = FixedToChan(span->red);
1526a98bef96189fbacc326ad9e407c1d4423aa8572Brian Paul      color[GCOMP] = FixedToChan(span->green);
1536a98bef96189fbacc326ad9e407c1d4423aa8572Brian Paul      color[BCOMP] = FixedToChan(span->blue);
1546a98bef96189fbacc326ad9e407c1d4423aa8572Brian Paul      color[ACOMP] = FixedToChan(span->alpha);
1552a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      for (i = 0; i < n; i++) {
15677df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul         COPY_CHAN4(span->array->rgba[i], color);
1572a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      }
1582a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   }
1592a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   else {
1602a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      /* interpolate */
1616a98bef96189fbacc326ad9e407c1d4423aa8572Brian Paul#if CHAN_TYPE == GL_FLOAT
1626a98bef96189fbacc326ad9e407c1d4423aa8572Brian Paul      GLfloat r = span->red;
1636a98bef96189fbacc326ad9e407c1d4423aa8572Brian Paul      GLfloat g = span->green;
1646a98bef96189fbacc326ad9e407c1d4423aa8572Brian Paul      GLfloat b = span->blue;
1656a98bef96189fbacc326ad9e407c1d4423aa8572Brian Paul      GLfloat a = span->alpha;
1666a98bef96189fbacc326ad9e407c1d4423aa8572Brian Paul      const GLfloat dr = span->redStep;
1676a98bef96189fbacc326ad9e407c1d4423aa8572Brian Paul      const GLfloat dg = span->greenStep;
1686a98bef96189fbacc326ad9e407c1d4423aa8572Brian Paul      const GLfloat db = span->blueStep;
1696a98bef96189fbacc326ad9e407c1d4423aa8572Brian Paul      const GLfloat da = span->alphaStep;
1706a98bef96189fbacc326ad9e407c1d4423aa8572Brian Paul#else
1716a98bef96189fbacc326ad9e407c1d4423aa8572Brian Paul      GLfixed r = span->red;
1726a98bef96189fbacc326ad9e407c1d4423aa8572Brian Paul      GLfixed g = span->green;
1736a98bef96189fbacc326ad9e407c1d4423aa8572Brian Paul      GLfixed b = span->blue;
1746a98bef96189fbacc326ad9e407c1d4423aa8572Brian Paul      GLfixed a = span->alpha;
1756a98bef96189fbacc326ad9e407c1d4423aa8572Brian Paul      const GLint dr = span->redStep;
1766a98bef96189fbacc326ad9e407c1d4423aa8572Brian Paul      const GLint dg = span->greenStep;
1776a98bef96189fbacc326ad9e407c1d4423aa8572Brian Paul      const GLint db = span->blueStep;
1786a98bef96189fbacc326ad9e407c1d4423aa8572Brian Paul      const GLint da = span->alphaStep;
1796a98bef96189fbacc326ad9e407c1d4423aa8572Brian Paul#endif
1802a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      for (i = 0; i < n; i++) {
1812a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         rgba[i][RCOMP] = FixedToChan(r);
1822a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         rgba[i][GCOMP] = FixedToChan(g);
1832a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         rgba[i][BCOMP] = FixedToChan(b);
1842a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         rgba[i][ACOMP] = FixedToChan(a);
1852a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         r += dr;
1862a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         g += dg;
1872a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         b += db;
1882a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         a += da;
1892a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      }
1902a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   }
1912a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   span->arrayMask |= SPAN_RGBA;
1922a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul}
1932a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul
1942a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul
1952a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul/* Fill in the span.color.index array from the interpolation values */
1962a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paulstatic void
1972a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paulinterpolate_indexes(GLcontext *ctx, struct sw_span *span)
1982a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul{
1992a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   GLfixed index = span->index;
2002a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   const GLint indexStep = span->indexStep;
2012a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   const GLuint n = span->end;
20277df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul   GLuint *indexes = span->array->index;
2032a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   GLuint i;
204b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul   ASSERT((span->interpMask & SPAN_INDEX)  &&
205b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul	  !(span->arrayMask & SPAN_INDEX));
2062a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul
2072a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   if ((span->interpMask & SPAN_FLAT) || (indexStep == 0)) {
2082a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      /* constant color */
2092a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      index = FixedToInt(index);
2102a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      for (i = 0; i < n; i++) {
2112a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         indexes[i] = index;
2122a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      }
2132a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   }
2142a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   else {
2152a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      /* interpolate */
2162a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      for (i = 0; i < n; i++) {
2172a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         indexes[i] = FixedToInt(index);
2182a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         index += indexStep;
2192a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      }
2202a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   }
2212a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   span->arrayMask |= SPAN_INDEX;
2222a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul}
2232a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul
2242a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul
22577df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul/* Fill in the span.->array->spec array from the interpolation values */
2262a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paulstatic void
2272a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paulinterpolate_specular(GLcontext *ctx, struct sw_span *span)
2282a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul{
2292a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   if (span->interpMask & SPAN_FLAT) {
2302a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      /* constant color */
2312a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      const GLchan r = FixedToChan(span->specRed);
2322a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      const GLchan g = FixedToChan(span->specGreen);
2332a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      const GLchan b = FixedToChan(span->specBlue);
2342a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      GLuint i;
2352a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      for (i = 0; i < span->end; i++) {
23677df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul         span->array->spec[i][RCOMP] = r;
23777df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul         span->array->spec[i][GCOMP] = g;
23877df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul         span->array->spec[i][BCOMP] = b;
2392a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      }
2402a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   }
2412a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   else {
2422a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      /* interpolate */
2432a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul#if CHAN_TYPE == GL_FLOAT
2442a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      GLfloat r = span->specRed;
2452a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      GLfloat g = span->specGreen;
2462a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      GLfloat b = span->specBlue;
2472a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul#else
2482a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      GLfixed r = span->specRed;
2492a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      GLfixed g = span->specGreen;
2502a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      GLfixed b = span->specBlue;
2512a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul#endif
2522a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      GLuint i;
2532a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      for (i = 0; i < span->end; i++) {
25477df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul         span->array->spec[i][RCOMP] = FixedToChan(r);
25577df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul         span->array->spec[i][GCOMP] = FixedToChan(g);
25677df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul         span->array->spec[i][BCOMP] = FixedToChan(b);
2572a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         r += span->specRedStep;
2582a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         g += span->specGreenStep;
2592a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         b += span->specBlueStep;
2602a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      }
2612a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   }
2622a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   span->arrayMask |= SPAN_SPEC;
2632a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul}
2642a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul
2652a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul
2662a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul/* Fill in the span.zArray array from the interpolation values */
267711e27fda27e4235b20a4cf73c2767c984ab2b81Brian Paulvoid
26845bc887da226403f2c41077e40ca38b6f60f1359Brian Paul_swrast_span_interpolate_z( const GLcontext *ctx, struct sw_span *span )
2692a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul{
2702a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   const GLuint n = span->end;
2712a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   GLuint i;
2722a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul
273b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul   ASSERT((span->interpMask & SPAN_Z)  &&
274b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul	  !(span->arrayMask & SPAN_Z));
2752a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul
2762a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   if (ctx->Visual.depthBits <= 16) {
2772a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      GLfixed zval = span->z;
27877df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul      GLdepth *z = span->array->z;
279ad8cd6111e022c90c93df106c0fde6f64d205816Brian Paul      for (i = 0; i < n; i++) {
28077df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul         z[i] = FixedToInt(zval);
2812a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         zval += span->zStep;
2822a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      }
2832a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   }
2842a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   else {
2852a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      /* Deep Z buffer, no fixed->int shift */
2862a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      GLfixed zval = span->z;
28777df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul      GLdepth *z = span->array->z;
2882a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      for (i = 0; i < n; i++) {
28977df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul         z[i] = zval;
2902a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         zval += span->zStep;
2912a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      }
2922a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   }
2932a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   span->arrayMask |= SPAN_Z;
2942a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul}
2952a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul
2962a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul
297c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul/*
29831f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul * This the ideal solution, as given in the OpenGL spec.
299c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul */
300c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul#if 0
30131f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paulstatic GLfloat
30231f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paulcompute_lambda(GLfloat dsdx, GLfloat dsdy, GLfloat dtdx, GLfloat dtdy,
30331f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul               GLfloat dqdx, GLfloat dqdy, GLfloat texW, GLfloat texH,
30431f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul               GLfloat s, GLfloat t, GLfloat q, GLfloat invQ)
305c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul{
30631f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul   GLfloat dudx = texW * ((s + dsdx) / (q + dqdx) - s * invQ);
30731f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul   GLfloat dvdx = texH * ((t + dtdx) / (q + dqdx) - t * invQ);
30831f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul   GLfloat dudy = texW * ((s + dsdy) / (q + dqdy) - s * invQ);
30931f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul   GLfloat dvdy = texH * ((t + dtdy) / (q + dqdy) - t * invQ);
310f9b1e5241facc8cf255c258082d5cb5b04783e93Brian Paul   GLfloat x = SQRTF(dudx * dudx + dvdx * dvdx);
311f9b1e5241facc8cf255c258082d5cb5b04783e93Brian Paul   GLfloat y = SQRTF(dudy * dudy + dvdy * dvdy);
31231f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul   GLfloat rho = MAX2(x, y);
31331f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul   GLfloat lambda = LOG2(rho);
31431f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul   return lambda;
315c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul}
316c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul#endif
317c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul
31831f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul
31931f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul/*
32031f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul * This is a faster approximation
321c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul */
322350353adcd75f94fda63c787c86961716114e0bfBrian PaulGLfloat
32345bc887da226403f2c41077e40ca38b6f60f1359Brian Paul_swrast_compute_lambda(GLfloat dsdx, GLfloat dsdy, GLfloat dtdx, GLfloat dtdy,
324350353adcd75f94fda63c787c86961716114e0bfBrian Paul                     GLfloat dqdx, GLfloat dqdy, GLfloat texW, GLfloat texH,
325350353adcd75f94fda63c787c86961716114e0bfBrian Paul                     GLfloat s, GLfloat t, GLfloat q, GLfloat invQ)
326c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul{
32731f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul   GLfloat dsdx2 = (s + dsdx) / (q + dqdx) - s * invQ;
32831f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul   GLfloat dtdx2 = (t + dtdx) / (q + dqdx) - t * invQ;
32931f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul   GLfloat dsdy2 = (s + dsdy) / (q + dqdy) - s * invQ;
33031f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul   GLfloat dtdy2 = (t + dtdy) / (q + dqdy) - t * invQ;
33131f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul   GLfloat maxU, maxV, rho, lambda;
33231f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul   dsdx2 = FABSF(dsdx2);
33331f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul   dsdy2 = FABSF(dsdy2);
33431f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul   dtdx2 = FABSF(dtdx2);
33531f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul   dtdy2 = FABSF(dtdy2);
33631f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul   maxU = MAX2(dsdx2, dsdy2) * texW;
33731f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul   maxV = MAX2(dtdx2, dtdy2) * texH;
33831f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul   rho = MAX2(maxU, maxV);
33931f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul   lambda = LOG2(rho);
34031f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul   return lambda;
341c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul}
342c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul
343c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul/*
344c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul * Fill in the span.texcoords array from the interpolation values.
345c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul * XXX We could optimize here for the case when dq = 0.  That would
346c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul * usually be the case when using an orthographic projection.
347c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul */
3482a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paulstatic void
3492a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paulinterpolate_texcoords(GLcontext *ctx, struct sw_span *span)
3502a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul{
3512a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   ASSERT(span->interpMask & SPAN_TEXTURE);
352b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul   ASSERT(!(span->arrayMask & SPAN_TEXTURE));
3532a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul
35436a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul   if (ctx->Texture._EnabledCoordUnits > 1) {
35531f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul      /* multitexture */
35631f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul      GLuint u;
357b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul      span->arrayMask |= SPAN_TEXTURE;
35831f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul      for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
35936a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul         if (ctx->Texture._EnabledCoordUnits & (1 << u)) {
36031f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul            const struct gl_texture_object *obj =ctx->Texture.Unit[u]._Current;
36136a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul            GLfloat texW, texH;
36236a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul            GLboolean needLambda;
36336a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul            if (obj) {
36418fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell               const struct gl_texture_image *img = obj->Image[0][obj->BaseLevel];
36536a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul               needLambda = (obj->MinFilter != obj->MagFilter)
36636a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul                  || ctx->FragmentProgram.Enabled;
36736a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul               texW = img->WidthScale;
36836a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul               texH = img->HeightScale;
36936a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul            }
37036a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul            else {
37136a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul               texW = 1.0;
37236a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul               texH = 1.0;
37336a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul               needLambda = GL_FALSE;
37436a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul            }
37531f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul            if (needLambda) {
37677df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul               GLfloat (*texcoord)[4] = span->array->texcoords[u];
37777df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul               GLfloat *lambda = span->array->lambda[u];
37831f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul               const GLfloat dsdx = span->texStepX[u][0];
37931f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul               const GLfloat dsdy = span->texStepY[u][0];
38031f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul               const GLfloat dtdx = span->texStepX[u][1];
38131f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul               const GLfloat dtdy = span->texStepY[u][1];
38231f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul               const GLfloat drdx = span->texStepX[u][2];
38331f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul               const GLfloat dqdx = span->texStepX[u][3];
38431f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul               const GLfloat dqdy = span->texStepY[u][3];
3852a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul               GLfloat s = span->tex[u][0];
3862a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul               GLfloat t = span->tex[u][1];
3872a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul               GLfloat r = span->tex[u][2];
3882a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul               GLfloat q = span->tex[u][3];
3892a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul               GLuint i;
39031f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul               for (i = 0; i < span->end; i++) {
3912a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul                  const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q);
39277df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul                  texcoord[i][0] = s * invQ;
39377df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul                  texcoord[i][1] = t * invQ;
39477df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul                  texcoord[i][2] = r * invQ;
395350353adcd75f94fda63c787c86961716114e0bfBrian Paul                  texcoord[i][3] = q;
39645bc887da226403f2c41077e40ca38b6f60f1359Brian Paul                  lambda[i] = _swrast_compute_lambda(dsdx, dsdy, dtdx, dtdy,
397350353adcd75f94fda63c787c86961716114e0bfBrian Paul                                                   dqdx, dqdy, texW, texH,
398350353adcd75f94fda63c787c86961716114e0bfBrian Paul                                                   s, t, q, invQ);
39931f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul                  s += dsdx;
40031f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul                  t += dtdx;
40131f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul                  r += drdx;
40231f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul                  q += dqdx;
4032a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul               }
40431f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul               span->arrayMask |= SPAN_LAMBDA;
4052a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul            }
40631f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul            else {
40777df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul               GLfloat (*texcoord)[4] = span->array->texcoords[u];
40877df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul               GLfloat *lambda = span->array->lambda[u];
40931f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul               const GLfloat dsdx = span->texStepX[u][0];
41031f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul               const GLfloat dtdx = span->texStepX[u][1];
41131f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul               const GLfloat drdx = span->texStepX[u][2];
41231f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul               const GLfloat dqdx = span->texStepX[u][3];
4132a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul               GLfloat s = span->tex[u][0];
4142a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul               GLfloat t = span->tex[u][1];
4152a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul               GLfloat r = span->tex[u][2];
4162a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul               GLfloat q = span->tex[u][3];
4172a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul               GLuint i;
41831f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul               if (dqdx == 0.0) {
419c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul                  /* Ortho projection or polygon's parallel to window X axis */
4202a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul                  const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q);
421c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul                  for (i = 0; i < span->end; i++) {
42277df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul                     texcoord[i][0] = s * invQ;
42377df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul                     texcoord[i][1] = t * invQ;
42477df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul                     texcoord[i][2] = r * invQ;
42536a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul                     texcoord[i][3] = q;
42677df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul                     lambda[i] = 0.0;
42731f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul                     s += dsdx;
42831f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul                     t += dtdx;
42931f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul                     r += drdx;
430c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul                  }
431c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul               }
432c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul               else {
433c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul                  for (i = 0; i < span->end; i++) {
434c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul                     const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q);
43577df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul                     texcoord[i][0] = s * invQ;
43677df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul                     texcoord[i][1] = t * invQ;
43777df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul                     texcoord[i][2] = r * invQ;
43836a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul                     texcoord[i][3] = q;
43977df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul                     lambda[i] = 0.0;
44031f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul                     s += dsdx;
44131f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul                     t += dtdx;
44231f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul                     r += drdx;
44331f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul                     q += dqdx;
444c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul                  }
4452a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul               }
44631f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul            } /* lambda */
44731f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul         } /* if */
44831f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul      } /* for */
4492a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   }
4502a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   else {
45131f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul      /* single texture */
45231f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul      const struct gl_texture_object *obj = ctx->Texture.Unit[0]._Current;
45336a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul      GLfloat texW, texH;
45436a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul      GLboolean needLambda;
45536a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul      if (obj) {
45618fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell         const struct gl_texture_image *img = obj->Image[0][obj->BaseLevel];
45736a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul         needLambda = (obj->MinFilter != obj->MagFilter)
45836a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul            || ctx->FragmentProgram.Enabled;
45936a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul         texW = (GLfloat) img->WidthScale;
46036a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul         texH = (GLfloat) img->HeightScale;
46136a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul      }
46236a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul      else {
46336a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul         needLambda = GL_FALSE;
46436a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul         texW = texH = 1.0;
46536a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul      }
466b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul      span->arrayMask |= SPAN_TEXTURE;
46731f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul      if (needLambda) {
4682a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         /* just texture unit 0, with lambda */
46977df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul         GLfloat (*texcoord)[4] = span->array->texcoords[0];
47077df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul         GLfloat *lambda = span->array->lambda[0];
47131f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul         const GLfloat dsdx = span->texStepX[0][0];
47231f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul         const GLfloat dsdy = span->texStepY[0][0];
47331f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul         const GLfloat dtdx = span->texStepX[0][1];
47431f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul         const GLfloat dtdy = span->texStepY[0][1];
47531f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul         const GLfloat drdx = span->texStepX[0][2];
47631f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul         const GLfloat dqdx = span->texStepX[0][3];
47731f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul         const GLfloat dqdy = span->texStepY[0][3];
4782a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         GLfloat s = span->tex[0][0];
4792a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         GLfloat t = span->tex[0][1];
4802a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         GLfloat r = span->tex[0][2];
4812a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         GLfloat q = span->tex[0][3];
4822a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         GLuint i;
48331f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul         for (i = 0; i < span->end; i++) {
4842a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul            const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q);
48545bc887da226403f2c41077e40ca38b6f60f1359Brian Paul            lambda[i] = _swrast_compute_lambda(dsdx, dsdy, dtdx, dtdy,
486350353adcd75f94fda63c787c86961716114e0bfBrian Paul                                             dqdx, dqdy, texW, texH,
487350353adcd75f94fda63c787c86961716114e0bfBrian Paul                                             s, t, q, invQ);
48877df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul            texcoord[i][0] = s * invQ;
48977df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul            texcoord[i][1] = t * invQ;
49077df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul            texcoord[i][2] = r * invQ;
491350353adcd75f94fda63c787c86961716114e0bfBrian Paul            texcoord[i][3] = q;
49231f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul            s += dsdx;
49331f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul            t += dtdx;
49431f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul            r += drdx;
49531f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul            q += dqdx;
4962a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         }
4972a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         span->arrayMask |= SPAN_LAMBDA;
4982a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      }
4992a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      else {
500733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul         /* just texture 0, without lambda */
50177df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul         GLfloat (*texcoord)[4] = span->array->texcoords[0];
50231f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul         const GLfloat dsdx = span->texStepX[0][0];
50331f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul         const GLfloat dtdx = span->texStepX[0][1];
50431f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul         const GLfloat drdx = span->texStepX[0][2];
50531f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul         const GLfloat dqdx = span->texStepX[0][3];
5062a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         GLfloat s = span->tex[0][0];
5072a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         GLfloat t = span->tex[0][1];
5082a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         GLfloat r = span->tex[0][2];
5092a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         GLfloat q = span->tex[0][3];
5102a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         GLuint i;
51131f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul         if (dqdx == 0.0) {
512c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul            /* Ortho projection or polygon's parallel to window X axis */
5132a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul            const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q);
514c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul            for (i = 0; i < span->end; i++) {
51577df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul               texcoord[i][0] = s * invQ;
51677df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul               texcoord[i][1] = t * invQ;
51777df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul               texcoord[i][2] = r * invQ;
5182b7a01a39ba5257407dddde38ef049856c34aa01Brian Paul               texcoord[i][3] = q;
51931f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul               s += dsdx;
52031f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul               t += dtdx;
52131f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul               r += drdx;
522c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul            }
523c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul         }
524c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul         else {
525c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul            for (i = 0; i < span->end; i++) {
526c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul               const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q);
52777df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul               texcoord[i][0] = s * invQ;
52877df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul               texcoord[i][1] = t * invQ;
52977df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul               texcoord[i][2] = r * invQ;
5302b7a01a39ba5257407dddde38ef049856c34aa01Brian Paul               texcoord[i][3] = q;
53131f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul               s += dsdx;
53231f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul               t += dtdx;
53331f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul               r += drdx;
53431f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul               q += dqdx;
535c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul            }
5362a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         }
5372a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      }
5382a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   }
53910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul}
540e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
541e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
54279c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/**
543e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Apply the current polygon stipple pattern to a span of pixels.
544e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */
5455071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paulstatic void
546733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paulstipple_polygon_span( GLcontext *ctx, struct sw_span *span )
54710f30eb43835c57c00783390a02d72daf4f78e26Brian Paul{
54810f30eb43835c57c00783390a02d72daf4f78e26Brian Paul   const GLuint highbit = 0x80000000;
549733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul   const GLuint stipple = ctx->PolygonStipple[span->y % 32];
55077df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul   GLubyte *mask = span->array->mask;
551733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul   GLuint i, m;
552733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul
553733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul   ASSERT(ctx->Polygon.StippleFlag);
554733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul   ASSERT((span->arrayMask & SPAN_XY) == 0);
55510f30eb43835c57c00783390a02d72daf4f78e26Brian Paul
55610f30eb43835c57c00783390a02d72daf4f78e26Brian Paul   m = highbit >> (GLuint) (span->x % 32);
55710f30eb43835c57c00783390a02d72daf4f78e26Brian Paul
55810f30eb43835c57c00783390a02d72daf4f78e26Brian Paul   for (i = 0; i < span->end; i++) {
55910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul      if ((m & stipple) == 0) {
56077df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul	 mask[i] = 0;
56110f30eb43835c57c00783390a02d72daf4f78e26Brian Paul      }
56210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul      m = m >> 1;
56310f30eb43835c57c00783390a02d72daf4f78e26Brian Paul      if (m == 0) {
56410f30eb43835c57c00783390a02d72daf4f78e26Brian Paul         m = highbit;
56510f30eb43835c57c00783390a02d72daf4f78e26Brian Paul      }
56610f30eb43835c57c00783390a02d72daf4f78e26Brian Paul   }
5672ef866d1fc0a5cc5ef8543d65744dfd4da4dbbafBrian Paul   span->writeAll = GL_FALSE;
56810f30eb43835c57c00783390a02d72daf4f78e26Brian Paul}
56910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul
570e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
57179c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/**
572733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul * Clip a pixel span to the current buffer/window boundaries:
573733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul * DrawBuffer->_Xmin, _Xmax, _Ymin, _Ymax.  This will accomplish
574733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul * window clipping and scissoring.
575733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul * Return:   GL_TRUE   some pixels still visible
57610f30eb43835c57c00783390a02d72daf4f78e26Brian Paul *           GL_FALSE  nothing visible
57710f30eb43835c57c00783390a02d72daf4f78e26Brian Paul */
57810f30eb43835c57c00783390a02d72daf4f78e26Brian Paulstatic GLuint
579733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paulclip_span( GLcontext *ctx, struct sw_span *span )
58010f30eb43835c57c00783390a02d72daf4f78e26Brian Paul{
581733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul   const GLint xmin = ctx->DrawBuffer->_Xmin;
582733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul   const GLint xmax = ctx->DrawBuffer->_Xmax;
583733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul   const GLint ymin = ctx->DrawBuffer->_Ymin;
584733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul   const GLint ymax = ctx->DrawBuffer->_Ymax;
585733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul
586733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul   if (span->arrayMask & SPAN_XY) {
587733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      /* arrays of x/y pixel coords */
58877df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul      const GLint *x = span->array->x;
58977df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul      const GLint *y = span->array->y;
590733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      const GLint n = span->end;
59177df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul      GLubyte *mask = span->array->mask;
592733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      GLint i;
593b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul      if (span->arrayMask & SPAN_MASK) {
594b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul         /* note: using & intead of && to reduce branches */
595b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul         for (i = 0; i < n; i++) {
596b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul            mask[i] &= (x[i] >= xmin) & (x[i] < xmax)
597b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul                     & (y[i] >= ymin) & (y[i] < ymax);
598b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul         }
599b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul      }
600b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul      else {
601b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul         /* note: using & intead of && to reduce branches */
602b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul         for (i = 0; i < n; i++) {
603b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul            mask[i] = (x[i] >= xmin) & (x[i] < xmax)
604b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul                    & (y[i] >= ymin) & (y[i] < ymax);
605b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul         }
60610f30eb43835c57c00783390a02d72daf4f78e26Brian Paul      }
607733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      return GL_TRUE;  /* some pixels visible */
60810f30eb43835c57c00783390a02d72daf4f78e26Brian Paul   }
609733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul   else {
610733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      /* horizontal span of pixels */
611733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      const GLint x = span->x;
612733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      const GLint y = span->y;
613733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      const GLint n = span->end;
614733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul
615733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      /* Trivial rejection tests */
616733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      if (y < ymin || y >= ymax || x + n <= xmin || x >= xmax) {
617733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul         span->end = 0;
618733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul         return GL_FALSE;  /* all pixels clipped */
619733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      }
62010f30eb43835c57c00783390a02d72daf4f78e26Brian Paul
621733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      /* Clip to the left */
622733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      if (x < xmin) {
623733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul         ASSERT(x + n > xmin);
624733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul         span->writeAll = GL_FALSE;
6256ec6b845fdf3c44436028ad6fff9471d18928719Brian Paul         _mesa_bzero(span->array->mask, (xmin - x) * sizeof(GLubyte));
62610f30eb43835c57c00783390a02d72daf4f78e26Brian Paul      }
627733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul
628733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      /* Clip to right */
629733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      if (x + n > xmax) {
630733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul         ASSERT(x < xmax);
631733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul         span->end = xmax - x;
63210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul      }
63310f30eb43835c57c00783390a02d72daf4f78e26Brian Paul
634733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      return GL_TRUE;  /* some pixels visible */
635733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul   }
63610f30eb43835c57c00783390a02d72daf4f78e26Brian Paul}
63710f30eb43835c57c00783390a02d72daf4f78e26Brian Paul
63810f30eb43835c57c00783390a02d72daf4f78e26Brian Paul
639e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
64079c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/**
641e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Draw to more than one color buffer (or none).
642e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */
6435071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paulstatic void
644733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paulmulti_write_index_span( GLcontext *ctx, struct sw_span *span )
645e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell{
646709892459922a32096fe9dd8261d0d92337bb02fKeith Whitwell   SWcontext *swrast = SWRAST_CONTEXT(ctx);
647e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   GLuint bufferBit;
648e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
649e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   /* loop over four possible dest color buffers */
6503b4fbbc129c711a5aec8d653d5c6eb2e195f947cBrian Paul   for (bufferBit = 1; bufferBit <= 8; bufferBit <<= 1) {
6513b4fbbc129c711a5aec8d653d5c6eb2e195f947cBrian Paul      if (bufferBit & ctx->Color._DrawDestMask) {
652e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         GLuint indexTmp[MAX_WIDTH];
653733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul         ASSERT(span->end < MAX_WIDTH);
654e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
6558ad1076dc2afda8ed37e5a9f6a757583eba90375Brian Paul         /* Set the current read/draw buffer */
6568ad1076dc2afda8ed37e5a9f6a757583eba90375Brian Paul         swrast->CurrentBuffer = bufferBit;
6578ad1076dc2afda8ed37e5a9f6a757583eba90375Brian Paul         (*swrast->Driver.SetBuffer)(ctx, ctx->DrawBuffer, bufferBit);
658e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
659e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         /* make copy of incoming indexes */
66077df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul         MEMCPY( indexTmp, span->array->index, span->end * sizeof(GLuint) );
661733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul
662e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         if (ctx->Color.IndexLogicOpEnabled) {
66345bc887da226403f2c41077e40ca38b6f60f1359Brian Paul            _swrast_logicop_ci_span(ctx, span, indexTmp);
664e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         }
665733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul
6667956292a765910077f50352d7cd0174e1e66d26cBrian Paul         if (ctx->Color.IndexMask != 0xffffffff) {
66745bc887da226403f2c41077e40ca38b6f60f1359Brian Paul            _swrast_mask_index_span(ctx, span, indexTmp);
668733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul         }
669733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul
670733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul         if (span->arrayMask & SPAN_XY) {
671733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul            /* array of pixel coords */
672733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul            (*swrast->Driver.WriteCI32Pixels)(ctx, span->end,
67377df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul                                              span->array->x, span->array->y,
67477df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul                                              indexTmp, span->array->mask);
675733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul         }
676733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul         else {
677733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul            /* horizontal run of pixels */
678733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul            (*swrast->Driver.WriteCI32Span)(ctx, span->end, span->x, span->y,
67977df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul                                            indexTmp, span->array->mask);
680e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         }
681e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
682e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
683e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
684e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   /* restore default dest buffer */
6853b4fbbc129c711a5aec8d653d5c6eb2e195f947cBrian Paul   _swrast_use_draw_buffer(ctx);
686e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell}
687e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
688e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
68979c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/**
69010f30eb43835c57c00783390a02d72daf4f78e26Brian Paul * Draw to more than one RGBA color buffer (or none).
691f1e236987829393c81dc86ea19cb49eefe190317Brian Paul * All fragment operations, up to (but not) blending/logicop should
692f1e236987829393c81dc86ea19cb49eefe190317Brian Paul * have been done first.
69310f30eb43835c57c00783390a02d72daf4f78e26Brian Paul */
69410f30eb43835c57c00783390a02d72daf4f78e26Brian Paulstatic void
695733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paulmulti_write_rgba_span( GLcontext *ctx, struct sw_span *span )
69610f30eb43835c57c00783390a02d72daf4f78e26Brian Paul{
69710f30eb43835c57c00783390a02d72daf4f78e26Brian Paul   const GLuint colorMask = *((GLuint *) ctx->Color.ColorMask);
69810f30eb43835c57c00783390a02d72daf4f78e26Brian Paul   GLuint bufferBit;
69910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul   SWcontext *swrast = SWRAST_CONTEXT(ctx);
70010f30eb43835c57c00783390a02d72daf4f78e26Brian Paul
701733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul   ASSERT(colorMask != 0x0);
702733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul
70310f30eb43835c57c00783390a02d72daf4f78e26Brian Paul   if (ctx->Color.DrawBuffer == GL_NONE)
70410f30eb43835c57c00783390a02d72daf4f78e26Brian Paul      return;
70510f30eb43835c57c00783390a02d72daf4f78e26Brian Paul
70610f30eb43835c57c00783390a02d72daf4f78e26Brian Paul   /* loop over four possible dest color buffers */
7073b4fbbc129c711a5aec8d653d5c6eb2e195f947cBrian Paul   for (bufferBit = 1; bufferBit <= 8; bufferBit <<= 1) {
7083b4fbbc129c711a5aec8d653d5c6eb2e195f947cBrian Paul      if (bufferBit & ctx->Color._DrawDestMask) {
70910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul         GLchan rgbaTmp[MAX_WIDTH][4];
710733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul         ASSERT(span->end < MAX_WIDTH);
71110f30eb43835c57c00783390a02d72daf4f78e26Brian Paul
7128ad1076dc2afda8ed37e5a9f6a757583eba90375Brian Paul         /* Set the current read/draw buffer */
7138ad1076dc2afda8ed37e5a9f6a757583eba90375Brian Paul         swrast->CurrentBuffer = bufferBit;
7148ad1076dc2afda8ed37e5a9f6a757583eba90375Brian Paul         (*swrast->Driver.SetBuffer)(ctx, ctx->DrawBuffer, bufferBit);
71510f30eb43835c57c00783390a02d72daf4f78e26Brian Paul
71610f30eb43835c57c00783390a02d72daf4f78e26Brian Paul         /* make copy of incoming colors */
71777df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul         MEMCPY( rgbaTmp, span->array->rgba, 4 * span->end * sizeof(GLchan) );
71810f30eb43835c57c00783390a02d72daf4f78e26Brian Paul
71957857ca0925116d6d254fef7e705cfe0b650d77fBrian Paul         if (ctx->Color._LogicOpEnabled) {
72045bc887da226403f2c41077e40ca38b6f60f1359Brian Paul            _swrast_logicop_rgba_span(ctx, span, rgbaTmp);
72110f30eb43835c57c00783390a02d72daf4f78e26Brian Paul         }
72210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul         else if (ctx->Color.BlendEnabled) {
72345bc887da226403f2c41077e40ca38b6f60f1359Brian Paul            _swrast_blend_span(ctx, span, rgbaTmp);
72410f30eb43835c57c00783390a02d72daf4f78e26Brian Paul         }
725733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul
726733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul         if (colorMask != 0xffffffff) {
72745bc887da226403f2c41077e40ca38b6f60f1359Brian Paul            _swrast_mask_rgba_span(ctx, span, rgbaTmp);
72810f30eb43835c57c00783390a02d72daf4f78e26Brian Paul         }
72910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul
730733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul         if (span->arrayMask & SPAN_XY) {
731733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul            /* array of pixel coords */
732733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul            (*swrast->Driver.WriteRGBAPixels)(ctx, span->end,
73377df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul                                              span->array->x, span->array->y,
734733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul                                              (const GLchan (*)[4]) rgbaTmp,
73577df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul                                              span->array->mask);
736733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul            if (SWRAST_CONTEXT(ctx)->_RasterMask & ALPHABUF_BIT) {
73745bc887da226403f2c41077e40ca38b6f60f1359Brian Paul               _swrast_write_alpha_pixels(ctx, span->end,
73877df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul                                        span->array->x, span->array->y,
739733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul                                        (const GLchan (*)[4]) rgbaTmp,
74077df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul                                        span->array->mask);
741733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul            }
742733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul         }
743733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul         else {
744733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul            /* horizontal run of pixels */
745733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul            (*swrast->Driver.WriteRGBASpan)(ctx, span->end, span->x, span->y,
746733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul                                            (const GLchan (*)[4]) rgbaTmp,
74777df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul                                            span->array->mask);
748733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul            if (swrast->_RasterMask & ALPHABUF_BIT) {
74945bc887da226403f2c41077e40ca38b6f60f1359Brian Paul               _swrast_write_alpha_span(ctx, span->end, span->x, span->y,
750733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul                                      (const GLchan (*)[4]) rgbaTmp,
75177df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul                                      span->array->mask);
752733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul            }
75310f30eb43835c57c00783390a02d72daf4f78e26Brian Paul         }
75410f30eb43835c57c00783390a02d72daf4f78e26Brian Paul      }
75510f30eb43835c57c00783390a02d72daf4f78e26Brian Paul   }
75610f30eb43835c57c00783390a02d72daf4f78e26Brian Paul
75710f30eb43835c57c00783390a02d72daf4f78e26Brian Paul   /* restore default dest buffer */
7583b4fbbc129c711a5aec8d653d5c6eb2e195f947cBrian Paul   _swrast_use_draw_buffer(ctx);
75910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul}
76010f30eb43835c57c00783390a02d72daf4f78e26Brian Paul
76110f30eb43835c57c00783390a02d72daf4f78e26Brian Paul
762e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
76379c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/**
7647956292a765910077f50352d7cd0174e1e66d26cBrian Paul * This function may modify any of the array values in the span.
7657956292a765910077f50352d7cd0174e1e66d26cBrian Paul * span->interpMask and span->arrayMask may be changed but will be restored
7667956292a765910077f50352d7cd0174e1e66d26cBrian Paul * to their original values before returning.
76710f30eb43835c57c00783390a02d72daf4f78e26Brian Paul */
76810f30eb43835c57c00783390a02d72daf4f78e26Brian Paulvoid
76945bc887da226403f2c41077e40ca38b6f60f1359Brian Paul_swrast_write_index_span( GLcontext *ctx, struct sw_span *span)
77010f30eb43835c57c00783390a02d72daf4f78e26Brian Paul{
77110f30eb43835c57c00783390a02d72daf4f78e26Brian Paul   SWcontext *swrast = SWRAST_CONTEXT(ctx);
7727956292a765910077f50352d7cd0174e1e66d26cBrian Paul   const GLuint origInterpMask = span->interpMask;
7732a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   const GLuint origArrayMask = span->arrayMask;
77410f30eb43835c57c00783390a02d72daf4f78e26Brian Paul
775733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul   ASSERT(span->end <= MAX_WIDTH);
776b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul   ASSERT(span->primitive == GL_POINT  ||  span->primitive == GL_LINE ||
777b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul	  span->primitive == GL_POLYGON  ||  span->primitive == GL_BITMAP);
778733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul   ASSERT((span->interpMask | span->arrayMask) & SPAN_INDEX);
7797956292a765910077f50352d7cd0174e1e66d26cBrian Paul   ASSERT((span->interpMask & span->arrayMask) == 0);
7807956292a765910077f50352d7cd0174e1e66d26cBrian Paul
781733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul   if (span->arrayMask & SPAN_MASK) {
782733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      /* mask was initialized by caller, probably glBitmap */
783733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      span->writeAll = GL_FALSE;
784733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul   }
785733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul   else {
78677df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul      MEMSET(span->array->mask, 1, span->end);
787733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      span->writeAll = GL_TRUE;
78810f30eb43835c57c00783390a02d72daf4f78e26Brian Paul   }
78910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul
790733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul   /* Clipping */
791b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul   if ((swrast->_RasterMask & CLIP_BIT) || (span->primitive != GL_POLYGON)) {
792733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      if (!clip_span(ctx, span)) {
79386ca15ece74ccb5a8f4d566a4b2c8024b178d73bBrian Paul         return;
794e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
795e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
796e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
797e5b244ff7f984805c1bcc020342f1300f2639c71Brian Paul   /* Depth bounds test */
798e5b244ff7f984805c1bcc020342f1300f2639c71Brian Paul   if (ctx->Depth.BoundsTest && ctx->Visual.depthBits > 0) {
799e5b244ff7f984805c1bcc020342f1300f2639c71Brian Paul      if (!_swrast_depth_bounds_test(ctx, span)) {
800e5b244ff7f984805c1bcc020342f1300f2639c71Brian Paul         return;
801e5b244ff7f984805c1bcc020342f1300f2639c71Brian Paul      }
802e5b244ff7f984805c1bcc020342f1300f2639c71Brian Paul   }
803e5b244ff7f984805c1bcc020342f1300f2639c71Brian Paul
804b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul#ifdef DEBUG
805b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul   if (span->arrayMask & SPAN_XY) {
806a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul      GLuint i;
807b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul      for (i = 0; i < span->end; i++) {
80877df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul         if (span->array->mask[i]) {
80977df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul            assert(span->array->x[i] >= ctx->DrawBuffer->_Xmin);
81077df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul            assert(span->array->x[i] < ctx->DrawBuffer->_Xmax);
81177df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul            assert(span->array->y[i] >= ctx->DrawBuffer->_Ymin);
81277df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul            assert(span->array->y[i] < ctx->DrawBuffer->_Ymax);
813b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul         }
814b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul      }
815b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul   }
816b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul#endif
817b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul
818e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   /* Polygon Stippling */
819b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul   if (ctx->Polygon.StippleFlag && span->primitive == GL_POLYGON) {
82010f30eb43835c57c00783390a02d72daf4f78e26Brian Paul      stipple_polygon_span(ctx, span);
821e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
822e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
8237956292a765910077f50352d7cd0174e1e66d26cBrian Paul   /* Depth test and stencil */
8247956292a765910077f50352d7cd0174e1e66d26cBrian Paul   if (ctx->Depth.Test || ctx->Stencil.Enabled) {
8257956292a765910077f50352d7cd0174e1e66d26cBrian Paul      if (span->interpMask & SPAN_Z)
82645bc887da226403f2c41077e40ca38b6f60f1359Brian Paul         _swrast_span_interpolate_z(ctx, span);
82710f30eb43835c57c00783390a02d72daf4f78e26Brian Paul
8287956292a765910077f50352d7cd0174e1e66d26cBrian Paul      if (ctx->Stencil.Enabled) {
82945bc887da226403f2c41077e40ca38b6f60f1359Brian Paul         if (!_swrast_stencil_and_ztest_span(ctx, span)) {
8307956292a765910077f50352d7cd0174e1e66d26cBrian Paul            span->arrayMask = origArrayMask;
8317956292a765910077f50352d7cd0174e1e66d26cBrian Paul            return;
8327956292a765910077f50352d7cd0174e1e66d26cBrian Paul         }
8332a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      }
8347956292a765910077f50352d7cd0174e1e66d26cBrian Paul      else {
8357956292a765910077f50352d7cd0174e1e66d26cBrian Paul         ASSERT(ctx->Depth.Test);
83645bc887da226403f2c41077e40ca38b6f60f1359Brian Paul         if (!_swrast_depth_test_span(ctx, span)) {
8377956292a765910077f50352d7cd0174e1e66d26cBrian Paul            span->arrayMask = origArrayMask;
8387956292a765910077f50352d7cd0174e1e66d26cBrian Paul            return;
8397956292a765910077f50352d7cd0174e1e66d26cBrian Paul         }
8402a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      }
84110f30eb43835c57c00783390a02d72daf4f78e26Brian Paul   }
84210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul
84310f30eb43835c57c00783390a02d72daf4f78e26Brian Paul   /* if we get here, something passed the depth test */
84410f30eb43835c57c00783390a02d72daf4f78e26Brian Paul   ctx->OcclusionResult = GL_TRUE;
84510f30eb43835c57c00783390a02d72daf4f78e26Brian Paul
846b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul#if FEATURE_ARB_occlusion_query
847b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul   if (ctx->Occlusion.Active) {
848b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul      GLuint i;
849b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul      for (i = 0; i < span->end; i++)
850b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul         ctx->Occlusion.PassedCounter += span->array->mask[i];
851b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul   }
852b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul#endif
853b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul
8547956292a765910077f50352d7cd0174e1e66d26cBrian Paul   /* we have to wait until after occlusion to do this test */
8557956292a765910077f50352d7cd0174e1e66d26cBrian Paul   if (ctx->Color.DrawBuffer == GL_NONE || ctx->Color.IndexMask == 0) {
85610f30eb43835c57c00783390a02d72daf4f78e26Brian Paul      /* write no pixels */
8572a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      span->arrayMask = origArrayMask;
85810f30eb43835c57c00783390a02d72daf4f78e26Brian Paul      return;
85910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul   }
86010f30eb43835c57c00783390a02d72daf4f78e26Brian Paul
8617956292a765910077f50352d7cd0174e1e66d26cBrian Paul   /* Interpolate the color indexes if needed */
8627956292a765910077f50352d7cd0174e1e66d26cBrian Paul   if (span->interpMask & SPAN_INDEX) {
8632a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      interpolate_indexes(ctx, span);
8647956292a765910077f50352d7cd0174e1e66d26cBrian Paul      /* clear the bit - this allows the WriteMonoCISpan optimization below */
8657956292a765910077f50352d7cd0174e1e66d26cBrian Paul      span->interpMask &= ~SPAN_INDEX;
8667956292a765910077f50352d7cd0174e1e66d26cBrian Paul   }
86710f30eb43835c57c00783390a02d72daf4f78e26Brian Paul
8687956292a765910077f50352d7cd0174e1e66d26cBrian Paul   /* Fog */
8692a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   if (ctx->Fog.Enabled) {
87045bc887da226403f2c41077e40ca38b6f60f1359Brian Paul      _swrast_fog_ci_span(ctx, span);
871e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
872e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
8732a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   /* Antialias coverage application */
8742a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   if (span->arrayMask & SPAN_COVERAGE) {
8752a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      GLuint i;
87677df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul      GLuint *index = span->array->index;
87777df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul      GLfloat *coverage = span->array->coverage;
87810f30eb43835c57c00783390a02d72daf4f78e26Brian Paul      for (i = 0; i < span->end; i++) {
87977df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul         ASSERT(coverage[i] < 16);
88077df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul         index[i] = (index[i] & ~0xf) | ((GLuint) coverage[i]);
8815071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paul      }
8822a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   }
8835071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paul
8842a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   if (swrast->_RasterMask & MULTI_DRAW_BIT) {
8852a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      /* draw to zero or two or more buffers */
886733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      multi_write_index_span(ctx, span);
887e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
888e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   else {
8892a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      /* normal situation: draw to exactly one buffer */
8902a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      if (ctx->Color.IndexLogicOpEnabled) {
89145bc887da226403f2c41077e40ca38b6f60f1359Brian Paul         _swrast_logicop_ci_span(ctx, span, span->array->index);
89210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul      }
8932a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul
8947956292a765910077f50352d7cd0174e1e66d26cBrian Paul      if (ctx->Color.IndexMask != 0xffffffff) {
89545bc887da226403f2c41077e40ca38b6f60f1359Brian Paul         _swrast_mask_index_span(ctx, span, span->array->index);
896e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
8972a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul
8982a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      /* write pixels */
899733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      if (span->arrayMask & SPAN_XY) {
900733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul         /* array of pixel coords */
901733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul         if ((span->interpMask & SPAN_INDEX) && span->indexStep == 0) {
902733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul            /* all pixels have same color index */
903733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul            (*swrast->Driver.WriteMonoCIPixels)(ctx, span->end,
90477df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul                                                span->array->x, span->array->y,
905733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul                                                FixedToInt(span->index),
90677df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul                                                span->array->mask);
907733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul         }
908733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul         else {
90977df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul            (*swrast->Driver.WriteCI32Pixels)(ctx, span->end, span->array->x,
91077df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul                                              span->array->y, span->array->index,
91177df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul                                              span->array->mask );
912733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul         }
9137956292a765910077f50352d7cd0174e1e66d26cBrian Paul      }
9147956292a765910077f50352d7cd0174e1e66d26cBrian Paul      else {
915733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul         /* horizontal run of pixels */
916733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul         if ((span->interpMask & SPAN_INDEX) && span->indexStep == 0) {
917733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul            /* all pixels have same color index */
918733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul            (*swrast->Driver.WriteMonoCISpan)(ctx, span->end, span->x, span->y,
919733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul                                              FixedToInt(span->index),
92077df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul                                              span->array->mask);
921733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul         }
922733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul         else {
923733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul            (*swrast->Driver.WriteCI32Span)(ctx, span->end, span->x, span->y,
92477df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul                                            span->array->index,
92577df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul                                            span->array->mask);
926733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul         }
9277956292a765910077f50352d7cd0174e1e66d26cBrian Paul      }
928e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
9292a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul
9307956292a765910077f50352d7cd0174e1e66d26cBrian Paul   span->interpMask = origInterpMask;
9312a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   span->arrayMask = origArrayMask;
932e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell}
933e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
934e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
93579c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/**
9367956292a765910077f50352d7cd0174e1e66d26cBrian Paul * This function may modify any of the array values in the span.
9377956292a765910077f50352d7cd0174e1e66d26cBrian Paul * span->interpMask and span->arrayMask may be changed but will be restored
9387956292a765910077f50352d7cd0174e1e66d26cBrian Paul * to their original values before returning.
9395d2621928823a06006c1586efe78fe8bf65a7e1fBrian Paul */
9405071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paulvoid
94145bc887da226403f2c41077e40ca38b6f60f1359Brian Paul_swrast_write_rgba_span( GLcontext *ctx, struct sw_span *span)
942e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell{
943cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell   SWcontext *swrast = SWRAST_CONTEXT(ctx);
9447956292a765910077f50352d7cd0174e1e66d26cBrian Paul   const GLuint colorMask = *((GLuint *) ctx->Color.ColorMask);
9457956292a765910077f50352d7cd0174e1e66d26cBrian Paul   const GLuint origInterpMask = span->interpMask;
9462a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   const GLuint origArrayMask = span->arrayMask;
9477956292a765910077f50352d7cd0174e1e66d26cBrian Paul   GLboolean monoColor;
9487956292a765910077f50352d7cd0174e1e66d26cBrian Paul
949733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul   ASSERT(span->end <= MAX_WIDTH);
950b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul   ASSERT(span->primitive == GL_POINT  ||  span->primitive == GL_LINE ||
951b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul	  span->primitive == GL_POLYGON  ||  span->primitive == GL_BITMAP);
9527956292a765910077f50352d7cd0174e1e66d26cBrian Paul   ASSERT((span->interpMask & span->arrayMask) == 0);
953ceb39f4f8dc4863fde17d668c752533a2184476eBrian Paul   ASSERT((span->interpMask | span->arrayMask) & SPAN_RGBA);
954bcb148de9201c7f90a68c7c46434e7ebf7204000Brian Paul#ifdef DEBUG
955733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul   if (ctx->Fog.Enabled)
956733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      ASSERT((span->interpMask | span->arrayMask) & SPAN_FOG);
957bcb148de9201c7f90a68c7c46434e7ebf7204000Brian Paul   if (ctx->Depth.Test)
958bcb148de9201c7f90a68c7c46434e7ebf7204000Brian Paul      ASSERT((span->interpMask | span->arrayMask) & SPAN_Z);
959bcb148de9201c7f90a68c7c46434e7ebf7204000Brian Paul#endif
960733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul
961733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul   if (span->arrayMask & SPAN_MASK) {
962733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      /* mask was initialized by caller, probably glBitmap */
963733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      span->writeAll = GL_FALSE;
964733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul   }
965733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul   else {
96677df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul      MEMSET(span->array->mask, 1, span->end);
967733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      span->writeAll = GL_TRUE;
968733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul   }
969e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
9707956292a765910077f50352d7cd0174e1e66d26cBrian Paul   /* Determine if we have mono-chromatic colors */
9717956292a765910077f50352d7cd0174e1e66d26cBrian Paul   monoColor = (span->interpMask & SPAN_RGBA) &&
9727956292a765910077f50352d7cd0174e1e66d26cBrian Paul      span->redStep == 0 && span->greenStep == 0 &&
9737956292a765910077f50352d7cd0174e1e66d26cBrian Paul      span->blueStep == 0 && span->alphaStep == 0;
9747956292a765910077f50352d7cd0174e1e66d26cBrian Paul
975733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul   /* Clipping */
976b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul   if ((swrast->_RasterMask & CLIP_BIT) || (span->primitive != GL_POLYGON)) {
977733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      if (!clip_span(ctx, span)) {
97886ca15ece74ccb5a8f4d566a4b2c8024b178d73bBrian Paul         return;
979e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
980e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
981e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
982e5b244ff7f984805c1bcc020342f1300f2639c71Brian Paul   /* Depth bounds test */
983e5b244ff7f984805c1bcc020342f1300f2639c71Brian Paul   if (ctx->Depth.BoundsTest && ctx->Visual.depthBits > 0) {
984e5b244ff7f984805c1bcc020342f1300f2639c71Brian Paul      if (!_swrast_depth_bounds_test(ctx, span)) {
985e5b244ff7f984805c1bcc020342f1300f2639c71Brian Paul         return;
986e5b244ff7f984805c1bcc020342f1300f2639c71Brian Paul      }
987e5b244ff7f984805c1bcc020342f1300f2639c71Brian Paul   }
988e5b244ff7f984805c1bcc020342f1300f2639c71Brian Paul
989b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul#ifdef DEBUG
990b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul   if (span->arrayMask & SPAN_XY) {
991a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul      GLuint i;
992b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul      for (i = 0; i < span->end; i++) {
99377df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul         if (span->array->mask[i]) {
99477df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul            assert(span->array->x[i] >= ctx->DrawBuffer->_Xmin);
99577df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul            assert(span->array->x[i] < ctx->DrawBuffer->_Xmax);
99677df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul            assert(span->array->y[i] >= ctx->DrawBuffer->_Ymin);
99777df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul            assert(span->array->y[i] < ctx->DrawBuffer->_Ymax);
998b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul         }
999b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul      }
1000b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul   }
1001b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul#endif
1002b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul
1003e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   /* Polygon Stippling */
1004b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul   if (ctx->Polygon.StippleFlag && span->primitive == GL_POLYGON) {
10057956292a765910077f50352d7cd0174e1e66d26cBrian Paul      stipple_polygon_span(ctx, span);
100610f30eb43835c57c00783390a02d72daf4f78e26Brian Paul   }
100710f30eb43835c57c00783390a02d72daf4f78e26Brian Paul
1008610d59981a9f43fefe29b34ef19c184d28e2bef5Brian Paul   /* Fragment program */
1009610d59981a9f43fefe29b34ef19c184d28e2bef5Brian Paul   if (ctx->FragmentProgram.Enabled) {
1010610d59981a9f43fefe29b34ef19c184d28e2bef5Brian Paul      /* Now we may need to interpolate the colors */
1011610d59981a9f43fefe29b34ef19c184d28e2bef5Brian Paul      if ((span->interpMask & SPAN_RGBA) &&
1012610d59981a9f43fefe29b34ef19c184d28e2bef5Brian Paul          (span->arrayMask & SPAN_RGBA) == 0) {
1013610d59981a9f43fefe29b34ef19c184d28e2bef5Brian Paul         interpolate_colors(ctx, span);
1014610d59981a9f43fefe29b34ef19c184d28e2bef5Brian Paul         span->interpMask &= ~SPAN_RGBA;
1015610d59981a9f43fefe29b34ef19c184d28e2bef5Brian Paul      }
101636a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul      if (span->interpMask & SPAN_SPEC) {
101736a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul         interpolate_specular(ctx, span);
101836a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul      }
1019610d59981a9f43fefe29b34ef19c184d28e2bef5Brian Paul      _swrast_exec_nv_fragment_program(ctx, span);
1020610d59981a9f43fefe29b34ef19c184d28e2bef5Brian Paul      monoColor = GL_FALSE;
1021610d59981a9f43fefe29b34ef19c184d28e2bef5Brian Paul   }
1022610d59981a9f43fefe29b34ef19c184d28e2bef5Brian Paul
1023e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   /* Do the alpha test */
1024e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   if (ctx->Color.AlphaEnabled) {
102545bc887da226403f2c41077e40ca38b6f60f1359Brian Paul      if (!_swrast_alpha_test(ctx, span)) {
10267956292a765910077f50352d7cd0174e1e66d26cBrian Paul         span->interpMask = origInterpMask;
10272a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         span->arrayMask = origArrayMask;
1028e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell	 return;
1029e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
103010f30eb43835c57c00783390a02d72daf4f78e26Brian Paul   }
103110f30eb43835c57c00783390a02d72daf4f78e26Brian Paul
1032f1e236987829393c81dc86ea19cb49eefe190317Brian Paul   /* Stencil and Z testing */
1033f1e236987829393c81dc86ea19cb49eefe190317Brian Paul   if (ctx->Stencil.Enabled || ctx->Depth.Test) {
1034f1e236987829393c81dc86ea19cb49eefe190317Brian Paul      if (span->interpMask & SPAN_Z)
103545bc887da226403f2c41077e40ca38b6f60f1359Brian Paul         _swrast_span_interpolate_z(ctx, span);
1036f1e236987829393c81dc86ea19cb49eefe190317Brian Paul
1037f1e236987829393c81dc86ea19cb49eefe190317Brian Paul      if (ctx->Stencil.Enabled) {
103845bc887da226403f2c41077e40ca38b6f60f1359Brian Paul         if (!_swrast_stencil_and_ztest_span(ctx, span)) {
10397956292a765910077f50352d7cd0174e1e66d26cBrian Paul            span->interpMask = origInterpMask;
1040f1e236987829393c81dc86ea19cb49eefe190317Brian Paul            span->arrayMask = origArrayMask;
1041f1e236987829393c81dc86ea19cb49eefe190317Brian Paul            return;
104210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul         }
104310f30eb43835c57c00783390a02d72daf4f78e26Brian Paul      }
104410f30eb43835c57c00783390a02d72daf4f78e26Brian Paul      else {
1045f1e236987829393c81dc86ea19cb49eefe190317Brian Paul         ASSERT(ctx->Depth.Test);
1046f1e236987829393c81dc86ea19cb49eefe190317Brian Paul         ASSERT(span->arrayMask & SPAN_Z);
1047f1e236987829393c81dc86ea19cb49eefe190317Brian Paul         /* regular depth testing */
104845bc887da226403f2c41077e40ca38b6f60f1359Brian Paul         if (!_swrast_depth_test_span(ctx, span)) {
10497956292a765910077f50352d7cd0174e1e66d26cBrian Paul            span->interpMask = origInterpMask;
1050f1e236987829393c81dc86ea19cb49eefe190317Brian Paul            span->arrayMask = origArrayMask;
1051f1e236987829393c81dc86ea19cb49eefe190317Brian Paul            return;
105210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul         }
105310f30eb43835c57c00783390a02d72daf4f78e26Brian Paul      }
1054e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
1055e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
1056e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   /* if we get here, something passed the depth test */
1057e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   ctx->OcclusionResult = GL_TRUE;
1058e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
1059b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul#if FEATURE_ARB_occlusion_query
1060b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul   if (ctx->Occlusion.Active) {
1061b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul      GLuint i;
1062b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul      for (i = 0; i < span->end; i++)
1063b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul         ctx->Occlusion.PassedCounter += span->array->mask[i];
1064b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul   }
1065b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul#endif
1066b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul
10677956292a765910077f50352d7cd0174e1e66d26cBrian Paul   /* can't abort span-writing until after occlusion testing */
10687956292a765910077f50352d7cd0174e1e66d26cBrian Paul   if (colorMask == 0x0) {
10697956292a765910077f50352d7cd0174e1e66d26cBrian Paul      span->interpMask = origInterpMask;
10707956292a765910077f50352d7cd0174e1e66d26cBrian Paul      span->arrayMask = origArrayMask;
10717956292a765910077f50352d7cd0174e1e66d26cBrian Paul      return;
10727956292a765910077f50352d7cd0174e1e66d26cBrian Paul   }
10737956292a765910077f50352d7cd0174e1e66d26cBrian Paul
1074ceb39f4f8dc4863fde17d668c752533a2184476eBrian Paul   /* Now we may need to interpolate the colors */
1075ceb39f4f8dc4863fde17d668c752533a2184476eBrian Paul   if ((span->interpMask & SPAN_RGBA) && (span->arrayMask & SPAN_RGBA) == 0) {
1076ceb39f4f8dc4863fde17d668c752533a2184476eBrian Paul      interpolate_colors(ctx, span);
1077ceb39f4f8dc4863fde17d668c752533a2184476eBrian Paul      /* clear the bit - this allows the WriteMonoCISpan optimization below */
1078ceb39f4f8dc4863fde17d668c752533a2184476eBrian Paul      span->interpMask &= ~SPAN_RGBA;
1079ceb39f4f8dc4863fde17d668c752533a2184476eBrian Paul   }
1080ceb39f4f8dc4863fde17d668c752533a2184476eBrian Paul
10816e1666437ea091ecc50ab2b56d87129318f641d2Brian Paul   /* Fog */
1082b38ad54c41aec2d08fdd26a4a8ea4dcdca8b1dfdBrian Paul   if (ctx->Fog.Enabled) {
108345bc887da226403f2c41077e40ca38b6f60f1359Brian Paul      _swrast_fog_rgba_span(ctx, span);
10847956292a765910077f50352d7cd0174e1e66d26cBrian Paul      monoColor = GL_FALSE;
1085b38ad54c41aec2d08fdd26a4a8ea4dcdca8b1dfdBrian Paul   }
1086b38ad54c41aec2d08fdd26a4a8ea4dcdca8b1dfdBrian Paul
10875071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paul   /* Antialias coverage application */
10882a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   if (span->arrayMask & SPAN_COVERAGE) {
108977df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul      GLchan (*rgba)[4] = span->array->rgba;
109077df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul      GLfloat *coverage = span->array->coverage;
10915071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paul      GLuint i;
109210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul      for (i = 0; i < span->end; i++) {
109377df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul         rgba[i][ACOMP] = (GLchan) (rgba[i][ACOMP] * coverage[i]);
10945071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paul      }
10957956292a765910077f50352d7cd0174e1e66d26cBrian Paul      monoColor = GL_FALSE;
10965071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paul   }
10975071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paul
1098cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell   if (swrast->_RasterMask & MULTI_DRAW_BIT) {
1099733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      multi_write_rgba_span(ctx, span);
1100e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
1101e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   else {
1102e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      /* normal: write to exactly one buffer */
110357857ca0925116d6d254fef7e705cfe0b650d77fBrian Paul      if (ctx->Color._LogicOpEnabled) {
110445bc887da226403f2c41077e40ca38b6f60f1359Brian Paul         _swrast_logicop_rgba_span(ctx, span, span->array->rgba);
11057956292a765910077f50352d7cd0174e1e66d26cBrian Paul         monoColor = GL_FALSE;
1106e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
1107e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      else if (ctx->Color.BlendEnabled) {
110845bc887da226403f2c41077e40ca38b6f60f1359Brian Paul         _swrast_blend_span(ctx, span, span->array->rgba);
11097956292a765910077f50352d7cd0174e1e66d26cBrian Paul         monoColor = GL_FALSE;
1110e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
111195e2c72fd52d87163eb543555345f115f050f3aaBrian Paul
1112e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      /* Color component masking */
11137956292a765910077f50352d7cd0174e1e66d26cBrian Paul      if (colorMask != 0xffffffff) {
111445bc887da226403f2c41077e40ca38b6f60f1359Brian Paul         _swrast_mask_rgba_span(ctx, span, span->array->rgba);
11157956292a765910077f50352d7cd0174e1e66d26cBrian Paul         monoColor = GL_FALSE;
1116e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
1117e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
1118e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      /* write pixels */
1119733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      if (span->arrayMask & SPAN_XY) {
1120733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul         /* array of pixel coords */
1121733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul         /* XXX test for mono color */
112277df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul         (*swrast->Driver.WriteRGBAPixels)(ctx, span->end, span->array->x,
112377df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul             span->array->y, (const GLchan (*)[4]) span->array->rgba, span->array->mask);
1124733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul         if (SWRAST_CONTEXT(ctx)->_RasterMask & ALPHABUF_BIT) {
112545bc887da226403f2c41077e40ca38b6f60f1359Brian Paul            _swrast_write_alpha_pixels(ctx, span->end,
112677df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul                                     span->array->x, span->array->y,
112777df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul                                     (const GLchan (*)[4]) span->array->rgba,
112877df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul                                     span->array->mask);
1129733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul         }
1130e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
1131e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      else {
1132733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul         /* horizontal run of pixels */
1133733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul         if (monoColor) {
1134733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul            /* all pixels have same color */
1135733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul            GLchan color[4];
1136733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul            color[RCOMP] = FixedToChan(span->red);
1137733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul            color[GCOMP] = FixedToChan(span->green);
1138733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul            color[BCOMP] = FixedToChan(span->blue);
1139733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul            color[ACOMP] = FixedToChan(span->alpha);
1140733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul            (*swrast->Driver.WriteMonoRGBASpan)(ctx, span->end, span->x,
114177df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul                                                span->y, color, span->array->mask);
1142957a0cdb13d2564a17c1fc9f6600d6cd56cb48d7Brian Paul            if (swrast->_RasterMask & ALPHABUF_BIT) {
114345bc887da226403f2c41077e40ca38b6f60f1359Brian Paul               _swrast_write_mono_alpha_span(ctx, span->end, span->x, span->y,
1144957a0cdb13d2564a17c1fc9f6600d6cd56cb48d7Brian Paul                      color[ACOMP],
1145957a0cdb13d2564a17c1fc9f6600d6cd56cb48d7Brian Paul                      span->writeAll ? ((const GLubyte *) NULL) : span->array->mask);
1146957a0cdb13d2564a17c1fc9f6600d6cd56cb48d7Brian Paul            }
1147733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul         }
1148733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul         else {
1149733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul            /* each pixel is a different color */
1150733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul            (*swrast->Driver.WriteRGBASpan)(ctx, span->end, span->x, span->y,
115177df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul                      (const GLchan (*)[4]) span->array->rgba,
115277df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul                      span->writeAll ? ((const GLubyte *) NULL) : span->array->mask);
1153733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul            if (swrast->_RasterMask & ALPHABUF_BIT) {
115445bc887da226403f2c41077e40ca38b6f60f1359Brian Paul               _swrast_write_alpha_span(ctx, span->end, span->x, span->y,
115577df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul                      (const GLchan (*)[4]) span->array->rgba,
115677df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul                      span->writeAll ? ((const GLubyte *) NULL) : span->array->mask);
1157733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul            }
1158733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul         }
1159e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
1160e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
1161e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
11627956292a765910077f50352d7cd0174e1e66d26cBrian Paul   span->interpMask = origInterpMask;
11637956292a765910077f50352d7cd0174e1e66d26cBrian Paul   span->arrayMask = origArrayMask;
11647956292a765910077f50352d7cd0174e1e66d26cBrian Paul}
1165e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
1166e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
116779c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/**
1168e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Add specular color to base color.  This is used only when
1169f1e236987829393c81dc86ea19cb49eefe190317Brian Paul * GL_LIGHT_MODEL_COLOR_CONTROL = GL_SEPARATE_SPECULAR_COLOR.
1170e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */
11715071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paulstatic void
1172f1e236987829393c81dc86ea19cb49eefe190317Brian Pauladd_colors(GLuint n, GLchan rgba[][4], GLchan specular[][4] )
1173e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell{
1174e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   GLuint i;
1175f1e236987829393c81dc86ea19cb49eefe190317Brian Paul   for (i = 0; i < n; i++) {
11764fa5c1966a985f81c615a9f5ef2f64dd466b252aBrian Paul#if CHAN_TYPE == GL_FLOAT
11774fa5c1966a985f81c615a9f5ef2f64dd466b252aBrian Paul      /* no clamping */
1178f1e236987829393c81dc86ea19cb49eefe190317Brian Paul      rgba[i][RCOMP] += specular[i][RCOMP];
1179f1e236987829393c81dc86ea19cb49eefe190317Brian Paul      rgba[i][GCOMP] += specular[i][GCOMP];
1180f1e236987829393c81dc86ea19cb49eefe190317Brian Paul      rgba[i][BCOMP] += specular[i][BCOMP];
11814fa5c1966a985f81c615a9f5ef2f64dd466b252aBrian Paul#else
1182f1e236987829393c81dc86ea19cb49eefe190317Brian Paul      GLint r = rgba[i][RCOMP] + specular[i][RCOMP];
1183f1e236987829393c81dc86ea19cb49eefe190317Brian Paul      GLint g = rgba[i][GCOMP] + specular[i][GCOMP];
1184f1e236987829393c81dc86ea19cb49eefe190317Brian Paul      GLint b = rgba[i][BCOMP] + specular[i][BCOMP];
1185e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      rgba[i][RCOMP] = (GLchan) MIN2(r, CHAN_MAX);
1186e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      rgba[i][GCOMP] = (GLchan) MIN2(g, CHAN_MAX);
1187e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      rgba[i][BCOMP] = (GLchan) MIN2(b, CHAN_MAX);
11884fa5c1966a985f81c615a9f5ef2f64dd466b252aBrian Paul#endif
1189e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
1190e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell}
1191e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
1192e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
119379c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/**
1194f1e236987829393c81dc86ea19cb49eefe190317Brian Paul * This function may modify any of the array values in the span.
11957956292a765910077f50352d7cd0174e1e66d26cBrian Paul * span->interpMask and span->arrayMask may be changed but will be restored
11967956292a765910077f50352d7cd0174e1e66d26cBrian Paul * to their original values before returning.
119778940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul */
119878940758e90069ceaca2b6cddb6438488fbad5ccBrian Paulvoid
119945bc887da226403f2c41077e40ca38b6f60f1359Brian Paul_swrast_write_texture_span( GLcontext *ctx, struct sw_span *span)
120078940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul{
120178940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul   const GLuint colorMask = *((GLuint *) ctx->Color.ColorMask);
120278940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul   SWcontext *swrast = SWRAST_CONTEXT(ctx);
1203e5b244ff7f984805c1bcc020342f1300f2639c71Brian Paul   const GLuint origInterpMask = span->interpMask;
1204f1e236987829393c81dc86ea19cb49eefe190317Brian Paul   const GLuint origArrayMask = span->arrayMask;
1205f1e236987829393c81dc86ea19cb49eefe190317Brian Paul
1206b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul   ASSERT(span->primitive == GL_POINT  ||  span->primitive == GL_LINE ||
1207b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul	  span->primitive == GL_POLYGON  ||  span->primitive == GL_BITMAP);
1208733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul   ASSERT(span->end <= MAX_WIDTH);
12097956292a765910077f50352d7cd0174e1e66d26cBrian Paul   ASSERT((span->interpMask & span->arrayMask) == 0);
1210853bda3e7c4dfa7d8cc462729f6a3dce89e44963Brian Paul   ASSERT(ctx->Texture._EnabledCoordUnits || ctx->FragmentProgram.Enabled);
121178940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul
1212ceb39f4f8dc4863fde17d668c752533a2184476eBrian Paul   /*
1213ceb39f4f8dc4863fde17d668c752533a2184476eBrian Paul   printf("%s()  interp 0x%x  array 0x%x\n", __FUNCTION__, span->interpMask, span->arrayMask);
1214ceb39f4f8dc4863fde17d668c752533a2184476eBrian Paul   */
1215ceb39f4f8dc4863fde17d668c752533a2184476eBrian Paul
1216733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul   if (span->arrayMask & SPAN_MASK) {
1217733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      /* mask was initialized by caller, probably glBitmap */
1218733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      span->writeAll = GL_FALSE;
1219733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul   }
1220733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul   else {
122177df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul      MEMSET(span->array->mask, 1, span->end);
1222733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      span->writeAll = GL_TRUE;
122378940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul   }
122478940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul
1225733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul   /* Clipping */
1226b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul   if ((swrast->_RasterMask & CLIP_BIT) || (span->primitive != GL_POLYGON)) {
1227733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      if (!clip_span(ctx, span)) {
1228733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul	 return;
122978940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul      }
123078940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul   }
123178940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul
1232b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul#ifdef DEBUG
1233b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul   if (span->arrayMask & SPAN_XY) {
1234a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul      GLuint i;
1235b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul      for (i = 0; i < span->end; i++) {
123677df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul         if (span->array->mask[i]) {
123777df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul            assert(span->array->x[i] >= ctx->DrawBuffer->_Xmin);
123877df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul            assert(span->array->x[i] < ctx->DrawBuffer->_Xmax);
123977df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul            assert(span->array->y[i] >= ctx->DrawBuffer->_Ymin);
124077df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul            assert(span->array->y[i] < ctx->DrawBuffer->_Ymax);
1241b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul         }
1242b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul      }
1243b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul   }
1244b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul#endif
1245b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul
124678940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul   /* Polygon Stippling */
1247b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul   if (ctx->Polygon.StippleFlag && span->primitive == GL_POLYGON) {
1248733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      stipple_polygon_span(ctx, span);
124978940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul   }
125078940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul
1251f1e236987829393c81dc86ea19cb49eefe190317Brian Paul   /* Need texture coordinates now */
1252f1e236987829393c81dc86ea19cb49eefe190317Brian Paul   if ((span->interpMask & SPAN_TEXTURE)
1253f1e236987829393c81dc86ea19cb49eefe190317Brian Paul       && (span->arrayMask & SPAN_TEXTURE) == 0)
1254f1e236987829393c81dc86ea19cb49eefe190317Brian Paul      interpolate_texcoords(ctx, span);
125578940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul
125678940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul   /* Texture with alpha test */
125778940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul   if (ctx->Color.AlphaEnabled) {
1258f1e236987829393c81dc86ea19cb49eefe190317Brian Paul
1259f1e236987829393c81dc86ea19cb49eefe190317Brian Paul      /* Now we need the rgba array, fill it in if needed */
1260f1e236987829393c81dc86ea19cb49eefe190317Brian Paul      if ((span->interpMask & SPAN_RGBA) && (span->arrayMask & SPAN_RGBA) == 0)
1261f1e236987829393c81dc86ea19cb49eefe190317Brian Paul         interpolate_colors(ctx, span);
1262f1e236987829393c81dc86ea19cb49eefe190317Brian Paul
126336a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul      if (span->interpMask & SPAN_SPEC) {
126436a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul         interpolate_specular(ctx, span);
126536a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul      }
126636a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul
126778940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul      /* Texturing without alpha is done after depth-testing which
1268f1e236987829393c81dc86ea19cb49eefe190317Brian Paul       * gives a potential speed-up.
1269f1e236987829393c81dc86ea19cb49eefe190317Brian Paul       */
1270610d59981a9f43fefe29b34ef19c184d28e2bef5Brian Paul      if (ctx->FragmentProgram.Enabled)
1271610d59981a9f43fefe29b34ef19c184d28e2bef5Brian Paul         _swrast_exec_nv_fragment_program( ctx, span );
1272610d59981a9f43fefe29b34ef19c184d28e2bef5Brian Paul      else
1273610d59981a9f43fefe29b34ef19c184d28e2bef5Brian Paul         _swrast_texture_span( ctx, span );
127478940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul
127578940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul      /* Do the alpha test */
127645bc887da226403f2c41077e40ca38b6f60f1359Brian Paul      if (!_swrast_alpha_test(ctx, span)) {
1277f1e236987829393c81dc86ea19cb49eefe190317Brian Paul         span->arrayMask = origArrayMask;
1278ceb39f4f8dc4863fde17d668c752533a2184476eBrian Paul	 return;
127978940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul      }
128078940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul   }
128178940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul
1282f1e236987829393c81dc86ea19cb49eefe190317Brian Paul   /* Stencil and Z testing */
1283f1e236987829393c81dc86ea19cb49eefe190317Brian Paul   if (ctx->Stencil.Enabled || ctx->Depth.Test) {
1284f1e236987829393c81dc86ea19cb49eefe190317Brian Paul      if (span->interpMask & SPAN_Z)
128545bc887da226403f2c41077e40ca38b6f60f1359Brian Paul         _swrast_span_interpolate_z(ctx, span);
128678940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul
128771340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul      if (ctx->Stencil.Enabled) {
128845bc887da226403f2c41077e40ca38b6f60f1359Brian Paul         if (!_swrast_stencil_and_ztest_span(ctx, span)) {
1289e5b244ff7f984805c1bcc020342f1300f2639c71Brian Paul            span->interpMask = origInterpMask;
1290f1e236987829393c81dc86ea19cb49eefe190317Brian Paul            span->arrayMask = origArrayMask;
129110f30eb43835c57c00783390a02d72daf4f78e26Brian Paul            return;
1292f1e236987829393c81dc86ea19cb49eefe190317Brian Paul         }
129371340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul      }
1294f1e236987829393c81dc86ea19cb49eefe190317Brian Paul      else {
1295f1e236987829393c81dc86ea19cb49eefe190317Brian Paul         ASSERT(ctx->Depth.Test);
1296f1e236987829393c81dc86ea19cb49eefe190317Brian Paul         ASSERT(span->arrayMask & SPAN_Z);
129710f30eb43835c57c00783390a02d72daf4f78e26Brian Paul         /* regular depth testing */
129845bc887da226403f2c41077e40ca38b6f60f1359Brian Paul         if (!_swrast_depth_test_span(ctx, span)) {
1299e5b244ff7f984805c1bcc020342f1300f2639c71Brian Paul            span->interpMask = origInterpMask;
1300f1e236987829393c81dc86ea19cb49eefe190317Brian Paul            span->arrayMask = origArrayMask;
130110f30eb43835c57c00783390a02d72daf4f78e26Brian Paul            return;
1302f1e236987829393c81dc86ea19cb49eefe190317Brian Paul         }
130371340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul      }
130471340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul   }
130571340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul
1306f1e236987829393c81dc86ea19cb49eefe190317Brian Paul   /* if we get here, some fragments passed the depth test */
130771340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul   ctx->OcclusionResult = GL_TRUE;
130871340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul
1309b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul#if FEATURE_ARB_occlusion_query
1310b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul   if (ctx->Occlusion.Active) {
1311b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul      GLuint i;
1312b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul      for (i = 0; i < span->end; i++)
1313b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul         ctx->Occlusion.PassedCounter += span->array->mask[i];
1314b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul   }
1315b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul#endif
1316b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul
1317f1e236987829393c81dc86ea19cb49eefe190317Brian Paul   /* We had to wait until now to check for glColorMask(F,F,F,F) because of
1318f1e236987829393c81dc86ea19cb49eefe190317Brian Paul    * the occlusion test.
1319f1e236987829393c81dc86ea19cb49eefe190317Brian Paul    */
1320f1e236987829393c81dc86ea19cb49eefe190317Brian Paul   if (colorMask == 0x0) {
1321e5b244ff7f984805c1bcc020342f1300f2639c71Brian Paul      span->interpMask = origInterpMask;
1322f1e236987829393c81dc86ea19cb49eefe190317Brian Paul      span->arrayMask = origArrayMask;
1323f1e236987829393c81dc86ea19cb49eefe190317Brian Paul      return;
132471340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul   }
132571340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul
1326f1e236987829393c81dc86ea19cb49eefe190317Brian Paul   /* Texture without alpha test */
1327f1e236987829393c81dc86ea19cb49eefe190317Brian Paul   if (!ctx->Color.AlphaEnabled) {
132871340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul
1329f1e236987829393c81dc86ea19cb49eefe190317Brian Paul      /* Now we need the rgba array, fill it in if needed */
1330f1e236987829393c81dc86ea19cb49eefe190317Brian Paul      if ((span->interpMask & SPAN_RGBA) && (span->arrayMask & SPAN_RGBA) == 0)
1331f1e236987829393c81dc86ea19cb49eefe190317Brian Paul         interpolate_colors(ctx, span);
133271340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul
133336a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul      if (span->interpMask & SPAN_SPEC) {
133436a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul         interpolate_specular(ctx, span);
133536a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul      }
133636a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul
1337610d59981a9f43fefe29b34ef19c184d28e2bef5Brian Paul      if (ctx->FragmentProgram.Enabled)
1338610d59981a9f43fefe29b34ef19c184d28e2bef5Brian Paul         _swrast_exec_nv_fragment_program( ctx, span );
1339610d59981a9f43fefe29b34ef19c184d28e2bef5Brian Paul      else
1340610d59981a9f43fefe29b34ef19c184d28e2bef5Brian Paul         _swrast_texture_span( ctx, span );
134171340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul   }
134271340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul
1343f1e236987829393c81dc86ea19cb49eefe190317Brian Paul   ASSERT(span->arrayMask & SPAN_RGBA);
13442ef866d1fc0a5cc5ef8543d65744dfd4da4dbbafBrian Paul
1345f1e236987829393c81dc86ea19cb49eefe190317Brian Paul   /* Add base and specular colors */
1346f1e236987829393c81dc86ea19cb49eefe190317Brian Paul   if (ctx->Fog.ColorSumEnabled ||
1347f1e236987829393c81dc86ea19cb49eefe190317Brian Paul       (ctx->Light.Enabled &&
1348f1e236987829393c81dc86ea19cb49eefe190317Brian Paul        ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR)) {
1349f1e236987829393c81dc86ea19cb49eefe190317Brian Paul      if (span->interpMask & SPAN_SPEC) {
1350f1e236987829393c81dc86ea19cb49eefe190317Brian Paul         interpolate_specular(ctx, span);
135171340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul      }
1352f1e236987829393c81dc86ea19cb49eefe190317Brian Paul      ASSERT(span->arrayMask & SPAN_SPEC);
135377df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul      add_colors( span->end, span->array->rgba, span->array->spec );
135471340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul   }
135571340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul
13566e1666437ea091ecc50ab2b56d87129318f641d2Brian Paul   /* Fog */
135771340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul   if (ctx->Fog.Enabled) {
135845bc887da226403f2c41077e40ca38b6f60f1359Brian Paul      _swrast_fog_rgba_span(ctx, span);
135971340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul   }
1360f1e236987829393c81dc86ea19cb49eefe190317Brian Paul
136171340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul   /* Antialias coverage application */
13622a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   if (span->arrayMask & SPAN_COVERAGE) {
136377df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul      GLchan (*rgba)[4] = span->array->rgba;
136477df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul      GLfloat *coverage = span->array->coverage;
136571340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul      GLuint i;
136610f30eb43835c57c00783390a02d72daf4f78e26Brian Paul      for (i = 0; i < span->end; i++) {
136777df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul         rgba[i][ACOMP] = (GLchan) (rgba[i][ACOMP] * coverage[i]);
136871340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul      }
136971340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul   }
137071340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul
137171340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul   if (swrast->_RasterMask & MULTI_DRAW_BIT) {
1372733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      multi_write_rgba_span(ctx, span);
137371340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul   }
137471340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul   else {
137571340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul      /* normal: write to exactly one buffer */
137657857ca0925116d6d254fef7e705cfe0b650d77fBrian Paul      if (ctx->Color._LogicOpEnabled) {
137745bc887da226403f2c41077e40ca38b6f60f1359Brian Paul         _swrast_logicop_rgba_span(ctx, span, span->array->rgba);
137871340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul      }
137995e2c72fd52d87163eb543555345f115f050f3aaBrian Paul      else if (ctx->Color.BlendEnabled) {
138045bc887da226403f2c41077e40ca38b6f60f1359Brian Paul         _swrast_blend_span(ctx, span, span->array->rgba);
138171340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul      }
138271340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul
1383e5b244ff7f984805c1bcc020342f1300f2639c71Brian Paul      /* Color component masking */
1384f1e236987829393c81dc86ea19cb49eefe190317Brian Paul      if (colorMask != 0xffffffff) {
138545bc887da226403f2c41077e40ca38b6f60f1359Brian Paul         _swrast_mask_rgba_span(ctx, span, span->array->rgba);
138671340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul      }
138771340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul
1388e5b244ff7f984805c1bcc020342f1300f2639c71Brian Paul      /* write pixels */
1389733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      if (span->arrayMask & SPAN_XY) {
1390733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul         /* array of pixel coords */
139177df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul         (*swrast->Driver.WriteRGBAPixels)(ctx, span->end, span->array->x,
139277df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul             span->array->y, (const GLchan (*)[4]) span->array->rgba, span->array->mask);
1393733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul         if (SWRAST_CONTEXT(ctx)->_RasterMask & ALPHABUF_BIT) {
139445bc887da226403f2c41077e40ca38b6f60f1359Brian Paul            _swrast_write_alpha_pixels(ctx, span->end,
139577df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul                                     span->array->x, span->array->y,
139677df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul                                     (const GLchan (*)[4]) span->array->rgba,
139777df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul                                     span->array->mask);
1398733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul         }
1399733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      }
1400733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      else {
1401733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul         /* horizontal run of pixels */
1402733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul         (*swrast->Driver.WriteRGBASpan)(ctx, span->end, span->x, span->y,
140377df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul                                       (const GLchan (*)[4]) span->array->rgba,
140477df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul                                       span->writeAll ? NULL : span->array->mask);
1405733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul         if (swrast->_RasterMask & ALPHABUF_BIT) {
140645bc887da226403f2c41077e40ca38b6f60f1359Brian Paul            _swrast_write_alpha_span(ctx, span->end, span->x, span->y,
140777df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul                                   (const GLchan (*)[4]) span->array->rgba,
140877df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul                                   span->writeAll ? NULL : span->array->mask);
1409733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul         }
141071340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul      }
141171340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul   }
141271340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul
1413e5b244ff7f984805c1bcc020342f1300f2639c71Brian Paul   span->interpMask = origInterpMask;
1414f1e236987829393c81dc86ea19cb49eefe190317Brian Paul   span->arrayMask = origArrayMask;
141510f30eb43835c57c00783390a02d72daf4f78e26Brian Paul}
141610f30eb43835c57c00783390a02d72daf4f78e26Brian Paul
1417e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
1418e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
141979c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/**
1420e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Read RGBA pixels from frame buffer.  Clipping will be done to prevent
1421e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * reading ouside the buffer's boundaries.
1422e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */
14235071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paulvoid
142445bc887da226403f2c41077e40ca38b6f60f1359Brian Paul_swrast_read_rgba_span( GLcontext *ctx, GLframebuffer *buffer,
14255071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paul                      GLuint n, GLint x, GLint y, GLchan rgba[][4] )
1426e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell{
1427709892459922a32096fe9dd8261d0d92337bb02fKeith Whitwell   SWcontext *swrast = SWRAST_CONTEXT(ctx);
1428a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul   const GLint bufWidth = (GLint) buffer->Width;
14291113e3266f1a9df3506fb80189bfe00d9681b55eBrian Paul   const GLint bufHeight = (GLint) buffer->Height;
1430a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul
1431a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul   if (y < 0 || y >= bufHeight || x + (GLint) n < 0 || x >= bufWidth) {
1432e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      /* completely above, below, or right */
1433e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      /* XXX maybe leave undefined? */
14346ec6b845fdf3c44436028ad6fff9471d18928719Brian Paul      _mesa_bzero(rgba, 4 * n * sizeof(GLchan));
1435e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
1436e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   else {
1437e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      GLint skip, length;
1438e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      if (x < 0) {
1439e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         /* left edge clippping */
1440e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         skip = -x;
1441e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         length = (GLint) n - skip;
1442e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         if (length < 0) {
1443e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            /* completely left of window */
1444e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            return;
1445e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         }
1446a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul         if (length > bufWidth) {
1447a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul            length = bufWidth;
1448e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         }
1449e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
1450a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul      else if ((GLint) (x + n) > bufWidth) {
1451e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         /* right edge clipping */
1452e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         skip = 0;
1453a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul         length = bufWidth - x;
1454e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         if (length < 0) {
1455e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            /* completely to right of window */
1456e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            return;
1457e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         }
1458e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
1459e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      else {
1460e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         /* no clipping */
1461e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         skip = 0;
1462e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         length = (GLint) n;
1463e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
1464e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
1465709892459922a32096fe9dd8261d0d92337bb02fKeith Whitwell      (*swrast->Driver.ReadRGBASpan)( ctx, length, x + skip, y, rgba + skip );
1466e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      if (buffer->UseSoftwareAlphaBuffers) {
146745bc887da226403f2c41077e40ca38b6f60f1359Brian Paul         _swrast_read_alpha_span(ctx, length, x + skip, y, rgba + skip);
1468e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
1469e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
1470e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell}
1471e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
1472e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
147379c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/**
1474e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Read CI pixels from frame buffer.  Clipping will be done to prevent
1475e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * reading ouside the buffer's boundaries.
1476e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */
14775071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paulvoid
147845bc887da226403f2c41077e40ca38b6f60f1359Brian Paul_swrast_read_index_span( GLcontext *ctx, GLframebuffer *buffer,
14795071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paul                       GLuint n, GLint x, GLint y, GLuint indx[] )
1480e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell{
1481709892459922a32096fe9dd8261d0d92337bb02fKeith Whitwell   SWcontext *swrast = SWRAST_CONTEXT(ctx);
1482a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul   const GLint bufWidth = (GLint) buffer->Width;
14831113e3266f1a9df3506fb80189bfe00d9681b55eBrian Paul   const GLint bufHeight = (GLint) buffer->Height;
1484a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul
1485a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul   if (y < 0 || y >= bufHeight || x + (GLint) n < 0 || x >= bufWidth) {
1486e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      /* completely above, below, or right */
14876ec6b845fdf3c44436028ad6fff9471d18928719Brian Paul      _mesa_bzero(indx, n * sizeof(GLuint));
1488e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
1489e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   else {
1490e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      GLint skip, length;
1491e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      if (x < 0) {
1492e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         /* left edge clippping */
1493e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         skip = -x;
1494e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         length = (GLint) n - skip;
1495e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         if (length < 0) {
1496e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            /* completely left of window */
1497e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            return;
1498e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         }
1499a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul         if (length > bufWidth) {
1500a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul            length = bufWidth;
1501e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         }
1502e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
1503a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul      else if ((GLint) (x + n) > bufWidth) {
1504e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         /* right edge clipping */
1505e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         skip = 0;
1506a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul         length = bufWidth - x;
1507e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         if (length < 0) {
1508e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            /* completely to right of window */
1509e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            return;
1510e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         }
1511e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
1512e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      else {
1513e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         /* no clipping */
1514e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         skip = 0;
1515e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         length = (GLint) n;
1516e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
1517e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
1518709892459922a32096fe9dd8261d0d92337bb02fKeith Whitwell      (*swrast->Driver.ReadCI32Span)( ctx, length, skip + x, y, indx + skip );
1519e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
1520e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell}
1521