s_span.c revision bb8b302dbce4f830d060efecd8a9f75b10e25abb
1e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell/* 2e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Mesa 3-D graphics library 3dfe508ca7af1a6d1099cd65e257512ed1e17d893Brian Paul * Version: 6.3 422144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes * 5e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul * Copyright (C) 1999-2005 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" 40e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_alpha.h" 41e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_blend.h" 42cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell#include "s_context.h" 43e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_depth.h" 44e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_fog.h" 45e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_logic.h" 46e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_masking.h" 47610d59981a9f43fefe29b34ef19c184d28e2bef5Brian Paul#include "s_nvfragprog.h" 48e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_span.h" 49e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_stencil.h" 50e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_texture.h" 51e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 522a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 5379c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/** 542a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul * Init span's Z interpolation values to the RasterPos Z. 552a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul * Used during setup for glDraw/CopyPixels. 562a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul */ 572a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paulvoid 5845bc887da226403f2c41077e40ca38b6f60f1359Brian Paul_swrast_span_default_z( GLcontext *ctx, struct sw_span *span ) 592a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul{ 60e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul const GLfloat depthMax = ctx->DrawBuffer->_DepthMaxF; 612a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul if (ctx->Visual.depthBits <= 16) 62e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul span->z = FloatToFixed(ctx->Current.RasterPos[2] * depthMax + 0.5F); 632a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul else 64e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul span->z = (GLint) (ctx->Current.RasterPos[2] * depthMax + 0.5F); 652a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->zStep = 0; 662a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->interpMask |= SPAN_Z; 672a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul} 682a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 692a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 7079c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/** 712a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul * Init span's fog interpolation values to the RasterPos fog. 722a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul * Used during setup for glDraw/CopyPixels. 732a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul */ 742a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paulvoid 7545bc887da226403f2c41077e40ca38b6f60f1359Brian Paul_swrast_span_default_fog( GLcontext *ctx, struct sw_span *span ) 762a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul{ 7745bc887da226403f2c41077e40ca38b6f60f1359Brian Paul span->fog = _swrast_z_to_fogfactor(ctx, ctx->Current.RasterDistance); 7854e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul span->fogStep = span->dfogdx = span->dfogdy = 0.0F; 792a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->interpMask |= SPAN_FOG; 802a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul} 812a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 822a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 8379c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/** 84a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul * Init span's rgba or index interpolation values to the RasterPos color. 852a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul * Used during setup for glDraw/CopyPixels. 862a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul */ 872a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paulvoid 8845bc887da226403f2c41077e40ca38b6f60f1359Brian Paul_swrast_span_default_color( GLcontext *ctx, struct sw_span *span ) 892a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul{ 902a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul if (ctx->Visual.rgbMode) { 912a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLchan r, g, b, a; 922a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul UNCLAMPED_FLOAT_TO_CHAN(r, ctx->Current.RasterColor[0]); 932a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul UNCLAMPED_FLOAT_TO_CHAN(g, ctx->Current.RasterColor[1]); 942a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul UNCLAMPED_FLOAT_TO_CHAN(b, ctx->Current.RasterColor[2]); 952a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul UNCLAMPED_FLOAT_TO_CHAN(a, ctx->Current.RasterColor[3]); 962a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul#if CHAN_TYPE == GL_FLOAT 972a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->red = r; 982a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->green = g; 992a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->blue = b; 1002a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->alpha = a; 1012a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul#else 1022a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->red = IntToFixed(r); 1032a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->green = IntToFixed(g); 1042a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->blue = IntToFixed(b); 1052a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->alpha = IntToFixed(a); 1062a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul#endif 1072a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->redStep = 0; 1082a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->greenStep = 0; 1092a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->blueStep = 0; 1102a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->alphaStep = 0; 1112a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->interpMask |= SPAN_RGBA; 1122a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 1132a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul else { 1140f3cd3f894612d156de454178effa4c732f96da7Brian Paul span->index = FloatToFixed(ctx->Current.RasterIndex); 1152a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->indexStep = 0; 1162a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->interpMask |= SPAN_INDEX; 1172a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 1182a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul} 1192a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 1202a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 1214753d60dd070bb08d0116076bcc08025c86ce857Brian Paul/** 1224753d60dd070bb08d0116076bcc08025c86ce857Brian Paul * Init span's texcoord interpolation values to the RasterPos texcoords. 1234753d60dd070bb08d0116076bcc08025c86ce857Brian Paul * Used during setup for glDraw/CopyPixels. 1244753d60dd070bb08d0116076bcc08025c86ce857Brian Paul */ 1254753d60dd070bb08d0116076bcc08025c86ce857Brian Paulvoid 12645bc887da226403f2c41077e40ca38b6f60f1359Brian Paul_swrast_span_default_texcoords( GLcontext *ctx, struct sw_span *span ) 1274753d60dd070bb08d0116076bcc08025c86ce857Brian Paul{ 1284753d60dd070bb08d0116076bcc08025c86ce857Brian Paul GLuint i; 1294753d60dd070bb08d0116076bcc08025c86ce857Brian Paul for (i = 0; i < ctx->Const.MaxTextureUnits; i++) { 130e63cb85cbc13c083f5d9f4640bb81ba9417a4f28Brian Paul const GLfloat *tc = ctx->Current.RasterTexCoords[i]; 13147b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell if (ctx->FragmentProgram._Active || ctx->ATIFragmentShader._Enabled) { 132a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul COPY_4V(span->tex[i], tc); 133a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul } 134a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul else if (tc[3] > 0.0F) { 135e63cb85cbc13c083f5d9f4640bb81ba9417a4f28Brian Paul /* use (s/q, t/q, r/q, 1) */ 136e63cb85cbc13c083f5d9f4640bb81ba9417a4f28Brian Paul span->tex[i][0] = tc[0] / tc[3]; 137e63cb85cbc13c083f5d9f4640bb81ba9417a4f28Brian Paul span->tex[i][1] = tc[1] / tc[3]; 138e63cb85cbc13c083f5d9f4640bb81ba9417a4f28Brian Paul span->tex[i][2] = tc[2] / tc[3]; 139e63cb85cbc13c083f5d9f4640bb81ba9417a4f28Brian Paul span->tex[i][3] = 1.0; 140e63cb85cbc13c083f5d9f4640bb81ba9417a4f28Brian Paul } 141e63cb85cbc13c083f5d9f4640bb81ba9417a4f28Brian Paul else { 142e63cb85cbc13c083f5d9f4640bb81ba9417a4f28Brian Paul ASSIGN_4V(span->tex[i], 0.0F, 0.0F, 0.0F, 1.0F); 143e63cb85cbc13c083f5d9f4640bb81ba9417a4f28Brian Paul } 1445f60a0b50ada1865d4fc6a724366e8ea0cc9a72fBrian Paul ASSIGN_4V(span->texStepX[i], 0.0F, 0.0F, 0.0F, 0.0F); 1455f60a0b50ada1865d4fc6a724366e8ea0cc9a72fBrian Paul ASSIGN_4V(span->texStepY[i], 0.0F, 0.0F, 0.0F, 0.0F); 1464753d60dd070bb08d0116076bcc08025c86ce857Brian Paul } 1474753d60dd070bb08d0116076bcc08025c86ce857Brian Paul span->interpMask |= SPAN_TEXTURE; 1484753d60dd070bb08d0116076bcc08025c86ce857Brian Paul} 1494753d60dd070bb08d0116076bcc08025c86ce857Brian Paul 1504753d60dd070bb08d0116076bcc08025c86ce857Brian Paul 1512a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul/* Fill in the span.color.rgba array from the interpolation values */ 1522a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paulstatic void 1532a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paulinterpolate_colors(GLcontext *ctx, struct sw_span *span) 1542a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul{ 1552a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul const GLuint n = span->end; 15677df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul GLchan (*rgba)[4] = span->array->rgba; 1572a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLuint i; 158a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul (void) ctx; 1592a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 160b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul ASSERT((span->interpMask & SPAN_RGBA) && 161b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul !(span->arrayMask & SPAN_RGBA)); 1622a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 1632a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul if (span->interpMask & SPAN_FLAT) { 1642a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul /* constant color */ 1652a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLchan color[4]; 1666a98bef96189fbacc326ad9e407c1d4423aa8572Brian Paul color[RCOMP] = FixedToChan(span->red); 1676a98bef96189fbacc326ad9e407c1d4423aa8572Brian Paul color[GCOMP] = FixedToChan(span->green); 1686a98bef96189fbacc326ad9e407c1d4423aa8572Brian Paul color[BCOMP] = FixedToChan(span->blue); 1696a98bef96189fbacc326ad9e407c1d4423aa8572Brian Paul color[ACOMP] = FixedToChan(span->alpha); 1702a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul for (i = 0; i < n; i++) { 17177df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul COPY_CHAN4(span->array->rgba[i], color); 1722a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 1732a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 1742a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul else { 1752a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul /* interpolate */ 1766a98bef96189fbacc326ad9e407c1d4423aa8572Brian Paul#if CHAN_TYPE == GL_FLOAT 1776a98bef96189fbacc326ad9e407c1d4423aa8572Brian Paul GLfloat r = span->red; 1786a98bef96189fbacc326ad9e407c1d4423aa8572Brian Paul GLfloat g = span->green; 1796a98bef96189fbacc326ad9e407c1d4423aa8572Brian Paul GLfloat b = span->blue; 1806a98bef96189fbacc326ad9e407c1d4423aa8572Brian Paul GLfloat a = span->alpha; 1816a98bef96189fbacc326ad9e407c1d4423aa8572Brian Paul const GLfloat dr = span->redStep; 1826a98bef96189fbacc326ad9e407c1d4423aa8572Brian Paul const GLfloat dg = span->greenStep; 1836a98bef96189fbacc326ad9e407c1d4423aa8572Brian Paul const GLfloat db = span->blueStep; 1846a98bef96189fbacc326ad9e407c1d4423aa8572Brian Paul const GLfloat da = span->alphaStep; 1856a98bef96189fbacc326ad9e407c1d4423aa8572Brian Paul#else 1866a98bef96189fbacc326ad9e407c1d4423aa8572Brian Paul GLfixed r = span->red; 1876a98bef96189fbacc326ad9e407c1d4423aa8572Brian Paul GLfixed g = span->green; 1886a98bef96189fbacc326ad9e407c1d4423aa8572Brian Paul GLfixed b = span->blue; 1896a98bef96189fbacc326ad9e407c1d4423aa8572Brian Paul GLfixed a = span->alpha; 1906a98bef96189fbacc326ad9e407c1d4423aa8572Brian Paul const GLint dr = span->redStep; 1916a98bef96189fbacc326ad9e407c1d4423aa8572Brian Paul const GLint dg = span->greenStep; 1926a98bef96189fbacc326ad9e407c1d4423aa8572Brian Paul const GLint db = span->blueStep; 1936a98bef96189fbacc326ad9e407c1d4423aa8572Brian Paul const GLint da = span->alphaStep; 1946a98bef96189fbacc326ad9e407c1d4423aa8572Brian Paul#endif 1952a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul for (i = 0; i < n; i++) { 1962a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul rgba[i][RCOMP] = FixedToChan(r); 1972a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul rgba[i][GCOMP] = FixedToChan(g); 1982a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul rgba[i][BCOMP] = FixedToChan(b); 1992a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul rgba[i][ACOMP] = FixedToChan(a); 2002a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul r += dr; 2012a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul g += dg; 2022a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul b += db; 2032a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul a += da; 2042a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 2052a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 2062a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->arrayMask |= SPAN_RGBA; 2072a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul} 2082a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 2092a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 2102a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul/* Fill in the span.color.index array from the interpolation values */ 2112a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paulstatic void 2122a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paulinterpolate_indexes(GLcontext *ctx, struct sw_span *span) 2132a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul{ 2142a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfixed index = span->index; 2152a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul const GLint indexStep = span->indexStep; 2162a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul const GLuint n = span->end; 21777df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul GLuint *indexes = span->array->index; 2182a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLuint i; 219a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul (void) ctx; 220b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul ASSERT((span->interpMask & SPAN_INDEX) && 221b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul !(span->arrayMask & SPAN_INDEX)); 2222a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 2232a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul if ((span->interpMask & SPAN_FLAT) || (indexStep == 0)) { 2242a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul /* constant color */ 2252a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul index = FixedToInt(index); 2262a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul for (i = 0; i < n; i++) { 2272a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul indexes[i] = index; 2282a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 2292a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 2302a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul else { 2312a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul /* interpolate */ 2322a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul for (i = 0; i < n; i++) { 2332a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul indexes[i] = FixedToInt(index); 2342a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul index += indexStep; 2352a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 2362a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 2372a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->arrayMask |= SPAN_INDEX; 238e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul span->interpMask &= ~SPAN_INDEX; 2392a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul} 2402a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 2412a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 24277df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul/* Fill in the span.->array->spec array from the interpolation values */ 2432a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paulstatic void 2442a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paulinterpolate_specular(GLcontext *ctx, struct sw_span *span) 2452a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul{ 246a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul (void) ctx; 2472a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul if (span->interpMask & SPAN_FLAT) { 2482a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul /* constant color */ 2492a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul const GLchan r = FixedToChan(span->specRed); 2502a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul const GLchan g = FixedToChan(span->specGreen); 2512a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul const GLchan b = FixedToChan(span->specBlue); 2522a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLuint i; 2532a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul for (i = 0; i < span->end; i++) { 25477df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul span->array->spec[i][RCOMP] = r; 25577df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul span->array->spec[i][GCOMP] = g; 25677df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul span->array->spec[i][BCOMP] = b; 2572a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 2582a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 2592a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul else { 2602a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul /* interpolate */ 2612a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul#if CHAN_TYPE == GL_FLOAT 2622a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat r = span->specRed; 2632a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat g = span->specGreen; 2642a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat b = span->specBlue; 2652a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul#else 2662a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfixed r = span->specRed; 2672a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfixed g = span->specGreen; 2682a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfixed b = span->specBlue; 2692a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul#endif 2702a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLuint i; 2712a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul for (i = 0; i < span->end; i++) { 27277df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul span->array->spec[i][RCOMP] = FixedToChan(r); 27377df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul span->array->spec[i][GCOMP] = FixedToChan(g); 27477df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul span->array->spec[i][BCOMP] = FixedToChan(b); 2752a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul r += span->specRedStep; 2762a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul g += span->specGreenStep; 2772a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul b += span->specBlueStep; 2782a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 2792a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 2802a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->arrayMask |= SPAN_SPEC; 2812a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul} 2822a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 2832a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 284d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul/* Fill in the span.array.fog values from the interpolation values */ 285d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paulstatic void 286d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paulinterpolate_fog(const GLcontext *ctx, struct sw_span *span) 287d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul{ 288d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul GLfloat *fog = span->array->fog; 289d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul const GLfloat fogStep = span->fogStep; 290d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul GLfloat fogCoord = span->fog; 291d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul const GLuint haveW = (span->interpMask & SPAN_W); 292d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul const GLfloat wStep = haveW ? span->dwdx : 0.0F; 293d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul GLfloat w = haveW ? span->w : 1.0F; 294d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul GLuint i; 295d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul for (i = 0; i < span->end; i++) { 296d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul fog[i] = fogCoord / w; 297d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul fogCoord += fogStep; 298d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul w += wStep; 299d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul } 300d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul span->arrayMask |= SPAN_FOG; 301d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul} 302d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul 303d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul 3042a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul/* Fill in the span.zArray array from the interpolation values */ 305711e27fda27e4235b20a4cf73c2767c984ab2b81Brian Paulvoid 30645bc887da226403f2c41077e40ca38b6f60f1359Brian Paul_swrast_span_interpolate_z( const GLcontext *ctx, struct sw_span *span ) 3072a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul{ 3082a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul const GLuint n = span->end; 3092a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLuint i; 3102a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 311b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul ASSERT((span->interpMask & SPAN_Z) && 312b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul !(span->arrayMask & SPAN_Z)); 3132a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 3142a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul if (ctx->Visual.depthBits <= 16) { 3152a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfixed zval = span->z; 31677df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul GLdepth *z = span->array->z; 317ad8cd6111e022c90c93df106c0fde6f64d205816Brian Paul for (i = 0; i < n; i++) { 31877df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul z[i] = FixedToInt(zval); 3192a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul zval += span->zStep; 3202a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 3212a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 3222a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul else { 3232a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul /* Deep Z buffer, no fixed->int shift */ 3242a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfixed zval = span->z; 32577df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul GLdepth *z = span->array->z; 3262a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul for (i = 0; i < n; i++) { 32777df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul z[i] = zval; 3282a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul zval += span->zStep; 3292a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 3302a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 3312a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->arrayMask |= SPAN_Z; 3322a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul} 3332a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 3342a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 335c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul/* 33631f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul * This the ideal solution, as given in the OpenGL spec. 337c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul */ 338c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul#if 0 33931f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paulstatic GLfloat 34031f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paulcompute_lambda(GLfloat dsdx, GLfloat dsdy, GLfloat dtdx, GLfloat dtdy, 34131f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat dqdx, GLfloat dqdy, GLfloat texW, GLfloat texH, 34231f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat s, GLfloat t, GLfloat q, GLfloat invQ) 343c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul{ 34431f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat dudx = texW * ((s + dsdx) / (q + dqdx) - s * invQ); 34531f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat dvdx = texH * ((t + dtdx) / (q + dqdx) - t * invQ); 34631f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat dudy = texW * ((s + dsdy) / (q + dqdy) - s * invQ); 34731f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat dvdy = texH * ((t + dtdy) / (q + dqdy) - t * invQ); 348f9b1e5241facc8cf255c258082d5cb5b04783e93Brian Paul GLfloat x = SQRTF(dudx * dudx + dvdx * dvdx); 349f9b1e5241facc8cf255c258082d5cb5b04783e93Brian Paul GLfloat y = SQRTF(dudy * dudy + dvdy * dvdy); 35031f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat rho = MAX2(x, y); 35131f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat lambda = LOG2(rho); 35231f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul return lambda; 353c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul} 354c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul#endif 355c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul 35631f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul 35731f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul/* 35831f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul * This is a faster approximation 359c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul */ 360350353adcd75f94fda63c787c86961716114e0bfBrian PaulGLfloat 36145bc887da226403f2c41077e40ca38b6f60f1359Brian Paul_swrast_compute_lambda(GLfloat dsdx, GLfloat dsdy, GLfloat dtdx, GLfloat dtdy, 362350353adcd75f94fda63c787c86961716114e0bfBrian Paul GLfloat dqdx, GLfloat dqdy, GLfloat texW, GLfloat texH, 363350353adcd75f94fda63c787c86961716114e0bfBrian Paul GLfloat s, GLfloat t, GLfloat q, GLfloat invQ) 364c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul{ 36531f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat dsdx2 = (s + dsdx) / (q + dqdx) - s * invQ; 36631f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat dtdx2 = (t + dtdx) / (q + dqdx) - t * invQ; 36731f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat dsdy2 = (s + dsdy) / (q + dqdy) - s * invQ; 36831f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat dtdy2 = (t + dtdy) / (q + dqdy) - t * invQ; 36931f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat maxU, maxV, rho, lambda; 37031f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul dsdx2 = FABSF(dsdx2); 37131f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul dsdy2 = FABSF(dsdy2); 37231f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul dtdx2 = FABSF(dtdx2); 37331f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul dtdy2 = FABSF(dtdy2); 37431f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul maxU = MAX2(dsdx2, dsdy2) * texW; 37531f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul maxV = MAX2(dtdx2, dtdy2) * texH; 37631f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul rho = MAX2(maxU, maxV); 37731f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul lambda = LOG2(rho); 37831f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul return lambda; 379c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul} 380c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul 381d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul 382d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul/** 383c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul * Fill in the span.texcoords array from the interpolation values. 384d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul * Note: in the places where we divide by Q (or mult by invQ) we're 385d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul * really doing two things: perspective correction and texcoord 386d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul * projection. Remember, for texcoord (s,t,r,q) we need to index 387d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul * texels with (s/q, t/q, r/q). 388d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul * If we're using a fragment program, we never do the division 389d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul * for texcoord projection. That's done by the TXP instruction 390d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul * or user-written code. 391c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul */ 3922a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paulstatic void 3932a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paulinterpolate_texcoords(GLcontext *ctx, struct sw_span *span) 3942a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul{ 3952a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul ASSERT(span->interpMask & SPAN_TEXTURE); 396b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul ASSERT(!(span->arrayMask & SPAN_TEXTURE)); 3972a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 39836a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul if (ctx->Texture._EnabledCoordUnits > 1) { 39931f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul /* multitexture */ 40031f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLuint u; 401b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul span->arrayMask |= SPAN_TEXTURE; 40231f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { 40336a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul if (ctx->Texture._EnabledCoordUnits & (1 << u)) { 40431f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const struct gl_texture_object *obj =ctx->Texture.Unit[u]._Current; 40536a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul GLfloat texW, texH; 40636a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul GLboolean needLambda; 40736a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul if (obj) { 40818fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell const struct gl_texture_image *img = obj->Image[0][obj->BaseLevel]; 40936a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul needLambda = (obj->MinFilter != obj->MagFilter) 41047b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell || ctx->FragmentProgram._Active; 41136a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul texW = img->WidthScale; 41236a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul texH = img->HeightScale; 41336a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul } 41436a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul else { 415d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul /* using a fragment program */ 41636a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul texW = 1.0; 41736a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul texH = 1.0; 41836a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul needLambda = GL_FALSE; 41936a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul } 42031f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul if (needLambda) { 42177df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul GLfloat (*texcoord)[4] = span->array->texcoords[u]; 42277df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul GLfloat *lambda = span->array->lambda[u]; 42331f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat dsdx = span->texStepX[u][0]; 42431f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat dsdy = span->texStepY[u][0]; 42531f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat dtdx = span->texStepX[u][1]; 42631f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat dtdy = span->texStepY[u][1]; 42731f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat drdx = span->texStepX[u][2]; 42831f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat dqdx = span->texStepX[u][3]; 42931f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat dqdy = span->texStepY[u][3]; 4302a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat s = span->tex[u][0]; 4312a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat t = span->tex[u][1]; 4322a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat r = span->tex[u][2]; 4332a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat q = span->tex[u][3]; 4342a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLuint i; 43547b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell if (ctx->FragmentProgram._Active) { 436d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul /* do perspective correction but don't divide s, t, r by q */ 437d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul const GLfloat dwdx = span->dwdx; 438d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul GLfloat w = span->w; 439d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul for (i = 0; i < span->end; i++) { 440d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul const GLfloat invW = 1.0F / w; 441d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul texcoord[i][0] = s * invW; 442d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul texcoord[i][1] = t * invW; 443d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul texcoord[i][2] = r * invW; 444d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul texcoord[i][3] = q * invW; 445d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul lambda[i] = _swrast_compute_lambda(dsdx, dsdy, dtdx, dtdy, 446d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul dqdx, dqdy, texW, texH, 447d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul s, t, q, invW); 448d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul s += dsdx; 449d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul t += dtdx; 450d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul r += drdx; 451d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul q += dqdx; 452d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul w += dwdx; 453d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul } 454d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul 455d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul } 456d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul else { 457d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul for (i = 0; i < span->end; i++) { 458d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q); 459d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul texcoord[i][0] = s * invQ; 460d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul texcoord[i][1] = t * invQ; 461d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul texcoord[i][2] = r * invQ; 462d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul texcoord[i][3] = q; 463d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul lambda[i] = _swrast_compute_lambda(dsdx, dsdy, dtdx, dtdy, 464d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul dqdx, dqdy, texW, texH, 465d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul s, t, q, invQ); 466d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul s += dsdx; 467d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul t += dtdx; 468d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul r += drdx; 469d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul q += dqdx; 470d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul } 4712a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 47231f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul span->arrayMask |= SPAN_LAMBDA; 4732a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 47431f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul else { 47577df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul GLfloat (*texcoord)[4] = span->array->texcoords[u]; 47677df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul GLfloat *lambda = span->array->lambda[u]; 47731f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat dsdx = span->texStepX[u][0]; 47831f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat dtdx = span->texStepX[u][1]; 47931f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat drdx = span->texStepX[u][2]; 48031f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat dqdx = span->texStepX[u][3]; 4812a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat s = span->tex[u][0]; 4822a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat t = span->tex[u][1]; 4832a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat r = span->tex[u][2]; 4842a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat q = span->tex[u][3]; 4852a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLuint i; 48647b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell if (ctx->FragmentProgram._Active) { 487d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul /* do perspective correction but don't divide s, t, r by q */ 488d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul const GLfloat dwdx = span->dwdx; 489d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul GLfloat w = span->w; 490d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul for (i = 0; i < span->end; i++) { 491d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul const GLfloat invW = 1.0F / w; 492d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul texcoord[i][0] = s * invW; 493d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul texcoord[i][1] = t * invW; 494d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul texcoord[i][2] = r * invW; 495d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul texcoord[i][3] = q * invW; 496d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul lambda[i] = 0.0; 497d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul s += dsdx; 498d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul t += dtdx; 499d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul r += drdx; 500d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul q += dqdx; 501d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul w += dwdx; 502d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul } 503d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul } 504d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul else if (dqdx == 0.0F) { 505c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul /* Ortho projection or polygon's parallel to window X axis */ 5062a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q); 507c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul for (i = 0; i < span->end; i++) { 50877df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul texcoord[i][0] = s * invQ; 50977df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul texcoord[i][1] = t * invQ; 51077df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul texcoord[i][2] = r * invQ; 51136a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul texcoord[i][3] = q; 51277df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul lambda[i] = 0.0; 51331f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul s += dsdx; 51431f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul t += dtdx; 51531f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul r += drdx; 516c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul } 517c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul } 518c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul else { 519c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul for (i = 0; i < span->end; i++) { 520c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q); 52177df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul texcoord[i][0] = s * invQ; 52277df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul texcoord[i][1] = t * invQ; 52377df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul texcoord[i][2] = r * invQ; 52436a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul texcoord[i][3] = q; 52577df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul lambda[i] = 0.0; 52631f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul s += dsdx; 52731f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul t += dtdx; 52831f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul r += drdx; 52931f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul q += dqdx; 530c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul } 5312a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 53231f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul } /* lambda */ 53331f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul } /* if */ 53431f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul } /* for */ 5352a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 5362a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul else { 53731f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul /* single texture */ 53831f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const struct gl_texture_object *obj = ctx->Texture.Unit[0]._Current; 53936a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul GLfloat texW, texH; 54036a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul GLboolean needLambda; 54136a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul if (obj) { 54218fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell const struct gl_texture_image *img = obj->Image[0][obj->BaseLevel]; 54336a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul needLambda = (obj->MinFilter != obj->MagFilter) 54447b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell || ctx->FragmentProgram._Active; 54536a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul texW = (GLfloat) img->WidthScale; 54636a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul texH = (GLfloat) img->HeightScale; 54736a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul } 54836a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul else { 54936a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul needLambda = GL_FALSE; 55036a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul texW = texH = 1.0; 55136a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul } 552b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul span->arrayMask |= SPAN_TEXTURE; 55331f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul if (needLambda) { 5542a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul /* just texture unit 0, with lambda */ 55577df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul GLfloat (*texcoord)[4] = span->array->texcoords[0]; 55677df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul GLfloat *lambda = span->array->lambda[0]; 55731f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat dsdx = span->texStepX[0][0]; 55831f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat dsdy = span->texStepY[0][0]; 55931f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat dtdx = span->texStepX[0][1]; 56031f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat dtdy = span->texStepY[0][1]; 56131f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat drdx = span->texStepX[0][2]; 56231f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat dqdx = span->texStepX[0][3]; 56331f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat dqdy = span->texStepY[0][3]; 5642a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat s = span->tex[0][0]; 5652a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat t = span->tex[0][1]; 5662a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat r = span->tex[0][2]; 5672a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat q = span->tex[0][3]; 5682a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLuint i; 56947b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell if (ctx->FragmentProgram._Active) { 570d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul /* do perspective correction but don't divide s, t, r by q */ 571d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul const GLfloat dwdx = span->dwdx; 572d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul GLfloat w = span->w; 573d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul for (i = 0; i < span->end; i++) { 574d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul const GLfloat invW = 1.0F / w; 575d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul texcoord[i][0] = s * invW; 576d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul texcoord[i][1] = t * invW; 577d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul texcoord[i][2] = r * invW; 578d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul texcoord[i][3] = q * invW; 579d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul lambda[i] = _swrast_compute_lambda(dsdx, dsdy, dtdx, dtdy, 580d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul dqdx, dqdy, texW, texH, 581d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul s, t, q, invW); 582d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul s += dsdx; 583d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul t += dtdx; 584d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul r += drdx; 585d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul q += dqdx; 586d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul w += dwdx; 587d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul } 588d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul } 589d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul else { 590d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul /* tex.c */ 591d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul for (i = 0; i < span->end; i++) { 592d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q); 593d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul lambda[i] = _swrast_compute_lambda(dsdx, dsdy, dtdx, dtdy, 594d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul dqdx, dqdy, texW, texH, 595d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul s, t, q, invQ); 596d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul texcoord[i][0] = s * invQ; 597d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul texcoord[i][1] = t * invQ; 598d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul texcoord[i][2] = r * invQ; 599d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul texcoord[i][3] = q; 600d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul s += dsdx; 601d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul t += dtdx; 602d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul r += drdx; 603d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul q += dqdx; 604d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul } 6052a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 6062a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->arrayMask |= SPAN_LAMBDA; 6072a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 6082a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul else { 609733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* just texture 0, without lambda */ 61077df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul GLfloat (*texcoord)[4] = span->array->texcoords[0]; 61131f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat dsdx = span->texStepX[0][0]; 61231f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat dtdx = span->texStepX[0][1]; 61331f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat drdx = span->texStepX[0][2]; 61431f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat dqdx = span->texStepX[0][3]; 6152a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat s = span->tex[0][0]; 6162a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat t = span->tex[0][1]; 6172a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat r = span->tex[0][2]; 6182a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat q = span->tex[0][3]; 6192a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLuint i; 62047b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell if (ctx->FragmentProgram._Active) { 621d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul /* do perspective correction but don't divide s, t, r by q */ 622d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul const GLfloat dwdx = span->dwdx; 623d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul GLfloat w = span->w; 624d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul for (i = 0; i < span->end; i++) { 625d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul const GLfloat invW = 1.0F / w; 626d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul texcoord[i][0] = s * invW; 627d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul texcoord[i][1] = t * invW; 628d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul texcoord[i][2] = r * invW; 629d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul texcoord[i][3] = q * invW; 630d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul s += dsdx; 631d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul t += dtdx; 632d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul r += drdx; 633d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul q += dqdx; 634d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul w += dwdx; 635d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul } 636d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul } 637d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul else if (dqdx == 0.0F) { 638c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul /* Ortho projection or polygon's parallel to window X axis */ 6392a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q); 640c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul for (i = 0; i < span->end; i++) { 64177df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul texcoord[i][0] = s * invQ; 64277df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul texcoord[i][1] = t * invQ; 64377df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul texcoord[i][2] = r * invQ; 6442b7a01a39ba5257407dddde38ef049856c34aa01Brian Paul texcoord[i][3] = q; 64531f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul s += dsdx; 64631f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul t += dtdx; 64731f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul r += drdx; 648c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul } 649c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul } 650c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul else { 651c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul for (i = 0; i < span->end; i++) { 652c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q); 65377df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul texcoord[i][0] = s * invQ; 65477df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul texcoord[i][1] = t * invQ; 65577df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul texcoord[i][2] = r * invQ; 6562b7a01a39ba5257407dddde38ef049856c34aa01Brian Paul texcoord[i][3] = q; 65731f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul s += dsdx; 65831f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul t += dtdx; 65931f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul r += drdx; 66031f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul q += dqdx; 661c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul } 6622a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 6632a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 6642a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 66510f30eb43835c57c00783390a02d72daf4f78e26Brian Paul} 666e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 667e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 66879c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/** 669e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Apply the current polygon stipple pattern to a span of pixels. 670e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */ 6715071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paulstatic void 672733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paulstipple_polygon_span( GLcontext *ctx, struct sw_span *span ) 67310f30eb43835c57c00783390a02d72daf4f78e26Brian Paul{ 67410f30eb43835c57c00783390a02d72daf4f78e26Brian Paul const GLuint highbit = 0x80000000; 675733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul const GLuint stipple = ctx->PolygonStipple[span->y % 32]; 67677df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul GLubyte *mask = span->array->mask; 677733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul GLuint i, m; 678733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul 679733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul ASSERT(ctx->Polygon.StippleFlag); 680733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul ASSERT((span->arrayMask & SPAN_XY) == 0); 68110f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 68210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul m = highbit >> (GLuint) (span->x % 32); 68310f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 68410f30eb43835c57c00783390a02d72daf4f78e26Brian Paul for (i = 0; i < span->end; i++) { 68510f30eb43835c57c00783390a02d72daf4f78e26Brian Paul if ((m & stipple) == 0) { 68677df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul mask[i] = 0; 68710f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 68810f30eb43835c57c00783390a02d72daf4f78e26Brian Paul m = m >> 1; 68910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul if (m == 0) { 69010f30eb43835c57c00783390a02d72daf4f78e26Brian Paul m = highbit; 69110f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 69210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 6932ef866d1fc0a5cc5ef8543d65744dfd4da4dbbafBrian Paul span->writeAll = GL_FALSE; 69410f30eb43835c57c00783390a02d72daf4f78e26Brian Paul} 69510f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 696e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 69779c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/** 698733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul * Clip a pixel span to the current buffer/window boundaries: 699733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul * DrawBuffer->_Xmin, _Xmax, _Ymin, _Ymax. This will accomplish 700733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul * window clipping and scissoring. 701733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul * Return: GL_TRUE some pixels still visible 70210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul * GL_FALSE nothing visible 70310f30eb43835c57c00783390a02d72daf4f78e26Brian Paul */ 70410f30eb43835c57c00783390a02d72daf4f78e26Brian Paulstatic GLuint 705733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paulclip_span( GLcontext *ctx, struct sw_span *span ) 70610f30eb43835c57c00783390a02d72daf4f78e26Brian Paul{ 707733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul const GLint xmin = ctx->DrawBuffer->_Xmin; 708733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul const GLint xmax = ctx->DrawBuffer->_Xmax; 709733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul const GLint ymin = ctx->DrawBuffer->_Ymin; 710733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul const GLint ymax = ctx->DrawBuffer->_Ymax; 711733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul 712733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (span->arrayMask & SPAN_XY) { 713733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* arrays of x/y pixel coords */ 71477df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul const GLint *x = span->array->x; 71577df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul const GLint *y = span->array->y; 716733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul const GLint n = span->end; 71777df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul GLubyte *mask = span->array->mask; 718733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul GLint i; 719b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul if (span->arrayMask & SPAN_MASK) { 720b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul /* note: using & intead of && to reduce branches */ 721b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul for (i = 0; i < n; i++) { 722b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul mask[i] &= (x[i] >= xmin) & (x[i] < xmax) 723b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul & (y[i] >= ymin) & (y[i] < ymax); 724b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul } 725b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul } 726b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul else { 727b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul /* note: using & intead of && to reduce branches */ 728b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul for (i = 0; i < n; i++) { 729b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul mask[i] = (x[i] >= xmin) & (x[i] < xmax) 730b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul & (y[i] >= ymin) & (y[i] < ymax); 731b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul } 73210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 733733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul return GL_TRUE; /* some pixels visible */ 73410f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 735733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul else { 736733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* horizontal span of pixels */ 737733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul const GLint x = span->x; 738733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul const GLint y = span->y; 739733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul const GLint n = span->end; 740733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul 741733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* Trivial rejection tests */ 742733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (y < ymin || y >= ymax || x + n <= xmin || x >= xmax) { 743733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->end = 0; 744733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul return GL_FALSE; /* all pixels clipped */ 745733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul } 74610f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 747733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* Clip to the left */ 748733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (x < xmin) { 749733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul ASSERT(x + n > xmin); 750733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->writeAll = GL_FALSE; 7516ec6b845fdf3c44436028ad6fff9471d18928719Brian Paul _mesa_bzero(span->array->mask, (xmin - x) * sizeof(GLubyte)); 75210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 753733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul 754733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* Clip to right */ 755733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (x + n > xmax) { 756733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul ASSERT(x < xmax); 757733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->end = xmax - x; 75810f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 75910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 760733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul return GL_TRUE; /* some pixels visible */ 761733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul } 76210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul} 76310f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 76410f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 76579c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/** 766e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul * Apply all the per-fragment opertions to a span of color index fragments 767e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul * and write them to the enabled color drawbuffers. 768e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul * The 'span' parameter can be considered to be const. Note that 7697956292a765910077f50352d7cd0174e1e66d26cBrian Paul * span->interpMask and span->arrayMask may be changed but will be restored 7707956292a765910077f50352d7cd0174e1e66d26cBrian Paul * to their original values before returning. 77110f30eb43835c57c00783390a02d72daf4f78e26Brian Paul */ 77210f30eb43835c57c00783390a02d72daf4f78e26Brian Paulvoid 77345bc887da226403f2c41077e40ca38b6f60f1359Brian Paul_swrast_write_index_span( GLcontext *ctx, struct sw_span *span) 77410f30eb43835c57c00783390a02d72daf4f78e26Brian Paul{ 775e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul const SWcontext *swrast = SWRAST_CONTEXT(ctx); 776e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul const struct gl_framebuffer *fb = ctx->DrawBuffer; 777e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul const GLuint output = 0; 7787956292a765910077f50352d7cd0174e1e66d26cBrian Paul const GLuint origInterpMask = span->interpMask; 7792a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul const GLuint origArrayMask = span->arrayMask; 780e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul GLuint buf; 78110f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 782733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul ASSERT(span->end <= MAX_WIDTH); 783b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul ASSERT(span->primitive == GL_POINT || span->primitive == GL_LINE || 784b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul span->primitive == GL_POLYGON || span->primitive == GL_BITMAP); 785733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul ASSERT((span->interpMask | span->arrayMask) & SPAN_INDEX); 7867956292a765910077f50352d7cd0174e1e66d26cBrian Paul ASSERT((span->interpMask & span->arrayMask) == 0); 7877956292a765910077f50352d7cd0174e1e66d26cBrian Paul 788733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (span->arrayMask & SPAN_MASK) { 789733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* mask was initialized by caller, probably glBitmap */ 790733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->writeAll = GL_FALSE; 791733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul } 792733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul else { 793a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul _mesa_memset(span->array->mask, 1, span->end); 794733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->writeAll = GL_TRUE; 79510f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 79610f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 797733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* Clipping */ 798b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul if ((swrast->_RasterMask & CLIP_BIT) || (span->primitive != GL_POLYGON)) { 799733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (!clip_span(ctx, span)) { 80086ca15ece74ccb5a8f4d566a4b2c8024b178d73bBrian Paul return; 801e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 802e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 803e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 804e5b244ff7f984805c1bcc020342f1300f2639c71Brian Paul /* Depth bounds test */ 805e5b244ff7f984805c1bcc020342f1300f2639c71Brian Paul if (ctx->Depth.BoundsTest && ctx->Visual.depthBits > 0) { 806e5b244ff7f984805c1bcc020342f1300f2639c71Brian Paul if (!_swrast_depth_bounds_test(ctx, span)) { 807e5b244ff7f984805c1bcc020342f1300f2639c71Brian Paul return; 808e5b244ff7f984805c1bcc020342f1300f2639c71Brian Paul } 809e5b244ff7f984805c1bcc020342f1300f2639c71Brian Paul } 810e5b244ff7f984805c1bcc020342f1300f2639c71Brian Paul 811b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul#ifdef DEBUG 812a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul /* Make sure all fragments are within window bounds */ 813b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul if (span->arrayMask & SPAN_XY) { 814a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul GLuint i; 815b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul for (i = 0; i < span->end; i++) { 81677df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul if (span->array->mask[i]) { 81777df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul assert(span->array->x[i] >= ctx->DrawBuffer->_Xmin); 81877df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul assert(span->array->x[i] < ctx->DrawBuffer->_Xmax); 81977df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul assert(span->array->y[i] >= ctx->DrawBuffer->_Ymin); 82077df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul assert(span->array->y[i] < ctx->DrawBuffer->_Ymax); 821b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul } 822b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul } 823b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul } 824b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul#endif 825b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul 826e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* Polygon Stippling */ 827b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul if (ctx->Polygon.StippleFlag && span->primitive == GL_POLYGON) { 82810f30eb43835c57c00783390a02d72daf4f78e26Brian Paul stipple_polygon_span(ctx, span); 829e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 830e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 831e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul /* Stencil and Z testing */ 8327956292a765910077f50352d7cd0174e1e66d26cBrian Paul if (ctx->Depth.Test || ctx->Stencil.Enabled) { 8337956292a765910077f50352d7cd0174e1e66d26cBrian Paul if (span->interpMask & SPAN_Z) 83445bc887da226403f2c41077e40ca38b6f60f1359Brian Paul _swrast_span_interpolate_z(ctx, span); 83510f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 8367956292a765910077f50352d7cd0174e1e66d26cBrian Paul if (ctx->Stencil.Enabled) { 83745bc887da226403f2c41077e40ca38b6f60f1359Brian Paul if (!_swrast_stencil_and_ztest_span(ctx, span)) { 8387956292a765910077f50352d7cd0174e1e66d26cBrian Paul span->arrayMask = origArrayMask; 8397956292a765910077f50352d7cd0174e1e66d26cBrian Paul return; 8407956292a765910077f50352d7cd0174e1e66d26cBrian Paul } 8412a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 8427956292a765910077f50352d7cd0174e1e66d26cBrian Paul else { 8437956292a765910077f50352d7cd0174e1e66d26cBrian Paul ASSERT(ctx->Depth.Test); 84445bc887da226403f2c41077e40ca38b6f60f1359Brian Paul if (!_swrast_depth_test_span(ctx, span)) { 845e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul span->interpMask = origInterpMask; 8467956292a765910077f50352d7cd0174e1e66d26cBrian Paul span->arrayMask = origArrayMask; 8477956292a765910077f50352d7cd0174e1e66d26cBrian Paul return; 8487956292a765910077f50352d7cd0174e1e66d26cBrian Paul } 8492a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 85010f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 85110f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 85210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul /* if we get here, something passed the depth test */ 853939dd17653245621bf7488803f09418244b7b0b7Brian Paul if (ctx->Depth.OcclusionTest) { 854939dd17653245621bf7488803f09418244b7b0b7Brian Paul ctx->OcclusionResult = GL_TRUE; 855939dd17653245621bf7488803f09418244b7b0b7Brian Paul } 85610f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 857b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul#if FEATURE_ARB_occlusion_query 858b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul if (ctx->Occlusion.Active) { 859939dd17653245621bf7488803f09418244b7b0b7Brian Paul /* update count of 'passed' fragments */ 860b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul GLuint i; 861b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul for (i = 0; i < span->end; i++) 862b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul ctx->Occlusion.PassedCounter += span->array->mask[i]; 863b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul } 864b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul#endif 865b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul 8667956292a765910077f50352d7cd0174e1e66d26cBrian Paul /* we have to wait until after occlusion to do this test */ 8677956292a765910077f50352d7cd0174e1e66d26cBrian Paul if (ctx->Color.DrawBuffer == GL_NONE || ctx->Color.IndexMask == 0) { 86810f30eb43835c57c00783390a02d72daf4f78e26Brian Paul /* write no pixels */ 8692a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->arrayMask = origArrayMask; 87010f30eb43835c57c00783390a02d72daf4f78e26Brian Paul return; 87110f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 87210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 8737956292a765910077f50352d7cd0174e1e66d26cBrian Paul /* Interpolate the color indexes if needed */ 874e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul if (ctx->Fog.Enabled || 875e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul ctx->Color.IndexLogicOpEnabled || 876e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul ctx->Color.IndexMask != 0xffffffff || 877e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul (span->arrayMask & SPAN_COVERAGE)) { 878e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul if (span->interpMask & SPAN_INDEX) { 879e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul interpolate_indexes(ctx, span); 880e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul } 8817956292a765910077f50352d7cd0174e1e66d26cBrian Paul } 88210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 8837956292a765910077f50352d7cd0174e1e66d26cBrian Paul /* Fog */ 8842a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul if (ctx->Fog.Enabled) { 88545bc887da226403f2c41077e40ca38b6f60f1359Brian Paul _swrast_fog_ci_span(ctx, span); 886e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 887e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 8882a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul /* Antialias coverage application */ 8892a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul if (span->arrayMask & SPAN_COVERAGE) { 890e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul const GLfloat *coverage = span->array->coverage; 89177df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul GLuint *index = span->array->index; 892e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul GLuint i; 89310f30eb43835c57c00783390a02d72daf4f78e26Brian Paul for (i = 0; i < span->end; i++) { 89477df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul ASSERT(coverage[i] < 16); 89577df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul index[i] = (index[i] & ~0xf) | ((GLuint) coverage[i]); 8965071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paul } 8972a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 8985071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paul 899e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul /* Loop over drawing buffers */ 900e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul for (buf = 0; buf < fb->_NumColorDrawBuffers[output]; buf++) { 901e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul struct gl_renderbuffer *rb = fb->_ColorDrawBuffers[output][buf]; 902e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul GLuint indexTemp[MAX_WIDTH], *index32; 903e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul 904e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul ASSERT(rb->_BaseFormat == GL_COLOR_INDEX); 905e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul 906e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul if (ctx->Color.IndexLogicOpEnabled || 907e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul ctx->Color.IndexMask != 0xffffffff) { 908e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul /* make copy of incoming indexes */ 909e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul MEMCPY(indexTemp, span->array->index, span->end * sizeof(GLuint)); 9102a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 911e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul if (ctx->Color.IndexLogicOpEnabled) { 912e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul _swrast_logicop_ci_span(ctx, rb, span, indexTemp); 913e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul } 914e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul 915e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul if (ctx->Color.IndexMask != 0xffffffff) { 916e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul _swrast_mask_ci_span(ctx, rb, span, indexTemp); 917e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul } 918e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul index32 = indexTemp; 919e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul } 920e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul else { 921e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul index32 = span->array->index; 922e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 9232a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 924e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul if ((span->interpMask & SPAN_INDEX) && span->indexStep == 0) { 925e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul /* all fragments have same color index */ 926e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul GLubyte index8; 927e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul GLushort index16; 928e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul GLuint index32; 929e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul void *value; 930e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul 931e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul if (rb->DataType == GL_UNSIGNED_BYTE) { 932e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul index8 = FixedToInt(span->index); 933e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul value = &index8; 934e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul } 935e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul else if (rb->DataType == GL_UNSIGNED_SHORT) { 936e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul index16 = FixedToInt(span->index); 937e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul value = &index16; 938733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul } 939733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul else { 940e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul ASSERT(rb->DataType == GL_UNSIGNED_INT); 941e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul index32 = FixedToInt(span->index); 942e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul value = &index32; 943e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul } 944e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul 945e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul if (span->arrayMask & SPAN_XY) { 946e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul rb->PutMonoValues(ctx, rb, span->end, span->array->x, 947e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul span->array->y, value, span->array->mask); 948e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul } 949e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul else { 950e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul rb->PutMonoRow(ctx, rb, span->end, span->x, span->y, 951e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul value, span->array->mask); 952733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul } 9537956292a765910077f50352d7cd0174e1e66d26cBrian Paul } 9547956292a765910077f50352d7cd0174e1e66d26cBrian Paul else { 955e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul /* each fragment is a different color */ 956e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul GLubyte index8[MAX_WIDTH]; 957e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul GLushort index16[MAX_WIDTH]; 958e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul void *values; 959e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul 960e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul if (rb->DataType == GL_UNSIGNED_BYTE) { 961e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul GLuint k; 962e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul for (k = 0; k < span->end; k++) { 963e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul index8[k] = (GLubyte) index32[k]; 964e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul } 965e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul values = index8; 966e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul } 967e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul else if (rb->DataType == GL_UNSIGNED_SHORT) { 968e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul GLuint k; 969e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul for (k = 0; k < span->end; k++) { 970e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul index16[k] = (GLushort) index32[k]; 971e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul } 972e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul values = index16; 973733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul } 974733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul else { 975e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul ASSERT(rb->DataType == GL_UNSIGNED_INT); 976e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul values = index32; 977e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul } 978e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul 979e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul if (span->arrayMask & SPAN_XY) { 980e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul rb->PutValues(ctx, rb, span->end, span->array->x, span->array->y, 981e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul values, span->array->mask); 982e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul } 983e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul else { 984e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul rb->PutRow(ctx, rb, span->end, span->x, span->y, 985e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul values, span->array->mask); 986733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul } 9877956292a765910077f50352d7cd0174e1e66d26cBrian Paul } 988e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 9892a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 990e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul#if OLD_RENDERBUFFER 991e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul /* restore default dest buffer */ 992e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul _swrast_use_draw_buffer(ctx); 993e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul#endif 994e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul 9957956292a765910077f50352d7cd0174e1e66d26cBrian Paul span->interpMask = origInterpMask; 9962a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->arrayMask = origArrayMask; 997e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell} 998e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 999e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 100079c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/** 1001e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Add specular color to base color. This is used only when 1002f1e236987829393c81dc86ea19cb49eefe190317Brian Paul * GL_LIGHT_MODEL_COLOR_CONTROL = GL_SEPARATE_SPECULAR_COLOR. 1003e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */ 10045071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paulstatic void 1005f1e236987829393c81dc86ea19cb49eefe190317Brian Pauladd_colors(GLuint n, GLchan rgba[][4], GLchan specular[][4] ) 1006e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell{ 1007e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell GLuint i; 1008f1e236987829393c81dc86ea19cb49eefe190317Brian Paul for (i = 0; i < n; i++) { 10094fa5c1966a985f81c615a9f5ef2f64dd466b252aBrian Paul#if CHAN_TYPE == GL_FLOAT 10104fa5c1966a985f81c615a9f5ef2f64dd466b252aBrian Paul /* no clamping */ 1011f1e236987829393c81dc86ea19cb49eefe190317Brian Paul rgba[i][RCOMP] += specular[i][RCOMP]; 1012f1e236987829393c81dc86ea19cb49eefe190317Brian Paul rgba[i][GCOMP] += specular[i][GCOMP]; 1013f1e236987829393c81dc86ea19cb49eefe190317Brian Paul rgba[i][BCOMP] += specular[i][BCOMP]; 10144fa5c1966a985f81c615a9f5ef2f64dd466b252aBrian Paul#else 1015f1e236987829393c81dc86ea19cb49eefe190317Brian Paul GLint r = rgba[i][RCOMP] + specular[i][RCOMP]; 1016f1e236987829393c81dc86ea19cb49eefe190317Brian Paul GLint g = rgba[i][GCOMP] + specular[i][GCOMP]; 1017f1e236987829393c81dc86ea19cb49eefe190317Brian Paul GLint b = rgba[i][BCOMP] + specular[i][BCOMP]; 1018e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell rgba[i][RCOMP] = (GLchan) MIN2(r, CHAN_MAX); 1019e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell rgba[i][GCOMP] = (GLchan) MIN2(g, CHAN_MAX); 1020e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell rgba[i][BCOMP] = (GLchan) MIN2(b, CHAN_MAX); 10214fa5c1966a985f81c615a9f5ef2f64dd466b252aBrian Paul#endif 1022e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1023e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell} 1024e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 1025e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 102679c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/** 1027e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul * XXX merge this code into the _swrast_write_rgba_span() routine! 1028e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul * 1029e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul * Draw to more than one RGBA color buffer (or none). 1030e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul * All fragment operations, up to (but not) blending/logicop should 1031e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul * have been done first. 1032e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul */ 1033e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paulstatic void 1034e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paulmulti_write_rgba_span( GLcontext *ctx, struct sw_span *span ) 1035e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul{ 1036bb8b302dbce4f830d060efecd8a9f75b10e25abbBrian Paul#if OLD_RENDERBUFFER || NEW_RENDERBUFFER 1037e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul SWcontext *swrast = SWRAST_CONTEXT(ctx); 1038bb8b302dbce4f830d060efecd8a9f75b10e25abbBrian Paul#endif 1039e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul const GLuint colorMask = *((GLuint *) ctx->Color.ColorMask); 1040e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul struct gl_framebuffer *fb = ctx->DrawBuffer; 1041e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul const GLuint output = 0; 1042e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul GLuint i; 1043e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul 1044e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul ASSERT(span->end < MAX_WIDTH); 1045e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul ASSERT(colorMask != 0x0); 1046e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul 1047e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul for (i = 0; i < fb->_NumColorDrawBuffers[output]; i++) { 1048e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul struct gl_renderbuffer *rb = fb->_ColorDrawBuffers[output][i]; 1049e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul GLchan rgbaTmp[MAX_WIDTH][4]; 1050e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul 1051bb8b302dbce4f830d060efecd8a9f75b10e25abbBrian Paul#if OLD_RENDERBUFFER || NEW_RENDERBUFFER 1052bb8b302dbce4f830d060efecd8a9f75b10e25abbBrian Paul /* obsolete code */ 1053e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul GLuint bufferBit = fb->_ColorDrawBit[output][i]; 1054e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul /* Set the current read/draw buffer */ 1055e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul swrast->CurrentBufferBit = bufferBit; 1056e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul (*swrast->Driver.SetBuffer)(ctx, ctx->DrawBuffer, bufferBit); 1057e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul#endif 1058e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul 1059e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul /* make copy of incoming colors */ 1060e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul MEMCPY( rgbaTmp, span->array->rgba, 4 * span->end * sizeof(GLchan) ); 1061e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul 1062e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul if (ctx->Color._LogicOpEnabled) { 1063e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul _swrast_logicop_rgba_span(ctx, rb, span, rgbaTmp); 1064e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul } 1065e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul else if (ctx->Color.BlendEnabled) { 1066e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul _swrast_blend_span(ctx, rb, span, rgbaTmp); 1067e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul } 1068e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul 1069e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul if (colorMask != 0xffffffff) { 1070e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul _swrast_mask_rgba_span(ctx, rb, span, rgbaTmp); 1071e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul } 1072e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul 1073e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul if (span->arrayMask & SPAN_XY) { 1074e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul /* array of pixel coords */ 1075bb8b302dbce4f830d060efecd8a9f75b10e25abbBrian Paul ASSERT(rb->PutValues); 1076bb8b302dbce4f830d060efecd8a9f75b10e25abbBrian Paul rb->PutValues(ctx, rb, span->end, span->array->x, 1077bb8b302dbce4f830d060efecd8a9f75b10e25abbBrian Paul span->array->y, rgbaTmp, span->array->mask); 1078e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul } 1079e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul else { 1080e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul /* horizontal run of pixels */ 1081bb8b302dbce4f830d060efecd8a9f75b10e25abbBrian Paul ASSERT(rb->PutRow); 1082bb8b302dbce4f830d060efecd8a9f75b10e25abbBrian Paul rb->PutRow(ctx, rb, span->end, span->x, span->y, rgbaTmp, 1083bb8b302dbce4f830d060efecd8a9f75b10e25abbBrian Paul span->array->mask); 1084e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul } 1085e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul } 1086e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul 1087bb8b302dbce4f830d060efecd8a9f75b10e25abbBrian Paul#if OLD_RENDERBUFFER || NEW_RENDERBUFFER 1088e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul /* restore default dest buffer */ 1089e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul _swrast_use_draw_buffer(ctx); 1090e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul#endif 1091e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul} 1092e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul 1093e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul 1094e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul/** 1095a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul * Apply all the per-fragment operations to a span. 1096a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul * This now includes texturing (_swrast_write_texture_span() is history). 1097f1e236987829393c81dc86ea19cb49eefe190317Brian Paul * This function may modify any of the array values in the span. 10987956292a765910077f50352d7cd0174e1e66d26cBrian Paul * span->interpMask and span->arrayMask may be changed but will be restored 10997956292a765910077f50352d7cd0174e1e66d26cBrian Paul * to their original values before returning. 110078940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul */ 110178940758e90069ceaca2b6cddb6438488fbad5ccBrian Paulvoid 1102a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul_swrast_write_rgba_span( GLcontext *ctx, struct sw_span *span) 110378940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul{ 110478940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul const GLuint colorMask = *((GLuint *) ctx->Color.ColorMask); 110578940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul SWcontext *swrast = SWRAST_CONTEXT(ctx); 1106e5b244ff7f984805c1bcc020342f1300f2639c71Brian Paul const GLuint origInterpMask = span->interpMask; 1107f1e236987829393c81dc86ea19cb49eefe190317Brian Paul const GLuint origArrayMask = span->arrayMask; 1108f1e236987829393c81dc86ea19cb49eefe190317Brian Paul 1109b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul ASSERT(span->primitive == GL_POINT || span->primitive == GL_LINE || 1110b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul span->primitive == GL_POLYGON || span->primitive == GL_BITMAP); 1111733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul ASSERT(span->end <= MAX_WIDTH); 11127956292a765910077f50352d7cd0174e1e66d26cBrian Paul ASSERT((span->interpMask & span->arrayMask) == 0); 111378940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul 1114ceb39f4f8dc4863fde17d668c752533a2184476eBrian Paul /* 1115a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul printf("%s() interp 0x%x array 0x%x\n", __FUNCTION__, 1116a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul span->interpMask, span->arrayMask); 1117ceb39f4f8dc4863fde17d668c752533a2184476eBrian Paul */ 1118ceb39f4f8dc4863fde17d668c752533a2184476eBrian Paul 1119733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (span->arrayMask & SPAN_MASK) { 1120733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* mask was initialized by caller, probably glBitmap */ 1121733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->writeAll = GL_FALSE; 1122733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul } 1123733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul else { 1124a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul _mesa_memset(span->array->mask, 1, span->end); 1125733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->writeAll = GL_TRUE; 112678940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul } 112778940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul 1128a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul /* Clip to window/scissor box */ 1129b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul if ((swrast->_RasterMask & CLIP_BIT) || (span->primitive != GL_POLYGON)) { 1130733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (!clip_span(ctx, span)) { 1131733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul return; 113278940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul } 113378940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul } 113478940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul 1135b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul#ifdef DEBUG 1136a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul /* Make sure all fragments are within window bounds */ 1137b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul if (span->arrayMask & SPAN_XY) { 1138a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul GLuint i; 1139b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul for (i = 0; i < span->end; i++) { 114077df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul if (span->array->mask[i]) { 114177df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul assert(span->array->x[i] >= ctx->DrawBuffer->_Xmin); 114277df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul assert(span->array->x[i] < ctx->DrawBuffer->_Xmax); 114377df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul assert(span->array->y[i] >= ctx->DrawBuffer->_Ymin); 114477df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul assert(span->array->y[i] < ctx->DrawBuffer->_Ymax); 1145b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul } 1146b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul } 1147b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul } 1148b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul#endif 1149b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul 115078940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul /* Polygon Stippling */ 1151b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul if (ctx->Polygon.StippleFlag && span->primitive == GL_POLYGON) { 1152733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul stipple_polygon_span(ctx, span); 115378940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul } 115478940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul 1155a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul /* Interpolate texcoords? */ 1156a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul if (ctx->Texture._EnabledCoordUnits 1157a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul && (span->interpMask & SPAN_TEXTURE) 1158a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul && (span->arrayMask & SPAN_TEXTURE) == 0) { 1159f1e236987829393c81dc86ea19cb49eefe190317Brian Paul interpolate_texcoords(ctx, span); 1160a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul } 116178940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul 1162a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul /* If the alpha test is enabled, we have to compute the fragment colors 1163a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul * at this point and do the alpha test. 1164a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul * Else, if alpha test is not enabled, we'll try to defer fragment 1165a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul * color computation (by interpolation, texture mapping, fragment program) 1166a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul * until after the Z/stencil tests in the hope that many fragments will 1167a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul * get culled, leaving less work to do. 1168a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul */ 116978940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul if (ctx->Color.AlphaEnabled) { 1170f1e236987829393c81dc86ea19cb49eefe190317Brian Paul /* Now we need the rgba array, fill it in if needed */ 1171f1e236987829393c81dc86ea19cb49eefe190317Brian Paul if ((span->interpMask & SPAN_RGBA) && (span->arrayMask & SPAN_RGBA) == 0) 1172f1e236987829393c81dc86ea19cb49eefe190317Brian Paul interpolate_colors(ctx, span); 1173f1e236987829393c81dc86ea19cb49eefe190317Brian Paul 1174a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul if (span->interpMask & SPAN_SPEC) 117536a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul interpolate_specular(ctx, span); 117636a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul 1177d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul if (span->interpMask & SPAN_FOG) 1178d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul interpolate_fog(ctx, span); 1179d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul 1180a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul /* Compute fragment colors with fragment program or texture lookups */ 118147b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell if (ctx->FragmentProgram._Active) 1182a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul /* XXX interpolate depth values here??? */ 1183e22540c2765e034fed558ea1d44488a03fbba170Brian Paul _swrast_exec_fragment_program( ctx, span ); 11847f752fed993e5e9423abac200dd59141edbada56Dave Airlie else if (ctx->ATIFragmentShader._Enabled) 11857f752fed993e5e9423abac200dd59141edbada56Dave Airlie _swrast_exec_fragment_shader( ctx, span ); 1186a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul else if (ctx->Texture._EnabledUnits) 1187610d59981a9f43fefe29b34ef19c184d28e2bef5Brian Paul _swrast_texture_span( ctx, span ); 118878940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul 118978940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul /* Do the alpha test */ 119045bc887da226403f2c41077e40ca38b6f60f1359Brian Paul if (!_swrast_alpha_test(ctx, span)) { 1191f1e236987829393c81dc86ea19cb49eefe190317Brian Paul span->arrayMask = origArrayMask; 1192ceb39f4f8dc4863fde17d668c752533a2184476eBrian Paul return; 119378940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul } 119478940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul } 119578940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul 1196f1e236987829393c81dc86ea19cb49eefe190317Brian Paul /* Stencil and Z testing */ 1197f1e236987829393c81dc86ea19cb49eefe190317Brian Paul if (ctx->Stencil.Enabled || ctx->Depth.Test) { 1198f1e236987829393c81dc86ea19cb49eefe190317Brian Paul if (span->interpMask & SPAN_Z) 119945bc887da226403f2c41077e40ca38b6f60f1359Brian Paul _swrast_span_interpolate_z(ctx, span); 120078940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul 1201e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul if (ctx->Stencil.Enabled && ctx->DrawBuffer->Visual.stencilBits > 0) { 1202a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul /* Combined Z/stencil tests */ 120345bc887da226403f2c41077e40ca38b6f60f1359Brian Paul if (!_swrast_stencil_and_ztest_span(ctx, span)) { 1204e5b244ff7f984805c1bcc020342f1300f2639c71Brian Paul span->interpMask = origInterpMask; 1205f1e236987829393c81dc86ea19cb49eefe190317Brian Paul span->arrayMask = origArrayMask; 120610f30eb43835c57c00783390a02d72daf4f78e26Brian Paul return; 1207f1e236987829393c81dc86ea19cb49eefe190317Brian Paul } 120871340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 1209e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul else if (ctx->DrawBuffer->Visual.depthBits > 0) { 1210a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul /* Just regular depth testing */ 1211f1e236987829393c81dc86ea19cb49eefe190317Brian Paul ASSERT(ctx->Depth.Test); 1212f1e236987829393c81dc86ea19cb49eefe190317Brian Paul ASSERT(span->arrayMask & SPAN_Z); 121345bc887da226403f2c41077e40ca38b6f60f1359Brian Paul if (!_swrast_depth_test_span(ctx, span)) { 1214e5b244ff7f984805c1bcc020342f1300f2639c71Brian Paul span->interpMask = origInterpMask; 1215f1e236987829393c81dc86ea19cb49eefe190317Brian Paul span->arrayMask = origArrayMask; 121610f30eb43835c57c00783390a02d72daf4f78e26Brian Paul return; 1217f1e236987829393c81dc86ea19cb49eefe190317Brian Paul } 121871340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 121971340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 122071340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul 1221f1e236987829393c81dc86ea19cb49eefe190317Brian Paul /* if we get here, some fragments passed the depth test */ 1222939dd17653245621bf7488803f09418244b7b0b7Brian Paul if (ctx->Depth.OcclusionTest) { 1223939dd17653245621bf7488803f09418244b7b0b7Brian Paul ctx->OcclusionResult = GL_TRUE; 1224939dd17653245621bf7488803f09418244b7b0b7Brian Paul } 122571340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul 1226b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul#if FEATURE_ARB_occlusion_query 1227b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul if (ctx->Occlusion.Active) { 1228939dd17653245621bf7488803f09418244b7b0b7Brian Paul /* update count of 'passed' fragments */ 1229b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul GLuint i; 1230b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul for (i = 0; i < span->end; i++) 1231b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul ctx->Occlusion.PassedCounter += span->array->mask[i]; 1232b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul } 1233b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul#endif 1234b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul 1235a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul /* We had to wait until now to check for glColorMask(0,0,0,0) because of 1236f1e236987829393c81dc86ea19cb49eefe190317Brian Paul * the occlusion test. 1237f1e236987829393c81dc86ea19cb49eefe190317Brian Paul */ 1238f1e236987829393c81dc86ea19cb49eefe190317Brian Paul if (colorMask == 0x0) { 1239e5b244ff7f984805c1bcc020342f1300f2639c71Brian Paul span->interpMask = origInterpMask; 1240f1e236987829393c81dc86ea19cb49eefe190317Brian Paul span->arrayMask = origArrayMask; 1241f1e236987829393c81dc86ea19cb49eefe190317Brian Paul return; 124271340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 124371340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul 1244a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul /* If the alpha test isn't enabled, we're able to defer computing fragment 1245a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul * colors (by interpolation, texturing, fragment program) until now. 1246a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul * Hopefully, Z/stencil tests culled many of the fragments! 1247a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul */ 1248f1e236987829393c81dc86ea19cb49eefe190317Brian Paul if (!ctx->Color.AlphaEnabled) { 1249f1e236987829393c81dc86ea19cb49eefe190317Brian Paul /* Now we need the rgba array, fill it in if needed */ 1250f1e236987829393c81dc86ea19cb49eefe190317Brian Paul if ((span->interpMask & SPAN_RGBA) && (span->arrayMask & SPAN_RGBA) == 0) 1251f1e236987829393c81dc86ea19cb49eefe190317Brian Paul interpolate_colors(ctx, span); 125271340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul 1253a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul if (span->interpMask & SPAN_SPEC) 125436a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul interpolate_specular(ctx, span); 125536a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul 1256d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul if (span->interpMask & SPAN_FOG) 1257d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul interpolate_fog(ctx, span); 1258d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul 125947b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell if (ctx->FragmentProgram._Active) 1260e22540c2765e034fed558ea1d44488a03fbba170Brian Paul _swrast_exec_fragment_program( ctx, span ); 12617f752fed993e5e9423abac200dd59141edbada56Dave Airlie else if (ctx->ATIFragmentShader._Enabled) 12627f752fed993e5e9423abac200dd59141edbada56Dave Airlie _swrast_exec_fragment_shader( ctx, span ); 1263a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul else if (ctx->Texture._EnabledUnits) 1264610d59981a9f43fefe29b34ef19c184d28e2bef5Brian Paul _swrast_texture_span( ctx, span ); 126571340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 126671340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul 1267f1e236987829393c81dc86ea19cb49eefe190317Brian Paul ASSERT(span->arrayMask & SPAN_RGBA); 12682ef866d1fc0a5cc5ef8543d65744dfd4da4dbbafBrian Paul 12699d148e6b2be33fe7ac72aaa3be239dc1bc8878a9Keith Whitwell if (!ctx->FragmentProgram._Enabled) { 1270dfe508ca7af1a6d1099cd65e257512ed1e17d893Brian Paul /* Add base and specular colors */ 1271dfe508ca7af1a6d1099cd65e257512ed1e17d893Brian Paul if (ctx->Fog.ColorSumEnabled || 1272dfe508ca7af1a6d1099cd65e257512ed1e17d893Brian Paul (ctx->Light.Enabled && 1273dfe508ca7af1a6d1099cd65e257512ed1e17d893Brian Paul ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR)) { 1274dfe508ca7af1a6d1099cd65e257512ed1e17d893Brian Paul if (span->interpMask & SPAN_SPEC) { 1275dfe508ca7af1a6d1099cd65e257512ed1e17d893Brian Paul interpolate_specular(ctx, span); 1276dfe508ca7af1a6d1099cd65e257512ed1e17d893Brian Paul } 1277a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul if (span->arrayMask & SPAN_SPEC) { 1278a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul add_colors( span->end, span->array->rgba, span->array->spec ); 1279a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul } 1280a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul else { 1281a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul /* We probably added the base/specular colors during the 1282a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul * vertex stage! 1283a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul */ 1284a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul } 128571340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 128671340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 128771340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul 12886e1666437ea091ecc50ab2b56d87129318f641d2Brian Paul /* Fog */ 128909da0b8e6621a831e3eeb9381430f2bed18a22adBrian Paul if (swrast->_FogEnabled) { 129045bc887da226403f2c41077e40ca38b6f60f1359Brian Paul _swrast_fog_rgba_span(ctx, span); 129171340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 1292f1e236987829393c81dc86ea19cb49eefe190317Brian Paul 129371340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul /* Antialias coverage application */ 12942a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul if (span->arrayMask & SPAN_COVERAGE) { 129577df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul GLchan (*rgba)[4] = span->array->rgba; 129677df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul GLfloat *coverage = span->array->coverage; 129771340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul GLuint i; 129810f30eb43835c57c00783390a02d72daf4f78e26Brian Paul for (i = 0; i < span->end; i++) { 129977df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul rgba[i][ACOMP] = (GLchan) (rgba[i][ACOMP] * coverage[i]); 130071340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 130171340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 130271340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul 130371340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul if (swrast->_RasterMask & MULTI_DRAW_BIT) { 1304a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul /* need to do blend/logicop separately for each color buffer */ 1305733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul multi_write_rgba_span(ctx, span); 130671340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 130771340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul else { 130871340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul /* normal: write to exactly one buffer */ 1309e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0][0]; 1310e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul 131157857ca0925116d6d254fef7e705cfe0b650d77fBrian Paul if (ctx->Color._LogicOpEnabled) { 1312e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul _swrast_logicop_rgba_span(ctx, rb, span, span->array->rgba); 131371340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 131495e2c72fd52d87163eb543555345f115f050f3aaBrian Paul else if (ctx->Color.BlendEnabled) { 1315e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul _swrast_blend_span(ctx, rb, span, span->array->rgba); 131671340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 131771340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul 1318e5b244ff7f984805c1bcc020342f1300f2639c71Brian Paul /* Color component masking */ 1319f1e236987829393c81dc86ea19cb49eefe190317Brian Paul if (colorMask != 0xffffffff) { 1320e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul _swrast_mask_rgba_span(ctx, rb, span, span->array->rgba); 132171340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 132271340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul 1323a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul /* Finally, write the pixels to a color buffer */ 1324733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (span->arrayMask & SPAN_XY) { 1325733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* array of pixel coords */ 1326bb8b302dbce4f830d060efecd8a9f75b10e25abbBrian Paul ASSERT(rb->PutValues); 1327bb8b302dbce4f830d060efecd8a9f75b10e25abbBrian Paul ASSERT(rb->_BaseFormat == GL_RGB || rb->_BaseFormat == GL_RGBA); 1328bb8b302dbce4f830d060efecd8a9f75b10e25abbBrian Paul /* XXX check datatype */ 1329bb8b302dbce4f830d060efecd8a9f75b10e25abbBrian Paul rb->PutValues(ctx, rb, span->end, span->array->x, span->array->y, 1330bb8b302dbce4f830d060efecd8a9f75b10e25abbBrian Paul span->array->rgba, span->array->mask); 1331733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul } 1332733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul else { 1333733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* horizontal run of pixels */ 1334bb8b302dbce4f830d060efecd8a9f75b10e25abbBrian Paul ASSERT(rb->PutRow); 1335bb8b302dbce4f830d060efecd8a9f75b10e25abbBrian Paul ASSERT(rb->_BaseFormat == GL_RGB || rb->_BaseFormat == GL_RGBA); 1336bb8b302dbce4f830d060efecd8a9f75b10e25abbBrian Paul /* XXX check datatype */ 1337bb8b302dbce4f830d060efecd8a9f75b10e25abbBrian Paul rb->PutRow(ctx, rb, span->end, span->x, span->y, span->array->rgba, 1338bb8b302dbce4f830d060efecd8a9f75b10e25abbBrian Paul span->writeAll ? NULL : span->array->mask); 133971340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 134071340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 134171340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul 1342e5b244ff7f984805c1bcc020342f1300f2639c71Brian Paul span->interpMask = origInterpMask; 1343f1e236987829393c81dc86ea19cb49eefe190317Brian Paul span->arrayMask = origArrayMask; 134410f30eb43835c57c00783390a02d72daf4f78e26Brian Paul} 134510f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 1346e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 1347e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 134879c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/** 1349e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Read RGBA pixels from frame buffer. Clipping will be done to prevent 1350e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * reading ouside the buffer's boundaries. 1351e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */ 13525071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paulvoid 1353e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul_swrast_read_rgba_span( GLcontext *ctx, struct gl_renderbuffer *rb, 1354a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul GLuint n, GLint x, GLint y, GLchan rgba[][4] ) 1355e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell{ 1356e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul const GLint bufWidth = (GLint) rb->Width; 1357e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul const GLint bufHeight = (GLint) rb->Height; 1358a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul 1359a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul if (y < 0 || y >= bufHeight || x + (GLint) n < 0 || x >= bufWidth) { 1360e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* completely above, below, or right */ 1361e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul /* XXX maybe leave rgba values undefined? */ 13626ec6b845fdf3c44436028ad6fff9471d18928719Brian Paul _mesa_bzero(rgba, 4 * n * sizeof(GLchan)); 1363e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1364e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell else { 1365e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell GLint skip, length; 1366e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell if (x < 0) { 1367e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* left edge clippping */ 1368e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell skip = -x; 1369e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell length = (GLint) n - skip; 1370e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell if (length < 0) { 1371e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* completely left of window */ 1372e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell return; 1373e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1374a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul if (length > bufWidth) { 1375a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul length = bufWidth; 1376e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1377e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1378a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul else if ((GLint) (x + n) > bufWidth) { 1379e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* right edge clipping */ 1380e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell skip = 0; 1381a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul length = bufWidth - x; 1382e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell if (length < 0) { 1383e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* completely to right of window */ 1384e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell return; 1385e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1386e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1387e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell else { 1388e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* no clipping */ 1389e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell skip = 0; 1390e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell length = (GLint) n; 1391e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1392e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 1393bb8b302dbce4f830d060efecd8a9f75b10e25abbBrian Paul ASSERT(rb); 1394bb8b302dbce4f830d060efecd8a9f75b10e25abbBrian Paul ASSERT(rb->GetRow); 1395bb8b302dbce4f830d060efecd8a9f75b10e25abbBrian Paul ASSERT(rb->_BaseFormat == GL_RGB || rb->_BaseFormat == GL_RGBA); 1396bb8b302dbce4f830d060efecd8a9f75b10e25abbBrian Paul ASSERT(rb->DataType == GL_UNSIGNED_BYTE); 1397bb8b302dbce4f830d060efecd8a9f75b10e25abbBrian Paul rb->GetRow(ctx, rb, length, x + skip, y, rgba + skip); 1398e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1399e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell} 1400e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 1401e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 140279c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/** 1403e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Read CI pixels from frame buffer. Clipping will be done to prevent 1404e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * reading ouside the buffer's boundaries. 1405e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */ 14065071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paulvoid 1407e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul_swrast_read_index_span( GLcontext *ctx, struct gl_renderbuffer *rb, 1408e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul GLuint n, GLint x, GLint y, GLuint index[] ) 1409e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell{ 1410e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul const GLint bufWidth = (GLint) rb->Width; 1411e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul const GLint bufHeight = (GLint) rb->Height; 1412a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul 1413a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul if (y < 0 || y >= bufHeight || x + (GLint) n < 0 || x >= bufWidth) { 1414e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* completely above, below, or right */ 1415e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul _mesa_bzero(index, n * sizeof(GLuint)); 1416e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1417e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell else { 1418e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell GLint skip, length; 1419e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell if (x < 0) { 1420e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* left edge clippping */ 1421e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell skip = -x; 1422e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell length = (GLint) n - skip; 1423e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell if (length < 0) { 1424e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* completely left of window */ 1425e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell return; 1426e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1427a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul if (length > bufWidth) { 1428a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul length = bufWidth; 1429e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1430e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1431a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul else if ((GLint) (x + n) > bufWidth) { 1432e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* right edge clipping */ 1433e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell skip = 0; 1434a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul length = bufWidth - x; 1435e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell if (length < 0) { 1436e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* completely to right of window */ 1437e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell return; 1438e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1439e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1440e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell else { 1441e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* no clipping */ 1442e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell skip = 0; 1443e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell length = (GLint) n; 1444e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1445e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 1446e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul ASSERT(rb->GetRow); 1447e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul ASSERT(rb->_BaseFormat == GL_COLOR_INDEX); 1448e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul 1449e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul if (rb->DataType == GL_UNSIGNED_BYTE) { 1450e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul GLubyte index8[MAX_WIDTH]; 1451e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul GLint i; 1452e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul rb->GetRow(ctx, rb, length, x + skip, y, index8); 1453e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul for (i = 0; i < length; i++) 1454e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul index[skip + i] = index8[i]; 1455e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul } 1456e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul else if (rb->DataType == GL_UNSIGNED_SHORT) { 1457e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul GLushort index16[MAX_WIDTH]; 1458e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul GLint i; 1459e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul rb->GetRow(ctx, rb, length, x + skip, y, index16); 1460e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul for (i = 0; i < length; i++) 1461e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul index[skip + i] = index16[i]; 1462e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul } 1463e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul else if (rb->DataType == GL_UNSIGNED_INT) { 1464e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul rb->GetRow(ctx, rb, length, x + skip, y, index + skip); 1465e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul } 1466e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1467e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell} 1468