s_span.c revision 711e27fda27e4235b20a4cf73c2767c984ab2b81
1711e27fda27e4235b20a4cf73c2767c984ab2b81Brian Paul/* $Id: s_span.c,v 1.36 2002/02/17 17:30:57 brianp Exp $ */ 2e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 3e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell/* 4e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Mesa 3-D graphics library 59927f1978da8530416f699d084dda099720e43e6Brian Paul * Version: 4.1 622144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes * 79927f1978da8530416f699d084dda099720e43e6Brian Paul * Copyright (C) 1999-2002 Brian Paul All Rights Reserved. 822144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes * 9e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Permission is hereby granted, free of charge, to any person obtaining a 10e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * copy of this software and associated documentation files (the "Software"), 11e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * to deal in the Software without restriction, including without limitation 12e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * the rights to use, copy, modify, merge, publish, distribute, sublicense, 13e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * and/or sell copies of the Software, and to permit persons to whom the 14e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Software is furnished to do so, subject to the following conditions: 1522144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes * 16e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * The above copyright notice and this permission notice shall be included 17e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * in all copies or substantial portions of the Software. 1822144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes * 19e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 20e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 22e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 23e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 24e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */ 26e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 27e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 2879c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/** 29bcb148de9201c7f90a68c7c46434e7ebf7204000Brian Paul * \file swrast/s_span.c 3079c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul * \brief Span processing functions used by all rasterization functions. 3179c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul * This is where all the per-fragment tests are performed 3279c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul * \author Brian Paul 33e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */ 34e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 35e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "glheader.h" 36e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "colormac.h" 3771340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul#include "context.h" 38e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "macros.h" 39e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "mem.h" 40e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 41e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_alpha.h" 42e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_alphabuf.h" 43e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_blend.h" 44cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell#include "s_context.h" 45e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_depth.h" 46e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_fog.h" 47e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_logic.h" 48e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_masking.h" 49e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_span.h" 50e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_stencil.h" 51e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_texture.h" 52e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 532a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 5479c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/** 552a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul * Init span's Z interpolation values to the RasterPos Z. 562a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul * Used during setup for glDraw/CopyPixels. 572a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul */ 582a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paulvoid 592a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul_mesa_span_default_z( GLcontext *ctx, struct sw_span *span ) 602a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul{ 612a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul if (ctx->Visual.depthBits <= 16) 622a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->z = FloatToFixed(ctx->Current.RasterPos[2] * ctx->DepthMax); 632a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul else 642a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->z = (GLint) (ctx->Current.RasterPos[2] * ctx->DepthMax); 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 752a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul_mesa_span_default_fog( GLcontext *ctx, struct sw_span *span ) 762a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul{ 77c9ceef41fe89f5ba6e16ec51c1f9b7bfd8119c64Brian Paul span->fog = _mesa_z_to_fogfactor(ctx, ctx->Current.RasterDistance); 782a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->fogStep = 0; 792a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->interpMask |= SPAN_FOG; 802a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul} 812a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 822a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 8379c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/** 842a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul * Init span's color or index interpolation values to the RasterPos color. 852a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul * Used during setup for glDraw/CopyPixels. 862a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul */ 872a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paulvoid 882a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul_mesa_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 { 1142a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->index = IntToFixed(ctx->Current.RasterIndex); 1152a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->indexStep = 0; 1162a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->interpMask |= SPAN_INDEX; 1172a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 1182a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul} 1192a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 1202a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 1212a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul/* Fill in the span.color.rgba array from the interpolation values */ 1222a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paulstatic void 1232a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paulinterpolate_colors(GLcontext *ctx, struct sw_span *span) 1242a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul{ 1252a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfixed r = span->red; 1262a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfixed g = span->green; 1272a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfixed b = span->blue; 1282a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfixed a = span->alpha; 1292a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul const GLint dr = span->redStep; 1302a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul const GLint dg = span->greenStep; 1312a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul const GLint db = span->blueStep; 1322a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul const GLint da = span->alphaStep; 1332a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul const GLuint n = span->end; 1342a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLchan (*rgba)[4] = span->color.rgba; 1352a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLuint i; 1362a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 1372a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul ASSERT(span->interpMask & SPAN_RGBA); 1382a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 1392a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul if (span->interpMask & SPAN_FLAT) { 1402a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul /* constant color */ 1412a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLchan color[4]; 1422a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul color[RCOMP] = FixedToChan(r); 1432a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul color[GCOMP] = FixedToChan(g); 1442a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul color[BCOMP] = FixedToChan(b); 1452a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul color[ACOMP] = FixedToChan(a); 1462a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul for (i = 0; i < n; i++) { 1472a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul COPY_CHAN4(span->color.rgba[i], color); 1482a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 1492a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 1502a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul else { 1512a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul /* interpolate */ 1522a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul for (i = 0; i < n; i++) { 1532a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul rgba[i][RCOMP] = FixedToChan(r); 1542a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul rgba[i][GCOMP] = FixedToChan(g); 1552a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul rgba[i][BCOMP] = FixedToChan(b); 1562a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul rgba[i][ACOMP] = FixedToChan(a); 1572a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul r += dr; 1582a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul g += dg; 1592a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul b += db; 1602a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul a += da; 1612a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 1622a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 1632a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->arrayMask |= SPAN_RGBA; 1642a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul} 1652a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 1662a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 1672a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul/* Fill in the span.color.index array from the interpolation values */ 1682a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paulstatic void 1692a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paulinterpolate_indexes(GLcontext *ctx, struct sw_span *span) 1702a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul{ 1712a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfixed index = span->index; 1722a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul const GLint indexStep = span->indexStep; 1732a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul const GLuint n = span->end; 1742a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLuint *indexes = span->color.index; 1752a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLuint i; 1762a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul ASSERT(span->interpMask & SPAN_INDEX); 1772a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 1782a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul if ((span->interpMask & SPAN_FLAT) || (indexStep == 0)) { 1792a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul /* constant color */ 1802a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul index = FixedToInt(index); 1812a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul for (i = 0; i < n; i++) { 1822a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul indexes[i] = index; 1832a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 1842a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 1852a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul else { 1862a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul /* interpolate */ 1872a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul for (i = 0; i < n; i++) { 1882a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul indexes[i] = FixedToInt(index); 1892a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul index += indexStep; 1902a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 1912a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 1922a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->arrayMask |= SPAN_INDEX; 1932a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul} 1942a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 1952a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 1962a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul/* Fill in the span.specArray array from the interpolation values */ 1972a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paulstatic void 1982a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paulinterpolate_specular(GLcontext *ctx, struct sw_span *span) 1992a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul{ 2002a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul if (span->interpMask & SPAN_FLAT) { 2012a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul /* constant color */ 2022a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul const GLchan r = FixedToChan(span->specRed); 2032a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul const GLchan g = FixedToChan(span->specGreen); 2042a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul const GLchan b = FixedToChan(span->specBlue); 2052a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLuint i; 2062a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul for (i = 0; i < span->end; i++) { 2072a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->specArray[i][RCOMP] = r; 2082a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->specArray[i][GCOMP] = g; 2092a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->specArray[i][BCOMP] = b; 2102a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 2112a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 2122a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul else { 2132a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul /* interpolate */ 2142a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul#if CHAN_TYPE == GL_FLOAT 2152a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat r = span->specRed; 2162a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat g = span->specGreen; 2172a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat b = span->specBlue; 2182a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul#else 2192a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfixed r = span->specRed; 2202a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfixed g = span->specGreen; 2212a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfixed b = span->specBlue; 2222a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul#endif 2232a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLuint i; 2242a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul for (i = 0; i < span->end; i++) { 2252a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->specArray[i][RCOMP] = FixedToChan(r); 2262a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->specArray[i][GCOMP] = FixedToChan(g); 2272a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->specArray[i][BCOMP] = FixedToChan(b); 2282a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul r += span->specRedStep; 2292a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul g += span->specGreenStep; 2302a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul b += span->specBlueStep; 2312a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 2322a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 2332a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->arrayMask |= SPAN_SPEC; 2342a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul} 2352a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 2362a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 2372a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul/* Fill in the span.zArray array from the interpolation values */ 238711e27fda27e4235b20a4cf73c2767c984ab2b81Brian Paulvoid 239711e27fda27e4235b20a4cf73c2767c984ab2b81Brian Paul_mesa_span_interpolate_z( const GLcontext *ctx, struct sw_span *span ) 2402a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul{ 2412a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul const GLuint n = span->end; 2422a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLuint i; 2432a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 2442a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul ASSERT(span->interpMask & SPAN_Z); 2452a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 2462a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul if (ctx->Visual.depthBits <= 16) { 2472a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfixed zval = span->z; 2482a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul for (i = 0; i < n; i++) { 2492a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->zArray[i] = FixedToInt(zval); 2502a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul zval += span->zStep; 2512a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 2522a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 2532a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul else { 2542a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul /* Deep Z buffer, no fixed->int shift */ 2552a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfixed zval = span->z; 2562a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul for (i = 0; i < n; i++) { 2572a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->zArray[i] = zval; 2582a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul zval += span->zStep; 2592a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 2602a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 2612a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->arrayMask |= SPAN_Z; 2622a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul} 2632a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 2642a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 265c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul/* 266c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul * Return log_base_2(x) / 2. 267c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul * We divide by two here since we didn't square rho in the triangle function. 268c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul */ 269c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul#ifdef USE_IEEE 270c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul 271c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul#if 0 272c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul/* This is pretty fast, but not accurate enough (only 2 fractional bits). 273c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul * Based on code from http://www.stereopsis.com/log2.html 274c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul */ 275c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paulstatic INLINE GLfloat HALF_LOG2(GLfloat x) 276c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul{ 277c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul const GLfloat y = x * x * x * x; 278c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul const GLuint ix = *((GLuint *) &y); 279c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul const GLuint exp = (ix >> 23) & 0xFF; 280c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul const GLint log2 = ((GLint) exp) - 127; 281c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul return (GLfloat) log2 * (0.5 / 4.0); /* 4, because of x^4 above */ 282c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul} 283c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul#endif 284c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul 285c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul/* Pretty fast, and accurate. 286c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul * Based on code from http://www.flipcode.com/totd/ 287c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul */ 288c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paulstatic INLINE GLfloat HALF_LOG2(GLfloat val) 289c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul{ 290c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul GLint *exp_ptr = (GLint *) &val; 291c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul GLint x = *exp_ptr; 292c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul const GLint log_2 = ((x >> 23) & 255) - 128; 293c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul x &= ~(255 << 23); 294c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul x += 127 << 23; 295c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul *exp_ptr = x; 296c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul val = ((-1.0f/3) * val + 2) * val - 2.0f/3; 297c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul return 0.5F * (val + log_2); 298c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul} 299c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul 300c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul#else /* USE_IEEE */ 301c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul 302c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul/* Slow, portable solution. 303c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul * NOTE: log_base_2(x) = log(x) / log(2) 304c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul * NOTE: 1.442695 = 1/log(2). 305c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul */ 306c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul#define HALF_LOG2(x) ((GLfloat) (log(x) * (1.442695F * 0.5F))) 3072a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 308c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul#endif /* USE_IEEE */ 309c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul 310c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul 311c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul 312c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul/* 313c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul * Fill in the span.texcoords array from the interpolation values. 314c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul * XXX We could optimize here for the case when dq = 0. That would 315c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul * usually be the case when using an orthographic projection. 316c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul */ 3172a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paulstatic void 3182a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paulinterpolate_texcoords(GLcontext *ctx, struct sw_span *span) 3192a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul{ 3202a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul ASSERT(span->interpMask & SPAN_TEXTURE); 3212a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 3222a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul if (ctx->Texture._ReallyEnabled & ~TEXTURE0_ANY) { 3232a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul if (span->interpMask & SPAN_LAMBDA) { 3242a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul /* multitexture, lambda */ 3252a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLuint u; 3262a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { 3272a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul if (ctx->Texture.Unit[u]._ReallyEnabled) { 328c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul const GLfloat rho = span->rho[u]; 3292a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul const GLfloat ds = span->texStep[u][0]; 3302a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul const GLfloat dt = span->texStep[u][1]; 3312a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul const GLfloat dr = span->texStep[u][2]; 3322a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul const GLfloat dq = span->texStep[u][3]; 3332a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat s = span->tex[u][0]; 3342a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat t = span->tex[u][1]; 3352a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat r = span->tex[u][2]; 3362a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat q = span->tex[u][3]; 3372a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLuint i; 338c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul if (dq == 0.0) { 339c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul /* Ortho projection or polygon's parallel to window X axis */ 3402a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q); 341c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul const GLfloat lambda = HALF_LOG2(rho * invQ * invQ); 342c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul for (i = 0; i < span->end; i++) { 343c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul span->texcoords[u][i][0] = s * invQ; 344c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul span->texcoords[u][i][1] = t * invQ; 345c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul span->texcoords[u][i][2] = r * invQ; 346c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul span->lambda[u][i] = lambda; 347c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul s += ds; 348c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul t += dt; 349c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul r += dr; 350c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul } 351c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul } 352c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul else { 353c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul for (i = 0; i < span->end; i++) { 354c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q); 355c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul span->texcoords[u][i][0] = s * invQ; 356c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul span->texcoords[u][i][1] = t * invQ; 357c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul span->texcoords[u][i][2] = r * invQ; 358c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul span->lambda[u][i] = HALF_LOG2(rho * invQ * invQ); 359c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul s += ds; 360c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul t += dt; 361c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul r += dr; 362c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul q += dq; 363c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul } 3642a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 3652a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 3662a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 3672a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->arrayMask |= SPAN_LAMBDA; 3682a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 3692a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul else { 3702a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul /* multitexture, no lambda */ 3712a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLuint u; 3722a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { 3732a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul if (ctx->Texture.Unit[u]._ReallyEnabled) { 3742a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul const GLfloat ds = span->texStep[u][0]; 3752a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul const GLfloat dt = span->texStep[u][1]; 3762a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul const GLfloat dr = span->texStep[u][2]; 3772a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul const GLfloat dq = span->texStep[u][3]; 3782a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat s = span->tex[u][0]; 3792a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat t = span->tex[u][1]; 3802a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat r = span->tex[u][2]; 3812a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat q = span->tex[u][3]; 3822a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLuint i; 383c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul if (dq == 0.0) { 384c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul /* Ortho projection or polygon's parallel to window X axis */ 3852a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q); 386c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul for (i = 0; i < span->end; i++) { 387c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul span->texcoords[u][i][0] = s * invQ; 388c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul span->texcoords[u][i][1] = t * invQ; 389c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul span->texcoords[u][i][2] = r * invQ; 390c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul s += ds; 391c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul t += dt; 392c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul r += dr; 393c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul } 394c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul } 395c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul else { 396c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul for (i = 0; i < span->end; i++) { 397c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q); 398c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul span->texcoords[u][i][0] = s * invQ; 399c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul span->texcoords[u][i][1] = t * invQ; 400c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul span->texcoords[u][i][2] = r * invQ; 401c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul s += ds; 402c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul t += dt; 403c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul r += dr; 404c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul q += dq; 405c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul } 4062a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 4072a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 4082a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 4092a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 4102a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 4112a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul else { 4122a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul if (span->interpMask & SPAN_LAMBDA) { 4132a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul /* just texture unit 0, with lambda */ 414c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul const GLfloat rho = span->rho[0]; 4152a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul const GLfloat ds = span->texStep[0][0]; 4162a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul const GLfloat dt = span->texStep[0][1]; 4172a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul const GLfloat dr = span->texStep[0][2]; 4182a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul const GLfloat dq = span->texStep[0][3]; 4192a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat s = span->tex[0][0]; 4202a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat t = span->tex[0][1]; 4212a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat r = span->tex[0][2]; 4222a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat q = span->tex[0][3]; 4232a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLuint i; 424c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul if (dq == 0.0) { 425c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul /* Ortho projection or polygon's parallel to window X axis */ 4262a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q); 427c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul const GLfloat lambda = HALF_LOG2(rho * invQ * invQ); 428c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul for (i = 0; i < span->end; i++) { 429c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul span->texcoords[0][i][0] = s * invQ; 430c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul span->texcoords[0][i][1] = t * invQ; 431c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul span->texcoords[0][i][2] = r * invQ; 432c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul span->lambda[0][i] = lambda; 433c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul s += ds; 434c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul t += dt; 435c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul r += dr; 436c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul } 437c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul } 438c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul else { 439c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul for (i = 0; i < span->end; i++) { 440c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q); 441c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul span->texcoords[0][i][0] = s * invQ; 442c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul span->texcoords[0][i][1] = t * invQ; 443c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul span->texcoords[0][i][2] = r * invQ; 444c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul span->lambda[0][i] = HALF_LOG2(rho * invQ * invQ); 445c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul s += ds; 446c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul t += dt; 447c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul r += dr; 448c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul q += dq; 449c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul } 4502a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 4512a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->arrayMask |= SPAN_LAMBDA; 4522a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 4532a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul else { 454733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* just texture 0, without lambda */ 4552a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul const GLfloat ds = span->texStep[0][0]; 4562a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul const GLfloat dt = span->texStep[0][1]; 4572a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul const GLfloat dr = span->texStep[0][2]; 4582a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul const GLfloat dq = span->texStep[0][3]; 4592a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat s = span->tex[0][0]; 4602a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat t = span->tex[0][1]; 4612a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat r = span->tex[0][2]; 4622a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat q = span->tex[0][3]; 4632a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLuint i; 464c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul if (dq == 0.0) { 465c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul /* Ortho projection or polygon's parallel to window X axis */ 4662a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q); 467c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul for (i = 0; i < span->end; i++) { 468c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul span->texcoords[0][i][0] = s * invQ; 469c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul span->texcoords[0][i][1] = t * invQ; 470c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul span->texcoords[0][i][2] = r * invQ; 471c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul s += ds; 472c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul t += dt; 473c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul r += dr; 474c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul } 475c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul } 476c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul else { 477c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul for (i = 0; i < span->end; i++) { 478c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q); 479c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul span->texcoords[0][i][0] = s * invQ; 480c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul span->texcoords[0][i][1] = t * invQ; 481c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul span->texcoords[0][i][2] = r * invQ; 482c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul s += ds; 483c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul t += dt; 484c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul r += dr; 485c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul q += dq; 486c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul } 4872a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 4882a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 4892a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 49010f30eb43835c57c00783390a02d72daf4f78e26Brian Paul} 491e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 492e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 49379c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/** 494e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Apply the current polygon stipple pattern to a span of pixels. 495e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */ 4965071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paulstatic void 497733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paulstipple_polygon_span( GLcontext *ctx, struct sw_span *span ) 49810f30eb43835c57c00783390a02d72daf4f78e26Brian Paul{ 49910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul const GLuint highbit = 0x80000000; 500733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul const GLuint stipple = ctx->PolygonStipple[span->y % 32]; 501733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul GLuint i, m; 502733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul 503733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul ASSERT(ctx->Polygon.StippleFlag); 504733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul ASSERT((span->arrayMask & SPAN_XY) == 0); 50510f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 50610f30eb43835c57c00783390a02d72daf4f78e26Brian Paul m = highbit >> (GLuint) (span->x % 32); 50710f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 50810f30eb43835c57c00783390a02d72daf4f78e26Brian Paul for (i = 0; i < span->end; i++) { 50910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul if ((m & stipple) == 0) { 51010f30eb43835c57c00783390a02d72daf4f78e26Brian Paul span->mask[i] = 0; 51110f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 51210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul m = m >> 1; 51310f30eb43835c57c00783390a02d72daf4f78e26Brian Paul if (m == 0) { 51410f30eb43835c57c00783390a02d72daf4f78e26Brian Paul m = highbit; 51510f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 51610f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 5172ef866d1fc0a5cc5ef8543d65744dfd4da4dbbafBrian Paul span->writeAll = GL_FALSE; 51810f30eb43835c57c00783390a02d72daf4f78e26Brian Paul} 51910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 520e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 52179c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/** 522733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul * Clip a pixel span to the current buffer/window boundaries: 523733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul * DrawBuffer->_Xmin, _Xmax, _Ymin, _Ymax. This will accomplish 524733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul * window clipping and scissoring. 525733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul * Return: GL_TRUE some pixels still visible 52610f30eb43835c57c00783390a02d72daf4f78e26Brian Paul * GL_FALSE nothing visible 52710f30eb43835c57c00783390a02d72daf4f78e26Brian Paul */ 52810f30eb43835c57c00783390a02d72daf4f78e26Brian Paulstatic GLuint 529733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paulclip_span( GLcontext *ctx, struct sw_span *span ) 53010f30eb43835c57c00783390a02d72daf4f78e26Brian Paul{ 531733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul const GLint xmin = ctx->DrawBuffer->_Xmin; 532733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul const GLint xmax = ctx->DrawBuffer->_Xmax; 533733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul const GLint ymin = ctx->DrawBuffer->_Ymin; 534733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul const GLint ymax = ctx->DrawBuffer->_Ymax; 535733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul 536733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (span->arrayMask & SPAN_XY) { 537733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* arrays of x/y pixel coords */ 538733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul const GLint *x = span->xArray; 539733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul const GLint *y = span->yArray; 540733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul const GLint n = span->end; 541733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul GLubyte *mask = span->mask; 542733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul GLint i; 543b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul if (span->arrayMask & SPAN_MASK) { 544b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul /* note: using & intead of && to reduce branches */ 545b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul for (i = 0; i < n; i++) { 546b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul mask[i] &= (x[i] >= xmin) & (x[i] < xmax) 547b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul & (y[i] >= ymin) & (y[i] < ymax); 548b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul } 549b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul } 550b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul else { 551b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul /* note: using & intead of && to reduce branches */ 552b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul for (i = 0; i < n; i++) { 553b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul mask[i] = (x[i] >= xmin) & (x[i] < xmax) 554b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul & (y[i] >= ymin) & (y[i] < ymax); 555b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul } 55610f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 557733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul return GL_TRUE; /* some pixels visible */ 55810f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 559733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul else { 560733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* horizontal span of pixels */ 561733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul const GLint x = span->x; 562733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul const GLint y = span->y; 563733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul const GLint n = span->end; 564733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul 565733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* Trivial rejection tests */ 566733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (y < ymin || y >= ymax || x + n <= xmin || x >= xmax) { 567733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->end = 0; 568733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul return GL_FALSE; /* all pixels clipped */ 569733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul } 57010f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 571733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* Clip to the left */ 572733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (x < xmin) { 573733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul ASSERT(x + n > xmin); 574733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->writeAll = GL_FALSE; 575733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul BZERO(span->mask, (xmin - x) * sizeof(GLubyte)); 57610f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 577733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul 578733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* Clip to right */ 579733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (x + n > xmax) { 580733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul ASSERT(x < xmax); 581733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->end = xmax - x; 58210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 58310f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 584733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul return GL_TRUE; /* some pixels visible */ 585733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul } 58610f30eb43835c57c00783390a02d72daf4f78e26Brian Paul} 58710f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 58810f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 589e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 59079c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/** 591e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Draw to more than one color buffer (or none). 592e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */ 5935071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paulstatic void 594733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paulmulti_write_index_span( GLcontext *ctx, struct sw_span *span ) 595e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell{ 596709892459922a32096fe9dd8261d0d92337bb02fKeith Whitwell SWcontext *swrast = SWRAST_CONTEXT(ctx); 597e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell GLuint bufferBit; 598e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 599e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* loop over four possible dest color buffers */ 600e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell for (bufferBit = 1; bufferBit <= 8; bufferBit = bufferBit << 1) { 601e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell if (bufferBit & ctx->Color.DrawDestMask) { 602e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell GLuint indexTmp[MAX_WIDTH]; 603733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul ASSERT(span->end < MAX_WIDTH); 604e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 605e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell if (bufferBit == FRONT_LEFT_BIT) 606e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell (void) (*ctx->Driver.SetDrawBuffer)( ctx, GL_FRONT_LEFT); 607e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell else if (bufferBit == FRONT_RIGHT_BIT) 608e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell (void) (*ctx->Driver.SetDrawBuffer)( ctx, GL_FRONT_RIGHT); 609e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell else if (bufferBit == BACK_LEFT_BIT) 610e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell (void) (*ctx->Driver.SetDrawBuffer)( ctx, GL_BACK_LEFT); 611e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell else 612e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell (void) (*ctx->Driver.SetDrawBuffer)( ctx, GL_BACK_RIGHT); 613e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 614e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* make copy of incoming indexes */ 615733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul MEMCPY( indexTmp, span->color.index, span->end * sizeof(GLuint) ); 616733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul 617e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell if (ctx->Color.IndexLogicOpEnabled) { 618733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul _mesa_logicop_ci_span(ctx, span, indexTmp); 619e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 620733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul 6217956292a765910077f50352d7cd0174e1e66d26cBrian Paul if (ctx->Color.IndexMask != 0xffffffff) { 622733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul _mesa_mask_index_span(ctx, span, indexTmp); 623733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul } 624733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul 625733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (span->arrayMask & SPAN_XY) { 626733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* array of pixel coords */ 627733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul (*swrast->Driver.WriteCI32Pixels)(ctx, span->end, 628733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->xArray, span->yArray, 629733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul indexTmp, span->mask); 630733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul } 631733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul else { 632733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* horizontal run of pixels */ 633733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul (*swrast->Driver.WriteCI32Span)(ctx, span->end, span->x, span->y, 634733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul indexTmp, span->mask); 635e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 636e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 637e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 638e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 639e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* restore default dest buffer */ 640e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell (void) (*ctx->Driver.SetDrawBuffer)( ctx, ctx->Color.DriverDrawBuffer); 641e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell} 642e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 643e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 64479c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/** 64510f30eb43835c57c00783390a02d72daf4f78e26Brian Paul * Draw to more than one RGBA color buffer (or none). 646f1e236987829393c81dc86ea19cb49eefe190317Brian Paul * All fragment operations, up to (but not) blending/logicop should 647f1e236987829393c81dc86ea19cb49eefe190317Brian Paul * have been done first. 64810f30eb43835c57c00783390a02d72daf4f78e26Brian Paul */ 64910f30eb43835c57c00783390a02d72daf4f78e26Brian Paulstatic void 650733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paulmulti_write_rgba_span( GLcontext *ctx, struct sw_span *span ) 65110f30eb43835c57c00783390a02d72daf4f78e26Brian Paul{ 65210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul const GLuint colorMask = *((GLuint *) ctx->Color.ColorMask); 65310f30eb43835c57c00783390a02d72daf4f78e26Brian Paul GLuint bufferBit; 65410f30eb43835c57c00783390a02d72daf4f78e26Brian Paul SWcontext *swrast = SWRAST_CONTEXT(ctx); 65510f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 656733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul ASSERT(colorMask != 0x0); 657733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul 65810f30eb43835c57c00783390a02d72daf4f78e26Brian Paul if (ctx->Color.DrawBuffer == GL_NONE) 65910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul return; 66010f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 66110f30eb43835c57c00783390a02d72daf4f78e26Brian Paul /* loop over four possible dest color buffers */ 66210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul for (bufferBit = 1; bufferBit <= 8; bufferBit = bufferBit << 1) { 66310f30eb43835c57c00783390a02d72daf4f78e26Brian Paul if (bufferBit & ctx->Color.DrawDestMask) { 66410f30eb43835c57c00783390a02d72daf4f78e26Brian Paul GLchan rgbaTmp[MAX_WIDTH][4]; 665733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul ASSERT(span->end < MAX_WIDTH); 66610f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 66710f30eb43835c57c00783390a02d72daf4f78e26Brian Paul if (bufferBit == FRONT_LEFT_BIT) { 66810f30eb43835c57c00783390a02d72daf4f78e26Brian Paul (void) (*ctx->Driver.SetDrawBuffer)( ctx, GL_FRONT_LEFT); 66910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul ctx->DrawBuffer->Alpha = ctx->DrawBuffer->FrontLeftAlpha; 67010f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 67110f30eb43835c57c00783390a02d72daf4f78e26Brian Paul else if (bufferBit == FRONT_RIGHT_BIT) { 67210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul (void) (*ctx->Driver.SetDrawBuffer)( ctx, GL_FRONT_RIGHT); 67310f30eb43835c57c00783390a02d72daf4f78e26Brian Paul ctx->DrawBuffer->Alpha = ctx->DrawBuffer->FrontRightAlpha; 67410f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 67510f30eb43835c57c00783390a02d72daf4f78e26Brian Paul else if (bufferBit == BACK_LEFT_BIT) { 67610f30eb43835c57c00783390a02d72daf4f78e26Brian Paul (void) (*ctx->Driver.SetDrawBuffer)( ctx, GL_BACK_LEFT); 67710f30eb43835c57c00783390a02d72daf4f78e26Brian Paul ctx->DrawBuffer->Alpha = ctx->DrawBuffer->BackLeftAlpha; 67810f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 67910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul else { 68010f30eb43835c57c00783390a02d72daf4f78e26Brian Paul (void) (*ctx->Driver.SetDrawBuffer)( ctx, GL_BACK_RIGHT); 68110f30eb43835c57c00783390a02d72daf4f78e26Brian Paul ctx->DrawBuffer->Alpha = ctx->DrawBuffer->BackRightAlpha; 68210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 68310f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 68410f30eb43835c57c00783390a02d72daf4f78e26Brian Paul /* make copy of incoming colors */ 685733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul MEMCPY( rgbaTmp, span->color.rgba, 4 * span->end * sizeof(GLchan) ); 68610f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 68710f30eb43835c57c00783390a02d72daf4f78e26Brian Paul if (ctx->Color.ColorLogicOpEnabled) { 688733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul _mesa_logicop_rgba_span(ctx, span, rgbaTmp); 68910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 69010f30eb43835c57c00783390a02d72daf4f78e26Brian Paul else if (ctx->Color.BlendEnabled) { 691733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul _mesa_blend_span(ctx, span, rgbaTmp); 69210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 693733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul 694733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (colorMask != 0xffffffff) { 695733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul _mesa_mask_rgba_span(ctx, span, rgbaTmp); 69610f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 69710f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 698733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (span->arrayMask & SPAN_XY) { 699733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* array of pixel coords */ 700733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul (*swrast->Driver.WriteRGBAPixels)(ctx, span->end, 701733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->xArray, span->yArray, 702733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul (const GLchan (*)[4]) rgbaTmp, 703733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->mask); 704733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (SWRAST_CONTEXT(ctx)->_RasterMask & ALPHABUF_BIT) { 705733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul _mesa_write_alpha_pixels(ctx, span->end, 706733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->xArray, span->yArray, 707733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul (const GLchan (*)[4]) rgbaTmp, 708733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->mask); 709733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul } 710733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul } 711733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul else { 712733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* horizontal run of pixels */ 713733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul (*swrast->Driver.WriteRGBASpan)(ctx, span->end, span->x, span->y, 714733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul (const GLchan (*)[4]) rgbaTmp, 715733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->mask); 716733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (swrast->_RasterMask & ALPHABUF_BIT) { 717733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul _mesa_write_alpha_span(ctx, span->end, span->x, span->y, 718733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul (const GLchan (*)[4]) rgbaTmp, 719733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->mask); 720733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul } 72110f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 72210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 72310f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 72410f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 72510f30eb43835c57c00783390a02d72daf4f78e26Brian Paul /* restore default dest buffer */ 72610f30eb43835c57c00783390a02d72daf4f78e26Brian Paul (void) (*ctx->Driver.SetDrawBuffer)( ctx, ctx->Color.DriverDrawBuffer ); 72710f30eb43835c57c00783390a02d72daf4f78e26Brian Paul} 72810f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 72910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 730e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 73179c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/** 7327956292a765910077f50352d7cd0174e1e66d26cBrian Paul * This function may modify any of the array values in the span. 7337956292a765910077f50352d7cd0174e1e66d26cBrian Paul * span->interpMask and span->arrayMask may be changed but will be restored 7347956292a765910077f50352d7cd0174e1e66d26cBrian Paul * to their original values before returning. 73510f30eb43835c57c00783390a02d72daf4f78e26Brian Paul */ 73610f30eb43835c57c00783390a02d72daf4f78e26Brian Paulvoid 7372a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul_mesa_write_index_span( GLcontext *ctx, struct sw_span *span, 7382a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLenum primitive) 73910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul{ 74010f30eb43835c57c00783390a02d72daf4f78e26Brian Paul SWcontext *swrast = SWRAST_CONTEXT(ctx); 7417956292a765910077f50352d7cd0174e1e66d26cBrian Paul const GLuint origInterpMask = span->interpMask; 7422a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul const GLuint origArrayMask = span->arrayMask; 74310f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 744733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul ASSERT(span->end <= MAX_WIDTH); 745733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul ASSERT((span->interpMask | span->arrayMask) & SPAN_INDEX); 7467956292a765910077f50352d7cd0174e1e66d26cBrian Paul ASSERT((span->interpMask & span->arrayMask) == 0); 7477956292a765910077f50352d7cd0174e1e66d26cBrian Paul 748733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (span->arrayMask & SPAN_MASK) { 749733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* mask was initialized by caller, probably glBitmap */ 750733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->writeAll = GL_FALSE; 751733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul } 752733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul else { 753733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul MEMSET(span->mask, 1, span->end); 754733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->writeAll = GL_TRUE; 75510f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 75610f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 757733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* Clipping */ 758733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if ((swrast->_RasterMask & CLIP_BIT) || (primitive == GL_BITMAP) 759b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul || (primitive == GL_POINT) || (primitive == GL_LINE)) { 760733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (!clip_span(ctx, span)) { 76186ca15ece74ccb5a8f4d566a4b2c8024b178d73bBrian Paul return; 762e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 763e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 764e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 765b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul#ifdef DEBUG 766b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul if (span->arrayMask & SPAN_XY) { 767b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul int i; 768b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul for (i = 0; i < span->end; i++) { 769b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul if (span->mask[i]) { 770b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul assert(span->xArray[i] >= ctx->DrawBuffer->_Xmin); 771b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul assert(span->xArray[i] < ctx->DrawBuffer->_Xmax); 772b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul assert(span->yArray[i] >= ctx->DrawBuffer->_Ymin); 773b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul assert(span->yArray[i] < ctx->DrawBuffer->_Ymax); 774b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul } 775b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul } 776b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul } 777b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul#endif 778b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul 779e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* Polygon Stippling */ 780733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (ctx->Polygon.StippleFlag && primitive == GL_POLYGON) { 78110f30eb43835c57c00783390a02d72daf4f78e26Brian Paul stipple_polygon_span(ctx, span); 782e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 783e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 7847956292a765910077f50352d7cd0174e1e66d26cBrian Paul /* Depth test and stencil */ 7857956292a765910077f50352d7cd0174e1e66d26cBrian Paul if (ctx->Depth.Test || ctx->Stencil.Enabled) { 7867956292a765910077f50352d7cd0174e1e66d26cBrian Paul if (span->interpMask & SPAN_Z) 787711e27fda27e4235b20a4cf73c2767c984ab2b81Brian Paul _mesa_span_interpolate_z(ctx, span); 78810f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 7897956292a765910077f50352d7cd0174e1e66d26cBrian Paul if (ctx->Stencil.Enabled) { 79079c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul if (!_mesa_stencil_and_ztest_span(ctx, span)) { 7917956292a765910077f50352d7cd0174e1e66d26cBrian Paul span->arrayMask = origArrayMask; 7927956292a765910077f50352d7cd0174e1e66d26cBrian Paul return; 7937956292a765910077f50352d7cd0174e1e66d26cBrian Paul } 7942a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 7957956292a765910077f50352d7cd0174e1e66d26cBrian Paul else { 7967956292a765910077f50352d7cd0174e1e66d26cBrian Paul ASSERT(ctx->Depth.Test); 79779c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul if (!_mesa_depth_test_span(ctx, span)) { 7987956292a765910077f50352d7cd0174e1e66d26cBrian Paul span->arrayMask = origArrayMask; 7997956292a765910077f50352d7cd0174e1e66d26cBrian Paul return; 8007956292a765910077f50352d7cd0174e1e66d26cBrian Paul } 8012a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 80210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 80310f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 80410f30eb43835c57c00783390a02d72daf4f78e26Brian Paul /* if we get here, something passed the depth test */ 80510f30eb43835c57c00783390a02d72daf4f78e26Brian Paul ctx->OcclusionResult = GL_TRUE; 80610f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 8077956292a765910077f50352d7cd0174e1e66d26cBrian Paul /* we have to wait until after occlusion to do this test */ 8087956292a765910077f50352d7cd0174e1e66d26cBrian Paul if (ctx->Color.DrawBuffer == GL_NONE || ctx->Color.IndexMask == 0) { 80910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul /* write no pixels */ 8102a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->arrayMask = origArrayMask; 81110f30eb43835c57c00783390a02d72daf4f78e26Brian Paul return; 81210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 81310f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 8147956292a765910077f50352d7cd0174e1e66d26cBrian Paul /* Interpolate the color indexes if needed */ 8157956292a765910077f50352d7cd0174e1e66d26cBrian Paul if (span->interpMask & SPAN_INDEX) { 8162a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul interpolate_indexes(ctx, span); 8177956292a765910077f50352d7cd0174e1e66d26cBrian Paul /* clear the bit - this allows the WriteMonoCISpan optimization below */ 8187956292a765910077f50352d7cd0174e1e66d26cBrian Paul span->interpMask &= ~SPAN_INDEX; 8197956292a765910077f50352d7cd0174e1e66d26cBrian Paul } 82010f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 8217956292a765910077f50352d7cd0174e1e66d26cBrian Paul /* Fog */ 8222a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul if (ctx->Fog.Enabled) { 823711e27fda27e4235b20a4cf73c2767c984ab2b81Brian Paul _mesa_fog_ci_span(ctx, span); 824e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 825e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 8262a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul /* Antialias coverage application */ 8272a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul if (span->arrayMask & SPAN_COVERAGE) { 8282a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLuint i; 8297956292a765910077f50352d7cd0174e1e66d26cBrian Paul GLuint *index = span->color.index; 83010f30eb43835c57c00783390a02d72daf4f78e26Brian Paul for (i = 0; i < span->end; i++) { 8312a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul ASSERT(span->coverage[i] < 16); 8322a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul index[i] = (index[i] & ~0xf) | ((GLuint) (span->coverage[i])); 8335071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paul } 8342a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 8355071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paul 8362a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul if (swrast->_RasterMask & MULTI_DRAW_BIT) { 8372a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul /* draw to zero or two or more buffers */ 838733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul multi_write_index_span(ctx, span); 839e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 840e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell else { 8412a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul /* normal situation: draw to exactly one buffer */ 8422a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul if (ctx->Color.IndexLogicOpEnabled) { 843733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul _mesa_logicop_ci_span(ctx, span, span->color.index); 84410f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 8452a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 8467956292a765910077f50352d7cd0174e1e66d26cBrian Paul if (ctx->Color.IndexMask != 0xffffffff) { 847733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul _mesa_mask_index_span(ctx, span, span->color.index); 848e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 8492a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 8502a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul /* write pixels */ 851733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (span->arrayMask & SPAN_XY) { 852733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* array of pixel coords */ 853733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if ((span->interpMask & SPAN_INDEX) && span->indexStep == 0) { 854733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* all pixels have same color index */ 855733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul (*swrast->Driver.WriteMonoCIPixels)(ctx, span->end, 856733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->xArray, span->yArray, 857733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul FixedToInt(span->index), 858733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->mask); 859733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul } 860733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul else { 861733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul (*swrast->Driver.WriteCI32Pixels)(ctx, span->end, span->xArray, 862733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->yArray, span->color.index, 863733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->mask ); 864733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul } 8657956292a765910077f50352d7cd0174e1e66d26cBrian Paul } 8667956292a765910077f50352d7cd0174e1e66d26cBrian Paul else { 867733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* horizontal run of pixels */ 868733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if ((span->interpMask & SPAN_INDEX) && span->indexStep == 0) { 869733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* all pixels have same color index */ 870733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul (*swrast->Driver.WriteMonoCISpan)(ctx, span->end, span->x, span->y, 871733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul FixedToInt(span->index), 872733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->mask); 873733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul } 874733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul else { 875733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul (*swrast->Driver.WriteCI32Span)(ctx, span->end, span->x, span->y, 876733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->color.index, span->mask); 877733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul } 8787956292a765910077f50352d7cd0174e1e66d26cBrian Paul } 879e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 8802a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 8817956292a765910077f50352d7cd0174e1e66d26cBrian Paul span->interpMask = origInterpMask; 8822a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->arrayMask = origArrayMask; 883e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell} 884e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 885e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 88679c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/** 8877956292a765910077f50352d7cd0174e1e66d26cBrian Paul * This function may modify any of the array values in the span. 8887956292a765910077f50352d7cd0174e1e66d26cBrian Paul * span->interpMask and span->arrayMask may be changed but will be restored 8897956292a765910077f50352d7cd0174e1e66d26cBrian Paul * to their original values before returning. 8905d2621928823a06006c1586efe78fe8bf65a7e1fBrian Paul */ 8915071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paulvoid 89210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul_mesa_write_rgba_span( GLcontext *ctx, struct sw_span *span, 8932a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLenum primitive) 894e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell{ 895cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell SWcontext *swrast = SWRAST_CONTEXT(ctx); 8967956292a765910077f50352d7cd0174e1e66d26cBrian Paul const GLuint colorMask = *((GLuint *) ctx->Color.ColorMask); 8977956292a765910077f50352d7cd0174e1e66d26cBrian Paul const GLuint origInterpMask = span->interpMask; 8982a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul const GLuint origArrayMask = span->arrayMask; 8997956292a765910077f50352d7cd0174e1e66d26cBrian Paul GLboolean monoColor; 9007956292a765910077f50352d7cd0174e1e66d26cBrian Paul 901733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul ASSERT(span->end <= MAX_WIDTH); 9027956292a765910077f50352d7cd0174e1e66d26cBrian Paul ASSERT((span->interpMask & span->arrayMask) == 0); 903ceb39f4f8dc4863fde17d668c752533a2184476eBrian Paul ASSERT((span->interpMask | span->arrayMask) & SPAN_RGBA); 904bcb148de9201c7f90a68c7c46434e7ebf7204000Brian Paul#ifdef DEBUG 905733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (ctx->Fog.Enabled) 906733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul ASSERT((span->interpMask | span->arrayMask) & SPAN_FOG); 907bcb148de9201c7f90a68c7c46434e7ebf7204000Brian Paul if (ctx->Depth.Test) 908bcb148de9201c7f90a68c7c46434e7ebf7204000Brian Paul ASSERT((span->interpMask | span->arrayMask) & SPAN_Z); 909bcb148de9201c7f90a68c7c46434e7ebf7204000Brian Paul#endif 910733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul 911733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* 912bcb148de9201c7f90a68c7c46434e7ebf7204000Brian Paul printf("%s() interp 0x%x array 0x%x p=0x%x\n", __FUNCTION__, span->interpMask, span->arrayMask, primitive); 913733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul */ 914e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 915733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (span->arrayMask & SPAN_MASK) { 916733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* mask was initialized by caller, probably glBitmap */ 917733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->writeAll = GL_FALSE; 918733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul } 919733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul else { 920733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul MEMSET(span->mask, 1, span->end); 921733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->writeAll = GL_TRUE; 922733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul } 923e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 9247956292a765910077f50352d7cd0174e1e66d26cBrian Paul /* Determine if we have mono-chromatic colors */ 9257956292a765910077f50352d7cd0174e1e66d26cBrian Paul monoColor = (span->interpMask & SPAN_RGBA) && 9267956292a765910077f50352d7cd0174e1e66d26cBrian Paul span->redStep == 0 && span->greenStep == 0 && 9277956292a765910077f50352d7cd0174e1e66d26cBrian Paul span->blueStep == 0 && span->alphaStep == 0; 9287956292a765910077f50352d7cd0174e1e66d26cBrian Paul 929733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* Clipping */ 930733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if ((swrast->_RasterMask & CLIP_BIT) || (primitive == GL_BITMAP) 931b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul || (primitive == GL_POINT) || (primitive == GL_LINE)) { 932733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (!clip_span(ctx, span)) { 93386ca15ece74ccb5a8f4d566a4b2c8024b178d73bBrian Paul return; 934e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 935e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 936e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 937b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul#ifdef DEBUG 938b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul if (span->arrayMask & SPAN_XY) { 939b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul int i; 940b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul for (i = 0; i < span->end; i++) { 941b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul if (span->mask[i]) { 942b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul assert(span->xArray[i] >= ctx->DrawBuffer->_Xmin); 943b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul assert(span->xArray[i] < ctx->DrawBuffer->_Xmax); 944b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul assert(span->yArray[i] >= ctx->DrawBuffer->_Ymin); 945b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul assert(span->yArray[i] < ctx->DrawBuffer->_Ymax); 946b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul } 947b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul } 948b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul } 949b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul#endif 950b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul 951e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* Polygon Stippling */ 9527956292a765910077f50352d7cd0174e1e66d26cBrian Paul if (ctx->Polygon.StippleFlag && primitive == GL_POLYGON) { 9537956292a765910077f50352d7cd0174e1e66d26cBrian Paul stipple_polygon_span(ctx, span); 95410f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 95510f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 956e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* Do the alpha test */ 957e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell if (ctx->Color.AlphaEnabled) { 958ceb39f4f8dc4863fde17d668c752533a2184476eBrian Paul if (!_mesa_alpha_test(ctx, span)) { 9597956292a765910077f50352d7cd0174e1e66d26cBrian Paul span->interpMask = origInterpMask; 9602a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->arrayMask = origArrayMask; 961e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell return; 962e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 96310f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 96410f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 965f1e236987829393c81dc86ea19cb49eefe190317Brian Paul /* Stencil and Z testing */ 966f1e236987829393c81dc86ea19cb49eefe190317Brian Paul if (ctx->Stencil.Enabled || ctx->Depth.Test) { 967f1e236987829393c81dc86ea19cb49eefe190317Brian Paul if (span->interpMask & SPAN_Z) 968711e27fda27e4235b20a4cf73c2767c984ab2b81Brian Paul _mesa_span_interpolate_z(ctx, span); 969f1e236987829393c81dc86ea19cb49eefe190317Brian Paul 970f1e236987829393c81dc86ea19cb49eefe190317Brian Paul if (ctx->Stencil.Enabled) { 971f1e236987829393c81dc86ea19cb49eefe190317Brian Paul if (!_mesa_stencil_and_ztest_span(ctx, span)) { 9727956292a765910077f50352d7cd0174e1e66d26cBrian Paul span->interpMask = origInterpMask; 973f1e236987829393c81dc86ea19cb49eefe190317Brian Paul span->arrayMask = origArrayMask; 974f1e236987829393c81dc86ea19cb49eefe190317Brian Paul return; 97510f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 97610f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 97710f30eb43835c57c00783390a02d72daf4f78e26Brian Paul else { 978f1e236987829393c81dc86ea19cb49eefe190317Brian Paul ASSERT(ctx->Depth.Test); 979f1e236987829393c81dc86ea19cb49eefe190317Brian Paul ASSERT(span->arrayMask & SPAN_Z); 980f1e236987829393c81dc86ea19cb49eefe190317Brian Paul /* regular depth testing */ 981f1e236987829393c81dc86ea19cb49eefe190317Brian Paul if (!_mesa_depth_test_span(ctx, span)) { 9827956292a765910077f50352d7cd0174e1e66d26cBrian Paul span->interpMask = origInterpMask; 983f1e236987829393c81dc86ea19cb49eefe190317Brian Paul span->arrayMask = origArrayMask; 984f1e236987829393c81dc86ea19cb49eefe190317Brian Paul return; 98510f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 98610f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 987e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 988e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 989e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* if we get here, something passed the depth test */ 990e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell ctx->OcclusionResult = GL_TRUE; 991e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 9927956292a765910077f50352d7cd0174e1e66d26cBrian Paul /* can't abort span-writing until after occlusion testing */ 9937956292a765910077f50352d7cd0174e1e66d26cBrian Paul if (colorMask == 0x0) { 9947956292a765910077f50352d7cd0174e1e66d26cBrian Paul span->interpMask = origInterpMask; 9957956292a765910077f50352d7cd0174e1e66d26cBrian Paul span->arrayMask = origArrayMask; 9967956292a765910077f50352d7cd0174e1e66d26cBrian Paul return; 9977956292a765910077f50352d7cd0174e1e66d26cBrian Paul } 9987956292a765910077f50352d7cd0174e1e66d26cBrian Paul 999ceb39f4f8dc4863fde17d668c752533a2184476eBrian Paul /* Now we may need to interpolate the colors */ 1000ceb39f4f8dc4863fde17d668c752533a2184476eBrian Paul if ((span->interpMask & SPAN_RGBA) && (span->arrayMask & SPAN_RGBA) == 0) { 1001ceb39f4f8dc4863fde17d668c752533a2184476eBrian Paul interpolate_colors(ctx, span); 1002ceb39f4f8dc4863fde17d668c752533a2184476eBrian Paul /* clear the bit - this allows the WriteMonoCISpan optimization below */ 1003ceb39f4f8dc4863fde17d668c752533a2184476eBrian Paul span->interpMask &= ~SPAN_RGBA; 1004ceb39f4f8dc4863fde17d668c752533a2184476eBrian Paul } 1005ceb39f4f8dc4863fde17d668c752533a2184476eBrian Paul 10066e1666437ea091ecc50ab2b56d87129318f641d2Brian Paul /* Fog */ 1007b38ad54c41aec2d08fdd26a4a8ea4dcdca8b1dfdBrian Paul if (ctx->Fog.Enabled) { 1008711e27fda27e4235b20a4cf73c2767c984ab2b81Brian Paul _mesa_fog_rgba_span(ctx, span); 10097956292a765910077f50352d7cd0174e1e66d26cBrian Paul monoColor = GL_FALSE; 1010b38ad54c41aec2d08fdd26a4a8ea4dcdca8b1dfdBrian Paul } 1011b38ad54c41aec2d08fdd26a4a8ea4dcdca8b1dfdBrian Paul 10125071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paul /* Antialias coverage application */ 10132a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul if (span->arrayMask & SPAN_COVERAGE) { 10147956292a765910077f50352d7cd0174e1e66d26cBrian Paul GLchan (*rgba)[4] = span->color.rgba; 10155071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paul GLuint i; 101610f30eb43835c57c00783390a02d72daf4f78e26Brian Paul for (i = 0; i < span->end; i++) { 101710f30eb43835c57c00783390a02d72daf4f78e26Brian Paul rgba[i][ACOMP] = (GLchan) (rgba[i][ACOMP] * span->coverage[i]); 10185071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paul } 10197956292a765910077f50352d7cd0174e1e66d26cBrian Paul monoColor = GL_FALSE; 10205071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paul } 10215071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paul 1022cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell if (swrast->_RasterMask & MULTI_DRAW_BIT) { 1023733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul multi_write_rgba_span(ctx, span); 1024e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1025e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell else { 1026e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* normal: write to exactly one buffer */ 1027e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell if (ctx->Color.ColorLogicOpEnabled) { 1028733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul _mesa_logicop_rgba_span(ctx, span, span->color.rgba); 10297956292a765910077f50352d7cd0174e1e66d26cBrian Paul monoColor = GL_FALSE; 1030e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1031e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell else if (ctx->Color.BlendEnabled) { 1032733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul _mesa_blend_span(ctx, span, span->color.rgba); 10337956292a765910077f50352d7cd0174e1e66d26cBrian Paul monoColor = GL_FALSE; 1034e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 103595e2c72fd52d87163eb543555345f115f050f3aaBrian Paul 1036e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* Color component masking */ 10377956292a765910077f50352d7cd0174e1e66d26cBrian Paul if (colorMask != 0xffffffff) { 1038733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul _mesa_mask_rgba_span(ctx, span, span->color.rgba); 10397956292a765910077f50352d7cd0174e1e66d26cBrian Paul monoColor = GL_FALSE; 1040e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1041e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 1042e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* write pixels */ 1043733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (span->arrayMask & SPAN_XY) { 1044733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* array of pixel coords */ 1045733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* XXX test for mono color */ 1046733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul (*swrast->Driver.WriteRGBAPixels)(ctx, span->end, span->xArray, 1047733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->yArray, (const GLchan (*)[4]) span->color.rgba, span->mask); 1048733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (SWRAST_CONTEXT(ctx)->_RasterMask & ALPHABUF_BIT) { 1049733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul _mesa_write_alpha_pixels(ctx, span->end, 1050733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->xArray, span->yArray, 1051733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul (const GLchan (*)[4]) span->color.rgba, 1052733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->mask); 1053733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul } 1054e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1055e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell else { 1056733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* horizontal run of pixels */ 1057733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (monoColor) { 1058733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* all pixels have same color */ 1059733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul GLchan color[4]; 1060733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul color[RCOMP] = FixedToChan(span->red); 1061733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul color[GCOMP] = FixedToChan(span->green); 1062733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul color[BCOMP] = FixedToChan(span->blue); 1063733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul color[ACOMP] = FixedToChan(span->alpha); 1064733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul (*swrast->Driver.WriteMonoRGBASpan)(ctx, span->end, span->x, 1065733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->y, color, span->mask); 1066733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* XXX software alpha buffer writes! */ 1067733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul } 1068733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul else { 1069733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* each pixel is a different color */ 1070733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul (*swrast->Driver.WriteRGBASpan)(ctx, span->end, span->x, span->y, 10717956292a765910077f50352d7cd0174e1e66d26cBrian Paul (const GLchan (*)[4]) span->color.rgba, 1072733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->writeAll ? ((const GLubyte *) NULL) : span->mask); 1073733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (swrast->_RasterMask & ALPHABUF_BIT) { 1074733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul _mesa_write_alpha_span(ctx, span->end, span->x, span->y, 10757956292a765910077f50352d7cd0174e1e66d26cBrian Paul (const GLchan (*)[4]) span->color.rgba, 1076733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->writeAll ? ((const GLubyte *) NULL) : span->mask); 1077733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul } 1078733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul } 1079e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1080e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1081e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 10827956292a765910077f50352d7cd0174e1e66d26cBrian Paul span->interpMask = origInterpMask; 10837956292a765910077f50352d7cd0174e1e66d26cBrian Paul span->arrayMask = origArrayMask; 10847956292a765910077f50352d7cd0174e1e66d26cBrian Paul} 1085e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 1086e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 108779c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/** 1088e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Add specular color to base color. This is used only when 1089f1e236987829393c81dc86ea19cb49eefe190317Brian Paul * GL_LIGHT_MODEL_COLOR_CONTROL = GL_SEPARATE_SPECULAR_COLOR. 1090e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */ 10915071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paulstatic void 1092f1e236987829393c81dc86ea19cb49eefe190317Brian Pauladd_colors(GLuint n, GLchan rgba[][4], GLchan specular[][4] ) 1093e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell{ 1094e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell GLuint i; 1095f1e236987829393c81dc86ea19cb49eefe190317Brian Paul for (i = 0; i < n; i++) { 10964fa5c1966a985f81c615a9f5ef2f64dd466b252aBrian Paul#if CHAN_TYPE == GL_FLOAT 10974fa5c1966a985f81c615a9f5ef2f64dd466b252aBrian Paul /* no clamping */ 1098f1e236987829393c81dc86ea19cb49eefe190317Brian Paul rgba[i][RCOMP] += specular[i][RCOMP]; 1099f1e236987829393c81dc86ea19cb49eefe190317Brian Paul rgba[i][GCOMP] += specular[i][GCOMP]; 1100f1e236987829393c81dc86ea19cb49eefe190317Brian Paul rgba[i][BCOMP] += specular[i][BCOMP]; 11014fa5c1966a985f81c615a9f5ef2f64dd466b252aBrian Paul#else 1102f1e236987829393c81dc86ea19cb49eefe190317Brian Paul GLint r = rgba[i][RCOMP] + specular[i][RCOMP]; 1103f1e236987829393c81dc86ea19cb49eefe190317Brian Paul GLint g = rgba[i][GCOMP] + specular[i][GCOMP]; 1104f1e236987829393c81dc86ea19cb49eefe190317Brian Paul GLint b = rgba[i][BCOMP] + specular[i][BCOMP]; 1105e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell rgba[i][RCOMP] = (GLchan) MIN2(r, CHAN_MAX); 1106e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell rgba[i][GCOMP] = (GLchan) MIN2(g, CHAN_MAX); 1107e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell rgba[i][BCOMP] = (GLchan) MIN2(b, CHAN_MAX); 11084fa5c1966a985f81c615a9f5ef2f64dd466b252aBrian Paul#endif 1109e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1110e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell} 1111e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 1112e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 111379c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/** 1114f1e236987829393c81dc86ea19cb49eefe190317Brian Paul * This function may modify any of the array values in the span. 11157956292a765910077f50352d7cd0174e1e66d26cBrian Paul * span->interpMask and span->arrayMask may be changed but will be restored 11167956292a765910077f50352d7cd0174e1e66d26cBrian Paul * to their original values before returning. 111778940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul */ 111878940758e90069ceaca2b6cddb6438488fbad5ccBrian Paulvoid 111978940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul_mesa_write_texture_span( GLcontext *ctx, struct sw_span *span, 1120f1e236987829393c81dc86ea19cb49eefe190317Brian Paul GLenum primitive ) 112178940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul{ 112278940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul const GLuint colorMask = *((GLuint *) ctx->Color.ColorMask); 112378940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul SWcontext *swrast = SWRAST_CONTEXT(ctx); 1124f1e236987829393c81dc86ea19cb49eefe190317Brian Paul const GLuint origArrayMask = span->arrayMask; 1125f1e236987829393c81dc86ea19cb49eefe190317Brian Paul 1126733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul ASSERT(span->end <= MAX_WIDTH); 11277956292a765910077f50352d7cd0174e1e66d26cBrian Paul ASSERT((span->interpMask & span->arrayMask) == 0); 1128f1e236987829393c81dc86ea19cb49eefe190317Brian Paul ASSERT(ctx->Texture._ReallyEnabled); 112978940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul 1130ceb39f4f8dc4863fde17d668c752533a2184476eBrian Paul /* 1131ceb39f4f8dc4863fde17d668c752533a2184476eBrian Paul printf("%s() interp 0x%x array 0x%x\n", __FUNCTION__, span->interpMask, span->arrayMask); 1132ceb39f4f8dc4863fde17d668c752533a2184476eBrian Paul */ 1133ceb39f4f8dc4863fde17d668c752533a2184476eBrian Paul 1134733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (span->arrayMask & SPAN_MASK) { 1135733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* mask was initialized by caller, probably glBitmap */ 1136733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->writeAll = GL_FALSE; 1137733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul } 1138733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul else { 1139733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul MEMSET(span->mask, 1, span->end); 1140733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->writeAll = GL_TRUE; 114178940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul } 114278940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul 1143733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* Clipping */ 1144733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if ((swrast->_RasterMask & CLIP_BIT) || (primitive == GL_BITMAP) 1145b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul || (primitive == GL_POINT) || (primitive == GL_LINE)) { 1146733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (!clip_span(ctx, span)) { 1147733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul return; 114878940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul } 114978940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul } 115078940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul 1151b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul#ifdef DEBUG 1152b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul if (span->arrayMask & SPAN_XY) { 1153b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul int i; 1154b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul for (i = 0; i < span->end; i++) { 1155b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul if (span->mask[i]) { 1156b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul assert(span->xArray[i] >= ctx->DrawBuffer->_Xmin); 1157b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul assert(span->xArray[i] < ctx->DrawBuffer->_Xmax); 1158b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul assert(span->yArray[i] >= ctx->DrawBuffer->_Ymin); 1159b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul assert(span->yArray[i] < ctx->DrawBuffer->_Ymax); 1160b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul } 1161b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul } 1162b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul } 1163b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul#endif 1164b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul 116578940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul /* Polygon Stippling */ 1166733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (ctx->Polygon.StippleFlag && primitive == GL_POLYGON) { 1167733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul stipple_polygon_span(ctx, span); 116878940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul } 116978940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul 1170f1e236987829393c81dc86ea19cb49eefe190317Brian Paul /* Need texture coordinates now */ 1171f1e236987829393c81dc86ea19cb49eefe190317Brian Paul if ((span->interpMask & SPAN_TEXTURE) 1172f1e236987829393c81dc86ea19cb49eefe190317Brian Paul && (span->arrayMask & SPAN_TEXTURE) == 0) 1173f1e236987829393c81dc86ea19cb49eefe190317Brian Paul interpolate_texcoords(ctx, span); 117478940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul 117578940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul /* Texture with alpha test */ 117678940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul if (ctx->Color.AlphaEnabled) { 1177f1e236987829393c81dc86ea19cb49eefe190317Brian Paul 1178f1e236987829393c81dc86ea19cb49eefe190317Brian Paul /* Now we need the rgba array, fill it in if needed */ 1179f1e236987829393c81dc86ea19cb49eefe190317Brian Paul if ((span->interpMask & SPAN_RGBA) && (span->arrayMask & SPAN_RGBA) == 0) 1180f1e236987829393c81dc86ea19cb49eefe190317Brian Paul interpolate_colors(ctx, span); 1181f1e236987829393c81dc86ea19cb49eefe190317Brian Paul 118278940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul /* Texturing without alpha is done after depth-testing which 1183f1e236987829393c81dc86ea19cb49eefe190317Brian Paul * gives a potential speed-up. 1184f1e236987829393c81dc86ea19cb49eefe190317Brian Paul */ 1185f1e236987829393c81dc86ea19cb49eefe190317Brian Paul _swrast_multitexture_fragments( ctx, span ); 118678940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul 118778940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul /* Do the alpha test */ 1188ceb39f4f8dc4863fde17d668c752533a2184476eBrian Paul if (!_mesa_alpha_test(ctx, span)) { 1189f1e236987829393c81dc86ea19cb49eefe190317Brian Paul span->arrayMask = origArrayMask; 1190ceb39f4f8dc4863fde17d668c752533a2184476eBrian Paul return; 119178940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul } 119278940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul } 119378940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul 1194f1e236987829393c81dc86ea19cb49eefe190317Brian Paul /* Stencil and Z testing */ 1195f1e236987829393c81dc86ea19cb49eefe190317Brian Paul if (ctx->Stencil.Enabled || ctx->Depth.Test) { 1196f1e236987829393c81dc86ea19cb49eefe190317Brian Paul if (span->interpMask & SPAN_Z) 1197711e27fda27e4235b20a4cf73c2767c984ab2b81Brian Paul _mesa_span_interpolate_z(ctx, span); 119878940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul 119971340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul if (ctx->Stencil.Enabled) { 1200f1e236987829393c81dc86ea19cb49eefe190317Brian Paul if (!_mesa_stencil_and_ztest_span(ctx, span)) { 1201f1e236987829393c81dc86ea19cb49eefe190317Brian Paul span->arrayMask = origArrayMask; 120210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul return; 1203f1e236987829393c81dc86ea19cb49eefe190317Brian Paul } 120471340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 1205f1e236987829393c81dc86ea19cb49eefe190317Brian Paul else { 1206f1e236987829393c81dc86ea19cb49eefe190317Brian Paul ASSERT(ctx->Depth.Test); 1207f1e236987829393c81dc86ea19cb49eefe190317Brian Paul ASSERT(span->arrayMask & SPAN_Z); 120810f30eb43835c57c00783390a02d72daf4f78e26Brian Paul /* regular depth testing */ 1209f1e236987829393c81dc86ea19cb49eefe190317Brian Paul if (!_mesa_depth_test_span(ctx, span)) { 1210f1e236987829393c81dc86ea19cb49eefe190317Brian Paul span->arrayMask = origArrayMask; 121110f30eb43835c57c00783390a02d72daf4f78e26Brian Paul return; 1212f1e236987829393c81dc86ea19cb49eefe190317Brian Paul } 121371340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 121471340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 121571340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul 1216f1e236987829393c81dc86ea19cb49eefe190317Brian Paul /* if we get here, some fragments passed the depth test */ 121771340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul ctx->OcclusionResult = GL_TRUE; 121871340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul 1219f1e236987829393c81dc86ea19cb49eefe190317Brian Paul /* We had to wait until now to check for glColorMask(F,F,F,F) because of 1220f1e236987829393c81dc86ea19cb49eefe190317Brian Paul * the occlusion test. 1221f1e236987829393c81dc86ea19cb49eefe190317Brian Paul */ 1222f1e236987829393c81dc86ea19cb49eefe190317Brian Paul if (colorMask == 0x0) { 1223f1e236987829393c81dc86ea19cb49eefe190317Brian Paul span->arrayMask = origArrayMask; 1224f1e236987829393c81dc86ea19cb49eefe190317Brian Paul return; 122571340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 122671340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul 1227f1e236987829393c81dc86ea19cb49eefe190317Brian Paul /* Texture without alpha test */ 1228f1e236987829393c81dc86ea19cb49eefe190317Brian Paul if (!ctx->Color.AlphaEnabled) { 122971340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul 1230f1e236987829393c81dc86ea19cb49eefe190317Brian Paul /* Now we need the rgba array, fill it in if needed */ 1231f1e236987829393c81dc86ea19cb49eefe190317Brian Paul if ((span->interpMask & SPAN_RGBA) && (span->arrayMask & SPAN_RGBA) == 0) 1232f1e236987829393c81dc86ea19cb49eefe190317Brian Paul interpolate_colors(ctx, span); 123371340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul 1234f1e236987829393c81dc86ea19cb49eefe190317Brian Paul _swrast_multitexture_fragments( ctx, span ); 123571340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 123671340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul 1237f1e236987829393c81dc86ea19cb49eefe190317Brian Paul ASSERT(span->arrayMask & SPAN_RGBA); 12382ef866d1fc0a5cc5ef8543d65744dfd4da4dbbafBrian Paul 1239f1e236987829393c81dc86ea19cb49eefe190317Brian Paul /* Add base and specular colors */ 1240f1e236987829393c81dc86ea19cb49eefe190317Brian Paul if (ctx->Fog.ColorSumEnabled || 1241f1e236987829393c81dc86ea19cb49eefe190317Brian Paul (ctx->Light.Enabled && 1242f1e236987829393c81dc86ea19cb49eefe190317Brian Paul ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR)) { 1243f1e236987829393c81dc86ea19cb49eefe190317Brian Paul if (span->interpMask & SPAN_SPEC) { 1244f1e236987829393c81dc86ea19cb49eefe190317Brian Paul interpolate_specular(ctx, span); 124571340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 1246f1e236987829393c81dc86ea19cb49eefe190317Brian Paul ASSERT(span->arrayMask & SPAN_SPEC); 1247f1e236987829393c81dc86ea19cb49eefe190317Brian Paul add_colors( span->end, span->color.rgba, span->specArray ); 124871340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 124971340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul 12506e1666437ea091ecc50ab2b56d87129318f641d2Brian Paul /* Fog */ 125171340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul if (ctx->Fog.Enabled) { 1252711e27fda27e4235b20a4cf73c2767c984ab2b81Brian Paul _mesa_fog_rgba_span(ctx, span); 125371340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 1254f1e236987829393c81dc86ea19cb49eefe190317Brian Paul 125571340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul /* Antialias coverage application */ 12562a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul if (span->arrayMask & SPAN_COVERAGE) { 1257f1e236987829393c81dc86ea19cb49eefe190317Brian Paul GLchan (*rgba)[4] = span->color.rgba; 125871340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul GLuint i; 125910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul for (i = 0; i < span->end; i++) { 126010f30eb43835c57c00783390a02d72daf4f78e26Brian Paul rgba[i][ACOMP] = (GLchan) (rgba[i][ACOMP] * span->coverage[i]); 126171340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 126271340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 126371340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul 126471340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul if (swrast->_RasterMask & MULTI_DRAW_BIT) { 1265733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul multi_write_rgba_span(ctx, span); 126671340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 126771340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul else { 126871340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul /* normal: write to exactly one buffer */ 126971340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul if (ctx->Color.ColorLogicOpEnabled) { 1270733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul _mesa_logicop_rgba_span(ctx, span, span->color.rgba); 127171340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 127295e2c72fd52d87163eb543555345f115f050f3aaBrian Paul else if (ctx->Color.BlendEnabled) { 1273733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul _mesa_blend_span(ctx, span, span->color.rgba); 127471340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 127571340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul 1276f1e236987829393c81dc86ea19cb49eefe190317Brian Paul if (colorMask != 0xffffffff) { 1277733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul _mesa_mask_rgba_span(ctx, span, span->color.rgba); 127871340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 127971340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul 1280733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul 1281733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (span->arrayMask & SPAN_XY) { 1282733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* array of pixel coords */ 1283733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul (*swrast->Driver.WriteRGBAPixels)(ctx, span->end, span->xArray, 1284733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->yArray, (const GLchan (*)[4]) span->color.rgba, span->mask); 1285733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (SWRAST_CONTEXT(ctx)->_RasterMask & ALPHABUF_BIT) { 1286733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul _mesa_write_alpha_pixels(ctx, span->end, 1287733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->xArray, span->yArray, 1288733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul (const GLchan (*)[4]) span->color.rgba, 1289733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->mask); 1290733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul } 1291733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul } 1292733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul else { 1293733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* horizontal run of pixels */ 1294733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul (*swrast->Driver.WriteRGBASpan)(ctx, span->end, span->x, span->y, 1295f1e236987829393c81dc86ea19cb49eefe190317Brian Paul (const GLchan (*)[4]) span->color.rgba, 1296733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->writeAll ? NULL : span->mask); 1297733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (swrast->_RasterMask & ALPHABUF_BIT) { 1298733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul _mesa_write_alpha_span(ctx, span->end, span->x, span->y, 1299733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul (const GLchan (*)[4]) span->color.rgba, 1300733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->writeAll ? NULL : span->mask); 1301733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul } 130271340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 130371340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 130471340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul 1305f1e236987829393c81dc86ea19cb49eefe190317Brian Paul span->arrayMask = origArrayMask; 130610f30eb43835c57c00783390a02d72daf4f78e26Brian Paul} 130710f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 1308e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 1309e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 131079c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/** 1311e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Read RGBA pixels from frame buffer. Clipping will be done to prevent 1312e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * reading ouside the buffer's boundaries. 1313e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */ 13145071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paulvoid 13155071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paul_mesa_read_rgba_span( GLcontext *ctx, GLframebuffer *buffer, 13165071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paul GLuint n, GLint x, GLint y, GLchan rgba[][4] ) 1317e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell{ 1318709892459922a32096fe9dd8261d0d92337bb02fKeith Whitwell SWcontext *swrast = SWRAST_CONTEXT(ctx); 1319e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell if (y < 0 || y >= buffer->Height 1320e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell || x + (GLint) n < 0 || x >= buffer->Width) { 1321e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* completely above, below, or right */ 1322e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* XXX maybe leave undefined? */ 1323e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell BZERO(rgba, 4 * n * sizeof(GLchan)); 1324e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1325e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell else { 1326e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell GLint skip, length; 1327e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell if (x < 0) { 1328e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* left edge clippping */ 1329e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell skip = -x; 1330e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell length = (GLint) n - skip; 1331e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell if (length < 0) { 1332e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* completely left of window */ 1333e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell return; 1334e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1335e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell if (length > buffer->Width) { 1336e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell length = buffer->Width; 1337e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1338e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1339e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell else if ((GLint) (x + n) > buffer->Width) { 1340e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* right edge clipping */ 1341e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell skip = 0; 1342e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell length = buffer->Width - x; 1343e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell if (length < 0) { 1344e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* completely to right of window */ 1345e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell return; 1346e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1347e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1348e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell else { 1349e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* no clipping */ 1350e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell skip = 0; 1351e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell length = (GLint) n; 1352e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1353e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 1354709892459922a32096fe9dd8261d0d92337bb02fKeith Whitwell (*swrast->Driver.ReadRGBASpan)( ctx, length, x + skip, y, rgba + skip ); 1355e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell if (buffer->UseSoftwareAlphaBuffers) { 1356733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul _mesa_read_alpha_span(ctx, length, x + skip, y, rgba + skip); 1357e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1358e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1359e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell} 1360e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 1361e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 136279c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/** 1363e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Read CI pixels from frame buffer. Clipping will be done to prevent 1364e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * reading ouside the buffer's boundaries. 1365e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */ 13665071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paulvoid 13675071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paul_mesa_read_index_span( GLcontext *ctx, GLframebuffer *buffer, 13685071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paul GLuint n, GLint x, GLint y, GLuint indx[] ) 1369e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell{ 1370709892459922a32096fe9dd8261d0d92337bb02fKeith Whitwell SWcontext *swrast = SWRAST_CONTEXT(ctx); 1371e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell if (y < 0 || y >= buffer->Height 1372e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell || x + (GLint) n < 0 || x >= buffer->Width) { 1373e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* completely above, below, or right */ 1374e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell BZERO(indx, n * sizeof(GLuint)); 1375e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1376e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell else { 1377e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell GLint skip, length; 1378e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell if (x < 0) { 1379e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* left edge clippping */ 1380e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell skip = -x; 1381e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell length = (GLint) n - skip; 1382e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell if (length < 0) { 1383e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* completely left of window */ 1384e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell return; 1385e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1386e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell if (length > buffer->Width) { 1387e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell length = buffer->Width; 1388e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1389e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1390e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell else if ((GLint) (x + n) > buffer->Width) { 1391e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* right edge clipping */ 1392e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell skip = 0; 1393e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell length = buffer->Width - x; 1394e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell if (length < 0) { 1395e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* completely to right of window */ 1396e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell return; 1397e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1398e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1399e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell else { 1400e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* no clipping */ 1401e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell skip = 0; 1402e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell length = (GLint) n; 1403e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1404e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 1405709892459922a32096fe9dd8261d0d92337bb02fKeith Whitwell (*swrast->Driver.ReadCI32Span)( ctx, length, skip + x, y, indx + skip ); 1406e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1407e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell} 1408