s_span.c revision f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3
1e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell/*
2e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Mesa 3-D graphics library
36e4f594a02fc384b17d5732be652d7d28618aec2Brian Paul * Version:  6.5
422144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes *
5a66393120411071b3f3ccce8583ab961a2935959Michal Krol * Copyright (C) 1999-2006  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"
38f971e24cf0341dd2779196a0836327b74fc82336Brian Paul#include "image.h"
39e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
407f752fed993e5e9423abac200dd59141edbada56Dave Airlie#include "s_atifragshader.h"
41bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol#include "s_alpha.h"
42e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_blend.h"
43cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell#include "s_context.h"
44e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_depth.h"
45e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_fog.h"
46e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_logic.h"
47e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_masking.h"
48c968d3d410a1897ecbb41d3557adaef69a4c627aBrian#include "s_fragprog.h"
49e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_span.h"
50e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_stencil.h"
5155187ea63e980b32c7a701855571332f4357d634Brian Paul#include "s_texcombine.h"
52e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
532a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul
5479c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/**
552a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul * Init span's Z interpolation values to the RasterPos Z.
562a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul * Used during setup for glDraw/CopyPixels.
572a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul */
582a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paulvoid
59cdb27e8242215271364602995d85607cfc06d441Brian Paul_swrast_span_default_z( GLcontext *ctx, SWspan *span )
602a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul{
61e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   const GLfloat depthMax = ctx->DrawBuffer->_DepthMaxF;
6231e739a18931fa48454f172818245b0927c8910fBrian Paul   if (ctx->DrawBuffer->Visual.depthBits <= 16)
63e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul      span->z = FloatToFixed(ctx->Current.RasterPos[2] * depthMax + 0.5F);
642a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   else
65e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul      span->z = (GLint) (ctx->Current.RasterPos[2] * depthMax + 0.5F);
662a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   span->zStep = 0;
672a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   span->interpMask |= SPAN_Z;
682a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul}
692a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul
702a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul
7179c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/**
722a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul * Init span's fog interpolation values to the RasterPos fog.
732a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul * Used during setup for glDraw/CopyPixels.
742a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul */
752a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paulvoid
76cdb27e8242215271364602995d85607cfc06d441Brian Paul_swrast_span_default_fog( GLcontext *ctx, SWspan *span )
772a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul{
7845bc887da226403f2c41077e40ca38b6f60f1359Brian Paul   span->fog = _swrast_z_to_fogfactor(ctx, ctx->Current.RasterDistance);
7954e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul   span->fogStep = span->dfogdx = span->dfogdy = 0.0F;
802a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   span->interpMask |= SPAN_FOG;
812a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul}
822a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul
832a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul
8479c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/**
85a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul * Init span's rgba or index interpolation values to the RasterPos color.
862a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul * Used during setup for glDraw/CopyPixels.
872a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul */
882a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paulvoid
89cdb27e8242215271364602995d85607cfc06d441Brian Paul_swrast_span_default_color( GLcontext *ctx, SWspan *span )
902a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul{
912a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   if (ctx->Visual.rgbMode) {
922a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      GLchan r, g, b, a;
932a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      UNCLAMPED_FLOAT_TO_CHAN(r, ctx->Current.RasterColor[0]);
942a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      UNCLAMPED_FLOAT_TO_CHAN(g, ctx->Current.RasterColor[1]);
952a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      UNCLAMPED_FLOAT_TO_CHAN(b, ctx->Current.RasterColor[2]);
962a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      UNCLAMPED_FLOAT_TO_CHAN(a, ctx->Current.RasterColor[3]);
972a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul#if CHAN_TYPE == GL_FLOAT
982a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      span->red = r;
992a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      span->green = g;
1002a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      span->blue = b;
1012a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      span->alpha = a;
1022a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul#else
1032a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      span->red   = IntToFixed(r);
1042a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      span->green = IntToFixed(g);
1052a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      span->blue  = IntToFixed(b);
1062a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      span->alpha = IntToFixed(a);
1072a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul#endif
1082a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      span->redStep = 0;
1092a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      span->greenStep = 0;
1102a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      span->blueStep = 0;
1112a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      span->alphaStep = 0;
1122a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      span->interpMask |= SPAN_RGBA;
1132a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   }
1142a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   else {
1150f3cd3f894612d156de454178effa4c732f96da7Brian Paul      span->index = FloatToFixed(ctx->Current.RasterIndex);
1162a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      span->indexStep = 0;
1172a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      span->interpMask |= SPAN_INDEX;
1182a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   }
1192a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul}
1202a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul
1212a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul
1224753d60dd070bb08d0116076bcc08025c86ce857Brian Paul/**
1234753d60dd070bb08d0116076bcc08025c86ce857Brian Paul * Init span's texcoord interpolation values to the RasterPos texcoords.
1244753d60dd070bb08d0116076bcc08025c86ce857Brian Paul * Used during setup for glDraw/CopyPixels.
1254753d60dd070bb08d0116076bcc08025c86ce857Brian Paul */
1264753d60dd070bb08d0116076bcc08025c86ce857Brian Paulvoid
127cdb27e8242215271364602995d85607cfc06d441Brian Paul_swrast_span_default_texcoords( GLcontext *ctx, SWspan *span )
1284753d60dd070bb08d0116076bcc08025c86ce857Brian Paul{
1294753d60dd070bb08d0116076bcc08025c86ce857Brian Paul   GLuint i;
130ee4e75bd6f768b7210436feeb32b4545ed62e025Brian Paul   for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) {
131e63cb85cbc13c083f5d9f4640bb81ba9417a4f28Brian Paul      const GLfloat *tc = ctx->Current.RasterTexCoords[i];
13212ef1fbefcee964b715783d3ade6b69b2c699ed8Brian      if (ctx->FragmentProgram._Current || ctx->ATIFragmentShader._Enabled) {
133a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul         COPY_4V(span->tex[i], tc);
134a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul      }
135a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul      else if (tc[3] > 0.0F) {
136e63cb85cbc13c083f5d9f4640bb81ba9417a4f28Brian Paul         /* use (s/q, t/q, r/q, 1) */
137e63cb85cbc13c083f5d9f4640bb81ba9417a4f28Brian Paul         span->tex[i][0] = tc[0] / tc[3];
138e63cb85cbc13c083f5d9f4640bb81ba9417a4f28Brian Paul         span->tex[i][1] = tc[1] / tc[3];
139e63cb85cbc13c083f5d9f4640bb81ba9417a4f28Brian Paul         span->tex[i][2] = tc[2] / tc[3];
140e63cb85cbc13c083f5d9f4640bb81ba9417a4f28Brian Paul         span->tex[i][3] = 1.0;
141e63cb85cbc13c083f5d9f4640bb81ba9417a4f28Brian Paul      }
142e63cb85cbc13c083f5d9f4640bb81ba9417a4f28Brian Paul      else {
143e63cb85cbc13c083f5d9f4640bb81ba9417a4f28Brian Paul         ASSIGN_4V(span->tex[i], 0.0F, 0.0F, 0.0F, 1.0F);
144e63cb85cbc13c083f5d9f4640bb81ba9417a4f28Brian Paul      }
1455f60a0b50ada1865d4fc6a724366e8ea0cc9a72fBrian Paul      ASSIGN_4V(span->texStepX[i], 0.0F, 0.0F, 0.0F, 0.0F);
1465f60a0b50ada1865d4fc6a724366e8ea0cc9a72fBrian Paul      ASSIGN_4V(span->texStepY[i], 0.0F, 0.0F, 0.0F, 0.0F);
1474753d60dd070bb08d0116076bcc08025c86ce857Brian Paul   }
1484753d60dd070bb08d0116076bcc08025c86ce857Brian Paul   span->interpMask |= SPAN_TEXTURE;
1494753d60dd070bb08d0116076bcc08025c86ce857Brian Paul}
1504753d60dd070bb08d0116076bcc08025c86ce857Brian Paul
1514753d60dd070bb08d0116076bcc08025c86ce857Brian Paul
152d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul/**
153e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul * Interpolate primary colors to fill in the span->array->color array.
154d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul */
155f614a6190562e550257afca0d04e3846648942e8Brian Paulstatic INLINE void
156e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paulinterpolate_colors(SWspan *span)
1572a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul{
1582a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   const GLuint n = span->end;
1592a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   GLuint i;
1602a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul
161e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul   ASSERT((span->interpMask & SPAN_RGBA)  &&
162e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul          !(span->arrayMask & SPAN_RGBA));
1632a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul
164e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul   switch (span->array->ChanType) {
1651e3223c02a2f6155beb5784cadbea1f46703829aBrian Paul#if CHAN_BITS != 32
166e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul   case GL_UNSIGNED_BYTE:
167e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul      {
168e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul         GLubyte (*rgba)[4] = span->array->color.sz1.rgba;
169e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul         if (span->interpMask & SPAN_FLAT) {
170d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            GLubyte color[4];
171e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul            color[RCOMP] = FixedToInt(span->red);
172e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul            color[GCOMP] = FixedToInt(span->green);
173e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul            color[BCOMP] = FixedToInt(span->blue);
174e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul            color[ACOMP] = FixedToInt(span->alpha);
175d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            for (i = 0; i < n; i++) {
176d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul               COPY_4UBV(rgba[i], color);
177d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            }
178d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul         }
179e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul         else {
180e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul            GLfixed r = span->red;
181e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul            GLfixed g = span->green;
182e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul            GLfixed b = span->blue;
183e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul            GLfixed a = span->alpha;
184e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul            GLint dr = span->redStep;
185e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul            GLint dg = span->greenStep;
186e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul            GLint db = span->blueStep;
187e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul            GLint da = span->alphaStep;
188d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            for (i = 0; i < n; i++) {
189e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul               rgba[i][RCOMP] = FixedToChan(r);
190e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul               rgba[i][GCOMP] = FixedToChan(g);
191e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul               rgba[i][BCOMP] = FixedToChan(b);
192e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul               rgba[i][ACOMP] = FixedToChan(a);
193e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul               r += dr;
194e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul               g += dg;
195e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul               b += db;
196e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul               a += da;
197d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            }
198d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul         }
199e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul      }
200e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul      break;
201e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul   case GL_UNSIGNED_SHORT:
202e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul      {
203e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul         GLushort (*rgba)[4] = span->array->color.sz2.rgba;
204e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul         if (span->interpMask & SPAN_FLAT) {
205e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul            GLushort color[4];
206e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul            color[RCOMP] = FixedToInt(span->red);
207e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul            color[GCOMP] = FixedToInt(span->green);
208e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul            color[BCOMP] = FixedToInt(span->blue);
209e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul            color[ACOMP] = FixedToInt(span->alpha);
210d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            for (i = 0; i < n; i++) {
211d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul               COPY_4V(rgba[i], color);
212d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            }
213d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul         }
214e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul         else {
215e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul            GLushort (*rgba)[4] = span->array->color.sz2.rgba;
216d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            GLfixed r, g, b, a;
217d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            GLint dr, dg, db, da;
218e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul            r = span->red;
219e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul            g = span->green;
220e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul            b = span->blue;
221e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul            a = span->alpha;
222e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul            dr = span->redStep;
223e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul            dg = span->greenStep;
224e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul            db = span->blueStep;
225e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul            da = span->alphaStep;
226d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            for (i = 0; i < n; i++) {
227d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul               rgba[i][RCOMP] = FixedToChan(r);
228d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul               rgba[i][GCOMP] = FixedToChan(g);
229d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul               rgba[i][BCOMP] = FixedToChan(b);
230d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul               rgba[i][ACOMP] = FixedToChan(a);
231d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul               r += dr;
232d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul               g += dg;
233d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul               b += db;
234d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul               a += da;
235d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            }
236d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul         }
237e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul      }
238e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul      break;
239e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul#endif
240e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul   case GL_FLOAT:
241e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul      {
242f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian         GLfloat (*rgba)[4] = span->array->attribs[FRAG_ATTRIB_COL0];
243e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul         GLfloat r, g, b, a, dr, dg, db, da;
244e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul         r = span->red;
245e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul         g = span->green;
246e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul         b = span->blue;
247e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul         a = span->alpha;
248e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul         if (span->interpMask & SPAN_FLAT) {
249e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul            dr = dg = db = da = 0.0;
250e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul         }
251e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul         else {
252e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul            dr = span->redStep;
253e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul            dg = span->greenStep;
254e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul            db = span->blueStep;
255e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul            da = span->alphaStep;
256e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul         }
257e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul         for (i = 0; i < n; i++) {
258e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul            rgba[i][RCOMP] = r;
259e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul            rgba[i][GCOMP] = g;
260e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul            rgba[i][BCOMP] = b;
261e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul            rgba[i][ACOMP] = a;
262e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul            r += dr;
263e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul            g += dg;
264e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul            b += db;
265e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul            a += da;
266e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul         }
267e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul      }
268e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul      break;
269e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul   default:
270e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul      _mesa_problem(NULL, "bad datatype in interpolate_colors");
271e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul   }
272e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul   span->arrayMask |= SPAN_RGBA;
273e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul}
274e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul
275e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul
276e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul/**
277e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul * Interpolate specular/secondary colors.
278e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul */
279f614a6190562e550257afca0d04e3846648942e8Brian Paulstatic INLINE void
280e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paulinterpolate_specular(SWspan *span)
281e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul{
282e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul   const GLuint n = span->end;
283e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul   GLuint i;
284e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul
285e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul   switch (span->array->ChanType) {
286c351858de8e51fa4a6425cf176cc43689189f3ffBrian Paul#if CHAN_BITS != 32
287e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul   case GL_UNSIGNED_BYTE:
288e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul      {
289e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul         GLubyte (*spec)[4] = span->array->color.sz1.spec;
290e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul         if (span->interpMask & SPAN_FLAT) {
291e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul            GLubyte color[4];
292e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul            color[RCOMP] = FixedToInt(span->specRed);
293e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul            color[GCOMP] = FixedToInt(span->specGreen);
294e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul            color[BCOMP] = FixedToInt(span->specBlue);
295e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul            color[ACOMP] = 0;
296e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul            for (i = 0; i < n; i++) {
297e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul               COPY_4UBV(spec[i], color);
298d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            }
299e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul         }
300e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul         else {
301e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul            GLfixed r = span->specRed;
302e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul            GLfixed g = span->specGreen;
303e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul            GLfixed b = span->specBlue;
304e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul            GLint dr = span->specRedStep;
305e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul            GLint dg = span->specGreenStep;
306e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul            GLint db = span->specBlueStep;
307d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            for (i = 0; i < n; i++) {
308e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul               spec[i][RCOMP] = CLAMP(FixedToChan(r), 0, 255);
309e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul               spec[i][GCOMP] = CLAMP(FixedToChan(g), 0, 255);
310e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul               spec[i][BCOMP] = CLAMP(FixedToChan(b), 0, 255);
311e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul               spec[i][ACOMP] = 0;
312d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul               r += dr;
313d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul               g += dg;
314d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul               b += db;
315d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            }
316d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul         }
317e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul      }
318e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul      break;
319e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul   case GL_UNSIGNED_SHORT:
320e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul      {
321e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul         GLushort (*spec)[4] = span->array->color.sz2.spec;
322e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul         if (span->interpMask & SPAN_FLAT) {
323e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul            GLushort color[4];
324e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul            color[RCOMP] = FixedToInt(span->specRed);
325e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul            color[GCOMP] = FixedToInt(span->specGreen);
326e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul            color[BCOMP] = FixedToInt(span->specBlue);
327e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul            color[ACOMP] = 0;
328e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul            for (i = 0; i < n; i++) {
329e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul               COPY_4V(spec[i], color);
330d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            }
331e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul         }
332e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul         else {
333e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul            GLfixed r = FloatToFixed(span->specRed);
334e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul            GLfixed g = FloatToFixed(span->specGreen);
335e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul            GLfixed b = FloatToFixed(span->specBlue);
336e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul            GLint dr = FloatToFixed(span->specRedStep);
337e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul            GLint dg = FloatToFixed(span->specGreenStep);
338e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul            GLint db = FloatToFixed(span->specBlueStep);
339e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul            for (i = 0; i < n; i++) {
340e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul               spec[i][RCOMP] = FixedToInt(r);
341e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul               spec[i][GCOMP] = FixedToInt(g);
342e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul               spec[i][BCOMP] = FixedToInt(b);
343e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul               spec[i][ACOMP] = 0;
344e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul               r += dr;
345e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul               g += dg;
346e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul               b += db;
347d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            }
348e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul         }
349e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul      }
350e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul      break;
351c351858de8e51fa4a6425cf176cc43689189f3ffBrian Paul#endif
352e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul   case GL_FLOAT:
353e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul      {
354f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian         GLfloat (*spec)[4] = span->array->attribs[FRAG_ATTRIB_COL1];
355e6f47d1855354165c6eed5080d8a72024891f10fBrian Paul#if CHAN_BITS <= 16
356e6f47d1855354165c6eed5080d8a72024891f10fBrian Paul         GLfloat r = CHAN_TO_FLOAT(FixedToChan(span->specRed));
357e6f47d1855354165c6eed5080d8a72024891f10fBrian Paul         GLfloat g = CHAN_TO_FLOAT(FixedToChan(span->specGreen));
358e6f47d1855354165c6eed5080d8a72024891f10fBrian Paul         GLfloat b = CHAN_TO_FLOAT(FixedToChan(span->specBlue));
359e6f47d1855354165c6eed5080d8a72024891f10fBrian Paul#else
360e6f47d1855354165c6eed5080d8a72024891f10fBrian Paul         GLfloat r = span->specRed;
361e6f47d1855354165c6eed5080d8a72024891f10fBrian Paul         GLfloat g = span->specGreen;
362e6f47d1855354165c6eed5080d8a72024891f10fBrian Paul         GLfloat b = span->specBlue;
363e6f47d1855354165c6eed5080d8a72024891f10fBrian Paul#endif
364e6f47d1855354165c6eed5080d8a72024891f10fBrian Paul         GLfloat dr, dg, db;
365e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul         if (span->interpMask & SPAN_FLAT) {
366e6f47d1855354165c6eed5080d8a72024891f10fBrian Paul            dr = dg = db = 0.0;
367e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul         }
368e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul         else {
369e6f47d1855354165c6eed5080d8a72024891f10fBrian Paul#if CHAN_BITS <= 16
370e6f47d1855354165c6eed5080d8a72024891f10fBrian Paul            dr = CHAN_TO_FLOAT(FixedToChan(span->specRedStep));
371e6f47d1855354165c6eed5080d8a72024891f10fBrian Paul            dg = CHAN_TO_FLOAT(FixedToChan(span->specGreenStep));
372e6f47d1855354165c6eed5080d8a72024891f10fBrian Paul            db = CHAN_TO_FLOAT(FixedToChan(span->specBlueStep));
373e6f47d1855354165c6eed5080d8a72024891f10fBrian Paul#else
374e6f47d1855354165c6eed5080d8a72024891f10fBrian Paul            dr = span->specRedStep;
375e6f47d1855354165c6eed5080d8a72024891f10fBrian Paul            dg = span->specGreenStep;
376e6f47d1855354165c6eed5080d8a72024891f10fBrian Paul            db = span->specBlueStep;
377e6f47d1855354165c6eed5080d8a72024891f10fBrian Paul#endif
378e6f47d1855354165c6eed5080d8a72024891f10fBrian Paul         }
379e6f47d1855354165c6eed5080d8a72024891f10fBrian Paul         for (i = 0; i < n; i++) {
380e6f47d1855354165c6eed5080d8a72024891f10fBrian Paul            spec[i][RCOMP] = r;
381e6f47d1855354165c6eed5080d8a72024891f10fBrian Paul            spec[i][GCOMP] = g;
382e6f47d1855354165c6eed5080d8a72024891f10fBrian Paul            spec[i][BCOMP] = b;
383e6f47d1855354165c6eed5080d8a72024891f10fBrian Paul            spec[i][ACOMP] = 0.0F;
384e6f47d1855354165c6eed5080d8a72024891f10fBrian Paul            r += dr;
385e6f47d1855354165c6eed5080d8a72024891f10fBrian Paul            g += dg;
386e6f47d1855354165c6eed5080d8a72024891f10fBrian Paul            b += db;
387d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul         }
3882a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      }
389e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul      break;
390e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul   default:
391e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul      _mesa_problem(NULL, "bad datatype in interpolate_specular");
3922a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   }
393e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul   span->arrayMask |= SPAN_SPEC;
3942a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul}
3952a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul
3962a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul
3972a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul/* Fill in the span.color.index array from the interpolation values */
398f614a6190562e550257afca0d04e3846648942e8Brian Paulstatic INLINE void
399cdb27e8242215271364602995d85607cfc06d441Brian Paulinterpolate_indexes(GLcontext *ctx, SWspan *span)
4002a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul{
4012a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   GLfixed index = span->index;
4022a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   const GLint indexStep = span->indexStep;
4032a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   const GLuint n = span->end;
40477df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul   GLuint *indexes = span->array->index;
4052a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   GLuint i;
406a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) ctx;
407b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul   ASSERT((span->interpMask & SPAN_INDEX)  &&
408b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul	  !(span->arrayMask & SPAN_INDEX));
4092a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul
4102a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   if ((span->interpMask & SPAN_FLAT) || (indexStep == 0)) {
4112a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      /* constant color */
4122a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      index = FixedToInt(index);
4132a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      for (i = 0; i < n; i++) {
4142a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         indexes[i] = index;
4152a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      }
4162a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   }
4172a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   else {
4182a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      /* interpolate */
4192a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      for (i = 0; i < n; i++) {
4202a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         indexes[i] = FixedToInt(index);
4212a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         index += indexStep;
4222a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      }
4232a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   }
4242a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   span->arrayMask |= SPAN_INDEX;
425e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   span->interpMask &= ~SPAN_INDEX;
4262a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul}
4272a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul
4282a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul
429d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul/* Fill in the span.array.fog values from the interpolation values */
430f614a6190562e550257afca0d04e3846648942e8Brian Paulstatic INLINE void
431cdb27e8242215271364602995d85607cfc06d441Brian Paulinterpolate_fog(const GLcontext *ctx, SWspan *span)
432d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul{
433f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian   GLfloat (*fog)[4] = span->array->attribs[FRAG_ATTRIB_FOGC];
434d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul   const GLfloat fogStep = span->fogStep;
435d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul   GLfloat fogCoord = span->fog;
436d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul   const GLuint haveW = (span->interpMask & SPAN_W);
437d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul   const GLfloat wStep = haveW ? span->dwdx : 0.0F;
438d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul   GLfloat w = haveW ? span->w : 1.0F;
439d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul   GLuint i;
440d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul   for (i = 0; i < span->end; i++) {
441f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian      fog[i][0] = fogCoord / w;
442d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul      fogCoord += fogStep;
443d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul      w += wStep;
444d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul   }
445d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul   span->arrayMask |= SPAN_FOG;
446d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul}
447d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul
448d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul
4492a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul/* Fill in the span.zArray array from the interpolation values */
450711e27fda27e4235b20a4cf73c2767c984ab2b81Brian Paulvoid
451cdb27e8242215271364602995d85607cfc06d441Brian Paul_swrast_span_interpolate_z( const GLcontext *ctx, SWspan *span )
4522a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul{
4532a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   const GLuint n = span->end;
4542a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   GLuint i;
4552a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul
456b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul   ASSERT((span->interpMask & SPAN_Z)  &&
457b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul	  !(span->arrayMask & SPAN_Z));
4582a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul
45931e739a18931fa48454f172818245b0927c8910fBrian Paul   if (ctx->DrawBuffer->Visual.depthBits <= 16) {
4602a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      GLfixed zval = span->z;
4613e37bafab0a339021354b9c78f983d05d433d735Brian Paul      GLuint *z = span->array->z;
462ad8cd6111e022c90c93df106c0fde6f64d205816Brian Paul      for (i = 0; i < n; i++) {
46377df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul         z[i] = FixedToInt(zval);
4642a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         zval += span->zStep;
4652a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      }
4662a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   }
4672a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   else {
4682a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      /* Deep Z buffer, no fixed->int shift */
4697265556b9aa0367e9b5031e7cb15ed2a5d73866dBrian Paul      GLuint zval = span->z;
4703e37bafab0a339021354b9c78f983d05d433d735Brian Paul      GLuint *z = span->array->z;
4712a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      for (i = 0; i < n; i++) {
47277df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul         z[i] = zval;
4732a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         zval += span->zStep;
4742a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      }
4752a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   }
47632340aea1308153dad5c105fc0748aea1e4c37eeBrian Paul   span->interpMask &= ~SPAN_Z;
4772a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   span->arrayMask |= SPAN_Z;
4782a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul}
4792a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul
4802a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul
481c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul/*
48231f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul * This the ideal solution, as given in the OpenGL spec.
483c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul */
484c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul#if 0
48531f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paulstatic GLfloat
48631f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paulcompute_lambda(GLfloat dsdx, GLfloat dsdy, GLfloat dtdx, GLfloat dtdy,
48731f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul               GLfloat dqdx, GLfloat dqdy, GLfloat texW, GLfloat texH,
48831f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul               GLfloat s, GLfloat t, GLfloat q, GLfloat invQ)
489c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul{
49031f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul   GLfloat dudx = texW * ((s + dsdx) / (q + dqdx) - s * invQ);
49131f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul   GLfloat dvdx = texH * ((t + dtdx) / (q + dqdx) - t * invQ);
49231f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul   GLfloat dudy = texW * ((s + dsdy) / (q + dqdy) - s * invQ);
49331f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul   GLfloat dvdy = texH * ((t + dtdy) / (q + dqdy) - t * invQ);
494f9b1e5241facc8cf255c258082d5cb5b04783e93Brian Paul   GLfloat x = SQRTF(dudx * dudx + dvdx * dvdx);
495f9b1e5241facc8cf255c258082d5cb5b04783e93Brian Paul   GLfloat y = SQRTF(dudy * dudy + dvdy * dvdy);
49631f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul   GLfloat rho = MAX2(x, y);
49731f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul   GLfloat lambda = LOG2(rho);
49831f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul   return lambda;
499c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul}
500c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul#endif
501c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul
50231f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul
50331f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul/*
50431f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul * This is a faster approximation
505c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul */
506350353adcd75f94fda63c787c86961716114e0bfBrian PaulGLfloat
50745bc887da226403f2c41077e40ca38b6f60f1359Brian Paul_swrast_compute_lambda(GLfloat dsdx, GLfloat dsdy, GLfloat dtdx, GLfloat dtdy,
508350353adcd75f94fda63c787c86961716114e0bfBrian Paul                     GLfloat dqdx, GLfloat dqdy, GLfloat texW, GLfloat texH,
509350353adcd75f94fda63c787c86961716114e0bfBrian Paul                     GLfloat s, GLfloat t, GLfloat q, GLfloat invQ)
510c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul{
51131f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul   GLfloat dsdx2 = (s + dsdx) / (q + dqdx) - s * invQ;
51231f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul   GLfloat dtdx2 = (t + dtdx) / (q + dqdx) - t * invQ;
51331f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul   GLfloat dsdy2 = (s + dsdy) / (q + dqdy) - s * invQ;
51431f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul   GLfloat dtdy2 = (t + dtdy) / (q + dqdy) - t * invQ;
51531f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul   GLfloat maxU, maxV, rho, lambda;
51631f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul   dsdx2 = FABSF(dsdx2);
51731f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul   dsdy2 = FABSF(dsdy2);
51831f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul   dtdx2 = FABSF(dtdx2);
51931f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul   dtdy2 = FABSF(dtdy2);
52031f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul   maxU = MAX2(dsdx2, dsdy2) * texW;
52131f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul   maxV = MAX2(dtdx2, dtdy2) * texH;
52231f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul   rho = MAX2(maxU, maxV);
52331f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul   lambda = LOG2(rho);
52431f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul   return lambda;
525c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul}
526c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul
527d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul
528d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul/**
529c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul * Fill in the span.texcoords array from the interpolation values.
530d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul * Note: in the places where we divide by Q (or mult by invQ) we're
531d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul * really doing two things: perspective correction and texcoord
532d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul * projection.  Remember, for texcoord (s,t,r,q) we need to index
533d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul * texels with (s/q, t/q, r/q).
534d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul * If we're using a fragment program, we never do the division
535d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul * for texcoord projection.  That's done by the TXP instruction
536d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul * or user-written code.
537c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul */
5382a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paulstatic void
539cdb27e8242215271364602995d85607cfc06d441Brian Paulinterpolate_texcoords(GLcontext *ctx, SWspan *span)
5402a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul{
5412a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   ASSERT(span->interpMask & SPAN_TEXTURE);
542b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul   ASSERT(!(span->arrayMask & SPAN_TEXTURE));
5432a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul
54436a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul   if (ctx->Texture._EnabledCoordUnits > 1) {
54531f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul      /* multitexture */
54631f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul      GLuint u;
547b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul      span->arrayMask |= SPAN_TEXTURE;
548ee4e75bd6f768b7210436feeb32b4545ed62e025Brian Paul      /* XXX CoordUnits vs. ImageUnits */
54931f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul      for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
55036a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul         if (ctx->Texture._EnabledCoordUnits & (1 << u)) {
55131f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul            const struct gl_texture_object *obj =ctx->Texture.Unit[u]._Current;
55236a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul            GLfloat texW, texH;
55336a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul            GLboolean needLambda;
55436a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul            if (obj) {
55518fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell               const struct gl_texture_image *img = obj->Image[0][obj->BaseLevel];
55636a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul               needLambda = (obj->MinFilter != obj->MagFilter)
55712ef1fbefcee964b715783d3ade6b69b2c699ed8Brian                  || ctx->FragmentProgram._Current;
55836a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul               texW = img->WidthScale;
55936a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul               texH = img->HeightScale;
56036a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul            }
56136a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul            else {
562d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul               /* using a fragment program */
56336a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul               texW = 1.0;
56436a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul               texH = 1.0;
56536a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul               needLambda = GL_FALSE;
56636a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul            }
56731f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul            if (needLambda) {
568f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian               GLfloat (*texcoord)[4] = span->array->attribs[FRAG_ATTRIB_TEX0 + u];
56977df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul               GLfloat *lambda = span->array->lambda[u];
57031f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul               const GLfloat dsdx = span->texStepX[u][0];
57131f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul               const GLfloat dsdy = span->texStepY[u][0];
57231f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul               const GLfloat dtdx = span->texStepX[u][1];
57331f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul               const GLfloat dtdy = span->texStepY[u][1];
57431f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul               const GLfloat drdx = span->texStepX[u][2];
57531f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul               const GLfloat dqdx = span->texStepX[u][3];
57631f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul               const GLfloat dqdy = span->texStepY[u][3];
5772a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul               GLfloat s = span->tex[u][0];
5782a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul               GLfloat t = span->tex[u][1];
5792a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul               GLfloat r = span->tex[u][2];
5802a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul               GLfloat q = span->tex[u][3];
5812a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul               GLuint i;
58212ef1fbefcee964b715783d3ade6b69b2c699ed8Brian               if (ctx->FragmentProgram._Current
58312ef1fbefcee964b715783d3ade6b69b2c699ed8Brian                   || ctx->ATIFragmentShader._Enabled) {
584d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul                  /* do perspective correction but don't divide s, t, r by q */
585d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul                  const GLfloat dwdx = span->dwdx;
586d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul                  GLfloat w = span->w;
587d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul                  for (i = 0; i < span->end; i++) {
588d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul                     const GLfloat invW = 1.0F / w;
589d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul                     texcoord[i][0] = s * invW;
590d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul                     texcoord[i][1] = t * invW;
591d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul                     texcoord[i][2] = r * invW;
592d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul                     texcoord[i][3] = q * invW;
593d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul                     lambda[i] = _swrast_compute_lambda(dsdx, dsdy, dtdx, dtdy,
594d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul                                                        dqdx, dqdy, texW, texH,
595d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul                                                        s, t, q, invW);
596d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul                     s += dsdx;
597d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul                     t += dtdx;
598d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul                     r += drdx;
599d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul                     q += dqdx;
600d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul                     w += dwdx;
601d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul                  }
602d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul
603d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul               }
604d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul               else {
605d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul                  for (i = 0; i < span->end; i++) {
606d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul                     const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q);
607d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul                     texcoord[i][0] = s * invQ;
608d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul                     texcoord[i][1] = t * invQ;
609d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul                     texcoord[i][2] = r * invQ;
610d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul                     texcoord[i][3] = q;
611d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul                     lambda[i] = _swrast_compute_lambda(dsdx, dsdy, dtdx, dtdy,
612d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul                                                        dqdx, dqdy, texW, texH,
613d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul                                                        s, t, q, invQ);
614d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul                     s += dsdx;
615d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul                     t += dtdx;
616d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul                     r += drdx;
617d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul                     q += dqdx;
618d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul                  }
6192a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul               }
62031f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul               span->arrayMask |= SPAN_LAMBDA;
6212a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul            }
62231f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul            else {
623f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian               GLfloat (*texcoord)[4] = span->array->attribs[FRAG_ATTRIB_TEX0 + u];
62477df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul               GLfloat *lambda = span->array->lambda[u];
62531f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul               const GLfloat dsdx = span->texStepX[u][0];
62631f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul               const GLfloat dtdx = span->texStepX[u][1];
62731f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul               const GLfloat drdx = span->texStepX[u][2];
62831f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul               const GLfloat dqdx = span->texStepX[u][3];
6292a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul               GLfloat s = span->tex[u][0];
6302a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul               GLfloat t = span->tex[u][1];
6312a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul               GLfloat r = span->tex[u][2];
6322a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul               GLfloat q = span->tex[u][3];
6332a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul               GLuint i;
63412ef1fbefcee964b715783d3ade6b69b2c699ed8Brian               if (ctx->FragmentProgram._Current ||
63512ef1fbefcee964b715783d3ade6b69b2c699ed8Brian                   ctx->ATIFragmentShader._Enabled) {
636d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul                  /* do perspective correction but don't divide s, t, r by q */
637d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul                  const GLfloat dwdx = span->dwdx;
638d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul                  GLfloat w = span->w;
639d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul                  for (i = 0; i < span->end; i++) {
640d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul                     const GLfloat invW = 1.0F / w;
641d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul                     texcoord[i][0] = s * invW;
642d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul                     texcoord[i][1] = t * invW;
643d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul                     texcoord[i][2] = r * invW;
644d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul                     texcoord[i][3] = q * invW;
645d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul                     lambda[i] = 0.0;
646d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul                     s += dsdx;
647d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul                     t += dtdx;
648d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul                     r += drdx;
649d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul                     q += dqdx;
650d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul                     w += dwdx;
651d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul                  }
652d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul               }
653d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul               else if (dqdx == 0.0F) {
654c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul                  /* Ortho projection or polygon's parallel to window X axis */
6552a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul                  const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q);
656c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul                  for (i = 0; i < span->end; i++) {
65777df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul                     texcoord[i][0] = s * invQ;
65877df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul                     texcoord[i][1] = t * invQ;
65977df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul                     texcoord[i][2] = r * invQ;
66036a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul                     texcoord[i][3] = q;
66177df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul                     lambda[i] = 0.0;
66231f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul                     s += dsdx;
66331f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul                     t += dtdx;
66431f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul                     r += drdx;
665c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul                  }
666c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul               }
667c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul               else {
668c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul                  for (i = 0; i < span->end; i++) {
669c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul                     const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q);
67077df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul                     texcoord[i][0] = s * invQ;
67177df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul                     texcoord[i][1] = t * invQ;
67277df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul                     texcoord[i][2] = r * invQ;
67336a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul                     texcoord[i][3] = q;
67477df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul                     lambda[i] = 0.0;
67531f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul                     s += dsdx;
67631f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul                     t += dtdx;
67731f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul                     r += drdx;
67831f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul                     q += dqdx;
679c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul                  }
6802a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul               }
68131f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul            } /* lambda */
68231f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul         } /* if */
68331f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul      } /* for */
6842a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   }
6852a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   else {
68631f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul      /* single texture */
68731f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul      const struct gl_texture_object *obj = ctx->Texture.Unit[0]._Current;
68836a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul      GLfloat texW, texH;
68936a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul      GLboolean needLambda;
69036a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul      if (obj) {
69118fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell         const struct gl_texture_image *img = obj->Image[0][obj->BaseLevel];
69236a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul         needLambda = (obj->MinFilter != obj->MagFilter)
69312ef1fbefcee964b715783d3ade6b69b2c699ed8Brian            || ctx->FragmentProgram._Current;
69436a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul         texW = (GLfloat) img->WidthScale;
69536a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul         texH = (GLfloat) img->HeightScale;
69636a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul      }
69736a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul      else {
69836a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul         needLambda = GL_FALSE;
69936a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul         texW = texH = 1.0;
70036a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul      }
701b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul      span->arrayMask |= SPAN_TEXTURE;
70231f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul      if (needLambda) {
7032a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         /* just texture unit 0, with lambda */
704f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian         GLfloat (*texcoord)[4] = span->array->attribs[FRAG_ATTRIB_TEX0];
70577df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul         GLfloat *lambda = span->array->lambda[0];
70631f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul         const GLfloat dsdx = span->texStepX[0][0];
70731f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul         const GLfloat dsdy = span->texStepY[0][0];
70831f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul         const GLfloat dtdx = span->texStepX[0][1];
70931f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul         const GLfloat dtdy = span->texStepY[0][1];
71031f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul         const GLfloat drdx = span->texStepX[0][2];
71131f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul         const GLfloat dqdx = span->texStepX[0][3];
71231f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul         const GLfloat dqdy = span->texStepY[0][3];
7132a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         GLfloat s = span->tex[0][0];
7142a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         GLfloat t = span->tex[0][1];
7152a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         GLfloat r = span->tex[0][2];
7162a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         GLfloat q = span->tex[0][3];
7172a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         GLuint i;
71812ef1fbefcee964b715783d3ade6b69b2c699ed8Brian         if (ctx->FragmentProgram._Current
71912ef1fbefcee964b715783d3ade6b69b2c699ed8Brian             || ctx->ATIFragmentShader._Enabled) {
720d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul            /* do perspective correction but don't divide s, t, r by q */
721d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul            const GLfloat dwdx = span->dwdx;
722d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul            GLfloat w = span->w;
723d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul            for (i = 0; i < span->end; i++) {
724d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul               const GLfloat invW = 1.0F / w;
725d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul               texcoord[i][0] = s * invW;
726d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul               texcoord[i][1] = t * invW;
727d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul               texcoord[i][2] = r * invW;
728d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul               texcoord[i][3] = q * invW;
729d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul               lambda[i] = _swrast_compute_lambda(dsdx, dsdy, dtdx, dtdy,
730d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul                                                  dqdx, dqdy, texW, texH,
731d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul                                                  s, t, q, invW);
732d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul               s += dsdx;
733d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul               t += dtdx;
734d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul               r += drdx;
735d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul               q += dqdx;
736d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul               w += dwdx;
737d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul            }
738d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul         }
739d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul         else {
740d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul            /* tex.c */
741d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul            for (i = 0; i < span->end; i++) {
742d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul               const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q);
743d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul               lambda[i] = _swrast_compute_lambda(dsdx, dsdy, dtdx, dtdy,
744d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul                                                dqdx, dqdy, texW, texH,
745d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul                                                s, t, q, invQ);
746d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul               texcoord[i][0] = s * invQ;
747d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul               texcoord[i][1] = t * invQ;
748d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul               texcoord[i][2] = r * invQ;
749d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul               texcoord[i][3] = q;
750d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul               s += dsdx;
751d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul               t += dtdx;
752d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul               r += drdx;
753d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul               q += dqdx;
754d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul            }
7552a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         }
7562a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         span->arrayMask |= SPAN_LAMBDA;
7572a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      }
7582a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      else {
759733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul         /* just texture 0, without lambda */
760f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian         GLfloat (*texcoord)[4] = span->array->attribs[FRAG_ATTRIB_TEX0];
76131f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul         const GLfloat dsdx = span->texStepX[0][0];
76231f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul         const GLfloat dtdx = span->texStepX[0][1];
76331f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul         const GLfloat drdx = span->texStepX[0][2];
76431f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul         const GLfloat dqdx = span->texStepX[0][3];
7652a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         GLfloat s = span->tex[0][0];
7662a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         GLfloat t = span->tex[0][1];
7672a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         GLfloat r = span->tex[0][2];
7682a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         GLfloat q = span->tex[0][3];
7692a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         GLuint i;
77012ef1fbefcee964b715783d3ade6b69b2c699ed8Brian         if (ctx->FragmentProgram._Current
77112ef1fbefcee964b715783d3ade6b69b2c699ed8Brian             || ctx->ATIFragmentShader._Enabled) {
772d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul            /* do perspective correction but don't divide s, t, r by q */
773d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul            const GLfloat dwdx = span->dwdx;
774d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul            GLfloat w = span->w;
775d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul            for (i = 0; i < span->end; i++) {
776d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul               const GLfloat invW = 1.0F / w;
777d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul               texcoord[i][0] = s * invW;
778d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul               texcoord[i][1] = t * invW;
779d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul               texcoord[i][2] = r * invW;
780d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul               texcoord[i][3] = q * invW;
781d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul               s += dsdx;
782d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul               t += dtdx;
783d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul               r += drdx;
784d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul               q += dqdx;
785d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul               w += dwdx;
786d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul            }
787d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul         }
788d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul         else if (dqdx == 0.0F) {
789c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul            /* Ortho projection or polygon's parallel to window X axis */
7902a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul            const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q);
791c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul            for (i = 0; i < span->end; i++) {
79277df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul               texcoord[i][0] = s * invQ;
79377df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul               texcoord[i][1] = t * invQ;
79477df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul               texcoord[i][2] = r * invQ;
7952b7a01a39ba5257407dddde38ef049856c34aa01Brian Paul               texcoord[i][3] = q;
79631f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul               s += dsdx;
79731f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul               t += dtdx;
79831f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul               r += drdx;
799c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul            }
800c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul         }
801c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul         else {
802c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul            for (i = 0; i < span->end; i++) {
803c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul               const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q);
80477df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul               texcoord[i][0] = s * invQ;
80577df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul               texcoord[i][1] = t * invQ;
80677df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul               texcoord[i][2] = r * invQ;
8072b7a01a39ba5257407dddde38ef049856c34aa01Brian Paul               texcoord[i][3] = q;
80831f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul               s += dsdx;
80931f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul               t += dtdx;
81031f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul               r += drdx;
81131f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul               q += dqdx;
812c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul            }
8132a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul         }
8142a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      }
8152a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   }
81610f30eb43835c57c00783390a02d72daf4f78e26Brian Paul}
817e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
818e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
81979c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/**
820bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol * Fill in the span.varying array from the interpolation values.
821bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol */
822f614a6190562e550257afca0d04e3846648942e8Brian Paulstatic INLINE void
823cdb27e8242215271364602995d85607cfc06d441Brian Paulinterpolate_varying(GLcontext *ctx, SWspan *span)
824bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol{
825ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian   GLuint var;
826ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian   const GLbitfield inputsUsed = ctx->FragmentProgram._Current->Base.InputsRead;
827bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol
828bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol   ASSERT(span->interpMask & SPAN_VARYING);
829bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol   ASSERT(!(span->arrayMask & SPAN_VARYING));
830bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol
831bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol   span->arrayMask |= SPAN_VARYING;
832bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol
833ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian   for (var = 0; var < MAX_VARYING; var++) {
834ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian      if (inputsUsed & FRAG_BIT_VAR(var)) {
835ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian         GLuint j;
836ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian         for (j = 0; j < 4; j++) {
837ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian            const GLfloat dvdx = span->varStepX[var][j];
838ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian            GLfloat v = span->var[var][j];
839ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian            const GLfloat dwdx = span->dwdx;
840ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian            GLfloat w = span->w;
841ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian            GLuint k;
842ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian            for (k = 0; k < span->end; k++) {
843ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian               GLfloat invW = 1.0f / w;
844f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian               span->array->attribs[FRAG_ATTRIB_VAR0 + var][k][j] = v * invW;
845ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian               v += dvdx;
846ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian               w += dwdx;
847ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian            }
848bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol         }
849bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol      }
850bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol   }
851bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol}
852bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol
853bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol
854bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol/**
855f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian * Fill in the arrays->attribs[FRAG_ATTRIB_WPOS] array.
856f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian */
857f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brianstatic INLINE void
858f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brianinterpolate_wpos(GLcontext *ctx, SWspan *span)
859f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian{
860f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian   GLfloat (*wpos)[4] = span->array->attribs[FRAG_ATTRIB_WPOS];
861f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian   GLuint i;
862f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian   if (span->arrayMask & SPAN_XY) {
863f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian      for (i = 0; i < span->end; i++) {
864f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian         wpos[i][0] = (GLfloat) span->array->x[i];
865f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian         wpos[i][1] = (GLfloat) span->array->y[i];
866f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian      }
867f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian   }
868f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian   else {
869f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian      for (i = 0; i < span->end; i++) {
870f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian         wpos[i][0] = (GLfloat) span->x + i;
871f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian         wpos[i][1] = (GLfloat) span->y;
872f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian      }
873f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian   }
874f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian   for (i = 0; i < span->end; i++) {
875f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian      wpos[i][2] = (GLfloat) span->array->z[i] / ctx->DrawBuffer->_DepthMaxF;
876f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian      wpos[i][3] = span->w + i * span->dwdx;
877f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian   }
878f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian}
879f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian
880f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian
881f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian/**
882e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Apply the current polygon stipple pattern to a span of pixels.
883e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */
884f614a6190562e550257afca0d04e3846648942e8Brian Paulstatic INLINE void
885ea8b68e0f7e7a4025ce662d36380157273ce10a3Brianstipple_polygon_span(GLcontext *ctx, SWspan *span)
88610f30eb43835c57c00783390a02d72daf4f78e26Brian Paul{
88777df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul   GLubyte *mask = span->array->mask;
888733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul
889733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul   ASSERT(ctx->Polygon.StippleFlag);
89010f30eb43835c57c00783390a02d72daf4f78e26Brian Paul
891ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian   if (span->arrayMask & SPAN_XY) {
892ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian      /* arrays of x/y pixel coords */
893ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian      GLuint i;
894ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian      for (i = 0; i < span->end; i++) {
895ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian         const GLint col = span->array->x[i] % 32;
896ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian         const GLint row = span->array->y[i] % 32;
897ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian         const GLuint stipple = ctx->PolygonStipple[row];
898ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian         if (((1 << col) & stipple) == 0) {
899ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian            mask[i] = 0;
900ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian         }
90110f30eb43835c57c00783390a02d72daf4f78e26Brian Paul      }
902ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian   }
903ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian   else {
904ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian      /* horizontal span of pixels */
905ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian      const GLuint highBit = 1 << 31;
906ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian      const GLuint stipple = ctx->PolygonStipple[span->y % 32];
907ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian      GLuint i, m = highBit >> (GLuint) (span->x % 32);
908ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian      for (i = 0; i < span->end; i++) {
909ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian         if ((m & stipple) == 0) {
910ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian            mask[i] = 0;
911ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian         }
912ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian         m = m >> 1;
913ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian         if (m == 0) {
914ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian            m = highBit;
915ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian         }
91610f30eb43835c57c00783390a02d72daf4f78e26Brian Paul      }
91710f30eb43835c57c00783390a02d72daf4f78e26Brian Paul   }
9182ef866d1fc0a5cc5ef8543d65744dfd4da4dbbafBrian Paul   span->writeAll = GL_FALSE;
91910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul}
92010f30eb43835c57c00783390a02d72daf4f78e26Brian Paul
921e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
92279c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/**
923733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul * Clip a pixel span to the current buffer/window boundaries:
924733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul * DrawBuffer->_Xmin, _Xmax, _Ymin, _Ymax.  This will accomplish
925733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul * window clipping and scissoring.
926733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul * Return:   GL_TRUE   some pixels still visible
92710f30eb43835c57c00783390a02d72daf4f78e26Brian Paul *           GL_FALSE  nothing visible
92810f30eb43835c57c00783390a02d72daf4f78e26Brian Paul */
929f614a6190562e550257afca0d04e3846648942e8Brian Paulstatic INLINE GLuint
930cdb27e8242215271364602995d85607cfc06d441Brian Paulclip_span( GLcontext *ctx, SWspan *span )
93110f30eb43835c57c00783390a02d72daf4f78e26Brian Paul{
932733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul   const GLint xmin = ctx->DrawBuffer->_Xmin;
933733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul   const GLint xmax = ctx->DrawBuffer->_Xmax;
934733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul   const GLint ymin = ctx->DrawBuffer->_Ymin;
935733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul   const GLint ymax = ctx->DrawBuffer->_Ymax;
936733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul
937733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul   if (span->arrayMask & SPAN_XY) {
938733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      /* arrays of x/y pixel coords */
93977df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul      const GLint *x = span->array->x;
94077df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul      const GLint *y = span->array->y;
941733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      const GLint n = span->end;
94277df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul      GLubyte *mask = span->array->mask;
943733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      GLint i;
944b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul      if (span->arrayMask & SPAN_MASK) {
945b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul         /* note: using & intead of && to reduce branches */
946b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul         for (i = 0; i < n; i++) {
947b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul            mask[i] &= (x[i] >= xmin) & (x[i] < xmax)
948b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul                     & (y[i] >= ymin) & (y[i] < ymax);
949b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul         }
950b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul      }
951b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul      else {
952b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul         /* note: using & intead of && to reduce branches */
953b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul         for (i = 0; i < n; i++) {
954b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul            mask[i] = (x[i] >= xmin) & (x[i] < xmax)
955b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul                    & (y[i] >= ymin) & (y[i] < ymax);
956b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul         }
95710f30eb43835c57c00783390a02d72daf4f78e26Brian Paul      }
958733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      return GL_TRUE;  /* some pixels visible */
95910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul   }
960733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul   else {
961733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      /* horizontal span of pixels */
962733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      const GLint x = span->x;
963733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      const GLint y = span->y;
964733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      const GLint n = span->end;
965733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul
966733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      /* Trivial rejection tests */
967733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      if (y < ymin || y >= ymax || x + n <= xmin || x >= xmax) {
968733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul         span->end = 0;
969733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul         return GL_FALSE;  /* all pixels clipped */
970733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      }
97110f30eb43835c57c00783390a02d72daf4f78e26Brian Paul
972733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      /* Clip to the left */
973733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      if (x < xmin) {
974733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul         ASSERT(x + n > xmin);
975733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul         span->writeAll = GL_FALSE;
9766ec6b845fdf3c44436028ad6fff9471d18928719Brian Paul         _mesa_bzero(span->array->mask, (xmin - x) * sizeof(GLubyte));
97710f30eb43835c57c00783390a02d72daf4f78e26Brian Paul      }
978733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul
979733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      /* Clip to right */
980733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      if (x + n > xmax) {
981733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul         ASSERT(x < xmax);
982733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul         span->end = xmax - x;
98310f30eb43835c57c00783390a02d72daf4f78e26Brian Paul      }
98410f30eb43835c57c00783390a02d72daf4f78e26Brian Paul
985733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      return GL_TRUE;  /* some pixels visible */
986733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul   }
98710f30eb43835c57c00783390a02d72daf4f78e26Brian Paul}
98810f30eb43835c57c00783390a02d72daf4f78e26Brian Paul
98910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul
99079c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/**
991e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul * Apply all the per-fragment opertions to a span of color index fragments
992e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul * and write them to the enabled color drawbuffers.
993e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul * The 'span' parameter can be considered to be const.  Note that
9947956292a765910077f50352d7cd0174e1e66d26cBrian Paul * span->interpMask and span->arrayMask may be changed but will be restored
9957956292a765910077f50352d7cd0174e1e66d26cBrian Paul * to their original values before returning.
99610f30eb43835c57c00783390a02d72daf4f78e26Brian Paul */
99710f30eb43835c57c00783390a02d72daf4f78e26Brian Paulvoid
998cdb27e8242215271364602995d85607cfc06d441Brian Paul_swrast_write_index_span( GLcontext *ctx, SWspan *span)
99910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul{
1000e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   const SWcontext *swrast = SWRAST_CONTEXT(ctx);
1001e00ac11d4dd05c56584622dc2707bbdcfe4b2707Brian Paul   const GLbitfield origInterpMask = span->interpMask;
1002e00ac11d4dd05c56584622dc2707bbdcfe4b2707Brian Paul   const GLbitfield origArrayMask = span->arrayMask;
100310f30eb43835c57c00783390a02d72daf4f78e26Brian Paul
1004733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul   ASSERT(span->end <= MAX_WIDTH);
1005b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul   ASSERT(span->primitive == GL_POINT  ||  span->primitive == GL_LINE ||
1006b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul	  span->primitive == GL_POLYGON  ||  span->primitive == GL_BITMAP);
1007733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul   ASSERT((span->interpMask | span->arrayMask) & SPAN_INDEX);
10087956292a765910077f50352d7cd0174e1e66d26cBrian Paul   ASSERT((span->interpMask & span->arrayMask) == 0);
10097956292a765910077f50352d7cd0174e1e66d26cBrian Paul
1010733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul   if (span->arrayMask & SPAN_MASK) {
1011733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      /* mask was initialized by caller, probably glBitmap */
1012733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      span->writeAll = GL_FALSE;
1013733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul   }
1014733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul   else {
1015a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul      _mesa_memset(span->array->mask, 1, span->end);
1016733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      span->writeAll = GL_TRUE;
101710f30eb43835c57c00783390a02d72daf4f78e26Brian Paul   }
101810f30eb43835c57c00783390a02d72daf4f78e26Brian Paul
1019733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul   /* Clipping */
1020b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul   if ((swrast->_RasterMask & CLIP_BIT) || (span->primitive != GL_POLYGON)) {
1021733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      if (!clip_span(ctx, span)) {
102286ca15ece74ccb5a8f4d566a4b2c8024b178d73bBrian Paul         return;
1023e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
1024e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
1025e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
1026e5b244ff7f984805c1bcc020342f1300f2639c71Brian Paul   /* Depth bounds test */
102731e739a18931fa48454f172818245b0927c8910fBrian Paul   if (ctx->Depth.BoundsTest && ctx->DrawBuffer->Visual.depthBits > 0) {
1028e5b244ff7f984805c1bcc020342f1300f2639c71Brian Paul      if (!_swrast_depth_bounds_test(ctx, span)) {
1029e5b244ff7f984805c1bcc020342f1300f2639c71Brian Paul         return;
1030e5b244ff7f984805c1bcc020342f1300f2639c71Brian Paul      }
1031e5b244ff7f984805c1bcc020342f1300f2639c71Brian Paul   }
1032e5b244ff7f984805c1bcc020342f1300f2639c71Brian Paul
1033b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul#ifdef DEBUG
1034a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul   /* Make sure all fragments are within window bounds */
1035b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul   if (span->arrayMask & SPAN_XY) {
1036a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul      GLuint i;
1037b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul      for (i = 0; i < span->end; i++) {
103877df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul         if (span->array->mask[i]) {
103977df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul            assert(span->array->x[i] >= ctx->DrawBuffer->_Xmin);
104077df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul            assert(span->array->x[i] < ctx->DrawBuffer->_Xmax);
104177df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul            assert(span->array->y[i] >= ctx->DrawBuffer->_Ymin);
104277df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul            assert(span->array->y[i] < ctx->DrawBuffer->_Ymax);
1043b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul         }
1044b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul      }
1045b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul   }
1046b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul#endif
1047b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul
1048e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   /* Polygon Stippling */
1049b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul   if (ctx->Polygon.StippleFlag && span->primitive == GL_POLYGON) {
105010f30eb43835c57c00783390a02d72daf4f78e26Brian Paul      stipple_polygon_span(ctx, span);
1051e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
1052e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
1053e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   /* Stencil and Z testing */
10547956292a765910077f50352d7cd0174e1e66d26cBrian Paul   if (ctx->Depth.Test || ctx->Stencil.Enabled) {
10557956292a765910077f50352d7cd0174e1e66d26cBrian Paul      if (span->interpMask & SPAN_Z)
105645bc887da226403f2c41077e40ca38b6f60f1359Brian Paul         _swrast_span_interpolate_z(ctx, span);
105710f30eb43835c57c00783390a02d72daf4f78e26Brian Paul
10587956292a765910077f50352d7cd0174e1e66d26cBrian Paul      if (ctx->Stencil.Enabled) {
105945bc887da226403f2c41077e40ca38b6f60f1359Brian Paul         if (!_swrast_stencil_and_ztest_span(ctx, span)) {
10607956292a765910077f50352d7cd0174e1e66d26cBrian Paul            span->arrayMask = origArrayMask;
10617956292a765910077f50352d7cd0174e1e66d26cBrian Paul            return;
10627956292a765910077f50352d7cd0174e1e66d26cBrian Paul         }
10632a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      }
10647956292a765910077f50352d7cd0174e1e66d26cBrian Paul      else {
10657956292a765910077f50352d7cd0174e1e66d26cBrian Paul         ASSERT(ctx->Depth.Test);
106645bc887da226403f2c41077e40ca38b6f60f1359Brian Paul         if (!_swrast_depth_test_span(ctx, span)) {
1067e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul            span->interpMask = origInterpMask;
10687956292a765910077f50352d7cd0174e1e66d26cBrian Paul            span->arrayMask = origArrayMask;
10697956292a765910077f50352d7cd0174e1e66d26cBrian Paul            return;
10707956292a765910077f50352d7cd0174e1e66d26cBrian Paul         }
10712a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      }
107210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul   }
107310f30eb43835c57c00783390a02d72daf4f78e26Brian Paul
1074b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul#if FEATURE_ARB_occlusion_query
107523ffc3a85d6172f8a98d17d7f23610bab808d84eBrian Paul   if (ctx->Query.CurrentOcclusionObject) {
1076939dd17653245621bf7488803f09418244b7b0b7Brian Paul      /* update count of 'passed' fragments */
107723ffc3a85d6172f8a98d17d7f23610bab808d84eBrian Paul      struct gl_query_object *q = ctx->Query.CurrentOcclusionObject;
1078b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul      GLuint i;
1079b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul      for (i = 0; i < span->end; i++)
108023ffc3a85d6172f8a98d17d7f23610bab808d84eBrian Paul         q->Result += span->array->mask[i];
1081b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul   }
1082b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul#endif
1083b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul
10847956292a765910077f50352d7cd0174e1e66d26cBrian Paul   /* we have to wait until after occlusion to do this test */
10857956292a765910077f50352d7cd0174e1e66d26cBrian Paul   if (ctx->Color.DrawBuffer == GL_NONE || ctx->Color.IndexMask == 0) {
108610f30eb43835c57c00783390a02d72daf4f78e26Brian Paul      /* write no pixels */
10872a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul      span->arrayMask = origArrayMask;
108810f30eb43835c57c00783390a02d72daf4f78e26Brian Paul      return;
108910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul   }
109010f30eb43835c57c00783390a02d72daf4f78e26Brian Paul
10917956292a765910077f50352d7cd0174e1e66d26cBrian Paul   /* Interpolate the color indexes if needed */
1092dcf4c17fb1624af47181c63af4c3ad29f919c17aBrian Paul   if (swrast->_FogEnabled ||
1093e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul       ctx->Color.IndexLogicOpEnabled ||
1094e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul       ctx->Color.IndexMask != 0xffffffff ||
1095e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul       (span->arrayMask & SPAN_COVERAGE)) {
1096e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul      if (span->interpMask & SPAN_INDEX) {
1097e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul         interpolate_indexes(ctx, span);
1098e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul      }
10997956292a765910077f50352d7cd0174e1e66d26cBrian Paul   }
110010f30eb43835c57c00783390a02d72daf4f78e26Brian Paul
11017956292a765910077f50352d7cd0174e1e66d26cBrian Paul   /* Fog */
1102dcf4c17fb1624af47181c63af4c3ad29f919c17aBrian Paul   if (swrast->_FogEnabled) {
110345bc887da226403f2c41077e40ca38b6f60f1359Brian Paul      _swrast_fog_ci_span(ctx, span);
1104e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
1105e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
11062a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   /* Antialias coverage application */
11072a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   if (span->arrayMask & SPAN_COVERAGE) {
1108e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul      const GLfloat *coverage = span->array->coverage;
110977df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul      GLuint *index = span->array->index;
1110e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul      GLuint i;
111110f30eb43835c57c00783390a02d72daf4f78e26Brian Paul      for (i = 0; i < span->end; i++) {
111277df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul         ASSERT(coverage[i] < 16);
111377df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul         index[i] = (index[i] & ~0xf) | ((GLuint) coverage[i]);
11145071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paul      }
11152a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   }
11165071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paul
1117ba001224a18fa12792696ef393e708e90092127eBrian Paul   /*
1118ba001224a18fa12792696ef393e708e90092127eBrian Paul    * Write to renderbuffers
1119ba001224a18fa12792696ef393e708e90092127eBrian Paul    */
1120ba001224a18fa12792696ef393e708e90092127eBrian Paul   {
1121ba001224a18fa12792696ef393e708e90092127eBrian Paul      struct gl_framebuffer *fb = ctx->DrawBuffer;
1122a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul      const GLuint output = 0; /* only frag progs can write to other outputs */
1123ba001224a18fa12792696ef393e708e90092127eBrian Paul      const GLuint numDrawBuffers = fb->_NumColorDrawBuffers[output];
1124ba001224a18fa12792696ef393e708e90092127eBrian Paul      GLuint indexSave[MAX_WIDTH];
1125ba001224a18fa12792696ef393e708e90092127eBrian Paul      GLuint buf;
1126e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul
1127ba001224a18fa12792696ef393e708e90092127eBrian Paul      if (numDrawBuffers > 1) {
1128ba001224a18fa12792696ef393e708e90092127eBrian Paul         /* save indexes for second, third renderbuffer writes */
1129ba001224a18fa12792696ef393e708e90092127eBrian Paul         _mesa_memcpy(indexSave, span->array->index,
1130ba001224a18fa12792696ef393e708e90092127eBrian Paul                      span->end * sizeof(indexSave[0]));
1131ba001224a18fa12792696ef393e708e90092127eBrian Paul      }
1132e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul
1133ba001224a18fa12792696ef393e708e90092127eBrian Paul      for (buf = 0; buf < fb->_NumColorDrawBuffers[output]; buf++) {
1134ba001224a18fa12792696ef393e708e90092127eBrian Paul         struct gl_renderbuffer *rb = fb->_ColorDrawBuffers[output][buf];
1135ba001224a18fa12792696ef393e708e90092127eBrian Paul         ASSERT(rb->_BaseFormat == GL_COLOR_INDEX);
11362a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul
1137e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul         if (ctx->Color.IndexLogicOpEnabled) {
1138f515c78a2320369ead087c4e0efd583f17b4b78bBrian Paul            _swrast_logicop_ci_span(ctx, rb, span);
1139e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul         }
1140e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul
1141e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul         if (ctx->Color.IndexMask != 0xffffffff) {
1142f515c78a2320369ead087c4e0efd583f17b4b78bBrian Paul            _swrast_mask_ci_span(ctx, rb, span);
1143e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul         }
11442a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul
1145ba001224a18fa12792696ef393e708e90092127eBrian Paul         if ((span->interpMask & SPAN_INDEX) && span->indexStep == 0) {
1146ba001224a18fa12792696ef393e708e90092127eBrian Paul            /* all fragments have same color index */
1147ba001224a18fa12792696ef393e708e90092127eBrian Paul            GLubyte index8;
1148ba001224a18fa12792696ef393e708e90092127eBrian Paul            GLushort index16;
1149ba001224a18fa12792696ef393e708e90092127eBrian Paul            GLuint index32;
1150ba001224a18fa12792696ef393e708e90092127eBrian Paul            void *value;
1151e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul
1152ba001224a18fa12792696ef393e708e90092127eBrian Paul            if (rb->DataType == GL_UNSIGNED_BYTE) {
1153ba001224a18fa12792696ef393e708e90092127eBrian Paul               index8 = FixedToInt(span->index);
1154ba001224a18fa12792696ef393e708e90092127eBrian Paul               value = &index8;
1155ba001224a18fa12792696ef393e708e90092127eBrian Paul            }
1156ba001224a18fa12792696ef393e708e90092127eBrian Paul            else if (rb->DataType == GL_UNSIGNED_SHORT) {
1157ba001224a18fa12792696ef393e708e90092127eBrian Paul               index16 = FixedToInt(span->index);
1158ba001224a18fa12792696ef393e708e90092127eBrian Paul               value = &index16;
1159ba001224a18fa12792696ef393e708e90092127eBrian Paul            }
1160ba001224a18fa12792696ef393e708e90092127eBrian Paul            else {
1161ba001224a18fa12792696ef393e708e90092127eBrian Paul               ASSERT(rb->DataType == GL_UNSIGNED_INT);
1162ba001224a18fa12792696ef393e708e90092127eBrian Paul               index32 = FixedToInt(span->index);
1163ba001224a18fa12792696ef393e708e90092127eBrian Paul               value = &index32;
1164ba001224a18fa12792696ef393e708e90092127eBrian Paul            }
1165e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul
1166ba001224a18fa12792696ef393e708e90092127eBrian Paul            if (span->arrayMask & SPAN_XY) {
1167ba001224a18fa12792696ef393e708e90092127eBrian Paul               rb->PutMonoValues(ctx, rb, span->end, span->array->x,
1168ba001224a18fa12792696ef393e708e90092127eBrian Paul                                 span->array->y, value, span->array->mask);
1169e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul            }
1170ba001224a18fa12792696ef393e708e90092127eBrian Paul            else {
1171ba001224a18fa12792696ef393e708e90092127eBrian Paul               rb->PutMonoRow(ctx, rb, span->end, span->x, span->y,
1172ba001224a18fa12792696ef393e708e90092127eBrian Paul                              value, span->array->mask);
1173e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul            }
1174733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul         }
1175733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul         else {
1176ba001224a18fa12792696ef393e708e90092127eBrian Paul            /* each fragment is a different color */
1177ba001224a18fa12792696ef393e708e90092127eBrian Paul            GLubyte index8[MAX_WIDTH];
1178ba001224a18fa12792696ef393e708e90092127eBrian Paul            GLushort index16[MAX_WIDTH];
1179ba001224a18fa12792696ef393e708e90092127eBrian Paul            void *values;
1180ba001224a18fa12792696ef393e708e90092127eBrian Paul
1181ba001224a18fa12792696ef393e708e90092127eBrian Paul            if (rb->DataType == GL_UNSIGNED_BYTE) {
1182ba001224a18fa12792696ef393e708e90092127eBrian Paul               GLuint k;
1183ba001224a18fa12792696ef393e708e90092127eBrian Paul               for (k = 0; k < span->end; k++) {
1184ba001224a18fa12792696ef393e708e90092127eBrian Paul                  index8[k] = (GLubyte) span->array->index[k];
1185ba001224a18fa12792696ef393e708e90092127eBrian Paul               }
1186ba001224a18fa12792696ef393e708e90092127eBrian Paul               values = index8;
1187ba001224a18fa12792696ef393e708e90092127eBrian Paul            }
1188ba001224a18fa12792696ef393e708e90092127eBrian Paul            else if (rb->DataType == GL_UNSIGNED_SHORT) {
1189ba001224a18fa12792696ef393e708e90092127eBrian Paul               GLuint k;
1190ba001224a18fa12792696ef393e708e90092127eBrian Paul               for (k = 0; k < span->end; k++) {
1191ba001224a18fa12792696ef393e708e90092127eBrian Paul                  index16[k] = (GLushort) span->array->index[k];
1192ba001224a18fa12792696ef393e708e90092127eBrian Paul               }
1193ba001224a18fa12792696ef393e708e90092127eBrian Paul               values = index16;
1194ba001224a18fa12792696ef393e708e90092127eBrian Paul            }
1195ba001224a18fa12792696ef393e708e90092127eBrian Paul            else {
1196ba001224a18fa12792696ef393e708e90092127eBrian Paul               ASSERT(rb->DataType == GL_UNSIGNED_INT);
1197ba001224a18fa12792696ef393e708e90092127eBrian Paul               values = span->array->index;
1198ba001224a18fa12792696ef393e708e90092127eBrian Paul            }
1199e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul
1200ba001224a18fa12792696ef393e708e90092127eBrian Paul            if (span->arrayMask & SPAN_XY) {
1201ba001224a18fa12792696ef393e708e90092127eBrian Paul               rb->PutValues(ctx, rb, span->end,
1202ba001224a18fa12792696ef393e708e90092127eBrian Paul                             span->array->x, span->array->y,
1203ba001224a18fa12792696ef393e708e90092127eBrian Paul                             values, span->array->mask);
1204ba001224a18fa12792696ef393e708e90092127eBrian Paul            }
1205ba001224a18fa12792696ef393e708e90092127eBrian Paul            else {
1206ba001224a18fa12792696ef393e708e90092127eBrian Paul               rb->PutRow(ctx, rb, span->end, span->x, span->y,
1207e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul                          values, span->array->mask);
1208ba001224a18fa12792696ef393e708e90092127eBrian Paul            }
1209e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul         }
1210ba001224a18fa12792696ef393e708e90092127eBrian Paul
1211ba001224a18fa12792696ef393e708e90092127eBrian Paul         if (buf + 1 < numDrawBuffers) {
1212ba001224a18fa12792696ef393e708e90092127eBrian Paul            /* restore original span values */
1213ba001224a18fa12792696ef393e708e90092127eBrian Paul            _mesa_memcpy(span->array->index, indexSave,
1214ba001224a18fa12792696ef393e708e90092127eBrian Paul                         span->end * sizeof(indexSave[0]));
1215733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul         }
1216ba001224a18fa12792696ef393e708e90092127eBrian Paul      } /* for buf */
1217e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
12182a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul
12197956292a765910077f50352d7cd0174e1e66d26cBrian Paul   span->interpMask = origInterpMask;
12202a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   span->arrayMask = origArrayMask;
1221e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell}
1222e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
1223e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
122479c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/**
1225e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Add specular color to base color.  This is used only when
1226f1e236987829393c81dc86ea19cb49eefe190317Brian Paul * GL_LIGHT_MODEL_COLOR_CONTROL = GL_SEPARATE_SPECULAR_COLOR.
1227e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */
1228f614a6190562e550257afca0d04e3846648942e8Brian Paulstatic INLINE void
1229cdb27e8242215271364602995d85607cfc06d441Brian Pauladd_specular(GLcontext *ctx, SWspan *span)
1230e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell{
1231d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul   switch (span->array->ChanType) {
1232d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul   case GL_UNSIGNED_BYTE:
1233d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      {
1234d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul         GLubyte (*rgba)[4] = span->array->color.sz1.rgba;
1235d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul         GLubyte (*spec)[4] = span->array->color.sz1.spec;
1236d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul         GLuint i;
1237d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul         for (i = 0; i < span->end; i++) {
1238d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            GLint r = rgba[i][RCOMP] + spec[i][RCOMP];
1239d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            GLint g = rgba[i][GCOMP] + spec[i][GCOMP];
1240d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            GLint b = rgba[i][BCOMP] + spec[i][BCOMP];
1241d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            GLint a = rgba[i][ACOMP] + spec[i][ACOMP];
1242d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            rgba[i][RCOMP] = MIN2(r, 255);
1243d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            rgba[i][GCOMP] = MIN2(g, 255);
1244d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            rgba[i][BCOMP] = MIN2(b, 255);
1245d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            rgba[i][ACOMP] = MIN2(a, 255);
1246d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul         }
1247d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      }
1248d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      break;
1249d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul   case GL_UNSIGNED_SHORT:
1250d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      {
1251d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul         GLushort (*rgba)[4] = span->array->color.sz2.rgba;
1252d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul         GLushort (*spec)[4] = span->array->color.sz2.spec;
1253d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul         GLuint i;
1254d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul         for (i = 0; i < span->end; i++) {
1255d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            GLint r = rgba[i][RCOMP] + spec[i][RCOMP];
1256d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            GLint g = rgba[i][GCOMP] + spec[i][GCOMP];
1257d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            GLint b = rgba[i][BCOMP] + spec[i][BCOMP];
1258d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            GLint a = rgba[i][ACOMP] + spec[i][ACOMP];
1259d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            rgba[i][RCOMP] = MIN2(r, 65535);
1260d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            rgba[i][GCOMP] = MIN2(g, 65535);
1261d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            rgba[i][BCOMP] = MIN2(b, 65535);
1262d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            rgba[i][ACOMP] = MIN2(a, 65535);
1263d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul         }
1264d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      }
1265d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      break;
1266d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul   case GL_FLOAT:
1267d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      {
1268f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian         GLfloat (*rgba)[4] = span->array->attribs[FRAG_ATTRIB_COL0];
1269f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian         GLfloat (*spec)[4] = span->array->attribs[FRAG_ATTRIB_COL1];
1270d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul         GLuint i;
1271d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul         for (i = 0; i < span->end; i++) {
1272d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            rgba[i][RCOMP] += spec[i][RCOMP];
1273d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            rgba[i][GCOMP] += spec[i][GCOMP];
1274d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            rgba[i][BCOMP] += spec[i][BCOMP];
1275d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            rgba[i][ACOMP] += spec[i][ACOMP];
1276d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul         }
1277d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      }
1278d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      break;
1279d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul   default:
1280d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      _mesa_problem(ctx, "Invalid datatype in add_specular");
1281e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
1282e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell}
1283e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
1284e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
128579c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/**
1286b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul * Apply antialiasing coverage value to alpha values.
1287b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul */
1288f614a6190562e550257afca0d04e3846648942e8Brian Paulstatic INLINE void
1289b88af5b4681d2085cd784b930dc259b66a55347eBrian Paulapply_aa_coverage(SWspan *span)
1290b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul{
1291b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul   const GLfloat *coverage = span->array->coverage;
1292b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul   GLuint i;
1293b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul   if (span->array->ChanType == GL_UNSIGNED_BYTE) {
1294b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul      GLubyte (*rgba)[4] = span->array->color.sz1.rgba;
1295b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul      for (i = 0; i < span->end; i++) {
1296e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul         const GLfloat a = rgba[i][ACOMP] * coverage[i];
1297e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul         rgba[i][ACOMP] = (GLubyte) CLAMP(a, 0.0, 255.0);
1298b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul         ASSERT(coverage[i] >= 0.0);
1299b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul         ASSERT(coverage[i] <= 1.0);
1300b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul      }
1301b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul   }
1302b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul   else if (span->array->ChanType == GL_UNSIGNED_SHORT) {
1303b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul      GLushort (*rgba)[4] = span->array->color.sz2.rgba;
1304b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul      for (i = 0; i < span->end; i++) {
1305e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul         const GLfloat a = rgba[i][ACOMP] * coverage[i];
1306e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul         rgba[i][ACOMP] = (GLushort) CLAMP(a, 0.0, 65535.0);
1307b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul      }
1308b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul   }
1309b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul   else {
1310f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian      GLfloat (*rgba)[4] = span->array->attribs[FRAG_ATTRIB_COL0];
1311b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul      for (i = 0; i < span->end; i++) {
1312b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul         rgba[i][ACOMP] = rgba[i][ACOMP] * coverage[i];
1313b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul      }
1314b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul   }
1315b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul}
1316b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul
1317b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul
1318b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul/**
131931293910b4e982f2ef54d79aff78f2f854121da1Brian Paul * Clamp span's float colors to [0,1]
132031293910b4e982f2ef54d79aff78f2f854121da1Brian Paul */
1321f614a6190562e550257afca0d04e3846648942e8Brian Paulstatic INLINE void
132231293910b4e982f2ef54d79aff78f2f854121da1Brian Paulclamp_colors(SWspan *span)
132331293910b4e982f2ef54d79aff78f2f854121da1Brian Paul{
1324f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian   GLfloat (*rgba)[4] = span->array->attribs[FRAG_ATTRIB_COL0];
132531293910b4e982f2ef54d79aff78f2f854121da1Brian Paul   GLuint i;
132631293910b4e982f2ef54d79aff78f2f854121da1Brian Paul   ASSERT(span->array->ChanType == GL_FLOAT);
132731293910b4e982f2ef54d79aff78f2f854121da1Brian Paul   for (i = 0; i < span->end; i++) {
132831293910b4e982f2ef54d79aff78f2f854121da1Brian Paul      rgba[i][RCOMP] = CLAMP(rgba[i][RCOMP], 0.0F, 1.0F);
132931293910b4e982f2ef54d79aff78f2f854121da1Brian Paul      rgba[i][GCOMP] = CLAMP(rgba[i][GCOMP], 0.0F, 1.0F);
133031293910b4e982f2ef54d79aff78f2f854121da1Brian Paul      rgba[i][BCOMP] = CLAMP(rgba[i][BCOMP], 0.0F, 1.0F);
133131293910b4e982f2ef54d79aff78f2f854121da1Brian Paul      rgba[i][ACOMP] = CLAMP(rgba[i][ACOMP], 0.0F, 1.0F);
133231293910b4e982f2ef54d79aff78f2f854121da1Brian Paul   }
133331293910b4e982f2ef54d79aff78f2f854121da1Brian Paul}
133431293910b4e982f2ef54d79aff78f2f854121da1Brian Paul
133531293910b4e982f2ef54d79aff78f2f854121da1Brian Paul
133631293910b4e982f2ef54d79aff78f2f854121da1Brian Paul/**
1337d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul * Convert the span's color arrays to the given type.
1338d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul */
1339f614a6190562e550257afca0d04e3846648942e8Brian Paulstatic INLINE void
1340ea8b68e0f7e7a4025ce662d36380157273ce10a3Brianconvert_color_type(SWspan *span, GLenum newType)
1341d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul{
1342f971e24cf0341dd2779196a0836327b74fc82336Brian Paul   GLvoid *src, *dst;
1343f971e24cf0341dd2779196a0836327b74fc82336Brian Paul   if (span->array->ChanType == GL_UNSIGNED_BYTE) {
1344f971e24cf0341dd2779196a0836327b74fc82336Brian Paul      src = span->array->color.sz1.rgba;
1345f971e24cf0341dd2779196a0836327b74fc82336Brian Paul   }
1346f971e24cf0341dd2779196a0836327b74fc82336Brian Paul   else if (span->array->ChanType == GL_UNSIGNED_BYTE) {
1347f971e24cf0341dd2779196a0836327b74fc82336Brian Paul      src = span->array->color.sz2.rgba;
1348f971e24cf0341dd2779196a0836327b74fc82336Brian Paul   }
1349f971e24cf0341dd2779196a0836327b74fc82336Brian Paul   else {
1350f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian      src = span->array->attribs[FRAG_ATTRIB_COL0];
1351f971e24cf0341dd2779196a0836327b74fc82336Brian Paul   }
1352f971e24cf0341dd2779196a0836327b74fc82336Brian Paul   if (newType == GL_UNSIGNED_BYTE) {
1353f971e24cf0341dd2779196a0836327b74fc82336Brian Paul      dst = span->array->color.sz1.rgba;
1354f971e24cf0341dd2779196a0836327b74fc82336Brian Paul   }
1355f971e24cf0341dd2779196a0836327b74fc82336Brian Paul   else if (newType == GL_UNSIGNED_BYTE) {
1356f971e24cf0341dd2779196a0836327b74fc82336Brian Paul      dst = span->array->color.sz2.rgba;
1357f971e24cf0341dd2779196a0836327b74fc82336Brian Paul   }
1358f971e24cf0341dd2779196a0836327b74fc82336Brian Paul   else {
1359f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian      dst = span->array->attribs[FRAG_ATTRIB_COL0];
1360f971e24cf0341dd2779196a0836327b74fc82336Brian Paul   }
1361d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul
1362f971e24cf0341dd2779196a0836327b74fc82336Brian Paul   _mesa_convert_colors(span->array->ChanType, src,
1363f971e24cf0341dd2779196a0836327b74fc82336Brian Paul                        newType, dst,
1364f971e24cf0341dd2779196a0836327b74fc82336Brian Paul                        span->end, span->array->mask);
1365d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul
1366d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul   span->array->ChanType = newType;
1367d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul}
1368d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul
1369d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul
1370d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul
1371d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul/**
137261c89be3135cedc795e48d36283769298e250837Brian Paul * Apply fragment shader, fragment program or normal texturing to span.
137361c89be3135cedc795e48d36283769298e250837Brian Paul */
1374f614a6190562e550257afca0d04e3846648942e8Brian Paulstatic INLINE void
137561c89be3135cedc795e48d36283769298e250837Brian Paulshade_texture_span(GLcontext *ctx, SWspan *span)
137661c89be3135cedc795e48d36283769298e250837Brian Paul{
137761c89be3135cedc795e48d36283769298e250837Brian Paul   /* Now we need the rgba array, fill it in if needed */
137861c89be3135cedc795e48d36283769298e250837Brian Paul   if (span->interpMask & SPAN_RGBA)
137961c89be3135cedc795e48d36283769298e250837Brian Paul      interpolate_colors(span);
138061c89be3135cedc795e48d36283769298e250837Brian Paul
1381f614a6190562e550257afca0d04e3846648942e8Brian Paul   if (ctx->Texture._EnabledCoordUnits && (span->interpMask & SPAN_TEXTURE))
1382f614a6190562e550257afca0d04e3846648942e8Brian Paul      interpolate_texcoords(ctx, span);
1383f614a6190562e550257afca0d04e3846648942e8Brian Paul
138412ef1fbefcee964b715783d3ade6b69b2c699ed8Brian   if (ctx->FragmentProgram._Current ||
138561c89be3135cedc795e48d36283769298e250837Brian Paul       ctx->ATIFragmentShader._Enabled) {
138661c89be3135cedc795e48d36283769298e250837Brian Paul
138761c89be3135cedc795e48d36283769298e250837Brian Paul      /* use float colors if running a fragment program or shader */
138861c89be3135cedc795e48d36283769298e250837Brian Paul      const GLenum oldType = span->array->ChanType;
138961c89be3135cedc795e48d36283769298e250837Brian Paul      const GLenum newType = GL_FLOAT;
139061c89be3135cedc795e48d36283769298e250837Brian Paul      if (oldType != newType) {
139161c89be3135cedc795e48d36283769298e250837Brian Paul         GLvoid *src = (oldType == GL_UNSIGNED_BYTE)
139261c89be3135cedc795e48d36283769298e250837Brian Paul            ? (GLvoid *) span->array->color.sz1.rgba
139361c89be3135cedc795e48d36283769298e250837Brian Paul            : (GLvoid *) span->array->color.sz2.rgba;
139461c89be3135cedc795e48d36283769298e250837Brian Paul         _mesa_convert_colors(oldType, src,
1395f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian                              newType, span->array->attribs[FRAG_ATTRIB_COL0],
139661c89be3135cedc795e48d36283769298e250837Brian Paul                              span->end, span->array->mask);
139761c89be3135cedc795e48d36283769298e250837Brian Paul         span->array->ChanType = newType;
139861c89be3135cedc795e48d36283769298e250837Brian Paul      }
139961c89be3135cedc795e48d36283769298e250837Brian Paul
140061c89be3135cedc795e48d36283769298e250837Brian Paul      /* fragment programs/shaders may need specular, fog and Z coords */
140161c89be3135cedc795e48d36283769298e250837Brian Paul      if (span->interpMask & SPAN_SPEC)
140261c89be3135cedc795e48d36283769298e250837Brian Paul         interpolate_specular(span);
140361c89be3135cedc795e48d36283769298e250837Brian Paul
140461c89be3135cedc795e48d36283769298e250837Brian Paul      if (span->interpMask & SPAN_FOG)
140561c89be3135cedc795e48d36283769298e250837Brian Paul         interpolate_fog(ctx, span);
140661c89be3135cedc795e48d36283769298e250837Brian Paul
140761c89be3135cedc795e48d36283769298e250837Brian Paul      if (span->interpMask & SPAN_Z)
140861c89be3135cedc795e48d36283769298e250837Brian Paul         _swrast_span_interpolate_z (ctx, span);
140961c89be3135cedc795e48d36283769298e250837Brian Paul
14100bf5dbe002a64e198f55724cc1542602c012490fBrian      if (ctx->Shader.CurrentProgram && span->interpMask & SPAN_VARYING)
1411828d15a6e0907fe4bb7c564d453a2b1a05f109bcBrian Paul         interpolate_varying(ctx, span);
141212ef1fbefcee964b715783d3ade6b69b2c699ed8Brian
1413f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian      if (ctx->FragmentProgram._Current &&
1414f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian          (ctx->FragmentProgram._Current->Base.InputsRead & FRAG_BIT_WPOS))
1415f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian         interpolate_wpos(ctx, span);
1416f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian
141712ef1fbefcee964b715783d3ade6b69b2c699ed8Brian      /* Run fragment program/shader now */
141812ef1fbefcee964b715783d3ade6b69b2c699ed8Brian      if (ctx->FragmentProgram._Current) {
141961c89be3135cedc795e48d36283769298e250837Brian Paul         _swrast_exec_fragment_program(ctx, span);
142061c89be3135cedc795e48d36283769298e250837Brian Paul      }
142161c89be3135cedc795e48d36283769298e250837Brian Paul      else {
142261c89be3135cedc795e48d36283769298e250837Brian Paul         ASSERT(ctx->ATIFragmentShader._Enabled);
142361c89be3135cedc795e48d36283769298e250837Brian Paul         _swrast_exec_fragment_shader(ctx, span);
142461c89be3135cedc795e48d36283769298e250837Brian Paul      }
142561c89be3135cedc795e48d36283769298e250837Brian Paul   }
142661c89be3135cedc795e48d36283769298e250837Brian Paul   else if (ctx->Texture._EnabledUnits && (span->arrayMask & SPAN_TEXTURE)) {
142761c89be3135cedc795e48d36283769298e250837Brian Paul      /* conventional texturing */
142861c89be3135cedc795e48d36283769298e250837Brian Paul      _swrast_texture_span(ctx, span);
142961c89be3135cedc795e48d36283769298e250837Brian Paul   }
143061c89be3135cedc795e48d36283769298e250837Brian Paul}
143161c89be3135cedc795e48d36283769298e250837Brian Paul
143261c89be3135cedc795e48d36283769298e250837Brian Paul
143361c89be3135cedc795e48d36283769298e250837Brian Paul
143461c89be3135cedc795e48d36283769298e250837Brian Paul/**
1435a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul * Apply all the per-fragment operations to a span.
1436a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul * This now includes texturing (_swrast_write_texture_span() is history).
1437f1e236987829393c81dc86ea19cb49eefe190317Brian Paul * This function may modify any of the array values in the span.
14387956292a765910077f50352d7cd0174e1e66d26cBrian Paul * span->interpMask and span->arrayMask may be changed but will be restored
14397956292a765910077f50352d7cd0174e1e66d26cBrian Paul * to their original values before returning.
144078940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul */
144178940758e90069ceaca2b6cddb6438488fbad5ccBrian Paulvoid
1442cdb27e8242215271364602995d85607cfc06d441Brian Paul_swrast_write_rgba_span( GLcontext *ctx, SWspan *span)
144378940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul{
144461c89be3135cedc795e48d36283769298e250837Brian Paul   const SWcontext *swrast = SWRAST_CONTEXT(ctx);
144578940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul   const GLuint colorMask = *((GLuint *) ctx->Color.ColorMask);
1446e00ac11d4dd05c56584622dc2707bbdcfe4b2707Brian Paul   const GLbitfield origInterpMask = span->interpMask;
1447e00ac11d4dd05c56584622dc2707bbdcfe4b2707Brian Paul   const GLbitfield origArrayMask = span->arrayMask;
1448c3caaa3dd45809e672177ab322445fe51d03af25Brian Paul   const GLenum chanType = span->array->ChanType;
144912ef1fbefcee964b715783d3ade6b69b2c699ed8Brian   const GLboolean shader = (ctx->FragmentProgram._Current
145012ef1fbefcee964b715783d3ade6b69b2c699ed8Brian                             || ctx->ATIFragmentShader._Enabled);
145161c89be3135cedc795e48d36283769298e250837Brian Paul   const GLboolean shaderOrTexture = shader || ctx->Texture._EnabledUnits;
1452bb19e64d12eaf27e2adc3faac7e09555bb66d724Brian Paul   GLboolean deferredTexture;
145361c89be3135cedc795e48d36283769298e250837Brian Paul
1454bb19e64d12eaf27e2adc3faac7e09555bb66d724Brian Paul   /*
1455bb19e64d12eaf27e2adc3faac7e09555bb66d724Brian Paul   printf("%s()  interp 0x%x  array 0x%x\n", __FUNCTION__,
1456bb19e64d12eaf27e2adc3faac7e09555bb66d724Brian Paul          span->interpMask, span->arrayMask);
1457bb19e64d12eaf27e2adc3faac7e09555bb66d724Brian Paul   */
1458f1e236987829393c81dc86ea19cb49eefe190317Brian Paul
145931293910b4e982f2ef54d79aff78f2f854121da1Brian Paul   ASSERT(span->primitive == GL_POINT ||
146031293910b4e982f2ef54d79aff78f2f854121da1Brian Paul          span->primitive == GL_LINE ||
146131293910b4e982f2ef54d79aff78f2f854121da1Brian Paul	  span->primitive == GL_POLYGON ||
146231293910b4e982f2ef54d79aff78f2f854121da1Brian Paul          span->primitive == GL_BITMAP);
1463733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul   ASSERT(span->end <= MAX_WIDTH);
14647956292a765910077f50352d7cd0174e1e66d26cBrian Paul   ASSERT((span->interpMask & span->arrayMask) == 0);
146531293910b4e982f2ef54d79aff78f2f854121da1Brian Paul   ASSERT((span->interpMask & SPAN_RGBA) ^ (span->arrayMask & SPAN_RGBA));
146678940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul
1467bb19e64d12eaf27e2adc3faac7e09555bb66d724Brian Paul   /* check for conditions that prevent deferred shading */
1468bb19e64d12eaf27e2adc3faac7e09555bb66d724Brian Paul   if (ctx->Color.AlphaEnabled) {
1469bb19e64d12eaf27e2adc3faac7e09555bb66d724Brian Paul      /* alpha test depends on post-texture/shader colors */
1470bb19e64d12eaf27e2adc3faac7e09555bb66d724Brian Paul      deferredTexture = GL_FALSE;
1471bb19e64d12eaf27e2adc3faac7e09555bb66d724Brian Paul   }
1472bb19e64d12eaf27e2adc3faac7e09555bb66d724Brian Paul   else if (shaderOrTexture) {
147312ef1fbefcee964b715783d3ade6b69b2c699ed8Brian      if (ctx->FragmentProgram._Current) {
1474ed324db249d068f14646eced55d106b5fe6b889cBrian Paul         if (ctx->FragmentProgram.Current->Base.OutputsWritten
1475ed324db249d068f14646eced55d106b5fe6b889cBrian Paul             & (1 << FRAG_RESULT_DEPR)) {
147612ef1fbefcee964b715783d3ade6b69b2c699ed8Brian            /* Z comes from fragment program/shader */
1477ed324db249d068f14646eced55d106b5fe6b889cBrian Paul            deferredTexture = GL_FALSE;
1478ed324db249d068f14646eced55d106b5fe6b889cBrian Paul         }
1479ed324db249d068f14646eced55d106b5fe6b889cBrian Paul         else {
1480ed324db249d068f14646eced55d106b5fe6b889cBrian Paul            deferredTexture = GL_TRUE;
1481ed324db249d068f14646eced55d106b5fe6b889cBrian Paul         }
1482bb19e64d12eaf27e2adc3faac7e09555bb66d724Brian Paul      }
1483bb19e64d12eaf27e2adc3faac7e09555bb66d724Brian Paul      else {
1484bb19e64d12eaf27e2adc3faac7e09555bb66d724Brian Paul         /* ATI frag shader or conventional texturing */
1485bb19e64d12eaf27e2adc3faac7e09555bb66d724Brian Paul         deferredTexture = GL_TRUE;
1486bb19e64d12eaf27e2adc3faac7e09555bb66d724Brian Paul      }
1487bb19e64d12eaf27e2adc3faac7e09555bb66d724Brian Paul   }
1488bb19e64d12eaf27e2adc3faac7e09555bb66d724Brian Paul   else {
1489bb19e64d12eaf27e2adc3faac7e09555bb66d724Brian Paul      /* no texturing or shadering */
1490bb19e64d12eaf27e2adc3faac7e09555bb66d724Brian Paul      deferredTexture = GL_FALSE;
1491bb19e64d12eaf27e2adc3faac7e09555bb66d724Brian Paul   }
1492ceb39f4f8dc4863fde17d668c752533a2184476eBrian Paul
1493bb19e64d12eaf27e2adc3faac7e09555bb66d724Brian Paul   /* Fragment write masks */
1494733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul   if (span->arrayMask & SPAN_MASK) {
1495733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      /* mask was initialized by caller, probably glBitmap */
1496733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      span->writeAll = GL_FALSE;
1497733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul   }
1498733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul   else {
1499a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul      _mesa_memset(span->array->mask, 1, span->end);
1500733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      span->writeAll = GL_TRUE;
150178940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul   }
150278940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul
1503a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul   /* Clip to window/scissor box */
1504b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul   if ((swrast->_RasterMask & CLIP_BIT) || (span->primitive != GL_POLYGON)) {
1505733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      if (!clip_span(ctx, span)) {
1506733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul	 return;
150778940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul      }
150878940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul   }
150978940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul
1510b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul#ifdef DEBUG
1511a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul   /* Make sure all fragments are within window bounds */
1512b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul   if (span->arrayMask & SPAN_XY) {
1513a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul      GLuint i;
1514b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul      for (i = 0; i < span->end; i++) {
151577df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul         if (span->array->mask[i]) {
151677df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul            assert(span->array->x[i] >= ctx->DrawBuffer->_Xmin);
151777df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul            assert(span->array->x[i] < ctx->DrawBuffer->_Xmax);
151877df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul            assert(span->array->y[i] >= ctx->DrawBuffer->_Ymin);
151977df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul            assert(span->array->y[i] < ctx->DrawBuffer->_Ymax);
1520b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul         }
1521b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul      }
1522b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul   }
1523b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul#endif
1524b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul
152578940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul   /* Polygon Stippling */
1526b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul   if (ctx->Polygon.StippleFlag && span->primitive == GL_POLYGON) {
1527733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      stipple_polygon_span(ctx, span);
152878940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul   }
152978940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul
153032340aea1308153dad5c105fc0748aea1e4c37eeBrian Paul   /* This is the normal place to compute the resulting fragment color/Z.
153132340aea1308153dad5c105fc0748aea1e4c37eeBrian Paul    * As an optimization, we try to defer this until after Z/stencil
153232340aea1308153dad5c105fc0748aea1e4c37eeBrian Paul    * testing in order to try to avoid computing colors that we won't
153332340aea1308153dad5c105fc0748aea1e4c37eeBrian Paul    * actually need.
1534a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul    */
153561c89be3135cedc795e48d36283769298e250837Brian Paul   if (shaderOrTexture && !deferredTexture) {
153661c89be3135cedc795e48d36283769298e250837Brian Paul      shade_texture_span(ctx, span);
153761c89be3135cedc795e48d36283769298e250837Brian Paul   }
1538c3caaa3dd45809e672177ab322445fe51d03af25Brian Paul
153961c89be3135cedc795e48d36283769298e250837Brian Paul   /* Do the alpha test */
154061c89be3135cedc795e48d36283769298e250837Brian Paul   if (ctx->Color.AlphaEnabled) {
154161c89be3135cedc795e48d36283769298e250837Brian Paul      if (!_swrast_alpha_test(ctx, span)) {
154261c89be3135cedc795e48d36283769298e250837Brian Paul         goto end;
154378940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul      }
154478940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul   }
154578940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul
1546f1e236987829393c81dc86ea19cb49eefe190317Brian Paul   /* Stencil and Z testing */
1547f1e236987829393c81dc86ea19cb49eefe190317Brian Paul   if (ctx->Stencil.Enabled || ctx->Depth.Test) {
1548f1e236987829393c81dc86ea19cb49eefe190317Brian Paul      if (span->interpMask & SPAN_Z)
154945bc887da226403f2c41077e40ca38b6f60f1359Brian Paul         _swrast_span_interpolate_z(ctx, span);
155078940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul
1551e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul      if (ctx->Stencil.Enabled && ctx->DrawBuffer->Visual.stencilBits > 0) {
1552a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul         /* Combined Z/stencil tests */
155345bc887da226403f2c41077e40ca38b6f60f1359Brian Paul         if (!_swrast_stencil_and_ztest_span(ctx, span)) {
1554c3caaa3dd45809e672177ab322445fe51d03af25Brian Paul            goto end;
1555f1e236987829393c81dc86ea19cb49eefe190317Brian Paul         }
155671340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul      }
1557e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul      else if (ctx->DrawBuffer->Visual.depthBits > 0) {
1558a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul         /* Just regular depth testing */
1559f1e236987829393c81dc86ea19cb49eefe190317Brian Paul         ASSERT(ctx->Depth.Test);
1560f1e236987829393c81dc86ea19cb49eefe190317Brian Paul         ASSERT(span->arrayMask & SPAN_Z);
156145bc887da226403f2c41077e40ca38b6f60f1359Brian Paul         if (!_swrast_depth_test_span(ctx, span)) {
1562c3caaa3dd45809e672177ab322445fe51d03af25Brian Paul            goto end;
1563f1e236987829393c81dc86ea19cb49eefe190317Brian Paul         }
156471340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul      }
156571340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul   }
156671340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul
1567b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul#if FEATURE_ARB_occlusion_query
156823ffc3a85d6172f8a98d17d7f23610bab808d84eBrian Paul   if (ctx->Query.CurrentOcclusionObject) {
1569939dd17653245621bf7488803f09418244b7b0b7Brian Paul      /* update count of 'passed' fragments */
157023ffc3a85d6172f8a98d17d7f23610bab808d84eBrian Paul      struct gl_query_object *q = ctx->Query.CurrentOcclusionObject;
1571b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul      GLuint i;
1572b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul      for (i = 0; i < span->end; i++)
157323ffc3a85d6172f8a98d17d7f23610bab808d84eBrian Paul         q->Result += span->array->mask[i];
1574b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul   }
1575b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul#endif
1576b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul
1577a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul   /* We had to wait until now to check for glColorMask(0,0,0,0) because of
1578f1e236987829393c81dc86ea19cb49eefe190317Brian Paul    * the occlusion test.
1579f1e236987829393c81dc86ea19cb49eefe190317Brian Paul    */
1580f1e236987829393c81dc86ea19cb49eefe190317Brian Paul   if (colorMask == 0x0) {
1581c3caaa3dd45809e672177ab322445fe51d03af25Brian Paul      goto end;
158271340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul   }
158371340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul
158432340aea1308153dad5c105fc0748aea1e4c37eeBrian Paul   /* If we were able to defer fragment color computation to now, there's
158532340aea1308153dad5c105fc0748aea1e4c37eeBrian Paul    * a good chance that many fragments will have already been killed by
158632340aea1308153dad5c105fc0748aea1e4c37eeBrian Paul    * Z/stencil testing.
1587a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul    */
158832340aea1308153dad5c105fc0748aea1e4c37eeBrian Paul   if (deferredTexture) {
158961c89be3135cedc795e48d36283769298e250837Brian Paul      ASSERT(shaderOrTexture);
159061c89be3135cedc795e48d36283769298e250837Brian Paul      shade_texture_span(ctx, span);
159161c89be3135cedc795e48d36283769298e250837Brian Paul   }
1592d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul
159361c89be3135cedc795e48d36283769298e250837Brian Paul   if ((span->arrayMask & SPAN_RGBA) == 0) {
159461c89be3135cedc795e48d36283769298e250837Brian Paul      interpolate_colors(span);
159571340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul   }
159671340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul
1597f1e236987829393c81dc86ea19cb49eefe190317Brian Paul   ASSERT(span->arrayMask & SPAN_RGBA);
15982ef866d1fc0a5cc5ef8543d65744dfd4da4dbbafBrian Paul
159961c89be3135cedc795e48d36283769298e250837Brian Paul   if (!shader) {
1600dfe508ca7af1a6d1099cd65e257512ed1e17d893Brian Paul      /* Add base and specular colors */
1601dfe508ca7af1a6d1099cd65e257512ed1e17d893Brian Paul      if (ctx->Fog.ColorSumEnabled ||
1602dfe508ca7af1a6d1099cd65e257512ed1e17d893Brian Paul          (ctx->Light.Enabled &&
1603dfe508ca7af1a6d1099cd65e257512ed1e17d893Brian Paul           ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR)) {
1604dfe508ca7af1a6d1099cd65e257512ed1e17d893Brian Paul         if (span->interpMask & SPAN_SPEC) {
1605e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul            interpolate_specular(span);
1606dfe508ca7af1a6d1099cd65e257512ed1e17d893Brian Paul         }
1607a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul         if (span->arrayMask & SPAN_SPEC) {
1608d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul            add_specular(ctx, span);
1609a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul         }
1610a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul         else {
1611a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul            /* We probably added the base/specular colors during the
1612a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul             * vertex stage!
1613a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul             */
1614a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul         }
161571340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul      }
161671340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul   }
161771340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul
16186e1666437ea091ecc50ab2b56d87129318f641d2Brian Paul   /* Fog */
161909da0b8e6621a831e3eeb9381430f2bed18a22adBrian Paul   if (swrast->_FogEnabled) {
162045bc887da226403f2c41077e40ca38b6f60f1359Brian Paul      _swrast_fog_rgba_span(ctx, span);
162171340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul   }
1622f1e236987829393c81dc86ea19cb49eefe190317Brian Paul
162371340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul   /* Antialias coverage application */
16242a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   if (span->arrayMask & SPAN_COVERAGE) {
1625b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul      apply_aa_coverage(span);
162671340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul   }
162771340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul
1628ba3da6154c324cc916845bc5de3de077d0b59ffcBrian Paul   /* Clamp color/alpha values over the range [0.0, 1.0] before storage */
16290b26e826bda0da7aeec9a79ee07fe21d54bb1263Brian Paul   if (ctx->Color.ClampFragmentColor == GL_TRUE &&
163031293910b4e982f2ef54d79aff78f2f854121da1Brian Paul       span->array->ChanType == GL_FLOAT) {
163131293910b4e982f2ef54d79aff78f2f854121da1Brian Paul      clamp_colors(span);
1632ba3da6154c324cc916845bc5de3de077d0b59ffcBrian Paul   }
1633ba3da6154c324cc916845bc5de3de077d0b59ffcBrian Paul
1634ba001224a18fa12792696ef393e708e90092127eBrian Paul   /*
1635ba001224a18fa12792696ef393e708e90092127eBrian Paul    * Write to renderbuffers
1636ba001224a18fa12792696ef393e708e90092127eBrian Paul    */
1637ba001224a18fa12792696ef393e708e90092127eBrian Paul   {
1638ba001224a18fa12792696ef393e708e90092127eBrian Paul      struct gl_framebuffer *fb = ctx->DrawBuffer;
1639a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul      const GLuint output = 0; /* only frag progs can write to other outputs */
1640ba001224a18fa12792696ef393e708e90092127eBrian Paul      const GLuint numDrawBuffers = fb->_NumColorDrawBuffers[output];
1641ba001224a18fa12792696ef393e708e90092127eBrian Paul      GLchan rgbaSave[MAX_WIDTH][4];
1642ba001224a18fa12792696ef393e708e90092127eBrian Paul      GLuint buf;
1643e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul
1644d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      if (numDrawBuffers > 0) {
1645d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul         if (fb->_ColorDrawBuffers[output][0]->DataType
1646d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul             != span->array->ChanType) {
1647ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian            convert_color_type(span,
1648d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul                               fb->_ColorDrawBuffers[output][0]->DataType);
1649d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul         }
1650d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul      }
1651d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul
1652ba001224a18fa12792696ef393e708e90092127eBrian Paul      if (numDrawBuffers > 1) {
1653ba001224a18fa12792696ef393e708e90092127eBrian Paul         /* save colors for second, third renderbuffer writes */
1654ba001224a18fa12792696ef393e708e90092127eBrian Paul         _mesa_memcpy(rgbaSave, span->array->rgba,
1655ba001224a18fa12792696ef393e708e90092127eBrian Paul                      4 * span->end * sizeof(GLchan));
165671340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul      }
165771340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul
1658ba001224a18fa12792696ef393e708e90092127eBrian Paul      for (buf = 0; buf < numDrawBuffers; buf++) {
1659ba001224a18fa12792696ef393e708e90092127eBrian Paul         struct gl_renderbuffer *rb = fb->_ColorDrawBuffers[output][buf];
1660f971e24cf0341dd2779196a0836327b74fc82336Brian Paul         ASSERT(rb->_BaseFormat == GL_RGBA || rb->_BaseFormat == GL_RGB);
166171340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul
1662ba001224a18fa12792696ef393e708e90092127eBrian Paul         if (ctx->Color._LogicOpEnabled) {
1663f515c78a2320369ead087c4e0efd583f17b4b78bBrian Paul            _swrast_logicop_rgba_span(ctx, rb, span);
1664ba001224a18fa12792696ef393e708e90092127eBrian Paul         }
1665ba001224a18fa12792696ef393e708e90092127eBrian Paul         else if (ctx->Color.BlendEnabled) {
1666f515c78a2320369ead087c4e0efd583f17b4b78bBrian Paul            _swrast_blend_span(ctx, rb, span);
1667ba001224a18fa12792696ef393e708e90092127eBrian Paul         }
1668ba001224a18fa12792696ef393e708e90092127eBrian Paul
1669ba001224a18fa12792696ef393e708e90092127eBrian Paul         if (colorMask != 0xffffffff) {
1670f515c78a2320369ead087c4e0efd583f17b4b78bBrian Paul            _swrast_mask_rgba_span(ctx, rb, span);
1671ba001224a18fa12792696ef393e708e90092127eBrian Paul         }
1672ba001224a18fa12792696ef393e708e90092127eBrian Paul
1673ba001224a18fa12792696ef393e708e90092127eBrian Paul         if (span->arrayMask & SPAN_XY) {
1674ba001224a18fa12792696ef393e708e90092127eBrian Paul            /* array of pixel coords */
1675ba001224a18fa12792696ef393e708e90092127eBrian Paul            ASSERT(rb->PutValues);
1676ba001224a18fa12792696ef393e708e90092127eBrian Paul            rb->PutValues(ctx, rb, span->end,
1677ba001224a18fa12792696ef393e708e90092127eBrian Paul                          span->array->x, span->array->y,
1678ba001224a18fa12792696ef393e708e90092127eBrian Paul                          span->array->rgba, span->array->mask);
1679ba001224a18fa12792696ef393e708e90092127eBrian Paul         }
1680ba001224a18fa12792696ef393e708e90092127eBrian Paul         else {
1681ba001224a18fa12792696ef393e708e90092127eBrian Paul            /* horizontal run of pixels */
1682ba001224a18fa12792696ef393e708e90092127eBrian Paul            ASSERT(rb->PutRow);
1683ba001224a18fa12792696ef393e708e90092127eBrian Paul            rb->PutRow(ctx, rb, span->end, span->x, span->y, span->array->rgba,
1684ba001224a18fa12792696ef393e708e90092127eBrian Paul                       span->writeAll ? NULL: span->array->mask);
1685ba001224a18fa12792696ef393e708e90092127eBrian Paul         }
1686ba001224a18fa12792696ef393e708e90092127eBrian Paul
1687ba001224a18fa12792696ef393e708e90092127eBrian Paul         if (buf + 1 < numDrawBuffers) {
1688ba001224a18fa12792696ef393e708e90092127eBrian Paul            /* restore original span values */
1689ba001224a18fa12792696ef393e708e90092127eBrian Paul            _mesa_memcpy(span->array->rgba, rgbaSave,
1690ba001224a18fa12792696ef393e708e90092127eBrian Paul                         4 * span->end * sizeof(GLchan));
1691ba001224a18fa12792696ef393e708e90092127eBrian Paul         }
1692ba001224a18fa12792696ef393e708e90092127eBrian Paul      } /* for buf */
16931e3223c02a2f6155beb5784cadbea1f46703829aBrian Paul
169471340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul   }
169571340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul
1696c3caaa3dd45809e672177ab322445fe51d03af25Brian Paulend:
169761c89be3135cedc795e48d36283769298e250837Brian Paul   /* restore these values before returning */
1698e5b244ff7f984805c1bcc020342f1300f2639c71Brian Paul   span->interpMask = origInterpMask;
1699f1e236987829393c81dc86ea19cb49eefe190317Brian Paul   span->arrayMask = origArrayMask;
170061c89be3135cedc795e48d36283769298e250837Brian Paul   span->array->ChanType = chanType;
170110f30eb43835c57c00783390a02d72daf4f78e26Brian Paul}
170210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul
1703e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
170479c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/**
1705ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian * Read RGBA pixels from a renderbuffer.  Clipping will be done to prevent
1706e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * reading ouside the buffer's boundaries.
1707ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian * \param dstType  datatype for returned colors
170876e778dce59aa6f290db50242df945943fc47b05Brian Paul * \param rgba  the returned colors
1709e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */
17105071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paulvoid
1711e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul_swrast_read_rgba_span( GLcontext *ctx, struct gl_renderbuffer *rb,
171276e778dce59aa6f290db50242df945943fc47b05Brian Paul                        GLuint n, GLint x, GLint y, GLenum dstType,
171376e778dce59aa6f290db50242df945943fc47b05Brian Paul                        GLvoid *rgba)
1714e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell{
1715e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   const GLint bufWidth = (GLint) rb->Width;
1716e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   const GLint bufHeight = (GLint) rb->Height;
1717a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul
1718a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul   if (y < 0 || y >= bufHeight || x + (GLint) n < 0 || x >= bufWidth) {
1719e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      /* completely above, below, or right */
1720e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul      /* XXX maybe leave rgba values undefined? */
17216ec6b845fdf3c44436028ad6fff9471d18928719Brian Paul      _mesa_bzero(rgba, 4 * n * sizeof(GLchan));
1722e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
1723e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   else {
1724e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      GLint skip, length;
1725e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      if (x < 0) {
17267e152b83cbc3af028175a52450c60101cb16acf8Brian Paul         /* left edge clipping */
1727e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         skip = -x;
1728e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         length = (GLint) n - skip;
1729e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         if (length < 0) {
1730e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            /* completely left of window */
1731e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            return;
1732e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         }
1733a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul         if (length > bufWidth) {
1734a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul            length = bufWidth;
1735e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         }
1736e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
1737a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul      else if ((GLint) (x + n) > bufWidth) {
1738e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         /* right edge clipping */
1739e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         skip = 0;
1740a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul         length = bufWidth - x;
1741e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         if (length < 0) {
1742e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            /* completely to right of window */
1743e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            return;
1744e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         }
1745e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
1746e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      else {
1747e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         /* no clipping */
1748e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         skip = 0;
1749e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         length = (GLint) n;
1750e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
1751e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
1752bb8b302dbce4f830d060efecd8a9f75b10e25abbBrian Paul      ASSERT(rb);
1753bb8b302dbce4f830d060efecd8a9f75b10e25abbBrian Paul      ASSERT(rb->GetRow);
1754bb8b302dbce4f830d060efecd8a9f75b10e25abbBrian Paul      ASSERT(rb->_BaseFormat == GL_RGB || rb->_BaseFormat == GL_RGBA);
175576e778dce59aa6f290db50242df945943fc47b05Brian Paul
175676e778dce59aa6f290db50242df945943fc47b05Brian Paul      if (rb->DataType == dstType) {
175776e778dce59aa6f290db50242df945943fc47b05Brian Paul         rb->GetRow(ctx, rb, length, x + skip, y,
175876e778dce59aa6f290db50242df945943fc47b05Brian Paul                    (GLubyte *) rgba + skip * RGBA_PIXEL_SIZE(rb->DataType));
175976e778dce59aa6f290db50242df945943fc47b05Brian Paul      }
176076e778dce59aa6f290db50242df945943fc47b05Brian Paul      else {
176176e778dce59aa6f290db50242df945943fc47b05Brian Paul         GLuint temp[MAX_WIDTH * 4];
176276e778dce59aa6f290db50242df945943fc47b05Brian Paul         rb->GetRow(ctx, rb, length, x + skip, y, temp);
176376e778dce59aa6f290db50242df945943fc47b05Brian Paul         _mesa_convert_colors(rb->DataType, temp,
176476e778dce59aa6f290db50242df945943fc47b05Brian Paul                   dstType, (GLubyte *) rgba + skip * RGBA_PIXEL_SIZE(dstType),
176576e778dce59aa6f290db50242df945943fc47b05Brian Paul                   length, NULL);
176676e778dce59aa6f290db50242df945943fc47b05Brian Paul      }
1767e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
1768e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell}
1769e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
1770e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
177179c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/**
1772ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian * Read CI pixels from a renderbuffer.  Clipping will be done to prevent
1773e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * reading ouside the buffer's boundaries.
1774e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */
17755071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paulvoid
1776e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul_swrast_read_index_span( GLcontext *ctx, struct gl_renderbuffer *rb,
1777e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul                         GLuint n, GLint x, GLint y, GLuint index[] )
1778e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell{
1779e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   const GLint bufWidth = (GLint) rb->Width;
1780e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   const GLint bufHeight = (GLint) rb->Height;
1781a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul
1782a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul   if (y < 0 || y >= bufHeight || x + (GLint) n < 0 || x >= bufWidth) {
1783e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      /* completely above, below, or right */
1784e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul      _mesa_bzero(index, n * sizeof(GLuint));
1785e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
1786e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   else {
1787e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      GLint skip, length;
1788e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      if (x < 0) {
17897e152b83cbc3af028175a52450c60101cb16acf8Brian Paul         /* left edge clipping */
1790e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         skip = -x;
1791e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         length = (GLint) n - skip;
1792e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         if (length < 0) {
1793e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            /* completely left of window */
1794e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            return;
1795e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         }
1796a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul         if (length > bufWidth) {
1797a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul            length = bufWidth;
1798e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         }
1799e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
1800a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul      else if ((GLint) (x + n) > bufWidth) {
1801e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         /* right edge clipping */
1802e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         skip = 0;
1803a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul         length = bufWidth - x;
1804e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         if (length < 0) {
1805e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            /* completely to right of window */
1806e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            return;
1807e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         }
1808e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
1809e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      else {
1810e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         /* no clipping */
1811e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         skip = 0;
1812e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         length = (GLint) n;
1813e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
1814e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
1815e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul      ASSERT(rb->GetRow);
1816e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul      ASSERT(rb->_BaseFormat == GL_COLOR_INDEX);
1817e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul
1818e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul      if (rb->DataType == GL_UNSIGNED_BYTE) {
1819e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul         GLubyte index8[MAX_WIDTH];
1820e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul         GLint i;
1821e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul         rb->GetRow(ctx, rb, length, x + skip, y, index8);
1822e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul         for (i = 0; i < length; i++)
1823e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul            index[skip + i] = index8[i];
1824e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul      }
1825e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul      else if (rb->DataType == GL_UNSIGNED_SHORT) {
1826e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul         GLushort index16[MAX_WIDTH];
1827e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul         GLint i;
1828e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul         rb->GetRow(ctx, rb, length, x + skip, y, index16);
1829e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul         for (i = 0; i < length; i++)
1830e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul            index[skip + i] = index16[i];
1831e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul      }
1832e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul      else if (rb->DataType == GL_UNSIGNED_INT) {
1833e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul         rb->GetRow(ctx, rb, length, x + skip, y, index + skip);
1834e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul      }
1835e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
1836e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell}
183767074332728acba86da7630353673b458713bb8aBrian Paul
183867074332728acba86da7630353673b458713bb8aBrian Paul
183967074332728acba86da7630353673b458713bb8aBrian Paul/**
184067074332728acba86da7630353673b458713bb8aBrian Paul * Wrapper for gl_renderbuffer::GetValues() which does clipping to avoid
184167074332728acba86da7630353673b458713bb8aBrian Paul * reading values outside the buffer bounds.
184267074332728acba86da7630353673b458713bb8aBrian Paul * We can use this for reading any format/type of renderbuffer.
1843ba001224a18fa12792696ef393e708e90092127eBrian Paul * \param valueSize is the size in bytes of each value (pixel) put into the
184467074332728acba86da7630353673b458713bb8aBrian Paul *                  values array.
184567074332728acba86da7630353673b458713bb8aBrian Paul */
184667074332728acba86da7630353673b458713bb8aBrian Paulvoid
184767074332728acba86da7630353673b458713bb8aBrian Paul_swrast_get_values(GLcontext *ctx, struct gl_renderbuffer *rb,
184867074332728acba86da7630353673b458713bb8aBrian Paul                   GLuint count, const GLint x[], const GLint y[],
184967074332728acba86da7630353673b458713bb8aBrian Paul                   void *values, GLuint valueSize)
185067074332728acba86da7630353673b458713bb8aBrian Paul{
185167074332728acba86da7630353673b458713bb8aBrian Paul   GLuint i, inCount = 0, inStart = 0;
185267074332728acba86da7630353673b458713bb8aBrian Paul
185367074332728acba86da7630353673b458713bb8aBrian Paul   for (i = 0; i < count; i++) {
1854ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian      if (x[i] >= 0 && y[i] >= 0 &&
1855ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian	  x[i] < (GLint) rb->Width && y[i] < (GLint) rb->Height) {
185667074332728acba86da7630353673b458713bb8aBrian Paul         /* inside */
185767074332728acba86da7630353673b458713bb8aBrian Paul         if (inCount == 0)
185867074332728acba86da7630353673b458713bb8aBrian Paul            inStart = i;
185967074332728acba86da7630353673b458713bb8aBrian Paul         inCount++;
186067074332728acba86da7630353673b458713bb8aBrian Paul      }
186167074332728acba86da7630353673b458713bb8aBrian Paul      else {
186267074332728acba86da7630353673b458713bb8aBrian Paul         if (inCount > 0) {
186367074332728acba86da7630353673b458713bb8aBrian Paul            /* read [inStart, inStart + inCount) */
186467074332728acba86da7630353673b458713bb8aBrian Paul            rb->GetValues(ctx, rb, inCount, x + inStart, y + inStart,
186567074332728acba86da7630353673b458713bb8aBrian Paul                          (GLubyte *) values + inStart * valueSize);
186667074332728acba86da7630353673b458713bb8aBrian Paul            inCount = 0;
186767074332728acba86da7630353673b458713bb8aBrian Paul         }
186867074332728acba86da7630353673b458713bb8aBrian Paul      }
186967074332728acba86da7630353673b458713bb8aBrian Paul   }
187067074332728acba86da7630353673b458713bb8aBrian Paul   if (inCount > 0) {
187167074332728acba86da7630353673b458713bb8aBrian Paul      /* read last values */
187267074332728acba86da7630353673b458713bb8aBrian Paul      rb->GetValues(ctx, rb, inCount, x + inStart, y + inStart,
187367074332728acba86da7630353673b458713bb8aBrian Paul                    (GLubyte *) values + inStart * valueSize);
187467074332728acba86da7630353673b458713bb8aBrian Paul   }
187567074332728acba86da7630353673b458713bb8aBrian Paul}
18763fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul
18773fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul
18783fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul/**
18793fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul * Wrapper for gl_renderbuffer::PutRow() which does clipping.
1880a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul * \param valueSize  size of each value (pixel) in bytes
18813fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul */
18823fd819aef8139761ce86cb8d763de83a11c81b33Brian Paulvoid
18833fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul_swrast_put_row(GLcontext *ctx, struct gl_renderbuffer *rb,
18843fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul                GLuint count, GLint x, GLint y,
18853fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul                const GLvoid *values, GLuint valueSize)
18863fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul{
18873fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul   GLint skip = 0;
18883fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul
1889ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian   if (y < 0 || y >= (GLint) rb->Height)
18903fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul      return; /* above or below */
18913fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul
1892ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian   if (x + (GLint) count <= 0 || x >= (GLint) rb->Width)
18933fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul      return; /* entirely left or right */
18943fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul
1895ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian   if ((GLint) (x + count) > (GLint) rb->Width) {
18963fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul      /* right clip */
18973fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul      GLint clip = x + count - rb->Width;
18983fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul      count -= clip;
18993fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul   }
19003fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul
19013fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul   if (x < 0) {
19023fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul      /* left clip */
19033fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul      skip = -x;
19043fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul      x = 0;
19053fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul      count -= skip;
19063fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul   }
19073fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul
19083fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul   rb->PutRow(ctx, rb, count, x, y,
19093fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul              (const GLubyte *) values + skip * valueSize, NULL);
19103fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul}
1911f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul
1912f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul
1913f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul/**
1914f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul * Wrapper for gl_renderbuffer::GetRow() which does clipping.
1915a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul * \param valueSize  size of each value (pixel) in bytes
1916f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul */
1917f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paulvoid
1918f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul_swrast_get_row(GLcontext *ctx, struct gl_renderbuffer *rb,
1919f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul                GLuint count, GLint x, GLint y,
1920f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul                GLvoid *values, GLuint valueSize)
1921f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul{
1922f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul   GLint skip = 0;
1923f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul
1924ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian   if (y < 0 || y >= (GLint) rb->Height)
1925f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul      return; /* above or below */
1926f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul
1927ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian   if (x + (GLint) count <= 0 || x >= (GLint) rb->Width)
1928f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul      return; /* entirely left or right */
1929f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul
1930f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul   if (x + count > rb->Width) {
1931f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul      /* right clip */
1932f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul      GLint clip = x + count - rb->Width;
1933f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul      count -= clip;
1934f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul   }
1935f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul
1936f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul   if (x < 0) {
1937f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul      /* left clip */
1938f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul      skip = -x;
1939f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul      x = 0;
1940f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul      count -= skip;
1941f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul   }
1942f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul
1943f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul   rb->GetRow(ctx, rb, count, x, y, (GLubyte *) values + skip * valueSize);
1944f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul}
1945a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul
1946a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul
1947a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul/**
1948a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul * Get RGBA pixels from the given renderbuffer.  Put the pixel colors into
1949a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul * the span's specular color arrays.  The specular color arrays should no
1950a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul * longer be needed by time this function is called.
1951a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul * Used by blending, logicop and masking functions.
1952a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul * \return pointer to the colors we read.
1953a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul */
1954a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paulvoid *
1955a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul_swrast_get_dest_rgba(GLcontext *ctx, struct gl_renderbuffer *rb,
1956cdb27e8242215271364602995d85607cfc06d441Brian Paul                      SWspan *span)
1957a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul{
195876e778dce59aa6f290db50242df945943fc47b05Brian Paul   const GLuint pixelSize = RGBA_PIXEL_SIZE(span->array->ChanType);
1959a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul   void *rbPixels;
1960a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul
1961a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul   /*
1962a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul    * Determine pixel size (in bytes).
1963a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul    * Point rbPixels to a temporary space (use specular color arrays).
1964a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul    */
1965a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul   if (span->array->ChanType == GL_UNSIGNED_BYTE) {
1966a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul      rbPixels = span->array->color.sz1.spec;
1967a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul   }
1968a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul   else if (span->array->ChanType == GL_UNSIGNED_SHORT) {
1969a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul      rbPixels = span->array->color.sz2.spec;
1970a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul   }
1971a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul   else {
1972f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian      rbPixels = span->array->attribs[FRAG_ATTRIB_COL1];
1973a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul   }
1974a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul
1975a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul   /* Get destination values from renderbuffer */
1976a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul   if (span->arrayMask & SPAN_XY) {
1977a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul      _swrast_get_values(ctx, rb, span->end, span->array->x, span->array->y,
1978a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul                         rbPixels, pixelSize);
1979a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul   }
1980a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul   else {
1981a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul      _swrast_get_row(ctx, rb, span->end, span->x, span->y,
1982a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul                      rbPixels, pixelSize);
1983a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul   }
1984a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul
1985a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul   return rbPixels;
1986a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul}
1987