s_span.c revision e4f976b8b9d74a74b5816146cb11880c3a493929
1e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell/* 2e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Mesa 3-D graphics library 36e4f594a02fc384b17d5732be652d7d28618aec2Brian Paul * Version: 6.5 422144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes * 5a66393120411071b3f3ccce8583ab961a2935959Michal Krol * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. 622144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes * 7e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Permission is hereby granted, free of charge, to any person obtaining a 8e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * copy of this software and associated documentation files (the "Software"), 9e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * to deal in the Software without restriction, including without limitation 10e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * the rights to use, copy, modify, merge, publish, distribute, sublicense, 11e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * and/or sell copies of the Software, and to permit persons to whom the 12e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Software is furnished to do so, subject to the following conditions: 1322144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes * 14e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * The above copyright notice and this permission notice shall be included 15e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * in all copies or substantial portions of the Software. 1622144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes * 17e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 21e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 22e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */ 24e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 25e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 2679c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/** 27bcb148de9201c7f90a68c7c46434e7ebf7204000Brian Paul * \file swrast/s_span.c 2879c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul * \brief Span processing functions used by all rasterization functions. 2979c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul * This is where all the per-fragment tests are performed 3079c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul * \author Brian Paul 31e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */ 32e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 33e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "glheader.h" 34e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "colormac.h" 3571340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul#include "context.h" 36e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "macros.h" 373c63452e64df7e10aa073c6c3b9492b1d7dabbb8Brian Paul#include "imports.h" 38f971e24cf0341dd2779196a0836327b74fc82336Brian Paul#include "image.h" 39e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 407f752fed993e5e9423abac200dd59141edbada56Dave Airlie#include "s_atifragshader.h" 41bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol#include "s_alpha.h" 42e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_blend.h" 43cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell#include "s_context.h" 44e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_depth.h" 45e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_fog.h" 46e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_logic.h" 47e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_masking.h" 48c968d3d410a1897ecbb41d3557adaef69a4c627aBrian#include "s_fragprog.h" 49e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_span.h" 50e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_stencil.h" 5155187ea63e980b32c7a701855571332f4357d634Brian Paul#include "s_texcombine.h" 52e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 532a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 5479c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/** 552a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul * Init span's Z interpolation values to the RasterPos Z. 562a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul * Used during setup for glDraw/CopyPixels. 572a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul */ 582a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paulvoid 59cdb27e8242215271364602995d85607cfc06d441Brian Paul_swrast_span_default_z( GLcontext *ctx, SWspan *span ) 602a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul{ 61e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul const GLfloat depthMax = ctx->DrawBuffer->_DepthMaxF; 6231e739a18931fa48454f172818245b0927c8910fBrian Paul if (ctx->DrawBuffer->Visual.depthBits <= 16) 63e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul span->z = FloatToFixed(ctx->Current.RasterPos[2] * depthMax + 0.5F); 642a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul else 65e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul span->z = (GLint) (ctx->Current.RasterPos[2] * depthMax + 0.5F); 662a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->zStep = 0; 672a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->interpMask |= SPAN_Z; 682a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul} 692a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 702a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 7179c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/** 722a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul * Init span's fog interpolation values to the RasterPos fog. 732a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul * Used during setup for glDraw/CopyPixels. 742a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul */ 752a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paulvoid 76cdb27e8242215271364602995d85607cfc06d441Brian Paul_swrast_span_default_fog( GLcontext *ctx, SWspan *span ) 772a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul{ 78e4f976b8b9d74a74b5816146cb11880c3a493929Brian span->attrStart[FRAG_ATTRIB_FOGC][0] 79e4f976b8b9d74a74b5816146cb11880c3a493929Brian = _swrast_z_to_fogfactor(ctx, ctx->Current.RasterDistance); 80462d8f5fafcc5ac69ea89cac1222abadded642e2Brian span->attrStepX[FRAG_ATTRIB_FOGC][0] = 0.0; 81462d8f5fafcc5ac69ea89cac1222abadded642e2Brian span->attrStepY[FRAG_ATTRIB_FOGC][0] = 0.0; 822a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->interpMask |= SPAN_FOG; 832a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul} 842a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 852a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 8679c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/** 87a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul * Init span's rgba or index interpolation values to the RasterPos color. 882a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul * Used during setup for glDraw/CopyPixels. 892a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul */ 902a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paulvoid 91cdb27e8242215271364602995d85607cfc06d441Brian Paul_swrast_span_default_color( GLcontext *ctx, SWspan *span ) 922a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul{ 932a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul if (ctx->Visual.rgbMode) { 942a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLchan r, g, b, a; 952a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul UNCLAMPED_FLOAT_TO_CHAN(r, ctx->Current.RasterColor[0]); 962a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul UNCLAMPED_FLOAT_TO_CHAN(g, ctx->Current.RasterColor[1]); 972a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul UNCLAMPED_FLOAT_TO_CHAN(b, ctx->Current.RasterColor[2]); 982a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul UNCLAMPED_FLOAT_TO_CHAN(a, ctx->Current.RasterColor[3]); 992a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul#if CHAN_TYPE == GL_FLOAT 1002a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->red = r; 1012a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->green = g; 1022a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->blue = b; 1032a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->alpha = a; 1042a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul#else 1052a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->red = IntToFixed(r); 1062a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->green = IntToFixed(g); 1072a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->blue = IntToFixed(b); 1082a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->alpha = IntToFixed(a); 1092a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul#endif 1102a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->redStep = 0; 1112a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->greenStep = 0; 1122a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->blueStep = 0; 1132a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->alphaStep = 0; 1142a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->interpMask |= SPAN_RGBA; 1152a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 1162a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul else { 1170f3cd3f894612d156de454178effa4c732f96da7Brian Paul span->index = FloatToFixed(ctx->Current.RasterIndex); 1182a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->indexStep = 0; 1192a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->interpMask |= SPAN_INDEX; 1202a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 1212a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul} 1222a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 1232a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 1244753d60dd070bb08d0116076bcc08025c86ce857Brian Paul/** 1254753d60dd070bb08d0116076bcc08025c86ce857Brian Paul * Init span's texcoord interpolation values to the RasterPos texcoords. 1264753d60dd070bb08d0116076bcc08025c86ce857Brian Paul * Used during setup for glDraw/CopyPixels. 1274753d60dd070bb08d0116076bcc08025c86ce857Brian Paul */ 1284753d60dd070bb08d0116076bcc08025c86ce857Brian Paulvoid 129cdb27e8242215271364602995d85607cfc06d441Brian Paul_swrast_span_default_texcoords( GLcontext *ctx, SWspan *span ) 1304753d60dd070bb08d0116076bcc08025c86ce857Brian Paul{ 1314753d60dd070bb08d0116076bcc08025c86ce857Brian Paul GLuint i; 132ee4e75bd6f768b7210436feeb32b4545ed62e025Brian Paul for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) { 1339ab512ad8cf3a12f4f7f8494fa99bc9389f217dbBrian const GLuint attr = FRAG_ATTRIB_TEX0 + i; 134e63cb85cbc13c083f5d9f4640bb81ba9417a4f28Brian Paul const GLfloat *tc = ctx->Current.RasterTexCoords[i]; 13512ef1fbefcee964b715783d3ade6b69b2c699ed8Brian if (ctx->FragmentProgram._Current || ctx->ATIFragmentShader._Enabled) { 1369ab512ad8cf3a12f4f7f8494fa99bc9389f217dbBrian COPY_4V(span->attrStart[attr], tc); 137a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul } 138a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul else if (tc[3] > 0.0F) { 139e63cb85cbc13c083f5d9f4640bb81ba9417a4f28Brian Paul /* use (s/q, t/q, r/q, 1) */ 1409ab512ad8cf3a12f4f7f8494fa99bc9389f217dbBrian span->attrStart[attr][0] = tc[0] / tc[3]; 1419ab512ad8cf3a12f4f7f8494fa99bc9389f217dbBrian span->attrStart[attr][1] = tc[1] / tc[3]; 1429ab512ad8cf3a12f4f7f8494fa99bc9389f217dbBrian span->attrStart[attr][2] = tc[2] / tc[3]; 1439ab512ad8cf3a12f4f7f8494fa99bc9389f217dbBrian span->attrStart[attr][3] = 1.0; 144e63cb85cbc13c083f5d9f4640bb81ba9417a4f28Brian Paul } 145e63cb85cbc13c083f5d9f4640bb81ba9417a4f28Brian Paul else { 1469ab512ad8cf3a12f4f7f8494fa99bc9389f217dbBrian ASSIGN_4V(span->attrStart[attr], 0.0F, 0.0F, 0.0F, 1.0F); 147e63cb85cbc13c083f5d9f4640bb81ba9417a4f28Brian Paul } 1489ab512ad8cf3a12f4f7f8494fa99bc9389f217dbBrian ASSIGN_4V(span->attrStepX[attr], 0.0F, 0.0F, 0.0F, 0.0F); 1499ab512ad8cf3a12f4f7f8494fa99bc9389f217dbBrian ASSIGN_4V(span->attrStepY[attr], 0.0F, 0.0F, 0.0F, 0.0F); 1504753d60dd070bb08d0116076bcc08025c86ce857Brian Paul } 1514753d60dd070bb08d0116076bcc08025c86ce857Brian Paul span->interpMask |= SPAN_TEXTURE; 1524753d60dd070bb08d0116076bcc08025c86ce857Brian Paul} 1534753d60dd070bb08d0116076bcc08025c86ce857Brian Paul 1544753d60dd070bb08d0116076bcc08025c86ce857Brian Paul 155d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul/** 156e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul * Interpolate primary colors to fill in the span->array->color array. 157d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul */ 158f614a6190562e550257afca0d04e3846648942e8Brian Paulstatic INLINE void 159e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paulinterpolate_colors(SWspan *span) 1602a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul{ 1612a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul const GLuint n = span->end; 1622a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLuint i; 1632a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 164e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul ASSERT((span->interpMask & SPAN_RGBA) && 165e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul !(span->arrayMask & SPAN_RGBA)); 1662a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 167e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul switch (span->array->ChanType) { 1681e3223c02a2f6155beb5784cadbea1f46703829aBrian Paul#if CHAN_BITS != 32 169e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul case GL_UNSIGNED_BYTE: 170e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul { 171e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul GLubyte (*rgba)[4] = span->array->color.sz1.rgba; 172e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul if (span->interpMask & SPAN_FLAT) { 173d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul GLubyte color[4]; 174e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul color[RCOMP] = FixedToInt(span->red); 175e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul color[GCOMP] = FixedToInt(span->green); 176e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul color[BCOMP] = FixedToInt(span->blue); 177e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul color[ACOMP] = FixedToInt(span->alpha); 178d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul for (i = 0; i < n; i++) { 179d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul COPY_4UBV(rgba[i], color); 180d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul } 181d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul } 182e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul else { 183e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul GLfixed r = span->red; 184e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul GLfixed g = span->green; 185e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul GLfixed b = span->blue; 186e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul GLfixed a = span->alpha; 187e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul GLint dr = span->redStep; 188e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul GLint dg = span->greenStep; 189e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul GLint db = span->blueStep; 190e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul GLint da = span->alphaStep; 191d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul for (i = 0; i < n; i++) { 192e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul rgba[i][RCOMP] = FixedToChan(r); 193e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul rgba[i][GCOMP] = FixedToChan(g); 194e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul rgba[i][BCOMP] = FixedToChan(b); 195e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul rgba[i][ACOMP] = FixedToChan(a); 196e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul r += dr; 197e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul g += dg; 198e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul b += db; 199e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul a += da; 200d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul } 201d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul } 202e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul } 203e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul break; 204e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul case GL_UNSIGNED_SHORT: 205e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul { 206e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul GLushort (*rgba)[4] = span->array->color.sz2.rgba; 207e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul if (span->interpMask & SPAN_FLAT) { 208e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul GLushort color[4]; 209e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul color[RCOMP] = FixedToInt(span->red); 210e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul color[GCOMP] = FixedToInt(span->green); 211e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul color[BCOMP] = FixedToInt(span->blue); 212e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul color[ACOMP] = FixedToInt(span->alpha); 213d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul for (i = 0; i < n; i++) { 214d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul COPY_4V(rgba[i], color); 215d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul } 216d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul } 217e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul else { 218e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul GLushort (*rgba)[4] = span->array->color.sz2.rgba; 219d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul GLfixed r, g, b, a; 220d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul GLint dr, dg, db, da; 221e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul r = span->red; 222e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul g = span->green; 223e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul b = span->blue; 224e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul a = span->alpha; 225e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul dr = span->redStep; 226e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul dg = span->greenStep; 227e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul db = span->blueStep; 228e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul da = span->alphaStep; 229d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul for (i = 0; i < n; i++) { 230d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul rgba[i][RCOMP] = FixedToChan(r); 231d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul rgba[i][GCOMP] = FixedToChan(g); 232d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul rgba[i][BCOMP] = FixedToChan(b); 233d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul rgba[i][ACOMP] = FixedToChan(a); 234d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul r += dr; 235d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul g += dg; 236d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul b += db; 237d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul a += da; 238d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul } 239d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul } 240e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul } 241e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul break; 242e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul#endif 243e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul case GL_FLOAT: 244e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul { 245f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian GLfloat (*rgba)[4] = span->array->attribs[FRAG_ATTRIB_COL0]; 246e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul GLfloat r, g, b, a, dr, dg, db, da; 247e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul r = span->red; 248e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul g = span->green; 249e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul b = span->blue; 250e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul a = span->alpha; 251e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul if (span->interpMask & SPAN_FLAT) { 252e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul dr = dg = db = da = 0.0; 253e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul } 254e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul else { 255e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul dr = span->redStep; 256e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul dg = span->greenStep; 257e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul db = span->blueStep; 258e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul da = span->alphaStep; 259e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul } 260e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul for (i = 0; i < n; i++) { 261e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul rgba[i][RCOMP] = r; 262e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul rgba[i][GCOMP] = g; 263e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul rgba[i][BCOMP] = b; 264e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul rgba[i][ACOMP] = a; 265e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul r += dr; 266e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul g += dg; 267e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul b += db; 268e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul a += da; 269e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul } 270e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul } 271e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul break; 272e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul default: 273e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul _mesa_problem(NULL, "bad datatype in interpolate_colors"); 274e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul } 275e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul span->arrayMask |= SPAN_RGBA; 276e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul} 277e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul 278e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul 279e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul/** 280e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul * Interpolate specular/secondary colors. 281e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul */ 282f614a6190562e550257afca0d04e3846648942e8Brian Paulstatic INLINE void 283e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paulinterpolate_specular(SWspan *span) 284e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul{ 285e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul const GLuint n = span->end; 286e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul GLuint i; 287e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul 288e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul switch (span->array->ChanType) { 289c351858de8e51fa4a6425cf176cc43689189f3ffBrian Paul#if CHAN_BITS != 32 290e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul case GL_UNSIGNED_BYTE: 291e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul { 292e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul GLubyte (*spec)[4] = span->array->color.sz1.spec; 293e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul if (span->interpMask & SPAN_FLAT) { 294e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul GLubyte color[4]; 295e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul color[RCOMP] = FixedToInt(span->specRed); 296e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul color[GCOMP] = FixedToInt(span->specGreen); 297e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul color[BCOMP] = FixedToInt(span->specBlue); 298e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul color[ACOMP] = 0; 299e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul for (i = 0; i < n; i++) { 300e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul COPY_4UBV(spec[i], color); 301d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul } 302e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul } 303e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul else { 304e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul GLfixed r = span->specRed; 305e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul GLfixed g = span->specGreen; 306e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul GLfixed b = span->specBlue; 307e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul GLint dr = span->specRedStep; 308e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul GLint dg = span->specGreenStep; 309e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul GLint db = span->specBlueStep; 310d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul for (i = 0; i < n; i++) { 311e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul spec[i][RCOMP] = CLAMP(FixedToChan(r), 0, 255); 312e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul spec[i][GCOMP] = CLAMP(FixedToChan(g), 0, 255); 313e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul spec[i][BCOMP] = CLAMP(FixedToChan(b), 0, 255); 314e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul spec[i][ACOMP] = 0; 315d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul r += dr; 316d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul g += dg; 317d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul b += db; 318d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul } 319d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul } 320e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul } 321e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul break; 322e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul case GL_UNSIGNED_SHORT: 323e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul { 324e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul GLushort (*spec)[4] = span->array->color.sz2.spec; 325e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul if (span->interpMask & SPAN_FLAT) { 326e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul GLushort color[4]; 327e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul color[RCOMP] = FixedToInt(span->specRed); 328e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul color[GCOMP] = FixedToInt(span->specGreen); 329e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul color[BCOMP] = FixedToInt(span->specBlue); 330e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul color[ACOMP] = 0; 331e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul for (i = 0; i < n; i++) { 332e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul COPY_4V(spec[i], color); 333d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul } 334e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul } 335e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul else { 336e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul GLfixed r = FloatToFixed(span->specRed); 337e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul GLfixed g = FloatToFixed(span->specGreen); 338e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul GLfixed b = FloatToFixed(span->specBlue); 339e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul GLint dr = FloatToFixed(span->specRedStep); 340e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul GLint dg = FloatToFixed(span->specGreenStep); 341e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul GLint db = FloatToFixed(span->specBlueStep); 342e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul for (i = 0; i < n; i++) { 343e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul spec[i][RCOMP] = FixedToInt(r); 344e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul spec[i][GCOMP] = FixedToInt(g); 345e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul spec[i][BCOMP] = FixedToInt(b); 346e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul spec[i][ACOMP] = 0; 347e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul r += dr; 348e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul g += dg; 349e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul b += db; 350d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul } 351e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul } 352e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul } 353e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul break; 354c351858de8e51fa4a6425cf176cc43689189f3ffBrian Paul#endif 355e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul case GL_FLOAT: 356e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul { 357f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian GLfloat (*spec)[4] = span->array->attribs[FRAG_ATTRIB_COL1]; 358e6f47d1855354165c6eed5080d8a72024891f10fBrian Paul#if CHAN_BITS <= 16 359e6f47d1855354165c6eed5080d8a72024891f10fBrian Paul GLfloat r = CHAN_TO_FLOAT(FixedToChan(span->specRed)); 360e6f47d1855354165c6eed5080d8a72024891f10fBrian Paul GLfloat g = CHAN_TO_FLOAT(FixedToChan(span->specGreen)); 361e6f47d1855354165c6eed5080d8a72024891f10fBrian Paul GLfloat b = CHAN_TO_FLOAT(FixedToChan(span->specBlue)); 362e6f47d1855354165c6eed5080d8a72024891f10fBrian Paul#else 363e6f47d1855354165c6eed5080d8a72024891f10fBrian Paul GLfloat r = span->specRed; 364e6f47d1855354165c6eed5080d8a72024891f10fBrian Paul GLfloat g = span->specGreen; 365e6f47d1855354165c6eed5080d8a72024891f10fBrian Paul GLfloat b = span->specBlue; 366e6f47d1855354165c6eed5080d8a72024891f10fBrian Paul#endif 367e6f47d1855354165c6eed5080d8a72024891f10fBrian Paul GLfloat dr, dg, db; 368e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul if (span->interpMask & SPAN_FLAT) { 369e6f47d1855354165c6eed5080d8a72024891f10fBrian Paul dr = dg = db = 0.0; 370e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul } 371e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul else { 372e6f47d1855354165c6eed5080d8a72024891f10fBrian Paul#if CHAN_BITS <= 16 373e6f47d1855354165c6eed5080d8a72024891f10fBrian Paul dr = CHAN_TO_FLOAT(FixedToChan(span->specRedStep)); 374e6f47d1855354165c6eed5080d8a72024891f10fBrian Paul dg = CHAN_TO_FLOAT(FixedToChan(span->specGreenStep)); 375e6f47d1855354165c6eed5080d8a72024891f10fBrian Paul db = CHAN_TO_FLOAT(FixedToChan(span->specBlueStep)); 376e6f47d1855354165c6eed5080d8a72024891f10fBrian Paul#else 377e6f47d1855354165c6eed5080d8a72024891f10fBrian Paul dr = span->specRedStep; 378e6f47d1855354165c6eed5080d8a72024891f10fBrian Paul dg = span->specGreenStep; 379e6f47d1855354165c6eed5080d8a72024891f10fBrian Paul db = span->specBlueStep; 380e6f47d1855354165c6eed5080d8a72024891f10fBrian Paul#endif 381e6f47d1855354165c6eed5080d8a72024891f10fBrian Paul } 382e6f47d1855354165c6eed5080d8a72024891f10fBrian Paul for (i = 0; i < n; i++) { 383e6f47d1855354165c6eed5080d8a72024891f10fBrian Paul spec[i][RCOMP] = r; 384e6f47d1855354165c6eed5080d8a72024891f10fBrian Paul spec[i][GCOMP] = g; 385e6f47d1855354165c6eed5080d8a72024891f10fBrian Paul spec[i][BCOMP] = b; 386e6f47d1855354165c6eed5080d8a72024891f10fBrian Paul spec[i][ACOMP] = 0.0F; 387e6f47d1855354165c6eed5080d8a72024891f10fBrian Paul r += dr; 388e6f47d1855354165c6eed5080d8a72024891f10fBrian Paul g += dg; 389e6f47d1855354165c6eed5080d8a72024891f10fBrian Paul b += db; 390d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul } 3912a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 392e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul break; 393e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul default: 394e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul _mesa_problem(NULL, "bad datatype in interpolate_specular"); 3952a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 396e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul span->arrayMask |= SPAN_SPEC; 3972a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul} 3982a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 3992a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 4002a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul/* Fill in the span.color.index array from the interpolation values */ 401f614a6190562e550257afca0d04e3846648942e8Brian Paulstatic INLINE void 402cdb27e8242215271364602995d85607cfc06d441Brian Paulinterpolate_indexes(GLcontext *ctx, SWspan *span) 4032a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul{ 4042a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfixed index = span->index; 4052a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul const GLint indexStep = span->indexStep; 4062a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul const GLuint n = span->end; 40777df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul GLuint *indexes = span->array->index; 4082a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLuint i; 409a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul (void) ctx; 410b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul ASSERT((span->interpMask & SPAN_INDEX) && 411b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul !(span->arrayMask & SPAN_INDEX)); 4122a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 4132a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul if ((span->interpMask & SPAN_FLAT) || (indexStep == 0)) { 4142a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul /* constant color */ 4152a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul index = FixedToInt(index); 4162a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul for (i = 0; i < n; i++) { 4172a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul indexes[i] = index; 4182a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 4192a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 4202a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul else { 4212a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul /* interpolate */ 4222a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul for (i = 0; i < n; i++) { 4232a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul indexes[i] = FixedToInt(index); 4242a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul index += indexStep; 4252a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 4262a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 4272a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->arrayMask |= SPAN_INDEX; 428e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul span->interpMask &= ~SPAN_INDEX; 4292a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul} 4302a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 4312a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 432d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul/* Fill in the span.array.fog values from the interpolation values */ 433f614a6190562e550257afca0d04e3846648942e8Brian Paulstatic INLINE void 434cdb27e8242215271364602995d85607cfc06d441Brian Paulinterpolate_fog(const GLcontext *ctx, SWspan *span) 435d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul{ 436f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian GLfloat (*fog)[4] = span->array->attribs[FRAG_ATTRIB_FOGC]; 437462d8f5fafcc5ac69ea89cac1222abadded642e2Brian const GLfloat fogStep = span->attrStepX[FRAG_ATTRIB_FOGC][0]; 438462d8f5fafcc5ac69ea89cac1222abadded642e2Brian GLfloat fogCoord = span->attrStart[FRAG_ATTRIB_FOGC][0]; 439d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul const GLuint haveW = (span->interpMask & SPAN_W); 4409ab512ad8cf3a12f4f7f8494fa99bc9389f217dbBrian const GLfloat wStep = haveW ? span->attrStepX[FRAG_ATTRIB_WPOS][3] : 0.0F; 4419ab512ad8cf3a12f4f7f8494fa99bc9389f217dbBrian GLfloat w = haveW ? span->attrStart[FRAG_ATTRIB_WPOS][3] : 1.0F; 442d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul GLuint i; 443d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul for (i = 0; i < span->end; i++) { 444f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian fog[i][0] = fogCoord / w; 445d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul fogCoord += fogStep; 446d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul w += wStep; 447d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul } 448d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul span->arrayMask |= SPAN_FOG; 449d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul} 450d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul 451d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul 4522a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul/* Fill in the span.zArray array from the interpolation values */ 453711e27fda27e4235b20a4cf73c2767c984ab2b81Brian Paulvoid 454cdb27e8242215271364602995d85607cfc06d441Brian Paul_swrast_span_interpolate_z( const GLcontext *ctx, SWspan *span ) 4552a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul{ 4562a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul const GLuint n = span->end; 4572a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLuint i; 4582a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 459b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul ASSERT((span->interpMask & SPAN_Z) && 460b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul !(span->arrayMask & SPAN_Z)); 4612a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 46231e739a18931fa48454f172818245b0927c8910fBrian Paul if (ctx->DrawBuffer->Visual.depthBits <= 16) { 4632a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfixed zval = span->z; 4643e37bafab0a339021354b9c78f983d05d433d735Brian Paul GLuint *z = span->array->z; 465ad8cd6111e022c90c93df106c0fde6f64d205816Brian Paul for (i = 0; i < n; i++) { 46677df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul z[i] = FixedToInt(zval); 4672a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul zval += span->zStep; 4682a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 4692a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 4702a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul else { 4712a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul /* Deep Z buffer, no fixed->int shift */ 4727265556b9aa0367e9b5031e7cb15ed2a5d73866dBrian Paul GLuint zval = span->z; 4733e37bafab0a339021354b9c78f983d05d433d735Brian Paul GLuint *z = span->array->z; 4742a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul for (i = 0; i < n; i++) { 47577df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul z[i] = zval; 4762a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul zval += span->zStep; 4772a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 4782a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 47932340aea1308153dad5c105fc0748aea1e4c37eeBrian Paul span->interpMask &= ~SPAN_Z; 4802a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->arrayMask |= SPAN_Z; 4812a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul} 4822a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 4832a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 484c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul/* 48531f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul * This the ideal solution, as given in the OpenGL spec. 486c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul */ 487c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul#if 0 48831f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paulstatic GLfloat 48931f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paulcompute_lambda(GLfloat dsdx, GLfloat dsdy, GLfloat dtdx, GLfloat dtdy, 49031f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat dqdx, GLfloat dqdy, GLfloat texW, GLfloat texH, 49131f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat s, GLfloat t, GLfloat q, GLfloat invQ) 492c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul{ 49331f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat dudx = texW * ((s + dsdx) / (q + dqdx) - s * invQ); 49431f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat dvdx = texH * ((t + dtdx) / (q + dqdx) - t * invQ); 49531f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat dudy = texW * ((s + dsdy) / (q + dqdy) - s * invQ); 49631f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat dvdy = texH * ((t + dtdy) / (q + dqdy) - t * invQ); 497f9b1e5241facc8cf255c258082d5cb5b04783e93Brian Paul GLfloat x = SQRTF(dudx * dudx + dvdx * dvdx); 498f9b1e5241facc8cf255c258082d5cb5b04783e93Brian Paul GLfloat y = SQRTF(dudy * dudy + dvdy * dvdy); 49931f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat rho = MAX2(x, y); 50031f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat lambda = LOG2(rho); 50131f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul return lambda; 502c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul} 503c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul#endif 504c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul 50531f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul 50631f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul/* 50731f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul * This is a faster approximation 508c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul */ 509350353adcd75f94fda63c787c86961716114e0bfBrian PaulGLfloat 51045bc887da226403f2c41077e40ca38b6f60f1359Brian Paul_swrast_compute_lambda(GLfloat dsdx, GLfloat dsdy, GLfloat dtdx, GLfloat dtdy, 511350353adcd75f94fda63c787c86961716114e0bfBrian Paul GLfloat dqdx, GLfloat dqdy, GLfloat texW, GLfloat texH, 512350353adcd75f94fda63c787c86961716114e0bfBrian Paul GLfloat s, GLfloat t, GLfloat q, GLfloat invQ) 513c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul{ 51431f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat dsdx2 = (s + dsdx) / (q + dqdx) - s * invQ; 51531f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat dtdx2 = (t + dtdx) / (q + dqdx) - t * invQ; 51631f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat dsdy2 = (s + dsdy) / (q + dqdy) - s * invQ; 51731f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat dtdy2 = (t + dtdy) / (q + dqdy) - t * invQ; 51831f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat maxU, maxV, rho, lambda; 51931f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul dsdx2 = FABSF(dsdx2); 52031f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul dsdy2 = FABSF(dsdy2); 52131f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul dtdx2 = FABSF(dtdx2); 52231f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul dtdy2 = FABSF(dtdy2); 52331f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul maxU = MAX2(dsdx2, dsdy2) * texW; 52431f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul maxV = MAX2(dtdx2, dtdy2) * texH; 52531f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul rho = MAX2(maxU, maxV); 52631f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul lambda = LOG2(rho); 52731f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul return lambda; 528c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul} 529c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul 530d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul 531d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul/** 532c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul * Fill in the span.texcoords array from the interpolation values. 533d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul * Note: in the places where we divide by Q (or mult by invQ) we're 534d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul * really doing two things: perspective correction and texcoord 535d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul * projection. Remember, for texcoord (s,t,r,q) we need to index 536d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul * texels with (s/q, t/q, r/q). 537d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul * If we're using a fragment program, we never do the division 538d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul * for texcoord projection. That's done by the TXP instruction 539d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul * or user-written code. 540c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul */ 5412a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paulstatic void 542cdb27e8242215271364602995d85607cfc06d441Brian Paulinterpolate_texcoords(GLcontext *ctx, SWspan *span) 5432a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul{ 544e4f976b8b9d74a74b5816146cb11880c3a493929Brian const GLuint maxUnit 545e4f976b8b9d74a74b5816146cb11880c3a493929Brian = (ctx->Texture._EnabledCoordUnits > 1) ? ctx->Const.MaxTextureUnits : 1; 546e4f976b8b9d74a74b5816146cb11880c3a493929Brian GLuint u; 547e4f976b8b9d74a74b5816146cb11880c3a493929Brian 5482a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul ASSERT(span->interpMask & SPAN_TEXTURE); 549b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul ASSERT(!(span->arrayMask & SPAN_TEXTURE)); 5502a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 551e4f976b8b9d74a74b5816146cb11880c3a493929Brian span->arrayMask |= SPAN_TEXTURE; 552e4f976b8b9d74a74b5816146cb11880c3a493929Brian 553e4f976b8b9d74a74b5816146cb11880c3a493929Brian /* XXX CoordUnits vs. ImageUnits */ 554e4f976b8b9d74a74b5816146cb11880c3a493929Brian for (u = 0; u < maxUnit; u++) { 555e4f976b8b9d74a74b5816146cb11880c3a493929Brian if (ctx->Texture._EnabledCoordUnits & (1 << u)) { 556e4f976b8b9d74a74b5816146cb11880c3a493929Brian const GLuint attr = FRAG_ATTRIB_TEX0 + u; 557e4f976b8b9d74a74b5816146cb11880c3a493929Brian const struct gl_texture_object *obj =ctx->Texture.Unit[u]._Current; 558e4f976b8b9d74a74b5816146cb11880c3a493929Brian GLfloat texW, texH; 559e4f976b8b9d74a74b5816146cb11880c3a493929Brian GLboolean needLambda; 560e4f976b8b9d74a74b5816146cb11880c3a493929Brian GLfloat (*texcoord)[4] = span->array->attribs[attr]; 561e4f976b8b9d74a74b5816146cb11880c3a493929Brian GLfloat *lambda = span->array->lambda[u]; 562e4f976b8b9d74a74b5816146cb11880c3a493929Brian const GLfloat dsdx = span->attrStepX[attr][0]; 563e4f976b8b9d74a74b5816146cb11880c3a493929Brian const GLfloat dsdy = span->attrStepY[attr][0]; 564e4f976b8b9d74a74b5816146cb11880c3a493929Brian const GLfloat dtdx = span->attrStepX[attr][1]; 565e4f976b8b9d74a74b5816146cb11880c3a493929Brian const GLfloat dtdy = span->attrStepY[attr][1]; 566e4f976b8b9d74a74b5816146cb11880c3a493929Brian const GLfloat drdx = span->attrStepX[attr][2]; 567e4f976b8b9d74a74b5816146cb11880c3a493929Brian const GLfloat dqdx = span->attrStepX[attr][3]; 568e4f976b8b9d74a74b5816146cb11880c3a493929Brian const GLfloat dqdy = span->attrStepY[attr][3]; 569e4f976b8b9d74a74b5816146cb11880c3a493929Brian GLfloat s = span->attrStart[attr][0]; 570e4f976b8b9d74a74b5816146cb11880c3a493929Brian GLfloat t = span->attrStart[attr][1]; 571e4f976b8b9d74a74b5816146cb11880c3a493929Brian GLfloat r = span->attrStart[attr][2]; 572e4f976b8b9d74a74b5816146cb11880c3a493929Brian GLfloat q = span->attrStart[attr][3]; 573e4f976b8b9d74a74b5816146cb11880c3a493929Brian 574e4f976b8b9d74a74b5816146cb11880c3a493929Brian if (obj) { 575e4f976b8b9d74a74b5816146cb11880c3a493929Brian const struct gl_texture_image *img = obj->Image[0][obj->BaseLevel]; 576e4f976b8b9d74a74b5816146cb11880c3a493929Brian needLambda = (obj->MinFilter != obj->MagFilter) 577e4f976b8b9d74a74b5816146cb11880c3a493929Brian || ctx->FragmentProgram._Current; 578e4f976b8b9d74a74b5816146cb11880c3a493929Brian texW = img->WidthScale; 579e4f976b8b9d74a74b5816146cb11880c3a493929Brian texH = img->HeightScale; 580e4f976b8b9d74a74b5816146cb11880c3a493929Brian } 581e4f976b8b9d74a74b5816146cb11880c3a493929Brian else { 582e4f976b8b9d74a74b5816146cb11880c3a493929Brian /* using a fragment program */ 583e4f976b8b9d74a74b5816146cb11880c3a493929Brian texW = 1.0; 584e4f976b8b9d74a74b5816146cb11880c3a493929Brian texH = 1.0; 585e4f976b8b9d74a74b5816146cb11880c3a493929Brian needLambda = GL_FALSE; 586e4f976b8b9d74a74b5816146cb11880c3a493929Brian } 587e4f976b8b9d74a74b5816146cb11880c3a493929Brian 588e4f976b8b9d74a74b5816146cb11880c3a493929Brian if (needLambda) { 589e4f976b8b9d74a74b5816146cb11880c3a493929Brian GLuint i; 590e4f976b8b9d74a74b5816146cb11880c3a493929Brian if (ctx->FragmentProgram._Current 591e4f976b8b9d74a74b5816146cb11880c3a493929Brian || ctx->ATIFragmentShader._Enabled) { 592e4f976b8b9d74a74b5816146cb11880c3a493929Brian /* do perspective correction but don't divide s, t, r by q */ 593e4f976b8b9d74a74b5816146cb11880c3a493929Brian const GLfloat dwdx = span->attrStepX[FRAG_ATTRIB_WPOS][3]; 594e4f976b8b9d74a74b5816146cb11880c3a493929Brian GLfloat w = span->attrStart[FRAG_ATTRIB_WPOS][3]; 595e4f976b8b9d74a74b5816146cb11880c3a493929Brian for (i = 0; i < span->end; i++) { 596e4f976b8b9d74a74b5816146cb11880c3a493929Brian const GLfloat invW = 1.0F / w; 597e4f976b8b9d74a74b5816146cb11880c3a493929Brian texcoord[i][0] = s * invW; 598e4f976b8b9d74a74b5816146cb11880c3a493929Brian texcoord[i][1] = t * invW; 599e4f976b8b9d74a74b5816146cb11880c3a493929Brian texcoord[i][2] = r * invW; 600e4f976b8b9d74a74b5816146cb11880c3a493929Brian texcoord[i][3] = q * invW; 601e4f976b8b9d74a74b5816146cb11880c3a493929Brian lambda[i] = _swrast_compute_lambda(dsdx, dsdy, dtdx, dtdy, 602e4f976b8b9d74a74b5816146cb11880c3a493929Brian dqdx, dqdy, texW, texH, 603e4f976b8b9d74a74b5816146cb11880c3a493929Brian s, t, q, invW); 604e4f976b8b9d74a74b5816146cb11880c3a493929Brian s += dsdx; 605e4f976b8b9d74a74b5816146cb11880c3a493929Brian t += dtdx; 606e4f976b8b9d74a74b5816146cb11880c3a493929Brian r += drdx; 607e4f976b8b9d74a74b5816146cb11880c3a493929Brian q += dqdx; 608e4f976b8b9d74a74b5816146cb11880c3a493929Brian w += dwdx; 6092a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 6102a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 61131f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul else { 612e4f976b8b9d74a74b5816146cb11880c3a493929Brian for (i = 0; i < span->end; i++) { 6132a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q); 614e4f976b8b9d74a74b5816146cb11880c3a493929Brian texcoord[i][0] = s * invQ; 615e4f976b8b9d74a74b5816146cb11880c3a493929Brian texcoord[i][1] = t * invQ; 616e4f976b8b9d74a74b5816146cb11880c3a493929Brian texcoord[i][2] = r * invQ; 617e4f976b8b9d74a74b5816146cb11880c3a493929Brian texcoord[i][3] = q; 618e4f976b8b9d74a74b5816146cb11880c3a493929Brian lambda[i] = _swrast_compute_lambda(dsdx, dsdy, dtdx, dtdy, 619e4f976b8b9d74a74b5816146cb11880c3a493929Brian dqdx, dqdy, texW, texH, 620e4f976b8b9d74a74b5816146cb11880c3a493929Brian s, t, q, invQ); 621e4f976b8b9d74a74b5816146cb11880c3a493929Brian s += dsdx; 622e4f976b8b9d74a74b5816146cb11880c3a493929Brian t += dtdx; 623e4f976b8b9d74a74b5816146cb11880c3a493929Brian r += drdx; 624e4f976b8b9d74a74b5816146cb11880c3a493929Brian q += dqdx; 6252a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 626d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul } 627e4f976b8b9d74a74b5816146cb11880c3a493929Brian span->arrayMask |= SPAN_LAMBDA; 628d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul } 629d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul else { 630e4f976b8b9d74a74b5816146cb11880c3a493929Brian GLuint i; 631e4f976b8b9d74a74b5816146cb11880c3a493929Brian if (ctx->FragmentProgram._Current || 632e4f976b8b9d74a74b5816146cb11880c3a493929Brian ctx->ATIFragmentShader._Enabled) { 633e4f976b8b9d74a74b5816146cb11880c3a493929Brian /* do perspective correction but don't divide s, t, r by q */ 634e4f976b8b9d74a74b5816146cb11880c3a493929Brian const GLfloat dwdx = span->attrStepX[FRAG_ATTRIB_WPOS][3]; 635e4f976b8b9d74a74b5816146cb11880c3a493929Brian GLfloat w = span->attrStart[FRAG_ATTRIB_WPOS][3]; 636e4f976b8b9d74a74b5816146cb11880c3a493929Brian for (i = 0; i < span->end; i++) { 637e4f976b8b9d74a74b5816146cb11880c3a493929Brian const GLfloat invW = 1.0F / w; 638e4f976b8b9d74a74b5816146cb11880c3a493929Brian texcoord[i][0] = s * invW; 639e4f976b8b9d74a74b5816146cb11880c3a493929Brian texcoord[i][1] = t * invW; 640e4f976b8b9d74a74b5816146cb11880c3a493929Brian texcoord[i][2] = r * invW; 641e4f976b8b9d74a74b5816146cb11880c3a493929Brian texcoord[i][3] = q * invW; 642e4f976b8b9d74a74b5816146cb11880c3a493929Brian lambda[i] = 0.0; 643e4f976b8b9d74a74b5816146cb11880c3a493929Brian s += dsdx; 644e4f976b8b9d74a74b5816146cb11880c3a493929Brian t += dtdx; 645e4f976b8b9d74a74b5816146cb11880c3a493929Brian r += drdx; 646e4f976b8b9d74a74b5816146cb11880c3a493929Brian q += dqdx; 647e4f976b8b9d74a74b5816146cb11880c3a493929Brian w += dwdx; 648e4f976b8b9d74a74b5816146cb11880c3a493929Brian } 649c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul } 650e4f976b8b9d74a74b5816146cb11880c3a493929Brian else if (dqdx == 0.0F) { 651e4f976b8b9d74a74b5816146cb11880c3a493929Brian /* Ortho projection or polygon's parallel to window X axis */ 652c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q); 653e4f976b8b9d74a74b5816146cb11880c3a493929Brian for (i = 0; i < span->end; i++) { 654e4f976b8b9d74a74b5816146cb11880c3a493929Brian texcoord[i][0] = s * invQ; 655e4f976b8b9d74a74b5816146cb11880c3a493929Brian texcoord[i][1] = t * invQ; 656e4f976b8b9d74a74b5816146cb11880c3a493929Brian texcoord[i][2] = r * invQ; 657e4f976b8b9d74a74b5816146cb11880c3a493929Brian texcoord[i][3] = q; 658e4f976b8b9d74a74b5816146cb11880c3a493929Brian lambda[i] = 0.0; 659e4f976b8b9d74a74b5816146cb11880c3a493929Brian s += dsdx; 660e4f976b8b9d74a74b5816146cb11880c3a493929Brian t += dtdx; 661e4f976b8b9d74a74b5816146cb11880c3a493929Brian r += drdx; 662e4f976b8b9d74a74b5816146cb11880c3a493929Brian } 663c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul } 664e4f976b8b9d74a74b5816146cb11880c3a493929Brian else { 665e4f976b8b9d74a74b5816146cb11880c3a493929Brian for (i = 0; i < span->end; i++) { 666e4f976b8b9d74a74b5816146cb11880c3a493929Brian const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q); 667e4f976b8b9d74a74b5816146cb11880c3a493929Brian texcoord[i][0] = s * invQ; 668e4f976b8b9d74a74b5816146cb11880c3a493929Brian texcoord[i][1] = t * invQ; 669e4f976b8b9d74a74b5816146cb11880c3a493929Brian texcoord[i][2] = r * invQ; 670e4f976b8b9d74a74b5816146cb11880c3a493929Brian texcoord[i][3] = q; 671e4f976b8b9d74a74b5816146cb11880c3a493929Brian lambda[i] = 0.0; 672e4f976b8b9d74a74b5816146cb11880c3a493929Brian s += dsdx; 673e4f976b8b9d74a74b5816146cb11880c3a493929Brian t += dtdx; 674e4f976b8b9d74a74b5816146cb11880c3a493929Brian r += drdx; 675e4f976b8b9d74a74b5816146cb11880c3a493929Brian q += dqdx; 676e4f976b8b9d74a74b5816146cb11880c3a493929Brian } 677e4f976b8b9d74a74b5816146cb11880c3a493929Brian } 678e4f976b8b9d74a74b5816146cb11880c3a493929Brian } /* lambda */ 679e4f976b8b9d74a74b5816146cb11880c3a493929Brian } /* if */ 680e4f976b8b9d74a74b5816146cb11880c3a493929Brian } /* for */ 68110f30eb43835c57c00783390a02d72daf4f78e26Brian Paul} 682e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 683e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 684e4f976b8b9d74a74b5816146cb11880c3a493929Brian 68579c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/** 686abeca8d17d0728e68ec0c7cb9d9ca91b06b560d0Brian * Fill in the arrays->attribs[FRAG_ATTRIB_VARx] arrays from the 687abeca8d17d0728e68ec0c7cb9d9ca91b06b560d0Brian * interpolation values. 688abeca8d17d0728e68ec0c7cb9d9ca91b06b560d0Brian * XXX since interpolants/arrays are getting uniformed, we might merge 689abeca8d17d0728e68ec0c7cb9d9ca91b06b560d0Brian * this with interpolate_texcoords(), interpolate_Fog(), etc. someday. 690bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol */ 691f614a6190562e550257afca0d04e3846648942e8Brian Paulstatic INLINE void 692cdb27e8242215271364602995d85607cfc06d441Brian Paulinterpolate_varying(GLcontext *ctx, SWspan *span) 693bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol{ 694ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian GLuint var; 695ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian const GLbitfield inputsUsed = ctx->FragmentProgram._Current->Base.InputsRead; 696bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol 697bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol ASSERT(span->interpMask & SPAN_VARYING); 698bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol ASSERT(!(span->arrayMask & SPAN_VARYING)); 699bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol 700bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol span->arrayMask |= SPAN_VARYING; 701bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol 702ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian for (var = 0; var < MAX_VARYING; var++) { 703ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian if (inputsUsed & FRAG_BIT_VAR(var)) { 704462d8f5fafcc5ac69ea89cac1222abadded642e2Brian const GLuint attr = FRAG_ATTRIB_VAR0 + var; 705ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian GLuint j; 706ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian for (j = 0; j < 4; j++) { 707462d8f5fafcc5ac69ea89cac1222abadded642e2Brian const GLfloat dvdx = span->attrStepX[attr][j]; 708462d8f5fafcc5ac69ea89cac1222abadded642e2Brian GLfloat v = span->attrStart[attr][j]; 7099ab512ad8cf3a12f4f7f8494fa99bc9389f217dbBrian const GLfloat dwdx = span->attrStepX[FRAG_ATTRIB_WPOS][3]; 7109ab512ad8cf3a12f4f7f8494fa99bc9389f217dbBrian GLfloat w = span->attrStart[FRAG_ATTRIB_WPOS][3]; 711ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian GLuint k; 712ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian for (k = 0; k < span->end; k++) { 713ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian GLfloat invW = 1.0f / w; 714462d8f5fafcc5ac69ea89cac1222abadded642e2Brian span->array->attribs[attr][k][j] = v * invW; 715ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian v += dvdx; 716ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian w += dwdx; 717ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian } 718bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol } 719bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol } 720bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol } 721bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol} 722bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol 723bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol 724bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol/** 725f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian * Fill in the arrays->attribs[FRAG_ATTRIB_WPOS] array. 726f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian */ 727f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brianstatic INLINE void 728f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brianinterpolate_wpos(GLcontext *ctx, SWspan *span) 729f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian{ 730f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian GLfloat (*wpos)[4] = span->array->attribs[FRAG_ATTRIB_WPOS]; 731f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian GLuint i; 732f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian if (span->arrayMask & SPAN_XY) { 733f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian for (i = 0; i < span->end; i++) { 734f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian wpos[i][0] = (GLfloat) span->array->x[i]; 735f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian wpos[i][1] = (GLfloat) span->array->y[i]; 736f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian } 737f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian } 738f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian else { 739f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian for (i = 0; i < span->end; i++) { 740f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian wpos[i][0] = (GLfloat) span->x + i; 741f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian wpos[i][1] = (GLfloat) span->y; 742f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian } 743f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian } 744f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian for (i = 0; i < span->end; i++) { 745f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian wpos[i][2] = (GLfloat) span->array->z[i] / ctx->DrawBuffer->_DepthMaxF; 7469ab512ad8cf3a12f4f7f8494fa99bc9389f217dbBrian wpos[i][3] = span->attrStart[FRAG_ATTRIB_WPOS][3] 7479ab512ad8cf3a12f4f7f8494fa99bc9389f217dbBrian + i * span->attrStepX[FRAG_ATTRIB_WPOS][3]; 748f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian } 749f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian} 750f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian 751f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian 752f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian/** 753e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Apply the current polygon stipple pattern to a span of pixels. 754e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */ 755f614a6190562e550257afca0d04e3846648942e8Brian Paulstatic INLINE void 756ea8b68e0f7e7a4025ce662d36380157273ce10a3Brianstipple_polygon_span(GLcontext *ctx, SWspan *span) 75710f30eb43835c57c00783390a02d72daf4f78e26Brian Paul{ 75877df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul GLubyte *mask = span->array->mask; 759733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul 760733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul ASSERT(ctx->Polygon.StippleFlag); 76110f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 762ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian if (span->arrayMask & SPAN_XY) { 763ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian /* arrays of x/y pixel coords */ 764ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian GLuint i; 765ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian for (i = 0; i < span->end; i++) { 766ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian const GLint col = span->array->x[i] % 32; 767ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian const GLint row = span->array->y[i] % 32; 768ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian const GLuint stipple = ctx->PolygonStipple[row]; 769ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian if (((1 << col) & stipple) == 0) { 770ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian mask[i] = 0; 771ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian } 77210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 773ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian } 774ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian else { 775ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian /* horizontal span of pixels */ 776ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian const GLuint highBit = 1 << 31; 777ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian const GLuint stipple = ctx->PolygonStipple[span->y % 32]; 778ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian GLuint i, m = highBit >> (GLuint) (span->x % 32); 779ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian for (i = 0; i < span->end; i++) { 780ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian if ((m & stipple) == 0) { 781ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian mask[i] = 0; 782ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian } 783ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian m = m >> 1; 784ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian if (m == 0) { 785ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian m = highBit; 786ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian } 78710f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 78810f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 7892ef866d1fc0a5cc5ef8543d65744dfd4da4dbbafBrian Paul span->writeAll = GL_FALSE; 79010f30eb43835c57c00783390a02d72daf4f78e26Brian Paul} 79110f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 792e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 79379c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/** 794733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul * Clip a pixel span to the current buffer/window boundaries: 795733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul * DrawBuffer->_Xmin, _Xmax, _Ymin, _Ymax. This will accomplish 796733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul * window clipping and scissoring. 797733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul * Return: GL_TRUE some pixels still visible 79810f30eb43835c57c00783390a02d72daf4f78e26Brian Paul * GL_FALSE nothing visible 79910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul */ 800f614a6190562e550257afca0d04e3846648942e8Brian Paulstatic INLINE GLuint 801cdb27e8242215271364602995d85607cfc06d441Brian Paulclip_span( GLcontext *ctx, SWspan *span ) 80210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul{ 803733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul const GLint xmin = ctx->DrawBuffer->_Xmin; 804733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul const GLint xmax = ctx->DrawBuffer->_Xmax; 805733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul const GLint ymin = ctx->DrawBuffer->_Ymin; 806733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul const GLint ymax = ctx->DrawBuffer->_Ymax; 807733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul 808733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (span->arrayMask & SPAN_XY) { 809733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* arrays of x/y pixel coords */ 81077df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul const GLint *x = span->array->x; 81177df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul const GLint *y = span->array->y; 812733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul const GLint n = span->end; 81377df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul GLubyte *mask = span->array->mask; 814733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul GLint i; 815b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul if (span->arrayMask & SPAN_MASK) { 816b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul /* note: using & intead of && to reduce branches */ 817b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul for (i = 0; i < n; i++) { 818b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul mask[i] &= (x[i] >= xmin) & (x[i] < xmax) 819b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul & (y[i] >= ymin) & (y[i] < ymax); 820b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul } 821b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul } 822b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul else { 823b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul /* note: using & intead of && to reduce branches */ 824b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul for (i = 0; i < n; i++) { 825b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul mask[i] = (x[i] >= xmin) & (x[i] < xmax) 826b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul & (y[i] >= ymin) & (y[i] < ymax); 827b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul } 82810f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 829733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul return GL_TRUE; /* some pixels visible */ 83010f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 831733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul else { 832733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* horizontal span of pixels */ 833733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul const GLint x = span->x; 834733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul const GLint y = span->y; 835733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul const GLint n = span->end; 836733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul 837733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* Trivial rejection tests */ 838733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (y < ymin || y >= ymax || x + n <= xmin || x >= xmax) { 839733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->end = 0; 840733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul return GL_FALSE; /* all pixels clipped */ 841733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul } 84210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 843733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* Clip to the left */ 844733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (x < xmin) { 845733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul ASSERT(x + n > xmin); 846733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->writeAll = GL_FALSE; 8476ec6b845fdf3c44436028ad6fff9471d18928719Brian Paul _mesa_bzero(span->array->mask, (xmin - x) * sizeof(GLubyte)); 84810f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 849733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul 850733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* Clip to right */ 851733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (x + n > xmax) { 852733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul ASSERT(x < xmax); 853733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->end = xmax - x; 85410f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 85510f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 856733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul return GL_TRUE; /* some pixels visible */ 857733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul } 85810f30eb43835c57c00783390a02d72daf4f78e26Brian Paul} 85910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 86010f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 86179c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/** 862e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul * Apply all the per-fragment opertions to a span of color index fragments 863e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul * and write them to the enabled color drawbuffers. 864e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul * The 'span' parameter can be considered to be const. Note that 8657956292a765910077f50352d7cd0174e1e66d26cBrian Paul * span->interpMask and span->arrayMask may be changed but will be restored 8667956292a765910077f50352d7cd0174e1e66d26cBrian Paul * to their original values before returning. 86710f30eb43835c57c00783390a02d72daf4f78e26Brian Paul */ 86810f30eb43835c57c00783390a02d72daf4f78e26Brian Paulvoid 869cdb27e8242215271364602995d85607cfc06d441Brian Paul_swrast_write_index_span( GLcontext *ctx, SWspan *span) 87010f30eb43835c57c00783390a02d72daf4f78e26Brian Paul{ 871e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul const SWcontext *swrast = SWRAST_CONTEXT(ctx); 872e00ac11d4dd05c56584622dc2707bbdcfe4b2707Brian Paul const GLbitfield origInterpMask = span->interpMask; 873e00ac11d4dd05c56584622dc2707bbdcfe4b2707Brian Paul const GLbitfield origArrayMask = span->arrayMask; 87410f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 875733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul ASSERT(span->end <= MAX_WIDTH); 876b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul ASSERT(span->primitive == GL_POINT || span->primitive == GL_LINE || 877b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul span->primitive == GL_POLYGON || span->primitive == GL_BITMAP); 878733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul ASSERT((span->interpMask | span->arrayMask) & SPAN_INDEX); 8797956292a765910077f50352d7cd0174e1e66d26cBrian Paul ASSERT((span->interpMask & span->arrayMask) == 0); 8807956292a765910077f50352d7cd0174e1e66d26cBrian Paul 881733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (span->arrayMask & SPAN_MASK) { 882733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* mask was initialized by caller, probably glBitmap */ 883733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->writeAll = GL_FALSE; 884733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul } 885733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul else { 886a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul _mesa_memset(span->array->mask, 1, span->end); 887733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->writeAll = GL_TRUE; 88810f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 88910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 890733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* Clipping */ 891b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul if ((swrast->_RasterMask & CLIP_BIT) || (span->primitive != GL_POLYGON)) { 892733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (!clip_span(ctx, span)) { 89386ca15ece74ccb5a8f4d566a4b2c8024b178d73bBrian Paul return; 894e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 895e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 896e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 897e5b244ff7f984805c1bcc020342f1300f2639c71Brian Paul /* Depth bounds test */ 89831e739a18931fa48454f172818245b0927c8910fBrian Paul if (ctx->Depth.BoundsTest && ctx->DrawBuffer->Visual.depthBits > 0) { 899e5b244ff7f984805c1bcc020342f1300f2639c71Brian Paul if (!_swrast_depth_bounds_test(ctx, span)) { 900e5b244ff7f984805c1bcc020342f1300f2639c71Brian Paul return; 901e5b244ff7f984805c1bcc020342f1300f2639c71Brian Paul } 902e5b244ff7f984805c1bcc020342f1300f2639c71Brian Paul } 903e5b244ff7f984805c1bcc020342f1300f2639c71Brian Paul 904b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul#ifdef DEBUG 905a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul /* Make sure all fragments are within window bounds */ 906b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul if (span->arrayMask & SPAN_XY) { 907a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul GLuint i; 908b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul for (i = 0; i < span->end; i++) { 90977df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul if (span->array->mask[i]) { 91077df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul assert(span->array->x[i] >= ctx->DrawBuffer->_Xmin); 91177df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul assert(span->array->x[i] < ctx->DrawBuffer->_Xmax); 91277df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul assert(span->array->y[i] >= ctx->DrawBuffer->_Ymin); 91377df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul assert(span->array->y[i] < ctx->DrawBuffer->_Ymax); 914b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul } 915b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul } 916b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul } 917b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul#endif 918b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul 919e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* Polygon Stippling */ 920b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul if (ctx->Polygon.StippleFlag && span->primitive == GL_POLYGON) { 92110f30eb43835c57c00783390a02d72daf4f78e26Brian Paul stipple_polygon_span(ctx, span); 922e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 923e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 924e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul /* Stencil and Z testing */ 9257956292a765910077f50352d7cd0174e1e66d26cBrian Paul if (ctx->Depth.Test || ctx->Stencil.Enabled) { 9267956292a765910077f50352d7cd0174e1e66d26cBrian Paul if (span->interpMask & SPAN_Z) 92745bc887da226403f2c41077e40ca38b6f60f1359Brian Paul _swrast_span_interpolate_z(ctx, span); 92810f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 9297956292a765910077f50352d7cd0174e1e66d26cBrian Paul if (ctx->Stencil.Enabled) { 93045bc887da226403f2c41077e40ca38b6f60f1359Brian Paul if (!_swrast_stencil_and_ztest_span(ctx, span)) { 9317956292a765910077f50352d7cd0174e1e66d26cBrian Paul span->arrayMask = origArrayMask; 9327956292a765910077f50352d7cd0174e1e66d26cBrian Paul return; 9337956292a765910077f50352d7cd0174e1e66d26cBrian Paul } 9342a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 9357956292a765910077f50352d7cd0174e1e66d26cBrian Paul else { 9367956292a765910077f50352d7cd0174e1e66d26cBrian Paul ASSERT(ctx->Depth.Test); 93745bc887da226403f2c41077e40ca38b6f60f1359Brian Paul if (!_swrast_depth_test_span(ctx, span)) { 938e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul span->interpMask = origInterpMask; 9397956292a765910077f50352d7cd0174e1e66d26cBrian Paul span->arrayMask = origArrayMask; 9407956292a765910077f50352d7cd0174e1e66d26cBrian Paul return; 9417956292a765910077f50352d7cd0174e1e66d26cBrian Paul } 9422a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 94310f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 94410f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 945b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul#if FEATURE_ARB_occlusion_query 94623ffc3a85d6172f8a98d17d7f23610bab808d84eBrian Paul if (ctx->Query.CurrentOcclusionObject) { 947939dd17653245621bf7488803f09418244b7b0b7Brian Paul /* update count of 'passed' fragments */ 94823ffc3a85d6172f8a98d17d7f23610bab808d84eBrian Paul struct gl_query_object *q = ctx->Query.CurrentOcclusionObject; 949b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul GLuint i; 950b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul for (i = 0; i < span->end; i++) 95123ffc3a85d6172f8a98d17d7f23610bab808d84eBrian Paul q->Result += span->array->mask[i]; 952b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul } 953b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul#endif 954b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul 9557956292a765910077f50352d7cd0174e1e66d26cBrian Paul /* we have to wait until after occlusion to do this test */ 9567956292a765910077f50352d7cd0174e1e66d26cBrian Paul if (ctx->Color.DrawBuffer == GL_NONE || ctx->Color.IndexMask == 0) { 95710f30eb43835c57c00783390a02d72daf4f78e26Brian Paul /* write no pixels */ 9582a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->arrayMask = origArrayMask; 95910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul return; 96010f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 96110f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 9627956292a765910077f50352d7cd0174e1e66d26cBrian Paul /* Interpolate the color indexes if needed */ 963dcf4c17fb1624af47181c63af4c3ad29f919c17aBrian Paul if (swrast->_FogEnabled || 964e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul ctx->Color.IndexLogicOpEnabled || 965e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul ctx->Color.IndexMask != 0xffffffff || 966e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul (span->arrayMask & SPAN_COVERAGE)) { 967e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul if (span->interpMask & SPAN_INDEX) { 968e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul interpolate_indexes(ctx, span); 969e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul } 9707956292a765910077f50352d7cd0174e1e66d26cBrian Paul } 97110f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 9727956292a765910077f50352d7cd0174e1e66d26cBrian Paul /* Fog */ 973dcf4c17fb1624af47181c63af4c3ad29f919c17aBrian Paul if (swrast->_FogEnabled) { 97445bc887da226403f2c41077e40ca38b6f60f1359Brian Paul _swrast_fog_ci_span(ctx, span); 975e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 976e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 9772a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul /* Antialias coverage application */ 9782a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul if (span->arrayMask & SPAN_COVERAGE) { 979e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul const GLfloat *coverage = span->array->coverage; 98077df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul GLuint *index = span->array->index; 981e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul GLuint i; 98210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul for (i = 0; i < span->end; i++) { 98377df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul ASSERT(coverage[i] < 16); 98477df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul index[i] = (index[i] & ~0xf) | ((GLuint) coverage[i]); 9855071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paul } 9862a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 9875071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paul 988ba001224a18fa12792696ef393e708e90092127eBrian Paul /* 989ba001224a18fa12792696ef393e708e90092127eBrian Paul * Write to renderbuffers 990ba001224a18fa12792696ef393e708e90092127eBrian Paul */ 991ba001224a18fa12792696ef393e708e90092127eBrian Paul { 992ba001224a18fa12792696ef393e708e90092127eBrian Paul struct gl_framebuffer *fb = ctx->DrawBuffer; 993a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul const GLuint output = 0; /* only frag progs can write to other outputs */ 994ba001224a18fa12792696ef393e708e90092127eBrian Paul const GLuint numDrawBuffers = fb->_NumColorDrawBuffers[output]; 995ba001224a18fa12792696ef393e708e90092127eBrian Paul GLuint indexSave[MAX_WIDTH]; 996ba001224a18fa12792696ef393e708e90092127eBrian Paul GLuint buf; 997e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul 998ba001224a18fa12792696ef393e708e90092127eBrian Paul if (numDrawBuffers > 1) { 999ba001224a18fa12792696ef393e708e90092127eBrian Paul /* save indexes for second, third renderbuffer writes */ 1000ba001224a18fa12792696ef393e708e90092127eBrian Paul _mesa_memcpy(indexSave, span->array->index, 1001ba001224a18fa12792696ef393e708e90092127eBrian Paul span->end * sizeof(indexSave[0])); 1002ba001224a18fa12792696ef393e708e90092127eBrian Paul } 1003e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul 1004ba001224a18fa12792696ef393e708e90092127eBrian Paul for (buf = 0; buf < fb->_NumColorDrawBuffers[output]; buf++) { 1005ba001224a18fa12792696ef393e708e90092127eBrian Paul struct gl_renderbuffer *rb = fb->_ColorDrawBuffers[output][buf]; 1006ba001224a18fa12792696ef393e708e90092127eBrian Paul ASSERT(rb->_BaseFormat == GL_COLOR_INDEX); 10072a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 1008e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul if (ctx->Color.IndexLogicOpEnabled) { 1009f515c78a2320369ead087c4e0efd583f17b4b78bBrian Paul _swrast_logicop_ci_span(ctx, rb, span); 1010e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul } 1011e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul 1012e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul if (ctx->Color.IndexMask != 0xffffffff) { 1013f515c78a2320369ead087c4e0efd583f17b4b78bBrian Paul _swrast_mask_ci_span(ctx, rb, span); 1014e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul } 10152a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 1016ba001224a18fa12792696ef393e708e90092127eBrian Paul if ((span->interpMask & SPAN_INDEX) && span->indexStep == 0) { 1017ba001224a18fa12792696ef393e708e90092127eBrian Paul /* all fragments have same color index */ 1018ba001224a18fa12792696ef393e708e90092127eBrian Paul GLubyte index8; 1019ba001224a18fa12792696ef393e708e90092127eBrian Paul GLushort index16; 1020ba001224a18fa12792696ef393e708e90092127eBrian Paul GLuint index32; 1021ba001224a18fa12792696ef393e708e90092127eBrian Paul void *value; 1022e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul 1023ba001224a18fa12792696ef393e708e90092127eBrian Paul if (rb->DataType == GL_UNSIGNED_BYTE) { 1024ba001224a18fa12792696ef393e708e90092127eBrian Paul index8 = FixedToInt(span->index); 1025ba001224a18fa12792696ef393e708e90092127eBrian Paul value = &index8; 1026ba001224a18fa12792696ef393e708e90092127eBrian Paul } 1027ba001224a18fa12792696ef393e708e90092127eBrian Paul else if (rb->DataType == GL_UNSIGNED_SHORT) { 1028ba001224a18fa12792696ef393e708e90092127eBrian Paul index16 = FixedToInt(span->index); 1029ba001224a18fa12792696ef393e708e90092127eBrian Paul value = &index16; 1030ba001224a18fa12792696ef393e708e90092127eBrian Paul } 1031ba001224a18fa12792696ef393e708e90092127eBrian Paul else { 1032ba001224a18fa12792696ef393e708e90092127eBrian Paul ASSERT(rb->DataType == GL_UNSIGNED_INT); 1033ba001224a18fa12792696ef393e708e90092127eBrian Paul index32 = FixedToInt(span->index); 1034ba001224a18fa12792696ef393e708e90092127eBrian Paul value = &index32; 1035ba001224a18fa12792696ef393e708e90092127eBrian Paul } 1036e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul 1037ba001224a18fa12792696ef393e708e90092127eBrian Paul if (span->arrayMask & SPAN_XY) { 1038ba001224a18fa12792696ef393e708e90092127eBrian Paul rb->PutMonoValues(ctx, rb, span->end, span->array->x, 1039ba001224a18fa12792696ef393e708e90092127eBrian Paul span->array->y, value, span->array->mask); 1040e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul } 1041ba001224a18fa12792696ef393e708e90092127eBrian Paul else { 1042ba001224a18fa12792696ef393e708e90092127eBrian Paul rb->PutMonoRow(ctx, rb, span->end, span->x, span->y, 1043ba001224a18fa12792696ef393e708e90092127eBrian Paul value, span->array->mask); 1044e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul } 1045733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul } 1046733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul else { 1047ba001224a18fa12792696ef393e708e90092127eBrian Paul /* each fragment is a different color */ 1048ba001224a18fa12792696ef393e708e90092127eBrian Paul GLubyte index8[MAX_WIDTH]; 1049ba001224a18fa12792696ef393e708e90092127eBrian Paul GLushort index16[MAX_WIDTH]; 1050ba001224a18fa12792696ef393e708e90092127eBrian Paul void *values; 1051ba001224a18fa12792696ef393e708e90092127eBrian Paul 1052ba001224a18fa12792696ef393e708e90092127eBrian Paul if (rb->DataType == GL_UNSIGNED_BYTE) { 1053ba001224a18fa12792696ef393e708e90092127eBrian Paul GLuint k; 1054ba001224a18fa12792696ef393e708e90092127eBrian Paul for (k = 0; k < span->end; k++) { 1055ba001224a18fa12792696ef393e708e90092127eBrian Paul index8[k] = (GLubyte) span->array->index[k]; 1056ba001224a18fa12792696ef393e708e90092127eBrian Paul } 1057ba001224a18fa12792696ef393e708e90092127eBrian Paul values = index8; 1058ba001224a18fa12792696ef393e708e90092127eBrian Paul } 1059ba001224a18fa12792696ef393e708e90092127eBrian Paul else if (rb->DataType == GL_UNSIGNED_SHORT) { 1060ba001224a18fa12792696ef393e708e90092127eBrian Paul GLuint k; 1061ba001224a18fa12792696ef393e708e90092127eBrian Paul for (k = 0; k < span->end; k++) { 1062ba001224a18fa12792696ef393e708e90092127eBrian Paul index16[k] = (GLushort) span->array->index[k]; 1063ba001224a18fa12792696ef393e708e90092127eBrian Paul } 1064ba001224a18fa12792696ef393e708e90092127eBrian Paul values = index16; 1065ba001224a18fa12792696ef393e708e90092127eBrian Paul } 1066ba001224a18fa12792696ef393e708e90092127eBrian Paul else { 1067ba001224a18fa12792696ef393e708e90092127eBrian Paul ASSERT(rb->DataType == GL_UNSIGNED_INT); 1068ba001224a18fa12792696ef393e708e90092127eBrian Paul values = span->array->index; 1069ba001224a18fa12792696ef393e708e90092127eBrian Paul } 1070e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul 1071ba001224a18fa12792696ef393e708e90092127eBrian Paul if (span->arrayMask & SPAN_XY) { 1072ba001224a18fa12792696ef393e708e90092127eBrian Paul rb->PutValues(ctx, rb, span->end, 1073ba001224a18fa12792696ef393e708e90092127eBrian Paul span->array->x, span->array->y, 1074ba001224a18fa12792696ef393e708e90092127eBrian Paul values, span->array->mask); 1075ba001224a18fa12792696ef393e708e90092127eBrian Paul } 1076ba001224a18fa12792696ef393e708e90092127eBrian Paul else { 1077ba001224a18fa12792696ef393e708e90092127eBrian Paul rb->PutRow(ctx, rb, span->end, span->x, span->y, 1078e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul values, span->array->mask); 1079ba001224a18fa12792696ef393e708e90092127eBrian Paul } 1080e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul } 1081ba001224a18fa12792696ef393e708e90092127eBrian Paul 1082ba001224a18fa12792696ef393e708e90092127eBrian Paul if (buf + 1 < numDrawBuffers) { 1083ba001224a18fa12792696ef393e708e90092127eBrian Paul /* restore original span values */ 1084ba001224a18fa12792696ef393e708e90092127eBrian Paul _mesa_memcpy(span->array->index, indexSave, 1085ba001224a18fa12792696ef393e708e90092127eBrian Paul span->end * sizeof(indexSave[0])); 1086733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul } 1087ba001224a18fa12792696ef393e708e90092127eBrian Paul } /* for buf */ 1088e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 10892a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 10907956292a765910077f50352d7cd0174e1e66d26cBrian Paul span->interpMask = origInterpMask; 10912a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->arrayMask = origArrayMask; 1092e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell} 1093e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 1094e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 109579c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/** 1096e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Add specular color to base color. This is used only when 1097f1e236987829393c81dc86ea19cb49eefe190317Brian Paul * GL_LIGHT_MODEL_COLOR_CONTROL = GL_SEPARATE_SPECULAR_COLOR. 1098e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */ 1099f614a6190562e550257afca0d04e3846648942e8Brian Paulstatic INLINE void 1100cdb27e8242215271364602995d85607cfc06d441Brian Pauladd_specular(GLcontext *ctx, SWspan *span) 1101e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell{ 1102d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul switch (span->array->ChanType) { 1103d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul case GL_UNSIGNED_BYTE: 1104d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul { 1105d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul GLubyte (*rgba)[4] = span->array->color.sz1.rgba; 1106d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul GLubyte (*spec)[4] = span->array->color.sz1.spec; 1107d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul GLuint i; 1108d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul for (i = 0; i < span->end; i++) { 1109d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul GLint r = rgba[i][RCOMP] + spec[i][RCOMP]; 1110d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul GLint g = rgba[i][GCOMP] + spec[i][GCOMP]; 1111d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul GLint b = rgba[i][BCOMP] + spec[i][BCOMP]; 1112d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul GLint a = rgba[i][ACOMP] + spec[i][ACOMP]; 1113d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul rgba[i][RCOMP] = MIN2(r, 255); 1114d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul rgba[i][GCOMP] = MIN2(g, 255); 1115d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul rgba[i][BCOMP] = MIN2(b, 255); 1116d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul rgba[i][ACOMP] = MIN2(a, 255); 1117d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul } 1118d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul } 1119d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul break; 1120d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul case GL_UNSIGNED_SHORT: 1121d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul { 1122d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul GLushort (*rgba)[4] = span->array->color.sz2.rgba; 1123d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul GLushort (*spec)[4] = span->array->color.sz2.spec; 1124d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul GLuint i; 1125d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul for (i = 0; i < span->end; i++) { 1126d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul GLint r = rgba[i][RCOMP] + spec[i][RCOMP]; 1127d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul GLint g = rgba[i][GCOMP] + spec[i][GCOMP]; 1128d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul GLint b = rgba[i][BCOMP] + spec[i][BCOMP]; 1129d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul GLint a = rgba[i][ACOMP] + spec[i][ACOMP]; 1130d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul rgba[i][RCOMP] = MIN2(r, 65535); 1131d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul rgba[i][GCOMP] = MIN2(g, 65535); 1132d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul rgba[i][BCOMP] = MIN2(b, 65535); 1133d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul rgba[i][ACOMP] = MIN2(a, 65535); 1134d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul } 1135d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul } 1136d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul break; 1137d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul case GL_FLOAT: 1138d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul { 1139f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian GLfloat (*rgba)[4] = span->array->attribs[FRAG_ATTRIB_COL0]; 1140f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian GLfloat (*spec)[4] = span->array->attribs[FRAG_ATTRIB_COL1]; 1141d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul GLuint i; 1142d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul for (i = 0; i < span->end; i++) { 1143d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul rgba[i][RCOMP] += spec[i][RCOMP]; 1144d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul rgba[i][GCOMP] += spec[i][GCOMP]; 1145d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul rgba[i][BCOMP] += spec[i][BCOMP]; 1146d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul rgba[i][ACOMP] += spec[i][ACOMP]; 1147d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul } 1148d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul } 1149d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul break; 1150d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul default: 1151d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul _mesa_problem(ctx, "Invalid datatype in add_specular"); 1152e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1153e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell} 1154e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 1155e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 115679c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/** 1157b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul * Apply antialiasing coverage value to alpha values. 1158b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul */ 1159f614a6190562e550257afca0d04e3846648942e8Brian Paulstatic INLINE void 1160b88af5b4681d2085cd784b930dc259b66a55347eBrian Paulapply_aa_coverage(SWspan *span) 1161b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul{ 1162b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul const GLfloat *coverage = span->array->coverage; 1163b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul GLuint i; 1164b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul if (span->array->ChanType == GL_UNSIGNED_BYTE) { 1165b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul GLubyte (*rgba)[4] = span->array->color.sz1.rgba; 1166b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul for (i = 0; i < span->end; i++) { 1167e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul const GLfloat a = rgba[i][ACOMP] * coverage[i]; 1168e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul rgba[i][ACOMP] = (GLubyte) CLAMP(a, 0.0, 255.0); 1169b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul ASSERT(coverage[i] >= 0.0); 1170b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul ASSERT(coverage[i] <= 1.0); 1171b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul } 1172b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul } 1173b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul else if (span->array->ChanType == GL_UNSIGNED_SHORT) { 1174b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul GLushort (*rgba)[4] = span->array->color.sz2.rgba; 1175b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul for (i = 0; i < span->end; i++) { 1176e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul const GLfloat a = rgba[i][ACOMP] * coverage[i]; 1177e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul rgba[i][ACOMP] = (GLushort) CLAMP(a, 0.0, 65535.0); 1178b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul } 1179b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul } 1180b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul else { 1181f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian GLfloat (*rgba)[4] = span->array->attribs[FRAG_ATTRIB_COL0]; 1182b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul for (i = 0; i < span->end; i++) { 1183b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul rgba[i][ACOMP] = rgba[i][ACOMP] * coverage[i]; 1184b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul } 1185b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul } 1186b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul} 1187b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul 1188b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul 1189b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul/** 119031293910b4e982f2ef54d79aff78f2f854121da1Brian Paul * Clamp span's float colors to [0,1] 119131293910b4e982f2ef54d79aff78f2f854121da1Brian Paul */ 1192f614a6190562e550257afca0d04e3846648942e8Brian Paulstatic INLINE void 119331293910b4e982f2ef54d79aff78f2f854121da1Brian Paulclamp_colors(SWspan *span) 119431293910b4e982f2ef54d79aff78f2f854121da1Brian Paul{ 1195f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian GLfloat (*rgba)[4] = span->array->attribs[FRAG_ATTRIB_COL0]; 119631293910b4e982f2ef54d79aff78f2f854121da1Brian Paul GLuint i; 119731293910b4e982f2ef54d79aff78f2f854121da1Brian Paul ASSERT(span->array->ChanType == GL_FLOAT); 119831293910b4e982f2ef54d79aff78f2f854121da1Brian Paul for (i = 0; i < span->end; i++) { 119931293910b4e982f2ef54d79aff78f2f854121da1Brian Paul rgba[i][RCOMP] = CLAMP(rgba[i][RCOMP], 0.0F, 1.0F); 120031293910b4e982f2ef54d79aff78f2f854121da1Brian Paul rgba[i][GCOMP] = CLAMP(rgba[i][GCOMP], 0.0F, 1.0F); 120131293910b4e982f2ef54d79aff78f2f854121da1Brian Paul rgba[i][BCOMP] = CLAMP(rgba[i][BCOMP], 0.0F, 1.0F); 120231293910b4e982f2ef54d79aff78f2f854121da1Brian Paul rgba[i][ACOMP] = CLAMP(rgba[i][ACOMP], 0.0F, 1.0F); 120331293910b4e982f2ef54d79aff78f2f854121da1Brian Paul } 120431293910b4e982f2ef54d79aff78f2f854121da1Brian Paul} 120531293910b4e982f2ef54d79aff78f2f854121da1Brian Paul 120631293910b4e982f2ef54d79aff78f2f854121da1Brian Paul 120731293910b4e982f2ef54d79aff78f2f854121da1Brian Paul/** 1208d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul * Convert the span's color arrays to the given type. 1209d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul */ 1210f614a6190562e550257afca0d04e3846648942e8Brian Paulstatic INLINE void 1211ea8b68e0f7e7a4025ce662d36380157273ce10a3Brianconvert_color_type(SWspan *span, GLenum newType) 1212d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul{ 1213f971e24cf0341dd2779196a0836327b74fc82336Brian Paul GLvoid *src, *dst; 1214f971e24cf0341dd2779196a0836327b74fc82336Brian Paul if (span->array->ChanType == GL_UNSIGNED_BYTE) { 1215f971e24cf0341dd2779196a0836327b74fc82336Brian Paul src = span->array->color.sz1.rgba; 1216f971e24cf0341dd2779196a0836327b74fc82336Brian Paul } 1217f971e24cf0341dd2779196a0836327b74fc82336Brian Paul else if (span->array->ChanType == GL_UNSIGNED_BYTE) { 1218f971e24cf0341dd2779196a0836327b74fc82336Brian Paul src = span->array->color.sz2.rgba; 1219f971e24cf0341dd2779196a0836327b74fc82336Brian Paul } 1220f971e24cf0341dd2779196a0836327b74fc82336Brian Paul else { 1221f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian src = span->array->attribs[FRAG_ATTRIB_COL0]; 1222f971e24cf0341dd2779196a0836327b74fc82336Brian Paul } 1223f971e24cf0341dd2779196a0836327b74fc82336Brian Paul if (newType == GL_UNSIGNED_BYTE) { 1224f971e24cf0341dd2779196a0836327b74fc82336Brian Paul dst = span->array->color.sz1.rgba; 1225f971e24cf0341dd2779196a0836327b74fc82336Brian Paul } 1226f971e24cf0341dd2779196a0836327b74fc82336Brian Paul else if (newType == GL_UNSIGNED_BYTE) { 1227f971e24cf0341dd2779196a0836327b74fc82336Brian Paul dst = span->array->color.sz2.rgba; 1228f971e24cf0341dd2779196a0836327b74fc82336Brian Paul } 1229f971e24cf0341dd2779196a0836327b74fc82336Brian Paul else { 1230f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian dst = span->array->attribs[FRAG_ATTRIB_COL0]; 1231f971e24cf0341dd2779196a0836327b74fc82336Brian Paul } 1232d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul 1233f971e24cf0341dd2779196a0836327b74fc82336Brian Paul _mesa_convert_colors(span->array->ChanType, src, 1234f971e24cf0341dd2779196a0836327b74fc82336Brian Paul newType, dst, 1235f971e24cf0341dd2779196a0836327b74fc82336Brian Paul span->end, span->array->mask); 1236d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul 1237d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul span->array->ChanType = newType; 1238d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul} 1239d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul 1240d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul 1241d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul 1242d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul/** 124361c89be3135cedc795e48d36283769298e250837Brian Paul * Apply fragment shader, fragment program or normal texturing to span. 124461c89be3135cedc795e48d36283769298e250837Brian Paul */ 1245f614a6190562e550257afca0d04e3846648942e8Brian Paulstatic INLINE void 124661c89be3135cedc795e48d36283769298e250837Brian Paulshade_texture_span(GLcontext *ctx, SWspan *span) 124761c89be3135cedc795e48d36283769298e250837Brian Paul{ 124861c89be3135cedc795e48d36283769298e250837Brian Paul /* Now we need the rgba array, fill it in if needed */ 124961c89be3135cedc795e48d36283769298e250837Brian Paul if (span->interpMask & SPAN_RGBA) 125061c89be3135cedc795e48d36283769298e250837Brian Paul interpolate_colors(span); 125161c89be3135cedc795e48d36283769298e250837Brian Paul 1252f614a6190562e550257afca0d04e3846648942e8Brian Paul if (ctx->Texture._EnabledCoordUnits && (span->interpMask & SPAN_TEXTURE)) 1253f614a6190562e550257afca0d04e3846648942e8Brian Paul interpolate_texcoords(ctx, span); 1254f614a6190562e550257afca0d04e3846648942e8Brian Paul 125512ef1fbefcee964b715783d3ade6b69b2c699ed8Brian if (ctx->FragmentProgram._Current || 125661c89be3135cedc795e48d36283769298e250837Brian Paul ctx->ATIFragmentShader._Enabled) { 125761c89be3135cedc795e48d36283769298e250837Brian Paul 125861c89be3135cedc795e48d36283769298e250837Brian Paul /* use float colors if running a fragment program or shader */ 125961c89be3135cedc795e48d36283769298e250837Brian Paul const GLenum oldType = span->array->ChanType; 126061c89be3135cedc795e48d36283769298e250837Brian Paul const GLenum newType = GL_FLOAT; 126161c89be3135cedc795e48d36283769298e250837Brian Paul if (oldType != newType) { 126261c89be3135cedc795e48d36283769298e250837Brian Paul GLvoid *src = (oldType == GL_UNSIGNED_BYTE) 126361c89be3135cedc795e48d36283769298e250837Brian Paul ? (GLvoid *) span->array->color.sz1.rgba 126461c89be3135cedc795e48d36283769298e250837Brian Paul : (GLvoid *) span->array->color.sz2.rgba; 126561c89be3135cedc795e48d36283769298e250837Brian Paul _mesa_convert_colors(oldType, src, 1266f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian newType, span->array->attribs[FRAG_ATTRIB_COL0], 126761c89be3135cedc795e48d36283769298e250837Brian Paul span->end, span->array->mask); 126861c89be3135cedc795e48d36283769298e250837Brian Paul span->array->ChanType = newType; 126961c89be3135cedc795e48d36283769298e250837Brian Paul } 127061c89be3135cedc795e48d36283769298e250837Brian Paul 127161c89be3135cedc795e48d36283769298e250837Brian Paul /* fragment programs/shaders may need specular, fog and Z coords */ 127261c89be3135cedc795e48d36283769298e250837Brian Paul if (span->interpMask & SPAN_SPEC) 127361c89be3135cedc795e48d36283769298e250837Brian Paul interpolate_specular(span); 127461c89be3135cedc795e48d36283769298e250837Brian Paul 127561c89be3135cedc795e48d36283769298e250837Brian Paul if (span->interpMask & SPAN_FOG) 127661c89be3135cedc795e48d36283769298e250837Brian Paul interpolate_fog(ctx, span); 127761c89be3135cedc795e48d36283769298e250837Brian Paul 127861c89be3135cedc795e48d36283769298e250837Brian Paul if (span->interpMask & SPAN_Z) 127961c89be3135cedc795e48d36283769298e250837Brian Paul _swrast_span_interpolate_z (ctx, span); 128061c89be3135cedc795e48d36283769298e250837Brian Paul 12810bf5dbe002a64e198f55724cc1542602c012490fBrian if (ctx->Shader.CurrentProgram && span->interpMask & SPAN_VARYING) 1282828d15a6e0907fe4bb7c564d453a2b1a05f109bcBrian Paul interpolate_varying(ctx, span); 128312ef1fbefcee964b715783d3ade6b69b2c699ed8Brian 1284f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian if (ctx->FragmentProgram._Current && 1285f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian (ctx->FragmentProgram._Current->Base.InputsRead & FRAG_BIT_WPOS)) 1286f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian interpolate_wpos(ctx, span); 1287f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian 128812ef1fbefcee964b715783d3ade6b69b2c699ed8Brian /* Run fragment program/shader now */ 128912ef1fbefcee964b715783d3ade6b69b2c699ed8Brian if (ctx->FragmentProgram._Current) { 129061c89be3135cedc795e48d36283769298e250837Brian Paul _swrast_exec_fragment_program(ctx, span); 129161c89be3135cedc795e48d36283769298e250837Brian Paul } 129261c89be3135cedc795e48d36283769298e250837Brian Paul else { 129361c89be3135cedc795e48d36283769298e250837Brian Paul ASSERT(ctx->ATIFragmentShader._Enabled); 129461c89be3135cedc795e48d36283769298e250837Brian Paul _swrast_exec_fragment_shader(ctx, span); 129561c89be3135cedc795e48d36283769298e250837Brian Paul } 129661c89be3135cedc795e48d36283769298e250837Brian Paul } 129761c89be3135cedc795e48d36283769298e250837Brian Paul else if (ctx->Texture._EnabledUnits && (span->arrayMask & SPAN_TEXTURE)) { 129861c89be3135cedc795e48d36283769298e250837Brian Paul /* conventional texturing */ 129961c89be3135cedc795e48d36283769298e250837Brian Paul _swrast_texture_span(ctx, span); 130061c89be3135cedc795e48d36283769298e250837Brian Paul } 130161c89be3135cedc795e48d36283769298e250837Brian Paul} 130261c89be3135cedc795e48d36283769298e250837Brian Paul 130361c89be3135cedc795e48d36283769298e250837Brian Paul 130461c89be3135cedc795e48d36283769298e250837Brian Paul 130561c89be3135cedc795e48d36283769298e250837Brian Paul/** 1306a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul * Apply all the per-fragment operations to a span. 1307a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul * This now includes texturing (_swrast_write_texture_span() is history). 1308f1e236987829393c81dc86ea19cb49eefe190317Brian Paul * This function may modify any of the array values in the span. 13097956292a765910077f50352d7cd0174e1e66d26cBrian Paul * span->interpMask and span->arrayMask may be changed but will be restored 13107956292a765910077f50352d7cd0174e1e66d26cBrian Paul * to their original values before returning. 131178940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul */ 131278940758e90069ceaca2b6cddb6438488fbad5ccBrian Paulvoid 1313cdb27e8242215271364602995d85607cfc06d441Brian Paul_swrast_write_rgba_span( GLcontext *ctx, SWspan *span) 131478940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul{ 131561c89be3135cedc795e48d36283769298e250837Brian Paul const SWcontext *swrast = SWRAST_CONTEXT(ctx); 131678940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul const GLuint colorMask = *((GLuint *) ctx->Color.ColorMask); 1317e00ac11d4dd05c56584622dc2707bbdcfe4b2707Brian Paul const GLbitfield origInterpMask = span->interpMask; 1318e00ac11d4dd05c56584622dc2707bbdcfe4b2707Brian Paul const GLbitfield origArrayMask = span->arrayMask; 1319c3caaa3dd45809e672177ab322445fe51d03af25Brian Paul const GLenum chanType = span->array->ChanType; 132012ef1fbefcee964b715783d3ade6b69b2c699ed8Brian const GLboolean shader = (ctx->FragmentProgram._Current 132112ef1fbefcee964b715783d3ade6b69b2c699ed8Brian || ctx->ATIFragmentShader._Enabled); 132261c89be3135cedc795e48d36283769298e250837Brian Paul const GLboolean shaderOrTexture = shader || ctx->Texture._EnabledUnits; 1323bb19e64d12eaf27e2adc3faac7e09555bb66d724Brian Paul GLboolean deferredTexture; 132461c89be3135cedc795e48d36283769298e250837Brian Paul 1325bb19e64d12eaf27e2adc3faac7e09555bb66d724Brian Paul /* 1326bb19e64d12eaf27e2adc3faac7e09555bb66d724Brian Paul printf("%s() interp 0x%x array 0x%x\n", __FUNCTION__, 1327bb19e64d12eaf27e2adc3faac7e09555bb66d724Brian Paul span->interpMask, span->arrayMask); 1328bb19e64d12eaf27e2adc3faac7e09555bb66d724Brian Paul */ 1329f1e236987829393c81dc86ea19cb49eefe190317Brian Paul 133031293910b4e982f2ef54d79aff78f2f854121da1Brian Paul ASSERT(span->primitive == GL_POINT || 133131293910b4e982f2ef54d79aff78f2f854121da1Brian Paul span->primitive == GL_LINE || 133231293910b4e982f2ef54d79aff78f2f854121da1Brian Paul span->primitive == GL_POLYGON || 133331293910b4e982f2ef54d79aff78f2f854121da1Brian Paul span->primitive == GL_BITMAP); 1334733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul ASSERT(span->end <= MAX_WIDTH); 13357956292a765910077f50352d7cd0174e1e66d26cBrian Paul ASSERT((span->interpMask & span->arrayMask) == 0); 133631293910b4e982f2ef54d79aff78f2f854121da1Brian Paul ASSERT((span->interpMask & SPAN_RGBA) ^ (span->arrayMask & SPAN_RGBA)); 133778940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul 1338bb19e64d12eaf27e2adc3faac7e09555bb66d724Brian Paul /* check for conditions that prevent deferred shading */ 1339bb19e64d12eaf27e2adc3faac7e09555bb66d724Brian Paul if (ctx->Color.AlphaEnabled) { 1340bb19e64d12eaf27e2adc3faac7e09555bb66d724Brian Paul /* alpha test depends on post-texture/shader colors */ 1341bb19e64d12eaf27e2adc3faac7e09555bb66d724Brian Paul deferredTexture = GL_FALSE; 1342bb19e64d12eaf27e2adc3faac7e09555bb66d724Brian Paul } 1343bb19e64d12eaf27e2adc3faac7e09555bb66d724Brian Paul else if (shaderOrTexture) { 134412ef1fbefcee964b715783d3ade6b69b2c699ed8Brian if (ctx->FragmentProgram._Current) { 1345ed324db249d068f14646eced55d106b5fe6b889cBrian Paul if (ctx->FragmentProgram.Current->Base.OutputsWritten 1346ed324db249d068f14646eced55d106b5fe6b889cBrian Paul & (1 << FRAG_RESULT_DEPR)) { 134712ef1fbefcee964b715783d3ade6b69b2c699ed8Brian /* Z comes from fragment program/shader */ 1348ed324db249d068f14646eced55d106b5fe6b889cBrian Paul deferredTexture = GL_FALSE; 1349ed324db249d068f14646eced55d106b5fe6b889cBrian Paul } 1350ed324db249d068f14646eced55d106b5fe6b889cBrian Paul else { 1351ed324db249d068f14646eced55d106b5fe6b889cBrian Paul deferredTexture = GL_TRUE; 1352ed324db249d068f14646eced55d106b5fe6b889cBrian Paul } 1353bb19e64d12eaf27e2adc3faac7e09555bb66d724Brian Paul } 1354bb19e64d12eaf27e2adc3faac7e09555bb66d724Brian Paul else { 1355bb19e64d12eaf27e2adc3faac7e09555bb66d724Brian Paul /* ATI frag shader or conventional texturing */ 1356bb19e64d12eaf27e2adc3faac7e09555bb66d724Brian Paul deferredTexture = GL_TRUE; 1357bb19e64d12eaf27e2adc3faac7e09555bb66d724Brian Paul } 1358bb19e64d12eaf27e2adc3faac7e09555bb66d724Brian Paul } 1359bb19e64d12eaf27e2adc3faac7e09555bb66d724Brian Paul else { 1360bb19e64d12eaf27e2adc3faac7e09555bb66d724Brian Paul /* no texturing or shadering */ 1361bb19e64d12eaf27e2adc3faac7e09555bb66d724Brian Paul deferredTexture = GL_FALSE; 1362bb19e64d12eaf27e2adc3faac7e09555bb66d724Brian Paul } 1363ceb39f4f8dc4863fde17d668c752533a2184476eBrian Paul 1364bb19e64d12eaf27e2adc3faac7e09555bb66d724Brian Paul /* Fragment write masks */ 1365733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (span->arrayMask & SPAN_MASK) { 1366733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* mask was initialized by caller, probably glBitmap */ 1367733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->writeAll = GL_FALSE; 1368733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul } 1369733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul else { 1370a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul _mesa_memset(span->array->mask, 1, span->end); 1371733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->writeAll = GL_TRUE; 137278940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul } 137378940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul 1374a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul /* Clip to window/scissor box */ 1375b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul if ((swrast->_RasterMask & CLIP_BIT) || (span->primitive != GL_POLYGON)) { 1376733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (!clip_span(ctx, span)) { 1377733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul return; 137878940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul } 137978940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul } 138078940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul 1381b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul#ifdef DEBUG 1382a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul /* Make sure all fragments are within window bounds */ 1383b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul if (span->arrayMask & SPAN_XY) { 1384a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul GLuint i; 1385b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul for (i = 0; i < span->end; i++) { 138677df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul if (span->array->mask[i]) { 138777df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul assert(span->array->x[i] >= ctx->DrawBuffer->_Xmin); 138877df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul assert(span->array->x[i] < ctx->DrawBuffer->_Xmax); 138977df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul assert(span->array->y[i] >= ctx->DrawBuffer->_Ymin); 139077df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul assert(span->array->y[i] < ctx->DrawBuffer->_Ymax); 1391b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul } 1392b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul } 1393b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul } 1394b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul#endif 1395b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul 139678940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul /* Polygon Stippling */ 1397b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul if (ctx->Polygon.StippleFlag && span->primitive == GL_POLYGON) { 1398733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul stipple_polygon_span(ctx, span); 139978940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul } 140078940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul 140132340aea1308153dad5c105fc0748aea1e4c37eeBrian Paul /* This is the normal place to compute the resulting fragment color/Z. 140232340aea1308153dad5c105fc0748aea1e4c37eeBrian Paul * As an optimization, we try to defer this until after Z/stencil 140332340aea1308153dad5c105fc0748aea1e4c37eeBrian Paul * testing in order to try to avoid computing colors that we won't 140432340aea1308153dad5c105fc0748aea1e4c37eeBrian Paul * actually need. 1405a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul */ 140661c89be3135cedc795e48d36283769298e250837Brian Paul if (shaderOrTexture && !deferredTexture) { 140761c89be3135cedc795e48d36283769298e250837Brian Paul shade_texture_span(ctx, span); 140861c89be3135cedc795e48d36283769298e250837Brian Paul } 1409c3caaa3dd45809e672177ab322445fe51d03af25Brian Paul 141061c89be3135cedc795e48d36283769298e250837Brian Paul /* Do the alpha test */ 141161c89be3135cedc795e48d36283769298e250837Brian Paul if (ctx->Color.AlphaEnabled) { 141261c89be3135cedc795e48d36283769298e250837Brian Paul if (!_swrast_alpha_test(ctx, span)) { 141361c89be3135cedc795e48d36283769298e250837Brian Paul goto end; 141478940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul } 141578940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul } 141678940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul 1417f1e236987829393c81dc86ea19cb49eefe190317Brian Paul /* Stencil and Z testing */ 1418f1e236987829393c81dc86ea19cb49eefe190317Brian Paul if (ctx->Stencil.Enabled || ctx->Depth.Test) { 1419f1e236987829393c81dc86ea19cb49eefe190317Brian Paul if (span->interpMask & SPAN_Z) 142045bc887da226403f2c41077e40ca38b6f60f1359Brian Paul _swrast_span_interpolate_z(ctx, span); 142178940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul 1422e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul if (ctx->Stencil.Enabled && ctx->DrawBuffer->Visual.stencilBits > 0) { 1423a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul /* Combined Z/stencil tests */ 142445bc887da226403f2c41077e40ca38b6f60f1359Brian Paul if (!_swrast_stencil_and_ztest_span(ctx, span)) { 1425c3caaa3dd45809e672177ab322445fe51d03af25Brian Paul goto end; 1426f1e236987829393c81dc86ea19cb49eefe190317Brian Paul } 142771340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 1428e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul else if (ctx->DrawBuffer->Visual.depthBits > 0) { 1429a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul /* Just regular depth testing */ 1430f1e236987829393c81dc86ea19cb49eefe190317Brian Paul ASSERT(ctx->Depth.Test); 1431f1e236987829393c81dc86ea19cb49eefe190317Brian Paul ASSERT(span->arrayMask & SPAN_Z); 143245bc887da226403f2c41077e40ca38b6f60f1359Brian Paul if (!_swrast_depth_test_span(ctx, span)) { 1433c3caaa3dd45809e672177ab322445fe51d03af25Brian Paul goto end; 1434f1e236987829393c81dc86ea19cb49eefe190317Brian Paul } 143571340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 143671340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 143771340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul 1438b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul#if FEATURE_ARB_occlusion_query 143923ffc3a85d6172f8a98d17d7f23610bab808d84eBrian Paul if (ctx->Query.CurrentOcclusionObject) { 1440939dd17653245621bf7488803f09418244b7b0b7Brian Paul /* update count of 'passed' fragments */ 144123ffc3a85d6172f8a98d17d7f23610bab808d84eBrian Paul struct gl_query_object *q = ctx->Query.CurrentOcclusionObject; 1442b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul GLuint i; 1443b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul for (i = 0; i < span->end; i++) 144423ffc3a85d6172f8a98d17d7f23610bab808d84eBrian Paul q->Result += span->array->mask[i]; 1445b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul } 1446b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul#endif 1447b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul 1448a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul /* We had to wait until now to check for glColorMask(0,0,0,0) because of 1449f1e236987829393c81dc86ea19cb49eefe190317Brian Paul * the occlusion test. 1450f1e236987829393c81dc86ea19cb49eefe190317Brian Paul */ 1451f1e236987829393c81dc86ea19cb49eefe190317Brian Paul if (colorMask == 0x0) { 1452c3caaa3dd45809e672177ab322445fe51d03af25Brian Paul goto end; 145371340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 145471340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul 145532340aea1308153dad5c105fc0748aea1e4c37eeBrian Paul /* If we were able to defer fragment color computation to now, there's 145632340aea1308153dad5c105fc0748aea1e4c37eeBrian Paul * a good chance that many fragments will have already been killed by 145732340aea1308153dad5c105fc0748aea1e4c37eeBrian Paul * Z/stencil testing. 1458a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul */ 145932340aea1308153dad5c105fc0748aea1e4c37eeBrian Paul if (deferredTexture) { 146061c89be3135cedc795e48d36283769298e250837Brian Paul ASSERT(shaderOrTexture); 146161c89be3135cedc795e48d36283769298e250837Brian Paul shade_texture_span(ctx, span); 146261c89be3135cedc795e48d36283769298e250837Brian Paul } 1463d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul 146461c89be3135cedc795e48d36283769298e250837Brian Paul if ((span->arrayMask & SPAN_RGBA) == 0) { 146561c89be3135cedc795e48d36283769298e250837Brian Paul interpolate_colors(span); 146671340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 146771340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul 1468f1e236987829393c81dc86ea19cb49eefe190317Brian Paul ASSERT(span->arrayMask & SPAN_RGBA); 14692ef866d1fc0a5cc5ef8543d65744dfd4da4dbbafBrian Paul 147061c89be3135cedc795e48d36283769298e250837Brian Paul if (!shader) { 1471dfe508ca7af1a6d1099cd65e257512ed1e17d893Brian Paul /* Add base and specular colors */ 1472dfe508ca7af1a6d1099cd65e257512ed1e17d893Brian Paul if (ctx->Fog.ColorSumEnabled || 1473dfe508ca7af1a6d1099cd65e257512ed1e17d893Brian Paul (ctx->Light.Enabled && 1474dfe508ca7af1a6d1099cd65e257512ed1e17d893Brian Paul ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR)) { 1475dfe508ca7af1a6d1099cd65e257512ed1e17d893Brian Paul if (span->interpMask & SPAN_SPEC) { 1476e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul interpolate_specular(span); 1477dfe508ca7af1a6d1099cd65e257512ed1e17d893Brian Paul } 1478a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul if (span->arrayMask & SPAN_SPEC) { 1479d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul add_specular(ctx, span); 1480a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul } 1481a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul else { 1482a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul /* We probably added the base/specular colors during the 1483a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul * vertex stage! 1484a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul */ 1485a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul } 148671340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 148771340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 148871340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul 14896e1666437ea091ecc50ab2b56d87129318f641d2Brian Paul /* Fog */ 149009da0b8e6621a831e3eeb9381430f2bed18a22adBrian Paul if (swrast->_FogEnabled) { 149145bc887da226403f2c41077e40ca38b6f60f1359Brian Paul _swrast_fog_rgba_span(ctx, span); 149271340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 1493f1e236987829393c81dc86ea19cb49eefe190317Brian Paul 149471340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul /* Antialias coverage application */ 14952a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul if (span->arrayMask & SPAN_COVERAGE) { 1496b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul apply_aa_coverage(span); 149771340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 149871340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul 1499ba3da6154c324cc916845bc5de3de077d0b59ffcBrian Paul /* Clamp color/alpha values over the range [0.0, 1.0] before storage */ 15000b26e826bda0da7aeec9a79ee07fe21d54bb1263Brian Paul if (ctx->Color.ClampFragmentColor == GL_TRUE && 150131293910b4e982f2ef54d79aff78f2f854121da1Brian Paul span->array->ChanType == GL_FLOAT) { 150231293910b4e982f2ef54d79aff78f2f854121da1Brian Paul clamp_colors(span); 1503ba3da6154c324cc916845bc5de3de077d0b59ffcBrian Paul } 1504ba3da6154c324cc916845bc5de3de077d0b59ffcBrian Paul 1505ba001224a18fa12792696ef393e708e90092127eBrian Paul /* 1506ba001224a18fa12792696ef393e708e90092127eBrian Paul * Write to renderbuffers 1507ba001224a18fa12792696ef393e708e90092127eBrian Paul */ 1508ba001224a18fa12792696ef393e708e90092127eBrian Paul { 1509ba001224a18fa12792696ef393e708e90092127eBrian Paul struct gl_framebuffer *fb = ctx->DrawBuffer; 1510a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul const GLuint output = 0; /* only frag progs can write to other outputs */ 1511ba001224a18fa12792696ef393e708e90092127eBrian Paul const GLuint numDrawBuffers = fb->_NumColorDrawBuffers[output]; 1512ba001224a18fa12792696ef393e708e90092127eBrian Paul GLchan rgbaSave[MAX_WIDTH][4]; 1513ba001224a18fa12792696ef393e708e90092127eBrian Paul GLuint buf; 1514e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul 1515d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul if (numDrawBuffers > 0) { 1516d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul if (fb->_ColorDrawBuffers[output][0]->DataType 1517d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul != span->array->ChanType) { 1518ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian convert_color_type(span, 1519d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul fb->_ColorDrawBuffers[output][0]->DataType); 1520d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul } 1521d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul } 1522d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul 1523ba001224a18fa12792696ef393e708e90092127eBrian Paul if (numDrawBuffers > 1) { 1524ba001224a18fa12792696ef393e708e90092127eBrian Paul /* save colors for second, third renderbuffer writes */ 1525ba001224a18fa12792696ef393e708e90092127eBrian Paul _mesa_memcpy(rgbaSave, span->array->rgba, 1526ba001224a18fa12792696ef393e708e90092127eBrian Paul 4 * span->end * sizeof(GLchan)); 152771340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 152871340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul 1529ba001224a18fa12792696ef393e708e90092127eBrian Paul for (buf = 0; buf < numDrawBuffers; buf++) { 1530ba001224a18fa12792696ef393e708e90092127eBrian Paul struct gl_renderbuffer *rb = fb->_ColorDrawBuffers[output][buf]; 1531f971e24cf0341dd2779196a0836327b74fc82336Brian Paul ASSERT(rb->_BaseFormat == GL_RGBA || rb->_BaseFormat == GL_RGB); 153271340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul 1533ba001224a18fa12792696ef393e708e90092127eBrian Paul if (ctx->Color._LogicOpEnabled) { 1534f515c78a2320369ead087c4e0efd583f17b4b78bBrian Paul _swrast_logicop_rgba_span(ctx, rb, span); 1535ba001224a18fa12792696ef393e708e90092127eBrian Paul } 1536ba001224a18fa12792696ef393e708e90092127eBrian Paul else if (ctx->Color.BlendEnabled) { 1537f515c78a2320369ead087c4e0efd583f17b4b78bBrian Paul _swrast_blend_span(ctx, rb, span); 1538ba001224a18fa12792696ef393e708e90092127eBrian Paul } 1539ba001224a18fa12792696ef393e708e90092127eBrian Paul 1540ba001224a18fa12792696ef393e708e90092127eBrian Paul if (colorMask != 0xffffffff) { 1541f515c78a2320369ead087c4e0efd583f17b4b78bBrian Paul _swrast_mask_rgba_span(ctx, rb, span); 1542ba001224a18fa12792696ef393e708e90092127eBrian Paul } 1543ba001224a18fa12792696ef393e708e90092127eBrian Paul 1544ba001224a18fa12792696ef393e708e90092127eBrian Paul if (span->arrayMask & SPAN_XY) { 1545ba001224a18fa12792696ef393e708e90092127eBrian Paul /* array of pixel coords */ 1546ba001224a18fa12792696ef393e708e90092127eBrian Paul ASSERT(rb->PutValues); 1547ba001224a18fa12792696ef393e708e90092127eBrian Paul rb->PutValues(ctx, rb, span->end, 1548ba001224a18fa12792696ef393e708e90092127eBrian Paul span->array->x, span->array->y, 1549ba001224a18fa12792696ef393e708e90092127eBrian Paul span->array->rgba, span->array->mask); 1550ba001224a18fa12792696ef393e708e90092127eBrian Paul } 1551ba001224a18fa12792696ef393e708e90092127eBrian Paul else { 1552ba001224a18fa12792696ef393e708e90092127eBrian Paul /* horizontal run of pixels */ 1553ba001224a18fa12792696ef393e708e90092127eBrian Paul ASSERT(rb->PutRow); 1554ba001224a18fa12792696ef393e708e90092127eBrian Paul rb->PutRow(ctx, rb, span->end, span->x, span->y, span->array->rgba, 1555ba001224a18fa12792696ef393e708e90092127eBrian Paul span->writeAll ? NULL: span->array->mask); 1556ba001224a18fa12792696ef393e708e90092127eBrian Paul } 1557ba001224a18fa12792696ef393e708e90092127eBrian Paul 1558ba001224a18fa12792696ef393e708e90092127eBrian Paul if (buf + 1 < numDrawBuffers) { 1559ba001224a18fa12792696ef393e708e90092127eBrian Paul /* restore original span values */ 1560ba001224a18fa12792696ef393e708e90092127eBrian Paul _mesa_memcpy(span->array->rgba, rgbaSave, 1561ba001224a18fa12792696ef393e708e90092127eBrian Paul 4 * span->end * sizeof(GLchan)); 1562ba001224a18fa12792696ef393e708e90092127eBrian Paul } 1563ba001224a18fa12792696ef393e708e90092127eBrian Paul } /* for buf */ 15641e3223c02a2f6155beb5784cadbea1f46703829aBrian Paul 156571340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 156671340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul 1567c3caaa3dd45809e672177ab322445fe51d03af25Brian Paulend: 156861c89be3135cedc795e48d36283769298e250837Brian Paul /* restore these values before returning */ 1569e5b244ff7f984805c1bcc020342f1300f2639c71Brian Paul span->interpMask = origInterpMask; 1570f1e236987829393c81dc86ea19cb49eefe190317Brian Paul span->arrayMask = origArrayMask; 157161c89be3135cedc795e48d36283769298e250837Brian Paul span->array->ChanType = chanType; 157210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul} 157310f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 1574e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 157579c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/** 1576ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian * Read RGBA pixels from a renderbuffer. Clipping will be done to prevent 1577e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * reading ouside the buffer's boundaries. 1578ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian * \param dstType datatype for returned colors 157976e778dce59aa6f290db50242df945943fc47b05Brian Paul * \param rgba the returned colors 1580e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */ 15815071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paulvoid 1582e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul_swrast_read_rgba_span( GLcontext *ctx, struct gl_renderbuffer *rb, 158376e778dce59aa6f290db50242df945943fc47b05Brian Paul GLuint n, GLint x, GLint y, GLenum dstType, 158476e778dce59aa6f290db50242df945943fc47b05Brian Paul GLvoid *rgba) 1585e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell{ 1586e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul const GLint bufWidth = (GLint) rb->Width; 1587e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul const GLint bufHeight = (GLint) rb->Height; 1588a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul 1589a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul if (y < 0 || y >= bufHeight || x + (GLint) n < 0 || x >= bufWidth) { 1590e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* completely above, below, or right */ 1591e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul /* XXX maybe leave rgba values undefined? */ 15926ec6b845fdf3c44436028ad6fff9471d18928719Brian Paul _mesa_bzero(rgba, 4 * n * sizeof(GLchan)); 1593e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1594e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell else { 1595e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell GLint skip, length; 1596e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell if (x < 0) { 15977e152b83cbc3af028175a52450c60101cb16acf8Brian Paul /* left edge clipping */ 1598e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell skip = -x; 1599e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell length = (GLint) n - skip; 1600e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell if (length < 0) { 1601e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* completely left of window */ 1602e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell return; 1603e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1604a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul if (length > bufWidth) { 1605a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul length = bufWidth; 1606e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1607e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1608a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul else if ((GLint) (x + n) > bufWidth) { 1609e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* right edge clipping */ 1610e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell skip = 0; 1611a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul length = bufWidth - x; 1612e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell if (length < 0) { 1613e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* completely to right of window */ 1614e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell return; 1615e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1616e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1617e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell else { 1618e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* no clipping */ 1619e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell skip = 0; 1620e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell length = (GLint) n; 1621e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1622e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 1623bb8b302dbce4f830d060efecd8a9f75b10e25abbBrian Paul ASSERT(rb); 1624bb8b302dbce4f830d060efecd8a9f75b10e25abbBrian Paul ASSERT(rb->GetRow); 1625bb8b302dbce4f830d060efecd8a9f75b10e25abbBrian Paul ASSERT(rb->_BaseFormat == GL_RGB || rb->_BaseFormat == GL_RGBA); 162676e778dce59aa6f290db50242df945943fc47b05Brian Paul 162776e778dce59aa6f290db50242df945943fc47b05Brian Paul if (rb->DataType == dstType) { 162876e778dce59aa6f290db50242df945943fc47b05Brian Paul rb->GetRow(ctx, rb, length, x + skip, y, 162976e778dce59aa6f290db50242df945943fc47b05Brian Paul (GLubyte *) rgba + skip * RGBA_PIXEL_SIZE(rb->DataType)); 163076e778dce59aa6f290db50242df945943fc47b05Brian Paul } 163176e778dce59aa6f290db50242df945943fc47b05Brian Paul else { 163276e778dce59aa6f290db50242df945943fc47b05Brian Paul GLuint temp[MAX_WIDTH * 4]; 163376e778dce59aa6f290db50242df945943fc47b05Brian Paul rb->GetRow(ctx, rb, length, x + skip, y, temp); 163476e778dce59aa6f290db50242df945943fc47b05Brian Paul _mesa_convert_colors(rb->DataType, temp, 163576e778dce59aa6f290db50242df945943fc47b05Brian Paul dstType, (GLubyte *) rgba + skip * RGBA_PIXEL_SIZE(dstType), 163676e778dce59aa6f290db50242df945943fc47b05Brian Paul length, NULL); 163776e778dce59aa6f290db50242df945943fc47b05Brian Paul } 1638e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1639e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell} 1640e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 1641e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 164279c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/** 1643ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian * Read CI pixels from a renderbuffer. Clipping will be done to prevent 1644e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * reading ouside the buffer's boundaries. 1645e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */ 16465071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paulvoid 1647e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul_swrast_read_index_span( GLcontext *ctx, struct gl_renderbuffer *rb, 1648e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul GLuint n, GLint x, GLint y, GLuint index[] ) 1649e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell{ 1650e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul const GLint bufWidth = (GLint) rb->Width; 1651e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul const GLint bufHeight = (GLint) rb->Height; 1652a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul 1653a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul if (y < 0 || y >= bufHeight || x + (GLint) n < 0 || x >= bufWidth) { 1654e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* completely above, below, or right */ 1655e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul _mesa_bzero(index, n * sizeof(GLuint)); 1656e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1657e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell else { 1658e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell GLint skip, length; 1659e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell if (x < 0) { 16607e152b83cbc3af028175a52450c60101cb16acf8Brian Paul /* left edge clipping */ 1661e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell skip = -x; 1662e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell length = (GLint) n - skip; 1663e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell if (length < 0) { 1664e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* completely left of window */ 1665e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell return; 1666e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1667a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul if (length > bufWidth) { 1668a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul length = bufWidth; 1669e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1670e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1671a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul else if ((GLint) (x + n) > bufWidth) { 1672e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* right edge clipping */ 1673e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell skip = 0; 1674a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul length = bufWidth - x; 1675e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell if (length < 0) { 1676e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* completely to right of window */ 1677e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell return; 1678e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1679e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1680e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell else { 1681e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* no clipping */ 1682e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell skip = 0; 1683e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell length = (GLint) n; 1684e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1685e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 1686e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul ASSERT(rb->GetRow); 1687e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul ASSERT(rb->_BaseFormat == GL_COLOR_INDEX); 1688e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul 1689e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul if (rb->DataType == GL_UNSIGNED_BYTE) { 1690e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul GLubyte index8[MAX_WIDTH]; 1691e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul GLint i; 1692e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul rb->GetRow(ctx, rb, length, x + skip, y, index8); 1693e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul for (i = 0; i < length; i++) 1694e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul index[skip + i] = index8[i]; 1695e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul } 1696e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul else if (rb->DataType == GL_UNSIGNED_SHORT) { 1697e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul GLushort index16[MAX_WIDTH]; 1698e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul GLint i; 1699e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul rb->GetRow(ctx, rb, length, x + skip, y, index16); 1700e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul for (i = 0; i < length; i++) 1701e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul index[skip + i] = index16[i]; 1702e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul } 1703e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul else if (rb->DataType == GL_UNSIGNED_INT) { 1704e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul rb->GetRow(ctx, rb, length, x + skip, y, index + skip); 1705e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul } 1706e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1707e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell} 170867074332728acba86da7630353673b458713bb8aBrian Paul 170967074332728acba86da7630353673b458713bb8aBrian Paul 171067074332728acba86da7630353673b458713bb8aBrian Paul/** 171167074332728acba86da7630353673b458713bb8aBrian Paul * Wrapper for gl_renderbuffer::GetValues() which does clipping to avoid 171267074332728acba86da7630353673b458713bb8aBrian Paul * reading values outside the buffer bounds. 171367074332728acba86da7630353673b458713bb8aBrian Paul * We can use this for reading any format/type of renderbuffer. 1714ba001224a18fa12792696ef393e708e90092127eBrian Paul * \param valueSize is the size in bytes of each value (pixel) put into the 171567074332728acba86da7630353673b458713bb8aBrian Paul * values array. 171667074332728acba86da7630353673b458713bb8aBrian Paul */ 171767074332728acba86da7630353673b458713bb8aBrian Paulvoid 171867074332728acba86da7630353673b458713bb8aBrian Paul_swrast_get_values(GLcontext *ctx, struct gl_renderbuffer *rb, 171967074332728acba86da7630353673b458713bb8aBrian Paul GLuint count, const GLint x[], const GLint y[], 172067074332728acba86da7630353673b458713bb8aBrian Paul void *values, GLuint valueSize) 172167074332728acba86da7630353673b458713bb8aBrian Paul{ 172267074332728acba86da7630353673b458713bb8aBrian Paul GLuint i, inCount = 0, inStart = 0; 172367074332728acba86da7630353673b458713bb8aBrian Paul 172467074332728acba86da7630353673b458713bb8aBrian Paul for (i = 0; i < count; i++) { 1725ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian if (x[i] >= 0 && y[i] >= 0 && 1726ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian x[i] < (GLint) rb->Width && y[i] < (GLint) rb->Height) { 172767074332728acba86da7630353673b458713bb8aBrian Paul /* inside */ 172867074332728acba86da7630353673b458713bb8aBrian Paul if (inCount == 0) 172967074332728acba86da7630353673b458713bb8aBrian Paul inStart = i; 173067074332728acba86da7630353673b458713bb8aBrian Paul inCount++; 173167074332728acba86da7630353673b458713bb8aBrian Paul } 173267074332728acba86da7630353673b458713bb8aBrian Paul else { 173367074332728acba86da7630353673b458713bb8aBrian Paul if (inCount > 0) { 173467074332728acba86da7630353673b458713bb8aBrian Paul /* read [inStart, inStart + inCount) */ 173567074332728acba86da7630353673b458713bb8aBrian Paul rb->GetValues(ctx, rb, inCount, x + inStart, y + inStart, 173667074332728acba86da7630353673b458713bb8aBrian Paul (GLubyte *) values + inStart * valueSize); 173767074332728acba86da7630353673b458713bb8aBrian Paul inCount = 0; 173867074332728acba86da7630353673b458713bb8aBrian Paul } 173967074332728acba86da7630353673b458713bb8aBrian Paul } 174067074332728acba86da7630353673b458713bb8aBrian Paul } 174167074332728acba86da7630353673b458713bb8aBrian Paul if (inCount > 0) { 174267074332728acba86da7630353673b458713bb8aBrian Paul /* read last values */ 174367074332728acba86da7630353673b458713bb8aBrian Paul rb->GetValues(ctx, rb, inCount, x + inStart, y + inStart, 174467074332728acba86da7630353673b458713bb8aBrian Paul (GLubyte *) values + inStart * valueSize); 174567074332728acba86da7630353673b458713bb8aBrian Paul } 174667074332728acba86da7630353673b458713bb8aBrian Paul} 17473fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul 17483fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul 17493fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul/** 17503fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul * Wrapper for gl_renderbuffer::PutRow() which does clipping. 1751a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul * \param valueSize size of each value (pixel) in bytes 17523fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul */ 17533fd819aef8139761ce86cb8d763de83a11c81b33Brian Paulvoid 17543fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul_swrast_put_row(GLcontext *ctx, struct gl_renderbuffer *rb, 17553fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul GLuint count, GLint x, GLint y, 17563fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul const GLvoid *values, GLuint valueSize) 17573fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul{ 17583fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul GLint skip = 0; 17593fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul 1760ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian if (y < 0 || y >= (GLint) rb->Height) 17613fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul return; /* above or below */ 17623fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul 1763ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian if (x + (GLint) count <= 0 || x >= (GLint) rb->Width) 17643fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul return; /* entirely left or right */ 17653fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul 1766ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian if ((GLint) (x + count) > (GLint) rb->Width) { 17673fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul /* right clip */ 17683fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul GLint clip = x + count - rb->Width; 17693fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul count -= clip; 17703fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul } 17713fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul 17723fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul if (x < 0) { 17733fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul /* left clip */ 17743fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul skip = -x; 17753fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul x = 0; 17763fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul count -= skip; 17773fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul } 17783fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul 17793fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul rb->PutRow(ctx, rb, count, x, y, 17803fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul (const GLubyte *) values + skip * valueSize, NULL); 17813fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul} 1782f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul 1783f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul 1784f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul/** 1785f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul * Wrapper for gl_renderbuffer::GetRow() which does clipping. 1786a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul * \param valueSize size of each value (pixel) in bytes 1787f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul */ 1788f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paulvoid 1789f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul_swrast_get_row(GLcontext *ctx, struct gl_renderbuffer *rb, 1790f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul GLuint count, GLint x, GLint y, 1791f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul GLvoid *values, GLuint valueSize) 1792f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul{ 1793f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul GLint skip = 0; 1794f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul 1795ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian if (y < 0 || y >= (GLint) rb->Height) 1796f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul return; /* above or below */ 1797f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul 1798ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian if (x + (GLint) count <= 0 || x >= (GLint) rb->Width) 1799f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul return; /* entirely left or right */ 1800f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul 1801f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul if (x + count > rb->Width) { 1802f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul /* right clip */ 1803f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul GLint clip = x + count - rb->Width; 1804f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul count -= clip; 1805f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul } 1806f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul 1807f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul if (x < 0) { 1808f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul /* left clip */ 1809f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul skip = -x; 1810f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul x = 0; 1811f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul count -= skip; 1812f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul } 1813f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul 1814f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul rb->GetRow(ctx, rb, count, x, y, (GLubyte *) values + skip * valueSize); 1815f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul} 1816a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul 1817a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul 1818a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul/** 1819a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul * Get RGBA pixels from the given renderbuffer. Put the pixel colors into 1820a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul * the span's specular color arrays. The specular color arrays should no 1821a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul * longer be needed by time this function is called. 1822a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul * Used by blending, logicop and masking functions. 1823a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul * \return pointer to the colors we read. 1824a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul */ 1825a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paulvoid * 1826a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul_swrast_get_dest_rgba(GLcontext *ctx, struct gl_renderbuffer *rb, 1827cdb27e8242215271364602995d85607cfc06d441Brian Paul SWspan *span) 1828a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul{ 182976e778dce59aa6f290db50242df945943fc47b05Brian Paul const GLuint pixelSize = RGBA_PIXEL_SIZE(span->array->ChanType); 1830a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul void *rbPixels; 1831a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul 1832a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul /* 1833a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul * Determine pixel size (in bytes). 1834a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul * Point rbPixels to a temporary space (use specular color arrays). 1835a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul */ 1836a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul if (span->array->ChanType == GL_UNSIGNED_BYTE) { 1837a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul rbPixels = span->array->color.sz1.spec; 1838a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul } 1839a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul else if (span->array->ChanType == GL_UNSIGNED_SHORT) { 1840a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul rbPixels = span->array->color.sz2.spec; 1841a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul } 1842a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul else { 1843f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian rbPixels = span->array->attribs[FRAG_ATTRIB_COL1]; 1844a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul } 1845a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul 1846a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul /* Get destination values from renderbuffer */ 1847a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul if (span->arrayMask & SPAN_XY) { 1848a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul _swrast_get_values(ctx, rb, span->end, span->array->x, span->array->y, 1849a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul rbPixels, pixelSize); 1850a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul } 1851a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul else { 1852a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul _swrast_get_row(ctx, rb, span->end, span->x, span->y, 1853a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul rbPixels, pixelSize); 1854a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul } 1855a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul 1856a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul return rbPixels; 1857a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul} 1858