s_span.c revision ad8cd6111e022c90c93df106c0fde6f64d205816
1ad8cd6111e022c90c93df106c0fde6f64d205816Brian Paul/* $Id: s_span.c,v 1.52 2002/11/09 21:28:41 brianp Exp $ */ 2e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 3e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell/* 4e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Mesa 3-D graphics library 5ad8cd6111e022c90c93df106c0fde6f64d205816Brian Paul * Version: 5.0 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" 403c63452e64df7e10aa073c6c3b9492b1d7dabbb8Brian Paul#include "imports.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) 63ad8cd6111e022c90c93df106c0fde6f64d205816Brian Paul span->z = FloatToFixed(ctx->Current.RasterPos[2] * ctx->DepthMax + 0.5F); 642a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul else 65ad8cd6111e022c90c93df106c0fde6f64d205816Brian Paul span->z = (GLint) (ctx->Current.RasterPos[2] * ctx->DepthMax + 0.5F); 662a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->zStep = 0; 672a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->interpMask |= SPAN_Z; 682a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul} 692a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 702a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 7179c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/** 722a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul * Init span's fog interpolation values to the RasterPos fog. 732a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul * Used during setup for glDraw/CopyPixels. 742a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul */ 752a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paulvoid 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 1224753d60dd070bb08d0116076bcc08025c86ce857Brian Paul/** 1234753d60dd070bb08d0116076bcc08025c86ce857Brian Paul * Init span's texcoord interpolation values to the RasterPos texcoords. 1244753d60dd070bb08d0116076bcc08025c86ce857Brian Paul * Used during setup for glDraw/CopyPixels. 1254753d60dd070bb08d0116076bcc08025c86ce857Brian Paul */ 1264753d60dd070bb08d0116076bcc08025c86ce857Brian Paulvoid 1274753d60dd070bb08d0116076bcc08025c86ce857Brian Paul_mesa_span_default_texcoords( GLcontext *ctx, struct sw_span *span ) 1284753d60dd070bb08d0116076bcc08025c86ce857Brian Paul{ 1294753d60dd070bb08d0116076bcc08025c86ce857Brian Paul GLuint i; 1304753d60dd070bb08d0116076bcc08025c86ce857Brian Paul for (i = 0; i < ctx->Const.MaxTextureUnits; i++) { 1315f60a0b50ada1865d4fc6a724366e8ea0cc9a72fBrian Paul COPY_4V(span->tex[i], ctx->Current.RasterTexCoords[i]); 1325f60a0b50ada1865d4fc6a724366e8ea0cc9a72fBrian Paul ASSIGN_4V(span->texStepX[i], 0.0F, 0.0F, 0.0F, 0.0F); 1335f60a0b50ada1865d4fc6a724366e8ea0cc9a72fBrian Paul ASSIGN_4V(span->texStepY[i], 0.0F, 0.0F, 0.0F, 0.0F); 1344753d60dd070bb08d0116076bcc08025c86ce857Brian Paul } 1354753d60dd070bb08d0116076bcc08025c86ce857Brian Paul span->interpMask |= SPAN_TEXTURE; 1364753d60dd070bb08d0116076bcc08025c86ce857Brian Paul} 1374753d60dd070bb08d0116076bcc08025c86ce857Brian Paul 1384753d60dd070bb08d0116076bcc08025c86ce857Brian Paul 1392a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul/* Fill in the span.color.rgba array from the interpolation values */ 1402a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paulstatic void 1412a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paulinterpolate_colors(GLcontext *ctx, struct sw_span *span) 1422a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul{ 1432a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfixed r = span->red; 1442a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfixed g = span->green; 1452a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfixed b = span->blue; 1462a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfixed a = span->alpha; 1472a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul const GLint dr = span->redStep; 1482a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul const GLint dg = span->greenStep; 1492a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul const GLint db = span->blueStep; 1502a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul const GLint da = span->alphaStep; 1512a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul const GLuint n = span->end; 15277df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul GLchan (*rgba)[4] = span->array->rgba; 1532a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLuint i; 1542a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 155b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul ASSERT((span->interpMask & SPAN_RGBA) && 156b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul !(span->arrayMask & SPAN_RGBA)); 1572a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 1582a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul if (span->interpMask & SPAN_FLAT) { 1592a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul /* constant color */ 1602a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLchan color[4]; 1612a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul color[RCOMP] = FixedToChan(r); 1622a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul color[GCOMP] = FixedToChan(g); 1632a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul color[BCOMP] = FixedToChan(b); 1642a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul color[ACOMP] = FixedToChan(a); 1652a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul for (i = 0; i < n; i++) { 16677df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul COPY_CHAN4(span->array->rgba[i], color); 1672a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 1682a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 1692a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul else { 1702a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul /* interpolate */ 1712a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul for (i = 0; i < n; i++) { 1722a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul rgba[i][RCOMP] = FixedToChan(r); 1732a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul rgba[i][GCOMP] = FixedToChan(g); 1742a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul rgba[i][BCOMP] = FixedToChan(b); 1752a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul rgba[i][ACOMP] = FixedToChan(a); 1762a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul r += dr; 1772a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul g += dg; 1782a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul b += db; 1792a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul a += da; 1802a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 1812a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 1822a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->arrayMask |= SPAN_RGBA; 1832a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul} 1842a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 1852a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 1862a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul/* Fill in the span.color.index array from the interpolation values */ 1872a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paulstatic void 1882a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paulinterpolate_indexes(GLcontext *ctx, struct sw_span *span) 1892a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul{ 1902a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfixed index = span->index; 1912a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul const GLint indexStep = span->indexStep; 1922a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul const GLuint n = span->end; 19377df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul GLuint *indexes = span->array->index; 1942a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLuint i; 195b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul ASSERT((span->interpMask & SPAN_INDEX) && 196b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul !(span->arrayMask & SPAN_INDEX)); 1972a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 1982a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul if ((span->interpMask & SPAN_FLAT) || (indexStep == 0)) { 1992a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul /* constant color */ 2002a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul index = FixedToInt(index); 2012a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul for (i = 0; i < n; i++) { 2022a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul indexes[i] = index; 2032a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 2042a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 2052a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul else { 2062a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul /* interpolate */ 2072a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul for (i = 0; i < n; i++) { 2082a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul indexes[i] = FixedToInt(index); 2092a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul index += indexStep; 2102a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 2112a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 2122a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->arrayMask |= SPAN_INDEX; 2132a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul} 2142a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 2152a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 21677df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul/* Fill in the span.->array->spec array from the interpolation values */ 2172a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paulstatic void 2182a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paulinterpolate_specular(GLcontext *ctx, struct sw_span *span) 2192a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul{ 2202a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul if (span->interpMask & SPAN_FLAT) { 2212a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul /* constant color */ 2222a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul const GLchan r = FixedToChan(span->specRed); 2232a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul const GLchan g = FixedToChan(span->specGreen); 2242a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul const GLchan b = FixedToChan(span->specBlue); 2252a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLuint i; 2262a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul for (i = 0; i < span->end; i++) { 22777df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul span->array->spec[i][RCOMP] = r; 22877df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul span->array->spec[i][GCOMP] = g; 22977df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul span->array->spec[i][BCOMP] = b; 2302a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 2312a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 2322a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul else { 2332a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul /* interpolate */ 2342a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul#if CHAN_TYPE == GL_FLOAT 2352a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat r = span->specRed; 2362a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat g = span->specGreen; 2372a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat b = span->specBlue; 2382a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul#else 2392a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfixed r = span->specRed; 2402a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfixed g = span->specGreen; 2412a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfixed b = span->specBlue; 2422a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul#endif 2432a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLuint i; 2442a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul for (i = 0; i < span->end; i++) { 24577df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul span->array->spec[i][RCOMP] = FixedToChan(r); 24677df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul span->array->spec[i][GCOMP] = FixedToChan(g); 24777df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul span->array->spec[i][BCOMP] = FixedToChan(b); 2482a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul r += span->specRedStep; 2492a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul g += span->specGreenStep; 2502a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul b += span->specBlueStep; 2512a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 2522a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 2532a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->arrayMask |= SPAN_SPEC; 2542a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul} 2552a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 2562a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 2572a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul/* Fill in the span.zArray array from the interpolation values */ 258711e27fda27e4235b20a4cf73c2767c984ab2b81Brian Paulvoid 259711e27fda27e4235b20a4cf73c2767c984ab2b81Brian Paul_mesa_span_interpolate_z( const GLcontext *ctx, struct sw_span *span ) 2602a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul{ 2612a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul const GLuint n = span->end; 2622a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLuint i; 2632a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 264b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul ASSERT((span->interpMask & SPAN_Z) && 265b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul !(span->arrayMask & SPAN_Z)); 2662a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 2672a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul if (ctx->Visual.depthBits <= 16) { 2682a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfixed zval = span->z; 26977df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul GLdepth *z = span->array->z; 270ad8cd6111e022c90c93df106c0fde6f64d205816Brian Paul for (i = 0; i < n; i++) { 27177df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul z[i] = FixedToInt(zval); 2722a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul zval += span->zStep; 2732a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 2742a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 2752a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul else { 2762a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul /* Deep Z buffer, no fixed->int shift */ 2772a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfixed zval = span->z; 27877df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul GLdepth *z = span->array->z; 2792a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul for (i = 0; i < n; i++) { 28077df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul z[i] = zval; 2812a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul zval += span->zStep; 2822a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 2832a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 2842a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->arrayMask |= SPAN_Z; 2852a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul} 2862a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 2872a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 288c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul/* 28931f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul * This the ideal solution, as given in the OpenGL spec. 290c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul */ 291c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul#if 0 29231f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paulstatic GLfloat 29331f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paulcompute_lambda(GLfloat dsdx, GLfloat dsdy, GLfloat dtdx, GLfloat dtdy, 29431f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat dqdx, GLfloat dqdy, GLfloat texW, GLfloat texH, 29531f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat s, GLfloat t, GLfloat q, GLfloat invQ) 296c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul{ 29731f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat dudx = texW * ((s + dsdx) / (q + dqdx) - s * invQ); 29831f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat dvdx = texH * ((t + dtdx) / (q + dqdx) - t * invQ); 29931f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat dudy = texW * ((s + dsdy) / (q + dqdy) - s * invQ); 30031f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat dvdy = texH * ((t + dtdy) / (q + dqdy) - t * invQ); 30131f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat x = sqrt(dudx * dudx + dvdx * dvdx); 30231f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat y = sqrt(dudy * dudy + dvdy * dvdy); 30331f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat rho = MAX2(x, y); 30431f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat lambda = LOG2(rho); 30531f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul return lambda; 306c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul} 307c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul#endif 308c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul 30931f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul 31031f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul/* 31131f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul * This is a faster approximation 312c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul */ 31331f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paulstatic GLfloat 31431f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paulcompute_lambda(GLfloat dsdx, GLfloat dsdy, GLfloat dtdx, GLfloat dtdy, 31531f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat dqdx, GLfloat dqdy, GLfloat texW, GLfloat texH, 31631f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat s, GLfloat t, GLfloat q, GLfloat invQ) 317c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul{ 31831f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat dsdx2 = (s + dsdx) / (q + dqdx) - s * invQ; 31931f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat dtdx2 = (t + dtdx) / (q + dqdx) - t * invQ; 32031f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat dsdy2 = (s + dsdy) / (q + dqdy) - s * invQ; 32131f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat dtdy2 = (t + dtdy) / (q + dqdy) - t * invQ; 32231f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat maxU, maxV, rho, lambda; 32331f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul dsdx2 = FABSF(dsdx2); 32431f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul dsdy2 = FABSF(dsdy2); 32531f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul dtdx2 = FABSF(dtdx2); 32631f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul dtdy2 = FABSF(dtdy2); 32731f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul maxU = MAX2(dsdx2, dsdy2) * texW; 32831f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul maxV = MAX2(dtdx2, dtdy2) * texH; 32931f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul rho = MAX2(maxU, maxV); 33031f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul lambda = LOG2(rho); 33131f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul return lambda; 332c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul} 333c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul 334c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul/* 335c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul * Fill in the span.texcoords array from the interpolation values. 336c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul * XXX We could optimize here for the case when dq = 0. That would 337c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul * usually be the case when using an orthographic projection. 338c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul */ 3392a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paulstatic void 3402a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paulinterpolate_texcoords(GLcontext *ctx, struct sw_span *span) 3412a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul{ 3422a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul ASSERT(span->interpMask & SPAN_TEXTURE); 343b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul ASSERT(!(span->arrayMask & SPAN_TEXTURE)); 3442a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 3458afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul if (ctx->Texture._EnabledUnits > 1) { 34631f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul /* multitexture */ 34731f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLuint u; 348b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul span->arrayMask |= SPAN_TEXTURE; 34931f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { 35031f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul if (ctx->Texture.Unit[u]._ReallyEnabled) { 35131f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const struct gl_texture_object *obj =ctx->Texture.Unit[u]._Current; 35231f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const struct gl_texture_image *img = obj->Image[obj->BaseLevel]; 35331f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLboolean needLambda = (obj->MinFilter != obj->MagFilter); 35431f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul if (needLambda) { 35577df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul GLfloat (*texcoord)[4] = span->array->texcoords[u]; 35677df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul GLfloat *lambda = span->array->lambda[u]; 3578afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul const GLfloat texW = (GLfloat) img->WidthScale; 3588afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul const GLfloat texH = (GLfloat) img->HeightScale; 35931f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat dsdx = span->texStepX[u][0]; 36031f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat dsdy = span->texStepY[u][0]; 36131f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat dtdx = span->texStepX[u][1]; 36231f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat dtdy = span->texStepY[u][1]; 36331f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat drdx = span->texStepX[u][2]; 36431f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat dqdx = span->texStepX[u][3]; 36531f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat dqdy = span->texStepY[u][3]; 3662a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat s = span->tex[u][0]; 3672a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat t = span->tex[u][1]; 3682a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat r = span->tex[u][2]; 3692a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat q = span->tex[u][3]; 3702a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLuint i; 37131f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul for (i = 0; i < span->end; i++) { 3722a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q); 37377df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul texcoord[i][0] = s * invQ; 37477df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul texcoord[i][1] = t * invQ; 37577df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul texcoord[i][2] = r * invQ; 37677df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul lambda[i] = compute_lambda(dsdx, dsdy, dtdx, dtdy, 37777df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul dqdx, dqdy, texW, texH, 37877df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul s, t, q, invQ); 37931f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul s += dsdx; 38031f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul t += dtdx; 38131f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul r += drdx; 38231f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul q += dqdx; 3832a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 38431f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul span->arrayMask |= SPAN_LAMBDA; 3852a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 38631f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul else { 38777df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul GLfloat (*texcoord)[4] = span->array->texcoords[u]; 38877df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul GLfloat *lambda = span->array->lambda[u]; 38931f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat dsdx = span->texStepX[u][0]; 39031f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat dtdx = span->texStepX[u][1]; 39131f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat drdx = span->texStepX[u][2]; 39231f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat dqdx = span->texStepX[u][3]; 3932a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat s = span->tex[u][0]; 3942a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat t = span->tex[u][1]; 3952a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat r = span->tex[u][2]; 3962a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat q = span->tex[u][3]; 3972a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLuint i; 39831f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul if (dqdx == 0.0) { 399c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul /* Ortho projection or polygon's parallel to window X axis */ 4002a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q); 401c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul for (i = 0; i < span->end; i++) { 40277df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul texcoord[i][0] = s * invQ; 40377df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul texcoord[i][1] = t * invQ; 40477df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul texcoord[i][2] = r * invQ; 40577df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul lambda[i] = 0.0; 40631f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul s += dsdx; 40731f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul t += dtdx; 40831f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul r += drdx; 409c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul } 410c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul } 411c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul else { 412c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul for (i = 0; i < span->end; i++) { 413c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q); 41477df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul texcoord[i][0] = s * invQ; 41577df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul texcoord[i][1] = t * invQ; 41677df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul texcoord[i][2] = r * invQ; 41777df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul lambda[i] = 0.0; 41831f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul s += dsdx; 41931f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul t += dtdx; 42031f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul r += drdx; 42131f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul q += dqdx; 422c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul } 4232a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 42431f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul } /* lambda */ 42531f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul } /* if */ 42631f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul } /* for */ 4272a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 4282a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul else { 42931f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul /* single texture */ 43031f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const struct gl_texture_object *obj = ctx->Texture.Unit[0]._Current; 43131f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const struct gl_texture_image *img = obj->Image[obj->BaseLevel]; 43231f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLboolean needLambda = (obj->MinFilter != obj->MagFilter); 433b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul span->arrayMask |= SPAN_TEXTURE; 43431f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul if (needLambda) { 4352a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul /* just texture unit 0, with lambda */ 43677df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul GLfloat (*texcoord)[4] = span->array->texcoords[0]; 43777df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul GLfloat *lambda = span->array->lambda[0]; 4388afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul const GLfloat texW = (GLfloat) img->WidthScale; 4398afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul const GLfloat texH = (GLfloat) img->HeightScale; 44031f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat dsdx = span->texStepX[0][0]; 44131f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat dsdy = span->texStepY[0][0]; 44231f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat dtdx = span->texStepX[0][1]; 44331f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat dtdy = span->texStepY[0][1]; 44431f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat drdx = span->texStepX[0][2]; 44531f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat dqdx = span->texStepX[0][3]; 44631f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat dqdy = span->texStepY[0][3]; 4472a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat s = span->tex[0][0]; 4482a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat t = span->tex[0][1]; 4492a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat r = span->tex[0][2]; 4502a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat q = span->tex[0][3]; 4512a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLuint i; 45231f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul for (i = 0; i < span->end; i++) { 4532a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q); 45477df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul lambda[i] = compute_lambda(dsdx, dsdy, dtdx, dtdy, 45577df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul dqdx, dqdy, texW, texH, 45677df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul s, t, q, invQ); 45777df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul texcoord[i][0] = s * invQ; 45877df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul texcoord[i][1] = t * invQ; 45977df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul texcoord[i][2] = r * invQ; 46031f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul s += dsdx; 46131f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul t += dtdx; 46231f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul r += drdx; 46331f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul q += dqdx; 4642a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 4652a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->arrayMask |= SPAN_LAMBDA; 4662a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 4672a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul else { 468733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* just texture 0, without lambda */ 46977df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul GLfloat (*texcoord)[4] = span->array->texcoords[0]; 47031f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat dsdx = span->texStepX[0][0]; 47131f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat dtdx = span->texStepX[0][1]; 47231f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat drdx = span->texStepX[0][2]; 47331f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul const GLfloat dqdx = span->texStepX[0][3]; 4742a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat s = span->tex[0][0]; 4752a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat t = span->tex[0][1]; 4762a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat r = span->tex[0][2]; 4772a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfloat q = span->tex[0][3]; 4782a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLuint i; 47931f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul if (dqdx == 0.0) { 480c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul /* Ortho projection or polygon's parallel to window X axis */ 4812a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q); 482c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul for (i = 0; i < span->end; i++) { 48377df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul texcoord[i][0] = s * invQ; 48477df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul texcoord[i][1] = t * invQ; 48577df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul texcoord[i][2] = r * invQ; 48631f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul s += dsdx; 48731f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul t += dtdx; 48831f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul r += drdx; 489c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul } 490c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul } 491c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul else { 492c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul for (i = 0; i < span->end; i++) { 493c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q); 49477df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul texcoord[i][0] = s * invQ; 49577df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul texcoord[i][1] = t * invQ; 49677df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul texcoord[i][2] = r * invQ; 49731f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul s += dsdx; 49831f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul t += dtdx; 49931f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul r += drdx; 50031f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul q += dqdx; 501c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul } 5022a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 5032a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 5042a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 50510f30eb43835c57c00783390a02d72daf4f78e26Brian Paul} 506e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 507e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 50879c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/** 509e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Apply the current polygon stipple pattern to a span of pixels. 510e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */ 5115071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paulstatic void 512733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paulstipple_polygon_span( GLcontext *ctx, struct sw_span *span ) 51310f30eb43835c57c00783390a02d72daf4f78e26Brian Paul{ 51410f30eb43835c57c00783390a02d72daf4f78e26Brian Paul const GLuint highbit = 0x80000000; 515733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul const GLuint stipple = ctx->PolygonStipple[span->y % 32]; 51677df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul GLubyte *mask = span->array->mask; 517733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul GLuint i, m; 518733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul 519733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul ASSERT(ctx->Polygon.StippleFlag); 520733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul ASSERT((span->arrayMask & SPAN_XY) == 0); 52110f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 52210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul m = highbit >> (GLuint) (span->x % 32); 52310f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 52410f30eb43835c57c00783390a02d72daf4f78e26Brian Paul for (i = 0; i < span->end; i++) { 52510f30eb43835c57c00783390a02d72daf4f78e26Brian Paul if ((m & stipple) == 0) { 52677df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul mask[i] = 0; 52710f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 52810f30eb43835c57c00783390a02d72daf4f78e26Brian Paul m = m >> 1; 52910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul if (m == 0) { 53010f30eb43835c57c00783390a02d72daf4f78e26Brian Paul m = highbit; 53110f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 53210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 5332ef866d1fc0a5cc5ef8543d65744dfd4da4dbbafBrian Paul span->writeAll = GL_FALSE; 53410f30eb43835c57c00783390a02d72daf4f78e26Brian Paul} 53510f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 536e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 53779c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/** 538733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul * Clip a pixel span to the current buffer/window boundaries: 539733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul * DrawBuffer->_Xmin, _Xmax, _Ymin, _Ymax. This will accomplish 540733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul * window clipping and scissoring. 541733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul * Return: GL_TRUE some pixels still visible 54210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul * GL_FALSE nothing visible 54310f30eb43835c57c00783390a02d72daf4f78e26Brian Paul */ 54410f30eb43835c57c00783390a02d72daf4f78e26Brian Paulstatic GLuint 545733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paulclip_span( GLcontext *ctx, struct sw_span *span ) 54610f30eb43835c57c00783390a02d72daf4f78e26Brian Paul{ 547733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul const GLint xmin = ctx->DrawBuffer->_Xmin; 548733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul const GLint xmax = ctx->DrawBuffer->_Xmax; 549733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul const GLint ymin = ctx->DrawBuffer->_Ymin; 550733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul const GLint ymax = ctx->DrawBuffer->_Ymax; 551733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul 552733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (span->arrayMask & SPAN_XY) { 553733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* arrays of x/y pixel coords */ 55477df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul const GLint *x = span->array->x; 55577df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul const GLint *y = span->array->y; 556733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul const GLint n = span->end; 55777df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul GLubyte *mask = span->array->mask; 558733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul GLint i; 559b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul if (span->arrayMask & SPAN_MASK) { 560b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul /* note: using & intead of && to reduce branches */ 561b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul for (i = 0; i < n; i++) { 562b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul mask[i] &= (x[i] >= xmin) & (x[i] < xmax) 563b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul & (y[i] >= ymin) & (y[i] < ymax); 564b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul } 565b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul } 566b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul else { 567b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul /* note: using & intead of && to reduce branches */ 568b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul for (i = 0; i < n; i++) { 569b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul mask[i] = (x[i] >= xmin) & (x[i] < xmax) 570b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul & (y[i] >= ymin) & (y[i] < ymax); 571b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul } 57210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 573733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul return GL_TRUE; /* some pixels visible */ 57410f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 575733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul else { 576733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* horizontal span of pixels */ 577733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul const GLint x = span->x; 578733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul const GLint y = span->y; 579733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul const GLint n = span->end; 580733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul 581733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* Trivial rejection tests */ 582733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (y < ymin || y >= ymax || x + n <= xmin || x >= xmax) { 583733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->end = 0; 584733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul return GL_FALSE; /* all pixels clipped */ 585733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul } 58610f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 587733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* Clip to the left */ 588733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (x < xmin) { 589733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul ASSERT(x + n > xmin); 590733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->writeAll = GL_FALSE; 5916ec6b845fdf3c44436028ad6fff9471d18928719Brian Paul _mesa_bzero(span->array->mask, (xmin - x) * sizeof(GLubyte)); 59210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 593733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul 594733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* Clip to right */ 595733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (x + n > xmax) { 596733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul ASSERT(x < xmax); 597733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->end = xmax - x; 59810f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 59910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 600733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul return GL_TRUE; /* some pixels visible */ 601733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul } 60210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul} 60310f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 60410f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 605e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 60679c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/** 607e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Draw to more than one color buffer (or none). 608e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */ 6095071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paulstatic void 610733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paulmulti_write_index_span( GLcontext *ctx, struct sw_span *span ) 611e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell{ 612709892459922a32096fe9dd8261d0d92337bb02fKeith Whitwell SWcontext *swrast = SWRAST_CONTEXT(ctx); 613e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell GLuint bufferBit; 614e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 615e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* loop over four possible dest color buffers */ 6163b4fbbc129c711a5aec8d653d5c6eb2e195f947cBrian Paul for (bufferBit = 1; bufferBit <= 8; bufferBit <<= 1) { 6173b4fbbc129c711a5aec8d653d5c6eb2e195f947cBrian Paul if (bufferBit & ctx->Color._DrawDestMask) { 618e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell GLuint indexTmp[MAX_WIDTH]; 619733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul ASSERT(span->end < MAX_WIDTH); 620e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 6218ad1076dc2afda8ed37e5a9f6a757583eba90375Brian Paul /* Set the current read/draw buffer */ 6228ad1076dc2afda8ed37e5a9f6a757583eba90375Brian Paul swrast->CurrentBuffer = bufferBit; 6238ad1076dc2afda8ed37e5a9f6a757583eba90375Brian Paul (*swrast->Driver.SetBuffer)(ctx, ctx->DrawBuffer, bufferBit); 624e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 625e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* make copy of incoming indexes */ 62677df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul MEMCPY( indexTmp, span->array->index, span->end * sizeof(GLuint) ); 627733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul 628e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell if (ctx->Color.IndexLogicOpEnabled) { 629733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul _mesa_logicop_ci_span(ctx, span, indexTmp); 630e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 631733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul 6327956292a765910077f50352d7cd0174e1e66d26cBrian Paul if (ctx->Color.IndexMask != 0xffffffff) { 633733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul _mesa_mask_index_span(ctx, span, indexTmp); 634733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul } 635733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul 636733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (span->arrayMask & SPAN_XY) { 637733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* array of pixel coords */ 638733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul (*swrast->Driver.WriteCI32Pixels)(ctx, span->end, 63977df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul span->array->x, span->array->y, 64077df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul indexTmp, span->array->mask); 641733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul } 642733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul else { 643733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* horizontal run of pixels */ 644733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul (*swrast->Driver.WriteCI32Span)(ctx, span->end, span->x, span->y, 64577df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul indexTmp, span->array->mask); 646e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 647e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 648e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 649e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 650e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* restore default dest buffer */ 6513b4fbbc129c711a5aec8d653d5c6eb2e195f947cBrian Paul _swrast_use_draw_buffer(ctx); 652e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell} 653e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 654e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 65579c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/** 65610f30eb43835c57c00783390a02d72daf4f78e26Brian Paul * Draw to more than one RGBA color buffer (or none). 657f1e236987829393c81dc86ea19cb49eefe190317Brian Paul * All fragment operations, up to (but not) blending/logicop should 658f1e236987829393c81dc86ea19cb49eefe190317Brian Paul * have been done first. 65910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul */ 66010f30eb43835c57c00783390a02d72daf4f78e26Brian Paulstatic void 661733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paulmulti_write_rgba_span( GLcontext *ctx, struct sw_span *span ) 66210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul{ 66310f30eb43835c57c00783390a02d72daf4f78e26Brian Paul const GLuint colorMask = *((GLuint *) ctx->Color.ColorMask); 66410f30eb43835c57c00783390a02d72daf4f78e26Brian Paul GLuint bufferBit; 66510f30eb43835c57c00783390a02d72daf4f78e26Brian Paul SWcontext *swrast = SWRAST_CONTEXT(ctx); 66610f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 667733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul ASSERT(colorMask != 0x0); 668733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul 66910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul if (ctx->Color.DrawBuffer == GL_NONE) 67010f30eb43835c57c00783390a02d72daf4f78e26Brian Paul return; 67110f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 67210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul /* loop over four possible dest color buffers */ 6733b4fbbc129c711a5aec8d653d5c6eb2e195f947cBrian Paul for (bufferBit = 1; bufferBit <= 8; bufferBit <<= 1) { 6743b4fbbc129c711a5aec8d653d5c6eb2e195f947cBrian Paul if (bufferBit & ctx->Color._DrawDestMask) { 67510f30eb43835c57c00783390a02d72daf4f78e26Brian Paul GLchan rgbaTmp[MAX_WIDTH][4]; 676733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul ASSERT(span->end < MAX_WIDTH); 67710f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 6788ad1076dc2afda8ed37e5a9f6a757583eba90375Brian Paul /* Set the current read/draw buffer */ 6798ad1076dc2afda8ed37e5a9f6a757583eba90375Brian Paul swrast->CurrentBuffer = bufferBit; 6808ad1076dc2afda8ed37e5a9f6a757583eba90375Brian Paul (*swrast->Driver.SetBuffer)(ctx, ctx->DrawBuffer, bufferBit); 68110f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 68210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul /* make copy of incoming colors */ 68377df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul MEMCPY( rgbaTmp, span->array->rgba, 4 * span->end * sizeof(GLchan) ); 68410f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 68510f30eb43835c57c00783390a02d72daf4f78e26Brian Paul if (ctx->Color.ColorLogicOpEnabled) { 686733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul _mesa_logicop_rgba_span(ctx, span, rgbaTmp); 68710f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 68810f30eb43835c57c00783390a02d72daf4f78e26Brian Paul else if (ctx->Color.BlendEnabled) { 689733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul _mesa_blend_span(ctx, span, rgbaTmp); 69010f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 691733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul 692733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (colorMask != 0xffffffff) { 693733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul _mesa_mask_rgba_span(ctx, span, rgbaTmp); 69410f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 69510f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 696733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (span->arrayMask & SPAN_XY) { 697733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* array of pixel coords */ 698733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul (*swrast->Driver.WriteRGBAPixels)(ctx, span->end, 69977df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul span->array->x, span->array->y, 700733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul (const GLchan (*)[4]) rgbaTmp, 70177df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul span->array->mask); 702733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (SWRAST_CONTEXT(ctx)->_RasterMask & ALPHABUF_BIT) { 703733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul _mesa_write_alpha_pixels(ctx, span->end, 70477df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul span->array->x, span->array->y, 705733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul (const GLchan (*)[4]) rgbaTmp, 70677df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul span->array->mask); 707733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul } 708733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul } 709733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul else { 710733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* horizontal run of pixels */ 711733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul (*swrast->Driver.WriteRGBASpan)(ctx, span->end, span->x, span->y, 712733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul (const GLchan (*)[4]) rgbaTmp, 71377df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul span->array->mask); 714733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (swrast->_RasterMask & ALPHABUF_BIT) { 715733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul _mesa_write_alpha_span(ctx, span->end, span->x, span->y, 716733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul (const GLchan (*)[4]) rgbaTmp, 71777df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul span->array->mask); 718733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul } 71910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 72010f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 72110f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 72210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 72310f30eb43835c57c00783390a02d72daf4f78e26Brian Paul /* restore default dest buffer */ 7243b4fbbc129c711a5aec8d653d5c6eb2e195f947cBrian Paul _swrast_use_draw_buffer(ctx); 72510f30eb43835c57c00783390a02d72daf4f78e26Brian Paul} 72610f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 72710f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 728e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 72979c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/** 7307956292a765910077f50352d7cd0174e1e66d26cBrian Paul * This function may modify any of the array values in the span. 7317956292a765910077f50352d7cd0174e1e66d26cBrian Paul * span->interpMask and span->arrayMask may be changed but will be restored 7327956292a765910077f50352d7cd0174e1e66d26cBrian Paul * to their original values before returning. 73310f30eb43835c57c00783390a02d72daf4f78e26Brian Paul */ 73410f30eb43835c57c00783390a02d72daf4f78e26Brian Paulvoid 735b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul_mesa_write_index_span( GLcontext *ctx, struct sw_span *span) 73610f30eb43835c57c00783390a02d72daf4f78e26Brian Paul{ 73710f30eb43835c57c00783390a02d72daf4f78e26Brian Paul SWcontext *swrast = SWRAST_CONTEXT(ctx); 7387956292a765910077f50352d7cd0174e1e66d26cBrian Paul const GLuint origInterpMask = span->interpMask; 7392a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul const GLuint origArrayMask = span->arrayMask; 74010f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 741733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul ASSERT(span->end <= MAX_WIDTH); 742b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul ASSERT(span->primitive == GL_POINT || span->primitive == GL_LINE || 743b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul span->primitive == GL_POLYGON || span->primitive == GL_BITMAP); 744733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul ASSERT((span->interpMask | span->arrayMask) & SPAN_INDEX); 7457956292a765910077f50352d7cd0174e1e66d26cBrian Paul ASSERT((span->interpMask & span->arrayMask) == 0); 7467956292a765910077f50352d7cd0174e1e66d26cBrian Paul 747733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (span->arrayMask & SPAN_MASK) { 748733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* mask was initialized by caller, probably glBitmap */ 749733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->writeAll = GL_FALSE; 750733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul } 751733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul else { 75277df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul MEMSET(span->array->mask, 1, span->end); 753733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->writeAll = GL_TRUE; 75410f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 75510f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 756733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* Clipping */ 757b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul if ((swrast->_RasterMask & CLIP_BIT) || (span->primitive != GL_POLYGON)) { 758733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (!clip_span(ctx, span)) { 75986ca15ece74ccb5a8f4d566a4b2c8024b178d73bBrian Paul return; 760e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 761e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 762e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 763b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul#ifdef DEBUG 764b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul if (span->arrayMask & SPAN_XY) { 765a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul GLuint i; 766b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul for (i = 0; i < span->end; i++) { 76777df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul if (span->array->mask[i]) { 76877df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul assert(span->array->x[i] >= ctx->DrawBuffer->_Xmin); 76977df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul assert(span->array->x[i] < ctx->DrawBuffer->_Xmax); 77077df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul assert(span->array->y[i] >= ctx->DrawBuffer->_Ymin); 77177df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul assert(span->array->y[i] < ctx->DrawBuffer->_Ymax); 772b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul } 773b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul } 774b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul } 775b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul#endif 776b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul 777e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* Polygon Stippling */ 778b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul if (ctx->Polygon.StippleFlag && span->primitive == GL_POLYGON) { 77910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul stipple_polygon_span(ctx, span); 780e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 781e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 7827956292a765910077f50352d7cd0174e1e66d26cBrian Paul /* Depth test and stencil */ 7837956292a765910077f50352d7cd0174e1e66d26cBrian Paul if (ctx->Depth.Test || ctx->Stencil.Enabled) { 7847956292a765910077f50352d7cd0174e1e66d26cBrian Paul if (span->interpMask & SPAN_Z) 785711e27fda27e4235b20a4cf73c2767c984ab2b81Brian Paul _mesa_span_interpolate_z(ctx, span); 78610f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 7877956292a765910077f50352d7cd0174e1e66d26cBrian Paul if (ctx->Stencil.Enabled) { 788be99e845bd7979fe46d38d9b294c1ba0a0aa95b8Brian Paul if (!_mesa_stencil_and_ztest_span(ctx, span)) { 7897956292a765910077f50352d7cd0174e1e66d26cBrian Paul span->arrayMask = origArrayMask; 7907956292a765910077f50352d7cd0174e1e66d26cBrian Paul return; 7917956292a765910077f50352d7cd0174e1e66d26cBrian Paul } 7922a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 7937956292a765910077f50352d7cd0174e1e66d26cBrian Paul else { 7947956292a765910077f50352d7cd0174e1e66d26cBrian Paul ASSERT(ctx->Depth.Test); 79579c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul if (!_mesa_depth_test_span(ctx, span)) { 7967956292a765910077f50352d7cd0174e1e66d26cBrian Paul span->arrayMask = origArrayMask; 7977956292a765910077f50352d7cd0174e1e66d26cBrian Paul return; 7987956292a765910077f50352d7cd0174e1e66d26cBrian Paul } 7992a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 80010f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 80110f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 80210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul /* if we get here, something passed the depth test */ 80310f30eb43835c57c00783390a02d72daf4f78e26Brian Paul ctx->OcclusionResult = GL_TRUE; 80410f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 8057956292a765910077f50352d7cd0174e1e66d26cBrian Paul /* we have to wait until after occlusion to do this test */ 8067956292a765910077f50352d7cd0174e1e66d26cBrian Paul if (ctx->Color.DrawBuffer == GL_NONE || ctx->Color.IndexMask == 0) { 80710f30eb43835c57c00783390a02d72daf4f78e26Brian Paul /* write no pixels */ 8082a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->arrayMask = origArrayMask; 80910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul return; 81010f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 81110f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 8127956292a765910077f50352d7cd0174e1e66d26cBrian Paul /* Interpolate the color indexes if needed */ 8137956292a765910077f50352d7cd0174e1e66d26cBrian Paul if (span->interpMask & SPAN_INDEX) { 8142a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul interpolate_indexes(ctx, span); 8157956292a765910077f50352d7cd0174e1e66d26cBrian Paul /* clear the bit - this allows the WriteMonoCISpan optimization below */ 8167956292a765910077f50352d7cd0174e1e66d26cBrian Paul span->interpMask &= ~SPAN_INDEX; 8177956292a765910077f50352d7cd0174e1e66d26cBrian Paul } 81810f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 8197956292a765910077f50352d7cd0174e1e66d26cBrian Paul /* Fog */ 8202a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul if (ctx->Fog.Enabled) { 821711e27fda27e4235b20a4cf73c2767c984ab2b81Brian Paul _mesa_fog_ci_span(ctx, span); 822e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 823e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 8242a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul /* Antialias coverage application */ 8252a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul if (span->arrayMask & SPAN_COVERAGE) { 8262a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLuint i; 82777df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul GLuint *index = span->array->index; 82877df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul GLfloat *coverage = span->array->coverage; 82910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul for (i = 0; i < span->end; i++) { 83077df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul ASSERT(coverage[i] < 16); 83177df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul index[i] = (index[i] & ~0xf) | ((GLuint) coverage[i]); 8325071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paul } 8332a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 8345071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paul 8352a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul if (swrast->_RasterMask & MULTI_DRAW_BIT) { 8362a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul /* draw to zero or two or more buffers */ 837733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul multi_write_index_span(ctx, span); 838e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 839e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell else { 8402a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul /* normal situation: draw to exactly one buffer */ 8412a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul if (ctx->Color.IndexLogicOpEnabled) { 84277df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul _mesa_logicop_ci_span(ctx, span, span->array->index); 84310f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 8442a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 8457956292a765910077f50352d7cd0174e1e66d26cBrian Paul if (ctx->Color.IndexMask != 0xffffffff) { 84677df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul _mesa_mask_index_span(ctx, span, span->array->index); 847e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 8482a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 8492a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul /* write pixels */ 850733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (span->arrayMask & SPAN_XY) { 851733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* array of pixel coords */ 852733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if ((span->interpMask & SPAN_INDEX) && span->indexStep == 0) { 853733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* all pixels have same color index */ 854733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul (*swrast->Driver.WriteMonoCIPixels)(ctx, span->end, 85577df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul span->array->x, span->array->y, 856733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul FixedToInt(span->index), 85777df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul span->array->mask); 858733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul } 859733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul else { 86077df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul (*swrast->Driver.WriteCI32Pixels)(ctx, span->end, span->array->x, 86177df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul span->array->y, span->array->index, 86277df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul span->array->mask ); 863733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul } 8647956292a765910077f50352d7cd0174e1e66d26cBrian Paul } 8657956292a765910077f50352d7cd0174e1e66d26cBrian Paul else { 866733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* horizontal run of pixels */ 867733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if ((span->interpMask & SPAN_INDEX) && span->indexStep == 0) { 868733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* all pixels have same color index */ 869733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul (*swrast->Driver.WriteMonoCISpan)(ctx, span->end, span->x, span->y, 870733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul FixedToInt(span->index), 87177df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul span->array->mask); 872733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul } 873733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul else { 874733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul (*swrast->Driver.WriteCI32Span)(ctx, span->end, span->x, span->y, 87577df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul span->array->index, 87677df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul span->array->mask); 877733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul } 8787956292a765910077f50352d7cd0174e1e66d26cBrian Paul } 879e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 8802a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 8817956292a765910077f50352d7cd0174e1e66d26cBrian Paul span->interpMask = origInterpMask; 8822a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->arrayMask = origArrayMask; 883e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell} 884e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 885e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 88679c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/** 8877956292a765910077f50352d7cd0174e1e66d26cBrian Paul * This function may modify any of the array values in the span. 8887956292a765910077f50352d7cd0174e1e66d26cBrian Paul * span->interpMask and span->arrayMask may be changed but will be restored 8897956292a765910077f50352d7cd0174e1e66d26cBrian Paul * to their original values before returning. 8905d2621928823a06006c1586efe78fe8bf65a7e1fBrian Paul */ 8915071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paulvoid 892b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul_mesa_write_rgba_span( GLcontext *ctx, struct sw_span *span) 893e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell{ 894cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell SWcontext *swrast = SWRAST_CONTEXT(ctx); 8957956292a765910077f50352d7cd0174e1e66d26cBrian Paul const GLuint colorMask = *((GLuint *) ctx->Color.ColorMask); 8967956292a765910077f50352d7cd0174e1e66d26cBrian Paul const GLuint origInterpMask = span->interpMask; 8972a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul const GLuint origArrayMask = span->arrayMask; 8987956292a765910077f50352d7cd0174e1e66d26cBrian Paul GLboolean monoColor; 8997956292a765910077f50352d7cd0174e1e66d26cBrian Paul 900733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul ASSERT(span->end <= MAX_WIDTH); 901b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul ASSERT(span->primitive == GL_POINT || span->primitive == GL_LINE || 902b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul span->primitive == GL_POLYGON || span->primitive == GL_BITMAP); 9037956292a765910077f50352d7cd0174e1e66d26cBrian Paul ASSERT((span->interpMask & span->arrayMask) == 0); 904ceb39f4f8dc4863fde17d668c752533a2184476eBrian Paul ASSERT((span->interpMask | span->arrayMask) & SPAN_RGBA); 905bcb148de9201c7f90a68c7c46434e7ebf7204000Brian Paul#ifdef DEBUG 906733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (ctx->Fog.Enabled) 907733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul ASSERT((span->interpMask | span->arrayMask) & SPAN_FOG); 908bcb148de9201c7f90a68c7c46434e7ebf7204000Brian Paul if (ctx->Depth.Test) 909bcb148de9201c7f90a68c7c46434e7ebf7204000Brian Paul ASSERT((span->interpMask | span->arrayMask) & SPAN_Z); 910bcb148de9201c7f90a68c7c46434e7ebf7204000Brian Paul#endif 911733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul 912733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (span->arrayMask & SPAN_MASK) { 913733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* mask was initialized by caller, probably glBitmap */ 914733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->writeAll = GL_FALSE; 915733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul } 916733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul else { 91777df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul MEMSET(span->array->mask, 1, span->end); 918733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->writeAll = GL_TRUE; 919733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul } 920e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 9217956292a765910077f50352d7cd0174e1e66d26cBrian Paul /* Determine if we have mono-chromatic colors */ 9227956292a765910077f50352d7cd0174e1e66d26cBrian Paul monoColor = (span->interpMask & SPAN_RGBA) && 9237956292a765910077f50352d7cd0174e1e66d26cBrian Paul span->redStep == 0 && span->greenStep == 0 && 9247956292a765910077f50352d7cd0174e1e66d26cBrian Paul span->blueStep == 0 && span->alphaStep == 0; 9257956292a765910077f50352d7cd0174e1e66d26cBrian Paul 926733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* Clipping */ 927b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul if ((swrast->_RasterMask & CLIP_BIT) || (span->primitive != GL_POLYGON)) { 928733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (!clip_span(ctx, span)) { 92986ca15ece74ccb5a8f4d566a4b2c8024b178d73bBrian Paul return; 930e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 931e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 932e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 933b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul#ifdef DEBUG 934b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul if (span->arrayMask & SPAN_XY) { 935a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul GLuint i; 936b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul for (i = 0; i < span->end; i++) { 93777df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul if (span->array->mask[i]) { 93877df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul assert(span->array->x[i] >= ctx->DrawBuffer->_Xmin); 93977df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul assert(span->array->x[i] < ctx->DrawBuffer->_Xmax); 94077df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul assert(span->array->y[i] >= ctx->DrawBuffer->_Ymin); 94177df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul assert(span->array->y[i] < ctx->DrawBuffer->_Ymax); 942b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul } 943b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul } 944b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul } 945b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul#endif 946b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul 947e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* Polygon Stippling */ 948b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul if (ctx->Polygon.StippleFlag && span->primitive == GL_POLYGON) { 9497956292a765910077f50352d7cd0174e1e66d26cBrian Paul stipple_polygon_span(ctx, span); 95010f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 95110f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 952e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* Do the alpha test */ 953e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell if (ctx->Color.AlphaEnabled) { 954ceb39f4f8dc4863fde17d668c752533a2184476eBrian Paul if (!_mesa_alpha_test(ctx, span)) { 9557956292a765910077f50352d7cd0174e1e66d26cBrian Paul span->interpMask = origInterpMask; 9562a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->arrayMask = origArrayMask; 957e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell return; 958e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 95910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 96010f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 961f1e236987829393c81dc86ea19cb49eefe190317Brian Paul /* Stencil and Z testing */ 962f1e236987829393c81dc86ea19cb49eefe190317Brian Paul if (ctx->Stencil.Enabled || ctx->Depth.Test) { 963f1e236987829393c81dc86ea19cb49eefe190317Brian Paul if (span->interpMask & SPAN_Z) 964711e27fda27e4235b20a4cf73c2767c984ab2b81Brian Paul _mesa_span_interpolate_z(ctx, span); 965f1e236987829393c81dc86ea19cb49eefe190317Brian Paul 966f1e236987829393c81dc86ea19cb49eefe190317Brian Paul if (ctx->Stencil.Enabled) { 967be99e845bd7979fe46d38d9b294c1ba0a0aa95b8Brian Paul if (!_mesa_stencil_and_ztest_span(ctx, span)) { 9687956292a765910077f50352d7cd0174e1e66d26cBrian Paul span->interpMask = origInterpMask; 969f1e236987829393c81dc86ea19cb49eefe190317Brian Paul span->arrayMask = origArrayMask; 970f1e236987829393c81dc86ea19cb49eefe190317Brian Paul return; 97110f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 97210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 97310f30eb43835c57c00783390a02d72daf4f78e26Brian Paul else { 974f1e236987829393c81dc86ea19cb49eefe190317Brian Paul ASSERT(ctx->Depth.Test); 975f1e236987829393c81dc86ea19cb49eefe190317Brian Paul ASSERT(span->arrayMask & SPAN_Z); 976f1e236987829393c81dc86ea19cb49eefe190317Brian Paul /* regular depth testing */ 977f1e236987829393c81dc86ea19cb49eefe190317Brian Paul if (!_mesa_depth_test_span(ctx, span)) { 9787956292a765910077f50352d7cd0174e1e66d26cBrian Paul span->interpMask = origInterpMask; 979f1e236987829393c81dc86ea19cb49eefe190317Brian Paul span->arrayMask = origArrayMask; 980f1e236987829393c81dc86ea19cb49eefe190317Brian Paul return; 98110f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 98210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 983e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 984e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 985e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* if we get here, something passed the depth test */ 986e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell ctx->OcclusionResult = GL_TRUE; 987e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 9887956292a765910077f50352d7cd0174e1e66d26cBrian Paul /* can't abort span-writing until after occlusion testing */ 9897956292a765910077f50352d7cd0174e1e66d26cBrian Paul if (colorMask == 0x0) { 9907956292a765910077f50352d7cd0174e1e66d26cBrian Paul span->interpMask = origInterpMask; 9917956292a765910077f50352d7cd0174e1e66d26cBrian Paul span->arrayMask = origArrayMask; 9927956292a765910077f50352d7cd0174e1e66d26cBrian Paul return; 9937956292a765910077f50352d7cd0174e1e66d26cBrian Paul } 9947956292a765910077f50352d7cd0174e1e66d26cBrian Paul 995ceb39f4f8dc4863fde17d668c752533a2184476eBrian Paul /* Now we may need to interpolate the colors */ 996ceb39f4f8dc4863fde17d668c752533a2184476eBrian Paul if ((span->interpMask & SPAN_RGBA) && (span->arrayMask & SPAN_RGBA) == 0) { 997ceb39f4f8dc4863fde17d668c752533a2184476eBrian Paul interpolate_colors(ctx, span); 998ceb39f4f8dc4863fde17d668c752533a2184476eBrian Paul /* clear the bit - this allows the WriteMonoCISpan optimization below */ 999ceb39f4f8dc4863fde17d668c752533a2184476eBrian Paul span->interpMask &= ~SPAN_RGBA; 1000ceb39f4f8dc4863fde17d668c752533a2184476eBrian Paul } 1001ceb39f4f8dc4863fde17d668c752533a2184476eBrian Paul 10026e1666437ea091ecc50ab2b56d87129318f641d2Brian Paul /* Fog */ 1003b38ad54c41aec2d08fdd26a4a8ea4dcdca8b1dfdBrian Paul if (ctx->Fog.Enabled) { 1004711e27fda27e4235b20a4cf73c2767c984ab2b81Brian Paul _mesa_fog_rgba_span(ctx, span); 10057956292a765910077f50352d7cd0174e1e66d26cBrian Paul monoColor = GL_FALSE; 1006b38ad54c41aec2d08fdd26a4a8ea4dcdca8b1dfdBrian Paul } 1007b38ad54c41aec2d08fdd26a4a8ea4dcdca8b1dfdBrian Paul 10085071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paul /* Antialias coverage application */ 10092a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul if (span->arrayMask & SPAN_COVERAGE) { 101077df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul GLchan (*rgba)[4] = span->array->rgba; 101177df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul GLfloat *coverage = span->array->coverage; 10125071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paul GLuint i; 101310f30eb43835c57c00783390a02d72daf4f78e26Brian Paul for (i = 0; i < span->end; i++) { 101477df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul rgba[i][ACOMP] = (GLchan) (rgba[i][ACOMP] * coverage[i]); 10155071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paul } 10167956292a765910077f50352d7cd0174e1e66d26cBrian Paul monoColor = GL_FALSE; 10175071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paul } 10185071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paul 1019cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell if (swrast->_RasterMask & MULTI_DRAW_BIT) { 1020733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul multi_write_rgba_span(ctx, span); 1021e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1022e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell else { 1023e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* normal: write to exactly one buffer */ 1024e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell if (ctx->Color.ColorLogicOpEnabled) { 102577df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul _mesa_logicop_rgba_span(ctx, span, span->array->rgba); 10267956292a765910077f50352d7cd0174e1e66d26cBrian Paul monoColor = GL_FALSE; 1027e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1028e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell else if (ctx->Color.BlendEnabled) { 102977df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul _mesa_blend_span(ctx, span, span->array->rgba); 10307956292a765910077f50352d7cd0174e1e66d26cBrian Paul monoColor = GL_FALSE; 1031e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 103295e2c72fd52d87163eb543555345f115f050f3aaBrian Paul 1033e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* Color component masking */ 10347956292a765910077f50352d7cd0174e1e66d26cBrian Paul if (colorMask != 0xffffffff) { 103577df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul _mesa_mask_rgba_span(ctx, span, span->array->rgba); 10367956292a765910077f50352d7cd0174e1e66d26cBrian Paul monoColor = GL_FALSE; 1037e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1038e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 1039e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* write pixels */ 1040733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (span->arrayMask & SPAN_XY) { 1041733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* array of pixel coords */ 1042733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* XXX test for mono color */ 104377df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul (*swrast->Driver.WriteRGBAPixels)(ctx, span->end, span->array->x, 104477df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul span->array->y, (const GLchan (*)[4]) span->array->rgba, span->array->mask); 1045733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (SWRAST_CONTEXT(ctx)->_RasterMask & ALPHABUF_BIT) { 1046733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul _mesa_write_alpha_pixels(ctx, span->end, 104777df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul span->array->x, span->array->y, 104877df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul (const GLchan (*)[4]) span->array->rgba, 104977df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul span->array->mask); 1050733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul } 1051e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1052e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell else { 1053733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* horizontal run of pixels */ 1054733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (monoColor) { 1055733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* all pixels have same color */ 1056733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul GLchan color[4]; 1057733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul color[RCOMP] = FixedToChan(span->red); 1058733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul color[GCOMP] = FixedToChan(span->green); 1059733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul color[BCOMP] = FixedToChan(span->blue); 1060733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul color[ACOMP] = FixedToChan(span->alpha); 1061733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul (*swrast->Driver.WriteMonoRGBASpan)(ctx, span->end, span->x, 106277df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul span->y, color, span->array->mask); 1063733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* XXX software alpha buffer writes! */ 1064733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul } 1065733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul else { 1066733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* each pixel is a different color */ 1067733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul (*swrast->Driver.WriteRGBASpan)(ctx, span->end, span->x, span->y, 106877df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul (const GLchan (*)[4]) span->array->rgba, 106977df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul span->writeAll ? ((const GLubyte *) NULL) : span->array->mask); 1070733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (swrast->_RasterMask & ALPHABUF_BIT) { 1071733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul _mesa_write_alpha_span(ctx, span->end, span->x, span->y, 107277df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul (const GLchan (*)[4]) span->array->rgba, 107377df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul span->writeAll ? ((const GLubyte *) NULL) : span->array->mask); 1074733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul } 1075733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul } 1076e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1077e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1078e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 10797956292a765910077f50352d7cd0174e1e66d26cBrian Paul span->interpMask = origInterpMask; 10807956292a765910077f50352d7cd0174e1e66d26cBrian Paul span->arrayMask = origArrayMask; 10817956292a765910077f50352d7cd0174e1e66d26cBrian Paul} 1082e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 1083e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 108479c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/** 1085e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Add specular color to base color. This is used only when 1086f1e236987829393c81dc86ea19cb49eefe190317Brian Paul * GL_LIGHT_MODEL_COLOR_CONTROL = GL_SEPARATE_SPECULAR_COLOR. 1087e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */ 10885071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paulstatic void 1089f1e236987829393c81dc86ea19cb49eefe190317Brian Pauladd_colors(GLuint n, GLchan rgba[][4], GLchan specular[][4] ) 1090e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell{ 1091e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell GLuint i; 1092f1e236987829393c81dc86ea19cb49eefe190317Brian Paul for (i = 0; i < n; i++) { 10934fa5c1966a985f81c615a9f5ef2f64dd466b252aBrian Paul#if CHAN_TYPE == GL_FLOAT 10944fa5c1966a985f81c615a9f5ef2f64dd466b252aBrian Paul /* no clamping */ 1095f1e236987829393c81dc86ea19cb49eefe190317Brian Paul rgba[i][RCOMP] += specular[i][RCOMP]; 1096f1e236987829393c81dc86ea19cb49eefe190317Brian Paul rgba[i][GCOMP] += specular[i][GCOMP]; 1097f1e236987829393c81dc86ea19cb49eefe190317Brian Paul rgba[i][BCOMP] += specular[i][BCOMP]; 10984fa5c1966a985f81c615a9f5ef2f64dd466b252aBrian Paul#else 1099f1e236987829393c81dc86ea19cb49eefe190317Brian Paul GLint r = rgba[i][RCOMP] + specular[i][RCOMP]; 1100f1e236987829393c81dc86ea19cb49eefe190317Brian Paul GLint g = rgba[i][GCOMP] + specular[i][GCOMP]; 1101f1e236987829393c81dc86ea19cb49eefe190317Brian Paul GLint b = rgba[i][BCOMP] + specular[i][BCOMP]; 1102e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell rgba[i][RCOMP] = (GLchan) MIN2(r, CHAN_MAX); 1103e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell rgba[i][GCOMP] = (GLchan) MIN2(g, CHAN_MAX); 1104e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell rgba[i][BCOMP] = (GLchan) MIN2(b, CHAN_MAX); 11054fa5c1966a985f81c615a9f5ef2f64dd466b252aBrian Paul#endif 1106e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1107e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell} 1108e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 1109e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 111079c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/** 1111f1e236987829393c81dc86ea19cb49eefe190317Brian Paul * This function may modify any of the array values in the span. 11127956292a765910077f50352d7cd0174e1e66d26cBrian Paul * span->interpMask and span->arrayMask may be changed but will be restored 11137956292a765910077f50352d7cd0174e1e66d26cBrian Paul * to their original values before returning. 111478940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul */ 111578940758e90069ceaca2b6cddb6438488fbad5ccBrian Paulvoid 1116b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul_mesa_write_texture_span( GLcontext *ctx, struct sw_span *span) 111778940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul{ 111878940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul const GLuint colorMask = *((GLuint *) ctx->Color.ColorMask); 111978940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul SWcontext *swrast = SWRAST_CONTEXT(ctx); 1120f1e236987829393c81dc86ea19cb49eefe190317Brian Paul const GLuint origArrayMask = span->arrayMask; 1121f1e236987829393c81dc86ea19cb49eefe190317Brian Paul 1122b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul ASSERT(span->primitive == GL_POINT || span->primitive == GL_LINE || 1123b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul span->primitive == GL_POLYGON || span->primitive == GL_BITMAP); 1124733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul ASSERT(span->end <= MAX_WIDTH); 11257956292a765910077f50352d7cd0174e1e66d26cBrian Paul ASSERT((span->interpMask & span->arrayMask) == 0); 11268afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul ASSERT(ctx->Texture._EnabledUnits); 112778940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul 1128ceb39f4f8dc4863fde17d668c752533a2184476eBrian Paul /* 1129ceb39f4f8dc4863fde17d668c752533a2184476eBrian Paul printf("%s() interp 0x%x array 0x%x\n", __FUNCTION__, span->interpMask, span->arrayMask); 1130ceb39f4f8dc4863fde17d668c752533a2184476eBrian Paul */ 1131ceb39f4f8dc4863fde17d668c752533a2184476eBrian Paul 1132733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (span->arrayMask & SPAN_MASK) { 1133733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* mask was initialized by caller, probably glBitmap */ 1134733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->writeAll = GL_FALSE; 1135733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul } 1136733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul else { 113777df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul MEMSET(span->array->mask, 1, span->end); 1138733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->writeAll = GL_TRUE; 113978940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul } 114078940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul 1141733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* Clipping */ 1142b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul if ((swrast->_RasterMask & CLIP_BIT) || (span->primitive != GL_POLYGON)) { 1143733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (!clip_span(ctx, span)) { 1144733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul return; 114578940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul } 114678940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul } 114778940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul 1148b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul#ifdef DEBUG 1149b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul if (span->arrayMask & SPAN_XY) { 1150a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul GLuint i; 1151b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul for (i = 0; i < span->end; i++) { 115277df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul if (span->array->mask[i]) { 115377df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul assert(span->array->x[i] >= ctx->DrawBuffer->_Xmin); 115477df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul assert(span->array->x[i] < ctx->DrawBuffer->_Xmax); 115577df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul assert(span->array->y[i] >= ctx->DrawBuffer->_Ymin); 115677df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul assert(span->array->y[i] < ctx->DrawBuffer->_Ymax); 1157b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul } 1158b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul } 1159b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul } 1160b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul#endif 1161b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul 116278940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul /* Polygon Stippling */ 1163b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul if (ctx->Polygon.StippleFlag && span->primitive == GL_POLYGON) { 1164733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul stipple_polygon_span(ctx, span); 116578940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul } 116678940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul 1167f1e236987829393c81dc86ea19cb49eefe190317Brian Paul /* Need texture coordinates now */ 1168f1e236987829393c81dc86ea19cb49eefe190317Brian Paul if ((span->interpMask & SPAN_TEXTURE) 1169f1e236987829393c81dc86ea19cb49eefe190317Brian Paul && (span->arrayMask & SPAN_TEXTURE) == 0) 1170f1e236987829393c81dc86ea19cb49eefe190317Brian Paul interpolate_texcoords(ctx, span); 117178940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul 117278940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul /* Texture with alpha test */ 117378940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul if (ctx->Color.AlphaEnabled) { 1174f1e236987829393c81dc86ea19cb49eefe190317Brian Paul 1175f1e236987829393c81dc86ea19cb49eefe190317Brian Paul /* Now we need the rgba array, fill it in if needed */ 1176f1e236987829393c81dc86ea19cb49eefe190317Brian Paul if ((span->interpMask & SPAN_RGBA) && (span->arrayMask & SPAN_RGBA) == 0) 1177f1e236987829393c81dc86ea19cb49eefe190317Brian Paul interpolate_colors(ctx, span); 1178f1e236987829393c81dc86ea19cb49eefe190317Brian Paul 117978940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul /* Texturing without alpha is done after depth-testing which 1180f1e236987829393c81dc86ea19cb49eefe190317Brian Paul * gives a potential speed-up. 1181f1e236987829393c81dc86ea19cb49eefe190317Brian Paul */ 1182f595212336ae63c981f0f39f4ea1dec67ff7fe25Brian Paul _swrast_texture_span( ctx, span ); 118378940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul 118478940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul /* Do the alpha test */ 1185ceb39f4f8dc4863fde17d668c752533a2184476eBrian Paul if (!_mesa_alpha_test(ctx, span)) { 1186f1e236987829393c81dc86ea19cb49eefe190317Brian Paul span->arrayMask = origArrayMask; 1187ceb39f4f8dc4863fde17d668c752533a2184476eBrian Paul return; 118878940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul } 118978940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul } 119078940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul 1191f1e236987829393c81dc86ea19cb49eefe190317Brian Paul /* Stencil and Z testing */ 1192f1e236987829393c81dc86ea19cb49eefe190317Brian Paul if (ctx->Stencil.Enabled || ctx->Depth.Test) { 1193f1e236987829393c81dc86ea19cb49eefe190317Brian Paul if (span->interpMask & SPAN_Z) 1194711e27fda27e4235b20a4cf73c2767c984ab2b81Brian Paul _mesa_span_interpolate_z(ctx, span); 119578940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul 119671340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul if (ctx->Stencil.Enabled) { 1197be99e845bd7979fe46d38d9b294c1ba0a0aa95b8Brian Paul if (!_mesa_stencil_and_ztest_span(ctx, span)) { 1198f1e236987829393c81dc86ea19cb49eefe190317Brian Paul span->arrayMask = origArrayMask; 119910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul return; 1200f1e236987829393c81dc86ea19cb49eefe190317Brian Paul } 120171340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 1202f1e236987829393c81dc86ea19cb49eefe190317Brian Paul else { 1203f1e236987829393c81dc86ea19cb49eefe190317Brian Paul ASSERT(ctx->Depth.Test); 1204f1e236987829393c81dc86ea19cb49eefe190317Brian Paul ASSERT(span->arrayMask & SPAN_Z); 120510f30eb43835c57c00783390a02d72daf4f78e26Brian Paul /* regular depth testing */ 1206f1e236987829393c81dc86ea19cb49eefe190317Brian Paul if (!_mesa_depth_test_span(ctx, span)) { 1207f1e236987829393c81dc86ea19cb49eefe190317Brian Paul span->arrayMask = origArrayMask; 120810f30eb43835c57c00783390a02d72daf4f78e26Brian Paul return; 1209f1e236987829393c81dc86ea19cb49eefe190317Brian Paul } 121071340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 121171340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 121271340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul 1213f1e236987829393c81dc86ea19cb49eefe190317Brian Paul /* if we get here, some fragments passed the depth test */ 121471340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul ctx->OcclusionResult = GL_TRUE; 121571340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul 1216f1e236987829393c81dc86ea19cb49eefe190317Brian Paul /* We had to wait until now to check for glColorMask(F,F,F,F) because of 1217f1e236987829393c81dc86ea19cb49eefe190317Brian Paul * the occlusion test. 1218f1e236987829393c81dc86ea19cb49eefe190317Brian Paul */ 1219f1e236987829393c81dc86ea19cb49eefe190317Brian Paul if (colorMask == 0x0) { 1220f1e236987829393c81dc86ea19cb49eefe190317Brian Paul span->arrayMask = origArrayMask; 1221f1e236987829393c81dc86ea19cb49eefe190317Brian Paul return; 122271340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 122371340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul 1224f1e236987829393c81dc86ea19cb49eefe190317Brian Paul /* Texture without alpha test */ 1225f1e236987829393c81dc86ea19cb49eefe190317Brian Paul if (!ctx->Color.AlphaEnabled) { 122671340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul 1227f1e236987829393c81dc86ea19cb49eefe190317Brian Paul /* Now we need the rgba array, fill it in if needed */ 1228f1e236987829393c81dc86ea19cb49eefe190317Brian Paul if ((span->interpMask & SPAN_RGBA) && (span->arrayMask & SPAN_RGBA) == 0) 1229f1e236987829393c81dc86ea19cb49eefe190317Brian Paul interpolate_colors(ctx, span); 123071340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul 1231f595212336ae63c981f0f39f4ea1dec67ff7fe25Brian Paul _swrast_texture_span( ctx, span ); 123271340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 123371340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul 1234f1e236987829393c81dc86ea19cb49eefe190317Brian Paul ASSERT(span->arrayMask & SPAN_RGBA); 12352ef866d1fc0a5cc5ef8543d65744dfd4da4dbbafBrian Paul 1236f1e236987829393c81dc86ea19cb49eefe190317Brian Paul /* Add base and specular colors */ 1237f1e236987829393c81dc86ea19cb49eefe190317Brian Paul if (ctx->Fog.ColorSumEnabled || 1238f1e236987829393c81dc86ea19cb49eefe190317Brian Paul (ctx->Light.Enabled && 1239f1e236987829393c81dc86ea19cb49eefe190317Brian Paul ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR)) { 1240f1e236987829393c81dc86ea19cb49eefe190317Brian Paul if (span->interpMask & SPAN_SPEC) { 1241f1e236987829393c81dc86ea19cb49eefe190317Brian Paul interpolate_specular(ctx, span); 124271340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 1243f1e236987829393c81dc86ea19cb49eefe190317Brian Paul ASSERT(span->arrayMask & SPAN_SPEC); 124477df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul add_colors( span->end, span->array->rgba, span->array->spec ); 124571340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 124671340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul 12476e1666437ea091ecc50ab2b56d87129318f641d2Brian Paul /* Fog */ 124871340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul if (ctx->Fog.Enabled) { 1249711e27fda27e4235b20a4cf73c2767c984ab2b81Brian Paul _mesa_fog_rgba_span(ctx, span); 125071340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 1251f1e236987829393c81dc86ea19cb49eefe190317Brian Paul 125271340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul /* Antialias coverage application */ 12532a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul if (span->arrayMask & SPAN_COVERAGE) { 125477df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul GLchan (*rgba)[4] = span->array->rgba; 125577df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul GLfloat *coverage = span->array->coverage; 125671340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul GLuint i; 125710f30eb43835c57c00783390a02d72daf4f78e26Brian Paul for (i = 0; i < span->end; i++) { 125877df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul rgba[i][ACOMP] = (GLchan) (rgba[i][ACOMP] * coverage[i]); 125971340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 126071340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 126171340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul 126271340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul if (swrast->_RasterMask & MULTI_DRAW_BIT) { 1263733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul multi_write_rgba_span(ctx, span); 126471340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 126571340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul else { 126671340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul /* normal: write to exactly one buffer */ 126771340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul if (ctx->Color.ColorLogicOpEnabled) { 126877df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul _mesa_logicop_rgba_span(ctx, span, span->array->rgba); 126971340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 127095e2c72fd52d87163eb543555345f115f050f3aaBrian Paul else if (ctx->Color.BlendEnabled) { 127177df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul _mesa_blend_span(ctx, span, span->array->rgba); 127271340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 127371340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul 1274f1e236987829393c81dc86ea19cb49eefe190317Brian Paul if (colorMask != 0xffffffff) { 127577df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul _mesa_mask_rgba_span(ctx, span, span->array->rgba); 127671340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 127771340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul 1278733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul 1279733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (span->arrayMask & SPAN_XY) { 1280733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* array of pixel coords */ 128177df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul (*swrast->Driver.WriteRGBAPixels)(ctx, span->end, span->array->x, 128277df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul span->array->y, (const GLchan (*)[4]) span->array->rgba, span->array->mask); 1283733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (SWRAST_CONTEXT(ctx)->_RasterMask & ALPHABUF_BIT) { 1284733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul _mesa_write_alpha_pixels(ctx, span->end, 128577df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul span->array->x, span->array->y, 128677df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul (const GLchan (*)[4]) span->array->rgba, 128777df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul span->array->mask); 1288733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul } 1289733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul } 1290733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul else { 1291733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* horizontal run of pixels */ 1292733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul (*swrast->Driver.WriteRGBASpan)(ctx, span->end, span->x, span->y, 129377df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul (const GLchan (*)[4]) span->array->rgba, 129477df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul span->writeAll ? NULL : span->array->mask); 1295733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (swrast->_RasterMask & ALPHABUF_BIT) { 1296733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul _mesa_write_alpha_span(ctx, span->end, span->x, span->y, 129777df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul (const GLchan (*)[4]) span->array->rgba, 129877df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul span->writeAll ? NULL : span->array->mask); 1299733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul } 130071340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 130171340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 130271340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul 1303f1e236987829393c81dc86ea19cb49eefe190317Brian Paul span->arrayMask = origArrayMask; 130410f30eb43835c57c00783390a02d72daf4f78e26Brian Paul} 130510f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 1306e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 1307e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 130879c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/** 1309e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Read RGBA pixels from frame buffer. Clipping will be done to prevent 1310e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * reading ouside the buffer's boundaries. 1311e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */ 13125071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paulvoid 13135071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paul_mesa_read_rgba_span( GLcontext *ctx, GLframebuffer *buffer, 13145071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paul GLuint n, GLint x, GLint y, GLchan rgba[][4] ) 1315e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell{ 1316709892459922a32096fe9dd8261d0d92337bb02fKeith Whitwell SWcontext *swrast = SWRAST_CONTEXT(ctx); 1317a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul const GLint bufWidth = (GLint) buffer->Width; 13181113e3266f1a9df3506fb80189bfe00d9681b55eBrian Paul const GLint bufHeight = (GLint) buffer->Height; 1319a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul 1320a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul if (y < 0 || y >= bufHeight || x + (GLint) n < 0 || x >= bufWidth) { 1321e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* completely above, below, or right */ 1322e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* XXX maybe leave undefined? */ 13236ec6b845fdf3c44436028ad6fff9471d18928719Brian Paul _mesa_bzero(rgba, 4 * n * sizeof(GLchan)); 1324e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1325e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell else { 1326e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell GLint skip, length; 1327e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell if (x < 0) { 1328e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* left edge clippping */ 1329e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell skip = -x; 1330e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell length = (GLint) n - skip; 1331e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell if (length < 0) { 1332e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* completely left of window */ 1333e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell return; 1334e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1335a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul if (length > bufWidth) { 1336a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul length = bufWidth; 1337e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1338e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1339a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul else if ((GLint) (x + n) > bufWidth) { 1340e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* right edge clipping */ 1341e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell skip = 0; 1342a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul length = bufWidth - x; 1343e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell if (length < 0) { 1344e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* completely to right of window */ 1345e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell return; 1346e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1347e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1348e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell else { 1349e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* no clipping */ 1350e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell skip = 0; 1351e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell length = (GLint) n; 1352e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1353e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 1354709892459922a32096fe9dd8261d0d92337bb02fKeith Whitwell (*swrast->Driver.ReadRGBASpan)( ctx, length, x + skip, y, rgba + skip ); 1355e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell if (buffer->UseSoftwareAlphaBuffers) { 1356733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul _mesa_read_alpha_span(ctx, length, x + skip, y, rgba + skip); 1357e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1358e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1359e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell} 1360e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 1361e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 136279c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/** 1363e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Read CI pixels from frame buffer. Clipping will be done to prevent 1364e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * reading ouside the buffer's boundaries. 1365e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */ 13665071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paulvoid 13675071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paul_mesa_read_index_span( GLcontext *ctx, GLframebuffer *buffer, 13685071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paul GLuint n, GLint x, GLint y, GLuint indx[] ) 1369e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell{ 1370709892459922a32096fe9dd8261d0d92337bb02fKeith Whitwell SWcontext *swrast = SWRAST_CONTEXT(ctx); 1371a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul const GLint bufWidth = (GLint) buffer->Width; 13721113e3266f1a9df3506fb80189bfe00d9681b55eBrian Paul const GLint bufHeight = (GLint) buffer->Height; 1373a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul 1374a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul if (y < 0 || y >= bufHeight || x + (GLint) n < 0 || x >= bufWidth) { 1375e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* completely above, below, or right */ 13766ec6b845fdf3c44436028ad6fff9471d18928719Brian Paul _mesa_bzero(indx, n * sizeof(GLuint)); 1377e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1378e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell else { 1379e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell GLint skip, length; 1380e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell if (x < 0) { 1381e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* left edge clippping */ 1382e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell skip = -x; 1383e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell length = (GLint) n - skip; 1384e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell if (length < 0) { 1385e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* completely left of window */ 1386e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell return; 1387e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1388a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul if (length > bufWidth) { 1389a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul length = bufWidth; 1390e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1391e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1392a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul else if ((GLint) (x + n) > bufWidth) { 1393e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* right edge clipping */ 1394e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell skip = 0; 1395a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul length = bufWidth - x; 1396e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell if (length < 0) { 1397e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* completely to right of window */ 1398e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell return; 1399e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1400e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1401e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell else { 1402e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* no clipping */ 1403e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell skip = 0; 1404e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell length = (GLint) n; 1405e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1406e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 1407709892459922a32096fe9dd8261d0d92337bb02fKeith Whitwell (*swrast->Driver.ReadCI32Span)( ctx, length, skip + x, y, indx + skip ); 1408e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1409e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell} 1410