s_span.c revision bb19e64d12eaf27e2adc3faac7e09555bb66d724
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" 42a66393120411071b3f3ccce8583ab961a2935959Michal Krol#include "s_arbshader.h" 43e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_blend.h" 44cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell#include "s_context.h" 45e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_depth.h" 46e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_fog.h" 47e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_logic.h" 48e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_masking.h" 49610d59981a9f43fefe29b34ef19c184d28e2bef5Brian Paul#include "s_nvfragprog.h" 50e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_span.h" 51e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_stencil.h" 5255187ea63e980b32c7a701855571332f4357d634Brian Paul#include "s_texcombine.h" 53e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 542a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 5579c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/** 562a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul * Init span's Z interpolation values to the RasterPos Z. 572a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul * Used during setup for glDraw/CopyPixels. 582a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul */ 592a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paulvoid 60cdb27e8242215271364602995d85607cfc06d441Brian Paul_swrast_span_default_z( GLcontext *ctx, SWspan *span ) 612a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul{ 62e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul const GLfloat depthMax = ctx->DrawBuffer->_DepthMaxF; 6331e739a18931fa48454f172818245b0927c8910fBrian Paul if (ctx->DrawBuffer->Visual.depthBits <= 16) 64e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul span->z = FloatToFixed(ctx->Current.RasterPos[2] * depthMax + 0.5F); 652a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul else 66e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul span->z = (GLint) (ctx->Current.RasterPos[2] * depthMax + 0.5F); 672a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->zStep = 0; 682a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->interpMask |= SPAN_Z; 692a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul} 702a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 712a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 7279c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/** 732a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul * Init span's fog interpolation values to the RasterPos fog. 742a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul * Used during setup for glDraw/CopyPixels. 752a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul */ 762a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paulvoid 77cdb27e8242215271364602995d85607cfc06d441Brian Paul_swrast_span_default_fog( GLcontext *ctx, SWspan *span ) 782a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul{ 7945bc887da226403f2c41077e40ca38b6f60f1359Brian Paul span->fog = _swrast_z_to_fogfactor(ctx, ctx->Current.RasterDistance); 8054e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul span->fogStep = span->dfogdx = span->dfogdy = 0.0F; 812a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->interpMask |= SPAN_FOG; 822a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul} 832a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 842a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 8579c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/** 86a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul * Init span's rgba or index interpolation values to the RasterPos color. 872a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul * Used during setup for glDraw/CopyPixels. 882a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul */ 892a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paulvoid 90cdb27e8242215271364602995d85607cfc06d441Brian Paul_swrast_span_default_color( GLcontext *ctx, SWspan *span ) 912a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul{ 922a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul if (ctx->Visual.rgbMode) { 932a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLchan r, g, b, a; 942a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul UNCLAMPED_FLOAT_TO_CHAN(r, ctx->Current.RasterColor[0]); 952a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul UNCLAMPED_FLOAT_TO_CHAN(g, ctx->Current.RasterColor[1]); 962a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul UNCLAMPED_FLOAT_TO_CHAN(b, ctx->Current.RasterColor[2]); 972a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul UNCLAMPED_FLOAT_TO_CHAN(a, ctx->Current.RasterColor[3]); 982a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul#if CHAN_TYPE == GL_FLOAT 992a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->red = r; 1002a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->green = g; 1012a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->blue = b; 1022a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->alpha = a; 1032a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul#else 1042a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->red = IntToFixed(r); 1052a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->green = IntToFixed(g); 1062a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->blue = IntToFixed(b); 1072a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->alpha = IntToFixed(a); 1082a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul#endif 1092a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->redStep = 0; 1102a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->greenStep = 0; 1112a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->blueStep = 0; 1122a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->alphaStep = 0; 1132a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->interpMask |= SPAN_RGBA; 1142a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 1152a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul else { 1160f3cd3f894612d156de454178effa4c732f96da7Brian Paul span->index = FloatToFixed(ctx->Current.RasterIndex); 1172a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->indexStep = 0; 1182a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->interpMask |= SPAN_INDEX; 1192a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 1202a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul} 1212a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 1222a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 1234753d60dd070bb08d0116076bcc08025c86ce857Brian Paul/** 1244753d60dd070bb08d0116076bcc08025c86ce857Brian Paul * Init span's texcoord interpolation values to the RasterPos texcoords. 1254753d60dd070bb08d0116076bcc08025c86ce857Brian Paul * Used during setup for glDraw/CopyPixels. 1264753d60dd070bb08d0116076bcc08025c86ce857Brian Paul */ 1274753d60dd070bb08d0116076bcc08025c86ce857Brian Paulvoid 128cdb27e8242215271364602995d85607cfc06d441Brian Paul_swrast_span_default_texcoords( GLcontext *ctx, SWspan *span ) 1294753d60dd070bb08d0116076bcc08025c86ce857Brian Paul{ 1304753d60dd070bb08d0116076bcc08025c86ce857Brian Paul GLuint i; 131ee4e75bd6f768b7210436feeb32b4545ed62e025Brian Paul for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) { 132e63cb85cbc13c083f5d9f4640bb81ba9417a4f28Brian Paul const GLfloat *tc = ctx->Current.RasterTexCoords[i]; 1337e9799ac3d7f3b1b90f098420d413be95916c541Keith Whitwell if (ctx->FragmentProgram._Enabled || ctx->ATIFragmentShader._Enabled) { 134a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul COPY_4V(span->tex[i], tc); 135a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul } 136a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul else if (tc[3] > 0.0F) { 137e63cb85cbc13c083f5d9f4640bb81ba9417a4f28Brian Paul /* use (s/q, t/q, r/q, 1) */ 138e63cb85cbc13c083f5d9f4640bb81ba9417a4f28Brian Paul span->tex[i][0] = tc[0] / tc[3]; 139e63cb85cbc13c083f5d9f4640bb81ba9417a4f28Brian Paul span->tex[i][1] = tc[1] / tc[3]; 140e63cb85cbc13c083f5d9f4640bb81ba9417a4f28Brian Paul span->tex[i][2] = tc[2] / tc[3]; 141e63cb85cbc13c083f5d9f4640bb81ba9417a4f28Brian Paul span->tex[i][3] = 1.0; 142e63cb85cbc13c083f5d9f4640bb81ba9417a4f28Brian Paul } 143e63cb85cbc13c083f5d9f4640bb81ba9417a4f28Brian Paul else { 144e63cb85cbc13c083f5d9f4640bb81ba9417a4f28Brian Paul ASSIGN_4V(span->tex[i], 0.0F, 0.0F, 0.0F, 1.0F); 145e63cb85cbc13c083f5d9f4640bb81ba9417a4f28Brian Paul } 1465f60a0b50ada1865d4fc6a724366e8ea0cc9a72fBrian Paul ASSIGN_4V(span->texStepX[i], 0.0F, 0.0F, 0.0F, 0.0F); 1475f60a0b50ada1865d4fc6a724366e8ea0cc9a72fBrian Paul ASSIGN_4V(span->texStepY[i], 0.0F, 0.0F, 0.0F, 0.0F); 1484753d60dd070bb08d0116076bcc08025c86ce857Brian Paul } 1494753d60dd070bb08d0116076bcc08025c86ce857Brian Paul span->interpMask |= SPAN_TEXTURE; 1504753d60dd070bb08d0116076bcc08025c86ce857Brian Paul} 1514753d60dd070bb08d0116076bcc08025c86ce857Brian Paul 1524753d60dd070bb08d0116076bcc08025c86ce857Brian Paul 153d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul/** 154e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul * Interpolate primary colors to fill in the span->array->color array. 155d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul */ 156f614a6190562e550257afca0d04e3846648942e8Brian Paulstatic INLINE void 157e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paulinterpolate_colors(SWspan *span) 1582a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul{ 1592a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul const GLuint n = span->end; 1602a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLuint i; 1612a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 162e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul ASSERT((span->interpMask & SPAN_RGBA) && 163e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul !(span->arrayMask & SPAN_RGBA)); 1642a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 165e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul switch (span->array->ChanType) { 1661e3223c02a2f6155beb5784cadbea1f46703829aBrian Paul#if CHAN_BITS != 32 167e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul case GL_UNSIGNED_BYTE: 168e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul { 169e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul GLubyte (*rgba)[4] = span->array->color.sz1.rgba; 170e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul if (span->interpMask & SPAN_FLAT) { 171d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul GLubyte color[4]; 172e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul color[RCOMP] = FixedToInt(span->red); 173e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul color[GCOMP] = FixedToInt(span->green); 174e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul color[BCOMP] = FixedToInt(span->blue); 175e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul color[ACOMP] = FixedToInt(span->alpha); 176d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul for (i = 0; i < n; i++) { 177d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul COPY_4UBV(rgba[i], color); 178d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul } 179d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul } 180e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul else { 181e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul GLfixed r = span->red; 182e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul GLfixed g = span->green; 183e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul GLfixed b = span->blue; 184e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul GLfixed a = span->alpha; 185e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul GLint dr = span->redStep; 186e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul GLint dg = span->greenStep; 187e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul GLint db = span->blueStep; 188e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul GLint da = span->alphaStep; 189d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul for (i = 0; i < n; i++) { 190e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul rgba[i][RCOMP] = FixedToChan(r); 191e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul rgba[i][GCOMP] = FixedToChan(g); 192e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul rgba[i][BCOMP] = FixedToChan(b); 193e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul rgba[i][ACOMP] = FixedToChan(a); 194e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul r += dr; 195e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul g += dg; 196e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul b += db; 197e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul a += da; 198d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul } 199d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul } 200e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul } 201e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul break; 202e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul case GL_UNSIGNED_SHORT: 203e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul { 204e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul GLushort (*rgba)[4] = span->array->color.sz2.rgba; 205e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul if (span->interpMask & SPAN_FLAT) { 206e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul GLushort color[4]; 207e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul color[RCOMP] = FixedToInt(span->red); 208e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul color[GCOMP] = FixedToInt(span->green); 209e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul color[BCOMP] = FixedToInt(span->blue); 210e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul color[ACOMP] = FixedToInt(span->alpha); 211d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul for (i = 0; i < n; i++) { 212d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul COPY_4V(rgba[i], color); 213d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul } 214d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul } 215e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul else { 216e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul GLushort (*rgba)[4] = span->array->color.sz2.rgba; 217d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul GLfixed r, g, b, a; 218d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul GLint dr, dg, db, da; 219e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul r = span->red; 220e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul g = span->green; 221e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul b = span->blue; 222e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul a = span->alpha; 223e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul dr = span->redStep; 224e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul dg = span->greenStep; 225e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul db = span->blueStep; 226e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul da = span->alphaStep; 227d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul for (i = 0; i < n; i++) { 228d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul rgba[i][RCOMP] = FixedToChan(r); 229d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul rgba[i][GCOMP] = FixedToChan(g); 230d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul rgba[i][BCOMP] = FixedToChan(b); 231d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul rgba[i][ACOMP] = FixedToChan(a); 232d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul r += dr; 233d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul g += dg; 234d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul b += db; 235d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul a += da; 236d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul } 237d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul } 238e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul } 239e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul break; 240e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul#endif 241e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul case GL_FLOAT: 242e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul { 243e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul GLfloat (*rgba)[4] = span->array->color.sz4.rgba; 244e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul GLfloat r, g, b, a, dr, dg, db, da; 245e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul r = span->red; 246e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul g = span->green; 247e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul b = span->blue; 248e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul a = span->alpha; 249e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul if (span->interpMask & SPAN_FLAT) { 250e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul dr = dg = db = da = 0.0; 251e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul } 252e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul else { 253e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul dr = span->redStep; 254e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul dg = span->greenStep; 255e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul db = span->blueStep; 256e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul da = span->alphaStep; 257e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul } 258e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul for (i = 0; i < n; i++) { 259e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul rgba[i][RCOMP] = r; 260e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul rgba[i][GCOMP] = g; 261e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul rgba[i][BCOMP] = b; 262e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul rgba[i][ACOMP] = a; 263e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul r += dr; 264e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul g += dg; 265e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul b += db; 266e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul a += da; 267e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul } 268e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul } 269e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul break; 270e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul default: 271e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul _mesa_problem(NULL, "bad datatype in interpolate_colors"); 272e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul } 273e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul span->arrayMask |= SPAN_RGBA; 274e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul} 275e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul 276e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul 277e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul/** 278e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul * Interpolate specular/secondary colors. 279e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul */ 280f614a6190562e550257afca0d04e3846648942e8Brian Paulstatic INLINE void 281e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paulinterpolate_specular(SWspan *span) 282e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul{ 283e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul const GLuint n = span->end; 284e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul GLuint i; 285e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul 286e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul switch (span->array->ChanType) { 287c351858de8e51fa4a6425cf176cc43689189f3ffBrian Paul#if CHAN_BITS != 32 288e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul case GL_UNSIGNED_BYTE: 289e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul { 290e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul GLubyte (*spec)[4] = span->array->color.sz1.spec; 291e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul if (span->interpMask & SPAN_FLAT) { 292e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul GLubyte color[4]; 293e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul color[RCOMP] = FixedToInt(span->specRed); 294e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul color[GCOMP] = FixedToInt(span->specGreen); 295e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul color[BCOMP] = FixedToInt(span->specBlue); 296e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul color[ACOMP] = 0; 297e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul for (i = 0; i < n; i++) { 298e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul COPY_4UBV(spec[i], color); 299d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul } 300e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul } 301e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul else { 302e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul GLfixed r = span->specRed; 303e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul GLfixed g = span->specGreen; 304e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul GLfixed b = span->specBlue; 305e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul GLint dr = span->specRedStep; 306e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul GLint dg = span->specGreenStep; 307e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul GLint db = span->specBlueStep; 308d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul for (i = 0; i < n; i++) { 309e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul spec[i][RCOMP] = CLAMP(FixedToChan(r), 0, 255); 310e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul spec[i][GCOMP] = CLAMP(FixedToChan(g), 0, 255); 311e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul spec[i][BCOMP] = CLAMP(FixedToChan(b), 0, 255); 312e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul spec[i][ACOMP] = 0; 313d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul r += dr; 314d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul g += dg; 315d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul b += db; 316d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul } 317d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul } 318e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul } 319e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul break; 320e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul case GL_UNSIGNED_SHORT: 321e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul { 322e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul GLushort (*spec)[4] = span->array->color.sz2.spec; 323e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul if (span->interpMask & SPAN_FLAT) { 324e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul GLushort color[4]; 325e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul color[RCOMP] = FixedToInt(span->specRed); 326e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul color[GCOMP] = FixedToInt(span->specGreen); 327e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul color[BCOMP] = FixedToInt(span->specBlue); 328e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul color[ACOMP] = 0; 329e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul for (i = 0; i < n; i++) { 330e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul COPY_4V(spec[i], color); 331d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul } 332e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul } 333e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul else { 334e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul GLfixed r = FloatToFixed(span->specRed); 335e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul GLfixed g = FloatToFixed(span->specGreen); 336e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul GLfixed b = FloatToFixed(span->specBlue); 337e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul GLint dr = FloatToFixed(span->specRedStep); 338e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul GLint dg = FloatToFixed(span->specGreenStep); 339e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul GLint db = FloatToFixed(span->specBlueStep); 340e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul for (i = 0; i < n; i++) { 341e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul spec[i][RCOMP] = FixedToInt(r); 342e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul spec[i][GCOMP] = FixedToInt(g); 343e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul spec[i][BCOMP] = FixedToInt(b); 344e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul spec[i][ACOMP] = 0; 345e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul r += dr; 346e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul g += dg; 347e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul b += db; 348d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul } 349e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul } 350e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul } 351e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul break; 352c351858de8e51fa4a6425cf176cc43689189f3ffBrian Paul#endif 353e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul case GL_FLOAT: 354e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul { 355e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul GLfloat (*spec)[4] = span->array->color.sz4.spec; 356e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul if (span->interpMask & SPAN_FLAT) { 357e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul GLfloat color[4]; 358e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul color[RCOMP] = span->specRed; 359e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul color[GCOMP] = span->specGreen; 360e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul color[BCOMP] = span->specBlue; 361e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul color[ACOMP] = 0.0F; 362d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul for (i = 0; i < n; i++) { 363e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul COPY_4V(spec[i], color); 364e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul } 365e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul } 366e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul else { 367e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul GLfloat r = span->specRed; 368e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul GLfloat g = span->specGreen; 369e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul GLfloat b = span->specBlue; 370e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul GLfloat dr = span->specRedStep; 371e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul GLfloat dg = span->specGreenStep; 372e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul GLfloat db = span->specBlueStep; 373e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul for (i = 0; i < n; i++) { 374e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul spec[i][RCOMP] = r; 375e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul spec[i][GCOMP] = g; 376e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul spec[i][BCOMP] = b; 377e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul spec[i][ACOMP] = 0.0F; 378d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul r += dr; 379d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul g += dg; 380d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul b += db; 381d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul } 382d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul } 3832a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 384e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul break; 385e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul default: 386e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul _mesa_problem(NULL, "bad datatype in interpolate_specular"); 3872a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 388e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul span->arrayMask |= SPAN_SPEC; 3892a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul} 3902a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 3912a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 3922a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul/* Fill in the span.color.index array from the interpolation values */ 393f614a6190562e550257afca0d04e3846648942e8Brian Paulstatic INLINE void 394cdb27e8242215271364602995d85607cfc06d441Brian Paulinterpolate_indexes(GLcontext *ctx, SWspan *span) 3952a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul{ 3962a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfixed index = span->index; 3972a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul const GLint indexStep = span->indexStep; 3982a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul const GLuint n = span->end; 39977df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul GLuint *indexes = span->array->index; 4002a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLuint i; 401a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul (void) ctx; 402b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul ASSERT((span->interpMask & SPAN_INDEX) && 403b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul !(span->arrayMask & SPAN_INDEX)); 4042a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 4052a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul if ((span->interpMask & SPAN_FLAT) || (indexStep == 0)) { 4062a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul /* constant color */ 4072a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul index = FixedToInt(index); 4082a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul for (i = 0; i < n; i++) { 4092a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul indexes[i] = index; 4102a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 4112a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 4122a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul else { 4132a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul /* interpolate */ 4142a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul for (i = 0; i < n; i++) { 4152a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul indexes[i] = FixedToInt(index); 4162a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul index += indexStep; 4172a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 4182a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 4192a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->arrayMask |= SPAN_INDEX; 420e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul span->interpMask &= ~SPAN_INDEX; 4212a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul} 4222a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 4232a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 424d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul/* Fill in the span.array.fog values from the interpolation values */ 425f614a6190562e550257afca0d04e3846648942e8Brian Paulstatic INLINE void 426cdb27e8242215271364602995d85607cfc06d441Brian Paulinterpolate_fog(const GLcontext *ctx, SWspan *span) 427d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul{ 428d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul GLfloat *fog = span->array->fog; 429d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul const GLfloat fogStep = span->fogStep; 430d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul GLfloat fogCoord = span->fog; 431d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul const GLuint haveW = (span->interpMask & SPAN_W); 432d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul const GLfloat wStep = haveW ? span->dwdx : 0.0F; 433d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul GLfloat w = haveW ? span->w : 1.0F; 434d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul GLuint i; 435d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul for (i = 0; i < span->end; i++) { 436d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul fog[i] = fogCoord / w; 437d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul fogCoord += fogStep; 438d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul w += wStep; 439d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul } 440d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul span->arrayMask |= SPAN_FOG; 441d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul} 442d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul 443d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul 4442a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul/* Fill in the span.zArray array from the interpolation values */ 445711e27fda27e4235b20a4cf73c2767c984ab2b81Brian Paulvoid 446cdb27e8242215271364602995d85607cfc06d441Brian Paul_swrast_span_interpolate_z( const GLcontext *ctx, SWspan *span ) 4472a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul{ 4482a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul const GLuint n = span->end; 4492a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLuint i; 4502a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 451b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul ASSERT((span->interpMask & SPAN_Z) && 452b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul !(span->arrayMask & SPAN_Z)); 4532a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 45431e739a18931fa48454f172818245b0927c8910fBrian Paul if (ctx->DrawBuffer->Visual.depthBits <= 16) { 4552a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfixed zval = span->z; 4563e37bafab0a339021354b9c78f983d05d433d735Brian Paul GLuint *z = span->array->z; 457ad8cd6111e022c90c93df106c0fde6f64d205816Brian Paul for (i = 0; i < n; i++) { 45877df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul z[i] = FixedToInt(zval); 4592a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul zval += span->zStep; 4602a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 4612a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 4622a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul else { 4632a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul /* Deep Z buffer, no fixed->int shift */ 4647265556b9aa0367e9b5031e7cb15ed2a5d73866dBrian Paul GLuint zval = span->z; 4653e37bafab0a339021354b9c78f983d05d433d735Brian Paul GLuint *z = span->array->z; 4662a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul for (i = 0; i < n; i++) { 46777df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul z[i] = zval; 4682a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul zval += span->zStep; 4692a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 4702a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 47132340aea1308153dad5c105fc0748aea1e4c37eeBrian Paul span->interpMask &= ~SPAN_Z; 4722a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->arrayMask |= SPAN_Z; 4732a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul} 4742a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 4752a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 476c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul/* 47731f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul * This the ideal solution, as given in the OpenGL spec. 478c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul */ 479c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul#if 0 48031f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paulstatic GLfloat 48131f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paulcompute_lambda(GLfloat dsdx, GLfloat dsdy, GLfloat dtdx, GLfloat dtdy, 48231f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat dqdx, GLfloat dqdy, GLfloat texW, GLfloat texH, 48331f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat s, GLfloat t, GLfloat q, GLfloat invQ) 484c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul{ 48531f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat dudx = texW * ((s + dsdx) / (q + dqdx) - s * invQ); 48631f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat dvdx = texH * ((t + dtdx) / (q + dqdx) - t * invQ); 48731f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat dudy = texW * ((s + dsdy) / (q + dqdy) - s * invQ); 48831f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat dvdy = texH * ((t + dtdy) / (q + dqdy) - t * invQ); 489f9b1e5241facc8cf255c258082d5cb5b04783e93Brian Paul GLfloat x = SQRTF(dudx * dudx + dvdx * dvdx); 490f9b1e5241facc8cf255c258082d5cb5b04783e93Brian Paul GLfloat y = SQRTF(dudy * dudy + dvdy * dvdy); 49131f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat rho = MAX2(x, y); 49231f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat lambda = LOG2(rho); 49331f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul return lambda; 494c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul} 495c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul#endif 496c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul 49731f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul 49831f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul/* 49931f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul * This is a faster approximation 500c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul */ 501350353adcd75f94fda63c787c86961716114e0bfBrian PaulGLfloat 50245bc887da226403f2c41077e40ca38b6f60f1359Brian Paul_swrast_compute_lambda(GLfloat dsdx, GLfloat dsdy, GLfloat dtdx, GLfloat dtdy, 503350353adcd75f94fda63c787c86961716114e0bfBrian Paul GLfloat dqdx, GLfloat dqdy, GLfloat texW, GLfloat texH, 504350353adcd75f94fda63c787c86961716114e0bfBrian Paul GLfloat s, GLfloat t, GLfloat q, GLfloat invQ) 505c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul{ 50631f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat dsdx2 = (s + dsdx) / (q + dqdx) - s * invQ; 50731f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat dtdx2 = (t + dtdx) / (q + dqdx) - t * invQ; 50831f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat dsdy2 = (s + dsdy) / (q + dqdy) - s * invQ; 50931f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat dtdy2 = (t + dtdy) / (q + dqdy) - t * invQ; 51031f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat maxU, maxV, rho, lambda; 51131f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul dsdx2 = FABSF(dsdx2); 51231f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul dsdy2 = FABSF(dsdy2); 51331f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul dtdx2 = FABSF(dtdx2); 51431f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul dtdy2 = FABSF(dtdy2); 51531f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul maxU = MAX2(dsdx2, dsdy2) * texW; 51631f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul maxV = MAX2(dtdx2, dtdy2) * texH; 51731f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul rho = MAX2(maxU, maxV); 51831f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul lambda = LOG2(rho); 51931f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul return lambda; 520c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul} 521c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul 522d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul 523d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul/** 524c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul * Fill in the span.texcoords array from the interpolation values. 525d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul * Note: in the places where we divide by Q (or mult by invQ) we're 526d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul * really doing two things: perspective correction and texcoord 527d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul * projection. Remember, for texcoord (s,t,r,q) we need to index 528d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul * texels with (s/q, t/q, r/q). 529d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul * If we're using a fragment program, we never do the division 530d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul * for texcoord projection. That's done by the TXP instruction 531d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul * or user-written code. 532c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul */ 5332a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paulstatic void 534cdb27e8242215271364602995d85607cfc06d441Brian Paulinterpolate_texcoords(GLcontext *ctx, SWspan *span) 5352a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul{ 5362a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul ASSERT(span->interpMask & SPAN_TEXTURE); 537b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul ASSERT(!(span->arrayMask & SPAN_TEXTURE)); 5382a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 53936a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul if (ctx->Texture._EnabledCoordUnits > 1) { 54031f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul /* multitexture */ 54131f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLuint u; 542b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul span->arrayMask |= SPAN_TEXTURE; 543ee4e75bd6f768b7210436feeb32b4545ed62e025Brian Paul /* XXX CoordUnits vs. ImageUnits */ 54431f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { 54536a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul if (ctx->Texture._EnabledCoordUnits & (1 << u)) { 54631f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const struct gl_texture_object *obj =ctx->Texture.Unit[u]._Current; 54736a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul GLfloat texW, texH; 54836a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul GLboolean needLambda; 54936a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul if (obj) { 55018fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell const struct gl_texture_image *img = obj->Image[0][obj->BaseLevel]; 55136a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul needLambda = (obj->MinFilter != obj->MagFilter) 5527e9799ac3d7f3b1b90f098420d413be95916c541Keith Whitwell || ctx->FragmentProgram._Enabled; 55336a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul texW = img->WidthScale; 55436a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul texH = img->HeightScale; 55536a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul } 55636a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul else { 557d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul /* using a fragment program */ 55836a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul texW = 1.0; 55936a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul texH = 1.0; 56036a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul needLambda = GL_FALSE; 56136a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul } 56231f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul if (needLambda) { 56377df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul GLfloat (*texcoord)[4] = span->array->texcoords[u]; 56477df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul GLfloat *lambda = span->array->lambda[u]; 56531f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat dsdx = span->texStepX[u][0]; 56631f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat dsdy = span->texStepY[u][0]; 56731f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat dtdx = span->texStepX[u][1]; 56831f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat dtdy = span->texStepY[u][1]; 56931f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat drdx = span->texStepX[u][2]; 57031f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat dqdx = span->texStepX[u][3]; 57131f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat dqdy = span->texStepY[u][3]; 5722a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat s = span->tex[u][0]; 5732a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat t = span->tex[u][1]; 5742a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat r = span->tex[u][2]; 5752a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat q = span->tex[u][3]; 5762a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLuint i; 5777e9799ac3d7f3b1b90f098420d413be95916c541Keith Whitwell if (ctx->FragmentProgram._Enabled || ctx->ATIFragmentShader._Enabled || 578bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol ctx->ShaderObjects._FragmentShaderPresent) { 579d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul /* do perspective correction but don't divide s, t, r by q */ 580d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul const GLfloat dwdx = span->dwdx; 581d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul GLfloat w = span->w; 582d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul for (i = 0; i < span->end; i++) { 583d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul const GLfloat invW = 1.0F / w; 584d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul texcoord[i][0] = s * invW; 585d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul texcoord[i][1] = t * invW; 586d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul texcoord[i][2] = r * invW; 587d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul texcoord[i][3] = q * invW; 588d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul lambda[i] = _swrast_compute_lambda(dsdx, dsdy, dtdx, dtdy, 589d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul dqdx, dqdy, texW, texH, 590d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul s, t, q, invW); 591d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul s += dsdx; 592d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul t += dtdx; 593d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul r += drdx; 594d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul q += dqdx; 595d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul w += dwdx; 596d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul } 597d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul 598d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul } 599d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul else { 600d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul for (i = 0; i < span->end; i++) { 601d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q); 602d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul texcoord[i][0] = s * invQ; 603d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul texcoord[i][1] = t * invQ; 604d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul texcoord[i][2] = r * invQ; 605d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul texcoord[i][3] = q; 606d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul lambda[i] = _swrast_compute_lambda(dsdx, dsdy, dtdx, dtdy, 607d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul dqdx, dqdy, texW, texH, 608d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul s, t, q, invQ); 609d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul s += dsdx; 610d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul t += dtdx; 611d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul r += drdx; 612d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul q += dqdx; 613d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul } 6142a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 61531f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul span->arrayMask |= SPAN_LAMBDA; 6162a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 61731f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul else { 61877df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul GLfloat (*texcoord)[4] = span->array->texcoords[u]; 61977df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul GLfloat *lambda = span->array->lambda[u]; 62031f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat dsdx = span->texStepX[u][0]; 62131f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat dtdx = span->texStepX[u][1]; 62231f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat drdx = span->texStepX[u][2]; 62331f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat dqdx = span->texStepX[u][3]; 6242a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat s = span->tex[u][0]; 6252a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat t = span->tex[u][1]; 6262a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat r = span->tex[u][2]; 6272a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat q = span->tex[u][3]; 6282a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLuint i; 6297e9799ac3d7f3b1b90f098420d413be95916c541Keith Whitwell if (ctx->FragmentProgram._Enabled || ctx->ATIFragmentShader._Enabled || 630bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol ctx->ShaderObjects._FragmentShaderPresent) { 631d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul /* do perspective correction but don't divide s, t, r by q */ 632d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul const GLfloat dwdx = span->dwdx; 633d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul GLfloat w = span->w; 634d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul for (i = 0; i < span->end; i++) { 635d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul const GLfloat invW = 1.0F / w; 636d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul texcoord[i][0] = s * invW; 637d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul texcoord[i][1] = t * invW; 638d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul texcoord[i][2] = r * invW; 639d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul texcoord[i][3] = q * invW; 640d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul lambda[i] = 0.0; 641d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul s += dsdx; 642d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul t += dtdx; 643d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul r += drdx; 644d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul q += dqdx; 645d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul w += dwdx; 646d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul } 647d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul } 648d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul else if (dqdx == 0.0F) { 649c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul /* Ortho projection or polygon's parallel to window X axis */ 6502a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q); 651c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul for (i = 0; i < span->end; i++) { 65277df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul texcoord[i][0] = s * invQ; 65377df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul texcoord[i][1] = t * invQ; 65477df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul texcoord[i][2] = r * invQ; 65536a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul texcoord[i][3] = q; 65677df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul lambda[i] = 0.0; 65731f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul s += dsdx; 65831f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul t += dtdx; 65931f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul r += drdx; 660c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul } 661c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul } 662c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul else { 663c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul for (i = 0; i < span->end; i++) { 664c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q); 66577df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul texcoord[i][0] = s * invQ; 66677df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul texcoord[i][1] = t * invQ; 66777df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul texcoord[i][2] = r * invQ; 66836a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul texcoord[i][3] = q; 66977df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul lambda[i] = 0.0; 67031f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul s += dsdx; 67131f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul t += dtdx; 67231f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul r += drdx; 67331f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul q += dqdx; 674c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul } 6752a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 67631f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul } /* lambda */ 67731f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul } /* if */ 67831f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul } /* for */ 6792a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 6802a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul else { 68131f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul /* single texture */ 68231f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const struct gl_texture_object *obj = ctx->Texture.Unit[0]._Current; 68336a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul GLfloat texW, texH; 68436a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul GLboolean needLambda; 68536a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul if (obj) { 68618fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell const struct gl_texture_image *img = obj->Image[0][obj->BaseLevel]; 68736a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul needLambda = (obj->MinFilter != obj->MagFilter) 6887e9799ac3d7f3b1b90f098420d413be95916c541Keith Whitwell || ctx->FragmentProgram._Enabled; 68936a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul texW = (GLfloat) img->WidthScale; 69036a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul texH = (GLfloat) img->HeightScale; 69136a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul } 69236a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul else { 69336a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul needLambda = GL_FALSE; 69436a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul texW = texH = 1.0; 69536a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul } 696b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul span->arrayMask |= SPAN_TEXTURE; 69731f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul if (needLambda) { 6982a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul /* just texture unit 0, with lambda */ 69977df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul GLfloat (*texcoord)[4] = span->array->texcoords[0]; 70077df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul GLfloat *lambda = span->array->lambda[0]; 70131f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat dsdx = span->texStepX[0][0]; 70231f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat dsdy = span->texStepY[0][0]; 70331f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat dtdx = span->texStepX[0][1]; 70431f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat dtdy = span->texStepY[0][1]; 70531f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat drdx = span->texStepX[0][2]; 70631f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat dqdx = span->texStepX[0][3]; 70731f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat dqdy = span->texStepY[0][3]; 7082a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat s = span->tex[0][0]; 7092a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat t = span->tex[0][1]; 7102a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat r = span->tex[0][2]; 7112a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat q = span->tex[0][3]; 7122a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLuint i; 7137e9799ac3d7f3b1b90f098420d413be95916c541Keith Whitwell if (ctx->FragmentProgram._Enabled || ctx->ATIFragmentShader._Enabled || 714bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol ctx->ShaderObjects._FragmentShaderPresent) { 715d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul /* do perspective correction but don't divide s, t, r by q */ 716d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul const GLfloat dwdx = span->dwdx; 717d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul GLfloat w = span->w; 718d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul for (i = 0; i < span->end; i++) { 719d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul const GLfloat invW = 1.0F / w; 720d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul texcoord[i][0] = s * invW; 721d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul texcoord[i][1] = t * invW; 722d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul texcoord[i][2] = r * invW; 723d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul texcoord[i][3] = q * invW; 724d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul lambda[i] = _swrast_compute_lambda(dsdx, dsdy, dtdx, dtdy, 725d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul dqdx, dqdy, texW, texH, 726d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul s, t, q, invW); 727d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul s += dsdx; 728d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul t += dtdx; 729d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul r += drdx; 730d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul q += dqdx; 731d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul w += dwdx; 732d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul } 733d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul } 734d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul else { 735d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul /* tex.c */ 736d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul for (i = 0; i < span->end; i++) { 737d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q); 738d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul lambda[i] = _swrast_compute_lambda(dsdx, dsdy, dtdx, dtdy, 739d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul dqdx, dqdy, texW, texH, 740d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul s, t, q, invQ); 741d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul texcoord[i][0] = s * invQ; 742d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul texcoord[i][1] = t * invQ; 743d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul texcoord[i][2] = r * invQ; 744d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul texcoord[i][3] = q; 745d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul s += dsdx; 746d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul t += dtdx; 747d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul r += drdx; 748d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul q += dqdx; 749d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul } 7502a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 7512a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->arrayMask |= SPAN_LAMBDA; 7522a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 7532a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul else { 754733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* just texture 0, without lambda */ 75577df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul GLfloat (*texcoord)[4] = span->array->texcoords[0]; 75631f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat dsdx = span->texStepX[0][0]; 75731f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat dtdx = span->texStepX[0][1]; 75831f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat drdx = span->texStepX[0][2]; 75931f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat dqdx = span->texStepX[0][3]; 7602a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat s = span->tex[0][0]; 7612a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat t = span->tex[0][1]; 7622a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat r = span->tex[0][2]; 7632a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat q = span->tex[0][3]; 7642a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLuint i; 7657e9799ac3d7f3b1b90f098420d413be95916c541Keith Whitwell if (ctx->FragmentProgram._Enabled || ctx->ATIFragmentShader._Enabled || 766bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol ctx->ShaderObjects._FragmentShaderPresent) { 767d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul /* do perspective correction but don't divide s, t, r by q */ 768d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul const GLfloat dwdx = span->dwdx; 769d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul GLfloat w = span->w; 770d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul for (i = 0; i < span->end; i++) { 771d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul const GLfloat invW = 1.0F / w; 772d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul texcoord[i][0] = s * invW; 773d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul texcoord[i][1] = t * invW; 774d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul texcoord[i][2] = r * invW; 775d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul texcoord[i][3] = q * invW; 776d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul s += dsdx; 777d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul t += dtdx; 778d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul r += drdx; 779d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul q += dqdx; 780d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul w += dwdx; 781d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul } 782d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul } 783d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul else if (dqdx == 0.0F) { 784c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul /* Ortho projection or polygon's parallel to window X axis */ 7852a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q); 786c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul for (i = 0; i < span->end; i++) { 78777df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul texcoord[i][0] = s * invQ; 78877df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul texcoord[i][1] = t * invQ; 78977df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul texcoord[i][2] = r * invQ; 7902b7a01a39ba5257407dddde38ef049856c34aa01Brian Paul texcoord[i][3] = q; 79131f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul s += dsdx; 79231f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul t += dtdx; 79331f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul r += drdx; 794c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul } 795c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul } 796c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul else { 797c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul for (i = 0; i < span->end; i++) { 798c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q); 79977df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul texcoord[i][0] = s * invQ; 80077df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul texcoord[i][1] = t * invQ; 80177df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul texcoord[i][2] = r * invQ; 8022b7a01a39ba5257407dddde38ef049856c34aa01Brian Paul texcoord[i][3] = q; 80331f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul s += dsdx; 80431f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul t += dtdx; 80531f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul r += drdx; 80631f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul q += dqdx; 807c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul } 8082a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 8092a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 8102a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 81110f30eb43835c57c00783390a02d72daf4f78e26Brian Paul} 812e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 813e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 81479c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/** 815bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol * Fill in the span.varying array from the interpolation values. 816bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol */ 817f614a6190562e550257afca0d04e3846648942e8Brian Paulstatic INLINE void 818cdb27e8242215271364602995d85607cfc06d441Brian Paulinterpolate_varying(GLcontext *ctx, SWspan *span) 819bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol{ 820bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol GLuint i, j; 821bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol 822bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol ASSERT(span->interpMask & SPAN_VARYING); 823bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol ASSERT(!(span->arrayMask & SPAN_VARYING)); 824bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol 825bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol span->arrayMask |= SPAN_VARYING; 826bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol 827bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol for (i = 0; i < MAX_VARYING_VECTORS; i++) { 828bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol for (j = 0; j < VARYINGS_PER_VECTOR; j++) { 829bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol const GLfloat dvdx = span->varStepX[i][j]; 830bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol GLfloat v = span->var[i][j]; 831bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol const GLfloat dwdx = span->dwdx; 832bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol GLfloat w = span->w; 833bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol GLuint k; 834bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol 835bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol for (k = 0; k < span->end; k++) { 836bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol GLfloat invW = 1.0f / w; 837bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol span->array->varying[k][i][j] = v * invW; 838bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol v += dvdx; 839bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol w += dwdx; 840bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol } 841bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol } 842bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol } 843bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol} 844bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol 845bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol 846bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol/** 847e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Apply the current polygon stipple pattern to a span of pixels. 848e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */ 849f614a6190562e550257afca0d04e3846648942e8Brian Paulstatic INLINE void 850cdb27e8242215271364602995d85607cfc06d441Brian Paulstipple_polygon_span( GLcontext *ctx, SWspan *span ) 85110f30eb43835c57c00783390a02d72daf4f78e26Brian Paul{ 85210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul const GLuint highbit = 0x80000000; 853733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul const GLuint stipple = ctx->PolygonStipple[span->y % 32]; 85477df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul GLubyte *mask = span->array->mask; 855733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul GLuint i, m; 856733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul 857733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul ASSERT(ctx->Polygon.StippleFlag); 858733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul ASSERT((span->arrayMask & SPAN_XY) == 0); 85910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 86010f30eb43835c57c00783390a02d72daf4f78e26Brian Paul m = highbit >> (GLuint) (span->x % 32); 86110f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 86210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul for (i = 0; i < span->end; i++) { 86310f30eb43835c57c00783390a02d72daf4f78e26Brian Paul if ((m & stipple) == 0) { 86477df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul mask[i] = 0; 86510f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 86610f30eb43835c57c00783390a02d72daf4f78e26Brian Paul m = m >> 1; 86710f30eb43835c57c00783390a02d72daf4f78e26Brian Paul if (m == 0) { 86810f30eb43835c57c00783390a02d72daf4f78e26Brian Paul m = highbit; 86910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 87010f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 8712ef866d1fc0a5cc5ef8543d65744dfd4da4dbbafBrian Paul span->writeAll = GL_FALSE; 87210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul} 87310f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 874e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 87579c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/** 876733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul * Clip a pixel span to the current buffer/window boundaries: 877733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul * DrawBuffer->_Xmin, _Xmax, _Ymin, _Ymax. This will accomplish 878733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul * window clipping and scissoring. 879733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul * Return: GL_TRUE some pixels still visible 88010f30eb43835c57c00783390a02d72daf4f78e26Brian Paul * GL_FALSE nothing visible 88110f30eb43835c57c00783390a02d72daf4f78e26Brian Paul */ 882f614a6190562e550257afca0d04e3846648942e8Brian Paulstatic INLINE GLuint 883cdb27e8242215271364602995d85607cfc06d441Brian Paulclip_span( GLcontext *ctx, SWspan *span ) 88410f30eb43835c57c00783390a02d72daf4f78e26Brian Paul{ 885733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul const GLint xmin = ctx->DrawBuffer->_Xmin; 886733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul const GLint xmax = ctx->DrawBuffer->_Xmax; 887733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul const GLint ymin = ctx->DrawBuffer->_Ymin; 888733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul const GLint ymax = ctx->DrawBuffer->_Ymax; 889733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul 890733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (span->arrayMask & SPAN_XY) { 891733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* arrays of x/y pixel coords */ 89277df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul const GLint *x = span->array->x; 89377df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul const GLint *y = span->array->y; 894733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul const GLint n = span->end; 89577df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul GLubyte *mask = span->array->mask; 896733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul GLint i; 897b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul if (span->arrayMask & SPAN_MASK) { 898b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul /* note: using & intead of && to reduce branches */ 899b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul for (i = 0; i < n; i++) { 900b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul mask[i] &= (x[i] >= xmin) & (x[i] < xmax) 901b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul & (y[i] >= ymin) & (y[i] < ymax); 902b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul } 903b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul } 904b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul else { 905b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul /* note: using & intead of && to reduce branches */ 906b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul for (i = 0; i < n; i++) { 907b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul mask[i] = (x[i] >= xmin) & (x[i] < xmax) 908b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul & (y[i] >= ymin) & (y[i] < ymax); 909b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul } 91010f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 911733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul return GL_TRUE; /* some pixels visible */ 91210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 913733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul else { 914733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* horizontal span of pixels */ 915733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul const GLint x = span->x; 916733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul const GLint y = span->y; 917733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul const GLint n = span->end; 918733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul 919733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* Trivial rejection tests */ 920733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (y < ymin || y >= ymax || x + n <= xmin || x >= xmax) { 921733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->end = 0; 922733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul return GL_FALSE; /* all pixels clipped */ 923733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul } 92410f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 925733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* Clip to the left */ 926733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (x < xmin) { 927733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul ASSERT(x + n > xmin); 928733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->writeAll = GL_FALSE; 9296ec6b845fdf3c44436028ad6fff9471d18928719Brian Paul _mesa_bzero(span->array->mask, (xmin - x) * sizeof(GLubyte)); 93010f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 931733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul 932733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* Clip to right */ 933733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (x + n > xmax) { 934733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul ASSERT(x < xmax); 935733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->end = xmax - x; 93610f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 93710f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 938733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul return GL_TRUE; /* some pixels visible */ 939733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul } 94010f30eb43835c57c00783390a02d72daf4f78e26Brian Paul} 94110f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 94210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 94379c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/** 944e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul * Apply all the per-fragment opertions to a span of color index fragments 945e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul * and write them to the enabled color drawbuffers. 946e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul * The 'span' parameter can be considered to be const. Note that 9477956292a765910077f50352d7cd0174e1e66d26cBrian Paul * span->interpMask and span->arrayMask may be changed but will be restored 9487956292a765910077f50352d7cd0174e1e66d26cBrian Paul * to their original values before returning. 94910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul */ 95010f30eb43835c57c00783390a02d72daf4f78e26Brian Paulvoid 951cdb27e8242215271364602995d85607cfc06d441Brian Paul_swrast_write_index_span( GLcontext *ctx, SWspan *span) 95210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul{ 953e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul const SWcontext *swrast = SWRAST_CONTEXT(ctx); 954e00ac11d4dd05c56584622dc2707bbdcfe4b2707Brian Paul const GLbitfield origInterpMask = span->interpMask; 955e00ac11d4dd05c56584622dc2707bbdcfe4b2707Brian Paul const GLbitfield origArrayMask = span->arrayMask; 95610f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 957733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul ASSERT(span->end <= MAX_WIDTH); 958b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul ASSERT(span->primitive == GL_POINT || span->primitive == GL_LINE || 959b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul span->primitive == GL_POLYGON || span->primitive == GL_BITMAP); 960733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul ASSERT((span->interpMask | span->arrayMask) & SPAN_INDEX); 9617956292a765910077f50352d7cd0174e1e66d26cBrian Paul ASSERT((span->interpMask & span->arrayMask) == 0); 9627956292a765910077f50352d7cd0174e1e66d26cBrian Paul 963733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (span->arrayMask & SPAN_MASK) { 964733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* mask was initialized by caller, probably glBitmap */ 965733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->writeAll = GL_FALSE; 966733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul } 967733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul else { 968a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul _mesa_memset(span->array->mask, 1, span->end); 969733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->writeAll = GL_TRUE; 97010f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 97110f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 972733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* Clipping */ 973b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul if ((swrast->_RasterMask & CLIP_BIT) || (span->primitive != GL_POLYGON)) { 974733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (!clip_span(ctx, span)) { 97586ca15ece74ccb5a8f4d566a4b2c8024b178d73bBrian Paul return; 976e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 977e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 978e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 979e5b244ff7f984805c1bcc020342f1300f2639c71Brian Paul /* Depth bounds test */ 98031e739a18931fa48454f172818245b0927c8910fBrian Paul if (ctx->Depth.BoundsTest && ctx->DrawBuffer->Visual.depthBits > 0) { 981e5b244ff7f984805c1bcc020342f1300f2639c71Brian Paul if (!_swrast_depth_bounds_test(ctx, span)) { 982e5b244ff7f984805c1bcc020342f1300f2639c71Brian Paul return; 983e5b244ff7f984805c1bcc020342f1300f2639c71Brian Paul } 984e5b244ff7f984805c1bcc020342f1300f2639c71Brian Paul } 985e5b244ff7f984805c1bcc020342f1300f2639c71Brian Paul 986b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul#ifdef DEBUG 987a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul /* Make sure all fragments are within window bounds */ 988b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul if (span->arrayMask & SPAN_XY) { 989a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul GLuint i; 990b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul for (i = 0; i < span->end; i++) { 99177df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul if (span->array->mask[i]) { 99277df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul assert(span->array->x[i] >= ctx->DrawBuffer->_Xmin); 99377df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul assert(span->array->x[i] < ctx->DrawBuffer->_Xmax); 99477df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul assert(span->array->y[i] >= ctx->DrawBuffer->_Ymin); 99577df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul assert(span->array->y[i] < ctx->DrawBuffer->_Ymax); 996b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul } 997b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul } 998b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul } 999b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul#endif 1000b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul 1001e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* Polygon Stippling */ 1002b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul if (ctx->Polygon.StippleFlag && span->primitive == GL_POLYGON) { 100310f30eb43835c57c00783390a02d72daf4f78e26Brian Paul stipple_polygon_span(ctx, span); 1004e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1005e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 1006e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul /* Stencil and Z testing */ 10077956292a765910077f50352d7cd0174e1e66d26cBrian Paul if (ctx->Depth.Test || ctx->Stencil.Enabled) { 10087956292a765910077f50352d7cd0174e1e66d26cBrian Paul if (span->interpMask & SPAN_Z) 100945bc887da226403f2c41077e40ca38b6f60f1359Brian Paul _swrast_span_interpolate_z(ctx, span); 101010f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 10117956292a765910077f50352d7cd0174e1e66d26cBrian Paul if (ctx->Stencil.Enabled) { 101245bc887da226403f2c41077e40ca38b6f60f1359Brian Paul if (!_swrast_stencil_and_ztest_span(ctx, span)) { 10137956292a765910077f50352d7cd0174e1e66d26cBrian Paul span->arrayMask = origArrayMask; 10147956292a765910077f50352d7cd0174e1e66d26cBrian Paul return; 10157956292a765910077f50352d7cd0174e1e66d26cBrian Paul } 10162a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 10177956292a765910077f50352d7cd0174e1e66d26cBrian Paul else { 10187956292a765910077f50352d7cd0174e1e66d26cBrian Paul ASSERT(ctx->Depth.Test); 101945bc887da226403f2c41077e40ca38b6f60f1359Brian Paul if (!_swrast_depth_test_span(ctx, span)) { 1020e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul span->interpMask = origInterpMask; 10217956292a765910077f50352d7cd0174e1e66d26cBrian Paul span->arrayMask = origArrayMask; 10227956292a765910077f50352d7cd0174e1e66d26cBrian Paul return; 10237956292a765910077f50352d7cd0174e1e66d26cBrian Paul } 10242a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 102510f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 102610f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 1027b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul#if FEATURE_ARB_occlusion_query 102823ffc3a85d6172f8a98d17d7f23610bab808d84eBrian Paul if (ctx->Query.CurrentOcclusionObject) { 1029939dd17653245621bf7488803f09418244b7b0b7Brian Paul /* update count of 'passed' fragments */ 103023ffc3a85d6172f8a98d17d7f23610bab808d84eBrian Paul struct gl_query_object *q = ctx->Query.CurrentOcclusionObject; 1031b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul GLuint i; 1032b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul for (i = 0; i < span->end; i++) 103323ffc3a85d6172f8a98d17d7f23610bab808d84eBrian Paul q->Result += span->array->mask[i]; 1034b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul } 1035b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul#endif 1036b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul 10377956292a765910077f50352d7cd0174e1e66d26cBrian Paul /* we have to wait until after occlusion to do this test */ 10387956292a765910077f50352d7cd0174e1e66d26cBrian Paul if (ctx->Color.DrawBuffer == GL_NONE || ctx->Color.IndexMask == 0) { 103910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul /* write no pixels */ 10402a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->arrayMask = origArrayMask; 104110f30eb43835c57c00783390a02d72daf4f78e26Brian Paul return; 104210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 104310f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 10447956292a765910077f50352d7cd0174e1e66d26cBrian Paul /* Interpolate the color indexes if needed */ 1045dcf4c17fb1624af47181c63af4c3ad29f919c17aBrian Paul if (swrast->_FogEnabled || 1046e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul ctx->Color.IndexLogicOpEnabled || 1047e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul ctx->Color.IndexMask != 0xffffffff || 1048e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul (span->arrayMask & SPAN_COVERAGE)) { 1049e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul if (span->interpMask & SPAN_INDEX) { 1050e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul interpolate_indexes(ctx, span); 1051e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul } 10527956292a765910077f50352d7cd0174e1e66d26cBrian Paul } 105310f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 10547956292a765910077f50352d7cd0174e1e66d26cBrian Paul /* Fog */ 1055dcf4c17fb1624af47181c63af4c3ad29f919c17aBrian Paul if (swrast->_FogEnabled) { 105645bc887da226403f2c41077e40ca38b6f60f1359Brian Paul _swrast_fog_ci_span(ctx, span); 1057e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1058e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 10592a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul /* Antialias coverage application */ 10602a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul if (span->arrayMask & SPAN_COVERAGE) { 1061e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul const GLfloat *coverage = span->array->coverage; 106277df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul GLuint *index = span->array->index; 1063e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul GLuint i; 106410f30eb43835c57c00783390a02d72daf4f78e26Brian Paul for (i = 0; i < span->end; i++) { 106577df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul ASSERT(coverage[i] < 16); 106677df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul index[i] = (index[i] & ~0xf) | ((GLuint) coverage[i]); 10675071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paul } 10682a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 10695071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paul 1070ba001224a18fa12792696ef393e708e90092127eBrian Paul /* 1071ba001224a18fa12792696ef393e708e90092127eBrian Paul * Write to renderbuffers 1072ba001224a18fa12792696ef393e708e90092127eBrian Paul */ 1073ba001224a18fa12792696ef393e708e90092127eBrian Paul { 1074ba001224a18fa12792696ef393e708e90092127eBrian Paul struct gl_framebuffer *fb = ctx->DrawBuffer; 1075a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul const GLuint output = 0; /* only frag progs can write to other outputs */ 1076ba001224a18fa12792696ef393e708e90092127eBrian Paul const GLuint numDrawBuffers = fb->_NumColorDrawBuffers[output]; 1077ba001224a18fa12792696ef393e708e90092127eBrian Paul GLuint indexSave[MAX_WIDTH]; 1078ba001224a18fa12792696ef393e708e90092127eBrian Paul GLuint buf; 1079e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul 1080ba001224a18fa12792696ef393e708e90092127eBrian Paul if (numDrawBuffers > 1) { 1081ba001224a18fa12792696ef393e708e90092127eBrian Paul /* save indexes for second, third renderbuffer writes */ 1082ba001224a18fa12792696ef393e708e90092127eBrian Paul _mesa_memcpy(indexSave, span->array->index, 1083ba001224a18fa12792696ef393e708e90092127eBrian Paul span->end * sizeof(indexSave[0])); 1084ba001224a18fa12792696ef393e708e90092127eBrian Paul } 1085e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul 1086ba001224a18fa12792696ef393e708e90092127eBrian Paul for (buf = 0; buf < fb->_NumColorDrawBuffers[output]; buf++) { 1087ba001224a18fa12792696ef393e708e90092127eBrian Paul struct gl_renderbuffer *rb = fb->_ColorDrawBuffers[output][buf]; 1088ba001224a18fa12792696ef393e708e90092127eBrian Paul ASSERT(rb->_BaseFormat == GL_COLOR_INDEX); 10892a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 1090e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul if (ctx->Color.IndexLogicOpEnabled) { 1091f515c78a2320369ead087c4e0efd583f17b4b78bBrian Paul _swrast_logicop_ci_span(ctx, rb, span); 1092e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul } 1093e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul 1094e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul if (ctx->Color.IndexMask != 0xffffffff) { 1095f515c78a2320369ead087c4e0efd583f17b4b78bBrian Paul _swrast_mask_ci_span(ctx, rb, span); 1096e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul } 10972a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 1098ba001224a18fa12792696ef393e708e90092127eBrian Paul if ((span->interpMask & SPAN_INDEX) && span->indexStep == 0) { 1099ba001224a18fa12792696ef393e708e90092127eBrian Paul /* all fragments have same color index */ 1100ba001224a18fa12792696ef393e708e90092127eBrian Paul GLubyte index8; 1101ba001224a18fa12792696ef393e708e90092127eBrian Paul GLushort index16; 1102ba001224a18fa12792696ef393e708e90092127eBrian Paul GLuint index32; 1103ba001224a18fa12792696ef393e708e90092127eBrian Paul void *value; 1104e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul 1105ba001224a18fa12792696ef393e708e90092127eBrian Paul if (rb->DataType == GL_UNSIGNED_BYTE) { 1106ba001224a18fa12792696ef393e708e90092127eBrian Paul index8 = FixedToInt(span->index); 1107ba001224a18fa12792696ef393e708e90092127eBrian Paul value = &index8; 1108ba001224a18fa12792696ef393e708e90092127eBrian Paul } 1109ba001224a18fa12792696ef393e708e90092127eBrian Paul else if (rb->DataType == GL_UNSIGNED_SHORT) { 1110ba001224a18fa12792696ef393e708e90092127eBrian Paul index16 = FixedToInt(span->index); 1111ba001224a18fa12792696ef393e708e90092127eBrian Paul value = &index16; 1112ba001224a18fa12792696ef393e708e90092127eBrian Paul } 1113ba001224a18fa12792696ef393e708e90092127eBrian Paul else { 1114ba001224a18fa12792696ef393e708e90092127eBrian Paul ASSERT(rb->DataType == GL_UNSIGNED_INT); 1115ba001224a18fa12792696ef393e708e90092127eBrian Paul index32 = FixedToInt(span->index); 1116ba001224a18fa12792696ef393e708e90092127eBrian Paul value = &index32; 1117ba001224a18fa12792696ef393e708e90092127eBrian Paul } 1118e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul 1119ba001224a18fa12792696ef393e708e90092127eBrian Paul if (span->arrayMask & SPAN_XY) { 1120ba001224a18fa12792696ef393e708e90092127eBrian Paul rb->PutMonoValues(ctx, rb, span->end, span->array->x, 1121ba001224a18fa12792696ef393e708e90092127eBrian Paul span->array->y, value, span->array->mask); 1122e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul } 1123ba001224a18fa12792696ef393e708e90092127eBrian Paul else { 1124ba001224a18fa12792696ef393e708e90092127eBrian Paul rb->PutMonoRow(ctx, rb, span->end, span->x, span->y, 1125ba001224a18fa12792696ef393e708e90092127eBrian Paul value, span->array->mask); 1126e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul } 1127733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul } 1128733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul else { 1129ba001224a18fa12792696ef393e708e90092127eBrian Paul /* each fragment is a different color */ 1130ba001224a18fa12792696ef393e708e90092127eBrian Paul GLubyte index8[MAX_WIDTH]; 1131ba001224a18fa12792696ef393e708e90092127eBrian Paul GLushort index16[MAX_WIDTH]; 1132ba001224a18fa12792696ef393e708e90092127eBrian Paul void *values; 1133ba001224a18fa12792696ef393e708e90092127eBrian Paul 1134ba001224a18fa12792696ef393e708e90092127eBrian Paul if (rb->DataType == GL_UNSIGNED_BYTE) { 1135ba001224a18fa12792696ef393e708e90092127eBrian Paul GLuint k; 1136ba001224a18fa12792696ef393e708e90092127eBrian Paul for (k = 0; k < span->end; k++) { 1137ba001224a18fa12792696ef393e708e90092127eBrian Paul index8[k] = (GLubyte) span->array->index[k]; 1138ba001224a18fa12792696ef393e708e90092127eBrian Paul } 1139ba001224a18fa12792696ef393e708e90092127eBrian Paul values = index8; 1140ba001224a18fa12792696ef393e708e90092127eBrian Paul } 1141ba001224a18fa12792696ef393e708e90092127eBrian Paul else if (rb->DataType == GL_UNSIGNED_SHORT) { 1142ba001224a18fa12792696ef393e708e90092127eBrian Paul GLuint k; 1143ba001224a18fa12792696ef393e708e90092127eBrian Paul for (k = 0; k < span->end; k++) { 1144ba001224a18fa12792696ef393e708e90092127eBrian Paul index16[k] = (GLushort) span->array->index[k]; 1145ba001224a18fa12792696ef393e708e90092127eBrian Paul } 1146ba001224a18fa12792696ef393e708e90092127eBrian Paul values = index16; 1147ba001224a18fa12792696ef393e708e90092127eBrian Paul } 1148ba001224a18fa12792696ef393e708e90092127eBrian Paul else { 1149ba001224a18fa12792696ef393e708e90092127eBrian Paul ASSERT(rb->DataType == GL_UNSIGNED_INT); 1150ba001224a18fa12792696ef393e708e90092127eBrian Paul values = span->array->index; 1151ba001224a18fa12792696ef393e708e90092127eBrian Paul } 1152e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul 1153ba001224a18fa12792696ef393e708e90092127eBrian Paul if (span->arrayMask & SPAN_XY) { 1154ba001224a18fa12792696ef393e708e90092127eBrian Paul rb->PutValues(ctx, rb, span->end, 1155ba001224a18fa12792696ef393e708e90092127eBrian Paul span->array->x, span->array->y, 1156ba001224a18fa12792696ef393e708e90092127eBrian Paul values, span->array->mask); 1157ba001224a18fa12792696ef393e708e90092127eBrian Paul } 1158ba001224a18fa12792696ef393e708e90092127eBrian Paul else { 1159ba001224a18fa12792696ef393e708e90092127eBrian Paul rb->PutRow(ctx, rb, span->end, span->x, span->y, 1160e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul values, span->array->mask); 1161ba001224a18fa12792696ef393e708e90092127eBrian Paul } 1162e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul } 1163ba001224a18fa12792696ef393e708e90092127eBrian Paul 1164ba001224a18fa12792696ef393e708e90092127eBrian Paul if (buf + 1 < numDrawBuffers) { 1165ba001224a18fa12792696ef393e708e90092127eBrian Paul /* restore original span values */ 1166ba001224a18fa12792696ef393e708e90092127eBrian Paul _mesa_memcpy(span->array->index, indexSave, 1167ba001224a18fa12792696ef393e708e90092127eBrian Paul span->end * sizeof(indexSave[0])); 1168733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul } 1169ba001224a18fa12792696ef393e708e90092127eBrian Paul } /* for buf */ 1170e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 11712a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 11727956292a765910077f50352d7cd0174e1e66d26cBrian Paul span->interpMask = origInterpMask; 11732a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->arrayMask = origArrayMask; 1174e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell} 1175e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 1176e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 117779c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/** 1178e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Add specular color to base color. This is used only when 1179f1e236987829393c81dc86ea19cb49eefe190317Brian Paul * GL_LIGHT_MODEL_COLOR_CONTROL = GL_SEPARATE_SPECULAR_COLOR. 1180e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */ 1181f614a6190562e550257afca0d04e3846648942e8Brian Paulstatic INLINE void 1182cdb27e8242215271364602995d85607cfc06d441Brian Pauladd_specular(GLcontext *ctx, SWspan *span) 1183e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell{ 1184d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul switch (span->array->ChanType) { 1185d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul case GL_UNSIGNED_BYTE: 1186d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul { 1187d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul GLubyte (*rgba)[4] = span->array->color.sz1.rgba; 1188d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul GLubyte (*spec)[4] = span->array->color.sz1.spec; 1189d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul GLuint i; 1190d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul for (i = 0; i < span->end; i++) { 1191d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul GLint r = rgba[i][RCOMP] + spec[i][RCOMP]; 1192d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul GLint g = rgba[i][GCOMP] + spec[i][GCOMP]; 1193d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul GLint b = rgba[i][BCOMP] + spec[i][BCOMP]; 1194d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul GLint a = rgba[i][ACOMP] + spec[i][ACOMP]; 1195d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul rgba[i][RCOMP] = MIN2(r, 255); 1196d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul rgba[i][GCOMP] = MIN2(g, 255); 1197d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul rgba[i][BCOMP] = MIN2(b, 255); 1198d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul rgba[i][ACOMP] = MIN2(a, 255); 1199d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul } 1200d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul } 1201d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul break; 1202d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul case GL_UNSIGNED_SHORT: 1203d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul { 1204d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul GLushort (*rgba)[4] = span->array->color.sz2.rgba; 1205d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul GLushort (*spec)[4] = span->array->color.sz2.spec; 1206d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul GLuint i; 1207d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul for (i = 0; i < span->end; i++) { 1208d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul GLint r = rgba[i][RCOMP] + spec[i][RCOMP]; 1209d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul GLint g = rgba[i][GCOMP] + spec[i][GCOMP]; 1210d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul GLint b = rgba[i][BCOMP] + spec[i][BCOMP]; 1211d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul GLint a = rgba[i][ACOMP] + spec[i][ACOMP]; 1212d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul rgba[i][RCOMP] = MIN2(r, 65535); 1213d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul rgba[i][GCOMP] = MIN2(g, 65535); 1214d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul rgba[i][BCOMP] = MIN2(b, 65535); 1215d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul rgba[i][ACOMP] = MIN2(a, 65535); 1216d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul } 1217d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul } 1218d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul break; 1219d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul case GL_FLOAT: 1220d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul { 1221d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul GLfloat (*rgba)[4] = span->array->color.sz4.rgba; 1222d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul GLfloat (*spec)[4] = span->array->color.sz4.spec; 1223d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul GLuint i; 1224d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul for (i = 0; i < span->end; i++) { 1225d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul rgba[i][RCOMP] += spec[i][RCOMP]; 1226d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul rgba[i][GCOMP] += spec[i][GCOMP]; 1227d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul rgba[i][BCOMP] += spec[i][BCOMP]; 1228d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul rgba[i][ACOMP] += spec[i][ACOMP]; 1229d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul } 1230d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul } 1231d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul break; 1232d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul default: 1233d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul _mesa_problem(ctx, "Invalid datatype in add_specular"); 1234e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1235e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell} 1236e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 1237e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 123879c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/** 1239b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul * Apply antialiasing coverage value to alpha values. 1240b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul */ 1241f614a6190562e550257afca0d04e3846648942e8Brian Paulstatic INLINE void 1242b88af5b4681d2085cd784b930dc259b66a55347eBrian Paulapply_aa_coverage(SWspan *span) 1243b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul{ 1244b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul const GLfloat *coverage = span->array->coverage; 1245b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul GLuint i; 1246b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul if (span->array->ChanType == GL_UNSIGNED_BYTE) { 1247b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul GLubyte (*rgba)[4] = span->array->color.sz1.rgba; 1248b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul for (i = 0; i < span->end; i++) { 1249e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul const GLfloat a = rgba[i][ACOMP] * coverage[i]; 1250e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul rgba[i][ACOMP] = (GLubyte) CLAMP(a, 0.0, 255.0); 1251b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul ASSERT(coverage[i] >= 0.0); 1252b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul ASSERT(coverage[i] <= 1.0); 1253b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul } 1254b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul } 1255b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul else if (span->array->ChanType == GL_UNSIGNED_SHORT) { 1256b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul GLushort (*rgba)[4] = span->array->color.sz2.rgba; 1257b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul for (i = 0; i < span->end; i++) { 1258e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul const GLfloat a = rgba[i][ACOMP] * coverage[i]; 1259e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul rgba[i][ACOMP] = (GLushort) CLAMP(a, 0.0, 65535.0); 1260b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul } 1261b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul } 1262b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul else { 1263b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul GLfloat (*rgba)[4] = span->array->color.sz4.rgba; 1264b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul for (i = 0; i < span->end; i++) { 1265b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul rgba[i][ACOMP] = rgba[i][ACOMP] * coverage[i]; 1266b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul } 1267b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul } 1268b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul} 1269b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul 1270b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul 1271b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul/** 127231293910b4e982f2ef54d79aff78f2f854121da1Brian Paul * Clamp span's float colors to [0,1] 127331293910b4e982f2ef54d79aff78f2f854121da1Brian Paul */ 1274f614a6190562e550257afca0d04e3846648942e8Brian Paulstatic INLINE void 127531293910b4e982f2ef54d79aff78f2f854121da1Brian Paulclamp_colors(SWspan *span) 127631293910b4e982f2ef54d79aff78f2f854121da1Brian Paul{ 127731293910b4e982f2ef54d79aff78f2f854121da1Brian Paul GLfloat (*rgba)[4] = span->array->color.sz4.rgba; 127831293910b4e982f2ef54d79aff78f2f854121da1Brian Paul GLuint i; 127931293910b4e982f2ef54d79aff78f2f854121da1Brian Paul ASSERT(span->array->ChanType == GL_FLOAT); 128031293910b4e982f2ef54d79aff78f2f854121da1Brian Paul for (i = 0; i < span->end; i++) { 128131293910b4e982f2ef54d79aff78f2f854121da1Brian Paul rgba[i][RCOMP] = CLAMP(rgba[i][RCOMP], 0.0F, 1.0F); 128231293910b4e982f2ef54d79aff78f2f854121da1Brian Paul rgba[i][GCOMP] = CLAMP(rgba[i][GCOMP], 0.0F, 1.0F); 128331293910b4e982f2ef54d79aff78f2f854121da1Brian Paul rgba[i][BCOMP] = CLAMP(rgba[i][BCOMP], 0.0F, 1.0F); 128431293910b4e982f2ef54d79aff78f2f854121da1Brian Paul rgba[i][ACOMP] = CLAMP(rgba[i][ACOMP], 0.0F, 1.0F); 128531293910b4e982f2ef54d79aff78f2f854121da1Brian Paul } 128631293910b4e982f2ef54d79aff78f2f854121da1Brian Paul} 128731293910b4e982f2ef54d79aff78f2f854121da1Brian Paul 128831293910b4e982f2ef54d79aff78f2f854121da1Brian Paul 128931293910b4e982f2ef54d79aff78f2f854121da1Brian Paul/** 1290d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul * Convert the span's color arrays to the given type. 1291d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul */ 1292f614a6190562e550257afca0d04e3846648942e8Brian Paulstatic INLINE void 1293cdb27e8242215271364602995d85607cfc06d441Brian Paulconvert_color_type(GLcontext *ctx, SWspan *span, GLenum newType) 1294d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul{ 1295f971e24cf0341dd2779196a0836327b74fc82336Brian Paul GLvoid *src, *dst; 1296f971e24cf0341dd2779196a0836327b74fc82336Brian Paul if (span->array->ChanType == GL_UNSIGNED_BYTE) { 1297f971e24cf0341dd2779196a0836327b74fc82336Brian Paul src = span->array->color.sz1.rgba; 1298f971e24cf0341dd2779196a0836327b74fc82336Brian Paul } 1299f971e24cf0341dd2779196a0836327b74fc82336Brian Paul else if (span->array->ChanType == GL_UNSIGNED_BYTE) { 1300f971e24cf0341dd2779196a0836327b74fc82336Brian Paul src = span->array->color.sz2.rgba; 1301f971e24cf0341dd2779196a0836327b74fc82336Brian Paul } 1302f971e24cf0341dd2779196a0836327b74fc82336Brian Paul else { 1303f971e24cf0341dd2779196a0836327b74fc82336Brian Paul src = span->array->color.sz4.rgba; 1304f971e24cf0341dd2779196a0836327b74fc82336Brian Paul } 1305f971e24cf0341dd2779196a0836327b74fc82336Brian Paul if (newType == GL_UNSIGNED_BYTE) { 1306f971e24cf0341dd2779196a0836327b74fc82336Brian Paul dst = span->array->color.sz1.rgba; 1307f971e24cf0341dd2779196a0836327b74fc82336Brian Paul } 1308f971e24cf0341dd2779196a0836327b74fc82336Brian Paul else if (newType == GL_UNSIGNED_BYTE) { 1309f971e24cf0341dd2779196a0836327b74fc82336Brian Paul dst = span->array->color.sz2.rgba; 1310f971e24cf0341dd2779196a0836327b74fc82336Brian Paul } 1311f971e24cf0341dd2779196a0836327b74fc82336Brian Paul else { 1312f971e24cf0341dd2779196a0836327b74fc82336Brian Paul dst = span->array->color.sz4.rgba; 1313f971e24cf0341dd2779196a0836327b74fc82336Brian Paul } 1314d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul 1315f971e24cf0341dd2779196a0836327b74fc82336Brian Paul _mesa_convert_colors(span->array->ChanType, src, 1316f971e24cf0341dd2779196a0836327b74fc82336Brian Paul newType, dst, 1317f971e24cf0341dd2779196a0836327b74fc82336Brian Paul span->end, span->array->mask); 1318d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul 1319d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul span->array->ChanType = newType; 1320d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul} 1321d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul 1322d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul 1323d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul 1324d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul/** 132561c89be3135cedc795e48d36283769298e250837Brian Paul * Apply fragment shader, fragment program or normal texturing to span. 132661c89be3135cedc795e48d36283769298e250837Brian Paul */ 1327f614a6190562e550257afca0d04e3846648942e8Brian Paulstatic INLINE void 132861c89be3135cedc795e48d36283769298e250837Brian Paulshade_texture_span(GLcontext *ctx, SWspan *span) 132961c89be3135cedc795e48d36283769298e250837Brian Paul{ 133061c89be3135cedc795e48d36283769298e250837Brian Paul /* Now we need the rgba array, fill it in if needed */ 133161c89be3135cedc795e48d36283769298e250837Brian Paul if (span->interpMask & SPAN_RGBA) 133261c89be3135cedc795e48d36283769298e250837Brian Paul interpolate_colors(span); 133361c89be3135cedc795e48d36283769298e250837Brian Paul 1334f614a6190562e550257afca0d04e3846648942e8Brian Paul if (ctx->Texture._EnabledCoordUnits && (span->interpMask & SPAN_TEXTURE)) 1335f614a6190562e550257afca0d04e3846648942e8Brian Paul interpolate_texcoords(ctx, span); 1336f614a6190562e550257afca0d04e3846648942e8Brian Paul 133761c89be3135cedc795e48d36283769298e250837Brian Paul if (ctx->ShaderObjects._FragmentShaderPresent || 133861c89be3135cedc795e48d36283769298e250837Brian Paul ctx->FragmentProgram._Enabled || 133961c89be3135cedc795e48d36283769298e250837Brian Paul ctx->ATIFragmentShader._Enabled) { 134061c89be3135cedc795e48d36283769298e250837Brian Paul 134161c89be3135cedc795e48d36283769298e250837Brian Paul /* use float colors if running a fragment program or shader */ 134261c89be3135cedc795e48d36283769298e250837Brian Paul const GLenum oldType = span->array->ChanType; 134361c89be3135cedc795e48d36283769298e250837Brian Paul const GLenum newType = GL_FLOAT; 134461c89be3135cedc795e48d36283769298e250837Brian Paul if (oldType != newType) { 134561c89be3135cedc795e48d36283769298e250837Brian Paul GLvoid *src = (oldType == GL_UNSIGNED_BYTE) 134661c89be3135cedc795e48d36283769298e250837Brian Paul ? (GLvoid *) span->array->color.sz1.rgba 134761c89be3135cedc795e48d36283769298e250837Brian Paul : (GLvoid *) span->array->color.sz2.rgba; 134861c89be3135cedc795e48d36283769298e250837Brian Paul _mesa_convert_colors(oldType, src, 134961c89be3135cedc795e48d36283769298e250837Brian Paul newType, span->array->color.sz4.rgba, 135061c89be3135cedc795e48d36283769298e250837Brian Paul span->end, span->array->mask); 135161c89be3135cedc795e48d36283769298e250837Brian Paul span->array->ChanType = newType; 135261c89be3135cedc795e48d36283769298e250837Brian Paul } 135361c89be3135cedc795e48d36283769298e250837Brian Paul 135461c89be3135cedc795e48d36283769298e250837Brian Paul /* fragment programs/shaders may need specular, fog and Z coords */ 135561c89be3135cedc795e48d36283769298e250837Brian Paul if (span->interpMask & SPAN_SPEC) 135661c89be3135cedc795e48d36283769298e250837Brian Paul interpolate_specular(span); 135761c89be3135cedc795e48d36283769298e250837Brian Paul 135861c89be3135cedc795e48d36283769298e250837Brian Paul if (span->interpMask & SPAN_FOG) 135961c89be3135cedc795e48d36283769298e250837Brian Paul interpolate_fog(ctx, span); 136061c89be3135cedc795e48d36283769298e250837Brian Paul 136161c89be3135cedc795e48d36283769298e250837Brian Paul if (span->interpMask & SPAN_Z) 136261c89be3135cedc795e48d36283769298e250837Brian Paul _swrast_span_interpolate_z (ctx, span); 136361c89be3135cedc795e48d36283769298e250837Brian Paul 136461c89be3135cedc795e48d36283769298e250837Brian Paul /* Run fragment program/shader now */ 136561c89be3135cedc795e48d36283769298e250837Brian Paul if (ctx->ShaderObjects._FragmentShaderPresent) { 1366828d15a6e0907fe4bb7c564d453a2b1a05f109bcBrian Paul interpolate_varying(ctx, span); 1367828d15a6e0907fe4bb7c564d453a2b1a05f109bcBrian Paul _swrast_exec_arbshader(ctx, span); 136861c89be3135cedc795e48d36283769298e250837Brian Paul } 136961c89be3135cedc795e48d36283769298e250837Brian Paul else if (ctx->FragmentProgram._Enabled) { 137061c89be3135cedc795e48d36283769298e250837Brian Paul _swrast_exec_fragment_program(ctx, span); 137161c89be3135cedc795e48d36283769298e250837Brian Paul } 137261c89be3135cedc795e48d36283769298e250837Brian Paul else { 137361c89be3135cedc795e48d36283769298e250837Brian Paul ASSERT(ctx->ATIFragmentShader._Enabled); 137461c89be3135cedc795e48d36283769298e250837Brian Paul _swrast_exec_fragment_shader(ctx, span); 137561c89be3135cedc795e48d36283769298e250837Brian Paul } 137661c89be3135cedc795e48d36283769298e250837Brian Paul } 137761c89be3135cedc795e48d36283769298e250837Brian Paul else if (ctx->Texture._EnabledUnits && (span->arrayMask & SPAN_TEXTURE)) { 137861c89be3135cedc795e48d36283769298e250837Brian Paul /* conventional texturing */ 137961c89be3135cedc795e48d36283769298e250837Brian Paul _swrast_texture_span(ctx, span); 138061c89be3135cedc795e48d36283769298e250837Brian Paul } 138161c89be3135cedc795e48d36283769298e250837Brian Paul} 138261c89be3135cedc795e48d36283769298e250837Brian Paul 138361c89be3135cedc795e48d36283769298e250837Brian Paul 138461c89be3135cedc795e48d36283769298e250837Brian Paul 138561c89be3135cedc795e48d36283769298e250837Brian Paul/** 1386a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul * Apply all the per-fragment operations to a span. 1387a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul * This now includes texturing (_swrast_write_texture_span() is history). 1388f1e236987829393c81dc86ea19cb49eefe190317Brian Paul * This function may modify any of the array values in the span. 13897956292a765910077f50352d7cd0174e1e66d26cBrian Paul * span->interpMask and span->arrayMask may be changed but will be restored 13907956292a765910077f50352d7cd0174e1e66d26cBrian Paul * to their original values before returning. 139178940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul */ 139278940758e90069ceaca2b6cddb6438488fbad5ccBrian Paulvoid 1393cdb27e8242215271364602995d85607cfc06d441Brian Paul_swrast_write_rgba_span( GLcontext *ctx, SWspan *span) 139478940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul{ 139561c89be3135cedc795e48d36283769298e250837Brian Paul const SWcontext *swrast = SWRAST_CONTEXT(ctx); 139678940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul const GLuint colorMask = *((GLuint *) ctx->Color.ColorMask); 1397e00ac11d4dd05c56584622dc2707bbdcfe4b2707Brian Paul const GLbitfield origInterpMask = span->interpMask; 1398e00ac11d4dd05c56584622dc2707bbdcfe4b2707Brian Paul const GLbitfield origArrayMask = span->arrayMask; 1399c3caaa3dd45809e672177ab322445fe51d03af25Brian Paul const GLenum chanType = span->array->ChanType; 140061c89be3135cedc795e48d36283769298e250837Brian Paul const GLboolean shader 140161c89be3135cedc795e48d36283769298e250837Brian Paul = ctx->FragmentProgram._Enabled 140261c89be3135cedc795e48d36283769298e250837Brian Paul || ctx->ShaderObjects._FragmentShaderPresent 140361c89be3135cedc795e48d36283769298e250837Brian Paul || ctx->ATIFragmentShader._Enabled; 140461c89be3135cedc795e48d36283769298e250837Brian Paul const GLboolean shaderOrTexture = shader || ctx->Texture._EnabledUnits; 1405bb19e64d12eaf27e2adc3faac7e09555bb66d724Brian Paul GLboolean deferredTexture; 140661c89be3135cedc795e48d36283769298e250837Brian Paul 1407bb19e64d12eaf27e2adc3faac7e09555bb66d724Brian Paul /* 1408bb19e64d12eaf27e2adc3faac7e09555bb66d724Brian Paul printf("%s() interp 0x%x array 0x%x\n", __FUNCTION__, 1409bb19e64d12eaf27e2adc3faac7e09555bb66d724Brian Paul span->interpMask, span->arrayMask); 1410bb19e64d12eaf27e2adc3faac7e09555bb66d724Brian Paul */ 1411f1e236987829393c81dc86ea19cb49eefe190317Brian Paul 141231293910b4e982f2ef54d79aff78f2f854121da1Brian Paul ASSERT(span->primitive == GL_POINT || 141331293910b4e982f2ef54d79aff78f2f854121da1Brian Paul span->primitive == GL_LINE || 141431293910b4e982f2ef54d79aff78f2f854121da1Brian Paul span->primitive == GL_POLYGON || 141531293910b4e982f2ef54d79aff78f2f854121da1Brian Paul span->primitive == GL_BITMAP); 1416733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul ASSERT(span->end <= MAX_WIDTH); 14177956292a765910077f50352d7cd0174e1e66d26cBrian Paul ASSERT((span->interpMask & span->arrayMask) == 0); 141831293910b4e982f2ef54d79aff78f2f854121da1Brian Paul ASSERT((span->interpMask & SPAN_RGBA) ^ (span->arrayMask & SPAN_RGBA)); 141978940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul 1420bb19e64d12eaf27e2adc3faac7e09555bb66d724Brian Paul /* check for conditions that prevent deferred shading */ 1421bb19e64d12eaf27e2adc3faac7e09555bb66d724Brian Paul if (ctx->Color.AlphaEnabled) { 1422bb19e64d12eaf27e2adc3faac7e09555bb66d724Brian Paul /* alpha test depends on post-texture/shader colors */ 1423bb19e64d12eaf27e2adc3faac7e09555bb66d724Brian Paul deferredTexture = GL_FALSE; 1424bb19e64d12eaf27e2adc3faac7e09555bb66d724Brian Paul } 1425bb19e64d12eaf27e2adc3faac7e09555bb66d724Brian Paul else if (shaderOrTexture) { 1426bb19e64d12eaf27e2adc3faac7e09555bb66d724Brian Paul if (ctx->FragmentProgram._Enabled && 1427bb19e64d12eaf27e2adc3faac7e09555bb66d724Brian Paul (ctx->FragmentProgram.Current->Base.OutputsWritten 1428bb19e64d12eaf27e2adc3faac7e09555bb66d724Brian Paul & (1 << FRAG_RESULT_DEPR))) { 1429bb19e64d12eaf27e2adc3faac7e09555bb66d724Brian Paul /* Z comes from fragment program */ 1430bb19e64d12eaf27e2adc3faac7e09555bb66d724Brian Paul deferredTexture = GL_FALSE; 1431bb19e64d12eaf27e2adc3faac7e09555bb66d724Brian Paul } 1432bb19e64d12eaf27e2adc3faac7e09555bb66d724Brian Paul else if (ctx->ShaderObjects._FragmentShaderPresent) { 1433bb19e64d12eaf27e2adc3faac7e09555bb66d724Brian Paul /* XXX how do we test if Z is written by shader? */ 1434bb19e64d12eaf27e2adc3faac7e09555bb66d724Brian Paul deferredTexture = GL_FALSE; /* never defer to be safe */ 1435bb19e64d12eaf27e2adc3faac7e09555bb66d724Brian Paul } 1436bb19e64d12eaf27e2adc3faac7e09555bb66d724Brian Paul else { 1437bb19e64d12eaf27e2adc3faac7e09555bb66d724Brian Paul /* ATI frag shader or conventional texturing */ 1438bb19e64d12eaf27e2adc3faac7e09555bb66d724Brian Paul deferredTexture = GL_TRUE; 1439bb19e64d12eaf27e2adc3faac7e09555bb66d724Brian Paul } 1440bb19e64d12eaf27e2adc3faac7e09555bb66d724Brian Paul } 1441bb19e64d12eaf27e2adc3faac7e09555bb66d724Brian Paul else { 1442bb19e64d12eaf27e2adc3faac7e09555bb66d724Brian Paul /* no texturing or shadering */ 1443bb19e64d12eaf27e2adc3faac7e09555bb66d724Brian Paul deferredTexture = GL_FALSE; 1444bb19e64d12eaf27e2adc3faac7e09555bb66d724Brian Paul } 1445ceb39f4f8dc4863fde17d668c752533a2184476eBrian Paul 1446bb19e64d12eaf27e2adc3faac7e09555bb66d724Brian Paul /* Fragment write masks */ 1447733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (span->arrayMask & SPAN_MASK) { 1448733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* mask was initialized by caller, probably glBitmap */ 1449733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->writeAll = GL_FALSE; 1450733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul } 1451733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul else { 1452a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul _mesa_memset(span->array->mask, 1, span->end); 1453733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->writeAll = GL_TRUE; 145478940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul } 145578940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul 1456a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul /* Clip to window/scissor box */ 1457b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul if ((swrast->_RasterMask & CLIP_BIT) || (span->primitive != GL_POLYGON)) { 1458733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (!clip_span(ctx, span)) { 1459733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul return; 146078940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul } 146178940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul } 146278940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul 1463b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul#ifdef DEBUG 1464a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul /* Make sure all fragments are within window bounds */ 1465b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul if (span->arrayMask & SPAN_XY) { 1466a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul GLuint i; 1467b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul for (i = 0; i < span->end; i++) { 146877df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul if (span->array->mask[i]) { 146977df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul assert(span->array->x[i] >= ctx->DrawBuffer->_Xmin); 147077df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul assert(span->array->x[i] < ctx->DrawBuffer->_Xmax); 147177df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul assert(span->array->y[i] >= ctx->DrawBuffer->_Ymin); 147277df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul assert(span->array->y[i] < ctx->DrawBuffer->_Ymax); 1473b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul } 1474b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul } 1475b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul } 1476b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul#endif 1477b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul 147878940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul /* Polygon Stippling */ 1479b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul if (ctx->Polygon.StippleFlag && span->primitive == GL_POLYGON) { 1480733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul stipple_polygon_span(ctx, span); 148178940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul } 148278940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul 148332340aea1308153dad5c105fc0748aea1e4c37eeBrian Paul /* This is the normal place to compute the resulting fragment color/Z. 148432340aea1308153dad5c105fc0748aea1e4c37eeBrian Paul * As an optimization, we try to defer this until after Z/stencil 148532340aea1308153dad5c105fc0748aea1e4c37eeBrian Paul * testing in order to try to avoid computing colors that we won't 148632340aea1308153dad5c105fc0748aea1e4c37eeBrian Paul * actually need. 1487a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul */ 148861c89be3135cedc795e48d36283769298e250837Brian Paul if (shaderOrTexture && !deferredTexture) { 148961c89be3135cedc795e48d36283769298e250837Brian Paul shade_texture_span(ctx, span); 149061c89be3135cedc795e48d36283769298e250837Brian Paul } 1491c3caaa3dd45809e672177ab322445fe51d03af25Brian Paul 149261c89be3135cedc795e48d36283769298e250837Brian Paul /* Do the alpha test */ 149361c89be3135cedc795e48d36283769298e250837Brian Paul if (ctx->Color.AlphaEnabled) { 149461c89be3135cedc795e48d36283769298e250837Brian Paul if (!_swrast_alpha_test(ctx, span)) { 149561c89be3135cedc795e48d36283769298e250837Brian Paul goto end; 149678940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul } 149778940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul } 149878940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul 1499f1e236987829393c81dc86ea19cb49eefe190317Brian Paul /* Stencil and Z testing */ 1500f1e236987829393c81dc86ea19cb49eefe190317Brian Paul if (ctx->Stencil.Enabled || ctx->Depth.Test) { 1501f1e236987829393c81dc86ea19cb49eefe190317Brian Paul if (span->interpMask & SPAN_Z) 150245bc887da226403f2c41077e40ca38b6f60f1359Brian Paul _swrast_span_interpolate_z(ctx, span); 150378940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul 1504e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul if (ctx->Stencil.Enabled && ctx->DrawBuffer->Visual.stencilBits > 0) { 1505a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul /* Combined Z/stencil tests */ 150645bc887da226403f2c41077e40ca38b6f60f1359Brian Paul if (!_swrast_stencil_and_ztest_span(ctx, span)) { 1507c3caaa3dd45809e672177ab322445fe51d03af25Brian Paul goto end; 1508f1e236987829393c81dc86ea19cb49eefe190317Brian Paul } 150971340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 1510e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul else if (ctx->DrawBuffer->Visual.depthBits > 0) { 1511a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul /* Just regular depth testing */ 1512f1e236987829393c81dc86ea19cb49eefe190317Brian Paul ASSERT(ctx->Depth.Test); 1513f1e236987829393c81dc86ea19cb49eefe190317Brian Paul ASSERT(span->arrayMask & SPAN_Z); 151445bc887da226403f2c41077e40ca38b6f60f1359Brian Paul if (!_swrast_depth_test_span(ctx, span)) { 1515c3caaa3dd45809e672177ab322445fe51d03af25Brian Paul goto end; 1516f1e236987829393c81dc86ea19cb49eefe190317Brian Paul } 151771340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 151871340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 151971340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul 1520b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul#if FEATURE_ARB_occlusion_query 152123ffc3a85d6172f8a98d17d7f23610bab808d84eBrian Paul if (ctx->Query.CurrentOcclusionObject) { 1522939dd17653245621bf7488803f09418244b7b0b7Brian Paul /* update count of 'passed' fragments */ 152323ffc3a85d6172f8a98d17d7f23610bab808d84eBrian Paul struct gl_query_object *q = ctx->Query.CurrentOcclusionObject; 1524b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul GLuint i; 1525b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul for (i = 0; i < span->end; i++) 152623ffc3a85d6172f8a98d17d7f23610bab808d84eBrian Paul q->Result += span->array->mask[i]; 1527b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul } 1528b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul#endif 1529b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul 1530a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul /* We had to wait until now to check for glColorMask(0,0,0,0) because of 1531f1e236987829393c81dc86ea19cb49eefe190317Brian Paul * the occlusion test. 1532f1e236987829393c81dc86ea19cb49eefe190317Brian Paul */ 1533f1e236987829393c81dc86ea19cb49eefe190317Brian Paul if (colorMask == 0x0) { 1534c3caaa3dd45809e672177ab322445fe51d03af25Brian Paul goto end; 153571340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 153671340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul 153732340aea1308153dad5c105fc0748aea1e4c37eeBrian Paul /* If we were able to defer fragment color computation to now, there's 153832340aea1308153dad5c105fc0748aea1e4c37eeBrian Paul * a good chance that many fragments will have already been killed by 153932340aea1308153dad5c105fc0748aea1e4c37eeBrian Paul * Z/stencil testing. 1540a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul */ 154132340aea1308153dad5c105fc0748aea1e4c37eeBrian Paul if (deferredTexture) { 154261c89be3135cedc795e48d36283769298e250837Brian Paul ASSERT(shaderOrTexture); 154361c89be3135cedc795e48d36283769298e250837Brian Paul shade_texture_span(ctx, span); 154461c89be3135cedc795e48d36283769298e250837Brian Paul } 1545d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul 154661c89be3135cedc795e48d36283769298e250837Brian Paul if ((span->arrayMask & SPAN_RGBA) == 0) { 154761c89be3135cedc795e48d36283769298e250837Brian Paul interpolate_colors(span); 154871340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 154971340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul 1550f1e236987829393c81dc86ea19cb49eefe190317Brian Paul ASSERT(span->arrayMask & SPAN_RGBA); 15512ef866d1fc0a5cc5ef8543d65744dfd4da4dbbafBrian Paul 155261c89be3135cedc795e48d36283769298e250837Brian Paul if (!shader) { 1553dfe508ca7af1a6d1099cd65e257512ed1e17d893Brian Paul /* Add base and specular colors */ 1554dfe508ca7af1a6d1099cd65e257512ed1e17d893Brian Paul if (ctx->Fog.ColorSumEnabled || 1555dfe508ca7af1a6d1099cd65e257512ed1e17d893Brian Paul (ctx->Light.Enabled && 1556dfe508ca7af1a6d1099cd65e257512ed1e17d893Brian Paul ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR)) { 1557dfe508ca7af1a6d1099cd65e257512ed1e17d893Brian Paul if (span->interpMask & SPAN_SPEC) { 1558e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul interpolate_specular(span); 1559dfe508ca7af1a6d1099cd65e257512ed1e17d893Brian Paul } 1560a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul if (span->arrayMask & SPAN_SPEC) { 1561d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul add_specular(ctx, span); 1562a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul } 1563a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul else { 1564a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul /* We probably added the base/specular colors during the 1565a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul * vertex stage! 1566a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul */ 1567a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul } 156871340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 156971340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 157071340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul 15716e1666437ea091ecc50ab2b56d87129318f641d2Brian Paul /* Fog */ 157209da0b8e6621a831e3eeb9381430f2bed18a22adBrian Paul if (swrast->_FogEnabled) { 157345bc887da226403f2c41077e40ca38b6f60f1359Brian Paul _swrast_fog_rgba_span(ctx, span); 157471340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 1575f1e236987829393c81dc86ea19cb49eefe190317Brian Paul 157671340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul /* Antialias coverage application */ 15772a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul if (span->arrayMask & SPAN_COVERAGE) { 1578b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul apply_aa_coverage(span); 157971340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 158071340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul 1581ba3da6154c324cc916845bc5de3de077d0b59ffcBrian Paul /* Clamp color/alpha values over the range [0.0, 1.0] before storage */ 158231293910b4e982f2ef54d79aff78f2f854121da1Brian Paul if (ctx->Color.ClampFragmentColor && 158331293910b4e982f2ef54d79aff78f2f854121da1Brian Paul span->array->ChanType == GL_FLOAT) { 158431293910b4e982f2ef54d79aff78f2f854121da1Brian Paul clamp_colors(span); 1585ba3da6154c324cc916845bc5de3de077d0b59ffcBrian Paul } 1586ba3da6154c324cc916845bc5de3de077d0b59ffcBrian Paul 1587ba001224a18fa12792696ef393e708e90092127eBrian Paul /* 1588ba001224a18fa12792696ef393e708e90092127eBrian Paul * Write to renderbuffers 1589ba001224a18fa12792696ef393e708e90092127eBrian Paul */ 1590ba001224a18fa12792696ef393e708e90092127eBrian Paul { 1591ba001224a18fa12792696ef393e708e90092127eBrian Paul struct gl_framebuffer *fb = ctx->DrawBuffer; 1592a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul const GLuint output = 0; /* only frag progs can write to other outputs */ 1593ba001224a18fa12792696ef393e708e90092127eBrian Paul const GLuint numDrawBuffers = fb->_NumColorDrawBuffers[output]; 1594ba001224a18fa12792696ef393e708e90092127eBrian Paul GLchan rgbaSave[MAX_WIDTH][4]; 1595ba001224a18fa12792696ef393e708e90092127eBrian Paul GLuint buf; 1596e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul 1597d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul if (numDrawBuffers > 0) { 1598d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul if (fb->_ColorDrawBuffers[output][0]->DataType 1599d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul != span->array->ChanType) { 1600d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul convert_color_type(ctx, span, 1601d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul fb->_ColorDrawBuffers[output][0]->DataType); 1602d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul } 1603d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul } 1604d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul 1605ba001224a18fa12792696ef393e708e90092127eBrian Paul if (numDrawBuffers > 1) { 1606ba001224a18fa12792696ef393e708e90092127eBrian Paul /* save colors for second, third renderbuffer writes */ 1607ba001224a18fa12792696ef393e708e90092127eBrian Paul _mesa_memcpy(rgbaSave, span->array->rgba, 1608ba001224a18fa12792696ef393e708e90092127eBrian Paul 4 * span->end * sizeof(GLchan)); 160971340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 161071340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul 1611ba001224a18fa12792696ef393e708e90092127eBrian Paul for (buf = 0; buf < numDrawBuffers; buf++) { 1612ba001224a18fa12792696ef393e708e90092127eBrian Paul struct gl_renderbuffer *rb = fb->_ColorDrawBuffers[output][buf]; 1613f971e24cf0341dd2779196a0836327b74fc82336Brian Paul ASSERT(rb->_BaseFormat == GL_RGBA || rb->_BaseFormat == GL_RGB); 161471340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul 1615ba001224a18fa12792696ef393e708e90092127eBrian Paul if (ctx->Color._LogicOpEnabled) { 1616f515c78a2320369ead087c4e0efd583f17b4b78bBrian Paul _swrast_logicop_rgba_span(ctx, rb, span); 1617ba001224a18fa12792696ef393e708e90092127eBrian Paul } 1618ba001224a18fa12792696ef393e708e90092127eBrian Paul else if (ctx->Color.BlendEnabled) { 1619f515c78a2320369ead087c4e0efd583f17b4b78bBrian Paul _swrast_blend_span(ctx, rb, span); 1620ba001224a18fa12792696ef393e708e90092127eBrian Paul } 1621ba001224a18fa12792696ef393e708e90092127eBrian Paul 1622ba001224a18fa12792696ef393e708e90092127eBrian Paul if (colorMask != 0xffffffff) { 1623f515c78a2320369ead087c4e0efd583f17b4b78bBrian Paul _swrast_mask_rgba_span(ctx, rb, span); 1624ba001224a18fa12792696ef393e708e90092127eBrian Paul } 1625ba001224a18fa12792696ef393e708e90092127eBrian Paul 1626ba001224a18fa12792696ef393e708e90092127eBrian Paul if (span->arrayMask & SPAN_XY) { 1627ba001224a18fa12792696ef393e708e90092127eBrian Paul /* array of pixel coords */ 1628ba001224a18fa12792696ef393e708e90092127eBrian Paul ASSERT(rb->PutValues); 1629ba001224a18fa12792696ef393e708e90092127eBrian Paul rb->PutValues(ctx, rb, span->end, 1630ba001224a18fa12792696ef393e708e90092127eBrian Paul span->array->x, span->array->y, 1631ba001224a18fa12792696ef393e708e90092127eBrian Paul span->array->rgba, span->array->mask); 1632ba001224a18fa12792696ef393e708e90092127eBrian Paul } 1633ba001224a18fa12792696ef393e708e90092127eBrian Paul else { 1634ba001224a18fa12792696ef393e708e90092127eBrian Paul /* horizontal run of pixels */ 1635ba001224a18fa12792696ef393e708e90092127eBrian Paul ASSERT(rb->PutRow); 1636ba001224a18fa12792696ef393e708e90092127eBrian Paul rb->PutRow(ctx, rb, span->end, span->x, span->y, span->array->rgba, 1637ba001224a18fa12792696ef393e708e90092127eBrian Paul span->writeAll ? NULL: span->array->mask); 1638ba001224a18fa12792696ef393e708e90092127eBrian Paul } 1639ba001224a18fa12792696ef393e708e90092127eBrian Paul 1640ba001224a18fa12792696ef393e708e90092127eBrian Paul if (buf + 1 < numDrawBuffers) { 1641ba001224a18fa12792696ef393e708e90092127eBrian Paul /* restore original span values */ 1642ba001224a18fa12792696ef393e708e90092127eBrian Paul _mesa_memcpy(span->array->rgba, rgbaSave, 1643ba001224a18fa12792696ef393e708e90092127eBrian Paul 4 * span->end * sizeof(GLchan)); 1644ba001224a18fa12792696ef393e708e90092127eBrian Paul } 1645ba001224a18fa12792696ef393e708e90092127eBrian Paul } /* for buf */ 16461e3223c02a2f6155beb5784cadbea1f46703829aBrian Paul 164771340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 164871340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul 1649c3caaa3dd45809e672177ab322445fe51d03af25Brian Paulend: 165061c89be3135cedc795e48d36283769298e250837Brian Paul /* restore these values before returning */ 1651e5b244ff7f984805c1bcc020342f1300f2639c71Brian Paul span->interpMask = origInterpMask; 1652f1e236987829393c81dc86ea19cb49eefe190317Brian Paul span->arrayMask = origArrayMask; 165361c89be3135cedc795e48d36283769298e250837Brian Paul span->array->ChanType = chanType; 165410f30eb43835c57c00783390a02d72daf4f78e26Brian Paul} 165510f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 1656e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 165779c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/** 1658e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Read RGBA pixels from frame buffer. Clipping will be done to prevent 1659e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * reading ouside the buffer's boundaries. 166076e778dce59aa6f290db50242df945943fc47b05Brian Paul * \param type datatype for returned colors 166176e778dce59aa6f290db50242df945943fc47b05Brian Paul * \param rgba the returned colors 1662e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */ 16635071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paulvoid 1664e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul_swrast_read_rgba_span( GLcontext *ctx, struct gl_renderbuffer *rb, 166576e778dce59aa6f290db50242df945943fc47b05Brian Paul GLuint n, GLint x, GLint y, GLenum dstType, 166676e778dce59aa6f290db50242df945943fc47b05Brian Paul GLvoid *rgba) 1667e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell{ 1668e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul const GLint bufWidth = (GLint) rb->Width; 1669e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul const GLint bufHeight = (GLint) rb->Height; 1670a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul 1671a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul if (y < 0 || y >= bufHeight || x + (GLint) n < 0 || x >= bufWidth) { 1672e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* completely above, below, or right */ 1673e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul /* XXX maybe leave rgba values undefined? */ 16746ec6b845fdf3c44436028ad6fff9471d18928719Brian Paul _mesa_bzero(rgba, 4 * n * sizeof(GLchan)); 1675e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1676e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell else { 1677e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell GLint skip, length; 1678e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell if (x < 0) { 16797e152b83cbc3af028175a52450c60101cb16acf8Brian Paul /* left edge clipping */ 1680e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell skip = -x; 1681e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell length = (GLint) n - skip; 1682e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell if (length < 0) { 1683e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* completely left of window */ 1684e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell return; 1685e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1686a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul if (length > bufWidth) { 1687a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul length = bufWidth; 1688e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1689e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1690a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul else if ((GLint) (x + n) > bufWidth) { 1691e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* right edge clipping */ 1692e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell skip = 0; 1693a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul length = bufWidth - x; 1694e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell if (length < 0) { 1695e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* completely to right of window */ 1696e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell return; 1697e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1698e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1699e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell else { 1700e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* no clipping */ 1701e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell skip = 0; 1702e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell length = (GLint) n; 1703e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1704e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 1705bb8b302dbce4f830d060efecd8a9f75b10e25abbBrian Paul ASSERT(rb); 1706bb8b302dbce4f830d060efecd8a9f75b10e25abbBrian Paul ASSERT(rb->GetRow); 1707bb8b302dbce4f830d060efecd8a9f75b10e25abbBrian Paul ASSERT(rb->_BaseFormat == GL_RGB || rb->_BaseFormat == GL_RGBA); 170876e778dce59aa6f290db50242df945943fc47b05Brian Paul 170976e778dce59aa6f290db50242df945943fc47b05Brian Paul if (rb->DataType == dstType) { 171076e778dce59aa6f290db50242df945943fc47b05Brian Paul rb->GetRow(ctx, rb, length, x + skip, y, 171176e778dce59aa6f290db50242df945943fc47b05Brian Paul (GLubyte *) rgba + skip * RGBA_PIXEL_SIZE(rb->DataType)); 171276e778dce59aa6f290db50242df945943fc47b05Brian Paul } 171376e778dce59aa6f290db50242df945943fc47b05Brian Paul else { 171476e778dce59aa6f290db50242df945943fc47b05Brian Paul GLuint temp[MAX_WIDTH * 4]; 171576e778dce59aa6f290db50242df945943fc47b05Brian Paul rb->GetRow(ctx, rb, length, x + skip, y, temp); 171676e778dce59aa6f290db50242df945943fc47b05Brian Paul _mesa_convert_colors(rb->DataType, temp, 171776e778dce59aa6f290db50242df945943fc47b05Brian Paul dstType, (GLubyte *) rgba + skip * RGBA_PIXEL_SIZE(dstType), 171876e778dce59aa6f290db50242df945943fc47b05Brian Paul length, NULL); 171976e778dce59aa6f290db50242df945943fc47b05Brian Paul } 1720e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1721e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell} 1722e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 1723e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 172479c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/** 1725e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Read CI pixels from frame buffer. Clipping will be done to prevent 1726e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * reading ouside the buffer's boundaries. 1727e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */ 17285071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paulvoid 1729e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul_swrast_read_index_span( GLcontext *ctx, struct gl_renderbuffer *rb, 1730e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul GLuint n, GLint x, GLint y, GLuint index[] ) 1731e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell{ 1732e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul const GLint bufWidth = (GLint) rb->Width; 1733e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul const GLint bufHeight = (GLint) rb->Height; 1734a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul 1735a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul if (y < 0 || y >= bufHeight || x + (GLint) n < 0 || x >= bufWidth) { 1736e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* completely above, below, or right */ 1737e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul _mesa_bzero(index, n * sizeof(GLuint)); 1738e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1739e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell else { 1740e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell GLint skip, length; 1741e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell if (x < 0) { 17427e152b83cbc3af028175a52450c60101cb16acf8Brian Paul /* left edge clipping */ 1743e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell skip = -x; 1744e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell length = (GLint) n - skip; 1745e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell if (length < 0) { 1746e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* completely left of window */ 1747e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell return; 1748e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1749a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul if (length > bufWidth) { 1750a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul length = bufWidth; 1751e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1752e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1753a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul else if ((GLint) (x + n) > bufWidth) { 1754e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* right edge clipping */ 1755e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell skip = 0; 1756a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul length = bufWidth - x; 1757e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell if (length < 0) { 1758e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* completely to right of window */ 1759e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell return; 1760e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1761e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1762e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell else { 1763e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* no clipping */ 1764e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell skip = 0; 1765e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell length = (GLint) n; 1766e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1767e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 1768e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul ASSERT(rb->GetRow); 1769e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul ASSERT(rb->_BaseFormat == GL_COLOR_INDEX); 1770e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul 1771e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul if (rb->DataType == GL_UNSIGNED_BYTE) { 1772e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul GLubyte index8[MAX_WIDTH]; 1773e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul GLint i; 1774e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul rb->GetRow(ctx, rb, length, x + skip, y, index8); 1775e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul for (i = 0; i < length; i++) 1776e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul index[skip + i] = index8[i]; 1777e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul } 1778e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul else if (rb->DataType == GL_UNSIGNED_SHORT) { 1779e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul GLushort index16[MAX_WIDTH]; 1780e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul GLint i; 1781e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul rb->GetRow(ctx, rb, length, x + skip, y, index16); 1782e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul for (i = 0; i < length; i++) 1783e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul index[skip + i] = index16[i]; 1784e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul } 1785e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul else if (rb->DataType == GL_UNSIGNED_INT) { 1786e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul rb->GetRow(ctx, rb, length, x + skip, y, index + skip); 1787e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul } 1788e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1789e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell} 179067074332728acba86da7630353673b458713bb8aBrian Paul 179167074332728acba86da7630353673b458713bb8aBrian Paul 179267074332728acba86da7630353673b458713bb8aBrian Paul/** 179367074332728acba86da7630353673b458713bb8aBrian Paul * Wrapper for gl_renderbuffer::GetValues() which does clipping to avoid 179467074332728acba86da7630353673b458713bb8aBrian Paul * reading values outside the buffer bounds. 179567074332728acba86da7630353673b458713bb8aBrian Paul * We can use this for reading any format/type of renderbuffer. 1796ba001224a18fa12792696ef393e708e90092127eBrian Paul * \param valueSize is the size in bytes of each value (pixel) put into the 179767074332728acba86da7630353673b458713bb8aBrian Paul * values array. 179867074332728acba86da7630353673b458713bb8aBrian Paul */ 179967074332728acba86da7630353673b458713bb8aBrian Paulvoid 180067074332728acba86da7630353673b458713bb8aBrian Paul_swrast_get_values(GLcontext *ctx, struct gl_renderbuffer *rb, 180167074332728acba86da7630353673b458713bb8aBrian Paul GLuint count, const GLint x[], const GLint y[], 180267074332728acba86da7630353673b458713bb8aBrian Paul void *values, GLuint valueSize) 180367074332728acba86da7630353673b458713bb8aBrian Paul{ 180467074332728acba86da7630353673b458713bb8aBrian Paul GLuint i, inCount = 0, inStart = 0; 180567074332728acba86da7630353673b458713bb8aBrian Paul 180667074332728acba86da7630353673b458713bb8aBrian Paul for (i = 0; i < count; i++) { 180767074332728acba86da7630353673b458713bb8aBrian Paul if (x[i] >= 0 && y[i] >= 0 && x[i] < rb->Width && y[i] < rb->Height) { 180867074332728acba86da7630353673b458713bb8aBrian Paul /* inside */ 180967074332728acba86da7630353673b458713bb8aBrian Paul if (inCount == 0) 181067074332728acba86da7630353673b458713bb8aBrian Paul inStart = i; 181167074332728acba86da7630353673b458713bb8aBrian Paul inCount++; 181267074332728acba86da7630353673b458713bb8aBrian Paul } 181367074332728acba86da7630353673b458713bb8aBrian Paul else { 181467074332728acba86da7630353673b458713bb8aBrian Paul if (inCount > 0) { 181567074332728acba86da7630353673b458713bb8aBrian Paul /* read [inStart, inStart + inCount) */ 181667074332728acba86da7630353673b458713bb8aBrian Paul rb->GetValues(ctx, rb, inCount, x + inStart, y + inStart, 181767074332728acba86da7630353673b458713bb8aBrian Paul (GLubyte *) values + inStart * valueSize); 181867074332728acba86da7630353673b458713bb8aBrian Paul inCount = 0; 181967074332728acba86da7630353673b458713bb8aBrian Paul } 182067074332728acba86da7630353673b458713bb8aBrian Paul } 182167074332728acba86da7630353673b458713bb8aBrian Paul } 182267074332728acba86da7630353673b458713bb8aBrian Paul if (inCount > 0) { 182367074332728acba86da7630353673b458713bb8aBrian Paul /* read last values */ 182467074332728acba86da7630353673b458713bb8aBrian Paul rb->GetValues(ctx, rb, inCount, x + inStart, y + inStart, 182567074332728acba86da7630353673b458713bb8aBrian Paul (GLubyte *) values + inStart * valueSize); 182667074332728acba86da7630353673b458713bb8aBrian Paul } 182767074332728acba86da7630353673b458713bb8aBrian Paul} 18283fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul 18293fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul 18303fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul/** 18313fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul * Wrapper for gl_renderbuffer::PutRow() which does clipping. 1832a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul * \param valueSize size of each value (pixel) in bytes 18333fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul */ 18343fd819aef8139761ce86cb8d763de83a11c81b33Brian Paulvoid 18353fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul_swrast_put_row(GLcontext *ctx, struct gl_renderbuffer *rb, 18363fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul GLuint count, GLint x, GLint y, 18373fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul const GLvoid *values, GLuint valueSize) 18383fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul{ 18393fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul GLint skip = 0; 18403fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul 18413fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul if (y < 0 || y >= rb->Height) 18423fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul return; /* above or below */ 18433fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul 18443fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul if (x + (GLint) count <= 0 || x >= rb->Width) 18453fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul return; /* entirely left or right */ 18463fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul 18473fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul if (x + count > rb->Width) { 18483fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul /* right clip */ 18493fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul GLint clip = x + count - rb->Width; 18503fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul count -= clip; 18513fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul } 18523fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul 18533fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul if (x < 0) { 18543fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul /* left clip */ 18553fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul skip = -x; 18563fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul x = 0; 18573fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul count -= skip; 18583fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul } 18593fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul 18603fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul rb->PutRow(ctx, rb, count, x, y, 18613fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul (const GLubyte *) values + skip * valueSize, NULL); 18623fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul} 1863f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul 1864f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul 1865f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul/** 1866f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul * Wrapper for gl_renderbuffer::GetRow() which does clipping. 1867a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul * \param valueSize size of each value (pixel) in bytes 1868f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul */ 1869f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paulvoid 1870f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul_swrast_get_row(GLcontext *ctx, struct gl_renderbuffer *rb, 1871f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul GLuint count, GLint x, GLint y, 1872f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul GLvoid *values, GLuint valueSize) 1873f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul{ 1874f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul GLint skip = 0; 1875f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul 1876f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul if (y < 0 || y >= rb->Height) 1877f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul return; /* above or below */ 1878f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul 1879f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul if (x + (GLint) count <= 0 || x >= rb->Width) 1880f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul return; /* entirely left or right */ 1881f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul 1882f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul if (x + count > rb->Width) { 1883f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul /* right clip */ 1884f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul GLint clip = x + count - rb->Width; 1885f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul count -= clip; 1886f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul } 1887f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul 1888f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul if (x < 0) { 1889f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul /* left clip */ 1890f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul skip = -x; 1891f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul x = 0; 1892f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul count -= skip; 1893f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul } 1894f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul 1895f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul rb->GetRow(ctx, rb, count, x, y, (GLubyte *) values + skip * valueSize); 1896f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul} 1897a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul 1898a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul 1899a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul/** 1900a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul * Get RGBA pixels from the given renderbuffer. Put the pixel colors into 1901a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul * the span's specular color arrays. The specular color arrays should no 1902a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul * longer be needed by time this function is called. 1903a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul * Used by blending, logicop and masking functions. 1904a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul * \return pointer to the colors we read. 1905a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul */ 1906a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paulvoid * 1907a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul_swrast_get_dest_rgba(GLcontext *ctx, struct gl_renderbuffer *rb, 1908cdb27e8242215271364602995d85607cfc06d441Brian Paul SWspan *span) 1909a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul{ 191076e778dce59aa6f290db50242df945943fc47b05Brian Paul const GLuint pixelSize = RGBA_PIXEL_SIZE(span->array->ChanType); 1911a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul void *rbPixels; 1912a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul 1913a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul /* 1914a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul * Determine pixel size (in bytes). 1915a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul * Point rbPixels to a temporary space (use specular color arrays). 1916a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul */ 1917a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul if (span->array->ChanType == GL_UNSIGNED_BYTE) { 1918a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul rbPixels = span->array->color.sz1.spec; 1919a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul } 1920a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul else if (span->array->ChanType == GL_UNSIGNED_SHORT) { 1921a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul rbPixels = span->array->color.sz2.spec; 1922a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul } 1923a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul else { 1924a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul rbPixels = span->array->color.sz4.spec; 1925a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul } 1926a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul 1927a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul /* Get destination values from renderbuffer */ 1928a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul if (span->arrayMask & SPAN_XY) { 1929a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul _swrast_get_values(ctx, rb, span->end, span->array->x, span->array->y, 1930a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul rbPixels, pixelSize); 1931a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul } 1932a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul else { 1933a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul _swrast_get_row(ctx, rb, span->end, span->x, span->y, 1934a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul rbPixels, pixelSize); 1935a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul } 1936a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul 1937a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul return rbPixels; 1938a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul} 1939