s_span.c revision f971e24cf0341dd2779196a0836327b74fc82336
1e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell/* 2e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Mesa 3-D graphics library 36e4f594a02fc384b17d5732be652d7d28618aec2Brian Paul * Version: 6.5 422144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes * 5a66393120411071b3f3ccce8583ab961a2935959Michal Krol * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. 622144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes * 7e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Permission is hereby granted, free of charge, to any person obtaining a 8e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * copy of this software and associated documentation files (the "Software"), 9e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * to deal in the Software without restriction, including without limitation 10e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * the rights to use, copy, modify, merge, publish, distribute, sublicense, 11e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * and/or sell copies of the Software, and to permit persons to whom the 12e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Software is furnished to do so, subject to the following conditions: 1322144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes * 14e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * The above copyright notice and this permission notice shall be included 15e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * in all copies or substantial portions of the Software. 1622144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes * 17e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 21e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 22e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */ 24e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 25e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 2679c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/** 27bcb148de9201c7f90a68c7c46434e7ebf7204000Brian Paul * \file swrast/s_span.c 2879c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul * \brief Span processing functions used by all rasterization functions. 2979c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul * This is where all the per-fragment tests are performed 3079c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul * \author Brian Paul 31e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */ 32e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 33e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "glheader.h" 34e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "colormac.h" 3571340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul#include "context.h" 36e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "macros.h" 373c63452e64df7e10aa073c6c3b9492b1d7dabbb8Brian Paul#include "imports.h" 38f971e24cf0341dd2779196a0836327b74fc82336Brian Paul#include "image.h" 39e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 407f752fed993e5e9423abac200dd59141edbada56Dave Airlie#include "s_atifragshader.h" 41bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol#include "s_alpha.h" 42a66393120411071b3f3ccce8583ab961a2935959Michal Krol#include "s_arbshader.h" 43e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_blend.h" 44cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell#include "s_context.h" 45e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_depth.h" 46e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_fog.h" 47e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_logic.h" 48e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_masking.h" 49610d59981a9f43fefe29b34ef19c184d28e2bef5Brian Paul#include "s_nvfragprog.h" 50e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_span.h" 51e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_stencil.h" 5255187ea63e980b32c7a701855571332f4357d634Brian Paul#include "s_texcombine.h" 53e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 542a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 5579c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/** 562a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul * Init span's Z interpolation values to the RasterPos Z. 572a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul * Used during setup for glDraw/CopyPixels. 582a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul */ 592a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paulvoid 60cdb27e8242215271364602995d85607cfc06d441Brian Paul_swrast_span_default_z( GLcontext *ctx, SWspan *span ) 612a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul{ 62e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul const GLfloat depthMax = ctx->DrawBuffer->_DepthMaxF; 6331e739a18931fa48454f172818245b0927c8910fBrian Paul if (ctx->DrawBuffer->Visual.depthBits <= 16) 64e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul span->z = FloatToFixed(ctx->Current.RasterPos[2] * depthMax + 0.5F); 652a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul else 66e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul span->z = (GLint) (ctx->Current.RasterPos[2] * depthMax + 0.5F); 672a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->zStep = 0; 682a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->interpMask |= SPAN_Z; 692a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul} 702a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 712a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 7279c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/** 732a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul * Init span's fog interpolation values to the RasterPos fog. 742a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul * Used during setup for glDraw/CopyPixels. 752a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul */ 762a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paulvoid 77cdb27e8242215271364602995d85607cfc06d441Brian Paul_swrast_span_default_fog( GLcontext *ctx, SWspan *span ) 782a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul{ 7945bc887da226403f2c41077e40ca38b6f60f1359Brian Paul span->fog = _swrast_z_to_fogfactor(ctx, ctx->Current.RasterDistance); 8054e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul span->fogStep = span->dfogdx = span->dfogdy = 0.0F; 812a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->interpMask |= SPAN_FOG; 822a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul} 832a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 842a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 8579c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/** 86a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul * Init span's rgba or index interpolation values to the RasterPos color. 872a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul * Used during setup for glDraw/CopyPixels. 882a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul */ 892a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paulvoid 90cdb27e8242215271364602995d85607cfc06d441Brian Paul_swrast_span_default_color( GLcontext *ctx, SWspan *span ) 912a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul{ 922a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul if (ctx->Visual.rgbMode) { 932a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLchan r, g, b, a; 942a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul UNCLAMPED_FLOAT_TO_CHAN(r, ctx->Current.RasterColor[0]); 952a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul UNCLAMPED_FLOAT_TO_CHAN(g, ctx->Current.RasterColor[1]); 962a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul UNCLAMPED_FLOAT_TO_CHAN(b, ctx->Current.RasterColor[2]); 972a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul UNCLAMPED_FLOAT_TO_CHAN(a, ctx->Current.RasterColor[3]); 982a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul#if CHAN_TYPE == GL_FLOAT 992a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->red = r; 1002a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->green = g; 1012a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->blue = b; 1022a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->alpha = a; 1032a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul#else 1042a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->red = IntToFixed(r); 1052a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->green = IntToFixed(g); 1062a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->blue = IntToFixed(b); 1072a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->alpha = IntToFixed(a); 1082a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul#endif 1092a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->redStep = 0; 1102a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->greenStep = 0; 1112a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->blueStep = 0; 1122a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->alphaStep = 0; 1132a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->interpMask |= SPAN_RGBA; 1142a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 1152a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul else { 1160f3cd3f894612d156de454178effa4c732f96da7Brian Paul span->index = FloatToFixed(ctx->Current.RasterIndex); 1172a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->indexStep = 0; 1182a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->interpMask |= SPAN_INDEX; 1192a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 1202a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul} 1212a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 1222a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 1234753d60dd070bb08d0116076bcc08025c86ce857Brian Paul/** 1244753d60dd070bb08d0116076bcc08025c86ce857Brian Paul * Init span's texcoord interpolation values to the RasterPos texcoords. 1254753d60dd070bb08d0116076bcc08025c86ce857Brian Paul * Used during setup for glDraw/CopyPixels. 1264753d60dd070bb08d0116076bcc08025c86ce857Brian Paul */ 1274753d60dd070bb08d0116076bcc08025c86ce857Brian Paulvoid 128cdb27e8242215271364602995d85607cfc06d441Brian Paul_swrast_span_default_texcoords( GLcontext *ctx, SWspan *span ) 1294753d60dd070bb08d0116076bcc08025c86ce857Brian Paul{ 1304753d60dd070bb08d0116076bcc08025c86ce857Brian Paul GLuint i; 131ee4e75bd6f768b7210436feeb32b4545ed62e025Brian Paul for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) { 132e63cb85cbc13c083f5d9f4640bb81ba9417a4f28Brian Paul const GLfloat *tc = ctx->Current.RasterTexCoords[i]; 1337e9799ac3d7f3b1b90f098420d413be95916c541Keith Whitwell if (ctx->FragmentProgram._Enabled || ctx->ATIFragmentShader._Enabled) { 134a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul COPY_4V(span->tex[i], tc); 135a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul } 136a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul else if (tc[3] > 0.0F) { 137e63cb85cbc13c083f5d9f4640bb81ba9417a4f28Brian Paul /* use (s/q, t/q, r/q, 1) */ 138e63cb85cbc13c083f5d9f4640bb81ba9417a4f28Brian Paul span->tex[i][0] = tc[0] / tc[3]; 139e63cb85cbc13c083f5d9f4640bb81ba9417a4f28Brian Paul span->tex[i][1] = tc[1] / tc[3]; 140e63cb85cbc13c083f5d9f4640bb81ba9417a4f28Brian Paul span->tex[i][2] = tc[2] / tc[3]; 141e63cb85cbc13c083f5d9f4640bb81ba9417a4f28Brian Paul span->tex[i][3] = 1.0; 142e63cb85cbc13c083f5d9f4640bb81ba9417a4f28Brian Paul } 143e63cb85cbc13c083f5d9f4640bb81ba9417a4f28Brian Paul else { 144e63cb85cbc13c083f5d9f4640bb81ba9417a4f28Brian Paul ASSIGN_4V(span->tex[i], 0.0F, 0.0F, 0.0F, 1.0F); 145e63cb85cbc13c083f5d9f4640bb81ba9417a4f28Brian Paul } 1465f60a0b50ada1865d4fc6a724366e8ea0cc9a72fBrian Paul ASSIGN_4V(span->texStepX[i], 0.0F, 0.0F, 0.0F, 0.0F); 1475f60a0b50ada1865d4fc6a724366e8ea0cc9a72fBrian Paul ASSIGN_4V(span->texStepY[i], 0.0F, 0.0F, 0.0F, 0.0F); 1484753d60dd070bb08d0116076bcc08025c86ce857Brian Paul } 1494753d60dd070bb08d0116076bcc08025c86ce857Brian Paul span->interpMask |= SPAN_TEXTURE; 1504753d60dd070bb08d0116076bcc08025c86ce857Brian Paul} 1514753d60dd070bb08d0116076bcc08025c86ce857Brian Paul 1524753d60dd070bb08d0116076bcc08025c86ce857Brian Paul 153d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul/** 154d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul * Interpolate colors to fill in the span->array->color array. 155d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul * \param specular if true, interpolate specular, else interpolate rgba. 156d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul */ 1572a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paulstatic void 158cdb27e8242215271364602995d85607cfc06d441Brian Paulinterpolate_colors(GLcontext *ctx, SWspan *span, GLboolean specular) 1592a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul{ 1602a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul const GLuint n = span->end; 1612a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLuint i; 162a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul (void) ctx; 1632a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 164d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul if (!specular) { 165d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul ASSERT((span->interpMask & SPAN_RGBA) && 166d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul !(span->arrayMask & SPAN_RGBA)); 167d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul } 1682a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 1692a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul if (span->interpMask & SPAN_FLAT) { 1702a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul /* constant color */ 171d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul switch (span->array->ChanType) { 172d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul case GL_UNSIGNED_BYTE: 173d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul { 174d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul GLubyte (*rgba)[4] = specular 175d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul ? span->array->color.sz1.spec : span->array->color.sz1.rgba; 176d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul GLubyte color[4]; 177d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul if (specular) { 178d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul color[RCOMP] = FixedToInt(span->specRed); 179d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul color[GCOMP] = FixedToInt(span->specGreen); 180d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul color[BCOMP] = FixedToInt(span->specBlue); 181d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul color[ACOMP] = 0; 182d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul } 183d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul else { 184d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul color[RCOMP] = FixedToInt(span->red); 185d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul color[GCOMP] = FixedToInt(span->green); 186d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul color[BCOMP] = FixedToInt(span->blue); 187d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul color[ACOMP] = FixedToInt(span->alpha); 188d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul } 189d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul for (i = 0; i < n; i++) { 190d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul COPY_4UBV(rgba[i], color); 191d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul } 192d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul } 193d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul break; 194d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul case GL_UNSIGNED_SHORT: 195d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul { 196d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul GLushort (*rgba)[4] = specular 197d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul ? span->array->color.sz2.spec : span->array->color.sz2.rgba; 198d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul GLushort color[4]; 199d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul if (specular) { 200d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul color[RCOMP] = FixedToInt(span->specRed); 201d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul color[GCOMP] = FixedToInt(span->specGreen); 202d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul color[BCOMP] = FixedToInt(span->specBlue); 203d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul color[ACOMP] = 0; 204d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul } 205d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul else { 206d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul color[RCOMP] = FixedToInt(span->red); 207d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul color[GCOMP] = FixedToInt(span->green); 208d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul color[BCOMP] = FixedToInt(span->blue); 209d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul color[ACOMP] = FixedToInt(span->alpha); 210d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul } 211d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul for (i = 0; i < n; i++) { 212d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul COPY_4V(rgba[i], color); 213d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul } 214d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul } 215d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul break; 216d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul case GL_FLOAT: 217d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul { 218d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul GLfloat (*rgba)[4] = specular ? 219d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul span->array->color.sz4.spec : span->array->color.sz4.rgba; 220d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul GLfloat color[4]; 221d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul ASSERT(CHAN_TYPE == GL_FLOAT); 222d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul if (specular) { 223d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul color[RCOMP] = span->specRed; 224d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul color[GCOMP] = span->specGreen; 225d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul color[BCOMP] = span->specBlue; 226d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul color[ACOMP] = 0.0F; 227d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul } 228d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul else { 229d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul color[RCOMP] = span->red; 230d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul color[GCOMP] = span->green; 231d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul color[BCOMP] = span->blue; 232d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul color[ACOMP] = span->alpha; 233d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul } 234d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul for (i = 0; i < n; i++) { 235d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul COPY_4V(rgba[i], color); 236d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul } 237d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul } 238d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul break; 239d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul default: 240d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul _mesa_problem(ctx, "bad datatype in interpolate_colors"); 2412a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 2422a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 2432a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul else { 2442a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul /* interpolate */ 245d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul switch (span->array->ChanType) { 246d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul case GL_UNSIGNED_BYTE: 247d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul { 248d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul GLubyte (*rgba)[4] = specular 249d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul ? span->array->color.sz1.spec : span->array->color.sz1.rgba; 250d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul GLfixed r, g, b, a; 251d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul GLint dr, dg, db, da; 252d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul if (specular) { 253d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul r = span->specRed; 254d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul g = span->specGreen; 255d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul b = span->specBlue; 256d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul a = 0; 257d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul dr = span->specRedStep; 258d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul dg = span->specGreenStep; 259d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul db = span->specBlueStep; 260d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul da = 0; 261d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul } 262d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul else { 263d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul r = span->red; 264d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul g = span->green; 265d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul b = span->blue; 266d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul a = span->alpha; 267d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul dr = span->redStep; 268d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul dg = span->greenStep; 269d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul db = span->blueStep; 270d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul da = span->alphaStep; 271d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul } 272d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul for (i = 0; i < n; i++) { 273d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul rgba[i][RCOMP] = FixedToChan(r); 274d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul rgba[i][GCOMP] = FixedToChan(g); 275d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul rgba[i][BCOMP] = FixedToChan(b); 276d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul rgba[i][ACOMP] = FixedToChan(a); 277d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul r += dr; 278d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul g += dg; 279d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul b += db; 280d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul a += da; 281d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul } 282d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul } 283d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul break; 284d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul case GL_UNSIGNED_SHORT: 285d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul { 286d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul GLushort (*rgba)[4] = specular 287d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul ? span->array->color.sz2.spec : span->array->color.sz2.rgba; 288d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul GLfixed r, g, b, a; 289d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul GLint dr, dg, db, da; 290d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul if (specular) { 291d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul r = span->specRed; 292d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul g = span->specGreen; 293d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul b = span->specBlue; 294d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul a = 0; 295d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul dr = span->specRedStep; 296d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul dg = span->specGreenStep; 297d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul db = span->specBlueStep; 298d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul da = 0; 299d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul } 300d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul else { 301d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul r = span->red; 302d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul g = span->green; 303d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul b = span->blue; 304d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul a = span->alpha; 305d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul dr = span->redStep; 306d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul dg = span->greenStep; 307d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul db = span->blueStep; 308d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul da = span->alphaStep; 309d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul } 310d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul for (i = 0; i < n; i++) { 311d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul rgba[i][RCOMP] = FixedToChan(r); 312d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul rgba[i][GCOMP] = FixedToChan(g); 313d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul rgba[i][BCOMP] = FixedToChan(b); 314d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul rgba[i][ACOMP] = FixedToChan(a); 315d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul r += dr; 316d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul g += dg; 317d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul b += db; 318d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul a += da; 319d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul } 320d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul } 321d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul break; 322d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul case GL_FLOAT: 323d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul { 324d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul GLfloat (*rgba)[4] = specular ? 325d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul span->array->color.sz4.spec : span->array->color.sz4.rgba; 326d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul GLfloat r, g, b, a, dr, dg, db, da; 327d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul if (specular) { 328d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul r = span->specRed; 329d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul g = span->specGreen; 330d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul b = span->specBlue; 331d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul a = 0.0F; 332d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul dr = span->specRedStep; 333d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul dg = span->specGreenStep; 334d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul db = span->specBlueStep; 335d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul da = 0.0F; 336d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul } 337d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul else { 338d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul r = span->red; 339d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul g = span->green; 340d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul b = span->blue; 341d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul a = span->alpha; 342d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul dr = span->redStep; 343d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul dg = span->greenStep; 344d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul db = span->blueStep; 345d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul da = span->alphaStep; 346d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul } 347f971e24cf0341dd2779196a0836327b74fc82336Brian Paul /* 348d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul ASSERT(CHAN_TYPE == GL_FLOAT); 349f971e24cf0341dd2779196a0836327b74fc82336Brian Paul */ 350d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul for (i = 0; i < n; i++) { 351d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul rgba[i][RCOMP] = r; 352d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul rgba[i][GCOMP] = g; 353d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul rgba[i][BCOMP] = b; 354d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul rgba[i][ACOMP] = a; 355d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul r += dr; 356d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul g += dg; 357d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul b += db; 358d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul a += da; 359d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul } 360d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul } 361d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul break; 362d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul default: 363d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul _mesa_problem(ctx, "bad datatype in interpolate_colors"); 3642a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 3652a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 366d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul span->arrayMask |= (specular ? SPAN_SPEC : SPAN_RGBA); 3672a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul} 3682a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 3692a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 3702a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul/* Fill in the span.color.index array from the interpolation values */ 3712a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paulstatic void 372cdb27e8242215271364602995d85607cfc06d441Brian Paulinterpolate_indexes(GLcontext *ctx, SWspan *span) 3732a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul{ 3742a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfixed index = span->index; 3752a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul const GLint indexStep = span->indexStep; 3762a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul const GLuint n = span->end; 37777df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul GLuint *indexes = span->array->index; 3782a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLuint i; 379a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul (void) ctx; 380b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul ASSERT((span->interpMask & SPAN_INDEX) && 381b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul !(span->arrayMask & SPAN_INDEX)); 3822a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 3832a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul if ((span->interpMask & SPAN_FLAT) || (indexStep == 0)) { 3842a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul /* constant color */ 3852a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul index = FixedToInt(index); 3862a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul for (i = 0; i < n; i++) { 3872a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul indexes[i] = index; 3882a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 3892a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 3902a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul else { 3912a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul /* interpolate */ 3922a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul for (i = 0; i < n; i++) { 3932a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul indexes[i] = FixedToInt(index); 3942a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul index += indexStep; 3952a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 3962a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 3972a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->arrayMask |= SPAN_INDEX; 398e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul span->interpMask &= ~SPAN_INDEX; 3992a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul} 4002a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 4012a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 402d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul/* Fill in the span.array.fog values from the interpolation values */ 403d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paulstatic void 404cdb27e8242215271364602995d85607cfc06d441Brian Paulinterpolate_fog(const GLcontext *ctx, SWspan *span) 405d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul{ 406d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul GLfloat *fog = span->array->fog; 407d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul const GLfloat fogStep = span->fogStep; 408d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul GLfloat fogCoord = span->fog; 409d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul const GLuint haveW = (span->interpMask & SPAN_W); 410d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul const GLfloat wStep = haveW ? span->dwdx : 0.0F; 411d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul GLfloat w = haveW ? span->w : 1.0F; 412d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul GLuint i; 413d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul for (i = 0; i < span->end; i++) { 414d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul fog[i] = fogCoord / w; 415d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul fogCoord += fogStep; 416d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul w += wStep; 417d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul } 418d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul span->arrayMask |= SPAN_FOG; 419d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul} 420d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul 421d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul 4222a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul/* Fill in the span.zArray array from the interpolation values */ 423711e27fda27e4235b20a4cf73c2767c984ab2b81Brian Paulvoid 424cdb27e8242215271364602995d85607cfc06d441Brian Paul_swrast_span_interpolate_z( const GLcontext *ctx, SWspan *span ) 4252a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul{ 4262a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul const GLuint n = span->end; 4272a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLuint i; 4282a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 429b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul ASSERT((span->interpMask & SPAN_Z) && 430b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul !(span->arrayMask & SPAN_Z)); 4312a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 43231e739a18931fa48454f172818245b0927c8910fBrian Paul if (ctx->DrawBuffer->Visual.depthBits <= 16) { 4332a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfixed zval = span->z; 4343e37bafab0a339021354b9c78f983d05d433d735Brian Paul GLuint *z = span->array->z; 435ad8cd6111e022c90c93df106c0fde6f64d205816Brian Paul for (i = 0; i < n; i++) { 43677df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul z[i] = FixedToInt(zval); 4372a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul zval += span->zStep; 4382a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 4392a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 4402a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul else { 4412a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul /* Deep Z buffer, no fixed->int shift */ 4427265556b9aa0367e9b5031e7cb15ed2a5d73866dBrian Paul GLuint zval = span->z; 4433e37bafab0a339021354b9c78f983d05d433d735Brian Paul GLuint *z = span->array->z; 4442a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul for (i = 0; i < n; i++) { 44577df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul z[i] = zval; 4462a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul zval += span->zStep; 4472a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 4482a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 44932340aea1308153dad5c105fc0748aea1e4c37eeBrian Paul span->interpMask &= ~SPAN_Z; 4502a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->arrayMask |= SPAN_Z; 4512a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul} 4522a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 4532a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 454c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul/* 45531f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul * This the ideal solution, as given in the OpenGL spec. 456c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul */ 457c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul#if 0 45831f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paulstatic GLfloat 45931f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paulcompute_lambda(GLfloat dsdx, GLfloat dsdy, GLfloat dtdx, GLfloat dtdy, 46031f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat dqdx, GLfloat dqdy, GLfloat texW, GLfloat texH, 46131f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat s, GLfloat t, GLfloat q, GLfloat invQ) 462c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul{ 46331f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat dudx = texW * ((s + dsdx) / (q + dqdx) - s * invQ); 46431f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat dvdx = texH * ((t + dtdx) / (q + dqdx) - t * invQ); 46531f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat dudy = texW * ((s + dsdy) / (q + dqdy) - s * invQ); 46631f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat dvdy = texH * ((t + dtdy) / (q + dqdy) - t * invQ); 467f9b1e5241facc8cf255c258082d5cb5b04783e93Brian Paul GLfloat x = SQRTF(dudx * dudx + dvdx * dvdx); 468f9b1e5241facc8cf255c258082d5cb5b04783e93Brian Paul GLfloat y = SQRTF(dudy * dudy + dvdy * dvdy); 46931f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat rho = MAX2(x, y); 47031f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat lambda = LOG2(rho); 47131f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul return lambda; 472c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul} 473c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul#endif 474c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul 47531f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul 47631f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul/* 47731f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul * This is a faster approximation 478c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul */ 479350353adcd75f94fda63c787c86961716114e0bfBrian PaulGLfloat 48045bc887da226403f2c41077e40ca38b6f60f1359Brian Paul_swrast_compute_lambda(GLfloat dsdx, GLfloat dsdy, GLfloat dtdx, GLfloat dtdy, 481350353adcd75f94fda63c787c86961716114e0bfBrian Paul GLfloat dqdx, GLfloat dqdy, GLfloat texW, GLfloat texH, 482350353adcd75f94fda63c787c86961716114e0bfBrian Paul GLfloat s, GLfloat t, GLfloat q, GLfloat invQ) 483c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul{ 48431f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat dsdx2 = (s + dsdx) / (q + dqdx) - s * invQ; 48531f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat dtdx2 = (t + dtdx) / (q + dqdx) - t * invQ; 48631f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat dsdy2 = (s + dsdy) / (q + dqdy) - s * invQ; 48731f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat dtdy2 = (t + dtdy) / (q + dqdy) - t * invQ; 48831f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat maxU, maxV, rho, lambda; 48931f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul dsdx2 = FABSF(dsdx2); 49031f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul dsdy2 = FABSF(dsdy2); 49131f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul dtdx2 = FABSF(dtdx2); 49231f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul dtdy2 = FABSF(dtdy2); 49331f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul maxU = MAX2(dsdx2, dsdy2) * texW; 49431f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul maxV = MAX2(dtdx2, dtdy2) * texH; 49531f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul rho = MAX2(maxU, maxV); 49631f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul lambda = LOG2(rho); 49731f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul return lambda; 498c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul} 499c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul 500d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul 501d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul/** 502c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul * Fill in the span.texcoords array from the interpolation values. 503d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul * Note: in the places where we divide by Q (or mult by invQ) we're 504d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul * really doing two things: perspective correction and texcoord 505d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul * projection. Remember, for texcoord (s,t,r,q) we need to index 506d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul * texels with (s/q, t/q, r/q). 507d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul * If we're using a fragment program, we never do the division 508d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul * for texcoord projection. That's done by the TXP instruction 509d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul * or user-written code. 510c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul */ 5112a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paulstatic void 512cdb27e8242215271364602995d85607cfc06d441Brian Paulinterpolate_texcoords(GLcontext *ctx, SWspan *span) 5132a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul{ 5142a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul ASSERT(span->interpMask & SPAN_TEXTURE); 515b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul ASSERT(!(span->arrayMask & SPAN_TEXTURE)); 5162a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 51736a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul if (ctx->Texture._EnabledCoordUnits > 1) { 51831f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul /* multitexture */ 51931f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLuint u; 520b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul span->arrayMask |= SPAN_TEXTURE; 521ee4e75bd6f768b7210436feeb32b4545ed62e025Brian Paul /* XXX CoordUnits vs. ImageUnits */ 52231f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { 52336a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul if (ctx->Texture._EnabledCoordUnits & (1 << u)) { 52431f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const struct gl_texture_object *obj =ctx->Texture.Unit[u]._Current; 52536a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul GLfloat texW, texH; 52636a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul GLboolean needLambda; 52736a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul if (obj) { 52818fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell const struct gl_texture_image *img = obj->Image[0][obj->BaseLevel]; 52936a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul needLambda = (obj->MinFilter != obj->MagFilter) 5307e9799ac3d7f3b1b90f098420d413be95916c541Keith Whitwell || ctx->FragmentProgram._Enabled; 53136a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul texW = img->WidthScale; 53236a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul texH = img->HeightScale; 53336a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul } 53436a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul else { 535d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul /* using a fragment program */ 53636a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul texW = 1.0; 53736a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul texH = 1.0; 53836a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul needLambda = GL_FALSE; 53936a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul } 54031f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul if (needLambda) { 54177df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul GLfloat (*texcoord)[4] = span->array->texcoords[u]; 54277df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul GLfloat *lambda = span->array->lambda[u]; 54331f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat dsdx = span->texStepX[u][0]; 54431f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat dsdy = span->texStepY[u][0]; 54531f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat dtdx = span->texStepX[u][1]; 54631f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat dtdy = span->texStepY[u][1]; 54731f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat drdx = span->texStepX[u][2]; 54831f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat dqdx = span->texStepX[u][3]; 54931f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat dqdy = span->texStepY[u][3]; 5502a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat s = span->tex[u][0]; 5512a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat t = span->tex[u][1]; 5522a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat r = span->tex[u][2]; 5532a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat q = span->tex[u][3]; 5542a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLuint i; 5557e9799ac3d7f3b1b90f098420d413be95916c541Keith Whitwell if (ctx->FragmentProgram._Enabled || ctx->ATIFragmentShader._Enabled || 556bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol ctx->ShaderObjects._FragmentShaderPresent) { 557d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul /* do perspective correction but don't divide s, t, r by q */ 558d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul const GLfloat dwdx = span->dwdx; 559d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul GLfloat w = span->w; 560d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul for (i = 0; i < span->end; i++) { 561d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul const GLfloat invW = 1.0F / w; 562d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul texcoord[i][0] = s * invW; 563d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul texcoord[i][1] = t * invW; 564d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul texcoord[i][2] = r * invW; 565d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul texcoord[i][3] = q * invW; 566d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul lambda[i] = _swrast_compute_lambda(dsdx, dsdy, dtdx, dtdy, 567d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul dqdx, dqdy, texW, texH, 568d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul s, t, q, invW); 569d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul s += dsdx; 570d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul t += dtdx; 571d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul r += drdx; 572d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul q += dqdx; 573d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul w += dwdx; 574d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul } 575d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul 576d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul } 577d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul else { 578d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul for (i = 0; i < span->end; i++) { 579d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q); 580d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul texcoord[i][0] = s * invQ; 581d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul texcoord[i][1] = t * invQ; 582d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul texcoord[i][2] = r * invQ; 583d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul texcoord[i][3] = q; 584d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul lambda[i] = _swrast_compute_lambda(dsdx, dsdy, dtdx, dtdy, 585d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul dqdx, dqdy, texW, texH, 586d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul s, t, q, invQ); 587d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul s += dsdx; 588d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul t += dtdx; 589d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul r += drdx; 590d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul q += dqdx; 591d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul } 5922a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 59331f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul span->arrayMask |= SPAN_LAMBDA; 5942a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 59531f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul else { 59677df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul GLfloat (*texcoord)[4] = span->array->texcoords[u]; 59777df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul GLfloat *lambda = span->array->lambda[u]; 59831f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat dsdx = span->texStepX[u][0]; 59931f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat dtdx = span->texStepX[u][1]; 60031f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat drdx = span->texStepX[u][2]; 60131f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat dqdx = span->texStepX[u][3]; 6022a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat s = span->tex[u][0]; 6032a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat t = span->tex[u][1]; 6042a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat r = span->tex[u][2]; 6052a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat q = span->tex[u][3]; 6062a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLuint i; 6077e9799ac3d7f3b1b90f098420d413be95916c541Keith Whitwell if (ctx->FragmentProgram._Enabled || ctx->ATIFragmentShader._Enabled || 608bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol ctx->ShaderObjects._FragmentShaderPresent) { 609d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul /* do perspective correction but don't divide s, t, r by q */ 610d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul const GLfloat dwdx = span->dwdx; 611d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul GLfloat w = span->w; 612d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul for (i = 0; i < span->end; i++) { 613d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul const GLfloat invW = 1.0F / w; 614d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul texcoord[i][0] = s * invW; 615d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul texcoord[i][1] = t * invW; 616d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul texcoord[i][2] = r * invW; 617d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul texcoord[i][3] = q * invW; 618d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul lambda[i] = 0.0; 619d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul s += dsdx; 620d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul t += dtdx; 621d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul r += drdx; 622d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul q += dqdx; 623d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul w += dwdx; 624d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul } 625d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul } 626d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul else if (dqdx == 0.0F) { 627c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul /* Ortho projection or polygon's parallel to window X axis */ 6282a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q); 629c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul for (i = 0; i < span->end; i++) { 63077df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul texcoord[i][0] = s * invQ; 63177df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul texcoord[i][1] = t * invQ; 63277df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul texcoord[i][2] = r * invQ; 63336a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul texcoord[i][3] = q; 63477df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul lambda[i] = 0.0; 63531f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul s += dsdx; 63631f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul t += dtdx; 63731f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul r += drdx; 638c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul } 639c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul } 640c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul else { 641c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul for (i = 0; i < span->end; i++) { 642c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q); 64377df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul texcoord[i][0] = s * invQ; 64477df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul texcoord[i][1] = t * invQ; 64577df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul texcoord[i][2] = r * invQ; 64636a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul texcoord[i][3] = q; 64777df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul lambda[i] = 0.0; 64831f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul s += dsdx; 64931f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul t += dtdx; 65031f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul r += drdx; 65131f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul q += dqdx; 652c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul } 6532a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 65431f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul } /* lambda */ 65531f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul } /* if */ 65631f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul } /* for */ 6572a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 6582a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul else { 65931f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul /* single texture */ 66031f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const struct gl_texture_object *obj = ctx->Texture.Unit[0]._Current; 66136a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul GLfloat texW, texH; 66236a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul GLboolean needLambda; 66336a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul if (obj) { 66418fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell const struct gl_texture_image *img = obj->Image[0][obj->BaseLevel]; 66536a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul needLambda = (obj->MinFilter != obj->MagFilter) 6667e9799ac3d7f3b1b90f098420d413be95916c541Keith Whitwell || ctx->FragmentProgram._Enabled; 66736a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul texW = (GLfloat) img->WidthScale; 66836a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul texH = (GLfloat) img->HeightScale; 66936a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul } 67036a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul else { 67136a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul needLambda = GL_FALSE; 67236a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul texW = texH = 1.0; 67336a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul } 674b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul span->arrayMask |= SPAN_TEXTURE; 67531f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul if (needLambda) { 6762a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul /* just texture unit 0, with lambda */ 67777df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul GLfloat (*texcoord)[4] = span->array->texcoords[0]; 67877df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul GLfloat *lambda = span->array->lambda[0]; 67931f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat dsdx = span->texStepX[0][0]; 68031f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat dsdy = span->texStepY[0][0]; 68131f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat dtdx = span->texStepX[0][1]; 68231f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat dtdy = span->texStepY[0][1]; 68331f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat drdx = span->texStepX[0][2]; 68431f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat dqdx = span->texStepX[0][3]; 68531f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat dqdy = span->texStepY[0][3]; 6862a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat s = span->tex[0][0]; 6872a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat t = span->tex[0][1]; 6882a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat r = span->tex[0][2]; 6892a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat q = span->tex[0][3]; 6902a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLuint i; 6917e9799ac3d7f3b1b90f098420d413be95916c541Keith Whitwell if (ctx->FragmentProgram._Enabled || ctx->ATIFragmentShader._Enabled || 692bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol ctx->ShaderObjects._FragmentShaderPresent) { 693d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul /* do perspective correction but don't divide s, t, r by q */ 694d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul const GLfloat dwdx = span->dwdx; 695d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul GLfloat w = span->w; 696d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul for (i = 0; i < span->end; i++) { 697d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul const GLfloat invW = 1.0F / w; 698d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul texcoord[i][0] = s * invW; 699d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul texcoord[i][1] = t * invW; 700d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul texcoord[i][2] = r * invW; 701d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul texcoord[i][3] = q * invW; 702d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul lambda[i] = _swrast_compute_lambda(dsdx, dsdy, dtdx, dtdy, 703d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul dqdx, dqdy, texW, texH, 704d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul s, t, q, invW); 705d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul s += dsdx; 706d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul t += dtdx; 707d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul r += drdx; 708d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul q += dqdx; 709d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul w += dwdx; 710d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul } 711d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul } 712d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul else { 713d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul /* tex.c */ 714d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul for (i = 0; i < span->end; i++) { 715d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q); 716d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul lambda[i] = _swrast_compute_lambda(dsdx, dsdy, dtdx, dtdy, 717d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul dqdx, dqdy, texW, texH, 718d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul s, t, q, invQ); 719d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul texcoord[i][0] = s * invQ; 720d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul texcoord[i][1] = t * invQ; 721d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul texcoord[i][2] = r * invQ; 722d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul texcoord[i][3] = q; 723d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul s += dsdx; 724d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul t += dtdx; 725d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul r += drdx; 726d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul q += dqdx; 727d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul } 7282a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 7292a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->arrayMask |= SPAN_LAMBDA; 7302a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 7312a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul else { 732733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* just texture 0, without lambda */ 73377df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul GLfloat (*texcoord)[4] = span->array->texcoords[0]; 73431f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat dsdx = span->texStepX[0][0]; 73531f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat dtdx = span->texStepX[0][1]; 73631f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat drdx = span->texStepX[0][2]; 73731f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat dqdx = span->texStepX[0][3]; 7382a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat s = span->tex[0][0]; 7392a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat t = span->tex[0][1]; 7402a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat r = span->tex[0][2]; 7412a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat q = span->tex[0][3]; 7422a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLuint i; 7437e9799ac3d7f3b1b90f098420d413be95916c541Keith Whitwell if (ctx->FragmentProgram._Enabled || ctx->ATIFragmentShader._Enabled || 744bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol ctx->ShaderObjects._FragmentShaderPresent) { 745d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul /* do perspective correction but don't divide s, t, r by q */ 746d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul const GLfloat dwdx = span->dwdx; 747d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul GLfloat w = span->w; 748d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul for (i = 0; i < span->end; i++) { 749d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul const GLfloat invW = 1.0F / w; 750d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul texcoord[i][0] = s * invW; 751d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul texcoord[i][1] = t * invW; 752d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul texcoord[i][2] = r * invW; 753d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul texcoord[i][3] = q * invW; 754d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul s += dsdx; 755d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul t += dtdx; 756d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul r += drdx; 757d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul q += dqdx; 758d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul w += dwdx; 759d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul } 760d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul } 761d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul else if (dqdx == 0.0F) { 762c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul /* Ortho projection or polygon's parallel to window X axis */ 7632a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q); 764c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul for (i = 0; i < span->end; i++) { 76577df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul texcoord[i][0] = s * invQ; 76677df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul texcoord[i][1] = t * invQ; 76777df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul texcoord[i][2] = r * invQ; 7682b7a01a39ba5257407dddde38ef049856c34aa01Brian Paul texcoord[i][3] = q; 76931f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul s += dsdx; 77031f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul t += dtdx; 77131f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul r += drdx; 772c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul } 773c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul } 774c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul else { 775c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul for (i = 0; i < span->end; i++) { 776c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q); 77777df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul texcoord[i][0] = s * invQ; 77877df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul texcoord[i][1] = t * invQ; 77977df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul texcoord[i][2] = r * invQ; 7802b7a01a39ba5257407dddde38ef049856c34aa01Brian Paul texcoord[i][3] = q; 78131f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul s += dsdx; 78231f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul t += dtdx; 78331f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul r += drdx; 78431f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul q += dqdx; 785c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul } 7862a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 7872a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 7882a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 78910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul} 790e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 791e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 79279c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/** 793bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol * Fill in the span.varying array from the interpolation values. 794bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol */ 795bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krolstatic void 796cdb27e8242215271364602995d85607cfc06d441Brian Paulinterpolate_varying(GLcontext *ctx, SWspan *span) 797bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol{ 798bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol GLuint i, j; 799bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol 800bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol ASSERT(span->interpMask & SPAN_VARYING); 801bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol ASSERT(!(span->arrayMask & SPAN_VARYING)); 802bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol 803bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol span->arrayMask |= SPAN_VARYING; 804bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol 805bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol for (i = 0; i < MAX_VARYING_VECTORS; i++) { 806bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol for (j = 0; j < VARYINGS_PER_VECTOR; j++) { 807bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol const GLfloat dvdx = span->varStepX[i][j]; 808bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol GLfloat v = span->var[i][j]; 809bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol const GLfloat dwdx = span->dwdx; 810bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol GLfloat w = span->w; 811bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol GLuint k; 812bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol 813bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol for (k = 0; k < span->end; k++) { 814bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol GLfloat invW = 1.0f / w; 815bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol span->array->varying[k][i][j] = v * invW; 816bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol v += dvdx; 817bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol w += dwdx; 818bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol } 819bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol } 820bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol } 821bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol} 822bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol 823bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol 824bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol/** 825e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Apply the current polygon stipple pattern to a span of pixels. 826e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */ 8275071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paulstatic void 828cdb27e8242215271364602995d85607cfc06d441Brian Paulstipple_polygon_span( GLcontext *ctx, SWspan *span ) 82910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul{ 83010f30eb43835c57c00783390a02d72daf4f78e26Brian Paul const GLuint highbit = 0x80000000; 831733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul const GLuint stipple = ctx->PolygonStipple[span->y % 32]; 83277df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul GLubyte *mask = span->array->mask; 833733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul GLuint i, m; 834733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul 835733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul ASSERT(ctx->Polygon.StippleFlag); 836733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul ASSERT((span->arrayMask & SPAN_XY) == 0); 83710f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 83810f30eb43835c57c00783390a02d72daf4f78e26Brian Paul m = highbit >> (GLuint) (span->x % 32); 83910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 84010f30eb43835c57c00783390a02d72daf4f78e26Brian Paul for (i = 0; i < span->end; i++) { 84110f30eb43835c57c00783390a02d72daf4f78e26Brian Paul if ((m & stipple) == 0) { 84277df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul mask[i] = 0; 84310f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 84410f30eb43835c57c00783390a02d72daf4f78e26Brian Paul m = m >> 1; 84510f30eb43835c57c00783390a02d72daf4f78e26Brian Paul if (m == 0) { 84610f30eb43835c57c00783390a02d72daf4f78e26Brian Paul m = highbit; 84710f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 84810f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 8492ef866d1fc0a5cc5ef8543d65744dfd4da4dbbafBrian Paul span->writeAll = GL_FALSE; 85010f30eb43835c57c00783390a02d72daf4f78e26Brian Paul} 85110f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 852e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 85379c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/** 854733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul * Clip a pixel span to the current buffer/window boundaries: 855733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul * DrawBuffer->_Xmin, _Xmax, _Ymin, _Ymax. This will accomplish 856733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul * window clipping and scissoring. 857733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul * Return: GL_TRUE some pixels still visible 85810f30eb43835c57c00783390a02d72daf4f78e26Brian Paul * GL_FALSE nothing visible 85910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul */ 86010f30eb43835c57c00783390a02d72daf4f78e26Brian Paulstatic GLuint 861cdb27e8242215271364602995d85607cfc06d441Brian Paulclip_span( GLcontext *ctx, SWspan *span ) 86210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul{ 863733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul const GLint xmin = ctx->DrawBuffer->_Xmin; 864733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul const GLint xmax = ctx->DrawBuffer->_Xmax; 865733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul const GLint ymin = ctx->DrawBuffer->_Ymin; 866733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul const GLint ymax = ctx->DrawBuffer->_Ymax; 867733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul 868733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (span->arrayMask & SPAN_XY) { 869733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* arrays of x/y pixel coords */ 87077df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul const GLint *x = span->array->x; 87177df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul const GLint *y = span->array->y; 872733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul const GLint n = span->end; 87377df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul GLubyte *mask = span->array->mask; 874733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul GLint i; 875b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul if (span->arrayMask & SPAN_MASK) { 876b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul /* note: using & intead of && to reduce branches */ 877b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul for (i = 0; i < n; i++) { 878b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul mask[i] &= (x[i] >= xmin) & (x[i] < xmax) 879b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul & (y[i] >= ymin) & (y[i] < ymax); 880b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul } 881b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul } 882b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul else { 883b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul /* note: using & intead of && to reduce branches */ 884b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul for (i = 0; i < n; i++) { 885b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul mask[i] = (x[i] >= xmin) & (x[i] < xmax) 886b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul & (y[i] >= ymin) & (y[i] < ymax); 887b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul } 88810f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 889733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul return GL_TRUE; /* some pixels visible */ 89010f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 891733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul else { 892733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* horizontal span of pixels */ 893733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul const GLint x = span->x; 894733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul const GLint y = span->y; 895733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul const GLint n = span->end; 896733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul 897733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* Trivial rejection tests */ 898733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (y < ymin || y >= ymax || x + n <= xmin || x >= xmax) { 899733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->end = 0; 900733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul return GL_FALSE; /* all pixels clipped */ 901733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul } 90210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 903733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* Clip to the left */ 904733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (x < xmin) { 905733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul ASSERT(x + n > xmin); 906733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->writeAll = GL_FALSE; 9076ec6b845fdf3c44436028ad6fff9471d18928719Brian Paul _mesa_bzero(span->array->mask, (xmin - x) * sizeof(GLubyte)); 90810f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 909733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul 910733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* Clip to right */ 911733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (x + n > xmax) { 912733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul ASSERT(x < xmax); 913733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->end = xmax - x; 91410f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 91510f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 916733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul return GL_TRUE; /* some pixels visible */ 917733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul } 91810f30eb43835c57c00783390a02d72daf4f78e26Brian Paul} 91910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 92010f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 92179c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/** 922e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul * Apply all the per-fragment opertions to a span of color index fragments 923e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul * and write them to the enabled color drawbuffers. 924e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul * The 'span' parameter can be considered to be const. Note that 9257956292a765910077f50352d7cd0174e1e66d26cBrian Paul * span->interpMask and span->arrayMask may be changed but will be restored 9267956292a765910077f50352d7cd0174e1e66d26cBrian Paul * to their original values before returning. 92710f30eb43835c57c00783390a02d72daf4f78e26Brian Paul */ 92810f30eb43835c57c00783390a02d72daf4f78e26Brian Paulvoid 929cdb27e8242215271364602995d85607cfc06d441Brian Paul_swrast_write_index_span( GLcontext *ctx, SWspan *span) 93010f30eb43835c57c00783390a02d72daf4f78e26Brian Paul{ 931e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul const SWcontext *swrast = SWRAST_CONTEXT(ctx); 932e00ac11d4dd05c56584622dc2707bbdcfe4b2707Brian Paul const GLbitfield origInterpMask = span->interpMask; 933e00ac11d4dd05c56584622dc2707bbdcfe4b2707Brian Paul const GLbitfield origArrayMask = span->arrayMask; 93410f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 935733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul ASSERT(span->end <= MAX_WIDTH); 936b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul ASSERT(span->primitive == GL_POINT || span->primitive == GL_LINE || 937b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul span->primitive == GL_POLYGON || span->primitive == GL_BITMAP); 938733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul ASSERT((span->interpMask | span->arrayMask) & SPAN_INDEX); 9397956292a765910077f50352d7cd0174e1e66d26cBrian Paul ASSERT((span->interpMask & span->arrayMask) == 0); 9407956292a765910077f50352d7cd0174e1e66d26cBrian Paul 941733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (span->arrayMask & SPAN_MASK) { 942733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* mask was initialized by caller, probably glBitmap */ 943733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->writeAll = GL_FALSE; 944733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul } 945733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul else { 946a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul _mesa_memset(span->array->mask, 1, span->end); 947733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->writeAll = GL_TRUE; 94810f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 94910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 950733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* Clipping */ 951b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul if ((swrast->_RasterMask & CLIP_BIT) || (span->primitive != GL_POLYGON)) { 952733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (!clip_span(ctx, span)) { 95386ca15ece74ccb5a8f4d566a4b2c8024b178d73bBrian Paul return; 954e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 955e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 956e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 957e5b244ff7f984805c1bcc020342f1300f2639c71Brian Paul /* Depth bounds test */ 95831e739a18931fa48454f172818245b0927c8910fBrian Paul if (ctx->Depth.BoundsTest && ctx->DrawBuffer->Visual.depthBits > 0) { 959e5b244ff7f984805c1bcc020342f1300f2639c71Brian Paul if (!_swrast_depth_bounds_test(ctx, span)) { 960e5b244ff7f984805c1bcc020342f1300f2639c71Brian Paul return; 961e5b244ff7f984805c1bcc020342f1300f2639c71Brian Paul } 962e5b244ff7f984805c1bcc020342f1300f2639c71Brian Paul } 963e5b244ff7f984805c1bcc020342f1300f2639c71Brian Paul 964b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul#ifdef DEBUG 965a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul /* Make sure all fragments are within window bounds */ 966b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul if (span->arrayMask & SPAN_XY) { 967a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul GLuint i; 968b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul for (i = 0; i < span->end; i++) { 96977df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul if (span->array->mask[i]) { 97077df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul assert(span->array->x[i] >= ctx->DrawBuffer->_Xmin); 97177df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul assert(span->array->x[i] < ctx->DrawBuffer->_Xmax); 97277df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul assert(span->array->y[i] >= ctx->DrawBuffer->_Ymin); 97377df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul assert(span->array->y[i] < ctx->DrawBuffer->_Ymax); 974b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul } 975b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul } 976b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul } 977b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul#endif 978b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul 979e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* Polygon Stippling */ 980b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul if (ctx->Polygon.StippleFlag && span->primitive == GL_POLYGON) { 98110f30eb43835c57c00783390a02d72daf4f78e26Brian Paul stipple_polygon_span(ctx, span); 982e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 983e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 984e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul /* Stencil and Z testing */ 9857956292a765910077f50352d7cd0174e1e66d26cBrian Paul if (ctx->Depth.Test || ctx->Stencil.Enabled) { 9867956292a765910077f50352d7cd0174e1e66d26cBrian Paul if (span->interpMask & SPAN_Z) 98745bc887da226403f2c41077e40ca38b6f60f1359Brian Paul _swrast_span_interpolate_z(ctx, span); 98810f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 9897956292a765910077f50352d7cd0174e1e66d26cBrian Paul if (ctx->Stencil.Enabled) { 99045bc887da226403f2c41077e40ca38b6f60f1359Brian Paul if (!_swrast_stencil_and_ztest_span(ctx, span)) { 9917956292a765910077f50352d7cd0174e1e66d26cBrian Paul span->arrayMask = origArrayMask; 9927956292a765910077f50352d7cd0174e1e66d26cBrian Paul return; 9937956292a765910077f50352d7cd0174e1e66d26cBrian Paul } 9942a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 9957956292a765910077f50352d7cd0174e1e66d26cBrian Paul else { 9967956292a765910077f50352d7cd0174e1e66d26cBrian Paul ASSERT(ctx->Depth.Test); 99745bc887da226403f2c41077e40ca38b6f60f1359Brian Paul if (!_swrast_depth_test_span(ctx, span)) { 998e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul span->interpMask = origInterpMask; 9997956292a765910077f50352d7cd0174e1e66d26cBrian Paul span->arrayMask = origArrayMask; 10007956292a765910077f50352d7cd0174e1e66d26cBrian Paul return; 10017956292a765910077f50352d7cd0174e1e66d26cBrian Paul } 10022a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 100310f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 100410f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 1005b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul#if FEATURE_ARB_occlusion_query 100623ffc3a85d6172f8a98d17d7f23610bab808d84eBrian Paul if (ctx->Query.CurrentOcclusionObject) { 1007939dd17653245621bf7488803f09418244b7b0b7Brian Paul /* update count of 'passed' fragments */ 100823ffc3a85d6172f8a98d17d7f23610bab808d84eBrian Paul struct gl_query_object *q = ctx->Query.CurrentOcclusionObject; 1009b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul GLuint i; 1010b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul for (i = 0; i < span->end; i++) 101123ffc3a85d6172f8a98d17d7f23610bab808d84eBrian Paul q->Result += span->array->mask[i]; 1012b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul } 1013b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul#endif 1014b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul 10157956292a765910077f50352d7cd0174e1e66d26cBrian Paul /* we have to wait until after occlusion to do this test */ 10167956292a765910077f50352d7cd0174e1e66d26cBrian Paul if (ctx->Color.DrawBuffer == GL_NONE || ctx->Color.IndexMask == 0) { 101710f30eb43835c57c00783390a02d72daf4f78e26Brian Paul /* write no pixels */ 10182a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->arrayMask = origArrayMask; 101910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul return; 102010f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 102110f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 10227956292a765910077f50352d7cd0174e1e66d26cBrian Paul /* Interpolate the color indexes if needed */ 1023dcf4c17fb1624af47181c63af4c3ad29f919c17aBrian Paul if (swrast->_FogEnabled || 1024e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul ctx->Color.IndexLogicOpEnabled || 1025e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul ctx->Color.IndexMask != 0xffffffff || 1026e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul (span->arrayMask & SPAN_COVERAGE)) { 1027e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul if (span->interpMask & SPAN_INDEX) { 1028e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul interpolate_indexes(ctx, span); 1029e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul } 10307956292a765910077f50352d7cd0174e1e66d26cBrian Paul } 103110f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 10327956292a765910077f50352d7cd0174e1e66d26cBrian Paul /* Fog */ 1033dcf4c17fb1624af47181c63af4c3ad29f919c17aBrian Paul if (swrast->_FogEnabled) { 103445bc887da226403f2c41077e40ca38b6f60f1359Brian Paul _swrast_fog_ci_span(ctx, span); 1035e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1036e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 10372a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul /* Antialias coverage application */ 10382a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul if (span->arrayMask & SPAN_COVERAGE) { 1039e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul const GLfloat *coverage = span->array->coverage; 104077df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul GLuint *index = span->array->index; 1041e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul GLuint i; 104210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul for (i = 0; i < span->end; i++) { 104377df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul ASSERT(coverage[i] < 16); 104477df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul index[i] = (index[i] & ~0xf) | ((GLuint) coverage[i]); 10455071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paul } 10462a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 10475071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paul 1048ba001224a18fa12792696ef393e708e90092127eBrian Paul /* 1049ba001224a18fa12792696ef393e708e90092127eBrian Paul * Write to renderbuffers 1050ba001224a18fa12792696ef393e708e90092127eBrian Paul */ 1051ba001224a18fa12792696ef393e708e90092127eBrian Paul { 1052ba001224a18fa12792696ef393e708e90092127eBrian Paul struct gl_framebuffer *fb = ctx->DrawBuffer; 1053a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul const GLuint output = 0; /* only frag progs can write to other outputs */ 1054ba001224a18fa12792696ef393e708e90092127eBrian Paul const GLuint numDrawBuffers = fb->_NumColorDrawBuffers[output]; 1055ba001224a18fa12792696ef393e708e90092127eBrian Paul GLuint indexSave[MAX_WIDTH]; 1056ba001224a18fa12792696ef393e708e90092127eBrian Paul GLuint buf; 1057e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul 1058ba001224a18fa12792696ef393e708e90092127eBrian Paul if (numDrawBuffers > 1) { 1059ba001224a18fa12792696ef393e708e90092127eBrian Paul /* save indexes for second, third renderbuffer writes */ 1060ba001224a18fa12792696ef393e708e90092127eBrian Paul _mesa_memcpy(indexSave, span->array->index, 1061ba001224a18fa12792696ef393e708e90092127eBrian Paul span->end * sizeof(indexSave[0])); 1062ba001224a18fa12792696ef393e708e90092127eBrian Paul } 1063e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul 1064ba001224a18fa12792696ef393e708e90092127eBrian Paul for (buf = 0; buf < fb->_NumColorDrawBuffers[output]; buf++) { 1065ba001224a18fa12792696ef393e708e90092127eBrian Paul struct gl_renderbuffer *rb = fb->_ColorDrawBuffers[output][buf]; 1066ba001224a18fa12792696ef393e708e90092127eBrian Paul ASSERT(rb->_BaseFormat == GL_COLOR_INDEX); 10672a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 1068e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul if (ctx->Color.IndexLogicOpEnabled) { 1069f515c78a2320369ead087c4e0efd583f17b4b78bBrian Paul _swrast_logicop_ci_span(ctx, rb, span); 1070e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul } 1071e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul 1072e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul if (ctx->Color.IndexMask != 0xffffffff) { 1073f515c78a2320369ead087c4e0efd583f17b4b78bBrian Paul _swrast_mask_ci_span(ctx, rb, span); 1074e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul } 10752a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 1076ba001224a18fa12792696ef393e708e90092127eBrian Paul if ((span->interpMask & SPAN_INDEX) && span->indexStep == 0) { 1077ba001224a18fa12792696ef393e708e90092127eBrian Paul /* all fragments have same color index */ 1078ba001224a18fa12792696ef393e708e90092127eBrian Paul GLubyte index8; 1079ba001224a18fa12792696ef393e708e90092127eBrian Paul GLushort index16; 1080ba001224a18fa12792696ef393e708e90092127eBrian Paul GLuint index32; 1081ba001224a18fa12792696ef393e708e90092127eBrian Paul void *value; 1082e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul 1083ba001224a18fa12792696ef393e708e90092127eBrian Paul if (rb->DataType == GL_UNSIGNED_BYTE) { 1084ba001224a18fa12792696ef393e708e90092127eBrian Paul index8 = FixedToInt(span->index); 1085ba001224a18fa12792696ef393e708e90092127eBrian Paul value = &index8; 1086ba001224a18fa12792696ef393e708e90092127eBrian Paul } 1087ba001224a18fa12792696ef393e708e90092127eBrian Paul else if (rb->DataType == GL_UNSIGNED_SHORT) { 1088ba001224a18fa12792696ef393e708e90092127eBrian Paul index16 = FixedToInt(span->index); 1089ba001224a18fa12792696ef393e708e90092127eBrian Paul value = &index16; 1090ba001224a18fa12792696ef393e708e90092127eBrian Paul } 1091ba001224a18fa12792696ef393e708e90092127eBrian Paul else { 1092ba001224a18fa12792696ef393e708e90092127eBrian Paul ASSERT(rb->DataType == GL_UNSIGNED_INT); 1093ba001224a18fa12792696ef393e708e90092127eBrian Paul index32 = FixedToInt(span->index); 1094ba001224a18fa12792696ef393e708e90092127eBrian Paul value = &index32; 1095ba001224a18fa12792696ef393e708e90092127eBrian Paul } 1096e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul 1097ba001224a18fa12792696ef393e708e90092127eBrian Paul if (span->arrayMask & SPAN_XY) { 1098ba001224a18fa12792696ef393e708e90092127eBrian Paul rb->PutMonoValues(ctx, rb, span->end, span->array->x, 1099ba001224a18fa12792696ef393e708e90092127eBrian Paul span->array->y, value, span->array->mask); 1100e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul } 1101ba001224a18fa12792696ef393e708e90092127eBrian Paul else { 1102ba001224a18fa12792696ef393e708e90092127eBrian Paul rb->PutMonoRow(ctx, rb, span->end, span->x, span->y, 1103ba001224a18fa12792696ef393e708e90092127eBrian Paul value, span->array->mask); 1104e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul } 1105733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul } 1106733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul else { 1107ba001224a18fa12792696ef393e708e90092127eBrian Paul /* each fragment is a different color */ 1108ba001224a18fa12792696ef393e708e90092127eBrian Paul GLubyte index8[MAX_WIDTH]; 1109ba001224a18fa12792696ef393e708e90092127eBrian Paul GLushort index16[MAX_WIDTH]; 1110ba001224a18fa12792696ef393e708e90092127eBrian Paul void *values; 1111ba001224a18fa12792696ef393e708e90092127eBrian Paul 1112ba001224a18fa12792696ef393e708e90092127eBrian Paul if (rb->DataType == GL_UNSIGNED_BYTE) { 1113ba001224a18fa12792696ef393e708e90092127eBrian Paul GLuint k; 1114ba001224a18fa12792696ef393e708e90092127eBrian Paul for (k = 0; k < span->end; k++) { 1115ba001224a18fa12792696ef393e708e90092127eBrian Paul index8[k] = (GLubyte) span->array->index[k]; 1116ba001224a18fa12792696ef393e708e90092127eBrian Paul } 1117ba001224a18fa12792696ef393e708e90092127eBrian Paul values = index8; 1118ba001224a18fa12792696ef393e708e90092127eBrian Paul } 1119ba001224a18fa12792696ef393e708e90092127eBrian Paul else if (rb->DataType == GL_UNSIGNED_SHORT) { 1120ba001224a18fa12792696ef393e708e90092127eBrian Paul GLuint k; 1121ba001224a18fa12792696ef393e708e90092127eBrian Paul for (k = 0; k < span->end; k++) { 1122ba001224a18fa12792696ef393e708e90092127eBrian Paul index16[k] = (GLushort) span->array->index[k]; 1123ba001224a18fa12792696ef393e708e90092127eBrian Paul } 1124ba001224a18fa12792696ef393e708e90092127eBrian Paul values = index16; 1125ba001224a18fa12792696ef393e708e90092127eBrian Paul } 1126ba001224a18fa12792696ef393e708e90092127eBrian Paul else { 1127ba001224a18fa12792696ef393e708e90092127eBrian Paul ASSERT(rb->DataType == GL_UNSIGNED_INT); 1128ba001224a18fa12792696ef393e708e90092127eBrian Paul values = span->array->index; 1129ba001224a18fa12792696ef393e708e90092127eBrian Paul } 1130e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul 1131ba001224a18fa12792696ef393e708e90092127eBrian Paul if (span->arrayMask & SPAN_XY) { 1132ba001224a18fa12792696ef393e708e90092127eBrian Paul rb->PutValues(ctx, rb, span->end, 1133ba001224a18fa12792696ef393e708e90092127eBrian Paul span->array->x, span->array->y, 1134ba001224a18fa12792696ef393e708e90092127eBrian Paul values, span->array->mask); 1135ba001224a18fa12792696ef393e708e90092127eBrian Paul } 1136ba001224a18fa12792696ef393e708e90092127eBrian Paul else { 1137ba001224a18fa12792696ef393e708e90092127eBrian Paul rb->PutRow(ctx, rb, span->end, span->x, span->y, 1138e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul values, span->array->mask); 1139ba001224a18fa12792696ef393e708e90092127eBrian Paul } 1140e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul } 1141ba001224a18fa12792696ef393e708e90092127eBrian Paul 1142ba001224a18fa12792696ef393e708e90092127eBrian Paul if (buf + 1 < numDrawBuffers) { 1143ba001224a18fa12792696ef393e708e90092127eBrian Paul /* restore original span values */ 1144ba001224a18fa12792696ef393e708e90092127eBrian Paul _mesa_memcpy(span->array->index, indexSave, 1145ba001224a18fa12792696ef393e708e90092127eBrian Paul span->end * sizeof(indexSave[0])); 1146733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul } 1147ba001224a18fa12792696ef393e708e90092127eBrian Paul } /* for buf */ 1148e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 11492a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 11507956292a765910077f50352d7cd0174e1e66d26cBrian Paul span->interpMask = origInterpMask; 11512a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->arrayMask = origArrayMask; 1152e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell} 1153e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 1154e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 115579c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/** 1156e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Add specular color to base color. This is used only when 1157f1e236987829393c81dc86ea19cb49eefe190317Brian Paul * GL_LIGHT_MODEL_COLOR_CONTROL = GL_SEPARATE_SPECULAR_COLOR. 1158e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */ 11595071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paulstatic void 1160cdb27e8242215271364602995d85607cfc06d441Brian Pauladd_specular(GLcontext *ctx, SWspan *span) 1161e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell{ 1162d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul switch (span->array->ChanType) { 1163d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul case GL_UNSIGNED_BYTE: 1164d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul { 1165d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul GLubyte (*rgba)[4] = span->array->color.sz1.rgba; 1166d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul GLubyte (*spec)[4] = span->array->color.sz1.spec; 1167d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul GLuint i; 1168d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul for (i = 0; i < span->end; i++) { 1169d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul GLint r = rgba[i][RCOMP] + spec[i][RCOMP]; 1170d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul GLint g = rgba[i][GCOMP] + spec[i][GCOMP]; 1171d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul GLint b = rgba[i][BCOMP] + spec[i][BCOMP]; 1172d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul GLint a = rgba[i][ACOMP] + spec[i][ACOMP]; 1173d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul rgba[i][RCOMP] = MIN2(r, 255); 1174d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul rgba[i][GCOMP] = MIN2(g, 255); 1175d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul rgba[i][BCOMP] = MIN2(b, 255); 1176d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul rgba[i][ACOMP] = MIN2(a, 255); 1177d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul } 1178d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul } 1179d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul break; 1180d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul case GL_UNSIGNED_SHORT: 1181d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul { 1182d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul GLushort (*rgba)[4] = span->array->color.sz2.rgba; 1183d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul GLushort (*spec)[4] = span->array->color.sz2.spec; 1184d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul GLuint i; 1185d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul for (i = 0; i < span->end; i++) { 1186d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul GLint r = rgba[i][RCOMP] + spec[i][RCOMP]; 1187d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul GLint g = rgba[i][GCOMP] + spec[i][GCOMP]; 1188d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul GLint b = rgba[i][BCOMP] + spec[i][BCOMP]; 1189d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul GLint a = rgba[i][ACOMP] + spec[i][ACOMP]; 1190d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul rgba[i][RCOMP] = MIN2(r, 65535); 1191d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul rgba[i][GCOMP] = MIN2(g, 65535); 1192d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul rgba[i][BCOMP] = MIN2(b, 65535); 1193d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul rgba[i][ACOMP] = MIN2(a, 65535); 1194d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul } 1195d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul } 1196d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul break; 1197d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul case GL_FLOAT: 1198d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul { 1199d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul GLfloat (*rgba)[4] = span->array->color.sz4.rgba; 1200d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul GLfloat (*spec)[4] = span->array->color.sz4.spec; 1201d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul GLuint i; 1202d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul for (i = 0; i < span->end; i++) { 1203d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul rgba[i][RCOMP] += spec[i][RCOMP]; 1204d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul rgba[i][GCOMP] += spec[i][GCOMP]; 1205d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul rgba[i][BCOMP] += spec[i][BCOMP]; 1206d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul rgba[i][ACOMP] += spec[i][ACOMP]; 1207d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul } 1208d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul } 1209d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul break; 1210d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul default: 1211d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul _mesa_problem(ctx, "Invalid datatype in add_specular"); 1212e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1213e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell} 1214e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 1215e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 121679c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/** 1217d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul * Convert the span's color arrays to the given type. 1218e18d0f82b6271103e292fde5bab6fceccb96f90aBrian Paul * XXX this could be put into image.c and reused in several places. 1219d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul */ 1220d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paulstatic void 1221cdb27e8242215271364602995d85607cfc06d441Brian Paulconvert_color_type(GLcontext *ctx, SWspan *span, GLenum newType) 1222d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul{ 1223f971e24cf0341dd2779196a0836327b74fc82336Brian Paul GLvoid *src, *dst; 1224f971e24cf0341dd2779196a0836327b74fc82336Brian Paul if (span->array->ChanType == GL_UNSIGNED_BYTE) { 1225f971e24cf0341dd2779196a0836327b74fc82336Brian Paul src = span->array->color.sz1.rgba; 1226f971e24cf0341dd2779196a0836327b74fc82336Brian Paul } 1227f971e24cf0341dd2779196a0836327b74fc82336Brian Paul else if (span->array->ChanType == GL_UNSIGNED_BYTE) { 1228f971e24cf0341dd2779196a0836327b74fc82336Brian Paul src = span->array->color.sz2.rgba; 1229f971e24cf0341dd2779196a0836327b74fc82336Brian Paul } 1230f971e24cf0341dd2779196a0836327b74fc82336Brian Paul else { 1231f971e24cf0341dd2779196a0836327b74fc82336Brian Paul src = span->array->color.sz4.rgba; 1232f971e24cf0341dd2779196a0836327b74fc82336Brian Paul } 1233f971e24cf0341dd2779196a0836327b74fc82336Brian Paul if (newType == GL_UNSIGNED_BYTE) { 1234f971e24cf0341dd2779196a0836327b74fc82336Brian Paul dst = span->array->color.sz1.rgba; 1235f971e24cf0341dd2779196a0836327b74fc82336Brian Paul } 1236f971e24cf0341dd2779196a0836327b74fc82336Brian Paul else if (newType == GL_UNSIGNED_BYTE) { 1237f971e24cf0341dd2779196a0836327b74fc82336Brian Paul dst = span->array->color.sz2.rgba; 1238f971e24cf0341dd2779196a0836327b74fc82336Brian Paul } 1239f971e24cf0341dd2779196a0836327b74fc82336Brian Paul else { 1240f971e24cf0341dd2779196a0836327b74fc82336Brian Paul dst = span->array->color.sz4.rgba; 1241f971e24cf0341dd2779196a0836327b74fc82336Brian Paul } 1242d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul 1243f971e24cf0341dd2779196a0836327b74fc82336Brian Paul _mesa_convert_colors(span->array->ChanType, src, 1244f971e24cf0341dd2779196a0836327b74fc82336Brian Paul newType, dst, 1245f971e24cf0341dd2779196a0836327b74fc82336Brian Paul span->end, span->array->mask); 1246d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul 1247d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul span->array->ChanType = newType; 1248d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul} 1249d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul 1250d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul 1251d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul 1252d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul/** 1253a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul * Apply all the per-fragment operations to a span. 1254a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul * This now includes texturing (_swrast_write_texture_span() is history). 1255f1e236987829393c81dc86ea19cb49eefe190317Brian Paul * This function may modify any of the array values in the span. 12567956292a765910077f50352d7cd0174e1e66d26cBrian Paul * span->interpMask and span->arrayMask may be changed but will be restored 12577956292a765910077f50352d7cd0174e1e66d26cBrian Paul * to their original values before returning. 125878940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul */ 125978940758e90069ceaca2b6cddb6438488fbad5ccBrian Paulvoid 1260cdb27e8242215271364602995d85607cfc06d441Brian Paul_swrast_write_rgba_span( GLcontext *ctx, SWspan *span) 126178940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul{ 126278940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul const GLuint colorMask = *((GLuint *) ctx->Color.ColorMask); 126378940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul SWcontext *swrast = SWRAST_CONTEXT(ctx); 1264e00ac11d4dd05c56584622dc2707bbdcfe4b2707Brian Paul const GLbitfield origInterpMask = span->interpMask; 1265e00ac11d4dd05c56584622dc2707bbdcfe4b2707Brian Paul const GLbitfield origArrayMask = span->arrayMask; 126632340aea1308153dad5c105fc0748aea1e4c37eeBrian Paul const GLboolean deferredTexture = !(ctx->Color.AlphaEnabled || 12677e9799ac3d7f3b1b90f098420d413be95916c541Keith Whitwell ctx->FragmentProgram._Enabled || 1268071357096e682e9af59ad45ea5abc444ab431837Michal Krol ctx->ShaderObjects._FragmentShaderPresent); 1269f1e236987829393c81dc86ea19cb49eefe190317Brian Paul 1270b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul ASSERT(span->primitive == GL_POINT || span->primitive == GL_LINE || 1271b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul span->primitive == GL_POLYGON || span->primitive == GL_BITMAP); 1272733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul ASSERT(span->end <= MAX_WIDTH); 12737956292a765910077f50352d7cd0174e1e66d26cBrian Paul ASSERT((span->interpMask & span->arrayMask) == 0); 127478940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul 1275ceb39f4f8dc4863fde17d668c752533a2184476eBrian Paul /* 1276a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul printf("%s() interp 0x%x array 0x%x\n", __FUNCTION__, 1277a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul span->interpMask, span->arrayMask); 1278ceb39f4f8dc4863fde17d668c752533a2184476eBrian Paul */ 1279ceb39f4f8dc4863fde17d668c752533a2184476eBrian Paul 1280733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (span->arrayMask & SPAN_MASK) { 1281733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* mask was initialized by caller, probably glBitmap */ 1282733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->writeAll = GL_FALSE; 1283733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul } 1284733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul else { 1285a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul _mesa_memset(span->array->mask, 1, span->end); 1286733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->writeAll = GL_TRUE; 128778940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul } 128878940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul 1289a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul /* Clip to window/scissor box */ 1290b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul if ((swrast->_RasterMask & CLIP_BIT) || (span->primitive != GL_POLYGON)) { 1291733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (!clip_span(ctx, span)) { 1292733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul return; 129378940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul } 129478940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul } 129578940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul 1296b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul#ifdef DEBUG 1297a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul /* Make sure all fragments are within window bounds */ 1298b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul if (span->arrayMask & SPAN_XY) { 1299a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul GLuint i; 1300b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul for (i = 0; i < span->end; i++) { 130177df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul if (span->array->mask[i]) { 130277df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul assert(span->array->x[i] >= ctx->DrawBuffer->_Xmin); 130377df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul assert(span->array->x[i] < ctx->DrawBuffer->_Xmax); 130477df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul assert(span->array->y[i] >= ctx->DrawBuffer->_Ymin); 130577df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul assert(span->array->y[i] < ctx->DrawBuffer->_Ymax); 1306b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul } 1307b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul } 1308b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul } 1309b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul#endif 1310b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul 131178940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul /* Polygon Stippling */ 1312b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul if (ctx->Polygon.StippleFlag && span->primitive == GL_POLYGON) { 1313733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul stipple_polygon_span(ctx, span); 131478940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul } 131578940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul 1316a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul /* Interpolate texcoords? */ 1317a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul if (ctx->Texture._EnabledCoordUnits 1318a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul && (span->interpMask & SPAN_TEXTURE) 1319a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul && (span->arrayMask & SPAN_TEXTURE) == 0) { 1320f1e236987829393c81dc86ea19cb49eefe190317Brian Paul interpolate_texcoords(ctx, span); 1321a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul } 132278940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul 1323bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol if (ctx->ShaderObjects._FragmentShaderPresent) { 1324bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol interpolate_varying(ctx, span); 1325bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol } 1326bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol 132732340aea1308153dad5c105fc0748aea1e4c37eeBrian Paul /* This is the normal place to compute the resulting fragment color/Z. 132832340aea1308153dad5c105fc0748aea1e4c37eeBrian Paul * As an optimization, we try to defer this until after Z/stencil 132932340aea1308153dad5c105fc0748aea1e4c37eeBrian Paul * testing in order to try to avoid computing colors that we won't 133032340aea1308153dad5c105fc0748aea1e4c37eeBrian Paul * actually need. 1331a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul */ 133232340aea1308153dad5c105fc0748aea1e4c37eeBrian Paul if (!deferredTexture) { 1333f1e236987829393c81dc86ea19cb49eefe190317Brian Paul /* Now we need the rgba array, fill it in if needed */ 1334f1e236987829393c81dc86ea19cb49eefe190317Brian Paul if ((span->interpMask & SPAN_RGBA) && (span->arrayMask & SPAN_RGBA) == 0) 1335d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul interpolate_colors(ctx, span, GL_FALSE); 1336f1e236987829393c81dc86ea19cb49eefe190317Brian Paul 1337a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul if (span->interpMask & SPAN_SPEC) 1338d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul interpolate_colors(ctx, span, GL_TRUE); 133936a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul 1340d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul if (span->interpMask & SPAN_FOG) 1341d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul interpolate_fog(ctx, span); 1342d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul 1343bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol /* Compute fragment colors with fragment program or texture lookups */ 1344365582dd6f632aafbc1c817aa57926d679bb2efcMichal Krol#if FEATURE_ARB_fragment_shader 1345bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol if (ctx->ShaderObjects._FragmentShaderPresent) { 1346bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol if (span->interpMask & SPAN_Z) 1347bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol _swrast_span_interpolate_z (ctx, span); 1348bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol _swrast_exec_arbshader (ctx, span); 1349a66393120411071b3f3ccce8583ab961a2935959Michal Krol } 1350365582dd6f632aafbc1c817aa57926d679bb2efcMichal Krol else 1351365582dd6f632aafbc1c817aa57926d679bb2efcMichal Krol#endif 13527e9799ac3d7f3b1b90f098420d413be95916c541Keith Whitwell if (ctx->FragmentProgram._Enabled) { 135332340aea1308153dad5c105fc0748aea1e4c37eeBrian Paul /* frag prog may need Z values */ 135432340aea1308153dad5c105fc0748aea1e4c37eeBrian Paul if (span->interpMask & SPAN_Z) 135532340aea1308153dad5c105fc0748aea1e4c37eeBrian Paul _swrast_span_interpolate_z(ctx, span); 1356e22540c2765e034fed558ea1d44488a03fbba170Brian Paul _swrast_exec_fragment_program( ctx, span ); 135732340aea1308153dad5c105fc0748aea1e4c37eeBrian Paul } 13587f752fed993e5e9423abac200dd59141edbada56Dave Airlie else if (ctx->ATIFragmentShader._Enabled) 13597f752fed993e5e9423abac200dd59141edbada56Dave Airlie _swrast_exec_fragment_shader( ctx, span ); 1360252d8e78cc07880239b085b713e2d37ddbba86f9Brian Paul else if (ctx->Texture._EnabledUnits && (span->arrayMask & SPAN_TEXTURE)) 1361610d59981a9f43fefe29b34ef19c184d28e2bef5Brian Paul _swrast_texture_span( ctx, span ); 136278940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul 136378940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul /* Do the alpha test */ 13645e01f9a11489079d8509927774d8239c1857224aRoland Scheidegger if (ctx->Color.AlphaEnabled) { 13655e01f9a11489079d8509927774d8239c1857224aRoland Scheidegger if (!_swrast_alpha_test(ctx, span)) { 13665e01f9a11489079d8509927774d8239c1857224aRoland Scheidegger span->arrayMask = origArrayMask; 13675e01f9a11489079d8509927774d8239c1857224aRoland Scheidegger return; 13685e01f9a11489079d8509927774d8239c1857224aRoland Scheidegger } 136978940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul } 137078940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul } 137178940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul 1372f1e236987829393c81dc86ea19cb49eefe190317Brian Paul /* Stencil and Z testing */ 1373f1e236987829393c81dc86ea19cb49eefe190317Brian Paul if (ctx->Stencil.Enabled || ctx->Depth.Test) { 1374f1e236987829393c81dc86ea19cb49eefe190317Brian Paul if (span->interpMask & SPAN_Z) 137545bc887da226403f2c41077e40ca38b6f60f1359Brian Paul _swrast_span_interpolate_z(ctx, span); 137678940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul 1377e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul if (ctx->Stencil.Enabled && ctx->DrawBuffer->Visual.stencilBits > 0) { 1378a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul /* Combined Z/stencil tests */ 137945bc887da226403f2c41077e40ca38b6f60f1359Brian Paul if (!_swrast_stencil_and_ztest_span(ctx, span)) { 1380e5b244ff7f984805c1bcc020342f1300f2639c71Brian Paul span->interpMask = origInterpMask; 1381f1e236987829393c81dc86ea19cb49eefe190317Brian Paul span->arrayMask = origArrayMask; 138210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul return; 1383f1e236987829393c81dc86ea19cb49eefe190317Brian Paul } 138471340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 1385e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul else if (ctx->DrawBuffer->Visual.depthBits > 0) { 1386a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul /* Just regular depth testing */ 1387f1e236987829393c81dc86ea19cb49eefe190317Brian Paul ASSERT(ctx->Depth.Test); 1388f1e236987829393c81dc86ea19cb49eefe190317Brian Paul ASSERT(span->arrayMask & SPAN_Z); 138945bc887da226403f2c41077e40ca38b6f60f1359Brian Paul if (!_swrast_depth_test_span(ctx, span)) { 1390e5b244ff7f984805c1bcc020342f1300f2639c71Brian Paul span->interpMask = origInterpMask; 1391f1e236987829393c81dc86ea19cb49eefe190317Brian Paul span->arrayMask = origArrayMask; 139210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul return; 1393f1e236987829393c81dc86ea19cb49eefe190317Brian Paul } 139471340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 139571340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 139671340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul 1397b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul#if FEATURE_ARB_occlusion_query 139823ffc3a85d6172f8a98d17d7f23610bab808d84eBrian Paul if (ctx->Query.CurrentOcclusionObject) { 1399939dd17653245621bf7488803f09418244b7b0b7Brian Paul /* update count of 'passed' fragments */ 140023ffc3a85d6172f8a98d17d7f23610bab808d84eBrian Paul struct gl_query_object *q = ctx->Query.CurrentOcclusionObject; 1401b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul GLuint i; 1402b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul for (i = 0; i < span->end; i++) 140323ffc3a85d6172f8a98d17d7f23610bab808d84eBrian Paul q->Result += span->array->mask[i]; 1404b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul } 1405b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul#endif 1406b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul 1407a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul /* We had to wait until now to check for glColorMask(0,0,0,0) because of 1408f1e236987829393c81dc86ea19cb49eefe190317Brian Paul * the occlusion test. 1409f1e236987829393c81dc86ea19cb49eefe190317Brian Paul */ 1410f1e236987829393c81dc86ea19cb49eefe190317Brian Paul if (colorMask == 0x0) { 1411e5b244ff7f984805c1bcc020342f1300f2639c71Brian Paul span->interpMask = origInterpMask; 1412f1e236987829393c81dc86ea19cb49eefe190317Brian Paul span->arrayMask = origArrayMask; 1413f1e236987829393c81dc86ea19cb49eefe190317Brian Paul return; 141471340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 141571340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul 141632340aea1308153dad5c105fc0748aea1e4c37eeBrian Paul /* If we were able to defer fragment color computation to now, there's 141732340aea1308153dad5c105fc0748aea1e4c37eeBrian Paul * a good chance that many fragments will have already been killed by 141832340aea1308153dad5c105fc0748aea1e4c37eeBrian Paul * Z/stencil testing. 1419a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul */ 142032340aea1308153dad5c105fc0748aea1e4c37eeBrian Paul if (deferredTexture) { 1421f1e236987829393c81dc86ea19cb49eefe190317Brian Paul /* Now we need the rgba array, fill it in if needed */ 1422f1e236987829393c81dc86ea19cb49eefe190317Brian Paul if ((span->interpMask & SPAN_RGBA) && (span->arrayMask & SPAN_RGBA) == 0) 1423d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul interpolate_colors(ctx, span, GL_FALSE); 142471340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul 1425a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul if (span->interpMask & SPAN_SPEC) 1426d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul interpolate_colors(ctx, span, GL_TRUE); 142736a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul 1428d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul if (span->interpMask & SPAN_FOG) 1429d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul interpolate_fog(ctx, span); 1430d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul 1431365582dd6f632aafbc1c817aa57926d679bb2efcMichal Krol#if FEATURE_ARB_fragment_shader 1432bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol if (ctx->ShaderObjects._FragmentShaderPresent) { 1433bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol if (span->interpMask & SPAN_Z) 1434bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol _swrast_span_interpolate_z (ctx, span); 1435bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol _swrast_exec_arbshader (ctx, span); 1436bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol } 1437365582dd6f632aafbc1c817aa57926d679bb2efcMichal Krol else 1438365582dd6f632aafbc1c817aa57926d679bb2efcMichal Krol#endif 14397e9799ac3d7f3b1b90f098420d413be95916c541Keith Whitwell if (ctx->FragmentProgram._Enabled) 1440e22540c2765e034fed558ea1d44488a03fbba170Brian Paul _swrast_exec_fragment_program( ctx, span ); 14417f752fed993e5e9423abac200dd59141edbada56Dave Airlie else if (ctx->ATIFragmentShader._Enabled) 14427f752fed993e5e9423abac200dd59141edbada56Dave Airlie _swrast_exec_fragment_shader( ctx, span ); 1443252d8e78cc07880239b085b713e2d37ddbba86f9Brian Paul else if (ctx->Texture._EnabledUnits && (span->arrayMask & SPAN_TEXTURE)) 1444610d59981a9f43fefe29b34ef19c184d28e2bef5Brian Paul _swrast_texture_span( ctx, span ); 144571340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 144671340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul 1447f1e236987829393c81dc86ea19cb49eefe190317Brian Paul ASSERT(span->arrayMask & SPAN_RGBA); 14482ef866d1fc0a5cc5ef8543d65744dfd4da4dbbafBrian Paul 14499d148e6b2be33fe7ac72aaa3be239dc1bc8878a9Keith Whitwell if (!ctx->FragmentProgram._Enabled) { 1450dfe508ca7af1a6d1099cd65e257512ed1e17d893Brian Paul /* Add base and specular colors */ 1451dfe508ca7af1a6d1099cd65e257512ed1e17d893Brian Paul if (ctx->Fog.ColorSumEnabled || 1452dfe508ca7af1a6d1099cd65e257512ed1e17d893Brian Paul (ctx->Light.Enabled && 1453dfe508ca7af1a6d1099cd65e257512ed1e17d893Brian Paul ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR)) { 1454dfe508ca7af1a6d1099cd65e257512ed1e17d893Brian Paul if (span->interpMask & SPAN_SPEC) { 1455d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul interpolate_colors(ctx, span, GL_TRUE); 1456dfe508ca7af1a6d1099cd65e257512ed1e17d893Brian Paul } 1457a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul if (span->arrayMask & SPAN_SPEC) { 1458d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul add_specular(ctx, span); 1459a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul } 1460a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul else { 1461a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul /* We probably added the base/specular colors during the 1462a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul * vertex stage! 1463a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul */ 1464a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul } 146571340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 146671340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 146771340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul 14686e1666437ea091ecc50ab2b56d87129318f641d2Brian Paul /* Fog */ 146909da0b8e6621a831e3eeb9381430f2bed18a22adBrian Paul if (swrast->_FogEnabled) { 147045bc887da226403f2c41077e40ca38b6f60f1359Brian Paul _swrast_fog_rgba_span(ctx, span); 147171340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 1472f1e236987829393c81dc86ea19cb49eefe190317Brian Paul 147371340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul /* Antialias coverage application */ 14742a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul if (span->arrayMask & SPAN_COVERAGE) { 147577df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul GLchan (*rgba)[4] = span->array->rgba; 147677df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul GLfloat *coverage = span->array->coverage; 147771340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul GLuint i; 147810f30eb43835c57c00783390a02d72daf4f78e26Brian Paul for (i = 0; i < span->end; i++) { 147977df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul rgba[i][ACOMP] = (GLchan) (rgba[i][ACOMP] * coverage[i]); 148071340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 148171340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 148271340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul 1483ba3da6154c324cc916845bc5de3de077d0b59ffcBrian Paul /* Clamp color/alpha values over the range [0.0, 1.0] before storage */ 1484ba3da6154c324cc916845bc5de3de077d0b59ffcBrian Paul#if CHAN_TYPE == GL_FLOAT 1485ba3da6154c324cc916845bc5de3de077d0b59ffcBrian Paul if (ctx->Color.ClampFragmentColor) { 1486ba3da6154c324cc916845bc5de3de077d0b59ffcBrian Paul GLchan (*rgba)[4] = span->array->rgba; 1487ba3da6154c324cc916845bc5de3de077d0b59ffcBrian Paul GLuint i; 1488ba3da6154c324cc916845bc5de3de077d0b59ffcBrian Paul for (i = 0; i < span->end; i++) { 1489ba3da6154c324cc916845bc5de3de077d0b59ffcBrian Paul rgba[i][RCOMP] = CLAMP(rgba[i][RCOMP], 0.0, CHAN_MAXF); 1490ba3da6154c324cc916845bc5de3de077d0b59ffcBrian Paul rgba[i][GCOMP] = CLAMP(rgba[i][GCOMP], 0.0, CHAN_MAXF); 1491ba3da6154c324cc916845bc5de3de077d0b59ffcBrian Paul rgba[i][BCOMP] = CLAMP(rgba[i][BCOMP], 0.0, CHAN_MAXF); 1492ba3da6154c324cc916845bc5de3de077d0b59ffcBrian Paul rgba[i][ACOMP] = CLAMP(rgba[i][ACOMP], 0.0, CHAN_MAXF); 1493ba3da6154c324cc916845bc5de3de077d0b59ffcBrian Paul } 1494ba3da6154c324cc916845bc5de3de077d0b59ffcBrian Paul } 1495ba3da6154c324cc916845bc5de3de077d0b59ffcBrian Paul#endif 1496ba3da6154c324cc916845bc5de3de077d0b59ffcBrian Paul 1497ba001224a18fa12792696ef393e708e90092127eBrian Paul /* 1498ba001224a18fa12792696ef393e708e90092127eBrian Paul * Write to renderbuffers 1499ba001224a18fa12792696ef393e708e90092127eBrian Paul */ 1500ba001224a18fa12792696ef393e708e90092127eBrian Paul { 1501ba001224a18fa12792696ef393e708e90092127eBrian Paul struct gl_framebuffer *fb = ctx->DrawBuffer; 1502a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul const GLuint output = 0; /* only frag progs can write to other outputs */ 1503ba001224a18fa12792696ef393e708e90092127eBrian Paul const GLuint numDrawBuffers = fb->_NumColorDrawBuffers[output]; 1504ba001224a18fa12792696ef393e708e90092127eBrian Paul GLchan rgbaSave[MAX_WIDTH][4]; 1505ba001224a18fa12792696ef393e708e90092127eBrian Paul GLuint buf; 1506e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul 1507d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul if (numDrawBuffers > 0) { 1508d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul if (fb->_ColorDrawBuffers[output][0]->DataType 1509d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul != span->array->ChanType) { 1510d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul convert_color_type(ctx, span, 1511d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul fb->_ColorDrawBuffers[output][0]->DataType); 1512d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul } 1513d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul } 1514d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul 1515ba001224a18fa12792696ef393e708e90092127eBrian Paul if (numDrawBuffers > 1) { 1516ba001224a18fa12792696ef393e708e90092127eBrian Paul /* save colors for second, third renderbuffer writes */ 1517ba001224a18fa12792696ef393e708e90092127eBrian Paul _mesa_memcpy(rgbaSave, span->array->rgba, 1518ba001224a18fa12792696ef393e708e90092127eBrian Paul 4 * span->end * sizeof(GLchan)); 151971340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 152071340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul 1521ba001224a18fa12792696ef393e708e90092127eBrian Paul for (buf = 0; buf < numDrawBuffers; buf++) { 1522ba001224a18fa12792696ef393e708e90092127eBrian Paul struct gl_renderbuffer *rb = fb->_ColorDrawBuffers[output][buf]; 1523f971e24cf0341dd2779196a0836327b74fc82336Brian Paul ASSERT(rb->_BaseFormat == GL_RGBA || rb->_BaseFormat == GL_RGB); 152471340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul 1525ba001224a18fa12792696ef393e708e90092127eBrian Paul if (ctx->Color._LogicOpEnabled) { 1526f515c78a2320369ead087c4e0efd583f17b4b78bBrian Paul _swrast_logicop_rgba_span(ctx, rb, span); 1527ba001224a18fa12792696ef393e708e90092127eBrian Paul } 1528ba001224a18fa12792696ef393e708e90092127eBrian Paul else if (ctx->Color.BlendEnabled) { 1529f515c78a2320369ead087c4e0efd583f17b4b78bBrian Paul _swrast_blend_span(ctx, rb, span); 1530ba001224a18fa12792696ef393e708e90092127eBrian Paul } 1531ba001224a18fa12792696ef393e708e90092127eBrian Paul 1532ba001224a18fa12792696ef393e708e90092127eBrian Paul if (colorMask != 0xffffffff) { 1533f515c78a2320369ead087c4e0efd583f17b4b78bBrian Paul _swrast_mask_rgba_span(ctx, rb, span); 1534ba001224a18fa12792696ef393e708e90092127eBrian Paul } 1535ba001224a18fa12792696ef393e708e90092127eBrian Paul 1536ba001224a18fa12792696ef393e708e90092127eBrian Paul if (span->arrayMask & SPAN_XY) { 1537ba001224a18fa12792696ef393e708e90092127eBrian Paul /* array of pixel coords */ 1538ba001224a18fa12792696ef393e708e90092127eBrian Paul ASSERT(rb->PutValues); 1539ba001224a18fa12792696ef393e708e90092127eBrian Paul rb->PutValues(ctx, rb, span->end, 1540ba001224a18fa12792696ef393e708e90092127eBrian Paul span->array->x, span->array->y, 1541ba001224a18fa12792696ef393e708e90092127eBrian Paul span->array->rgba, span->array->mask); 1542ba001224a18fa12792696ef393e708e90092127eBrian Paul } 1543ba001224a18fa12792696ef393e708e90092127eBrian Paul else { 1544ba001224a18fa12792696ef393e708e90092127eBrian Paul /* horizontal run of pixels */ 1545ba001224a18fa12792696ef393e708e90092127eBrian Paul ASSERT(rb->PutRow); 1546ba001224a18fa12792696ef393e708e90092127eBrian Paul rb->PutRow(ctx, rb, span->end, span->x, span->y, span->array->rgba, 1547ba001224a18fa12792696ef393e708e90092127eBrian Paul span->writeAll ? NULL: span->array->mask); 1548ba001224a18fa12792696ef393e708e90092127eBrian Paul } 1549ba001224a18fa12792696ef393e708e90092127eBrian Paul 1550ba001224a18fa12792696ef393e708e90092127eBrian Paul if (buf + 1 < numDrawBuffers) { 1551ba001224a18fa12792696ef393e708e90092127eBrian Paul /* restore original span values */ 1552ba001224a18fa12792696ef393e708e90092127eBrian Paul _mesa_memcpy(span->array->rgba, rgbaSave, 1553ba001224a18fa12792696ef393e708e90092127eBrian Paul 4 * span->end * sizeof(GLchan)); 1554ba001224a18fa12792696ef393e708e90092127eBrian Paul } 1555ba001224a18fa12792696ef393e708e90092127eBrian Paul } /* for buf */ 155671340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 155771340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul 1558e5b244ff7f984805c1bcc020342f1300f2639c71Brian Paul span->interpMask = origInterpMask; 1559f1e236987829393c81dc86ea19cb49eefe190317Brian Paul span->arrayMask = origArrayMask; 156010f30eb43835c57c00783390a02d72daf4f78e26Brian Paul} 156110f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 1562e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 1563e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 156479c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/** 1565e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Read RGBA pixels from frame buffer. Clipping will be done to prevent 1566e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * reading ouside the buffer's boundaries. 1567e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */ 15685071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paulvoid 1569e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul_swrast_read_rgba_span( GLcontext *ctx, struct gl_renderbuffer *rb, 1570a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul GLuint n, GLint x, GLint y, GLchan rgba[][4] ) 1571e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell{ 1572e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul const GLint bufWidth = (GLint) rb->Width; 1573e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul const GLint bufHeight = (GLint) rb->Height; 1574a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul 1575a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul if (y < 0 || y >= bufHeight || x + (GLint) n < 0 || x >= bufWidth) { 1576e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* completely above, below, or right */ 1577e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul /* XXX maybe leave rgba values undefined? */ 15786ec6b845fdf3c44436028ad6fff9471d18928719Brian Paul _mesa_bzero(rgba, 4 * n * sizeof(GLchan)); 1579e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1580e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell else { 1581e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell GLint skip, length; 1582e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell if (x < 0) { 15837e152b83cbc3af028175a52450c60101cb16acf8Brian Paul /* left edge clipping */ 1584e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell skip = -x; 1585e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell length = (GLint) n - skip; 1586e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell if (length < 0) { 1587e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* completely left of window */ 1588e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell return; 1589e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1590a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul if (length > bufWidth) { 1591a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul length = bufWidth; 1592e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1593e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1594a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul else if ((GLint) (x + n) > bufWidth) { 1595e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* right edge clipping */ 1596e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell skip = 0; 1597a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul length = bufWidth - x; 1598e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell if (length < 0) { 1599e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* completely to right of window */ 1600e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell return; 1601e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1602e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1603e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell else { 1604e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* no clipping */ 1605e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell skip = 0; 1606e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell length = (GLint) n; 1607e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1608e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 1609bb8b302dbce4f830d060efecd8a9f75b10e25abbBrian Paul ASSERT(rb); 1610bb8b302dbce4f830d060efecd8a9f75b10e25abbBrian Paul ASSERT(rb->GetRow); 1611bb8b302dbce4f830d060efecd8a9f75b10e25abbBrian Paul ASSERT(rb->_BaseFormat == GL_RGB || rb->_BaseFormat == GL_RGBA); 161265dccf377de51d6cbc15cb968eec85ba3f1febc1Brian Paul ASSERT(rb->DataType == CHAN_TYPE); 1613bb8b302dbce4f830d060efecd8a9f75b10e25abbBrian Paul rb->GetRow(ctx, rb, length, x + skip, y, rgba + skip); 1614e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1615e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell} 1616e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 1617e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 161879c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/** 1619e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Read CI pixels from frame buffer. Clipping will be done to prevent 1620e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * reading ouside the buffer's boundaries. 1621e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */ 16225071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paulvoid 1623e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul_swrast_read_index_span( GLcontext *ctx, struct gl_renderbuffer *rb, 1624e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul GLuint n, GLint x, GLint y, GLuint index[] ) 1625e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell{ 1626e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul const GLint bufWidth = (GLint) rb->Width; 1627e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul const GLint bufHeight = (GLint) rb->Height; 1628a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul 1629a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul if (y < 0 || y >= bufHeight || x + (GLint) n < 0 || x >= bufWidth) { 1630e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* completely above, below, or right */ 1631e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul _mesa_bzero(index, n * sizeof(GLuint)); 1632e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1633e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell else { 1634e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell GLint skip, length; 1635e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell if (x < 0) { 16367e152b83cbc3af028175a52450c60101cb16acf8Brian Paul /* left edge clipping */ 1637e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell skip = -x; 1638e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell length = (GLint) n - skip; 1639e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell if (length < 0) { 1640e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* completely left of window */ 1641e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell return; 1642e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1643a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul if (length > bufWidth) { 1644a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul length = bufWidth; 1645e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1646e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1647a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul else if ((GLint) (x + n) > bufWidth) { 1648e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* right edge clipping */ 1649e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell skip = 0; 1650a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul length = bufWidth - x; 1651e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell if (length < 0) { 1652e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* completely to right of window */ 1653e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell return; 1654e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1655e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1656e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell else { 1657e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* no clipping */ 1658e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell skip = 0; 1659e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell length = (GLint) n; 1660e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1661e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 1662e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul ASSERT(rb->GetRow); 1663e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul ASSERT(rb->_BaseFormat == GL_COLOR_INDEX); 1664e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul 1665e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul if (rb->DataType == GL_UNSIGNED_BYTE) { 1666e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul GLubyte index8[MAX_WIDTH]; 1667e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul GLint i; 1668e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul rb->GetRow(ctx, rb, length, x + skip, y, index8); 1669e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul for (i = 0; i < length; i++) 1670e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul index[skip + i] = index8[i]; 1671e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul } 1672e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul else if (rb->DataType == GL_UNSIGNED_SHORT) { 1673e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul GLushort index16[MAX_WIDTH]; 1674e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul GLint i; 1675e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul rb->GetRow(ctx, rb, length, x + skip, y, index16); 1676e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul for (i = 0; i < length; i++) 1677e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul index[skip + i] = index16[i]; 1678e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul } 1679e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul else if (rb->DataType == GL_UNSIGNED_INT) { 1680e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul rb->GetRow(ctx, rb, length, x + skip, y, index + skip); 1681e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul } 1682e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1683e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell} 168467074332728acba86da7630353673b458713bb8aBrian Paul 168567074332728acba86da7630353673b458713bb8aBrian Paul 168667074332728acba86da7630353673b458713bb8aBrian Paul/** 168767074332728acba86da7630353673b458713bb8aBrian Paul * Wrapper for gl_renderbuffer::GetValues() which does clipping to avoid 168867074332728acba86da7630353673b458713bb8aBrian Paul * reading values outside the buffer bounds. 168967074332728acba86da7630353673b458713bb8aBrian Paul * We can use this for reading any format/type of renderbuffer. 1690ba001224a18fa12792696ef393e708e90092127eBrian Paul * \param valueSize is the size in bytes of each value (pixel) put into the 169167074332728acba86da7630353673b458713bb8aBrian Paul * values array. 169267074332728acba86da7630353673b458713bb8aBrian Paul */ 169367074332728acba86da7630353673b458713bb8aBrian Paulvoid 169467074332728acba86da7630353673b458713bb8aBrian Paul_swrast_get_values(GLcontext *ctx, struct gl_renderbuffer *rb, 169567074332728acba86da7630353673b458713bb8aBrian Paul GLuint count, const GLint x[], const GLint y[], 169667074332728acba86da7630353673b458713bb8aBrian Paul void *values, GLuint valueSize) 169767074332728acba86da7630353673b458713bb8aBrian Paul{ 169867074332728acba86da7630353673b458713bb8aBrian Paul GLuint i, inCount = 0, inStart = 0; 169967074332728acba86da7630353673b458713bb8aBrian Paul 170067074332728acba86da7630353673b458713bb8aBrian Paul for (i = 0; i < count; i++) { 170167074332728acba86da7630353673b458713bb8aBrian Paul if (x[i] >= 0 && y[i] >= 0 && x[i] < rb->Width && y[i] < rb->Height) { 170267074332728acba86da7630353673b458713bb8aBrian Paul /* inside */ 170367074332728acba86da7630353673b458713bb8aBrian Paul if (inCount == 0) 170467074332728acba86da7630353673b458713bb8aBrian Paul inStart = i; 170567074332728acba86da7630353673b458713bb8aBrian Paul inCount++; 170667074332728acba86da7630353673b458713bb8aBrian Paul } 170767074332728acba86da7630353673b458713bb8aBrian Paul else { 170867074332728acba86da7630353673b458713bb8aBrian Paul if (inCount > 0) { 170967074332728acba86da7630353673b458713bb8aBrian Paul /* read [inStart, inStart + inCount) */ 171067074332728acba86da7630353673b458713bb8aBrian Paul rb->GetValues(ctx, rb, inCount, x + inStart, y + inStart, 171167074332728acba86da7630353673b458713bb8aBrian Paul (GLubyte *) values + inStart * valueSize); 171267074332728acba86da7630353673b458713bb8aBrian Paul inCount = 0; 171367074332728acba86da7630353673b458713bb8aBrian Paul } 171467074332728acba86da7630353673b458713bb8aBrian Paul } 171567074332728acba86da7630353673b458713bb8aBrian Paul } 171667074332728acba86da7630353673b458713bb8aBrian Paul if (inCount > 0) { 171767074332728acba86da7630353673b458713bb8aBrian Paul /* read last values */ 171867074332728acba86da7630353673b458713bb8aBrian Paul rb->GetValues(ctx, rb, inCount, x + inStart, y + inStart, 171967074332728acba86da7630353673b458713bb8aBrian Paul (GLubyte *) values + inStart * valueSize); 172067074332728acba86da7630353673b458713bb8aBrian Paul } 172167074332728acba86da7630353673b458713bb8aBrian Paul} 17223fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul 17233fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul 17243fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul/** 17253fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul * Wrapper for gl_renderbuffer::PutRow() which does clipping. 1726a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul * \param valueSize size of each value (pixel) in bytes 17273fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul */ 17283fd819aef8139761ce86cb8d763de83a11c81b33Brian Paulvoid 17293fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul_swrast_put_row(GLcontext *ctx, struct gl_renderbuffer *rb, 17303fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul GLuint count, GLint x, GLint y, 17313fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul const GLvoid *values, GLuint valueSize) 17323fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul{ 17333fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul GLint skip = 0; 17343fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul 17353fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul if (y < 0 || y >= rb->Height) 17363fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul return; /* above or below */ 17373fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul 17383fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul if (x + (GLint) count <= 0 || x >= rb->Width) 17393fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul return; /* entirely left or right */ 17403fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul 17413fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul if (x + count > rb->Width) { 17423fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul /* right clip */ 17433fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul GLint clip = x + count - rb->Width; 17443fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul count -= clip; 17453fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul } 17463fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul 17473fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul if (x < 0) { 17483fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul /* left clip */ 17493fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul skip = -x; 17503fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul x = 0; 17513fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul count -= skip; 17523fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul } 17533fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul 17543fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul rb->PutRow(ctx, rb, count, x, y, 17553fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul (const GLubyte *) values + skip * valueSize, NULL); 17563fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul} 1757f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul 1758f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul 1759f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul/** 1760f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul * Wrapper for gl_renderbuffer::GetRow() which does clipping. 1761a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul * \param valueSize size of each value (pixel) in bytes 1762f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul */ 1763f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paulvoid 1764f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul_swrast_get_row(GLcontext *ctx, struct gl_renderbuffer *rb, 1765f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul GLuint count, GLint x, GLint y, 1766f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul GLvoid *values, GLuint valueSize) 1767f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul{ 1768f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul GLint skip = 0; 1769f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul 1770f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul if (y < 0 || y >= rb->Height) 1771f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul return; /* above or below */ 1772f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul 1773f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul if (x + (GLint) count <= 0 || x >= rb->Width) 1774f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul return; /* entirely left or right */ 1775f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul 1776f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul if (x + count > rb->Width) { 1777f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul /* right clip */ 1778f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul GLint clip = x + count - rb->Width; 1779f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul count -= clip; 1780f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul } 1781f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul 1782f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul if (x < 0) { 1783f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul /* left clip */ 1784f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul skip = -x; 1785f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul x = 0; 1786f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul count -= skip; 1787f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul } 1788f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul 1789f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul rb->GetRow(ctx, rb, count, x, y, (GLubyte *) values + skip * valueSize); 1790f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul} 1791a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul 1792a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul 1793a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul/** 1794a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul * Get RGBA pixels from the given renderbuffer. Put the pixel colors into 1795a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul * the span's specular color arrays. The specular color arrays should no 1796a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul * longer be needed by time this function is called. 1797a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul * Used by blending, logicop and masking functions. 1798a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul * \return pointer to the colors we read. 1799a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul */ 1800a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paulvoid * 1801a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul_swrast_get_dest_rgba(GLcontext *ctx, struct gl_renderbuffer *rb, 1802cdb27e8242215271364602995d85607cfc06d441Brian Paul SWspan *span) 1803a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul{ 1804a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul GLuint pixelSize; 1805a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul void *rbPixels; 1806a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul 1807a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul /* 1808a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul * Determine pixel size (in bytes). 1809a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul * Point rbPixels to a temporary space (use specular color arrays). 1810a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul */ 1811a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul if (span->array->ChanType == GL_UNSIGNED_BYTE) { 1812a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul pixelSize = 4 * sizeof(GLubyte); 1813a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul rbPixels = span->array->color.sz1.spec; 1814a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul } 1815a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul else if (span->array->ChanType == GL_UNSIGNED_SHORT) { 1816a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul pixelSize = 4 * sizeof(GLushort); 1817a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul rbPixels = span->array->color.sz2.spec; 1818a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul } 1819a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul else { 1820a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul pixelSize = 4 * sizeof(GLfloat); 1821a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul rbPixels = span->array->color.sz4.spec; 1822a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul } 1823a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul 1824a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul /* Get destination values from renderbuffer */ 1825a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul if (span->arrayMask & SPAN_XY) { 1826a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul _swrast_get_values(ctx, rb, span->end, span->array->x, span->array->y, 1827a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul rbPixels, pixelSize); 1828a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul } 1829a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul else { 1830a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul _swrast_get_row(ctx, rb, span->end, span->x, span->y, 1831a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul rbPixels, pixelSize); 1832a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul } 1833a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul 1834a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul return rbPixels; 1835a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul} 1836