s_span.c revision bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4d
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" 38e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 397f752fed993e5e9423abac200dd59141edbada56Dave Airlie#include "s_atifragshader.h" 40bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol#include "s_alpha.h" 41a66393120411071b3f3ccce8583ab961a2935959Michal Krol#include "s_arbshader.h" 42e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_blend.h" 43cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell#include "s_context.h" 44e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_depth.h" 45e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_fog.h" 46e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_logic.h" 47e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_masking.h" 48610d59981a9f43fefe29b34ef19c184d28e2bef5Brian Paul#include "s_nvfragprog.h" 49e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_span.h" 50e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_stencil.h" 5155187ea63e980b32c7a701855571332f4357d634Brian Paul#include "s_texcombine.h" 52e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 532a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 5479c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/** 552a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul * Init span's Z interpolation values to the RasterPos Z. 562a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul * Used during setup for glDraw/CopyPixels. 572a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul */ 582a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paulvoid 5945bc887da226403f2c41077e40ca38b6f60f1359Brian Paul_swrast_span_default_z( GLcontext *ctx, struct sw_span *span ) 602a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul{ 61e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul const GLfloat depthMax = ctx->DrawBuffer->_DepthMaxF; 6231e739a18931fa48454f172818245b0927c8910fBrian Paul if (ctx->DrawBuffer->Visual.depthBits <= 16) 63e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul span->z = FloatToFixed(ctx->Current.RasterPos[2] * depthMax + 0.5F); 642a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul else 65e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul span->z = (GLint) (ctx->Current.RasterPos[2] * depthMax + 0.5F); 662a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->zStep = 0; 672a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->interpMask |= SPAN_Z; 682a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul} 692a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 702a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 7179c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/** 722a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul * Init span's fog interpolation values to the RasterPos fog. 732a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul * Used during setup for glDraw/CopyPixels. 742a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul */ 752a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paulvoid 7645bc887da226403f2c41077e40ca38b6f60f1359Brian Paul_swrast_span_default_fog( GLcontext *ctx, struct sw_span *span ) 772a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul{ 7845bc887da226403f2c41077e40ca38b6f60f1359Brian Paul span->fog = _swrast_z_to_fogfactor(ctx, ctx->Current.RasterDistance); 7954e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul span->fogStep = span->dfogdx = span->dfogdy = 0.0F; 802a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->interpMask |= SPAN_FOG; 812a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul} 822a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 832a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 8479c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/** 85a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul * Init span's rgba or index interpolation values to the RasterPos color. 862a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul * Used during setup for glDraw/CopyPixels. 872a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul */ 882a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paulvoid 8945bc887da226403f2c41077e40ca38b6f60f1359Brian Paul_swrast_span_default_color( GLcontext *ctx, struct sw_span *span ) 902a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul{ 912a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul if (ctx->Visual.rgbMode) { 922a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLchan r, g, b, a; 932a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul UNCLAMPED_FLOAT_TO_CHAN(r, ctx->Current.RasterColor[0]); 942a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul UNCLAMPED_FLOAT_TO_CHAN(g, ctx->Current.RasterColor[1]); 952a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul UNCLAMPED_FLOAT_TO_CHAN(b, ctx->Current.RasterColor[2]); 962a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul UNCLAMPED_FLOAT_TO_CHAN(a, ctx->Current.RasterColor[3]); 972a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul#if CHAN_TYPE == GL_FLOAT 982a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->red = r; 992a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->green = g; 1002a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->blue = b; 1012a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->alpha = a; 1022a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul#else 1032a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->red = IntToFixed(r); 1042a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->green = IntToFixed(g); 1052a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->blue = IntToFixed(b); 1062a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->alpha = IntToFixed(a); 1072a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul#endif 1082a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->redStep = 0; 1092a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->greenStep = 0; 1102a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->blueStep = 0; 1112a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->alphaStep = 0; 1122a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->interpMask |= SPAN_RGBA; 1132a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 1142a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul else { 1150f3cd3f894612d156de454178effa4c732f96da7Brian Paul span->index = FloatToFixed(ctx->Current.RasterIndex); 1162a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->indexStep = 0; 1172a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->interpMask |= SPAN_INDEX; 1182a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 1192a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul} 1202a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 1212a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 1224753d60dd070bb08d0116076bcc08025c86ce857Brian Paul/** 1234753d60dd070bb08d0116076bcc08025c86ce857Brian Paul * Init span's texcoord interpolation values to the RasterPos texcoords. 1244753d60dd070bb08d0116076bcc08025c86ce857Brian Paul * Used during setup for glDraw/CopyPixels. 1254753d60dd070bb08d0116076bcc08025c86ce857Brian Paul */ 1264753d60dd070bb08d0116076bcc08025c86ce857Brian Paulvoid 12745bc887da226403f2c41077e40ca38b6f60f1359Brian Paul_swrast_span_default_texcoords( GLcontext *ctx, struct sw_span *span ) 1284753d60dd070bb08d0116076bcc08025c86ce857Brian Paul{ 1294753d60dd070bb08d0116076bcc08025c86ce857Brian Paul GLuint i; 1304753d60dd070bb08d0116076bcc08025c86ce857Brian Paul for (i = 0; i < ctx->Const.MaxTextureUnits; i++) { 131e63cb85cbc13c083f5d9f4640bb81ba9417a4f28Brian Paul const GLfloat *tc = ctx->Current.RasterTexCoords[i]; 13247b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell if (ctx->FragmentProgram._Active || ctx->ATIFragmentShader._Enabled) { 133a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul COPY_4V(span->tex[i], tc); 134a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul } 135a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul else if (tc[3] > 0.0F) { 136e63cb85cbc13c083f5d9f4640bb81ba9417a4f28Brian Paul /* use (s/q, t/q, r/q, 1) */ 137e63cb85cbc13c083f5d9f4640bb81ba9417a4f28Brian Paul span->tex[i][0] = tc[0] / tc[3]; 138e63cb85cbc13c083f5d9f4640bb81ba9417a4f28Brian Paul span->tex[i][1] = tc[1] / tc[3]; 139e63cb85cbc13c083f5d9f4640bb81ba9417a4f28Brian Paul span->tex[i][2] = tc[2] / tc[3]; 140e63cb85cbc13c083f5d9f4640bb81ba9417a4f28Brian Paul span->tex[i][3] = 1.0; 141e63cb85cbc13c083f5d9f4640bb81ba9417a4f28Brian Paul } 142e63cb85cbc13c083f5d9f4640bb81ba9417a4f28Brian Paul else { 143e63cb85cbc13c083f5d9f4640bb81ba9417a4f28Brian Paul ASSIGN_4V(span->tex[i], 0.0F, 0.0F, 0.0F, 1.0F); 144e63cb85cbc13c083f5d9f4640bb81ba9417a4f28Brian Paul } 1455f60a0b50ada1865d4fc6a724366e8ea0cc9a72fBrian Paul ASSIGN_4V(span->texStepX[i], 0.0F, 0.0F, 0.0F, 0.0F); 1465f60a0b50ada1865d4fc6a724366e8ea0cc9a72fBrian Paul ASSIGN_4V(span->texStepY[i], 0.0F, 0.0F, 0.0F, 0.0F); 1474753d60dd070bb08d0116076bcc08025c86ce857Brian Paul } 1484753d60dd070bb08d0116076bcc08025c86ce857Brian Paul span->interpMask |= SPAN_TEXTURE; 1494753d60dd070bb08d0116076bcc08025c86ce857Brian Paul} 1504753d60dd070bb08d0116076bcc08025c86ce857Brian Paul 1514753d60dd070bb08d0116076bcc08025c86ce857Brian Paul 1522a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul/* Fill in the span.color.rgba array from the interpolation values */ 1532a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paulstatic void 1542a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paulinterpolate_colors(GLcontext *ctx, struct sw_span *span) 1552a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul{ 1562a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul const GLuint n = span->end; 15777df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul GLchan (*rgba)[4] = span->array->rgba; 1582a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLuint i; 159a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul (void) ctx; 1602a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 161b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul ASSERT((span->interpMask & SPAN_RGBA) && 162b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul !(span->arrayMask & SPAN_RGBA)); 1632a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 1642a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul if (span->interpMask & SPAN_FLAT) { 1652a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul /* constant color */ 1662a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLchan color[4]; 1676a98bef96189fbacc326ad9e407c1d4423aa8572Brian Paul color[RCOMP] = FixedToChan(span->red); 1686a98bef96189fbacc326ad9e407c1d4423aa8572Brian Paul color[GCOMP] = FixedToChan(span->green); 1696a98bef96189fbacc326ad9e407c1d4423aa8572Brian Paul color[BCOMP] = FixedToChan(span->blue); 1706a98bef96189fbacc326ad9e407c1d4423aa8572Brian Paul color[ACOMP] = FixedToChan(span->alpha); 1712a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul for (i = 0; i < n; i++) { 17277df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul COPY_CHAN4(span->array->rgba[i], color); 1732a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 1742a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 1752a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul else { 1762a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul /* interpolate */ 1776a98bef96189fbacc326ad9e407c1d4423aa8572Brian Paul#if CHAN_TYPE == GL_FLOAT 1786a98bef96189fbacc326ad9e407c1d4423aa8572Brian Paul GLfloat r = span->red; 1796a98bef96189fbacc326ad9e407c1d4423aa8572Brian Paul GLfloat g = span->green; 1806a98bef96189fbacc326ad9e407c1d4423aa8572Brian Paul GLfloat b = span->blue; 1816a98bef96189fbacc326ad9e407c1d4423aa8572Brian Paul GLfloat a = span->alpha; 1826a98bef96189fbacc326ad9e407c1d4423aa8572Brian Paul const GLfloat dr = span->redStep; 1836a98bef96189fbacc326ad9e407c1d4423aa8572Brian Paul const GLfloat dg = span->greenStep; 1846a98bef96189fbacc326ad9e407c1d4423aa8572Brian Paul const GLfloat db = span->blueStep; 1856a98bef96189fbacc326ad9e407c1d4423aa8572Brian Paul const GLfloat da = span->alphaStep; 1866a98bef96189fbacc326ad9e407c1d4423aa8572Brian Paul#else 1876a98bef96189fbacc326ad9e407c1d4423aa8572Brian Paul GLfixed r = span->red; 1886a98bef96189fbacc326ad9e407c1d4423aa8572Brian Paul GLfixed g = span->green; 1896a98bef96189fbacc326ad9e407c1d4423aa8572Brian Paul GLfixed b = span->blue; 1906a98bef96189fbacc326ad9e407c1d4423aa8572Brian Paul GLfixed a = span->alpha; 1916a98bef96189fbacc326ad9e407c1d4423aa8572Brian Paul const GLint dr = span->redStep; 1926a98bef96189fbacc326ad9e407c1d4423aa8572Brian Paul const GLint dg = span->greenStep; 1936a98bef96189fbacc326ad9e407c1d4423aa8572Brian Paul const GLint db = span->blueStep; 1946a98bef96189fbacc326ad9e407c1d4423aa8572Brian Paul const GLint da = span->alphaStep; 1956a98bef96189fbacc326ad9e407c1d4423aa8572Brian Paul#endif 1962a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul for (i = 0; i < n; i++) { 1972a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul rgba[i][RCOMP] = FixedToChan(r); 1982a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul rgba[i][GCOMP] = FixedToChan(g); 1992a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul rgba[i][BCOMP] = FixedToChan(b); 2002a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul rgba[i][ACOMP] = FixedToChan(a); 2012a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul r += dr; 2022a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul g += dg; 2032a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul b += db; 2042a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul a += da; 2052a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 2062a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 2072a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->arrayMask |= SPAN_RGBA; 2082a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul} 2092a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 2102a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 2112a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul/* Fill in the span.color.index array from the interpolation values */ 2122a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paulstatic void 2132a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paulinterpolate_indexes(GLcontext *ctx, struct sw_span *span) 2142a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul{ 2152a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfixed index = span->index; 2162a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul const GLint indexStep = span->indexStep; 2172a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul const GLuint n = span->end; 21877df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul GLuint *indexes = span->array->index; 2192a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLuint i; 220a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul (void) ctx; 221b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul ASSERT((span->interpMask & SPAN_INDEX) && 222b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul !(span->arrayMask & SPAN_INDEX)); 2232a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 2242a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul if ((span->interpMask & SPAN_FLAT) || (indexStep == 0)) { 2252a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul /* constant color */ 2262a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul index = FixedToInt(index); 2272a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul for (i = 0; i < n; i++) { 2282a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul indexes[i] = index; 2292a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 2302a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 2312a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul else { 2322a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul /* interpolate */ 2332a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul for (i = 0; i < n; i++) { 2342a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul indexes[i] = FixedToInt(index); 2352a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul index += indexStep; 2362a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 2372a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 2382a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->arrayMask |= SPAN_INDEX; 239e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul span->interpMask &= ~SPAN_INDEX; 2402a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul} 2412a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 2422a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 24377df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul/* Fill in the span.->array->spec array from the interpolation values */ 2442a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paulstatic void 2452a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paulinterpolate_specular(GLcontext *ctx, struct sw_span *span) 2462a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul{ 247a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul (void) ctx; 2482a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul if (span->interpMask & SPAN_FLAT) { 2492a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul /* constant color */ 2502a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul const GLchan r = FixedToChan(span->specRed); 2512a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul const GLchan g = FixedToChan(span->specGreen); 2522a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul const GLchan b = FixedToChan(span->specBlue); 2532a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLuint i; 2542a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul for (i = 0; i < span->end; i++) { 25577df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul span->array->spec[i][RCOMP] = r; 25677df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul span->array->spec[i][GCOMP] = g; 25777df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul span->array->spec[i][BCOMP] = b; 2582a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 2592a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 2602a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul else { 2612a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul /* interpolate */ 2622a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul#if CHAN_TYPE == GL_FLOAT 2632a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat r = span->specRed; 2642a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat g = span->specGreen; 2652a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat b = span->specBlue; 2662a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul#else 2672a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfixed r = span->specRed; 2682a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfixed g = span->specGreen; 2692a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfixed b = span->specBlue; 2702a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul#endif 2712a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLuint i; 2722a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul for (i = 0; i < span->end; i++) { 27377df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul span->array->spec[i][RCOMP] = FixedToChan(r); 27477df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul span->array->spec[i][GCOMP] = FixedToChan(g); 27577df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul span->array->spec[i][BCOMP] = FixedToChan(b); 2762a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul r += span->specRedStep; 2772a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul g += span->specGreenStep; 2782a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul b += span->specBlueStep; 2792a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 2802a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 2812a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->arrayMask |= SPAN_SPEC; 2822a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul} 2832a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 2842a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 285d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul/* Fill in the span.array.fog values from the interpolation values */ 286d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paulstatic void 287d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paulinterpolate_fog(const GLcontext *ctx, struct sw_span *span) 288d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul{ 289d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul GLfloat *fog = span->array->fog; 290d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul const GLfloat fogStep = span->fogStep; 291d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul GLfloat fogCoord = span->fog; 292d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul const GLuint haveW = (span->interpMask & SPAN_W); 293d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul const GLfloat wStep = haveW ? span->dwdx : 0.0F; 294d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul GLfloat w = haveW ? span->w : 1.0F; 295d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul GLuint i; 296d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul for (i = 0; i < span->end; i++) { 297d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul fog[i] = fogCoord / w; 298d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul fogCoord += fogStep; 299d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul w += wStep; 300d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul } 301d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul span->arrayMask |= SPAN_FOG; 302d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul} 303d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul 304d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul 3052a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul/* Fill in the span.zArray array from the interpolation values */ 306711e27fda27e4235b20a4cf73c2767c984ab2b81Brian Paulvoid 30745bc887da226403f2c41077e40ca38b6f60f1359Brian Paul_swrast_span_interpolate_z( const GLcontext *ctx, struct sw_span *span ) 3082a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul{ 3092a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul const GLuint n = span->end; 3102a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLuint i; 3112a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 312b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul ASSERT((span->interpMask & SPAN_Z) && 313b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul !(span->arrayMask & SPAN_Z)); 3142a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 31531e739a18931fa48454f172818245b0927c8910fBrian Paul if (ctx->DrawBuffer->Visual.depthBits <= 16) { 3162a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfixed zval = span->z; 3173e37bafab0a339021354b9c78f983d05d433d735Brian Paul GLuint *z = span->array->z; 318ad8cd6111e022c90c93df106c0fde6f64d205816Brian Paul for (i = 0; i < n; i++) { 31977df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul z[i] = FixedToInt(zval); 3202a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul zval += span->zStep; 3212a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 3222a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 3232a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul else { 3242a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul /* Deep Z buffer, no fixed->int shift */ 3257265556b9aa0367e9b5031e7cb15ed2a5d73866dBrian Paul GLuint zval = span->z; 3263e37bafab0a339021354b9c78f983d05d433d735Brian Paul GLuint *z = span->array->z; 3272a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul for (i = 0; i < n; i++) { 32877df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul z[i] = zval; 3292a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul zval += span->zStep; 3302a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 3312a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 33232340aea1308153dad5c105fc0748aea1e4c37eeBrian Paul span->interpMask &= ~SPAN_Z; 3332a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->arrayMask |= SPAN_Z; 3342a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul} 3352a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 3362a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 337c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul/* 33831f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul * This the ideal solution, as given in the OpenGL spec. 339c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul */ 340c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul#if 0 34131f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paulstatic GLfloat 34231f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paulcompute_lambda(GLfloat dsdx, GLfloat dsdy, GLfloat dtdx, GLfloat dtdy, 34331f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat dqdx, GLfloat dqdy, GLfloat texW, GLfloat texH, 34431f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat s, GLfloat t, GLfloat q, GLfloat invQ) 345c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul{ 34631f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat dudx = texW * ((s + dsdx) / (q + dqdx) - s * invQ); 34731f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat dvdx = texH * ((t + dtdx) / (q + dqdx) - t * invQ); 34831f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat dudy = texW * ((s + dsdy) / (q + dqdy) - s * invQ); 34931f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat dvdy = texH * ((t + dtdy) / (q + dqdy) - t * invQ); 350f9b1e5241facc8cf255c258082d5cb5b04783e93Brian Paul GLfloat x = SQRTF(dudx * dudx + dvdx * dvdx); 351f9b1e5241facc8cf255c258082d5cb5b04783e93Brian Paul GLfloat y = SQRTF(dudy * dudy + dvdy * dvdy); 35231f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat rho = MAX2(x, y); 35331f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat lambda = LOG2(rho); 35431f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul return lambda; 355c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul} 356c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul#endif 357c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul 35831f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul 35931f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul/* 36031f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul * This is a faster approximation 361c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul */ 362350353adcd75f94fda63c787c86961716114e0bfBrian PaulGLfloat 36345bc887da226403f2c41077e40ca38b6f60f1359Brian Paul_swrast_compute_lambda(GLfloat dsdx, GLfloat dsdy, GLfloat dtdx, GLfloat dtdy, 364350353adcd75f94fda63c787c86961716114e0bfBrian Paul GLfloat dqdx, GLfloat dqdy, GLfloat texW, GLfloat texH, 365350353adcd75f94fda63c787c86961716114e0bfBrian Paul GLfloat s, GLfloat t, GLfloat q, GLfloat invQ) 366c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul{ 36731f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat dsdx2 = (s + dsdx) / (q + dqdx) - s * invQ; 36831f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat dtdx2 = (t + dtdx) / (q + dqdx) - t * invQ; 36931f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat dsdy2 = (s + dsdy) / (q + dqdy) - s * invQ; 37031f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat dtdy2 = (t + dtdy) / (q + dqdy) - t * invQ; 37131f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat maxU, maxV, rho, lambda; 37231f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul dsdx2 = FABSF(dsdx2); 37331f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul dsdy2 = FABSF(dsdy2); 37431f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul dtdx2 = FABSF(dtdx2); 37531f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul dtdy2 = FABSF(dtdy2); 37631f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul maxU = MAX2(dsdx2, dsdy2) * texW; 37731f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul maxV = MAX2(dtdx2, dtdy2) * texH; 37831f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul rho = MAX2(maxU, maxV); 37931f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul lambda = LOG2(rho); 38031f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul return lambda; 381c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul} 382c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul 383d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul 384d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul/** 385c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul * Fill in the span.texcoords array from the interpolation values. 386d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul * Note: in the places where we divide by Q (or mult by invQ) we're 387d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul * really doing two things: perspective correction and texcoord 388d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul * projection. Remember, for texcoord (s,t,r,q) we need to index 389d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul * texels with (s/q, t/q, r/q). 390d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul * If we're using a fragment program, we never do the division 391d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul * for texcoord projection. That's done by the TXP instruction 392d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul * or user-written code. 393c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul */ 3942a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paulstatic void 3952a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paulinterpolate_texcoords(GLcontext *ctx, struct sw_span *span) 3962a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul{ 3972a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul ASSERT(span->interpMask & SPAN_TEXTURE); 398b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul ASSERT(!(span->arrayMask & SPAN_TEXTURE)); 3992a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 40036a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul if (ctx->Texture._EnabledCoordUnits > 1) { 40131f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul /* multitexture */ 40231f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLuint u; 403b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul span->arrayMask |= SPAN_TEXTURE; 40431f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { 40536a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul if (ctx->Texture._EnabledCoordUnits & (1 << u)) { 40631f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const struct gl_texture_object *obj =ctx->Texture.Unit[u]._Current; 40736a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul GLfloat texW, texH; 40836a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul GLboolean needLambda; 40936a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul if (obj) { 41018fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell const struct gl_texture_image *img = obj->Image[0][obj->BaseLevel]; 41136a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul needLambda = (obj->MinFilter != obj->MagFilter) 41247b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell || ctx->FragmentProgram._Active; 41336a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul texW = img->WidthScale; 41436a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul texH = img->HeightScale; 41536a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul } 41636a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul else { 417d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul /* using a fragment program */ 41836a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul texW = 1.0; 41936a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul texH = 1.0; 42036a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul needLambda = GL_FALSE; 42136a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul } 42231f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul if (needLambda) { 42377df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul GLfloat (*texcoord)[4] = span->array->texcoords[u]; 42477df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul GLfloat *lambda = span->array->lambda[u]; 42531f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat dsdx = span->texStepX[u][0]; 42631f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat dsdy = span->texStepY[u][0]; 42731f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat dtdx = span->texStepX[u][1]; 42831f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat dtdy = span->texStepY[u][1]; 42931f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat drdx = span->texStepX[u][2]; 43031f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat dqdx = span->texStepX[u][3]; 43131f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat dqdy = span->texStepY[u][3]; 4322a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat s = span->tex[u][0]; 4332a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat t = span->tex[u][1]; 4342a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat r = span->tex[u][2]; 4352a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat q = span->tex[u][3]; 4362a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLuint i; 437bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol if (ctx->FragmentProgram._Active || ctx->ATIFragmentShader._Enabled || 438bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol ctx->ShaderObjects._FragmentShaderPresent) { 439d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul /* do perspective correction but don't divide s, t, r by q */ 440d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul const GLfloat dwdx = span->dwdx; 441d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul GLfloat w = span->w; 442d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul for (i = 0; i < span->end; i++) { 443d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul const GLfloat invW = 1.0F / w; 444d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul texcoord[i][0] = s * invW; 445d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul texcoord[i][1] = t * invW; 446d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul texcoord[i][2] = r * invW; 447d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul texcoord[i][3] = q * invW; 448d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul lambda[i] = _swrast_compute_lambda(dsdx, dsdy, dtdx, dtdy, 449d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul dqdx, dqdy, texW, texH, 450d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul s, t, q, invW); 451d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul s += dsdx; 452d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul t += dtdx; 453d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul r += drdx; 454d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul q += dqdx; 455d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul w += dwdx; 456d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul } 457d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul 458d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul } 459d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul else { 460d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul for (i = 0; i < span->end; i++) { 461d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q); 462d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul texcoord[i][0] = s * invQ; 463d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul texcoord[i][1] = t * invQ; 464d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul texcoord[i][2] = r * invQ; 465d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul texcoord[i][3] = q; 466d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul lambda[i] = _swrast_compute_lambda(dsdx, dsdy, dtdx, dtdy, 467d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul dqdx, dqdy, texW, texH, 468d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul s, t, q, invQ); 469d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul s += dsdx; 470d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul t += dtdx; 471d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul r += drdx; 472d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul q += dqdx; 473d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul } 4742a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 47531f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul span->arrayMask |= SPAN_LAMBDA; 4762a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 47731f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul else { 47877df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul GLfloat (*texcoord)[4] = span->array->texcoords[u]; 47977df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul GLfloat *lambda = span->array->lambda[u]; 48031f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat dsdx = span->texStepX[u][0]; 48131f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat dtdx = span->texStepX[u][1]; 48231f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat drdx = span->texStepX[u][2]; 48331f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat dqdx = span->texStepX[u][3]; 4842a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat s = span->tex[u][0]; 4852a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat t = span->tex[u][1]; 4862a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat r = span->tex[u][2]; 4872a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat q = span->tex[u][3]; 4882a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLuint i; 489bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol if (ctx->FragmentProgram._Active || ctx->ATIFragmentShader._Enabled || 490bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol ctx->ShaderObjects._FragmentShaderPresent) { 491d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul /* do perspective correction but don't divide s, t, r by q */ 492d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul const GLfloat dwdx = span->dwdx; 493d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul GLfloat w = span->w; 494d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul for (i = 0; i < span->end; i++) { 495d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul const GLfloat invW = 1.0F / w; 496d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul texcoord[i][0] = s * invW; 497d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul texcoord[i][1] = t * invW; 498d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul texcoord[i][2] = r * invW; 499d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul texcoord[i][3] = q * invW; 500d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul lambda[i] = 0.0; 501d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul s += dsdx; 502d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul t += dtdx; 503d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul r += drdx; 504d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul q += dqdx; 505d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul w += dwdx; 506d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul } 507d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul } 508d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul else if (dqdx == 0.0F) { 509c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul /* Ortho projection or polygon's parallel to window X axis */ 5102a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q); 511c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul for (i = 0; i < span->end; i++) { 51277df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul texcoord[i][0] = s * invQ; 51377df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul texcoord[i][1] = t * invQ; 51477df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul texcoord[i][2] = r * invQ; 51536a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul texcoord[i][3] = q; 51677df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul lambda[i] = 0.0; 51731f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul s += dsdx; 51831f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul t += dtdx; 51931f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul r += drdx; 520c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul } 521c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul } 522c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul else { 523c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul for (i = 0; i < span->end; i++) { 524c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q); 52577df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul texcoord[i][0] = s * invQ; 52677df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul texcoord[i][1] = t * invQ; 52777df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul texcoord[i][2] = r * invQ; 52836a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul texcoord[i][3] = q; 52977df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul lambda[i] = 0.0; 53031f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul s += dsdx; 53131f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul t += dtdx; 53231f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul r += drdx; 53331f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul q += dqdx; 534c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul } 5352a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 53631f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul } /* lambda */ 53731f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul } /* if */ 53831f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul } /* for */ 5392a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 5402a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul else { 54131f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul /* single texture */ 54231f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const struct gl_texture_object *obj = ctx->Texture.Unit[0]._Current; 54336a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul GLfloat texW, texH; 54436a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul GLboolean needLambda; 54536a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul if (obj) { 54618fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell const struct gl_texture_image *img = obj->Image[0][obj->BaseLevel]; 54736a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul needLambda = (obj->MinFilter != obj->MagFilter) 54847b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell || ctx->FragmentProgram._Active; 54936a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul texW = (GLfloat) img->WidthScale; 55036a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul texH = (GLfloat) img->HeightScale; 55136a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul } 55236a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul else { 55336a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul needLambda = GL_FALSE; 55436a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul texW = texH = 1.0; 55536a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul } 556b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul span->arrayMask |= SPAN_TEXTURE; 55731f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul if (needLambda) { 5582a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul /* just texture unit 0, with lambda */ 55977df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul GLfloat (*texcoord)[4] = span->array->texcoords[0]; 56077df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul GLfloat *lambda = span->array->lambda[0]; 56131f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat dsdx = span->texStepX[0][0]; 56231f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat dsdy = span->texStepY[0][0]; 56331f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat dtdx = span->texStepX[0][1]; 56431f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat dtdy = span->texStepY[0][1]; 56531f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat drdx = span->texStepX[0][2]; 56631f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat dqdx = span->texStepX[0][3]; 56731f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat dqdy = span->texStepY[0][3]; 5682a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat s = span->tex[0][0]; 5692a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat t = span->tex[0][1]; 5702a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat r = span->tex[0][2]; 5712a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat q = span->tex[0][3]; 5722a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLuint i; 573bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol if (ctx->FragmentProgram._Active || ctx->ATIFragmentShader._Enabled || 574bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol ctx->ShaderObjects._FragmentShaderPresent) { 575d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul /* do perspective correction but don't divide s, t, r by q */ 576d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul const GLfloat dwdx = span->dwdx; 577d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul GLfloat w = span->w; 578d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul for (i = 0; i < span->end; i++) { 579d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul const GLfloat invW = 1.0F / w; 580d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul texcoord[i][0] = s * invW; 581d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul texcoord[i][1] = t * invW; 582d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul texcoord[i][2] = r * invW; 583d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul texcoord[i][3] = q * invW; 584d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul lambda[i] = _swrast_compute_lambda(dsdx, dsdy, dtdx, dtdy, 585d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul dqdx, dqdy, texW, texH, 586d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul s, t, q, invW); 587d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul s += dsdx; 588d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul t += dtdx; 589d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul r += drdx; 590d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul q += dqdx; 591d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul w += dwdx; 592d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul } 593d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul } 594d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul else { 595d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul /* tex.c */ 596d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul for (i = 0; i < span->end; i++) { 597d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q); 598d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul lambda[i] = _swrast_compute_lambda(dsdx, dsdy, dtdx, dtdy, 599d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul dqdx, dqdy, texW, texH, 600d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul s, t, q, invQ); 601d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul texcoord[i][0] = s * invQ; 602d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul texcoord[i][1] = t * invQ; 603d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul texcoord[i][2] = r * invQ; 604d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul texcoord[i][3] = q; 605d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul s += dsdx; 606d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul t += dtdx; 607d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul r += drdx; 608d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul q += dqdx; 609d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul } 6102a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 6112a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->arrayMask |= SPAN_LAMBDA; 6122a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 6132a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul else { 614733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* just texture 0, without lambda */ 61577df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul GLfloat (*texcoord)[4] = span->array->texcoords[0]; 61631f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat dsdx = span->texStepX[0][0]; 61731f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat dtdx = span->texStepX[0][1]; 61831f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat drdx = span->texStepX[0][2]; 61931f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat dqdx = span->texStepX[0][3]; 6202a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat s = span->tex[0][0]; 6212a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat t = span->tex[0][1]; 6222a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat r = span->tex[0][2]; 6232a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat q = span->tex[0][3]; 6242a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLuint i; 625bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol if (ctx->FragmentProgram._Active || ctx->ATIFragmentShader._Enabled || 626bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol ctx->ShaderObjects._FragmentShaderPresent) { 627d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul /* do perspective correction but don't divide s, t, r by q */ 628d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul const GLfloat dwdx = span->dwdx; 629d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul GLfloat w = span->w; 630d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul for (i = 0; i < span->end; i++) { 631d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul const GLfloat invW = 1.0F / w; 632d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul texcoord[i][0] = s * invW; 633d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul texcoord[i][1] = t * invW; 634d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul texcoord[i][2] = r * invW; 635d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul texcoord[i][3] = q * invW; 636d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul s += dsdx; 637d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul t += dtdx; 638d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul r += drdx; 639d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul q += dqdx; 640d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul w += dwdx; 641d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul } 642d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul } 643d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul else if (dqdx == 0.0F) { 644c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul /* Ortho projection or polygon's parallel to window X axis */ 6452a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q); 646c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul for (i = 0; i < span->end; i++) { 64777df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul texcoord[i][0] = s * invQ; 64877df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul texcoord[i][1] = t * invQ; 64977df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul texcoord[i][2] = r * invQ; 6502b7a01a39ba5257407dddde38ef049856c34aa01Brian Paul texcoord[i][3] = q; 65131f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul s += dsdx; 65231f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul t += dtdx; 65331f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul r += drdx; 654c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul } 655c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul } 656c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul else { 657c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul for (i = 0; i < span->end; i++) { 658c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q); 65977df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul texcoord[i][0] = s * invQ; 66077df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul texcoord[i][1] = t * invQ; 66177df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul texcoord[i][2] = r * invQ; 6622b7a01a39ba5257407dddde38ef049856c34aa01Brian Paul texcoord[i][3] = q; 66331f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul s += dsdx; 66431f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul t += dtdx; 66531f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul r += drdx; 66631f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul q += dqdx; 667c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul } 6682a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 6692a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 6702a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 67110f30eb43835c57c00783390a02d72daf4f78e26Brian Paul} 672e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 673e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 67479c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/** 675bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol * Fill in the span.varying array from the interpolation values. 676bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol */ 677bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krolstatic void 678bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krolinterpolate_varying(GLcontext *ctx, struct sw_span *span) 679bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol{ 680bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol GLuint i, j; 681bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol 682bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol ASSERT(span->interpMask & SPAN_VARYING); 683bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol ASSERT(!(span->arrayMask & SPAN_VARYING)); 684bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol 685bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol span->arrayMask |= SPAN_VARYING; 686bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol 687bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol for (i = 0; i < MAX_VARYING_VECTORS; i++) { 688bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol for (j = 0; j < VARYINGS_PER_VECTOR; j++) { 689bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol const GLfloat dvdx = span->varStepX[i][j]; 690bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol GLfloat v = span->var[i][j]; 691bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol const GLfloat dwdx = span->dwdx; 692bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol GLfloat w = span->w; 693bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol GLuint k; 694bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol 695bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol for (k = 0; k < span->end; k++) { 696bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol GLfloat invW = 1.0f / w; 697bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol span->array->varying[k][i][j] = v * invW; 698bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol v += dvdx; 699bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol w += dwdx; 700bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol } 701bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol } 702bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol } 703bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol} 704bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol 705bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol 706bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol/** 707e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Apply the current polygon stipple pattern to a span of pixels. 708e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */ 7095071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paulstatic void 710733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paulstipple_polygon_span( GLcontext *ctx, struct sw_span *span ) 71110f30eb43835c57c00783390a02d72daf4f78e26Brian Paul{ 71210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul const GLuint highbit = 0x80000000; 713733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul const GLuint stipple = ctx->PolygonStipple[span->y % 32]; 71477df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul GLubyte *mask = span->array->mask; 715733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul GLuint i, m; 716733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul 717733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul ASSERT(ctx->Polygon.StippleFlag); 718733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul ASSERT((span->arrayMask & SPAN_XY) == 0); 71910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 72010f30eb43835c57c00783390a02d72daf4f78e26Brian Paul m = highbit >> (GLuint) (span->x % 32); 72110f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 72210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul for (i = 0; i < span->end; i++) { 72310f30eb43835c57c00783390a02d72daf4f78e26Brian Paul if ((m & stipple) == 0) { 72477df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul mask[i] = 0; 72510f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 72610f30eb43835c57c00783390a02d72daf4f78e26Brian Paul m = m >> 1; 72710f30eb43835c57c00783390a02d72daf4f78e26Brian Paul if (m == 0) { 72810f30eb43835c57c00783390a02d72daf4f78e26Brian Paul m = highbit; 72910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 73010f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 7312ef866d1fc0a5cc5ef8543d65744dfd4da4dbbafBrian Paul span->writeAll = GL_FALSE; 73210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul} 73310f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 734e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 73579c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/** 736733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul * Clip a pixel span to the current buffer/window boundaries: 737733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul * DrawBuffer->_Xmin, _Xmax, _Ymin, _Ymax. This will accomplish 738733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul * window clipping and scissoring. 739733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul * Return: GL_TRUE some pixels still visible 74010f30eb43835c57c00783390a02d72daf4f78e26Brian Paul * GL_FALSE nothing visible 74110f30eb43835c57c00783390a02d72daf4f78e26Brian Paul */ 74210f30eb43835c57c00783390a02d72daf4f78e26Brian Paulstatic GLuint 743733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paulclip_span( GLcontext *ctx, struct sw_span *span ) 74410f30eb43835c57c00783390a02d72daf4f78e26Brian Paul{ 745733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul const GLint xmin = ctx->DrawBuffer->_Xmin; 746733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul const GLint xmax = ctx->DrawBuffer->_Xmax; 747733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul const GLint ymin = ctx->DrawBuffer->_Ymin; 748733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul const GLint ymax = ctx->DrawBuffer->_Ymax; 749733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul 750733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (span->arrayMask & SPAN_XY) { 751733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* arrays of x/y pixel coords */ 75277df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul const GLint *x = span->array->x; 75377df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul const GLint *y = span->array->y; 754733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul const GLint n = span->end; 75577df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul GLubyte *mask = span->array->mask; 756733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul GLint i; 757b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul if (span->arrayMask & SPAN_MASK) { 758b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul /* note: using & intead of && to reduce branches */ 759b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul for (i = 0; i < n; i++) { 760b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul mask[i] &= (x[i] >= xmin) & (x[i] < xmax) 761b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul & (y[i] >= ymin) & (y[i] < ymax); 762b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul } 763b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul } 764b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul else { 765b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul /* note: using & intead of && to reduce branches */ 766b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul for (i = 0; i < n; i++) { 767b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul mask[i] = (x[i] >= xmin) & (x[i] < xmax) 768b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul & (y[i] >= ymin) & (y[i] < ymax); 769b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul } 77010f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 771733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul return GL_TRUE; /* some pixels visible */ 77210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 773733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul else { 774733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* horizontal span of pixels */ 775733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul const GLint x = span->x; 776733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul const GLint y = span->y; 777733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul const GLint n = span->end; 778733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul 779733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* Trivial rejection tests */ 780733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (y < ymin || y >= ymax || x + n <= xmin || x >= xmax) { 781733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->end = 0; 782733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul return GL_FALSE; /* all pixels clipped */ 783733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul } 78410f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 785733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* Clip to the left */ 786733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (x < xmin) { 787733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul ASSERT(x + n > xmin); 788733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->writeAll = GL_FALSE; 7896ec6b845fdf3c44436028ad6fff9471d18928719Brian Paul _mesa_bzero(span->array->mask, (xmin - x) * sizeof(GLubyte)); 79010f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 791733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul 792733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* Clip to right */ 793733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (x + n > xmax) { 794733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul ASSERT(x < xmax); 795733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->end = xmax - x; 79610f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 79710f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 798733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul return GL_TRUE; /* some pixels visible */ 799733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul } 80010f30eb43835c57c00783390a02d72daf4f78e26Brian Paul} 80110f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 80210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 80379c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/** 804e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul * Apply all the per-fragment opertions to a span of color index fragments 805e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul * and write them to the enabled color drawbuffers. 806e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul * The 'span' parameter can be considered to be const. Note that 8077956292a765910077f50352d7cd0174e1e66d26cBrian Paul * span->interpMask and span->arrayMask may be changed but will be restored 8087956292a765910077f50352d7cd0174e1e66d26cBrian Paul * to their original values before returning. 80910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul */ 81010f30eb43835c57c00783390a02d72daf4f78e26Brian Paulvoid 81145bc887da226403f2c41077e40ca38b6f60f1359Brian Paul_swrast_write_index_span( GLcontext *ctx, struct sw_span *span) 81210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul{ 813e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul const SWcontext *swrast = SWRAST_CONTEXT(ctx); 814e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul const struct gl_framebuffer *fb = ctx->DrawBuffer; 815e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul const GLuint output = 0; 816e00ac11d4dd05c56584622dc2707bbdcfe4b2707Brian Paul const GLbitfield origInterpMask = span->interpMask; 817e00ac11d4dd05c56584622dc2707bbdcfe4b2707Brian Paul const GLbitfield origArrayMask = span->arrayMask; 818e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul GLuint buf; 81910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 820733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul ASSERT(span->end <= MAX_WIDTH); 821b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul ASSERT(span->primitive == GL_POINT || span->primitive == GL_LINE || 822b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul span->primitive == GL_POLYGON || span->primitive == GL_BITMAP); 823733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul ASSERT((span->interpMask | span->arrayMask) & SPAN_INDEX); 8247956292a765910077f50352d7cd0174e1e66d26cBrian Paul ASSERT((span->interpMask & span->arrayMask) == 0); 8257956292a765910077f50352d7cd0174e1e66d26cBrian Paul 826733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (span->arrayMask & SPAN_MASK) { 827733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* mask was initialized by caller, probably glBitmap */ 828733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->writeAll = GL_FALSE; 829733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul } 830733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul else { 831a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul _mesa_memset(span->array->mask, 1, span->end); 832733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->writeAll = GL_TRUE; 83310f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 83410f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 835733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* Clipping */ 836b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul if ((swrast->_RasterMask & CLIP_BIT) || (span->primitive != GL_POLYGON)) { 837733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (!clip_span(ctx, span)) { 83886ca15ece74ccb5a8f4d566a4b2c8024b178d73bBrian Paul return; 839e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 840e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 841e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 842e5b244ff7f984805c1bcc020342f1300f2639c71Brian Paul /* Depth bounds test */ 84331e739a18931fa48454f172818245b0927c8910fBrian Paul if (ctx->Depth.BoundsTest && ctx->DrawBuffer->Visual.depthBits > 0) { 844e5b244ff7f984805c1bcc020342f1300f2639c71Brian Paul if (!_swrast_depth_bounds_test(ctx, span)) { 845e5b244ff7f984805c1bcc020342f1300f2639c71Brian Paul return; 846e5b244ff7f984805c1bcc020342f1300f2639c71Brian Paul } 847e5b244ff7f984805c1bcc020342f1300f2639c71Brian Paul } 848e5b244ff7f984805c1bcc020342f1300f2639c71Brian Paul 849b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul#ifdef DEBUG 850a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul /* Make sure all fragments are within window bounds */ 851b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul if (span->arrayMask & SPAN_XY) { 852a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul GLuint i; 853b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul for (i = 0; i < span->end; i++) { 85477df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul if (span->array->mask[i]) { 85577df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul assert(span->array->x[i] >= ctx->DrawBuffer->_Xmin); 85677df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul assert(span->array->x[i] < ctx->DrawBuffer->_Xmax); 85777df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul assert(span->array->y[i] >= ctx->DrawBuffer->_Ymin); 85877df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul assert(span->array->y[i] < ctx->DrawBuffer->_Ymax); 859b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul } 860b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul } 861b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul } 862b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul#endif 863b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul 864e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* Polygon Stippling */ 865b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul if (ctx->Polygon.StippleFlag && span->primitive == GL_POLYGON) { 86610f30eb43835c57c00783390a02d72daf4f78e26Brian Paul stipple_polygon_span(ctx, span); 867e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 868e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 869e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul /* Stencil and Z testing */ 8707956292a765910077f50352d7cd0174e1e66d26cBrian Paul if (ctx->Depth.Test || ctx->Stencil.Enabled) { 8717956292a765910077f50352d7cd0174e1e66d26cBrian Paul if (span->interpMask & SPAN_Z) 87245bc887da226403f2c41077e40ca38b6f60f1359Brian Paul _swrast_span_interpolate_z(ctx, span); 87310f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 8747956292a765910077f50352d7cd0174e1e66d26cBrian Paul if (ctx->Stencil.Enabled) { 87545bc887da226403f2c41077e40ca38b6f60f1359Brian Paul if (!_swrast_stencil_and_ztest_span(ctx, span)) { 8767956292a765910077f50352d7cd0174e1e66d26cBrian Paul span->arrayMask = origArrayMask; 8777956292a765910077f50352d7cd0174e1e66d26cBrian Paul return; 8787956292a765910077f50352d7cd0174e1e66d26cBrian Paul } 8792a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 8807956292a765910077f50352d7cd0174e1e66d26cBrian Paul else { 8817956292a765910077f50352d7cd0174e1e66d26cBrian Paul ASSERT(ctx->Depth.Test); 88245bc887da226403f2c41077e40ca38b6f60f1359Brian Paul if (!_swrast_depth_test_span(ctx, span)) { 883e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul span->interpMask = origInterpMask; 8847956292a765910077f50352d7cd0174e1e66d26cBrian Paul span->arrayMask = origArrayMask; 8857956292a765910077f50352d7cd0174e1e66d26cBrian Paul return; 8867956292a765910077f50352d7cd0174e1e66d26cBrian Paul } 8872a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 88810f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 88910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 890b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul#if FEATURE_ARB_occlusion_query 89123ffc3a85d6172f8a98d17d7f23610bab808d84eBrian Paul if (ctx->Query.CurrentOcclusionObject) { 892939dd17653245621bf7488803f09418244b7b0b7Brian Paul /* update count of 'passed' fragments */ 89323ffc3a85d6172f8a98d17d7f23610bab808d84eBrian Paul struct gl_query_object *q = ctx->Query.CurrentOcclusionObject; 894b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul GLuint i; 895b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul for (i = 0; i < span->end; i++) 89623ffc3a85d6172f8a98d17d7f23610bab808d84eBrian Paul q->Result += span->array->mask[i]; 897b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul } 898b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul#endif 899b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul 9007956292a765910077f50352d7cd0174e1e66d26cBrian Paul /* we have to wait until after occlusion to do this test */ 9017956292a765910077f50352d7cd0174e1e66d26cBrian Paul if (ctx->Color.DrawBuffer == GL_NONE || ctx->Color.IndexMask == 0) { 90210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul /* write no pixels */ 9032a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->arrayMask = origArrayMask; 90410f30eb43835c57c00783390a02d72daf4f78e26Brian Paul return; 90510f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 90610f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 9077956292a765910077f50352d7cd0174e1e66d26cBrian Paul /* Interpolate the color indexes if needed */ 908dcf4c17fb1624af47181c63af4c3ad29f919c17aBrian Paul if (swrast->_FogEnabled || 909e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul ctx->Color.IndexLogicOpEnabled || 910e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul ctx->Color.IndexMask != 0xffffffff || 911e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul (span->arrayMask & SPAN_COVERAGE)) { 912e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul if (span->interpMask & SPAN_INDEX) { 913e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul interpolate_indexes(ctx, span); 914e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul } 9157956292a765910077f50352d7cd0174e1e66d26cBrian Paul } 91610f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 9177956292a765910077f50352d7cd0174e1e66d26cBrian Paul /* Fog */ 918dcf4c17fb1624af47181c63af4c3ad29f919c17aBrian Paul if (swrast->_FogEnabled) { 91945bc887da226403f2c41077e40ca38b6f60f1359Brian Paul _swrast_fog_ci_span(ctx, span); 920e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 921e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 9222a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul /* Antialias coverage application */ 9232a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul if (span->arrayMask & SPAN_COVERAGE) { 924e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul const GLfloat *coverage = span->array->coverage; 92577df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul GLuint *index = span->array->index; 926e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul GLuint i; 92710f30eb43835c57c00783390a02d72daf4f78e26Brian Paul for (i = 0; i < span->end; i++) { 92877df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul ASSERT(coverage[i] < 16); 92977df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul index[i] = (index[i] & ~0xf) | ((GLuint) coverage[i]); 9305071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paul } 9312a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 9325071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paul 933e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul /* Loop over drawing buffers */ 934e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul for (buf = 0; buf < fb->_NumColorDrawBuffers[output]; buf++) { 935e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul struct gl_renderbuffer *rb = fb->_ColorDrawBuffers[output][buf]; 936e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul GLuint indexTemp[MAX_WIDTH], *index32; 937e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul 938e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul ASSERT(rb->_BaseFormat == GL_COLOR_INDEX); 939e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul 940e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul if (ctx->Color.IndexLogicOpEnabled || 941e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul ctx->Color.IndexMask != 0xffffffff) { 942e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul /* make copy of incoming indexes */ 943e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul MEMCPY(indexTemp, span->array->index, span->end * sizeof(GLuint)); 9442a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 945e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul if (ctx->Color.IndexLogicOpEnabled) { 946e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul _swrast_logicop_ci_span(ctx, rb, span, indexTemp); 947e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul } 948e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul 949e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul if (ctx->Color.IndexMask != 0xffffffff) { 950e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul _swrast_mask_ci_span(ctx, rb, span, indexTemp); 951e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul } 952e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul index32 = indexTemp; 953e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul } 954e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul else { 955e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul index32 = span->array->index; 956e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 9572a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 958e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul if ((span->interpMask & SPAN_INDEX) && span->indexStep == 0) { 959e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul /* all fragments have same color index */ 960e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul GLubyte index8; 961e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul GLushort index16; 962e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul GLuint index32; 963e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul void *value; 964e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul 965e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul if (rb->DataType == GL_UNSIGNED_BYTE) { 966e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul index8 = FixedToInt(span->index); 967e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul value = &index8; 968e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul } 969e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul else if (rb->DataType == GL_UNSIGNED_SHORT) { 970e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul index16 = FixedToInt(span->index); 971e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul value = &index16; 972733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul } 973733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul else { 974e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul ASSERT(rb->DataType == GL_UNSIGNED_INT); 975e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul index32 = FixedToInt(span->index); 976e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul value = &index32; 977e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul } 978e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul 979e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul if (span->arrayMask & SPAN_XY) { 980e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul rb->PutMonoValues(ctx, rb, span->end, span->array->x, 981e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul span->array->y, value, span->array->mask); 982e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul } 983e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul else { 984e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul rb->PutMonoRow(ctx, rb, span->end, span->x, span->y, 985e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul value, span->array->mask); 986733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul } 9877956292a765910077f50352d7cd0174e1e66d26cBrian Paul } 9887956292a765910077f50352d7cd0174e1e66d26cBrian Paul else { 989e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul /* each fragment is a different color */ 990e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul GLubyte index8[MAX_WIDTH]; 991e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul GLushort index16[MAX_WIDTH]; 992e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul void *values; 993e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul 994e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul if (rb->DataType == GL_UNSIGNED_BYTE) { 995e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul GLuint k; 996e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul for (k = 0; k < span->end; k++) { 997e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul index8[k] = (GLubyte) index32[k]; 998e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul } 999e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul values = index8; 1000e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul } 1001e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul else if (rb->DataType == GL_UNSIGNED_SHORT) { 1002e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul GLuint k; 1003e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul for (k = 0; k < span->end; k++) { 1004e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul index16[k] = (GLushort) index32[k]; 1005e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul } 1006e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul values = index16; 1007733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul } 1008733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul else { 1009e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul ASSERT(rb->DataType == GL_UNSIGNED_INT); 1010e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul values = index32; 1011e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul } 1012e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul 1013e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul if (span->arrayMask & SPAN_XY) { 1014e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul rb->PutValues(ctx, rb, span->end, span->array->x, span->array->y, 1015e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul values, span->array->mask); 1016e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul } 1017e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul else { 1018e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul rb->PutRow(ctx, rb, span->end, span->x, span->y, 1019e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul values, span->array->mask); 1020733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul } 10217956292a765910077f50352d7cd0174e1e66d26cBrian Paul } 1022e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 10232a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 10247956292a765910077f50352d7cd0174e1e66d26cBrian Paul span->interpMask = origInterpMask; 10252a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->arrayMask = origArrayMask; 1026e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell} 1027e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 1028e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 102979c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/** 1030e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Add specular color to base color. This is used only when 1031f1e236987829393c81dc86ea19cb49eefe190317Brian Paul * GL_LIGHT_MODEL_COLOR_CONTROL = GL_SEPARATE_SPECULAR_COLOR. 1032e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */ 10335071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paulstatic void 1034f1e236987829393c81dc86ea19cb49eefe190317Brian Pauladd_colors(GLuint n, GLchan rgba[][4], GLchan specular[][4] ) 1035e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell{ 1036e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell GLuint i; 1037f1e236987829393c81dc86ea19cb49eefe190317Brian Paul for (i = 0; i < n; i++) { 10384fa5c1966a985f81c615a9f5ef2f64dd466b252aBrian Paul#if CHAN_TYPE == GL_FLOAT 10394fa5c1966a985f81c615a9f5ef2f64dd466b252aBrian Paul /* no clamping */ 1040f1e236987829393c81dc86ea19cb49eefe190317Brian Paul rgba[i][RCOMP] += specular[i][RCOMP]; 1041f1e236987829393c81dc86ea19cb49eefe190317Brian Paul rgba[i][GCOMP] += specular[i][GCOMP]; 1042f1e236987829393c81dc86ea19cb49eefe190317Brian Paul rgba[i][BCOMP] += specular[i][BCOMP]; 10434fa5c1966a985f81c615a9f5ef2f64dd466b252aBrian Paul#else 1044f1e236987829393c81dc86ea19cb49eefe190317Brian Paul GLint r = rgba[i][RCOMP] + specular[i][RCOMP]; 1045f1e236987829393c81dc86ea19cb49eefe190317Brian Paul GLint g = rgba[i][GCOMP] + specular[i][GCOMP]; 1046f1e236987829393c81dc86ea19cb49eefe190317Brian Paul GLint b = rgba[i][BCOMP] + specular[i][BCOMP]; 1047e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell rgba[i][RCOMP] = (GLchan) MIN2(r, CHAN_MAX); 1048e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell rgba[i][GCOMP] = (GLchan) MIN2(g, CHAN_MAX); 1049e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell rgba[i][BCOMP] = (GLchan) MIN2(b, CHAN_MAX); 10504fa5c1966a985f81c615a9f5ef2f64dd466b252aBrian Paul#endif 1051e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1052e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell} 1053e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 1054e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 105579c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/** 1056e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul * XXX merge this code into the _swrast_write_rgba_span() routine! 1057e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul * 1058e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul * Draw to more than one RGBA color buffer (or none). 1059e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul * All fragment operations, up to (but not) blending/logicop should 1060e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul * have been done first. 1061e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul */ 1062e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paulstatic void 1063e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paulmulti_write_rgba_span( GLcontext *ctx, struct sw_span *span ) 1064e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul{ 1065e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul const GLuint colorMask = *((GLuint *) ctx->Color.ColorMask); 1066e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul struct gl_framebuffer *fb = ctx->DrawBuffer; 1067e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul const GLuint output = 0; 1068e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul GLuint i; 1069e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul 1070e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul ASSERT(span->end < MAX_WIDTH); 1071e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul ASSERT(colorMask != 0x0); 1072e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul 1073e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul for (i = 0; i < fb->_NumColorDrawBuffers[output]; i++) { 1074e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul struct gl_renderbuffer *rb = fb->_ColorDrawBuffers[output][i]; 1075e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul GLchan rgbaTmp[MAX_WIDTH][4]; 1076e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul 1077e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul /* make copy of incoming colors */ 1078e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul MEMCPY( rgbaTmp, span->array->rgba, 4 * span->end * sizeof(GLchan) ); 1079e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul 1080e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul if (ctx->Color._LogicOpEnabled) { 1081e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul _swrast_logicop_rgba_span(ctx, rb, span, rgbaTmp); 1082e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul } 1083e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul else if (ctx->Color.BlendEnabled) { 1084e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul _swrast_blend_span(ctx, rb, span, rgbaTmp); 1085e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul } 1086e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul 1087e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul if (colorMask != 0xffffffff) { 1088e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul _swrast_mask_rgba_span(ctx, rb, span, rgbaTmp); 1089e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul } 1090e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul 1091e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul if (span->arrayMask & SPAN_XY) { 1092e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul /* array of pixel coords */ 1093bb8b302dbce4f830d060efecd8a9f75b10e25abbBrian Paul ASSERT(rb->PutValues); 1094bb8b302dbce4f830d060efecd8a9f75b10e25abbBrian Paul rb->PutValues(ctx, rb, span->end, span->array->x, 1095bb8b302dbce4f830d060efecd8a9f75b10e25abbBrian Paul span->array->y, rgbaTmp, span->array->mask); 1096e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul } 1097e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul else { 1098e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul /* horizontal run of pixels */ 1099bb8b302dbce4f830d060efecd8a9f75b10e25abbBrian Paul ASSERT(rb->PutRow); 1100bb8b302dbce4f830d060efecd8a9f75b10e25abbBrian Paul rb->PutRow(ctx, rb, span->end, span->x, span->y, rgbaTmp, 1101bb8b302dbce4f830d060efecd8a9f75b10e25abbBrian Paul span->array->mask); 1102e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul } 1103e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul } 1104e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul} 1105e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul 1106e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul 1107e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul/** 1108a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul * Apply all the per-fragment operations to a span. 1109a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul * This now includes texturing (_swrast_write_texture_span() is history). 1110f1e236987829393c81dc86ea19cb49eefe190317Brian Paul * This function may modify any of the array values in the span. 11117956292a765910077f50352d7cd0174e1e66d26cBrian Paul * span->interpMask and span->arrayMask may be changed but will be restored 11127956292a765910077f50352d7cd0174e1e66d26cBrian Paul * to their original values before returning. 111378940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul */ 111478940758e90069ceaca2b6cddb6438488fbad5ccBrian Paulvoid 1115a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul_swrast_write_rgba_span( GLcontext *ctx, struct sw_span *span) 111678940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul{ 111778940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul const GLuint colorMask = *((GLuint *) ctx->Color.ColorMask); 111878940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul SWcontext *swrast = SWRAST_CONTEXT(ctx); 1119e00ac11d4dd05c56584622dc2707bbdcfe4b2707Brian Paul const GLbitfield origInterpMask = span->interpMask; 1120e00ac11d4dd05c56584622dc2707bbdcfe4b2707Brian Paul const GLbitfield origArrayMask = span->arrayMask; 112132340aea1308153dad5c105fc0748aea1e4c37eeBrian Paul const GLboolean deferredTexture = !(ctx->Color.AlphaEnabled || 112232340aea1308153dad5c105fc0748aea1e4c37eeBrian Paul ctx->FragmentProgram._Active || 1123071357096e682e9af59ad45ea5abc444ab431837Michal Krol ctx->ShaderObjects._FragmentShaderPresent); 1124f1e236987829393c81dc86ea19cb49eefe190317Brian Paul 1125b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul ASSERT(span->primitive == GL_POINT || span->primitive == GL_LINE || 1126b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul span->primitive == GL_POLYGON || span->primitive == GL_BITMAP); 1127733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul ASSERT(span->end <= MAX_WIDTH); 11287956292a765910077f50352d7cd0174e1e66d26cBrian Paul ASSERT((span->interpMask & span->arrayMask) == 0); 112978940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul 1130ceb39f4f8dc4863fde17d668c752533a2184476eBrian Paul /* 1131a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul printf("%s() interp 0x%x array 0x%x\n", __FUNCTION__, 1132a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul span->interpMask, span->arrayMask); 1133ceb39f4f8dc4863fde17d668c752533a2184476eBrian Paul */ 1134ceb39f4f8dc4863fde17d668c752533a2184476eBrian Paul 1135733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (span->arrayMask & SPAN_MASK) { 1136733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* mask was initialized by caller, probably glBitmap */ 1137733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->writeAll = GL_FALSE; 1138733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul } 1139733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul else { 1140a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul _mesa_memset(span->array->mask, 1, span->end); 1141733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->writeAll = GL_TRUE; 114278940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul } 114378940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul 1144a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul /* Clip to window/scissor box */ 1145b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul if ((swrast->_RasterMask & CLIP_BIT) || (span->primitive != GL_POLYGON)) { 1146733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (!clip_span(ctx, span)) { 1147733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul return; 114878940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul } 114978940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul } 115078940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul 1151b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul#ifdef DEBUG 1152a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul /* Make sure all fragments are within window bounds */ 1153b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul if (span->arrayMask & SPAN_XY) { 1154a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul GLuint i; 1155b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul for (i = 0; i < span->end; i++) { 115677df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul if (span->array->mask[i]) { 115777df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul assert(span->array->x[i] >= ctx->DrawBuffer->_Xmin); 115877df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul assert(span->array->x[i] < ctx->DrawBuffer->_Xmax); 115977df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul assert(span->array->y[i] >= ctx->DrawBuffer->_Ymin); 116077df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul assert(span->array->y[i] < ctx->DrawBuffer->_Ymax); 1161b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul } 1162b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul } 1163b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul } 1164b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul#endif 1165b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul 116678940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul /* Polygon Stippling */ 1167b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul if (ctx->Polygon.StippleFlag && span->primitive == GL_POLYGON) { 1168733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul stipple_polygon_span(ctx, span); 116978940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul } 117078940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul 1171a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul /* Interpolate texcoords? */ 1172a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul if (ctx->Texture._EnabledCoordUnits 1173a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul && (span->interpMask & SPAN_TEXTURE) 1174a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul && (span->arrayMask & SPAN_TEXTURE) == 0) { 1175f1e236987829393c81dc86ea19cb49eefe190317Brian Paul interpolate_texcoords(ctx, span); 1176a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul } 117778940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul 1178bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol if (ctx->ShaderObjects._FragmentShaderPresent) { 1179bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol interpolate_varying(ctx, span); 1180bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol } 1181bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol 118232340aea1308153dad5c105fc0748aea1e4c37eeBrian Paul /* This is the normal place to compute the resulting fragment color/Z. 118332340aea1308153dad5c105fc0748aea1e4c37eeBrian Paul * As an optimization, we try to defer this until after Z/stencil 118432340aea1308153dad5c105fc0748aea1e4c37eeBrian Paul * testing in order to try to avoid computing colors that we won't 118532340aea1308153dad5c105fc0748aea1e4c37eeBrian Paul * actually need. 1186a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul */ 118732340aea1308153dad5c105fc0748aea1e4c37eeBrian Paul if (!deferredTexture) { 1188f1e236987829393c81dc86ea19cb49eefe190317Brian Paul /* Now we need the rgba array, fill it in if needed */ 1189f1e236987829393c81dc86ea19cb49eefe190317Brian Paul if ((span->interpMask & SPAN_RGBA) && (span->arrayMask & SPAN_RGBA) == 0) 1190f1e236987829393c81dc86ea19cb49eefe190317Brian Paul interpolate_colors(ctx, span); 1191f1e236987829393c81dc86ea19cb49eefe190317Brian Paul 1192a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul if (span->interpMask & SPAN_SPEC) 119336a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul interpolate_specular(ctx, span); 119436a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul 1195d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul if (span->interpMask & SPAN_FOG) 1196d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul interpolate_fog(ctx, span); 1197d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul 1198bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol /* Compute fragment colors with fragment program or texture lookups */ 1199bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol if (ctx->ShaderObjects._FragmentShaderPresent) { 1200bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol if (span->interpMask & SPAN_Z) 1201bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol _swrast_span_interpolate_z (ctx, span); 1202bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol _swrast_exec_arbshader (ctx, span); 1203a66393120411071b3f3ccce8583ab961a2935959Michal Krol } 1204a66393120411071b3f3ccce8583ab961a2935959Michal Krol else if (ctx->FragmentProgram._Active) { 120532340aea1308153dad5c105fc0748aea1e4c37eeBrian Paul /* frag prog may need Z values */ 120632340aea1308153dad5c105fc0748aea1e4c37eeBrian Paul if (span->interpMask & SPAN_Z) 120732340aea1308153dad5c105fc0748aea1e4c37eeBrian Paul _swrast_span_interpolate_z(ctx, span); 1208e22540c2765e034fed558ea1d44488a03fbba170Brian Paul _swrast_exec_fragment_program( ctx, span ); 120932340aea1308153dad5c105fc0748aea1e4c37eeBrian Paul } 12107f752fed993e5e9423abac200dd59141edbada56Dave Airlie else if (ctx->ATIFragmentShader._Enabled) 12117f752fed993e5e9423abac200dd59141edbada56Dave Airlie _swrast_exec_fragment_shader( ctx, span ); 1212252d8e78cc07880239b085b713e2d37ddbba86f9Brian Paul else if (ctx->Texture._EnabledUnits && (span->arrayMask & SPAN_TEXTURE)) 1213610d59981a9f43fefe29b34ef19c184d28e2bef5Brian Paul _swrast_texture_span( ctx, span ); 121478940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul 121578940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul /* Do the alpha test */ 12165e01f9a11489079d8509927774d8239c1857224aRoland Scheidegger if (ctx->Color.AlphaEnabled) { 12175e01f9a11489079d8509927774d8239c1857224aRoland Scheidegger if (!_swrast_alpha_test(ctx, span)) { 12185e01f9a11489079d8509927774d8239c1857224aRoland Scheidegger span->arrayMask = origArrayMask; 12195e01f9a11489079d8509927774d8239c1857224aRoland Scheidegger return; 12205e01f9a11489079d8509927774d8239c1857224aRoland Scheidegger } 122178940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul } 122278940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul } 122378940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul 1224f1e236987829393c81dc86ea19cb49eefe190317Brian Paul /* Stencil and Z testing */ 1225f1e236987829393c81dc86ea19cb49eefe190317Brian Paul if (ctx->Stencil.Enabled || ctx->Depth.Test) { 1226f1e236987829393c81dc86ea19cb49eefe190317Brian Paul if (span->interpMask & SPAN_Z) 122745bc887da226403f2c41077e40ca38b6f60f1359Brian Paul _swrast_span_interpolate_z(ctx, span); 122878940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul 1229e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul if (ctx->Stencil.Enabled && ctx->DrawBuffer->Visual.stencilBits > 0) { 1230a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul /* Combined Z/stencil tests */ 123145bc887da226403f2c41077e40ca38b6f60f1359Brian Paul if (!_swrast_stencil_and_ztest_span(ctx, span)) { 1232e5b244ff7f984805c1bcc020342f1300f2639c71Brian Paul span->interpMask = origInterpMask; 1233f1e236987829393c81dc86ea19cb49eefe190317Brian Paul span->arrayMask = origArrayMask; 123410f30eb43835c57c00783390a02d72daf4f78e26Brian Paul return; 1235f1e236987829393c81dc86ea19cb49eefe190317Brian Paul } 123671340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 1237e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul else if (ctx->DrawBuffer->Visual.depthBits > 0) { 1238a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul /* Just regular depth testing */ 1239f1e236987829393c81dc86ea19cb49eefe190317Brian Paul ASSERT(ctx->Depth.Test); 1240f1e236987829393c81dc86ea19cb49eefe190317Brian Paul ASSERT(span->arrayMask & SPAN_Z); 124145bc887da226403f2c41077e40ca38b6f60f1359Brian Paul if (!_swrast_depth_test_span(ctx, span)) { 1242e5b244ff7f984805c1bcc020342f1300f2639c71Brian Paul span->interpMask = origInterpMask; 1243f1e236987829393c81dc86ea19cb49eefe190317Brian Paul span->arrayMask = origArrayMask; 124410f30eb43835c57c00783390a02d72daf4f78e26Brian Paul return; 1245f1e236987829393c81dc86ea19cb49eefe190317Brian Paul } 124671340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 124771340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 124871340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul 1249b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul#if FEATURE_ARB_occlusion_query 125023ffc3a85d6172f8a98d17d7f23610bab808d84eBrian Paul if (ctx->Query.CurrentOcclusionObject) { 1251939dd17653245621bf7488803f09418244b7b0b7Brian Paul /* update count of 'passed' fragments */ 125223ffc3a85d6172f8a98d17d7f23610bab808d84eBrian Paul struct gl_query_object *q = ctx->Query.CurrentOcclusionObject; 1253b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul GLuint i; 1254b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul for (i = 0; i < span->end; i++) 125523ffc3a85d6172f8a98d17d7f23610bab808d84eBrian Paul q->Result += span->array->mask[i]; 1256b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul } 1257b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul#endif 1258b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul 1259a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul /* We had to wait until now to check for glColorMask(0,0,0,0) because of 1260f1e236987829393c81dc86ea19cb49eefe190317Brian Paul * the occlusion test. 1261f1e236987829393c81dc86ea19cb49eefe190317Brian Paul */ 1262f1e236987829393c81dc86ea19cb49eefe190317Brian Paul if (colorMask == 0x0) { 1263e5b244ff7f984805c1bcc020342f1300f2639c71Brian Paul span->interpMask = origInterpMask; 1264f1e236987829393c81dc86ea19cb49eefe190317Brian Paul span->arrayMask = origArrayMask; 1265f1e236987829393c81dc86ea19cb49eefe190317Brian Paul return; 126671340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 126771340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul 126832340aea1308153dad5c105fc0748aea1e4c37eeBrian Paul /* If we were able to defer fragment color computation to now, there's 126932340aea1308153dad5c105fc0748aea1e4c37eeBrian Paul * a good chance that many fragments will have already been killed by 127032340aea1308153dad5c105fc0748aea1e4c37eeBrian Paul * Z/stencil testing. 1271a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul */ 127232340aea1308153dad5c105fc0748aea1e4c37eeBrian Paul if (deferredTexture) { 1273f1e236987829393c81dc86ea19cb49eefe190317Brian Paul /* Now we need the rgba array, fill it in if needed */ 1274f1e236987829393c81dc86ea19cb49eefe190317Brian Paul if ((span->interpMask & SPAN_RGBA) && (span->arrayMask & SPAN_RGBA) == 0) 1275f1e236987829393c81dc86ea19cb49eefe190317Brian Paul interpolate_colors(ctx, span); 127671340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul 1277a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul if (span->interpMask & SPAN_SPEC) 127836a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul interpolate_specular(ctx, span); 127936a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul 1280d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul if (span->interpMask & SPAN_FOG) 1281d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul interpolate_fog(ctx, span); 1282d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul 1283bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol if (ctx->ShaderObjects._FragmentShaderPresent) { 1284bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol if (span->interpMask & SPAN_Z) 1285bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol _swrast_span_interpolate_z (ctx, span); 1286bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol _swrast_exec_arbshader (ctx, span); 1287bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol } 1288a66393120411071b3f3ccce8583ab961a2935959Michal Krol else if (ctx->FragmentProgram._Active) 1289e22540c2765e034fed558ea1d44488a03fbba170Brian Paul _swrast_exec_fragment_program( ctx, span ); 12907f752fed993e5e9423abac200dd59141edbada56Dave Airlie else if (ctx->ATIFragmentShader._Enabled) 12917f752fed993e5e9423abac200dd59141edbada56Dave Airlie _swrast_exec_fragment_shader( ctx, span ); 1292252d8e78cc07880239b085b713e2d37ddbba86f9Brian Paul else if (ctx->Texture._EnabledUnits && (span->arrayMask & SPAN_TEXTURE)) 1293610d59981a9f43fefe29b34ef19c184d28e2bef5Brian Paul _swrast_texture_span( ctx, span ); 129471340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 129571340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul 1296f1e236987829393c81dc86ea19cb49eefe190317Brian Paul ASSERT(span->arrayMask & SPAN_RGBA); 12972ef866d1fc0a5cc5ef8543d65744dfd4da4dbbafBrian Paul 12989d148e6b2be33fe7ac72aaa3be239dc1bc8878a9Keith Whitwell if (!ctx->FragmentProgram._Enabled) { 1299dfe508ca7af1a6d1099cd65e257512ed1e17d893Brian Paul /* Add base and specular colors */ 1300dfe508ca7af1a6d1099cd65e257512ed1e17d893Brian Paul if (ctx->Fog.ColorSumEnabled || 1301dfe508ca7af1a6d1099cd65e257512ed1e17d893Brian Paul (ctx->Light.Enabled && 1302dfe508ca7af1a6d1099cd65e257512ed1e17d893Brian Paul ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR)) { 1303dfe508ca7af1a6d1099cd65e257512ed1e17d893Brian Paul if (span->interpMask & SPAN_SPEC) { 1304dfe508ca7af1a6d1099cd65e257512ed1e17d893Brian Paul interpolate_specular(ctx, span); 1305dfe508ca7af1a6d1099cd65e257512ed1e17d893Brian Paul } 1306a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul if (span->arrayMask & SPAN_SPEC) { 1307a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul add_colors( span->end, span->array->rgba, span->array->spec ); 1308a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul } 1309a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul else { 1310a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul /* We probably added the base/specular colors during the 1311a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul * vertex stage! 1312a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul */ 1313a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul } 131471340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 131571340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 131671340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul 13176e1666437ea091ecc50ab2b56d87129318f641d2Brian Paul /* Fog */ 131809da0b8e6621a831e3eeb9381430f2bed18a22adBrian Paul if (swrast->_FogEnabled) { 131945bc887da226403f2c41077e40ca38b6f60f1359Brian Paul _swrast_fog_rgba_span(ctx, span); 132071340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 1321f1e236987829393c81dc86ea19cb49eefe190317Brian Paul 132271340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul /* Antialias coverage application */ 13232a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul if (span->arrayMask & SPAN_COVERAGE) { 132477df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul GLchan (*rgba)[4] = span->array->rgba; 132577df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul GLfloat *coverage = span->array->coverage; 132671340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul GLuint i; 132710f30eb43835c57c00783390a02d72daf4f78e26Brian Paul for (i = 0; i < span->end; i++) { 132877df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul rgba[i][ACOMP] = (GLchan) (rgba[i][ACOMP] * coverage[i]); 132971340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 133071340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 133171340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul 1332ba3da6154c324cc916845bc5de3de077d0b59ffcBrian Paul /* Clamp color/alpha values over the range [0.0, 1.0] before storage */ 1333ba3da6154c324cc916845bc5de3de077d0b59ffcBrian Paul#if CHAN_TYPE == GL_FLOAT 1334ba3da6154c324cc916845bc5de3de077d0b59ffcBrian Paul if (ctx->Color.ClampFragmentColor) { 1335ba3da6154c324cc916845bc5de3de077d0b59ffcBrian Paul GLchan (*rgba)[4] = span->array->rgba; 1336ba3da6154c324cc916845bc5de3de077d0b59ffcBrian Paul GLuint i; 1337ba3da6154c324cc916845bc5de3de077d0b59ffcBrian Paul for (i = 0; i < span->end; i++) { 1338ba3da6154c324cc916845bc5de3de077d0b59ffcBrian Paul rgba[i][RCOMP] = CLAMP(rgba[i][RCOMP], 0.0, CHAN_MAXF); 1339ba3da6154c324cc916845bc5de3de077d0b59ffcBrian Paul rgba[i][GCOMP] = CLAMP(rgba[i][GCOMP], 0.0, CHAN_MAXF); 1340ba3da6154c324cc916845bc5de3de077d0b59ffcBrian Paul rgba[i][BCOMP] = CLAMP(rgba[i][BCOMP], 0.0, CHAN_MAXF); 1341ba3da6154c324cc916845bc5de3de077d0b59ffcBrian Paul rgba[i][ACOMP] = CLAMP(rgba[i][ACOMP], 0.0, CHAN_MAXF); 1342ba3da6154c324cc916845bc5de3de077d0b59ffcBrian Paul } 1343ba3da6154c324cc916845bc5de3de077d0b59ffcBrian Paul } 1344ba3da6154c324cc916845bc5de3de077d0b59ffcBrian Paul#endif 1345ba3da6154c324cc916845bc5de3de077d0b59ffcBrian Paul 134671340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul if (swrast->_RasterMask & MULTI_DRAW_BIT) { 1347a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul /* need to do blend/logicop separately for each color buffer */ 1348733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul multi_write_rgba_span(ctx, span); 134971340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 135071340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul else { 135171340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul /* normal: write to exactly one buffer */ 1352e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0][0]; 1353e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul 135457857ca0925116d6d254fef7e705cfe0b650d77fBrian Paul if (ctx->Color._LogicOpEnabled) { 1355e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul _swrast_logicop_rgba_span(ctx, rb, span, span->array->rgba); 135671340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 135795e2c72fd52d87163eb543555345f115f050f3aaBrian Paul else if (ctx->Color.BlendEnabled) { 1358e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul _swrast_blend_span(ctx, rb, span, span->array->rgba); 135971340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 136071340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul 1361e5b244ff7f984805c1bcc020342f1300f2639c71Brian Paul /* Color component masking */ 1362f1e236987829393c81dc86ea19cb49eefe190317Brian Paul if (colorMask != 0xffffffff) { 1363e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul _swrast_mask_rgba_span(ctx, rb, span, span->array->rgba); 136471340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 136571340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul 1366a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul /* Finally, write the pixels to a color buffer */ 1367733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (span->arrayMask & SPAN_XY) { 1368733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* array of pixel coords */ 1369bb8b302dbce4f830d060efecd8a9f75b10e25abbBrian Paul ASSERT(rb->PutValues); 1370bb8b302dbce4f830d060efecd8a9f75b10e25abbBrian Paul ASSERT(rb->_BaseFormat == GL_RGB || rb->_BaseFormat == GL_RGBA); 1371bb8b302dbce4f830d060efecd8a9f75b10e25abbBrian Paul /* XXX check datatype */ 1372bb8b302dbce4f830d060efecd8a9f75b10e25abbBrian Paul rb->PutValues(ctx, rb, span->end, span->array->x, span->array->y, 1373bb8b302dbce4f830d060efecd8a9f75b10e25abbBrian Paul span->array->rgba, span->array->mask); 1374733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul } 1375733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul else { 1376733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* horizontal run of pixels */ 1377bb8b302dbce4f830d060efecd8a9f75b10e25abbBrian Paul ASSERT(rb->PutRow); 1378bb8b302dbce4f830d060efecd8a9f75b10e25abbBrian Paul ASSERT(rb->_BaseFormat == GL_RGB || rb->_BaseFormat == GL_RGBA); 1379bb8b302dbce4f830d060efecd8a9f75b10e25abbBrian Paul /* XXX check datatype */ 1380bb8b302dbce4f830d060efecd8a9f75b10e25abbBrian Paul rb->PutRow(ctx, rb, span->end, span->x, span->y, span->array->rgba, 1381bb8b302dbce4f830d060efecd8a9f75b10e25abbBrian Paul span->writeAll ? NULL : span->array->mask); 138271340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 138371340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 138471340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul 1385e5b244ff7f984805c1bcc020342f1300f2639c71Brian Paul span->interpMask = origInterpMask; 1386f1e236987829393c81dc86ea19cb49eefe190317Brian Paul span->arrayMask = origArrayMask; 138710f30eb43835c57c00783390a02d72daf4f78e26Brian Paul} 138810f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 1389e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 1390e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 139179c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/** 1392e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Read RGBA pixels from frame buffer. Clipping will be done to prevent 1393e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * reading ouside the buffer's boundaries. 1394e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */ 13955071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paulvoid 1396e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul_swrast_read_rgba_span( GLcontext *ctx, struct gl_renderbuffer *rb, 1397a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul GLuint n, GLint x, GLint y, GLchan rgba[][4] ) 1398e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell{ 1399e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul const GLint bufWidth = (GLint) rb->Width; 1400e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul const GLint bufHeight = (GLint) rb->Height; 1401a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul 1402a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul if (y < 0 || y >= bufHeight || x + (GLint) n < 0 || x >= bufWidth) { 1403e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* completely above, below, or right */ 1404e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul /* XXX maybe leave rgba values undefined? */ 14056ec6b845fdf3c44436028ad6fff9471d18928719Brian Paul _mesa_bzero(rgba, 4 * n * sizeof(GLchan)); 1406e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1407e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell else { 1408e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell GLint skip, length; 1409e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell if (x < 0) { 14107e152b83cbc3af028175a52450c60101cb16acf8Brian Paul /* left edge clipping */ 1411e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell skip = -x; 1412e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell length = (GLint) n - skip; 1413e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell if (length < 0) { 1414e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* completely left of window */ 1415e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell return; 1416e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1417a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul if (length > bufWidth) { 1418a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul length = bufWidth; 1419e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1420e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1421a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul else if ((GLint) (x + n) > bufWidth) { 1422e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* right edge clipping */ 1423e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell skip = 0; 1424a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul length = bufWidth - x; 1425e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell if (length < 0) { 1426e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* completely to right of window */ 1427e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell return; 1428e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1429e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1430e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell else { 1431e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* no clipping */ 1432e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell skip = 0; 1433e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell length = (GLint) n; 1434e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1435e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 1436bb8b302dbce4f830d060efecd8a9f75b10e25abbBrian Paul ASSERT(rb); 1437bb8b302dbce4f830d060efecd8a9f75b10e25abbBrian Paul ASSERT(rb->GetRow); 1438bb8b302dbce4f830d060efecd8a9f75b10e25abbBrian Paul ASSERT(rb->_BaseFormat == GL_RGB || rb->_BaseFormat == GL_RGBA); 1439bb8b302dbce4f830d060efecd8a9f75b10e25abbBrian Paul ASSERT(rb->DataType == GL_UNSIGNED_BYTE); 1440bb8b302dbce4f830d060efecd8a9f75b10e25abbBrian Paul rb->GetRow(ctx, rb, length, x + skip, y, rgba + skip); 1441e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1442e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell} 1443e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 1444e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 144579c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/** 1446e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Read CI pixels from frame buffer. Clipping will be done to prevent 1447e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * reading ouside the buffer's boundaries. 1448e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */ 14495071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paulvoid 1450e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul_swrast_read_index_span( GLcontext *ctx, struct gl_renderbuffer *rb, 1451e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul GLuint n, GLint x, GLint y, GLuint index[] ) 1452e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell{ 1453e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul const GLint bufWidth = (GLint) rb->Width; 1454e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul const GLint bufHeight = (GLint) rb->Height; 1455a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul 1456a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul if (y < 0 || y >= bufHeight || x + (GLint) n < 0 || x >= bufWidth) { 1457e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* completely above, below, or right */ 1458e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul _mesa_bzero(index, n * sizeof(GLuint)); 1459e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1460e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell else { 1461e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell GLint skip, length; 1462e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell if (x < 0) { 14637e152b83cbc3af028175a52450c60101cb16acf8Brian Paul /* left edge clipping */ 1464e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell skip = -x; 1465e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell length = (GLint) n - skip; 1466e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell if (length < 0) { 1467e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* completely left of window */ 1468e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell return; 1469e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1470a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul if (length > bufWidth) { 1471a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul length = bufWidth; 1472e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1473e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1474a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul else if ((GLint) (x + n) > bufWidth) { 1475e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* right edge clipping */ 1476e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell skip = 0; 1477a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul length = bufWidth - x; 1478e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell if (length < 0) { 1479e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* completely to right of window */ 1480e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell return; 1481e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1482e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1483e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell else { 1484e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* no clipping */ 1485e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell skip = 0; 1486e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell length = (GLint) n; 1487e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1488e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 1489e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul ASSERT(rb->GetRow); 1490e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul ASSERT(rb->_BaseFormat == GL_COLOR_INDEX); 1491e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul 1492e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul if (rb->DataType == GL_UNSIGNED_BYTE) { 1493e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul GLubyte index8[MAX_WIDTH]; 1494e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul GLint i; 1495e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul rb->GetRow(ctx, rb, length, x + skip, y, index8); 1496e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul for (i = 0; i < length; i++) 1497e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul index[skip + i] = index8[i]; 1498e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul } 1499e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul else if (rb->DataType == GL_UNSIGNED_SHORT) { 1500e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul GLushort index16[MAX_WIDTH]; 1501e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul GLint i; 1502e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul rb->GetRow(ctx, rb, length, x + skip, y, index16); 1503e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul for (i = 0; i < length; i++) 1504e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul index[skip + i] = index16[i]; 1505e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul } 1506e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul else if (rb->DataType == GL_UNSIGNED_INT) { 1507e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul rb->GetRow(ctx, rb, length, x + skip, y, index + skip); 1508e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul } 1509e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1510e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell} 151167074332728acba86da7630353673b458713bb8aBrian Paul 151267074332728acba86da7630353673b458713bb8aBrian Paul 151367074332728acba86da7630353673b458713bb8aBrian Paul/** 151467074332728acba86da7630353673b458713bb8aBrian Paul * Wrapper for gl_renderbuffer::GetValues() which does clipping to avoid 151567074332728acba86da7630353673b458713bb8aBrian Paul * reading values outside the buffer bounds. 151667074332728acba86da7630353673b458713bb8aBrian Paul * We can use this for reading any format/type of renderbuffer. 151767074332728acba86da7630353673b458713bb8aBrian Paul * \param valueSize is the size in bytes of each value put into the 151867074332728acba86da7630353673b458713bb8aBrian Paul * values array. 151967074332728acba86da7630353673b458713bb8aBrian Paul */ 152067074332728acba86da7630353673b458713bb8aBrian Paulvoid 152167074332728acba86da7630353673b458713bb8aBrian Paul_swrast_get_values(GLcontext *ctx, struct gl_renderbuffer *rb, 152267074332728acba86da7630353673b458713bb8aBrian Paul GLuint count, const GLint x[], const GLint y[], 152367074332728acba86da7630353673b458713bb8aBrian Paul void *values, GLuint valueSize) 152467074332728acba86da7630353673b458713bb8aBrian Paul{ 152567074332728acba86da7630353673b458713bb8aBrian Paul GLuint i, inCount = 0, inStart = 0; 152667074332728acba86da7630353673b458713bb8aBrian Paul 152767074332728acba86da7630353673b458713bb8aBrian Paul for (i = 0; i < count; i++) { 152867074332728acba86da7630353673b458713bb8aBrian Paul if (x[i] >= 0 && y[i] >= 0 && x[i] < rb->Width && y[i] < rb->Height) { 152967074332728acba86da7630353673b458713bb8aBrian Paul /* inside */ 153067074332728acba86da7630353673b458713bb8aBrian Paul if (inCount == 0) 153167074332728acba86da7630353673b458713bb8aBrian Paul inStart = i; 153267074332728acba86da7630353673b458713bb8aBrian Paul inCount++; 153367074332728acba86da7630353673b458713bb8aBrian Paul } 153467074332728acba86da7630353673b458713bb8aBrian Paul else { 153567074332728acba86da7630353673b458713bb8aBrian Paul if (inCount > 0) { 153667074332728acba86da7630353673b458713bb8aBrian Paul /* read [inStart, inStart + inCount) */ 153767074332728acba86da7630353673b458713bb8aBrian Paul rb->GetValues(ctx, rb, inCount, x + inStart, y + inStart, 153867074332728acba86da7630353673b458713bb8aBrian Paul (GLubyte *) values + inStart * valueSize); 153967074332728acba86da7630353673b458713bb8aBrian Paul inCount = 0; 154067074332728acba86da7630353673b458713bb8aBrian Paul } 154167074332728acba86da7630353673b458713bb8aBrian Paul } 154267074332728acba86da7630353673b458713bb8aBrian Paul } 154367074332728acba86da7630353673b458713bb8aBrian Paul if (inCount > 0) { 154467074332728acba86da7630353673b458713bb8aBrian Paul /* read last values */ 154567074332728acba86da7630353673b458713bb8aBrian Paul rb->GetValues(ctx, rb, inCount, x + inStart, y + inStart, 154667074332728acba86da7630353673b458713bb8aBrian Paul (GLubyte *) values + inStart * valueSize); 154767074332728acba86da7630353673b458713bb8aBrian Paul } 154867074332728acba86da7630353673b458713bb8aBrian Paul} 15493fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul 15503fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul 15513fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul/** 15523fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul * Wrapper for gl_renderbuffer::PutRow() which does clipping. 15533fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul */ 15543fd819aef8139761ce86cb8d763de83a11c81b33Brian Paulvoid 15553fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul_swrast_put_row(GLcontext *ctx, struct gl_renderbuffer *rb, 15563fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul GLuint count, GLint x, GLint y, 15573fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul const GLvoid *values, GLuint valueSize) 15583fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul{ 15593fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul GLint skip = 0; 15603fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul 15613fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul if (y < 0 || y >= rb->Height) 15623fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul return; /* above or below */ 15633fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul 15643fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul if (x + (GLint) count <= 0 || x >= rb->Width) 15653fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul return; /* entirely left or right */ 15663fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul 15673fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul if (x + count > rb->Width) { 15683fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul /* right clip */ 15693fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul GLint clip = x + count - rb->Width; 15703fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul count -= clip; 15713fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul } 15723fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul 15733fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul if (x < 0) { 15743fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul /* left clip */ 15753fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul skip = -x; 15763fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul x = 0; 15773fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul count -= skip; 15783fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul } 15793fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul 15803fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul rb->PutRow(ctx, rb, count, x, y, 15813fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul (const GLubyte *) values + skip * valueSize, NULL); 15823fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul} 1583f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul 1584f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul 1585f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul/** 1586f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul * Wrapper for gl_renderbuffer::GetRow() which does clipping. 1587f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul */ 1588f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paulvoid 1589f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul_swrast_get_row(GLcontext *ctx, struct gl_renderbuffer *rb, 1590f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul GLuint count, GLint x, GLint y, 1591f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul GLvoid *values, GLuint valueSize) 1592f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul{ 1593f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul GLint skip = 0; 1594f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul 1595f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul if (y < 0 || y >= rb->Height) 1596f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul return; /* above or below */ 1597f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul 1598f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul if (x + (GLint) count <= 0 || x >= rb->Width) 1599f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul return; /* entirely left or right */ 1600f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul 1601f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul if (x + count > rb->Width) { 1602f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul /* right clip */ 1603f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul GLint clip = x + count - rb->Width; 1604f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul count -= clip; 1605f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul } 1606f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul 1607f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul if (x < 0) { 1608f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul /* left clip */ 1609f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul skip = -x; 1610f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul x = 0; 1611f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul count -= skip; 1612f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul } 1613f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul 1614f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul rb->GetRow(ctx, rb, count, x, y, (GLubyte *) values + skip * valueSize); 1615f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul} 1616