s_span.c revision 31f12f504e61cb2ad65b8890a68eb7154edcb64b
131f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul/* $Id: s_span.c,v 1.37 2002/03/16 18:02:08 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" 3931f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul#include "mmath.h" 40e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "mem.h" 41e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 42e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_alpha.h" 43e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_alphabuf.h" 44e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_blend.h" 45cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell#include "s_context.h" 46e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_depth.h" 47e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_fog.h" 48e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_logic.h" 49e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_masking.h" 50e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_span.h" 51e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_stencil.h" 52e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_texture.h" 53e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 542a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 5579c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/** 562a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul * Init span's Z interpolation values to the RasterPos Z. 572a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul * Used during setup for glDraw/CopyPixels. 582a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul */ 592a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paulvoid 602a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul_mesa_span_default_z( GLcontext *ctx, struct sw_span *span ) 612a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul{ 622a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul if (ctx->Visual.depthBits <= 16) 632a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->z = FloatToFixed(ctx->Current.RasterPos[2] * ctx->DepthMax); 642a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul else 652a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->z = (GLint) (ctx->Current.RasterPos[2] * ctx->DepthMax); 662a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->zStep = 0; 672a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->interpMask |= SPAN_Z; 682a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul} 692a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 702a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 7179c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/** 722a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul * Init span's fog interpolation values to the RasterPos fog. 732a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul * Used during setup for glDraw/CopyPixels. 742a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul */ 752a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paulvoid 762a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul_mesa_span_default_fog( GLcontext *ctx, struct sw_span *span ) 772a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul{ 78c9ceef41fe89f5ba6e16ec51c1f9b7bfd8119c64Brian Paul span->fog = _mesa_z_to_fogfactor(ctx, ctx->Current.RasterDistance); 792a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->fogStep = 0; 802a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->interpMask |= SPAN_FOG; 812a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul} 822a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 832a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 8479c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/** 852a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul * Init span's color or index interpolation values to the RasterPos color. 862a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul * Used during setup for glDraw/CopyPixels. 872a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul */ 882a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paulvoid 892a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul_mesa_span_default_color( GLcontext *ctx, struct sw_span *span ) 902a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul{ 912a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul if (ctx->Visual.rgbMode) { 922a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLchan r, g, b, a; 932a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul UNCLAMPED_FLOAT_TO_CHAN(r, ctx->Current.RasterColor[0]); 942a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul UNCLAMPED_FLOAT_TO_CHAN(g, ctx->Current.RasterColor[1]); 952a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul UNCLAMPED_FLOAT_TO_CHAN(b, ctx->Current.RasterColor[2]); 962a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul UNCLAMPED_FLOAT_TO_CHAN(a, ctx->Current.RasterColor[3]); 972a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul#if CHAN_TYPE == GL_FLOAT 982a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->red = r; 992a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->green = g; 1002a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->blue = b; 1012a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->alpha = a; 1022a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul#else 1032a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->red = IntToFixed(r); 1042a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->green = IntToFixed(g); 1052a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->blue = IntToFixed(b); 1062a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->alpha = IntToFixed(a); 1072a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul#endif 1082a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->redStep = 0; 1092a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->greenStep = 0; 1102a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->blueStep = 0; 1112a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->alphaStep = 0; 1122a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->interpMask |= SPAN_RGBA; 1132a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 1142a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul else { 1152a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->index = IntToFixed(ctx->Current.RasterIndex); 1162a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->indexStep = 0; 1172a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->interpMask |= SPAN_INDEX; 1182a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 1192a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul} 1202a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 1212a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 1222a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul/* Fill in the span.color.rgba array from the interpolation values */ 1232a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paulstatic void 1242a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paulinterpolate_colors(GLcontext *ctx, struct sw_span *span) 1252a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul{ 1262a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfixed r = span->red; 1272a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfixed g = span->green; 1282a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfixed b = span->blue; 1292a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfixed a = span->alpha; 1302a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul const GLint dr = span->redStep; 1312a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul const GLint dg = span->greenStep; 1322a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul const GLint db = span->blueStep; 1332a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul const GLint da = span->alphaStep; 1342a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul const GLuint n = span->end; 1352a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLchan (*rgba)[4] = span->color.rgba; 1362a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLuint i; 1372a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 1382a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul ASSERT(span->interpMask & SPAN_RGBA); 1392a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 1402a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul if (span->interpMask & SPAN_FLAT) { 1412a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul /* constant color */ 1422a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLchan color[4]; 1432a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul color[RCOMP] = FixedToChan(r); 1442a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul color[GCOMP] = FixedToChan(g); 1452a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul color[BCOMP] = FixedToChan(b); 1462a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul color[ACOMP] = FixedToChan(a); 1472a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul for (i = 0; i < n; i++) { 1482a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul COPY_CHAN4(span->color.rgba[i], color); 1492a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 1502a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 1512a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul else { 1522a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul /* interpolate */ 1532a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul for (i = 0; i < n; i++) { 1542a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul rgba[i][RCOMP] = FixedToChan(r); 1552a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul rgba[i][GCOMP] = FixedToChan(g); 1562a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul rgba[i][BCOMP] = FixedToChan(b); 1572a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul rgba[i][ACOMP] = FixedToChan(a); 1582a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul r += dr; 1592a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul g += dg; 1602a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul b += db; 1612a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul a += da; 1622a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 1632a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 1642a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->arrayMask |= SPAN_RGBA; 1652a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul} 1662a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 1672a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 1682a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul/* Fill in the span.color.index array from the interpolation values */ 1692a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paulstatic void 1702a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paulinterpolate_indexes(GLcontext *ctx, struct sw_span *span) 1712a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul{ 1722a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfixed index = span->index; 1732a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul const GLint indexStep = span->indexStep; 1742a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul const GLuint n = span->end; 1752a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLuint *indexes = span->color.index; 1762a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLuint i; 1772a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul ASSERT(span->interpMask & SPAN_INDEX); 1782a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 1792a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul if ((span->interpMask & SPAN_FLAT) || (indexStep == 0)) { 1802a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul /* constant color */ 1812a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul index = FixedToInt(index); 1822a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul for (i = 0; i < n; i++) { 1832a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul indexes[i] = index; 1842a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 1852a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 1862a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul else { 1872a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul /* interpolate */ 1882a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul for (i = 0; i < n; i++) { 1892a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul indexes[i] = FixedToInt(index); 1902a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul index += indexStep; 1912a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 1922a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 1932a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->arrayMask |= SPAN_INDEX; 1942a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul} 1952a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 1962a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 1972a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul/* Fill in the span.specArray array from the interpolation values */ 1982a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paulstatic void 1992a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paulinterpolate_specular(GLcontext *ctx, struct sw_span *span) 2002a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul{ 2012a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul if (span->interpMask & SPAN_FLAT) { 2022a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul /* constant color */ 2032a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul const GLchan r = FixedToChan(span->specRed); 2042a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul const GLchan g = FixedToChan(span->specGreen); 2052a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul const GLchan b = FixedToChan(span->specBlue); 2062a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLuint i; 2072a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul for (i = 0; i < span->end; i++) { 2082a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->specArray[i][RCOMP] = r; 2092a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->specArray[i][GCOMP] = g; 2102a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->specArray[i][BCOMP] = b; 2112a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 2122a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 2132a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul else { 2142a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul /* interpolate */ 2152a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul#if CHAN_TYPE == GL_FLOAT 2162a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat r = span->specRed; 2172a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat g = span->specGreen; 2182a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat b = span->specBlue; 2192a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul#else 2202a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfixed r = span->specRed; 2212a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfixed g = span->specGreen; 2222a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfixed b = span->specBlue; 2232a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul#endif 2242a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLuint i; 2252a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul for (i = 0; i < span->end; i++) { 2262a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->specArray[i][RCOMP] = FixedToChan(r); 2272a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->specArray[i][GCOMP] = FixedToChan(g); 2282a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->specArray[i][BCOMP] = FixedToChan(b); 2292a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul r += span->specRedStep; 2302a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul g += span->specGreenStep; 2312a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul b += span->specBlueStep; 2322a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 2332a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 2342a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->arrayMask |= SPAN_SPEC; 2352a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul} 2362a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 2372a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 2382a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul/* Fill in the span.zArray array from the interpolation values */ 239711e27fda27e4235b20a4cf73c2767c984ab2b81Brian Paulvoid 240711e27fda27e4235b20a4cf73c2767c984ab2b81Brian Paul_mesa_span_interpolate_z( const GLcontext *ctx, struct sw_span *span ) 2412a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul{ 2422a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul const GLuint n = span->end; 2432a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLuint i; 2442a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 2452a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul ASSERT(span->interpMask & SPAN_Z); 2462a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 2472a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul if (ctx->Visual.depthBits <= 16) { 2482a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfixed zval = span->z; 2492a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul for (i = 0; i < n; i++) { 2502a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->zArray[i] = FixedToInt(zval); 2512a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul zval += span->zStep; 2522a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 2532a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 2542a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul else { 2552a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul /* Deep Z buffer, no fixed->int shift */ 2562a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfixed zval = span->z; 2572a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul for (i = 0; i < n; i++) { 2582a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->zArray[i] = zval; 2592a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul zval += span->zStep; 2602a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 2612a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 2622a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->arrayMask |= SPAN_Z; 2632a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul} 2642a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 2652a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 266c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul/* 26731f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul * This the ideal solution, as given in the OpenGL spec. 268c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul */ 269c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul#if 0 27031f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paulstatic GLfloat 27131f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paulcompute_lambda(GLfloat dsdx, GLfloat dsdy, GLfloat dtdx, GLfloat dtdy, 27231f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat dqdx, GLfloat dqdy, GLfloat texW, GLfloat texH, 27331f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat s, GLfloat t, GLfloat q, GLfloat invQ) 274c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul{ 27531f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat dudx = texW * ((s + dsdx) / (q + dqdx) - s * invQ); 27631f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat dvdx = texH * ((t + dtdx) / (q + dqdx) - t * invQ); 27731f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat dudy = texW * ((s + dsdy) / (q + dqdy) - s * invQ); 27831f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat dvdy = texH * ((t + dtdy) / (q + dqdy) - t * invQ); 27931f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat x = sqrt(dudx * dudx + dvdx * dvdx); 28031f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat y = sqrt(dudy * dudy + dvdy * dvdy); 28131f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat rho = MAX2(x, y); 28231f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat lambda = LOG2(rho); 28331f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul return lambda; 284c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul} 285c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul#endif 286c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul 28731f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul 28831f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul/* 28931f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul * This is a faster approximation 290c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul */ 29131f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paulstatic GLfloat 29231f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paulcompute_lambda(GLfloat dsdx, GLfloat dsdy, GLfloat dtdx, GLfloat dtdy, 29331f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat dqdx, GLfloat dqdy, GLfloat texW, GLfloat texH, 29431f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat s, GLfloat t, GLfloat q, GLfloat invQ) 295c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul{ 29631f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat dsdx2 = (s + dsdx) / (q + dqdx) - s * invQ; 29731f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat dtdx2 = (t + dtdx) / (q + dqdx) - t * invQ; 29831f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat dsdy2 = (s + dsdy) / (q + dqdy) - s * invQ; 29931f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat dtdy2 = (t + dtdy) / (q + dqdy) - t * invQ; 30031f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat maxU, maxV, rho, lambda; 30131f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul dsdx2 = FABSF(dsdx2); 30231f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul dsdy2 = FABSF(dsdy2); 30331f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul dtdx2 = FABSF(dtdx2); 30431f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul dtdy2 = FABSF(dtdy2); 30531f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul maxU = MAX2(dsdx2, dsdy2) * texW; 30631f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul maxV = MAX2(dtdx2, dtdy2) * texH; 30731f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul rho = MAX2(maxU, maxV); 30831f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul lambda = LOG2(rho); 30931f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul return lambda; 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) { 32331f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul /* multitexture */ 32431f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLuint u; 32531f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { 32631f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul if (ctx->Texture.Unit[u]._ReallyEnabled) { 32731f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const struct gl_texture_object *obj =ctx->Texture.Unit[u]._Current; 32831f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const struct gl_texture_image *img = obj->Image[obj->BaseLevel]; 32931f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLboolean needLambda = (obj->MinFilter != obj->MagFilter); 33031f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul if (needLambda) { 33131f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat texW = (GLfloat) img->Width; 33231f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat texH = (GLfloat) img->Height; 33331f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat dsdx = span->texStepX[u][0]; 33431f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat dsdy = span->texStepY[u][0]; 33531f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat dtdx = span->texStepX[u][1]; 33631f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat dtdy = span->texStepY[u][1]; 33731f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat drdx = span->texStepX[u][2]; 33831f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat dqdx = span->texStepX[u][3]; 33931f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat dqdy = span->texStepY[u][3]; 3402a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat s = span->tex[u][0]; 3412a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat t = span->tex[u][1]; 3422a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat r = span->tex[u][2]; 3432a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat q = span->tex[u][3]; 3442a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLuint i; 34531f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul for (i = 0; i < span->end; i++) { 3462a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q); 34731f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul span->texcoords[u][i][0] = s * invQ; 34831f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul span->texcoords[u][i][1] = t * invQ; 34931f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul span->texcoords[u][i][2] = r * invQ; 35031f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul span->lambda[u][i] = compute_lambda(dsdx, dsdy, dtdx, dtdy, 35131f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul dqdx, dqdy, texW, texH, 35231f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul s, t, q, invQ); 35331f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul s += dsdx; 35431f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul t += dtdx; 35531f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul r += drdx; 35631f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul q += dqdx; 3572a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 35831f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul span->arrayMask |= SPAN_LAMBDA; 3592a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 36031f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul else { 36131f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat dsdx = span->texStepX[u][0]; 36231f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat dtdx = span->texStepX[u][1]; 36331f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat drdx = span->texStepX[u][2]; 36431f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat dqdx = span->texStepX[u][3]; 3652a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat s = span->tex[u][0]; 3662a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat t = span->tex[u][1]; 3672a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat r = span->tex[u][2]; 3682a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat q = span->tex[u][3]; 3692a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLuint i; 37031f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul if (dqdx == 0.0) { 371c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul /* Ortho projection or polygon's parallel to window X axis */ 3722a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q); 373c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul for (i = 0; i < span->end; i++) { 374c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul span->texcoords[u][i][0] = s * invQ; 375c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul span->texcoords[u][i][1] = t * invQ; 376c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul span->texcoords[u][i][2] = r * invQ; 37731f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul span->lambda[u][i] = 0.0; 37831f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul s += dsdx; 37931f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul t += dtdx; 38031f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul r += drdx; 381c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul } 382c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul } 383c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul else { 384c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul for (i = 0; i < span->end; i++) { 385c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q); 386c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul span->texcoords[u][i][0] = s * invQ; 387c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul span->texcoords[u][i][1] = t * invQ; 388c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul span->texcoords[u][i][2] = r * invQ; 38931f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul span->lambda[u][i] = 0.0; 39031f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul s += dsdx; 39131f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul t += dtdx; 39231f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul r += drdx; 39331f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul q += dqdx; 394c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul } 3952a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 39631f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul } /* lambda */ 39731f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul } /* if */ 39831f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul } /* for */ 3992a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 4002a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul else { 40131f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul /* single texture */ 40231f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const struct gl_texture_object *obj = ctx->Texture.Unit[0]._Current; 40331f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const struct gl_texture_image *img = obj->Image[obj->BaseLevel]; 40431f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLboolean needLambda = (obj->MinFilter != obj->MagFilter); 40531f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul if (needLambda) { 4062a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul /* just texture unit 0, with lambda */ 40731f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat texW = (GLfloat) img->Width; 40831f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat texH = (GLfloat) img->Height; 40931f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat dsdx = span->texStepX[0][0]; 41031f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat dsdy = span->texStepY[0][0]; 41131f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat dtdx = span->texStepX[0][1]; 41231f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat dtdy = span->texStepY[0][1]; 41331f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat drdx = span->texStepX[0][2]; 41431f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat dqdx = span->texStepX[0][3]; 41531f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat dqdy = span->texStepY[0][3]; 4162a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat s = span->tex[0][0]; 4172a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat t = span->tex[0][1]; 4182a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat r = span->tex[0][2]; 4192a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat q = span->tex[0][3]; 4202a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLuint i; 42131f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul for (i = 0; i < span->end; i++) { 4222a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q); 42331f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul span->lambda[0][i] = compute_lambda(dsdx, dsdy, dtdx, dtdy, 42431f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul dqdx, dqdy, texW, texH, 42531f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul s, t, q, invQ); 42631f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul span->texcoords[0][i][0] = s * invQ; 42731f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul span->texcoords[0][i][1] = t * invQ; 42831f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul span->texcoords[0][i][2] = r * invQ; 42931f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul s += dsdx; 43031f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul t += dtdx; 43131f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul r += drdx; 43231f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul q += dqdx; 4332a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 4342a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->arrayMask |= SPAN_LAMBDA; 4352a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 4362a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul else { 437733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* just texture 0, without lambda */ 43831f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat dsdx = span->texStepX[0][0]; 43931f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat dtdx = span->texStepX[0][1]; 44031f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat drdx = span->texStepX[0][2]; 44131f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat dqdx = span->texStepX[0][3]; 4422a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat s = span->tex[0][0]; 4432a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat t = span->tex[0][1]; 4442a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat r = span->tex[0][2]; 4452a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat q = span->tex[0][3]; 4462a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLuint i; 44731f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul if (dqdx == 0.0) { 448c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul /* Ortho projection or polygon's parallel to window X axis */ 4492a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q); 450c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul for (i = 0; i < span->end; i++) { 451c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul span->texcoords[0][i][0] = s * invQ; 452c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul span->texcoords[0][i][1] = t * invQ; 453c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul span->texcoords[0][i][2] = r * invQ; 45431f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul s += dsdx; 45531f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul t += dtdx; 45631f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul r += drdx; 457c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul } 458c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul } 459c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul else { 460c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul for (i = 0; i < span->end; i++) { 461c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q); 462c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul span->texcoords[0][i][0] = s * invQ; 463c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul span->texcoords[0][i][1] = t * invQ; 464c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul span->texcoords[0][i][2] = r * invQ; 46531f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul s += dsdx; 46631f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul t += dtdx; 46731f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul r += drdx; 46831f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul q += dqdx; 469c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul } 4702a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 4712a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 4722a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 47310f30eb43835c57c00783390a02d72daf4f78e26Brian Paul} 474e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 475e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 47679c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/** 477e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Apply the current polygon stipple pattern to a span of pixels. 478e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */ 4795071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paulstatic void 480733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paulstipple_polygon_span( GLcontext *ctx, struct sw_span *span ) 48110f30eb43835c57c00783390a02d72daf4f78e26Brian Paul{ 48210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul const GLuint highbit = 0x80000000; 483733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul const GLuint stipple = ctx->PolygonStipple[span->y % 32]; 484733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul GLuint i, m; 485733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul 486733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul ASSERT(ctx->Polygon.StippleFlag); 487733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul ASSERT((span->arrayMask & SPAN_XY) == 0); 48810f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 48910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul m = highbit >> (GLuint) (span->x % 32); 49010f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 49110f30eb43835c57c00783390a02d72daf4f78e26Brian Paul for (i = 0; i < span->end; i++) { 49210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul if ((m & stipple) == 0) { 49310f30eb43835c57c00783390a02d72daf4f78e26Brian Paul span->mask[i] = 0; 49410f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 49510f30eb43835c57c00783390a02d72daf4f78e26Brian Paul m = m >> 1; 49610f30eb43835c57c00783390a02d72daf4f78e26Brian Paul if (m == 0) { 49710f30eb43835c57c00783390a02d72daf4f78e26Brian Paul m = highbit; 49810f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 49910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 5002ef866d1fc0a5cc5ef8543d65744dfd4da4dbbafBrian Paul span->writeAll = GL_FALSE; 50110f30eb43835c57c00783390a02d72daf4f78e26Brian Paul} 50210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 503e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 50479c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/** 505733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul * Clip a pixel span to the current buffer/window boundaries: 506733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul * DrawBuffer->_Xmin, _Xmax, _Ymin, _Ymax. This will accomplish 507733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul * window clipping and scissoring. 508733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul * Return: GL_TRUE some pixels still visible 50910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul * GL_FALSE nothing visible 51010f30eb43835c57c00783390a02d72daf4f78e26Brian Paul */ 51110f30eb43835c57c00783390a02d72daf4f78e26Brian Paulstatic GLuint 512733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paulclip_span( GLcontext *ctx, struct sw_span *span ) 51310f30eb43835c57c00783390a02d72daf4f78e26Brian Paul{ 514733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul const GLint xmin = ctx->DrawBuffer->_Xmin; 515733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul const GLint xmax = ctx->DrawBuffer->_Xmax; 516733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul const GLint ymin = ctx->DrawBuffer->_Ymin; 517733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul const GLint ymax = ctx->DrawBuffer->_Ymax; 518733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul 519733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (span->arrayMask & SPAN_XY) { 520733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* arrays of x/y pixel coords */ 521733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul const GLint *x = span->xArray; 522733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul const GLint *y = span->yArray; 523733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul const GLint n = span->end; 524733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul GLubyte *mask = span->mask; 525733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul GLint i; 526b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul if (span->arrayMask & SPAN_MASK) { 527b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul /* note: using & intead of && to reduce branches */ 528b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul for (i = 0; i < n; i++) { 529b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul mask[i] &= (x[i] >= xmin) & (x[i] < xmax) 530b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul & (y[i] >= ymin) & (y[i] < ymax); 531b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul } 532b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul } 533b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul else { 534b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul /* note: using & intead of && to reduce branches */ 535b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul for (i = 0; i < n; i++) { 536b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul mask[i] = (x[i] >= xmin) & (x[i] < xmax) 537b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul & (y[i] >= ymin) & (y[i] < ymax); 538b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul } 53910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 540733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul return GL_TRUE; /* some pixels visible */ 54110f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 542733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul else { 543733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* horizontal span of pixels */ 544733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul const GLint x = span->x; 545733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul const GLint y = span->y; 546733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul const GLint n = span->end; 547733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul 548733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* Trivial rejection tests */ 549733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (y < ymin || y >= ymax || x + n <= xmin || x >= xmax) { 550733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->end = 0; 551733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul return GL_FALSE; /* all pixels clipped */ 552733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul } 55310f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 554733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* Clip to the left */ 555733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (x < xmin) { 556733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul ASSERT(x + n > xmin); 557733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->writeAll = GL_FALSE; 558733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul BZERO(span->mask, (xmin - x) * sizeof(GLubyte)); 55910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 560733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul 561733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* Clip to right */ 562733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (x + n > xmax) { 563733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul ASSERT(x < xmax); 564733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->end = xmax - x; 56510f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 56610f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 567733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul return GL_TRUE; /* some pixels visible */ 568733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul } 56910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul} 57010f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 57110f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 572e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 57379c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/** 574e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Draw to more than one color buffer (or none). 575e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */ 5765071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paulstatic void 577733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paulmulti_write_index_span( GLcontext *ctx, struct sw_span *span ) 578e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell{ 579709892459922a32096fe9dd8261d0d92337bb02fKeith Whitwell SWcontext *swrast = SWRAST_CONTEXT(ctx); 580e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell GLuint bufferBit; 581e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 582e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* loop over four possible dest color buffers */ 583e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell for (bufferBit = 1; bufferBit <= 8; bufferBit = bufferBit << 1) { 584e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell if (bufferBit & ctx->Color.DrawDestMask) { 585e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell GLuint indexTmp[MAX_WIDTH]; 586733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul ASSERT(span->end < MAX_WIDTH); 587e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 588e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell if (bufferBit == FRONT_LEFT_BIT) 589e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell (void) (*ctx->Driver.SetDrawBuffer)( ctx, GL_FRONT_LEFT); 590e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell else if (bufferBit == FRONT_RIGHT_BIT) 591e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell (void) (*ctx->Driver.SetDrawBuffer)( ctx, GL_FRONT_RIGHT); 592e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell else if (bufferBit == BACK_LEFT_BIT) 593e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell (void) (*ctx->Driver.SetDrawBuffer)( ctx, GL_BACK_LEFT); 594e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell else 595e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell (void) (*ctx->Driver.SetDrawBuffer)( ctx, GL_BACK_RIGHT); 596e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 597e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* make copy of incoming indexes */ 598733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul MEMCPY( indexTmp, span->color.index, span->end * sizeof(GLuint) ); 599733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul 600e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell if (ctx->Color.IndexLogicOpEnabled) { 601733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul _mesa_logicop_ci_span(ctx, span, indexTmp); 602e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 603733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul 6047956292a765910077f50352d7cd0174e1e66d26cBrian Paul if (ctx->Color.IndexMask != 0xffffffff) { 605733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul _mesa_mask_index_span(ctx, span, indexTmp); 606733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul } 607733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul 608733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (span->arrayMask & SPAN_XY) { 609733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* array of pixel coords */ 610733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul (*swrast->Driver.WriteCI32Pixels)(ctx, span->end, 611733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->xArray, span->yArray, 612733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul indexTmp, span->mask); 613733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul } 614733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul else { 615733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* horizontal run of pixels */ 616733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul (*swrast->Driver.WriteCI32Span)(ctx, span->end, span->x, span->y, 617733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul indexTmp, span->mask); 618e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 619e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 620e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 621e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 622e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* restore default dest buffer */ 623e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell (void) (*ctx->Driver.SetDrawBuffer)( ctx, ctx->Color.DriverDrawBuffer); 624e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell} 625e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 626e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 62779c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/** 62810f30eb43835c57c00783390a02d72daf4f78e26Brian Paul * Draw to more than one RGBA color buffer (or none). 629f1e236987829393c81dc86ea19cb49eefe190317Brian Paul * All fragment operations, up to (but not) blending/logicop should 630f1e236987829393c81dc86ea19cb49eefe190317Brian Paul * have been done first. 63110f30eb43835c57c00783390a02d72daf4f78e26Brian Paul */ 63210f30eb43835c57c00783390a02d72daf4f78e26Brian Paulstatic void 633733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paulmulti_write_rgba_span( GLcontext *ctx, struct sw_span *span ) 63410f30eb43835c57c00783390a02d72daf4f78e26Brian Paul{ 63510f30eb43835c57c00783390a02d72daf4f78e26Brian Paul const GLuint colorMask = *((GLuint *) ctx->Color.ColorMask); 63610f30eb43835c57c00783390a02d72daf4f78e26Brian Paul GLuint bufferBit; 63710f30eb43835c57c00783390a02d72daf4f78e26Brian Paul SWcontext *swrast = SWRAST_CONTEXT(ctx); 63810f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 639733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul ASSERT(colorMask != 0x0); 640733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul 64110f30eb43835c57c00783390a02d72daf4f78e26Brian Paul if (ctx->Color.DrawBuffer == GL_NONE) 64210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul return; 64310f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 64410f30eb43835c57c00783390a02d72daf4f78e26Brian Paul /* loop over four possible dest color buffers */ 64510f30eb43835c57c00783390a02d72daf4f78e26Brian Paul for (bufferBit = 1; bufferBit <= 8; bufferBit = bufferBit << 1) { 64610f30eb43835c57c00783390a02d72daf4f78e26Brian Paul if (bufferBit & ctx->Color.DrawDestMask) { 64710f30eb43835c57c00783390a02d72daf4f78e26Brian Paul GLchan rgbaTmp[MAX_WIDTH][4]; 648733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul ASSERT(span->end < MAX_WIDTH); 64910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 65010f30eb43835c57c00783390a02d72daf4f78e26Brian Paul if (bufferBit == FRONT_LEFT_BIT) { 65110f30eb43835c57c00783390a02d72daf4f78e26Brian Paul (void) (*ctx->Driver.SetDrawBuffer)( ctx, GL_FRONT_LEFT); 65210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul ctx->DrawBuffer->Alpha = ctx->DrawBuffer->FrontLeftAlpha; 65310f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 65410f30eb43835c57c00783390a02d72daf4f78e26Brian Paul else if (bufferBit == FRONT_RIGHT_BIT) { 65510f30eb43835c57c00783390a02d72daf4f78e26Brian Paul (void) (*ctx->Driver.SetDrawBuffer)( ctx, GL_FRONT_RIGHT); 65610f30eb43835c57c00783390a02d72daf4f78e26Brian Paul ctx->DrawBuffer->Alpha = ctx->DrawBuffer->FrontRightAlpha; 65710f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 65810f30eb43835c57c00783390a02d72daf4f78e26Brian Paul else if (bufferBit == BACK_LEFT_BIT) { 65910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul (void) (*ctx->Driver.SetDrawBuffer)( ctx, GL_BACK_LEFT); 66010f30eb43835c57c00783390a02d72daf4f78e26Brian Paul ctx->DrawBuffer->Alpha = ctx->DrawBuffer->BackLeftAlpha; 66110f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 66210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul else { 66310f30eb43835c57c00783390a02d72daf4f78e26Brian Paul (void) (*ctx->Driver.SetDrawBuffer)( ctx, GL_BACK_RIGHT); 66410f30eb43835c57c00783390a02d72daf4f78e26Brian Paul ctx->DrawBuffer->Alpha = ctx->DrawBuffer->BackRightAlpha; 66510f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 66610f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 66710f30eb43835c57c00783390a02d72daf4f78e26Brian Paul /* make copy of incoming colors */ 668733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul MEMCPY( rgbaTmp, span->color.rgba, 4 * span->end * sizeof(GLchan) ); 66910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 67010f30eb43835c57c00783390a02d72daf4f78e26Brian Paul if (ctx->Color.ColorLogicOpEnabled) { 671733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul _mesa_logicop_rgba_span(ctx, span, rgbaTmp); 67210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 67310f30eb43835c57c00783390a02d72daf4f78e26Brian Paul else if (ctx->Color.BlendEnabled) { 674733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul _mesa_blend_span(ctx, span, rgbaTmp); 67510f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 676733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul 677733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (colorMask != 0xffffffff) { 678733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul _mesa_mask_rgba_span(ctx, span, rgbaTmp); 67910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 68010f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 681733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (span->arrayMask & SPAN_XY) { 682733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* array of pixel coords */ 683733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul (*swrast->Driver.WriteRGBAPixels)(ctx, span->end, 684733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->xArray, span->yArray, 685733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul (const GLchan (*)[4]) rgbaTmp, 686733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->mask); 687733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (SWRAST_CONTEXT(ctx)->_RasterMask & ALPHABUF_BIT) { 688733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul _mesa_write_alpha_pixels(ctx, span->end, 689733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->xArray, span->yArray, 690733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul (const GLchan (*)[4]) rgbaTmp, 691733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->mask); 692733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul } 693733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul } 694733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul else { 695733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* horizontal run of pixels */ 696733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul (*swrast->Driver.WriteRGBASpan)(ctx, span->end, span->x, span->y, 697733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul (const GLchan (*)[4]) rgbaTmp, 698733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->mask); 699733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (swrast->_RasterMask & ALPHABUF_BIT) { 700733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul _mesa_write_alpha_span(ctx, span->end, span->x, span->y, 701733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul (const GLchan (*)[4]) rgbaTmp, 702733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->mask); 703733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul } 70410f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 70510f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 70610f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 70710f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 70810f30eb43835c57c00783390a02d72daf4f78e26Brian Paul /* restore default dest buffer */ 70910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul (void) (*ctx->Driver.SetDrawBuffer)( ctx, ctx->Color.DriverDrawBuffer ); 71010f30eb43835c57c00783390a02d72daf4f78e26Brian Paul} 71110f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 71210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 713e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 71479c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/** 7157956292a765910077f50352d7cd0174e1e66d26cBrian Paul * This function may modify any of the array values in the span. 7167956292a765910077f50352d7cd0174e1e66d26cBrian Paul * span->interpMask and span->arrayMask may be changed but will be restored 7177956292a765910077f50352d7cd0174e1e66d26cBrian Paul * to their original values before returning. 71810f30eb43835c57c00783390a02d72daf4f78e26Brian Paul */ 71910f30eb43835c57c00783390a02d72daf4f78e26Brian Paulvoid 7202a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul_mesa_write_index_span( GLcontext *ctx, struct sw_span *span, 7212a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLenum primitive) 72210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul{ 72310f30eb43835c57c00783390a02d72daf4f78e26Brian Paul SWcontext *swrast = SWRAST_CONTEXT(ctx); 7247956292a765910077f50352d7cd0174e1e66d26cBrian Paul const GLuint origInterpMask = span->interpMask; 7252a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul const GLuint origArrayMask = span->arrayMask; 72610f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 727733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul ASSERT(span->end <= MAX_WIDTH); 728733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul ASSERT((span->interpMask | span->arrayMask) & SPAN_INDEX); 7297956292a765910077f50352d7cd0174e1e66d26cBrian Paul ASSERT((span->interpMask & span->arrayMask) == 0); 7307956292a765910077f50352d7cd0174e1e66d26cBrian Paul 731733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (span->arrayMask & SPAN_MASK) { 732733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* mask was initialized by caller, probably glBitmap */ 733733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->writeAll = GL_FALSE; 734733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul } 735733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul else { 736733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul MEMSET(span->mask, 1, span->end); 737733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->writeAll = GL_TRUE; 73810f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 73910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 740733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* Clipping */ 741733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if ((swrast->_RasterMask & CLIP_BIT) || (primitive == GL_BITMAP) 742b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul || (primitive == GL_POINT) || (primitive == GL_LINE)) { 743733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (!clip_span(ctx, span)) { 74486ca15ece74ccb5a8f4d566a4b2c8024b178d73bBrian Paul return; 745e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 746e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 747e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 748b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul#ifdef DEBUG 749b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul if (span->arrayMask & SPAN_XY) { 750b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul int i; 751b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul for (i = 0; i < span->end; i++) { 752b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul if (span->mask[i]) { 753b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul assert(span->xArray[i] >= ctx->DrawBuffer->_Xmin); 754b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul assert(span->xArray[i] < ctx->DrawBuffer->_Xmax); 755b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul assert(span->yArray[i] >= ctx->DrawBuffer->_Ymin); 756b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul assert(span->yArray[i] < ctx->DrawBuffer->_Ymax); 757b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul } 758b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul } 759b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul } 760b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul#endif 761b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul 762e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* Polygon Stippling */ 763733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (ctx->Polygon.StippleFlag && primitive == GL_POLYGON) { 76410f30eb43835c57c00783390a02d72daf4f78e26Brian Paul stipple_polygon_span(ctx, span); 765e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 766e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 7677956292a765910077f50352d7cd0174e1e66d26cBrian Paul /* Depth test and stencil */ 7687956292a765910077f50352d7cd0174e1e66d26cBrian Paul if (ctx->Depth.Test || ctx->Stencil.Enabled) { 7697956292a765910077f50352d7cd0174e1e66d26cBrian Paul if (span->interpMask & SPAN_Z) 770711e27fda27e4235b20a4cf73c2767c984ab2b81Brian Paul _mesa_span_interpolate_z(ctx, span); 77110f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 7727956292a765910077f50352d7cd0174e1e66d26cBrian Paul if (ctx->Stencil.Enabled) { 77379c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul if (!_mesa_stencil_and_ztest_span(ctx, span)) { 7747956292a765910077f50352d7cd0174e1e66d26cBrian Paul span->arrayMask = origArrayMask; 7757956292a765910077f50352d7cd0174e1e66d26cBrian Paul return; 7767956292a765910077f50352d7cd0174e1e66d26cBrian Paul } 7772a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 7787956292a765910077f50352d7cd0174e1e66d26cBrian Paul else { 7797956292a765910077f50352d7cd0174e1e66d26cBrian Paul ASSERT(ctx->Depth.Test); 78079c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul if (!_mesa_depth_test_span(ctx, span)) { 7817956292a765910077f50352d7cd0174e1e66d26cBrian Paul span->arrayMask = origArrayMask; 7827956292a765910077f50352d7cd0174e1e66d26cBrian Paul return; 7837956292a765910077f50352d7cd0174e1e66d26cBrian Paul } 7842a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 78510f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 78610f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 78710f30eb43835c57c00783390a02d72daf4f78e26Brian Paul /* if we get here, something passed the depth test */ 78810f30eb43835c57c00783390a02d72daf4f78e26Brian Paul ctx->OcclusionResult = GL_TRUE; 78910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 7907956292a765910077f50352d7cd0174e1e66d26cBrian Paul /* we have to wait until after occlusion to do this test */ 7917956292a765910077f50352d7cd0174e1e66d26cBrian Paul if (ctx->Color.DrawBuffer == GL_NONE || ctx->Color.IndexMask == 0) { 79210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul /* write no pixels */ 7932a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->arrayMask = origArrayMask; 79410f30eb43835c57c00783390a02d72daf4f78e26Brian Paul return; 79510f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 79610f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 7977956292a765910077f50352d7cd0174e1e66d26cBrian Paul /* Interpolate the color indexes if needed */ 7987956292a765910077f50352d7cd0174e1e66d26cBrian Paul if (span->interpMask & SPAN_INDEX) { 7992a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul interpolate_indexes(ctx, span); 8007956292a765910077f50352d7cd0174e1e66d26cBrian Paul /* clear the bit - this allows the WriteMonoCISpan optimization below */ 8017956292a765910077f50352d7cd0174e1e66d26cBrian Paul span->interpMask &= ~SPAN_INDEX; 8027956292a765910077f50352d7cd0174e1e66d26cBrian Paul } 80310f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 8047956292a765910077f50352d7cd0174e1e66d26cBrian Paul /* Fog */ 8052a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul if (ctx->Fog.Enabled) { 806711e27fda27e4235b20a4cf73c2767c984ab2b81Brian Paul _mesa_fog_ci_span(ctx, span); 807e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 808e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 8092a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul /* Antialias coverage application */ 8102a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul if (span->arrayMask & SPAN_COVERAGE) { 8112a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLuint i; 8127956292a765910077f50352d7cd0174e1e66d26cBrian Paul GLuint *index = span->color.index; 81310f30eb43835c57c00783390a02d72daf4f78e26Brian Paul for (i = 0; i < span->end; i++) { 8142a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul ASSERT(span->coverage[i] < 16); 8152a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul index[i] = (index[i] & ~0xf) | ((GLuint) (span->coverage[i])); 8165071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paul } 8172a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 8185071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paul 8192a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul if (swrast->_RasterMask & MULTI_DRAW_BIT) { 8202a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul /* draw to zero or two or more buffers */ 821733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul multi_write_index_span(ctx, span); 822e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 823e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell else { 8242a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul /* normal situation: draw to exactly one buffer */ 8252a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul if (ctx->Color.IndexLogicOpEnabled) { 826733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul _mesa_logicop_ci_span(ctx, span, span->color.index); 82710f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 8282a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 8297956292a765910077f50352d7cd0174e1e66d26cBrian Paul if (ctx->Color.IndexMask != 0xffffffff) { 830733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul _mesa_mask_index_span(ctx, span, span->color.index); 831e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 8322a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 8332a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul /* write pixels */ 834733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (span->arrayMask & SPAN_XY) { 835733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* array of pixel coords */ 836733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if ((span->interpMask & SPAN_INDEX) && span->indexStep == 0) { 837733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* all pixels have same color index */ 838733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul (*swrast->Driver.WriteMonoCIPixels)(ctx, span->end, 839733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->xArray, span->yArray, 840733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul FixedToInt(span->index), 841733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->mask); 842733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul } 843733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul else { 844733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul (*swrast->Driver.WriteCI32Pixels)(ctx, span->end, span->xArray, 845733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->yArray, span->color.index, 846733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->mask ); 847733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul } 8487956292a765910077f50352d7cd0174e1e66d26cBrian Paul } 8497956292a765910077f50352d7cd0174e1e66d26cBrian Paul else { 850733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* horizontal run of pixels */ 851733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if ((span->interpMask & SPAN_INDEX) && span->indexStep == 0) { 852733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* all pixels have same color index */ 853733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul (*swrast->Driver.WriteMonoCISpan)(ctx, span->end, span->x, span->y, 854733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul FixedToInt(span->index), 855733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->mask); 856733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul } 857733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul else { 858733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul (*swrast->Driver.WriteCI32Span)(ctx, span->end, span->x, span->y, 859733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->color.index, span->mask); 860733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul } 8617956292a765910077f50352d7cd0174e1e66d26cBrian Paul } 862e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 8632a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 8647956292a765910077f50352d7cd0174e1e66d26cBrian Paul span->interpMask = origInterpMask; 8652a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->arrayMask = origArrayMask; 866e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell} 867e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 868e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 86979c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/** 8707956292a765910077f50352d7cd0174e1e66d26cBrian Paul * This function may modify any of the array values in the span. 8717956292a765910077f50352d7cd0174e1e66d26cBrian Paul * span->interpMask and span->arrayMask may be changed but will be restored 8727956292a765910077f50352d7cd0174e1e66d26cBrian Paul * to their original values before returning. 8735d2621928823a06006c1586efe78fe8bf65a7e1fBrian Paul */ 8745071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paulvoid 87510f30eb43835c57c00783390a02d72daf4f78e26Brian Paul_mesa_write_rgba_span( GLcontext *ctx, struct sw_span *span, 8762a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLenum primitive) 877e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell{ 878cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell SWcontext *swrast = SWRAST_CONTEXT(ctx); 8797956292a765910077f50352d7cd0174e1e66d26cBrian Paul const GLuint colorMask = *((GLuint *) ctx->Color.ColorMask); 8807956292a765910077f50352d7cd0174e1e66d26cBrian Paul const GLuint origInterpMask = span->interpMask; 8812a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul const GLuint origArrayMask = span->arrayMask; 8827956292a765910077f50352d7cd0174e1e66d26cBrian Paul GLboolean monoColor; 8837956292a765910077f50352d7cd0174e1e66d26cBrian Paul 884733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul ASSERT(span->end <= MAX_WIDTH); 8857956292a765910077f50352d7cd0174e1e66d26cBrian Paul ASSERT((span->interpMask & span->arrayMask) == 0); 886ceb39f4f8dc4863fde17d668c752533a2184476eBrian Paul ASSERT((span->interpMask | span->arrayMask) & SPAN_RGBA); 887bcb148de9201c7f90a68c7c46434e7ebf7204000Brian Paul#ifdef DEBUG 888733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (ctx->Fog.Enabled) 889733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul ASSERT((span->interpMask | span->arrayMask) & SPAN_FOG); 890bcb148de9201c7f90a68c7c46434e7ebf7204000Brian Paul if (ctx->Depth.Test) 891bcb148de9201c7f90a68c7c46434e7ebf7204000Brian Paul ASSERT((span->interpMask | span->arrayMask) & SPAN_Z); 892bcb148de9201c7f90a68c7c46434e7ebf7204000Brian Paul#endif 893733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul 894733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* 895bcb148de9201c7f90a68c7c46434e7ebf7204000Brian Paul printf("%s() interp 0x%x array 0x%x p=0x%x\n", __FUNCTION__, span->interpMask, span->arrayMask, primitive); 896733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul */ 897e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 898733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (span->arrayMask & SPAN_MASK) { 899733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* mask was initialized by caller, probably glBitmap */ 900733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->writeAll = GL_FALSE; 901733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul } 902733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul else { 903733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul MEMSET(span->mask, 1, span->end); 904733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->writeAll = GL_TRUE; 905733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul } 906e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 9077956292a765910077f50352d7cd0174e1e66d26cBrian Paul /* Determine if we have mono-chromatic colors */ 9087956292a765910077f50352d7cd0174e1e66d26cBrian Paul monoColor = (span->interpMask & SPAN_RGBA) && 9097956292a765910077f50352d7cd0174e1e66d26cBrian Paul span->redStep == 0 && span->greenStep == 0 && 9107956292a765910077f50352d7cd0174e1e66d26cBrian Paul span->blueStep == 0 && span->alphaStep == 0; 9117956292a765910077f50352d7cd0174e1e66d26cBrian Paul 912733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* Clipping */ 913733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if ((swrast->_RasterMask & CLIP_BIT) || (primitive == GL_BITMAP) 914b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul || (primitive == GL_POINT) || (primitive == GL_LINE)) { 915733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (!clip_span(ctx, span)) { 91686ca15ece74ccb5a8f4d566a4b2c8024b178d73bBrian Paul return; 917e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 918e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 919e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 920b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul#ifdef DEBUG 921b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul if (span->arrayMask & SPAN_XY) { 922b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul int i; 923b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul for (i = 0; i < span->end; i++) { 924b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul if (span->mask[i]) { 925b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul assert(span->xArray[i] >= ctx->DrawBuffer->_Xmin); 926b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul assert(span->xArray[i] < ctx->DrawBuffer->_Xmax); 927b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul assert(span->yArray[i] >= ctx->DrawBuffer->_Ymin); 928b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul assert(span->yArray[i] < ctx->DrawBuffer->_Ymax); 929b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul } 930b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul } 931b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul } 932b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul#endif 933b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul 934e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* Polygon Stippling */ 9357956292a765910077f50352d7cd0174e1e66d26cBrian Paul if (ctx->Polygon.StippleFlag && primitive == GL_POLYGON) { 9367956292a765910077f50352d7cd0174e1e66d26cBrian Paul stipple_polygon_span(ctx, span); 93710f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 93810f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 939e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* Do the alpha test */ 940e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell if (ctx->Color.AlphaEnabled) { 941ceb39f4f8dc4863fde17d668c752533a2184476eBrian Paul if (!_mesa_alpha_test(ctx, span)) { 9427956292a765910077f50352d7cd0174e1e66d26cBrian Paul span->interpMask = origInterpMask; 9432a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->arrayMask = origArrayMask; 944e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell return; 945e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 94610f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 94710f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 948f1e236987829393c81dc86ea19cb49eefe190317Brian Paul /* Stencil and Z testing */ 949f1e236987829393c81dc86ea19cb49eefe190317Brian Paul if (ctx->Stencil.Enabled || ctx->Depth.Test) { 950f1e236987829393c81dc86ea19cb49eefe190317Brian Paul if (span->interpMask & SPAN_Z) 951711e27fda27e4235b20a4cf73c2767c984ab2b81Brian Paul _mesa_span_interpolate_z(ctx, span); 952f1e236987829393c81dc86ea19cb49eefe190317Brian Paul 953f1e236987829393c81dc86ea19cb49eefe190317Brian Paul if (ctx->Stencil.Enabled) { 954f1e236987829393c81dc86ea19cb49eefe190317Brian Paul if (!_mesa_stencil_and_ztest_span(ctx, span)) { 9557956292a765910077f50352d7cd0174e1e66d26cBrian Paul span->interpMask = origInterpMask; 956f1e236987829393c81dc86ea19cb49eefe190317Brian Paul span->arrayMask = origArrayMask; 957f1e236987829393c81dc86ea19cb49eefe190317Brian Paul return; 95810f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 95910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 96010f30eb43835c57c00783390a02d72daf4f78e26Brian Paul else { 961f1e236987829393c81dc86ea19cb49eefe190317Brian Paul ASSERT(ctx->Depth.Test); 962f1e236987829393c81dc86ea19cb49eefe190317Brian Paul ASSERT(span->arrayMask & SPAN_Z); 963f1e236987829393c81dc86ea19cb49eefe190317Brian Paul /* regular depth testing */ 964f1e236987829393c81dc86ea19cb49eefe190317Brian Paul if (!_mesa_depth_test_span(ctx, span)) { 9657956292a765910077f50352d7cd0174e1e66d26cBrian Paul span->interpMask = origInterpMask; 966f1e236987829393c81dc86ea19cb49eefe190317Brian Paul span->arrayMask = origArrayMask; 967f1e236987829393c81dc86ea19cb49eefe190317Brian Paul return; 96810f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 96910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 970e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 971e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 972e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* if we get here, something passed the depth test */ 973e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell ctx->OcclusionResult = GL_TRUE; 974e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 9757956292a765910077f50352d7cd0174e1e66d26cBrian Paul /* can't abort span-writing until after occlusion testing */ 9767956292a765910077f50352d7cd0174e1e66d26cBrian Paul if (colorMask == 0x0) { 9777956292a765910077f50352d7cd0174e1e66d26cBrian Paul span->interpMask = origInterpMask; 9787956292a765910077f50352d7cd0174e1e66d26cBrian Paul span->arrayMask = origArrayMask; 9797956292a765910077f50352d7cd0174e1e66d26cBrian Paul return; 9807956292a765910077f50352d7cd0174e1e66d26cBrian Paul } 9817956292a765910077f50352d7cd0174e1e66d26cBrian Paul 982ceb39f4f8dc4863fde17d668c752533a2184476eBrian Paul /* Now we may need to interpolate the colors */ 983ceb39f4f8dc4863fde17d668c752533a2184476eBrian Paul if ((span->interpMask & SPAN_RGBA) && (span->arrayMask & SPAN_RGBA) == 0) { 984ceb39f4f8dc4863fde17d668c752533a2184476eBrian Paul interpolate_colors(ctx, span); 985ceb39f4f8dc4863fde17d668c752533a2184476eBrian Paul /* clear the bit - this allows the WriteMonoCISpan optimization below */ 986ceb39f4f8dc4863fde17d668c752533a2184476eBrian Paul span->interpMask &= ~SPAN_RGBA; 987ceb39f4f8dc4863fde17d668c752533a2184476eBrian Paul } 988ceb39f4f8dc4863fde17d668c752533a2184476eBrian Paul 9896e1666437ea091ecc50ab2b56d87129318f641d2Brian Paul /* Fog */ 990b38ad54c41aec2d08fdd26a4a8ea4dcdca8b1dfdBrian Paul if (ctx->Fog.Enabled) { 991711e27fda27e4235b20a4cf73c2767c984ab2b81Brian Paul _mesa_fog_rgba_span(ctx, span); 9927956292a765910077f50352d7cd0174e1e66d26cBrian Paul monoColor = GL_FALSE; 993b38ad54c41aec2d08fdd26a4a8ea4dcdca8b1dfdBrian Paul } 994b38ad54c41aec2d08fdd26a4a8ea4dcdca8b1dfdBrian Paul 9955071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paul /* Antialias coverage application */ 9962a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul if (span->arrayMask & SPAN_COVERAGE) { 9977956292a765910077f50352d7cd0174e1e66d26cBrian Paul GLchan (*rgba)[4] = span->color.rgba; 9985071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paul GLuint i; 99910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul for (i = 0; i < span->end; i++) { 100010f30eb43835c57c00783390a02d72daf4f78e26Brian Paul rgba[i][ACOMP] = (GLchan) (rgba[i][ACOMP] * span->coverage[i]); 10015071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paul } 10027956292a765910077f50352d7cd0174e1e66d26cBrian Paul monoColor = GL_FALSE; 10035071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paul } 10045071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paul 1005cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell if (swrast->_RasterMask & MULTI_DRAW_BIT) { 1006733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul multi_write_rgba_span(ctx, span); 1007e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1008e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell else { 1009e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* normal: write to exactly one buffer */ 1010e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell if (ctx->Color.ColorLogicOpEnabled) { 1011733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul _mesa_logicop_rgba_span(ctx, span, span->color.rgba); 10127956292a765910077f50352d7cd0174e1e66d26cBrian Paul monoColor = GL_FALSE; 1013e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1014e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell else if (ctx->Color.BlendEnabled) { 1015733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul _mesa_blend_span(ctx, span, span->color.rgba); 10167956292a765910077f50352d7cd0174e1e66d26cBrian Paul monoColor = GL_FALSE; 1017e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 101895e2c72fd52d87163eb543555345f115f050f3aaBrian Paul 1019e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* Color component masking */ 10207956292a765910077f50352d7cd0174e1e66d26cBrian Paul if (colorMask != 0xffffffff) { 1021733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul _mesa_mask_rgba_span(ctx, span, span->color.rgba); 10227956292a765910077f50352d7cd0174e1e66d26cBrian Paul monoColor = GL_FALSE; 1023e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1024e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 1025e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* write pixels */ 1026733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (span->arrayMask & SPAN_XY) { 1027733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* array of pixel coords */ 1028733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* XXX test for mono color */ 1029733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul (*swrast->Driver.WriteRGBAPixels)(ctx, span->end, span->xArray, 1030733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->yArray, (const GLchan (*)[4]) span->color.rgba, span->mask); 1031733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (SWRAST_CONTEXT(ctx)->_RasterMask & ALPHABUF_BIT) { 1032733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul _mesa_write_alpha_pixels(ctx, span->end, 1033733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->xArray, span->yArray, 1034733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul (const GLchan (*)[4]) span->color.rgba, 1035733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->mask); 1036733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul } 1037e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1038e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell else { 1039733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* horizontal run of pixels */ 1040733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (monoColor) { 1041733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* all pixels have same color */ 1042733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul GLchan color[4]; 1043733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul color[RCOMP] = FixedToChan(span->red); 1044733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul color[GCOMP] = FixedToChan(span->green); 1045733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul color[BCOMP] = FixedToChan(span->blue); 1046733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul color[ACOMP] = FixedToChan(span->alpha); 1047733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul (*swrast->Driver.WriteMonoRGBASpan)(ctx, span->end, span->x, 1048733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->y, color, span->mask); 1049733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* XXX software alpha buffer writes! */ 1050733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul } 1051733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul else { 1052733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* each pixel is a different color */ 1053733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul (*swrast->Driver.WriteRGBASpan)(ctx, span->end, span->x, span->y, 10547956292a765910077f50352d7cd0174e1e66d26cBrian Paul (const GLchan (*)[4]) span->color.rgba, 1055733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->writeAll ? ((const GLubyte *) NULL) : span->mask); 1056733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (swrast->_RasterMask & ALPHABUF_BIT) { 1057733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul _mesa_write_alpha_span(ctx, span->end, span->x, span->y, 10587956292a765910077f50352d7cd0174e1e66d26cBrian Paul (const GLchan (*)[4]) span->color.rgba, 1059733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->writeAll ? ((const GLubyte *) NULL) : span->mask); 1060733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul } 1061733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul } 1062e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1063e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1064e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 10657956292a765910077f50352d7cd0174e1e66d26cBrian Paul span->interpMask = origInterpMask; 10667956292a765910077f50352d7cd0174e1e66d26cBrian Paul span->arrayMask = origArrayMask; 10677956292a765910077f50352d7cd0174e1e66d26cBrian Paul} 1068e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 1069e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 107079c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/** 1071e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Add specular color to base color. This is used only when 1072f1e236987829393c81dc86ea19cb49eefe190317Brian Paul * GL_LIGHT_MODEL_COLOR_CONTROL = GL_SEPARATE_SPECULAR_COLOR. 1073e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */ 10745071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paulstatic void 1075f1e236987829393c81dc86ea19cb49eefe190317Brian Pauladd_colors(GLuint n, GLchan rgba[][4], GLchan specular[][4] ) 1076e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell{ 1077e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell GLuint i; 1078f1e236987829393c81dc86ea19cb49eefe190317Brian Paul for (i = 0; i < n; i++) { 10794fa5c1966a985f81c615a9f5ef2f64dd466b252aBrian Paul#if CHAN_TYPE == GL_FLOAT 10804fa5c1966a985f81c615a9f5ef2f64dd466b252aBrian Paul /* no clamping */ 1081f1e236987829393c81dc86ea19cb49eefe190317Brian Paul rgba[i][RCOMP] += specular[i][RCOMP]; 1082f1e236987829393c81dc86ea19cb49eefe190317Brian Paul rgba[i][GCOMP] += specular[i][GCOMP]; 1083f1e236987829393c81dc86ea19cb49eefe190317Brian Paul rgba[i][BCOMP] += specular[i][BCOMP]; 10844fa5c1966a985f81c615a9f5ef2f64dd466b252aBrian Paul#else 1085f1e236987829393c81dc86ea19cb49eefe190317Brian Paul GLint r = rgba[i][RCOMP] + specular[i][RCOMP]; 1086f1e236987829393c81dc86ea19cb49eefe190317Brian Paul GLint g = rgba[i][GCOMP] + specular[i][GCOMP]; 1087f1e236987829393c81dc86ea19cb49eefe190317Brian Paul GLint b = rgba[i][BCOMP] + specular[i][BCOMP]; 1088e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell rgba[i][RCOMP] = (GLchan) MIN2(r, CHAN_MAX); 1089e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell rgba[i][GCOMP] = (GLchan) MIN2(g, CHAN_MAX); 1090e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell rgba[i][BCOMP] = (GLchan) MIN2(b, CHAN_MAX); 10914fa5c1966a985f81c615a9f5ef2f64dd466b252aBrian Paul#endif 1092e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1093e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell} 1094e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 1095e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 109679c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/** 1097f1e236987829393c81dc86ea19cb49eefe190317Brian Paul * This function may modify any of the array values in the span. 10987956292a765910077f50352d7cd0174e1e66d26cBrian Paul * span->interpMask and span->arrayMask may be changed but will be restored 10997956292a765910077f50352d7cd0174e1e66d26cBrian Paul * to their original values before returning. 110078940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul */ 110178940758e90069ceaca2b6cddb6438488fbad5ccBrian Paulvoid 110278940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul_mesa_write_texture_span( GLcontext *ctx, struct sw_span *span, 1103f1e236987829393c81dc86ea19cb49eefe190317Brian Paul GLenum primitive ) 110478940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul{ 110578940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul const GLuint colorMask = *((GLuint *) ctx->Color.ColorMask); 110678940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul SWcontext *swrast = SWRAST_CONTEXT(ctx); 1107f1e236987829393c81dc86ea19cb49eefe190317Brian Paul const GLuint origArrayMask = span->arrayMask; 1108f1e236987829393c81dc86ea19cb49eefe190317Brian Paul 1109733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul ASSERT(span->end <= MAX_WIDTH); 11107956292a765910077f50352d7cd0174e1e66d26cBrian Paul ASSERT((span->interpMask & span->arrayMask) == 0); 1111f1e236987829393c81dc86ea19cb49eefe190317Brian Paul ASSERT(ctx->Texture._ReallyEnabled); 111278940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul 1113ceb39f4f8dc4863fde17d668c752533a2184476eBrian Paul /* 1114ceb39f4f8dc4863fde17d668c752533a2184476eBrian Paul printf("%s() interp 0x%x array 0x%x\n", __FUNCTION__, span->interpMask, span->arrayMask); 1115ceb39f4f8dc4863fde17d668c752533a2184476eBrian Paul */ 1116ceb39f4f8dc4863fde17d668c752533a2184476eBrian Paul 1117733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (span->arrayMask & SPAN_MASK) { 1118733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* mask was initialized by caller, probably glBitmap */ 1119733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->writeAll = GL_FALSE; 1120733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul } 1121733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul else { 1122733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul MEMSET(span->mask, 1, span->end); 1123733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->writeAll = GL_TRUE; 112478940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul } 112578940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul 1126733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* Clipping */ 1127733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if ((swrast->_RasterMask & CLIP_BIT) || (primitive == GL_BITMAP) 1128b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul || (primitive == GL_POINT) || (primitive == GL_LINE)) { 1129733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (!clip_span(ctx, span)) { 1130733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul return; 113178940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul } 113278940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul } 113378940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul 1134b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul#ifdef DEBUG 1135b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul if (span->arrayMask & SPAN_XY) { 1136b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul int i; 1137b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul for (i = 0; i < span->end; i++) { 1138b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul if (span->mask[i]) { 1139b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul assert(span->xArray[i] >= ctx->DrawBuffer->_Xmin); 1140b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul assert(span->xArray[i] < ctx->DrawBuffer->_Xmax); 1141b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul assert(span->yArray[i] >= ctx->DrawBuffer->_Ymin); 1142b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul assert(span->yArray[i] < ctx->DrawBuffer->_Ymax); 1143b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul } 1144b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul } 1145b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul } 1146b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul#endif 1147b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul 114878940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul /* Polygon Stippling */ 1149733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (ctx->Polygon.StippleFlag && primitive == GL_POLYGON) { 1150733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul stipple_polygon_span(ctx, span); 115178940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul } 115278940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul 1153f1e236987829393c81dc86ea19cb49eefe190317Brian Paul /* Need texture coordinates now */ 1154f1e236987829393c81dc86ea19cb49eefe190317Brian Paul if ((span->interpMask & SPAN_TEXTURE) 1155f1e236987829393c81dc86ea19cb49eefe190317Brian Paul && (span->arrayMask & SPAN_TEXTURE) == 0) 1156f1e236987829393c81dc86ea19cb49eefe190317Brian Paul interpolate_texcoords(ctx, span); 115778940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul 115878940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul /* Texture with alpha test */ 115978940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul if (ctx->Color.AlphaEnabled) { 1160f1e236987829393c81dc86ea19cb49eefe190317Brian Paul 1161f1e236987829393c81dc86ea19cb49eefe190317Brian Paul /* Now we need the rgba array, fill it in if needed */ 1162f1e236987829393c81dc86ea19cb49eefe190317Brian Paul if ((span->interpMask & SPAN_RGBA) && (span->arrayMask & SPAN_RGBA) == 0) 1163f1e236987829393c81dc86ea19cb49eefe190317Brian Paul interpolate_colors(ctx, span); 1164f1e236987829393c81dc86ea19cb49eefe190317Brian Paul 116578940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul /* Texturing without alpha is done after depth-testing which 1166f1e236987829393c81dc86ea19cb49eefe190317Brian Paul * gives a potential speed-up. 1167f1e236987829393c81dc86ea19cb49eefe190317Brian Paul */ 1168f1e236987829393c81dc86ea19cb49eefe190317Brian Paul _swrast_multitexture_fragments( ctx, span ); 116978940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul 117078940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul /* Do the alpha test */ 1171ceb39f4f8dc4863fde17d668c752533a2184476eBrian Paul if (!_mesa_alpha_test(ctx, span)) { 1172f1e236987829393c81dc86ea19cb49eefe190317Brian Paul span->arrayMask = origArrayMask; 1173ceb39f4f8dc4863fde17d668c752533a2184476eBrian Paul return; 117478940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul } 117578940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul } 117678940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul 1177f1e236987829393c81dc86ea19cb49eefe190317Brian Paul /* Stencil and Z testing */ 1178f1e236987829393c81dc86ea19cb49eefe190317Brian Paul if (ctx->Stencil.Enabled || ctx->Depth.Test) { 1179f1e236987829393c81dc86ea19cb49eefe190317Brian Paul if (span->interpMask & SPAN_Z) 1180711e27fda27e4235b20a4cf73c2767c984ab2b81Brian Paul _mesa_span_interpolate_z(ctx, span); 118178940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul 118271340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul if (ctx->Stencil.Enabled) { 1183f1e236987829393c81dc86ea19cb49eefe190317Brian Paul if (!_mesa_stencil_and_ztest_span(ctx, span)) { 1184f1e236987829393c81dc86ea19cb49eefe190317Brian Paul span->arrayMask = origArrayMask; 118510f30eb43835c57c00783390a02d72daf4f78e26Brian Paul return; 1186f1e236987829393c81dc86ea19cb49eefe190317Brian Paul } 118771340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 1188f1e236987829393c81dc86ea19cb49eefe190317Brian Paul else { 1189f1e236987829393c81dc86ea19cb49eefe190317Brian Paul ASSERT(ctx->Depth.Test); 1190f1e236987829393c81dc86ea19cb49eefe190317Brian Paul ASSERT(span->arrayMask & SPAN_Z); 119110f30eb43835c57c00783390a02d72daf4f78e26Brian Paul /* regular depth testing */ 1192f1e236987829393c81dc86ea19cb49eefe190317Brian Paul if (!_mesa_depth_test_span(ctx, span)) { 1193f1e236987829393c81dc86ea19cb49eefe190317Brian Paul span->arrayMask = origArrayMask; 119410f30eb43835c57c00783390a02d72daf4f78e26Brian Paul return; 1195f1e236987829393c81dc86ea19cb49eefe190317Brian Paul } 119671340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 119771340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 119871340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul 1199f1e236987829393c81dc86ea19cb49eefe190317Brian Paul /* if we get here, some fragments passed the depth test */ 120071340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul ctx->OcclusionResult = GL_TRUE; 120171340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul 1202f1e236987829393c81dc86ea19cb49eefe190317Brian Paul /* We had to wait until now to check for glColorMask(F,F,F,F) because of 1203f1e236987829393c81dc86ea19cb49eefe190317Brian Paul * the occlusion test. 1204f1e236987829393c81dc86ea19cb49eefe190317Brian Paul */ 1205f1e236987829393c81dc86ea19cb49eefe190317Brian Paul if (colorMask == 0x0) { 1206f1e236987829393c81dc86ea19cb49eefe190317Brian Paul span->arrayMask = origArrayMask; 1207f1e236987829393c81dc86ea19cb49eefe190317Brian Paul return; 120871340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 120971340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul 1210f1e236987829393c81dc86ea19cb49eefe190317Brian Paul /* Texture without alpha test */ 1211f1e236987829393c81dc86ea19cb49eefe190317Brian Paul if (!ctx->Color.AlphaEnabled) { 121271340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul 1213f1e236987829393c81dc86ea19cb49eefe190317Brian Paul /* Now we need the rgba array, fill it in if needed */ 1214f1e236987829393c81dc86ea19cb49eefe190317Brian Paul if ((span->interpMask & SPAN_RGBA) && (span->arrayMask & SPAN_RGBA) == 0) 1215f1e236987829393c81dc86ea19cb49eefe190317Brian Paul interpolate_colors(ctx, span); 121671340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul 1217f1e236987829393c81dc86ea19cb49eefe190317Brian Paul _swrast_multitexture_fragments( ctx, span ); 121871340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 121971340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul 1220f1e236987829393c81dc86ea19cb49eefe190317Brian Paul ASSERT(span->arrayMask & SPAN_RGBA); 12212ef866d1fc0a5cc5ef8543d65744dfd4da4dbbafBrian Paul 1222f1e236987829393c81dc86ea19cb49eefe190317Brian Paul /* Add base and specular colors */ 1223f1e236987829393c81dc86ea19cb49eefe190317Brian Paul if (ctx->Fog.ColorSumEnabled || 1224f1e236987829393c81dc86ea19cb49eefe190317Brian Paul (ctx->Light.Enabled && 1225f1e236987829393c81dc86ea19cb49eefe190317Brian Paul ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR)) { 1226f1e236987829393c81dc86ea19cb49eefe190317Brian Paul if (span->interpMask & SPAN_SPEC) { 1227f1e236987829393c81dc86ea19cb49eefe190317Brian Paul interpolate_specular(ctx, span); 122871340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 1229f1e236987829393c81dc86ea19cb49eefe190317Brian Paul ASSERT(span->arrayMask & SPAN_SPEC); 1230f1e236987829393c81dc86ea19cb49eefe190317Brian Paul add_colors( span->end, span->color.rgba, span->specArray ); 123171340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 123271340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul 12336e1666437ea091ecc50ab2b56d87129318f641d2Brian Paul /* Fog */ 123471340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul if (ctx->Fog.Enabled) { 1235711e27fda27e4235b20a4cf73c2767c984ab2b81Brian Paul _mesa_fog_rgba_span(ctx, span); 123671340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 1237f1e236987829393c81dc86ea19cb49eefe190317Brian Paul 123871340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul /* Antialias coverage application */ 12392a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul if (span->arrayMask & SPAN_COVERAGE) { 1240f1e236987829393c81dc86ea19cb49eefe190317Brian Paul GLchan (*rgba)[4] = span->color.rgba; 124171340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul GLuint i; 124210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul for (i = 0; i < span->end; i++) { 124310f30eb43835c57c00783390a02d72daf4f78e26Brian Paul rgba[i][ACOMP] = (GLchan) (rgba[i][ACOMP] * span->coverage[i]); 124471340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 124571340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 124671340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul 124771340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul if (swrast->_RasterMask & MULTI_DRAW_BIT) { 1248733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul multi_write_rgba_span(ctx, span); 124971340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 125071340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul else { 125171340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul /* normal: write to exactly one buffer */ 125271340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul if (ctx->Color.ColorLogicOpEnabled) { 1253733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul _mesa_logicop_rgba_span(ctx, span, span->color.rgba); 125471340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 125595e2c72fd52d87163eb543555345f115f050f3aaBrian Paul else if (ctx->Color.BlendEnabled) { 1256733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul _mesa_blend_span(ctx, span, span->color.rgba); 125771340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 125871340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul 1259f1e236987829393c81dc86ea19cb49eefe190317Brian Paul if (colorMask != 0xffffffff) { 1260733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul _mesa_mask_rgba_span(ctx, span, span->color.rgba); 126171340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 126271340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul 1263733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul 1264733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (span->arrayMask & SPAN_XY) { 1265733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* array of pixel coords */ 1266733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul (*swrast->Driver.WriteRGBAPixels)(ctx, span->end, span->xArray, 1267733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->yArray, (const GLchan (*)[4]) span->color.rgba, span->mask); 1268733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (SWRAST_CONTEXT(ctx)->_RasterMask & ALPHABUF_BIT) { 1269733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul _mesa_write_alpha_pixels(ctx, span->end, 1270733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->xArray, span->yArray, 1271733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul (const GLchan (*)[4]) span->color.rgba, 1272733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->mask); 1273733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul } 1274733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul } 1275733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul else { 1276733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* horizontal run of pixels */ 1277733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul (*swrast->Driver.WriteRGBASpan)(ctx, span->end, span->x, span->y, 1278f1e236987829393c81dc86ea19cb49eefe190317Brian Paul (const GLchan (*)[4]) span->color.rgba, 1279733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->writeAll ? NULL : span->mask); 1280733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (swrast->_RasterMask & ALPHABUF_BIT) { 1281733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul _mesa_write_alpha_span(ctx, span->end, span->x, span->y, 1282733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul (const GLchan (*)[4]) span->color.rgba, 1283733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->writeAll ? NULL : span->mask); 1284733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul } 128571340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 128671340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 128771340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul 1288f1e236987829393c81dc86ea19cb49eefe190317Brian Paul span->arrayMask = origArrayMask; 128910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul} 129010f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 1291e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 1292e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 129379c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/** 1294e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Read RGBA pixels from frame buffer. Clipping will be done to prevent 1295e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * reading ouside the buffer's boundaries. 1296e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */ 12975071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paulvoid 12985071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paul_mesa_read_rgba_span( GLcontext *ctx, GLframebuffer *buffer, 12995071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paul GLuint n, GLint x, GLint y, GLchan rgba[][4] ) 1300e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell{ 1301709892459922a32096fe9dd8261d0d92337bb02fKeith Whitwell SWcontext *swrast = SWRAST_CONTEXT(ctx); 1302e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell if (y < 0 || y >= buffer->Height 1303e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell || x + (GLint) n < 0 || x >= buffer->Width) { 1304e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* completely above, below, or right */ 1305e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* XXX maybe leave undefined? */ 1306e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell BZERO(rgba, 4 * n * sizeof(GLchan)); 1307e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1308e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell else { 1309e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell GLint skip, length; 1310e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell if (x < 0) { 1311e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* left edge clippping */ 1312e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell skip = -x; 1313e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell length = (GLint) n - skip; 1314e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell if (length < 0) { 1315e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* completely left of window */ 1316e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell return; 1317e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1318e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell if (length > buffer->Width) { 1319e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell length = buffer->Width; 1320e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1321e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1322e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell else if ((GLint) (x + n) > buffer->Width) { 1323e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* right edge clipping */ 1324e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell skip = 0; 1325e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell length = buffer->Width - x; 1326e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell if (length < 0) { 1327e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* completely to right of window */ 1328e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell return; 1329e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1330e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1331e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell else { 1332e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* no clipping */ 1333e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell skip = 0; 1334e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell length = (GLint) n; 1335e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1336e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 1337709892459922a32096fe9dd8261d0d92337bb02fKeith Whitwell (*swrast->Driver.ReadRGBASpan)( ctx, length, x + skip, y, rgba + skip ); 1338e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell if (buffer->UseSoftwareAlphaBuffers) { 1339733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul _mesa_read_alpha_span(ctx, length, x + skip, y, rgba + skip); 1340e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1341e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1342e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell} 1343e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 1344e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 134579c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/** 1346e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Read CI pixels from frame buffer. Clipping will be done to prevent 1347e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * reading ouside the buffer's boundaries. 1348e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */ 13495071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paulvoid 13505071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paul_mesa_read_index_span( GLcontext *ctx, GLframebuffer *buffer, 13515071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paul GLuint n, GLint x, GLint y, GLuint indx[] ) 1352e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell{ 1353709892459922a32096fe9dd8261d0d92337bb02fKeith Whitwell SWcontext *swrast = SWRAST_CONTEXT(ctx); 1354e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell if (y < 0 || y >= buffer->Height 1355e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell || x + (GLint) n < 0 || x >= buffer->Width) { 1356e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* completely above, below, or right */ 1357e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell BZERO(indx, n * sizeof(GLuint)); 1358e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1359e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell else { 1360e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell GLint skip, length; 1361e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell if (x < 0) { 1362e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* left edge clippping */ 1363e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell skip = -x; 1364e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell length = (GLint) n - skip; 1365e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell if (length < 0) { 1366e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* completely left of window */ 1367e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell return; 1368e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1369e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell if (length > buffer->Width) { 1370e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell length = buffer->Width; 1371e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1372e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1373e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell else if ((GLint) (x + n) > buffer->Width) { 1374e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* right edge clipping */ 1375e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell skip = 0; 1376e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell length = buffer->Width - x; 1377e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell if (length < 0) { 1378e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* completely to right of window */ 1379e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell return; 1380e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1381e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1382e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell else { 1383e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* no clipping */ 1384e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell skip = 0; 1385e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell length = (GLint) n; 1386e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1387e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 1388709892459922a32096fe9dd8261d0d92337bb02fKeith Whitwell (*swrast->Driver.ReadCI32Span)( ctx, length, skip + x, y, indx + skip ); 1389e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1390e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell} 1391