s_span.c revision 9d216be8cfe57f88cd2d890c2334df8ff5c30436
1e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell/* 2e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Mesa 3-D graphics library 31d52b6aaf41b32aaf8d1cdf5a3cd5ff4ecba28f4Brian * Version: 7.1 422144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes * 5884af408644e3fa9aa0ffc544f84ec4a7f3a93b9Brian * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. 622144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes * 7e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Permission is hereby granted, free of charge, to any person obtaining a 8e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * copy of this software and associated documentation files (the "Software"), 9e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * to deal in the Software without restriction, including without limitation 10e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * the rights to use, copy, modify, merge, publish, distribute, sublicense, 11e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * and/or sell copies of the Software, and to permit persons to whom the 12e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Software is furnished to do so, subject to the following conditions: 1322144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes * 14e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * The above copyright notice and this permission notice shall be included 15e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * in all copies or substantial portions of the Software. 1622144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes * 17e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 21e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 22e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */ 24e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 25e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 2679c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/** 27bcb148de9201c7f90a68c7c46434e7ebf7204000Brian Paul * \file swrast/s_span.c 2879c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul * \brief Span processing functions used by all rasterization functions. 2979c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul * This is where all the per-fragment tests are performed 3079c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul * \author Brian Paul 31e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */ 32e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 33bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul#include "main/glheader.h" 34bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul#include "main/colormac.h" 35bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul#include "main/context.h" 36bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul#include "main/macros.h" 37bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul#include "main/imports.h" 38bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul#include "main/image.h" 39e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 407f752fed993e5e9423abac200dd59141edbada56Dave Airlie#include "s_atifragshader.h" 41bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol#include "s_alpha.h" 42e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_blend.h" 43cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell#include "s_context.h" 44e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_depth.h" 45e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_fog.h" 46e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_logic.h" 47e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_masking.h" 48c968d3d410a1897ecbb41d3557adaef69a4c627aBrian#include "s_fragprog.h" 49e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_span.h" 50e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_stencil.h" 5155187ea63e980b32c7a701855571332f4357d634Brian Paul#include "s_texcombine.h" 52e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 532a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 5479c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/** 559e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian * Set default fragment attributes for the span using the 569e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian * current raster values. Used prior to glDraw/CopyPixels 579e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian * and glBitmap. 582a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul */ 592a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paulvoid 609e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian_swrast_span_default_attribs(GLcontext *ctx, SWspan *span) 612a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul{ 629e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian /* Z*/ 639e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian { 649e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian const GLfloat depthMax = ctx->DrawBuffer->_DepthMaxF; 659e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian if (ctx->DrawBuffer->Visual.depthBits <= 16) 669e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian span->z = FloatToFixed(ctx->Current.RasterPos[2] * depthMax + 0.5F); 676254be9b7144821e044d3fbade514fa0358db693Xiang, Haihao else { 686254be9b7144821e044d3fbade514fa0358db693Xiang, Haihao GLfloat tmpf = ctx->Current.RasterPos[2] * depthMax; 696254be9b7144821e044d3fbade514fa0358db693Xiang, Haihao tmpf = MIN2(tmpf, depthMax); 706254be9b7144821e044d3fbade514fa0358db693Xiang, Haihao span->z = (GLint)tmpf; 716254be9b7144821e044d3fbade514fa0358db693Xiang, Haihao } 729e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian span->zStep = 0; 739e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian span->interpMask |= SPAN_Z; 74884af408644e3fa9aa0ffc544f84ec4a7f3a93b9Brian } 752a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 769e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian /* W (for perspective correction) */ 779e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian span->attrStart[FRAG_ATTRIB_WPOS][3] = 1.0; 789e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian span->attrStepX[FRAG_ATTRIB_WPOS][3] = 0.0; 799e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian span->attrStepY[FRAG_ATTRIB_WPOS][3] = 0.0; 802a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 819e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian /* primary color, or color index */ 822a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul if (ctx->Visual.rgbMode) { 832a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLchan r, g, b, a; 842a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul UNCLAMPED_FLOAT_TO_CHAN(r, ctx->Current.RasterColor[0]); 852a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul UNCLAMPED_FLOAT_TO_CHAN(g, ctx->Current.RasterColor[1]); 862a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul UNCLAMPED_FLOAT_TO_CHAN(b, ctx->Current.RasterColor[2]); 872a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul UNCLAMPED_FLOAT_TO_CHAN(a, ctx->Current.RasterColor[3]); 882a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul#if CHAN_TYPE == GL_FLOAT 892a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->red = r; 902a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->green = g; 912a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->blue = b; 922a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->alpha = a; 932a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul#else 942a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->red = IntToFixed(r); 952a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->green = IntToFixed(g); 962a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->blue = IntToFixed(b); 972a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->alpha = IntToFixed(a); 982a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul#endif 992a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->redStep = 0; 1002a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->greenStep = 0; 1012a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->blueStep = 0; 1022a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->alphaStep = 0; 1032a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->interpMask |= SPAN_RGBA; 1049e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian 1059e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian COPY_4V(span->attrStart[FRAG_ATTRIB_COL0], ctx->Current.RasterColor); 1069e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian ASSIGN_4V(span->attrStepX[FRAG_ATTRIB_COL0], 0.0, 0.0, 0.0, 0.0); 1079e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian ASSIGN_4V(span->attrStepY[FRAG_ATTRIB_COL0], 0.0, 0.0, 0.0, 0.0); 1082a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 1092a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul else { 1100f3cd3f894612d156de454178effa4c732f96da7Brian Paul span->index = FloatToFixed(ctx->Current.RasterIndex); 1112a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->indexStep = 0; 1122a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->interpMask |= SPAN_INDEX; 1132a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 1142a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 1159e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian /* Secondary color */ 116f793e90e823a58c0408771c38f3a6209f78a3617Brian if (ctx->Visual.rgbMode && (ctx->Light.Enabled || ctx->Fog.ColorSumEnabled)) 117f793e90e823a58c0408771c38f3a6209f78a3617Brian { 1189e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian COPY_4V(span->attrStart[FRAG_ATTRIB_COL1], ctx->Current.RasterSecondaryColor); 1199e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian ASSIGN_4V(span->attrStepX[FRAG_ATTRIB_COL1], 0.0, 0.0, 0.0, 0.0); 1209e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian ASSIGN_4V(span->attrStepY[FRAG_ATTRIB_COL1], 0.0, 0.0, 0.0, 0.0); 1219e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian } 1229e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian 1239e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian /* fog */ 1249e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian { 1259e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian const SWcontext *swrast = SWRAST_CONTEXT(ctx); 1269e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian GLfloat fogVal; /* a coord or a blend factor */ 1279e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian if (swrast->_PreferPixelFog) { 1289e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian /* fog blend factors will be computed from fog coordinates per pixel */ 1299e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian fogVal = ctx->Current.RasterDistance; 1309e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian } 1319e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian else { 1329e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian /* fog blend factor should be computed from fogcoord now */ 1339e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian fogVal = _swrast_z_to_fogfactor(ctx, ctx->Current.RasterDistance); 1349e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian } 1359e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian span->attrStart[FRAG_ATTRIB_FOGC][0] = fogVal; 1369e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian span->attrStepX[FRAG_ATTRIB_FOGC][0] = 0.0; 1379e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian span->attrStepY[FRAG_ATTRIB_FOGC][0] = 0.0; 1389e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian } 1399e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian 1409e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian /* texcoords */ 1419e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian { 1429e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian GLuint i; 1439e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) { 1449e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian const GLuint attr = FRAG_ATTRIB_TEX0 + i; 1459e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian const GLfloat *tc = ctx->Current.RasterTexCoords[i]; 1469e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian if (ctx->FragmentProgram._Current || ctx->ATIFragmentShader._Enabled) { 1479e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian COPY_4V(span->attrStart[attr], tc); 1489e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian } 1499e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian else if (tc[3] > 0.0F) { 1509e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian /* use (s/q, t/q, r/q, 1) */ 1519e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian span->attrStart[attr][0] = tc[0] / tc[3]; 1529e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian span->attrStart[attr][1] = tc[1] / tc[3]; 1539e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian span->attrStart[attr][2] = tc[2] / tc[3]; 1549e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian span->attrStart[attr][3] = 1.0; 1559e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian } 1569e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian else { 1579e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian ASSIGN_4V(span->attrStart[attr], 0.0F, 0.0F, 0.0F, 1.0F); 1589e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian } 1599e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian ASSIGN_4V(span->attrStepX[attr], 0.0F, 0.0F, 0.0F, 0.0F); 1609e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian ASSIGN_4V(span->attrStepY[attr], 0.0F, 0.0F, 0.0F, 0.0F); 1619e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian } 16238a1c2b4959d35236933c14d3944cce94283ca30Brian } 16338a1c2b4959d35236933c14d3944cce94283ca30Brian} 16438a1c2b4959d35236933c14d3944cce94283ca30Brian 16538a1c2b4959d35236933c14d3944cce94283ca30Brian 1664753d60dd070bb08d0116076bcc08025c86ce857Brian Paul/** 1679e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian * Interpolate the active attributes (and'd with attrMask) to 1689e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian * fill in span->array->attribs[]. 1699e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian * Perspective correction will be done. The point/line/triangle function 1709e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian * should have computed attrStart/Step values for FRAG_ATTRIB_WPOS[3]! 1714753d60dd070bb08d0116076bcc08025c86ce857Brian Paul */ 1729e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrianstatic INLINE void 1739e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrianinterpolate_active_attribs(GLcontext *ctx, SWspan *span, GLbitfield attrMask) 1744753d60dd070bb08d0116076bcc08025c86ce857Brian Paul{ 1759e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian const SWcontext *swrast = SWRAST_CONTEXT(ctx); 1769e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian 1779dca42a4a10acbf1980c0f2eafb3e28e11ca1bf3Brian /* 1789dca42a4a10acbf1980c0f2eafb3e28e11ca1bf3Brian * Don't overwrite existing array values, such as colors that may have 1799dca42a4a10acbf1980c0f2eafb3e28e11ca1bf3Brian * been produced by glDraw/CopyPixels. 180171dcdfa27dda30916a7f9bfed89577feee5d350Brian */ 1819dca42a4a10acbf1980c0f2eafb3e28e11ca1bf3Brian attrMask &= ~span->arrayAttribs; 182171dcdfa27dda30916a7f9bfed89577feee5d350Brian 1839e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian ATTRIB_LOOP_BEGIN 1849e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian if (attrMask & (1 << attr)) { 1859e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian const GLfloat dwdx = span->attrStepX[FRAG_ATTRIB_WPOS][3]; 1869e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian GLfloat w = span->attrStart[FRAG_ATTRIB_WPOS][3]; 1879e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian const GLfloat dv0dx = span->attrStepX[attr][0]; 1889e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian const GLfloat dv1dx = span->attrStepX[attr][1]; 1899e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian const GLfloat dv2dx = span->attrStepX[attr][2]; 1909e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian const GLfloat dv3dx = span->attrStepX[attr][3]; 1919e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian GLfloat v0 = span->attrStart[attr][0]; 1929e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian GLfloat v1 = span->attrStart[attr][1]; 1939e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian GLfloat v2 = span->attrStart[attr][2]; 1949e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian GLfloat v3 = span->attrStart[attr][3]; 1959e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian GLuint k; 1969e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian for (k = 0; k < span->end; k++) { 1979e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian const GLfloat invW = 1.0f / w; 1989e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian span->array->attribs[attr][k][0] = v0 * invW; 1999e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian span->array->attribs[attr][k][1] = v1 * invW; 2009e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian span->array->attribs[attr][k][2] = v2 * invW; 2019e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian span->array->attribs[attr][k][3] = v3 * invW; 2029e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian v0 += dv0dx; 2039e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian v1 += dv1dx; 2049e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian v2 += dv2dx; 2059e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian v3 += dv3dx; 2069e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian w += dwdx; 2079e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian } 2089dca42a4a10acbf1980c0f2eafb3e28e11ca1bf3Brian ASSERT((span->arrayAttribs & (1 << attr)) == 0); 2099e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian span->arrayAttribs |= (1 << attr); 210e63cb85cbc13c083f5d9f4640bb81ba9417a4f28Brian Paul } 2119e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian ATTRIB_LOOP_END 2124753d60dd070bb08d0116076bcc08025c86ce857Brian Paul} 2134753d60dd070bb08d0116076bcc08025c86ce857Brian Paul 2144753d60dd070bb08d0116076bcc08025c86ce857Brian Paul 215d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul/** 2169e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian * Interpolate primary colors to fill in the span->array->rgba8 (or rgb16) 2179e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian * color array. 218d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul */ 219f614a6190562e550257afca0d04e3846648942e8Brian Paulstatic INLINE void 2209e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrianinterpolate_int_colors(GLcontext *ctx, SWspan *span) 2212a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul{ 2222a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul const GLuint n = span->end; 2232a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLuint i; 2242a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 2259e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian#if CHAN_BITS != 32 2269e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian ASSERT(!(span->arrayMask & SPAN_RGBA)); 2279e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian#endif 2282a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 229e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul switch (span->array->ChanType) { 2301e3223c02a2f6155beb5784cadbea1f46703829aBrian Paul#if CHAN_BITS != 32 231e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul case GL_UNSIGNED_BYTE: 232e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul { 2339e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian GLubyte (*rgba)[4] = span->array->rgba8; 234e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul if (span->interpMask & SPAN_FLAT) { 235d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul GLubyte color[4]; 236e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul color[RCOMP] = FixedToInt(span->red); 237e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul color[GCOMP] = FixedToInt(span->green); 238e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul color[BCOMP] = FixedToInt(span->blue); 239e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul color[ACOMP] = FixedToInt(span->alpha); 240d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul for (i = 0; i < n; i++) { 241d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul COPY_4UBV(rgba[i], color); 242d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul } 243d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul } 244e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul else { 245e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul GLfixed r = span->red; 246e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul GLfixed g = span->green; 247e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul GLfixed b = span->blue; 248e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul GLfixed a = span->alpha; 249e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul GLint dr = span->redStep; 250e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul GLint dg = span->greenStep; 251e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul GLint db = span->blueStep; 252e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul GLint da = span->alphaStep; 253d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul for (i = 0; i < n; i++) { 254e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul rgba[i][RCOMP] = FixedToChan(r); 255e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul rgba[i][GCOMP] = FixedToChan(g); 256e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul rgba[i][BCOMP] = FixedToChan(b); 257e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul rgba[i][ACOMP] = FixedToChan(a); 258e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul r += dr; 259e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul g += dg; 260e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul b += db; 261e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul a += da; 262d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul } 263d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul } 264e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul } 265e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul break; 266e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul case GL_UNSIGNED_SHORT: 267e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul { 2689e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian GLushort (*rgba)[4] = span->array->rgba16; 269e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul if (span->interpMask & SPAN_FLAT) { 270e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul GLushort color[4]; 271e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul color[RCOMP] = FixedToInt(span->red); 272e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul color[GCOMP] = FixedToInt(span->green); 273e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul color[BCOMP] = FixedToInt(span->blue); 274e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul color[ACOMP] = FixedToInt(span->alpha); 275d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul for (i = 0; i < n; i++) { 276d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul COPY_4V(rgba[i], color); 277d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul } 278d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul } 279e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul else { 2809e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian GLushort (*rgba)[4] = span->array->rgba16; 281d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul GLfixed r, g, b, a; 282d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul GLint dr, dg, db, da; 283e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul r = span->red; 284e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul g = span->green; 285e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul b = span->blue; 286e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul a = span->alpha; 287e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul dr = span->redStep; 288e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul dg = span->greenStep; 289e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul db = span->blueStep; 290e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul da = span->alphaStep; 291d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul for (i = 0; i < n; i++) { 292d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul rgba[i][RCOMP] = FixedToChan(r); 293d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul rgba[i][GCOMP] = FixedToChan(g); 294d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul rgba[i][BCOMP] = FixedToChan(b); 295d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul rgba[i][ACOMP] = FixedToChan(a); 296d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul r += dr; 297d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul g += dg; 298d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul b += db; 299d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul a += da; 300d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul } 301d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul } 302e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul } 303e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul break; 304e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul#endif 305e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul case GL_FLOAT: 3069e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian interpolate_active_attribs(ctx, span, FRAG_BIT_COL0); 307e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul break; 308e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul default: 3099e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian _mesa_problem(NULL, "bad datatype in interpolate_int_colors"); 310e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul } 311e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul span->arrayMask |= SPAN_RGBA; 312e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul} 313e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul 314e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul 315e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul/** 3169e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian * Populate the FRAG_ATTRIB_COL0 array. 317e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul */ 318f614a6190562e550257afca0d04e3846648942e8Brian Paulstatic INLINE void 3199e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrianinterpolate_float_colors(SWspan *span) 320e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul{ 3219e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian GLfloat (*col0)[4] = span->array->attribs[FRAG_ATTRIB_COL0]; 322e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul const GLuint n = span->end; 323e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul GLuint i; 324e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul 3259e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian assert(!(span->arrayAttribs & FRAG_BIT_COL0)); 3269e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian 3279e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian if (span->arrayMask & SPAN_RGBA) { 3289e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian /* convert array of int colors */ 3299e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian for (i = 0; i < n; i++) { 3309e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian col0[i][0] = UBYTE_TO_FLOAT(span->array->rgba8[i][0]); 3319e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian col0[i][1] = UBYTE_TO_FLOAT(span->array->rgba8[i][1]); 3329e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian col0[i][2] = UBYTE_TO_FLOAT(span->array->rgba8[i][2]); 3339e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian col0[i][3] = UBYTE_TO_FLOAT(span->array->rgba8[i][3]); 334e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul } 3359e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian } 3369e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian else { 3379e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian /* interpolate red/green/blue/alpha to get float colors */ 3389e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian ASSERT(span->interpMask & SPAN_RGBA); 3399e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian if (span->interpMask & SPAN_FLAT) { 3409e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian GLfloat r = FixedToFloat(span->red); 3419e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian GLfloat g = FixedToFloat(span->green); 3429e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian GLfloat b = FixedToFloat(span->blue); 3439e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian GLfloat a = FixedToFloat(span->alpha); 3449e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian for (i = 0; i < n; i++) { 3459e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian ASSIGN_4V(col0[i], r, g, b, a); 346e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul } 347e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul } 3489e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian else { 3499e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian GLfloat r = FixedToFloat(span->red); 3509e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian GLfloat g = FixedToFloat(span->green); 3519e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian GLfloat b = FixedToFloat(span->blue); 3529e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian GLfloat a = FixedToFloat(span->alpha); 3539e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian GLfloat dr = FixedToFloat(span->redStep); 3549e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian GLfloat dg = FixedToFloat(span->greenStep); 3559e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian GLfloat db = FixedToFloat(span->blueStep); 3569e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian GLfloat da = FixedToFloat(span->alphaStep); 357e6f47d1855354165c6eed5080d8a72024891f10fBrian Paul for (i = 0; i < n; i++) { 3589e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian col0[i][0] = r; 3599e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian col0[i][1] = g; 3609e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian col0[i][2] = b; 3619e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian col0[i][3] = a; 362e6f47d1855354165c6eed5080d8a72024891f10fBrian Paul r += dr; 363e6f47d1855354165c6eed5080d8a72024891f10fBrian Paul g += dg; 364e6f47d1855354165c6eed5080d8a72024891f10fBrian Paul b += db; 3659e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian a += da; 366d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul } 3672a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 3682a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 3699e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian 3709e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian span->arrayAttribs |= FRAG_BIT_COL0; 3719e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian span->array->ChanType = GL_FLOAT; 3722a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul} 3732a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 3742a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 3759e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian 3762a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul/* Fill in the span.color.index array from the interpolation values */ 377f614a6190562e550257afca0d04e3846648942e8Brian Paulstatic INLINE void 378cdb27e8242215271364602995d85607cfc06d441Brian Paulinterpolate_indexes(GLcontext *ctx, SWspan *span) 3792a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul{ 3802a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfixed index = span->index; 3812a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul const GLint indexStep = span->indexStep; 3822a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul const GLuint n = span->end; 38377df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul GLuint *indexes = span->array->index; 3842a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLuint i; 385a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul (void) ctx; 3869e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian 3879e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian ASSERT(!(span->arrayMask & SPAN_INDEX)); 3882a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 3892a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul if ((span->interpMask & SPAN_FLAT) || (indexStep == 0)) { 3902a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul /* constant color */ 3912a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul index = FixedToInt(index); 3922a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul for (i = 0; i < n; i++) { 3932a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul indexes[i] = index; 3942a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 3952a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 3962a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul else { 3972a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul /* interpolate */ 3982a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul for (i = 0; i < n; i++) { 3992a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul indexes[i] = FixedToInt(index); 4002a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul index += indexStep; 4012a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 4022a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 4032a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->arrayMask |= SPAN_INDEX; 404e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul span->interpMask &= ~SPAN_INDEX; 4052a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul} 4062a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 4072a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 4089e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian/** 4099e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian * Fill in the span.zArray array from the span->z, zStep values. 4109e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian */ 411711e27fda27e4235b20a4cf73c2767c984ab2b81Brian Paulvoid 412cdb27e8242215271364602995d85607cfc06d441Brian Paul_swrast_span_interpolate_z( const GLcontext *ctx, SWspan *span ) 4132a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul{ 4142a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul const GLuint n = span->end; 4152a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLuint i; 4162a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 4179e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian ASSERT(!(span->arrayMask & SPAN_Z)); 4182a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 41931e739a18931fa48454f172818245b0927c8910fBrian Paul if (ctx->DrawBuffer->Visual.depthBits <= 16) { 4202a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfixed zval = span->z; 4213e37bafab0a339021354b9c78f983d05d433d735Brian Paul GLuint *z = span->array->z; 422ad8cd6111e022c90c93df106c0fde6f64d205816Brian Paul for (i = 0; i < n; i++) { 42377df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul z[i] = FixedToInt(zval); 4242a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul zval += span->zStep; 4252a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 4262a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 4272a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul else { 4282a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul /* Deep Z buffer, no fixed->int shift */ 4297265556b9aa0367e9b5031e7cb15ed2a5d73866dBrian Paul GLuint zval = span->z; 4303e37bafab0a339021354b9c78f983d05d433d735Brian Paul GLuint *z = span->array->z; 4312a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul for (i = 0; i < n; i++) { 43277df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul z[i] = zval; 4332a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul zval += span->zStep; 4342a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 4352a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 43632340aea1308153dad5c105fc0748aea1e4c37eeBrian Paul span->interpMask &= ~SPAN_Z; 4372a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->arrayMask |= SPAN_Z; 4382a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul} 4392a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 4402a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 4419e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian/** 4429e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian * Compute mipmap LOD from partial derivatives. 44331f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul * This the ideal solution, as given in the OpenGL spec. 444c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul */ 445c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul#if 0 44631f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paulstatic GLfloat 44731f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paulcompute_lambda(GLfloat dsdx, GLfloat dsdy, GLfloat dtdx, GLfloat dtdy, 44831f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat dqdx, GLfloat dqdy, GLfloat texW, GLfloat texH, 44931f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat s, GLfloat t, GLfloat q, GLfloat invQ) 450c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul{ 45131f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat dudx = texW * ((s + dsdx) / (q + dqdx) - s * invQ); 45231f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat dvdx = texH * ((t + dtdx) / (q + dqdx) - t * invQ); 45331f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat dudy = texW * ((s + dsdy) / (q + dqdy) - s * invQ); 45431f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat dvdy = texH * ((t + dtdy) / (q + dqdy) - t * invQ); 455f9b1e5241facc8cf255c258082d5cb5b04783e93Brian Paul GLfloat x = SQRTF(dudx * dudx + dvdx * dvdx); 456f9b1e5241facc8cf255c258082d5cb5b04783e93Brian Paul GLfloat y = SQRTF(dudy * dudy + dvdy * dvdy); 45731f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat rho = MAX2(x, y); 45831f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat lambda = LOG2(rho); 45931f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul return lambda; 460c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul} 461c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul#endif 462c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul 46331f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul 4649e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian/** 4659e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian * Compute mipmap LOD from partial derivatives. 4669e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian * This is a faster approximation than above function. 467c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul */ 468350353adcd75f94fda63c787c86961716114e0bfBrian PaulGLfloat 46945bc887da226403f2c41077e40ca38b6f60f1359Brian Paul_swrast_compute_lambda(GLfloat dsdx, GLfloat dsdy, GLfloat dtdx, GLfloat dtdy, 470350353adcd75f94fda63c787c86961716114e0bfBrian Paul GLfloat dqdx, GLfloat dqdy, GLfloat texW, GLfloat texH, 471350353adcd75f94fda63c787c86961716114e0bfBrian Paul GLfloat s, GLfloat t, GLfloat q, GLfloat invQ) 472c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul{ 47331f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat dsdx2 = (s + dsdx) / (q + dqdx) - s * invQ; 47431f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat dtdx2 = (t + dtdx) / (q + dqdx) - t * invQ; 47531f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat dsdy2 = (s + dsdy) / (q + dqdy) - s * invQ; 47631f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat dtdy2 = (t + dtdy) / (q + dqdy) - t * invQ; 47731f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat maxU, maxV, rho, lambda; 47831f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul dsdx2 = FABSF(dsdx2); 47931f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul dsdy2 = FABSF(dsdy2); 48031f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul dtdx2 = FABSF(dtdx2); 48131f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul dtdy2 = FABSF(dtdy2); 48231f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul maxU = MAX2(dsdx2, dsdy2) * texW; 48331f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul maxV = MAX2(dtdx2, dtdy2) * texH; 48431f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul rho = MAX2(maxU, maxV); 48531f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul lambda = LOG2(rho); 48631f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul return lambda; 487c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul} 488c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul 489d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul 490d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul/** 4919e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian * Fill in the span.array->attrib[FRAG_ATTRIB_TEXn] arrays from the 4929e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian * using the attrStart/Step values. 4939e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian * 4949e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian * This function only used during fixed-function fragment processing. 4959e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian * 496d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul * Note: in the places where we divide by Q (or mult by invQ) we're 497d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul * really doing two things: perspective correction and texcoord 498d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul * projection. Remember, for texcoord (s,t,r,q) we need to index 499d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul * texels with (s/q, t/q, r/q). 500c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul */ 5012a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paulstatic void 502cdb27e8242215271364602995d85607cfc06d441Brian Paulinterpolate_texcoords(GLcontext *ctx, SWspan *span) 5032a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul{ 504e4f976b8b9d74a74b5816146cb11880c3a493929Brian const GLuint maxUnit 505e4f976b8b9d74a74b5816146cb11880c3a493929Brian = (ctx->Texture._EnabledCoordUnits > 1) ? ctx->Const.MaxTextureUnits : 1; 506e4f976b8b9d74a74b5816146cb11880c3a493929Brian GLuint u; 507e4f976b8b9d74a74b5816146cb11880c3a493929Brian 508e4f976b8b9d74a74b5816146cb11880c3a493929Brian /* XXX CoordUnits vs. ImageUnits */ 509e4f976b8b9d74a74b5816146cb11880c3a493929Brian for (u = 0; u < maxUnit; u++) { 510e4f976b8b9d74a74b5816146cb11880c3a493929Brian if (ctx->Texture._EnabledCoordUnits & (1 << u)) { 511e4f976b8b9d74a74b5816146cb11880c3a493929Brian const GLuint attr = FRAG_ATTRIB_TEX0 + u; 512c000843a14e73d593d87ff6674d0295d2cb64a12Brian const struct gl_texture_object *obj = ctx->Texture.Unit[u]._Current; 513e4f976b8b9d74a74b5816146cb11880c3a493929Brian GLfloat texW, texH; 514e4f976b8b9d74a74b5816146cb11880c3a493929Brian GLboolean needLambda; 515e4f976b8b9d74a74b5816146cb11880c3a493929Brian GLfloat (*texcoord)[4] = span->array->attribs[attr]; 516e4f976b8b9d74a74b5816146cb11880c3a493929Brian GLfloat *lambda = span->array->lambda[u]; 517e4f976b8b9d74a74b5816146cb11880c3a493929Brian const GLfloat dsdx = span->attrStepX[attr][0]; 518e4f976b8b9d74a74b5816146cb11880c3a493929Brian const GLfloat dsdy = span->attrStepY[attr][0]; 519e4f976b8b9d74a74b5816146cb11880c3a493929Brian const GLfloat dtdx = span->attrStepX[attr][1]; 520e4f976b8b9d74a74b5816146cb11880c3a493929Brian const GLfloat dtdy = span->attrStepY[attr][1]; 521e4f976b8b9d74a74b5816146cb11880c3a493929Brian const GLfloat drdx = span->attrStepX[attr][2]; 522e4f976b8b9d74a74b5816146cb11880c3a493929Brian const GLfloat dqdx = span->attrStepX[attr][3]; 523e4f976b8b9d74a74b5816146cb11880c3a493929Brian const GLfloat dqdy = span->attrStepY[attr][3]; 524e4f976b8b9d74a74b5816146cb11880c3a493929Brian GLfloat s = span->attrStart[attr][0]; 525e4f976b8b9d74a74b5816146cb11880c3a493929Brian GLfloat t = span->attrStart[attr][1]; 526e4f976b8b9d74a74b5816146cb11880c3a493929Brian GLfloat r = span->attrStart[attr][2]; 527e4f976b8b9d74a74b5816146cb11880c3a493929Brian GLfloat q = span->attrStart[attr][3]; 528e4f976b8b9d74a74b5816146cb11880c3a493929Brian 529e4f976b8b9d74a74b5816146cb11880c3a493929Brian if (obj) { 530e4f976b8b9d74a74b5816146cb11880c3a493929Brian const struct gl_texture_image *img = obj->Image[0][obj->BaseLevel]; 531e4f976b8b9d74a74b5816146cb11880c3a493929Brian needLambda = (obj->MinFilter != obj->MagFilter) 532e4f976b8b9d74a74b5816146cb11880c3a493929Brian || ctx->FragmentProgram._Current; 533e4f976b8b9d74a74b5816146cb11880c3a493929Brian texW = img->WidthScale; 534e4f976b8b9d74a74b5816146cb11880c3a493929Brian texH = img->HeightScale; 535e4f976b8b9d74a74b5816146cb11880c3a493929Brian } 536e4f976b8b9d74a74b5816146cb11880c3a493929Brian else { 537e4f976b8b9d74a74b5816146cb11880c3a493929Brian /* using a fragment program */ 538e4f976b8b9d74a74b5816146cb11880c3a493929Brian texW = 1.0; 539e4f976b8b9d74a74b5816146cb11880c3a493929Brian texH = 1.0; 540e4f976b8b9d74a74b5816146cb11880c3a493929Brian needLambda = GL_FALSE; 541e4f976b8b9d74a74b5816146cb11880c3a493929Brian } 542e4f976b8b9d74a74b5816146cb11880c3a493929Brian 543e4f976b8b9d74a74b5816146cb11880c3a493929Brian if (needLambda) { 544e4f976b8b9d74a74b5816146cb11880c3a493929Brian GLuint i; 545e4f976b8b9d74a74b5816146cb11880c3a493929Brian if (ctx->FragmentProgram._Current 546e4f976b8b9d74a74b5816146cb11880c3a493929Brian || ctx->ATIFragmentShader._Enabled) { 547e4f976b8b9d74a74b5816146cb11880c3a493929Brian /* do perspective correction but don't divide s, t, r by q */ 548e4f976b8b9d74a74b5816146cb11880c3a493929Brian const GLfloat dwdx = span->attrStepX[FRAG_ATTRIB_WPOS][3]; 549e4f976b8b9d74a74b5816146cb11880c3a493929Brian GLfloat w = span->attrStart[FRAG_ATTRIB_WPOS][3]; 550e4f976b8b9d74a74b5816146cb11880c3a493929Brian for (i = 0; i < span->end; i++) { 551e4f976b8b9d74a74b5816146cb11880c3a493929Brian const GLfloat invW = 1.0F / w; 552e4f976b8b9d74a74b5816146cb11880c3a493929Brian texcoord[i][0] = s * invW; 553e4f976b8b9d74a74b5816146cb11880c3a493929Brian texcoord[i][1] = t * invW; 554e4f976b8b9d74a74b5816146cb11880c3a493929Brian texcoord[i][2] = r * invW; 555e4f976b8b9d74a74b5816146cb11880c3a493929Brian texcoord[i][3] = q * invW; 556e4f976b8b9d74a74b5816146cb11880c3a493929Brian lambda[i] = _swrast_compute_lambda(dsdx, dsdy, dtdx, dtdy, 557e4f976b8b9d74a74b5816146cb11880c3a493929Brian dqdx, dqdy, texW, texH, 558e4f976b8b9d74a74b5816146cb11880c3a493929Brian s, t, q, invW); 559e4f976b8b9d74a74b5816146cb11880c3a493929Brian s += dsdx; 560e4f976b8b9d74a74b5816146cb11880c3a493929Brian t += dtdx; 561e4f976b8b9d74a74b5816146cb11880c3a493929Brian r += drdx; 562e4f976b8b9d74a74b5816146cb11880c3a493929Brian q += dqdx; 563e4f976b8b9d74a74b5816146cb11880c3a493929Brian w += dwdx; 5642a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 5652a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 56631f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul else { 567e4f976b8b9d74a74b5816146cb11880c3a493929Brian for (i = 0; i < span->end; i++) { 5682a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q); 569e4f976b8b9d74a74b5816146cb11880c3a493929Brian texcoord[i][0] = s * invQ; 570e4f976b8b9d74a74b5816146cb11880c3a493929Brian texcoord[i][1] = t * invQ; 571e4f976b8b9d74a74b5816146cb11880c3a493929Brian texcoord[i][2] = r * invQ; 572e4f976b8b9d74a74b5816146cb11880c3a493929Brian texcoord[i][3] = q; 573e4f976b8b9d74a74b5816146cb11880c3a493929Brian lambda[i] = _swrast_compute_lambda(dsdx, dsdy, dtdx, dtdy, 574e4f976b8b9d74a74b5816146cb11880c3a493929Brian dqdx, dqdy, texW, texH, 575e4f976b8b9d74a74b5816146cb11880c3a493929Brian s, t, q, invQ); 576e4f976b8b9d74a74b5816146cb11880c3a493929Brian s += dsdx; 577e4f976b8b9d74a74b5816146cb11880c3a493929Brian t += dtdx; 578e4f976b8b9d74a74b5816146cb11880c3a493929Brian r += drdx; 579e4f976b8b9d74a74b5816146cb11880c3a493929Brian q += dqdx; 5802a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 581d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul } 582e4f976b8b9d74a74b5816146cb11880c3a493929Brian span->arrayMask |= SPAN_LAMBDA; 583d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul } 584d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul else { 585e4f976b8b9d74a74b5816146cb11880c3a493929Brian GLuint i; 586e4f976b8b9d74a74b5816146cb11880c3a493929Brian if (ctx->FragmentProgram._Current || 587e4f976b8b9d74a74b5816146cb11880c3a493929Brian ctx->ATIFragmentShader._Enabled) { 588e4f976b8b9d74a74b5816146cb11880c3a493929Brian /* do perspective correction but don't divide s, t, r by q */ 589e4f976b8b9d74a74b5816146cb11880c3a493929Brian const GLfloat dwdx = span->attrStepX[FRAG_ATTRIB_WPOS][3]; 590e4f976b8b9d74a74b5816146cb11880c3a493929Brian GLfloat w = span->attrStart[FRAG_ATTRIB_WPOS][3]; 591e4f976b8b9d74a74b5816146cb11880c3a493929Brian for (i = 0; i < span->end; i++) { 592e4f976b8b9d74a74b5816146cb11880c3a493929Brian const GLfloat invW = 1.0F / w; 593e4f976b8b9d74a74b5816146cb11880c3a493929Brian texcoord[i][0] = s * invW; 594e4f976b8b9d74a74b5816146cb11880c3a493929Brian texcoord[i][1] = t * invW; 595e4f976b8b9d74a74b5816146cb11880c3a493929Brian texcoord[i][2] = r * invW; 596e4f976b8b9d74a74b5816146cb11880c3a493929Brian texcoord[i][3] = q * invW; 597e4f976b8b9d74a74b5816146cb11880c3a493929Brian lambda[i] = 0.0; 598e4f976b8b9d74a74b5816146cb11880c3a493929Brian s += dsdx; 599e4f976b8b9d74a74b5816146cb11880c3a493929Brian t += dtdx; 600e4f976b8b9d74a74b5816146cb11880c3a493929Brian r += drdx; 601e4f976b8b9d74a74b5816146cb11880c3a493929Brian q += dqdx; 602e4f976b8b9d74a74b5816146cb11880c3a493929Brian w += dwdx; 603e4f976b8b9d74a74b5816146cb11880c3a493929Brian } 604c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul } 605e4f976b8b9d74a74b5816146cb11880c3a493929Brian else if (dqdx == 0.0F) { 606e4f976b8b9d74a74b5816146cb11880c3a493929Brian /* Ortho projection or polygon's parallel to window X axis */ 607c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q); 608e4f976b8b9d74a74b5816146cb11880c3a493929Brian for (i = 0; i < span->end; i++) { 609e4f976b8b9d74a74b5816146cb11880c3a493929Brian texcoord[i][0] = s * invQ; 610e4f976b8b9d74a74b5816146cb11880c3a493929Brian texcoord[i][1] = t * invQ; 611e4f976b8b9d74a74b5816146cb11880c3a493929Brian texcoord[i][2] = r * invQ; 612e4f976b8b9d74a74b5816146cb11880c3a493929Brian texcoord[i][3] = q; 613e4f976b8b9d74a74b5816146cb11880c3a493929Brian lambda[i] = 0.0; 614e4f976b8b9d74a74b5816146cb11880c3a493929Brian s += dsdx; 615e4f976b8b9d74a74b5816146cb11880c3a493929Brian t += dtdx; 616e4f976b8b9d74a74b5816146cb11880c3a493929Brian r += drdx; 617e4f976b8b9d74a74b5816146cb11880c3a493929Brian } 618c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul } 619e4f976b8b9d74a74b5816146cb11880c3a493929Brian else { 620e4f976b8b9d74a74b5816146cb11880c3a493929Brian for (i = 0; i < span->end; i++) { 621e4f976b8b9d74a74b5816146cb11880c3a493929Brian const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q); 622e4f976b8b9d74a74b5816146cb11880c3a493929Brian texcoord[i][0] = s * invQ; 623e4f976b8b9d74a74b5816146cb11880c3a493929Brian texcoord[i][1] = t * invQ; 624e4f976b8b9d74a74b5816146cb11880c3a493929Brian texcoord[i][2] = r * invQ; 625e4f976b8b9d74a74b5816146cb11880c3a493929Brian texcoord[i][3] = q; 626e4f976b8b9d74a74b5816146cb11880c3a493929Brian lambda[i] = 0.0; 627e4f976b8b9d74a74b5816146cb11880c3a493929Brian s += dsdx; 628e4f976b8b9d74a74b5816146cb11880c3a493929Brian t += dtdx; 629e4f976b8b9d74a74b5816146cb11880c3a493929Brian r += drdx; 630e4f976b8b9d74a74b5816146cb11880c3a493929Brian q += dqdx; 631e4f976b8b9d74a74b5816146cb11880c3a493929Brian } 632e4f976b8b9d74a74b5816146cb11880c3a493929Brian } 633e4f976b8b9d74a74b5816146cb11880c3a493929Brian } /* lambda */ 634e4f976b8b9d74a74b5816146cb11880c3a493929Brian } /* if */ 635e4f976b8b9d74a74b5816146cb11880c3a493929Brian } /* for */ 63610f30eb43835c57c00783390a02d72daf4f78e26Brian Paul} 637e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 638e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 639bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol/** 640f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian * Fill in the arrays->attribs[FRAG_ATTRIB_WPOS] array. 641f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian */ 642f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brianstatic INLINE void 643f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brianinterpolate_wpos(GLcontext *ctx, SWspan *span) 644f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian{ 645f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian GLfloat (*wpos)[4] = span->array->attribs[FRAG_ATTRIB_WPOS]; 646f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian GLuint i; 6478e6207396c6314d07614c80670f4e3196e3a8551Brian const GLfloat zScale = 1.0 / ctx->DrawBuffer->_DepthMaxF; 6488e6207396c6314d07614c80670f4e3196e3a8551Brian GLfloat w, dw; 6498e6207396c6314d07614c80670f4e3196e3a8551Brian 650f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian if (span->arrayMask & SPAN_XY) { 651f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian for (i = 0; i < span->end; i++) { 652f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian wpos[i][0] = (GLfloat) span->array->x[i]; 653f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian wpos[i][1] = (GLfloat) span->array->y[i]; 654f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian } 655f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian } 656f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian else { 657f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian for (i = 0; i < span->end; i++) { 658f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian wpos[i][0] = (GLfloat) span->x + i; 659f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian wpos[i][1] = (GLfloat) span->y; 660f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian } 661f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian } 6628e6207396c6314d07614c80670f4e3196e3a8551Brian 6638e6207396c6314d07614c80670f4e3196e3a8551Brian w = span->attrStart[FRAG_ATTRIB_WPOS][3]; 6648e6207396c6314d07614c80670f4e3196e3a8551Brian dw = span->attrStepX[FRAG_ATTRIB_WPOS][3]; 665f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian for (i = 0; i < span->end; i++) { 6668e6207396c6314d07614c80670f4e3196e3a8551Brian wpos[i][2] = (GLfloat) span->array->z[i] * zScale; 6678e6207396c6314d07614c80670f4e3196e3a8551Brian wpos[i][3] = w; 6688e6207396c6314d07614c80670f4e3196e3a8551Brian w += dw; 669f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian } 670f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian} 671f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian 672f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian 673f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian/** 674e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Apply the current polygon stipple pattern to a span of pixels. 675e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */ 676f614a6190562e550257afca0d04e3846648942e8Brian Paulstatic INLINE void 677ea8b68e0f7e7a4025ce662d36380157273ce10a3Brianstipple_polygon_span(GLcontext *ctx, SWspan *span) 67810f30eb43835c57c00783390a02d72daf4f78e26Brian Paul{ 67977df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul GLubyte *mask = span->array->mask; 680733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul 681733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul ASSERT(ctx->Polygon.StippleFlag); 68210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 683ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian if (span->arrayMask & SPAN_XY) { 684ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian /* arrays of x/y pixel coords */ 685ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian GLuint i; 686ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian for (i = 0; i < span->end; i++) { 687ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian const GLint col = span->array->x[i] % 32; 688ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian const GLint row = span->array->y[i] % 32; 689ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian const GLuint stipple = ctx->PolygonStipple[row]; 690ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian if (((1 << col) & stipple) == 0) { 691ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian mask[i] = 0; 692ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian } 69310f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 694ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian } 695ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian else { 696ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian /* horizontal span of pixels */ 697ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian const GLuint highBit = 1 << 31; 698ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian const GLuint stipple = ctx->PolygonStipple[span->y % 32]; 699ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian GLuint i, m = highBit >> (GLuint) (span->x % 32); 700ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian for (i = 0; i < span->end; i++) { 701ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian if ((m & stipple) == 0) { 702ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian mask[i] = 0; 703ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian } 704ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian m = m >> 1; 705ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian if (m == 0) { 706ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian m = highBit; 707ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian } 70810f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 70910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 7102ef866d1fc0a5cc5ef8543d65744dfd4da4dbbafBrian Paul span->writeAll = GL_FALSE; 71110f30eb43835c57c00783390a02d72daf4f78e26Brian Paul} 71210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 713e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 71479c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/** 715733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul * Clip a pixel span to the current buffer/window boundaries: 716733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul * DrawBuffer->_Xmin, _Xmax, _Ymin, _Ymax. This will accomplish 717733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul * window clipping and scissoring. 718733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul * Return: GL_TRUE some pixels still visible 71910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul * GL_FALSE nothing visible 72010f30eb43835c57c00783390a02d72daf4f78e26Brian Paul */ 721f614a6190562e550257afca0d04e3846648942e8Brian Paulstatic INLINE GLuint 722cdb27e8242215271364602995d85607cfc06d441Brian Paulclip_span( GLcontext *ctx, SWspan *span ) 72310f30eb43835c57c00783390a02d72daf4f78e26Brian Paul{ 724733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul const GLint xmin = ctx->DrawBuffer->_Xmin; 725733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul const GLint xmax = ctx->DrawBuffer->_Xmax; 726733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul const GLint ymin = ctx->DrawBuffer->_Ymin; 727733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul const GLint ymax = ctx->DrawBuffer->_Ymax; 728733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul 729733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (span->arrayMask & SPAN_XY) { 730733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* arrays of x/y pixel coords */ 73177df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul const GLint *x = span->array->x; 73277df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul const GLint *y = span->array->y; 733733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul const GLint n = span->end; 73477df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul GLubyte *mask = span->array->mask; 735733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul GLint i; 736b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul if (span->arrayMask & SPAN_MASK) { 737b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul /* note: using & intead of && to reduce branches */ 738b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul for (i = 0; i < n; i++) { 739b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul mask[i] &= (x[i] >= xmin) & (x[i] < xmax) 740b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul & (y[i] >= ymin) & (y[i] < ymax); 741b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul } 742b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul } 743b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul else { 744b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul /* note: using & intead of && to reduce branches */ 745b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul for (i = 0; i < n; i++) { 746b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul mask[i] = (x[i] >= xmin) & (x[i] < xmax) 747b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul & (y[i] >= ymin) & (y[i] < ymax); 748b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul } 74910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 750733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul return GL_TRUE; /* some pixels visible */ 75110f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 752733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul else { 753733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* horizontal span of pixels */ 754733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul const GLint x = span->x; 755733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul const GLint y = span->y; 756733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul const GLint n = span->end; 757733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul 758733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* Trivial rejection tests */ 759733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (y < ymin || y >= ymax || x + n <= xmin || x >= xmax) { 760733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->end = 0; 761733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul return GL_FALSE; /* all pixels clipped */ 762733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul } 76310f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 764733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* Clip to the left */ 765733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (x < xmin) { 766733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul ASSERT(x + n > xmin); 767733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->writeAll = GL_FALSE; 7686ec6b845fdf3c44436028ad6fff9471d18928719Brian Paul _mesa_bzero(span->array->mask, (xmin - x) * sizeof(GLubyte)); 76910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 770733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul 771733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* Clip to right */ 772733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (x + n > xmax) { 773733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul ASSERT(x < xmax); 774733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->end = xmax - x; 77510f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 77610f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 777733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul return GL_TRUE; /* some pixels visible */ 778733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul } 77910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul} 78010f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 78110f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 78279c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/** 783e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul * Apply all the per-fragment opertions to a span of color index fragments 784e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul * and write them to the enabled color drawbuffers. 785e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul * The 'span' parameter can be considered to be const. Note that 7867956292a765910077f50352d7cd0174e1e66d26cBrian Paul * span->interpMask and span->arrayMask may be changed but will be restored 7877956292a765910077f50352d7cd0174e1e66d26cBrian Paul * to their original values before returning. 78810f30eb43835c57c00783390a02d72daf4f78e26Brian Paul */ 78910f30eb43835c57c00783390a02d72daf4f78e26Brian Paulvoid 790cdb27e8242215271364602995d85607cfc06d441Brian Paul_swrast_write_index_span( GLcontext *ctx, SWspan *span) 79110f30eb43835c57c00783390a02d72daf4f78e26Brian Paul{ 792e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul const SWcontext *swrast = SWRAST_CONTEXT(ctx); 793e00ac11d4dd05c56584622dc2707bbdcfe4b2707Brian Paul const GLbitfield origInterpMask = span->interpMask; 794e00ac11d4dd05c56584622dc2707bbdcfe4b2707Brian Paul const GLbitfield origArrayMask = span->arrayMask; 795ff73c783cc47361ff0dd819c82d067b4b85870ddBrian struct gl_framebuffer *fb = ctx->DrawBuffer; 79610f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 797733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul ASSERT(span->end <= MAX_WIDTH); 798b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul ASSERT(span->primitive == GL_POINT || span->primitive == GL_LINE || 799b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul span->primitive == GL_POLYGON || span->primitive == GL_BITMAP); 800733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul ASSERT((span->interpMask | span->arrayMask) & SPAN_INDEX); 8019e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian /* 8027956292a765910077f50352d7cd0174e1e66d26cBrian Paul ASSERT((span->interpMask & span->arrayMask) == 0); 8039e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian */ 8047956292a765910077f50352d7cd0174e1e66d26cBrian Paul 805733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (span->arrayMask & SPAN_MASK) { 806733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* mask was initialized by caller, probably glBitmap */ 807733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->writeAll = GL_FALSE; 808733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul } 809733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul else { 810a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul _mesa_memset(span->array->mask, 1, span->end); 811733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->writeAll = GL_TRUE; 81210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 81310f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 814733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* Clipping */ 815b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul if ((swrast->_RasterMask & CLIP_BIT) || (span->primitive != GL_POLYGON)) { 816733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (!clip_span(ctx, span)) { 81786ca15ece74ccb5a8f4d566a4b2c8024b178d73bBrian Paul return; 818e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 819e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 820e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 821e5b244ff7f984805c1bcc020342f1300f2639c71Brian Paul /* Depth bounds test */ 822ff73c783cc47361ff0dd819c82d067b4b85870ddBrian if (ctx->Depth.BoundsTest && fb->Visual.depthBits > 0) { 823e5b244ff7f984805c1bcc020342f1300f2639c71Brian Paul if (!_swrast_depth_bounds_test(ctx, span)) { 824e5b244ff7f984805c1bcc020342f1300f2639c71Brian Paul return; 825e5b244ff7f984805c1bcc020342f1300f2639c71Brian Paul } 826e5b244ff7f984805c1bcc020342f1300f2639c71Brian Paul } 827e5b244ff7f984805c1bcc020342f1300f2639c71Brian Paul 828b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul#ifdef DEBUG 829a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul /* Make sure all fragments are within window bounds */ 830b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul if (span->arrayMask & SPAN_XY) { 831a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul GLuint i; 832b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul for (i = 0; i < span->end; i++) { 83377df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul if (span->array->mask[i]) { 834ff73c783cc47361ff0dd819c82d067b4b85870ddBrian assert(span->array->x[i] >= fb->_Xmin); 835ff73c783cc47361ff0dd819c82d067b4b85870ddBrian assert(span->array->x[i] < fb->_Xmax); 836ff73c783cc47361ff0dd819c82d067b4b85870ddBrian assert(span->array->y[i] >= fb->_Ymin); 837ff73c783cc47361ff0dd819c82d067b4b85870ddBrian assert(span->array->y[i] < fb->_Ymax); 838b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul } 839b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul } 840b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul } 841b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul#endif 842b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul 843e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* Polygon Stippling */ 844b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul if (ctx->Polygon.StippleFlag && span->primitive == GL_POLYGON) { 84510f30eb43835c57c00783390a02d72daf4f78e26Brian Paul stipple_polygon_span(ctx, span); 846e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 847e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 848e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul /* Stencil and Z testing */ 8497956292a765910077f50352d7cd0174e1e66d26cBrian Paul if (ctx->Depth.Test || ctx->Stencil.Enabled) { 8509e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian if (!(span->arrayMask & SPAN_Z)) 85145bc887da226403f2c41077e40ca38b6f60f1359Brian Paul _swrast_span_interpolate_z(ctx, span); 85210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 8537956292a765910077f50352d7cd0174e1e66d26cBrian Paul if (ctx->Stencil.Enabled) { 85445bc887da226403f2c41077e40ca38b6f60f1359Brian Paul if (!_swrast_stencil_and_ztest_span(ctx, span)) { 8557956292a765910077f50352d7cd0174e1e66d26cBrian Paul span->arrayMask = origArrayMask; 8567956292a765910077f50352d7cd0174e1e66d26cBrian Paul return; 8577956292a765910077f50352d7cd0174e1e66d26cBrian Paul } 8582a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 8597956292a765910077f50352d7cd0174e1e66d26cBrian Paul else { 8607956292a765910077f50352d7cd0174e1e66d26cBrian Paul ASSERT(ctx->Depth.Test); 86145bc887da226403f2c41077e40ca38b6f60f1359Brian Paul if (!_swrast_depth_test_span(ctx, span)) { 862e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul span->interpMask = origInterpMask; 8637956292a765910077f50352d7cd0174e1e66d26cBrian Paul span->arrayMask = origArrayMask; 8647956292a765910077f50352d7cd0174e1e66d26cBrian Paul return; 8657956292a765910077f50352d7cd0174e1e66d26cBrian Paul } 8662a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 86710f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 86810f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 869b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul#if FEATURE_ARB_occlusion_query 87023ffc3a85d6172f8a98d17d7f23610bab808d84eBrian Paul if (ctx->Query.CurrentOcclusionObject) { 871939dd17653245621bf7488803f09418244b7b0b7Brian Paul /* update count of 'passed' fragments */ 87223ffc3a85d6172f8a98d17d7f23610bab808d84eBrian Paul struct gl_query_object *q = ctx->Query.CurrentOcclusionObject; 873b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul GLuint i; 874b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul for (i = 0; i < span->end; i++) 87523ffc3a85d6172f8a98d17d7f23610bab808d84eBrian Paul q->Result += span->array->mask[i]; 876b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul } 877b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul#endif 878b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul 8797956292a765910077f50352d7cd0174e1e66d26cBrian Paul /* we have to wait until after occlusion to do this test */ 880c5a5d12743b4921ab9c01ee69fa6a06b6b4d716aBrian if (ctx->Color.IndexMask == 0) { 88110f30eb43835c57c00783390a02d72daf4f78e26Brian Paul /* write no pixels */ 8822a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->arrayMask = origArrayMask; 88310f30eb43835c57c00783390a02d72daf4f78e26Brian Paul return; 88410f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 88510f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 8867956292a765910077f50352d7cd0174e1e66d26cBrian Paul /* Interpolate the color indexes if needed */ 887dcf4c17fb1624af47181c63af4c3ad29f919c17aBrian Paul if (swrast->_FogEnabled || 888e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul ctx->Color.IndexLogicOpEnabled || 889e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul ctx->Color.IndexMask != 0xffffffff || 890e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul (span->arrayMask & SPAN_COVERAGE)) { 8919e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian if (!(span->arrayMask & SPAN_INDEX) /*span->interpMask & SPAN_INDEX*/) { 892e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul interpolate_indexes(ctx, span); 893e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul } 8947956292a765910077f50352d7cd0174e1e66d26cBrian Paul } 89510f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 8967956292a765910077f50352d7cd0174e1e66d26cBrian Paul /* Fog */ 897dcf4c17fb1624af47181c63af4c3ad29f919c17aBrian Paul if (swrast->_FogEnabled) { 89845bc887da226403f2c41077e40ca38b6f60f1359Brian Paul _swrast_fog_ci_span(ctx, span); 899e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 900e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 9012a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul /* Antialias coverage application */ 9022a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul if (span->arrayMask & SPAN_COVERAGE) { 903e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul const GLfloat *coverage = span->array->coverage; 90477df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul GLuint *index = span->array->index; 905e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul GLuint i; 90610f30eb43835c57c00783390a02d72daf4f78e26Brian Paul for (i = 0; i < span->end; i++) { 90777df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul ASSERT(coverage[i] < 16); 90877df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul index[i] = (index[i] & ~0xf) | ((GLuint) coverage[i]); 9095071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paul } 9102a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 9115071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paul 912ba001224a18fa12792696ef393e708e90092127eBrian Paul /* 913ba001224a18fa12792696ef393e708e90092127eBrian Paul * Write to renderbuffers 914ba001224a18fa12792696ef393e708e90092127eBrian Paul */ 915ba001224a18fa12792696ef393e708e90092127eBrian Paul { 916ff73c783cc47361ff0dd819c82d067b4b85870ddBrian const GLuint numBuffers = fb->_NumColorDrawBuffers; 917ba001224a18fa12792696ef393e708e90092127eBrian Paul GLuint buf; 918e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul 919ff73c783cc47361ff0dd819c82d067b4b85870ddBrian for (buf = 0; buf < numBuffers; buf++) { 920ff73c783cc47361ff0dd819c82d067b4b85870ddBrian struct gl_renderbuffer *rb = fb->_ColorDrawBuffers[buf]; 921ff73c783cc47361ff0dd819c82d067b4b85870ddBrian GLuint indexSave[MAX_WIDTH]; 922e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul 923ba001224a18fa12792696ef393e708e90092127eBrian Paul ASSERT(rb->_BaseFormat == GL_COLOR_INDEX); 9242a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 925ff73c783cc47361ff0dd819c82d067b4b85870ddBrian if (numBuffers > 1) { 926ff73c783cc47361ff0dd819c82d067b4b85870ddBrian /* save indexes for second, third renderbuffer writes */ 927ff73c783cc47361ff0dd819c82d067b4b85870ddBrian _mesa_memcpy(indexSave, span->array->index, 928ff73c783cc47361ff0dd819c82d067b4b85870ddBrian span->end * sizeof(indexSave[0])); 929ff73c783cc47361ff0dd819c82d067b4b85870ddBrian } 930ff73c783cc47361ff0dd819c82d067b4b85870ddBrian 931e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul if (ctx->Color.IndexLogicOpEnabled) { 932f515c78a2320369ead087c4e0efd583f17b4b78bBrian Paul _swrast_logicop_ci_span(ctx, rb, span); 933e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul } 934e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul 935e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul if (ctx->Color.IndexMask != 0xffffffff) { 936f515c78a2320369ead087c4e0efd583f17b4b78bBrian Paul _swrast_mask_ci_span(ctx, rb, span); 937e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul } 9382a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 9399e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian if (!(span->arrayMask & SPAN_INDEX) && span->indexStep == 0) { 940ba001224a18fa12792696ef393e708e90092127eBrian Paul /* all fragments have same color index */ 941ba001224a18fa12792696ef393e708e90092127eBrian Paul GLubyte index8; 942ba001224a18fa12792696ef393e708e90092127eBrian Paul GLushort index16; 943ba001224a18fa12792696ef393e708e90092127eBrian Paul GLuint index32; 944ba001224a18fa12792696ef393e708e90092127eBrian Paul void *value; 945e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul 946ba001224a18fa12792696ef393e708e90092127eBrian Paul if (rb->DataType == GL_UNSIGNED_BYTE) { 947ba001224a18fa12792696ef393e708e90092127eBrian Paul index8 = FixedToInt(span->index); 948ba001224a18fa12792696ef393e708e90092127eBrian Paul value = &index8; 949ba001224a18fa12792696ef393e708e90092127eBrian Paul } 950ba001224a18fa12792696ef393e708e90092127eBrian Paul else if (rb->DataType == GL_UNSIGNED_SHORT) { 951ba001224a18fa12792696ef393e708e90092127eBrian Paul index16 = FixedToInt(span->index); 952ba001224a18fa12792696ef393e708e90092127eBrian Paul value = &index16; 953ba001224a18fa12792696ef393e708e90092127eBrian Paul } 954ba001224a18fa12792696ef393e708e90092127eBrian Paul else { 955ba001224a18fa12792696ef393e708e90092127eBrian Paul ASSERT(rb->DataType == GL_UNSIGNED_INT); 956ba001224a18fa12792696ef393e708e90092127eBrian Paul index32 = FixedToInt(span->index); 957ba001224a18fa12792696ef393e708e90092127eBrian Paul value = &index32; 958ba001224a18fa12792696ef393e708e90092127eBrian Paul } 959e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul 960ba001224a18fa12792696ef393e708e90092127eBrian Paul if (span->arrayMask & SPAN_XY) { 961ba001224a18fa12792696ef393e708e90092127eBrian Paul rb->PutMonoValues(ctx, rb, span->end, span->array->x, 962ba001224a18fa12792696ef393e708e90092127eBrian Paul span->array->y, value, span->array->mask); 963e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul } 964ba001224a18fa12792696ef393e708e90092127eBrian Paul else { 965ba001224a18fa12792696ef393e708e90092127eBrian Paul rb->PutMonoRow(ctx, rb, span->end, span->x, span->y, 966ba001224a18fa12792696ef393e708e90092127eBrian Paul value, span->array->mask); 967e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul } 968733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul } 969733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul else { 970ba001224a18fa12792696ef393e708e90092127eBrian Paul /* each fragment is a different color */ 971ba001224a18fa12792696ef393e708e90092127eBrian Paul GLubyte index8[MAX_WIDTH]; 972ba001224a18fa12792696ef393e708e90092127eBrian Paul GLushort index16[MAX_WIDTH]; 973ba001224a18fa12792696ef393e708e90092127eBrian Paul void *values; 974ba001224a18fa12792696ef393e708e90092127eBrian Paul 975ba001224a18fa12792696ef393e708e90092127eBrian Paul if (rb->DataType == GL_UNSIGNED_BYTE) { 976ba001224a18fa12792696ef393e708e90092127eBrian Paul GLuint k; 977ba001224a18fa12792696ef393e708e90092127eBrian Paul for (k = 0; k < span->end; k++) { 978ba001224a18fa12792696ef393e708e90092127eBrian Paul index8[k] = (GLubyte) span->array->index[k]; 979ba001224a18fa12792696ef393e708e90092127eBrian Paul } 980ba001224a18fa12792696ef393e708e90092127eBrian Paul values = index8; 981ba001224a18fa12792696ef393e708e90092127eBrian Paul } 982ba001224a18fa12792696ef393e708e90092127eBrian Paul else if (rb->DataType == GL_UNSIGNED_SHORT) { 983ba001224a18fa12792696ef393e708e90092127eBrian Paul GLuint k; 984ba001224a18fa12792696ef393e708e90092127eBrian Paul for (k = 0; k < span->end; k++) { 985ba001224a18fa12792696ef393e708e90092127eBrian Paul index16[k] = (GLushort) span->array->index[k]; 986ba001224a18fa12792696ef393e708e90092127eBrian Paul } 987ba001224a18fa12792696ef393e708e90092127eBrian Paul values = index16; 988ba001224a18fa12792696ef393e708e90092127eBrian Paul } 989ba001224a18fa12792696ef393e708e90092127eBrian Paul else { 990ba001224a18fa12792696ef393e708e90092127eBrian Paul ASSERT(rb->DataType == GL_UNSIGNED_INT); 991ba001224a18fa12792696ef393e708e90092127eBrian Paul values = span->array->index; 992ba001224a18fa12792696ef393e708e90092127eBrian Paul } 993e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul 994ba001224a18fa12792696ef393e708e90092127eBrian Paul if (span->arrayMask & SPAN_XY) { 995ba001224a18fa12792696ef393e708e90092127eBrian Paul rb->PutValues(ctx, rb, span->end, 996ba001224a18fa12792696ef393e708e90092127eBrian Paul span->array->x, span->array->y, 997ba001224a18fa12792696ef393e708e90092127eBrian Paul values, span->array->mask); 998ba001224a18fa12792696ef393e708e90092127eBrian Paul } 999ba001224a18fa12792696ef393e708e90092127eBrian Paul else { 1000ba001224a18fa12792696ef393e708e90092127eBrian Paul rb->PutRow(ctx, rb, span->end, span->x, span->y, 1001e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul values, span->array->mask); 1002ba001224a18fa12792696ef393e708e90092127eBrian Paul } 1003e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul } 1004ba001224a18fa12792696ef393e708e90092127eBrian Paul 1005ff73c783cc47361ff0dd819c82d067b4b85870ddBrian if (buf + 1 < numBuffers) { 1006ba001224a18fa12792696ef393e708e90092127eBrian Paul /* restore original span values */ 1007ba001224a18fa12792696ef393e708e90092127eBrian Paul _mesa_memcpy(span->array->index, indexSave, 1008ba001224a18fa12792696ef393e708e90092127eBrian Paul span->end * sizeof(indexSave[0])); 1009733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul } 1010ba001224a18fa12792696ef393e708e90092127eBrian Paul } /* for buf */ 1011e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 10122a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 10137956292a765910077f50352d7cd0174e1e66d26cBrian Paul span->interpMask = origInterpMask; 10142a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->arrayMask = origArrayMask; 1015e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell} 1016e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 1017e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 101879c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/** 10199e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian * Add specular colors to primary colors. 10209e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian * Only called during fixed-function operation. 10219e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian * Result is float color array (FRAG_ATTRIB_COL0). 1022e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */ 1023f614a6190562e550257afca0d04e3846648942e8Brian Paulstatic INLINE void 1024cdb27e8242215271364602995d85607cfc06d441Brian Pauladd_specular(GLcontext *ctx, SWspan *span) 1025e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell{ 10269e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian const SWcontext *swrast = SWRAST_CONTEXT(ctx); 10279e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian const GLubyte *mask = span->array->mask; 10289e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian GLfloat (*col0)[4] = span->array->attribs[FRAG_ATTRIB_COL0]; 10299e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian GLfloat (*col1)[4] = span->array->attribs[FRAG_ATTRIB_COL1]; 10309e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian GLuint i; 10319e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian 10329e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian ASSERT(!ctx->FragmentProgram._Current); 10339e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian ASSERT(span->arrayMask & SPAN_RGBA); 10349e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian ASSERT(swrast->_ActiveAttribMask & FRAG_BIT_COL1); 10359d216be8cfe57f88cd2d890c2334df8ff5c30436Brian Paul (void) swrast; /* silence warning */ 10369e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian 10379e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian if (span->array->ChanType == GL_FLOAT) { 10389e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian if ((span->arrayAttribs & FRAG_BIT_COL0) == 0) { 10399e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian interpolate_active_attribs(ctx, span, FRAG_BIT_COL0); 1040d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul } 10419e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian } 10429e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian else { 10439e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian /* need float colors */ 10449e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian if ((span->arrayAttribs & FRAG_BIT_COL0) == 0) { 10459e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian interpolate_float_colors(span); 1046d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul } 10479e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian } 10489e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian 10499e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian if ((span->arrayAttribs & FRAG_BIT_COL1) == 0) { 10509e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian /* XXX could avoid this and interpolate COL1 in the loop below */ 10519e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian interpolate_active_attribs(ctx, span, FRAG_BIT_COL1); 10529e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian } 10539e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian 10549e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian ASSERT(span->arrayAttribs & FRAG_BIT_COL0); 10559e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian ASSERT(span->arrayAttribs & FRAG_BIT_COL1); 10569e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian 10579e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian for (i = 0; i < span->end; i++) { 10589e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian if (mask[i]) { 10599e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian col0[i][0] += col1[i][0]; 10609e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian col0[i][1] += col1[i][1]; 10619e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian col0[i][2] += col1[i][2]; 1062d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul } 1063e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 10649e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian 10659e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian span->array->ChanType = GL_FLOAT; 1066e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell} 1067e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 1068e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 106979c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/** 1070b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul * Apply antialiasing coverage value to alpha values. 1071b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul */ 1072f614a6190562e550257afca0d04e3846648942e8Brian Paulstatic INLINE void 1073b88af5b4681d2085cd784b930dc259b66a55347eBrian Paulapply_aa_coverage(SWspan *span) 1074b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul{ 1075b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul const GLfloat *coverage = span->array->coverage; 1076b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul GLuint i; 1077b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul if (span->array->ChanType == GL_UNSIGNED_BYTE) { 10789e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian GLubyte (*rgba)[4] = span->array->rgba8; 1079b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul for (i = 0; i < span->end; i++) { 1080e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul const GLfloat a = rgba[i][ACOMP] * coverage[i]; 1081e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul rgba[i][ACOMP] = (GLubyte) CLAMP(a, 0.0, 255.0); 1082b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul ASSERT(coverage[i] >= 0.0); 1083b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul ASSERT(coverage[i] <= 1.0); 1084b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul } 1085b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul } 1086b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul else if (span->array->ChanType == GL_UNSIGNED_SHORT) { 10879e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian GLushort (*rgba)[4] = span->array->rgba16; 1088b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul for (i = 0; i < span->end; i++) { 1089e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul const GLfloat a = rgba[i][ACOMP] * coverage[i]; 1090e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul rgba[i][ACOMP] = (GLushort) CLAMP(a, 0.0, 65535.0); 1091b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul } 1092b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul } 1093b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul else { 1094f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian GLfloat (*rgba)[4] = span->array->attribs[FRAG_ATTRIB_COL0]; 1095b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul for (i = 0; i < span->end; i++) { 1096b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul rgba[i][ACOMP] = rgba[i][ACOMP] * coverage[i]; 10979e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian /* clamp later */ 1098b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul } 1099b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul } 1100b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul} 1101b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul 1102b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul 1103b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul/** 110431293910b4e982f2ef54d79aff78f2f854121da1Brian Paul * Clamp span's float colors to [0,1] 110531293910b4e982f2ef54d79aff78f2f854121da1Brian Paul */ 1106f614a6190562e550257afca0d04e3846648942e8Brian Paulstatic INLINE void 110731293910b4e982f2ef54d79aff78f2f854121da1Brian Paulclamp_colors(SWspan *span) 110831293910b4e982f2ef54d79aff78f2f854121da1Brian Paul{ 1109f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian GLfloat (*rgba)[4] = span->array->attribs[FRAG_ATTRIB_COL0]; 111031293910b4e982f2ef54d79aff78f2f854121da1Brian Paul GLuint i; 111131293910b4e982f2ef54d79aff78f2f854121da1Brian Paul ASSERT(span->array->ChanType == GL_FLOAT); 111231293910b4e982f2ef54d79aff78f2f854121da1Brian Paul for (i = 0; i < span->end; i++) { 111331293910b4e982f2ef54d79aff78f2f854121da1Brian Paul rgba[i][RCOMP] = CLAMP(rgba[i][RCOMP], 0.0F, 1.0F); 111431293910b4e982f2ef54d79aff78f2f854121da1Brian Paul rgba[i][GCOMP] = CLAMP(rgba[i][GCOMP], 0.0F, 1.0F); 111531293910b4e982f2ef54d79aff78f2f854121da1Brian Paul rgba[i][BCOMP] = CLAMP(rgba[i][BCOMP], 0.0F, 1.0F); 111631293910b4e982f2ef54d79aff78f2f854121da1Brian Paul rgba[i][ACOMP] = CLAMP(rgba[i][ACOMP], 0.0F, 1.0F); 111731293910b4e982f2ef54d79aff78f2f854121da1Brian Paul } 111831293910b4e982f2ef54d79aff78f2f854121da1Brian Paul} 111931293910b4e982f2ef54d79aff78f2f854121da1Brian Paul 112031293910b4e982f2ef54d79aff78f2f854121da1Brian Paul 112131293910b4e982f2ef54d79aff78f2f854121da1Brian Paul/** 1122d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul * Convert the span's color arrays to the given type. 1123ff73c783cc47361ff0dd819c82d067b4b85870ddBrian * The only way 'output' can be greater than zero is when we have a fragment 11241c09bcfdda4083636a3ac27d804a34ef87875ce7Brian * program that writes to gl_FragData[1] or higher. 11251c09bcfdda4083636a3ac27d804a34ef87875ce7Brian * \param output which fragment program color output is being processed 1126d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul */ 1127f614a6190562e550257afca0d04e3846648942e8Brian Paulstatic INLINE void 11281c09bcfdda4083636a3ac27d804a34ef87875ce7Brianconvert_color_type(SWspan *span, GLenum newType, GLuint output) 1129d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul{ 1130f971e24cf0341dd2779196a0836327b74fc82336Brian Paul GLvoid *src, *dst; 11311c09bcfdda4083636a3ac27d804a34ef87875ce7Brian 11321c09bcfdda4083636a3ac27d804a34ef87875ce7Brian if (output > 0 || span->array->ChanType == GL_FLOAT) { 11331c09bcfdda4083636a3ac27d804a34ef87875ce7Brian src = span->array->attribs[FRAG_ATTRIB_COL0 + output]; 11341c09bcfdda4083636a3ac27d804a34ef87875ce7Brian span->array->ChanType = GL_FLOAT; 1135f971e24cf0341dd2779196a0836327b74fc82336Brian Paul } 1136f971e24cf0341dd2779196a0836327b74fc82336Brian Paul else if (span->array->ChanType == GL_UNSIGNED_BYTE) { 11379e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian src = span->array->rgba8; 1138f971e24cf0341dd2779196a0836327b74fc82336Brian Paul } 1139f971e24cf0341dd2779196a0836327b74fc82336Brian Paul else { 11401c09bcfdda4083636a3ac27d804a34ef87875ce7Brian ASSERT(span->array->ChanType == GL_UNSIGNED_SHORT); 11419e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian src = span->array->rgba16; 1142f971e24cf0341dd2779196a0836327b74fc82336Brian Paul } 11431c09bcfdda4083636a3ac27d804a34ef87875ce7Brian 1144f971e24cf0341dd2779196a0836327b74fc82336Brian Paul if (newType == GL_UNSIGNED_BYTE) { 11459e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian dst = span->array->rgba8; 1146f971e24cf0341dd2779196a0836327b74fc82336Brian Paul } 11471c09bcfdda4083636a3ac27d804a34ef87875ce7Brian else if (newType == GL_UNSIGNED_SHORT) { 11489e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian dst = span->array->rgba16; 1149f971e24cf0341dd2779196a0836327b74fc82336Brian Paul } 1150f971e24cf0341dd2779196a0836327b74fc82336Brian Paul else { 1151f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian dst = span->array->attribs[FRAG_ATTRIB_COL0]; 1152f971e24cf0341dd2779196a0836327b74fc82336Brian Paul } 1153d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul 1154f971e24cf0341dd2779196a0836327b74fc82336Brian Paul _mesa_convert_colors(span->array->ChanType, src, 1155f971e24cf0341dd2779196a0836327b74fc82336Brian Paul newType, dst, 1156f971e24cf0341dd2779196a0836327b74fc82336Brian Paul span->end, span->array->mask); 1157d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul 1158d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul span->array->ChanType = newType; 115993becd8a18f6ccf2f86e506ee36fc0bb75787c29Brian span->array->rgba = dst; 1160d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul} 1161d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul 1162d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul 1163d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul 1164d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul/** 116561c89be3135cedc795e48d36283769298e250837Brian Paul * Apply fragment shader, fragment program or normal texturing to span. 116661c89be3135cedc795e48d36283769298e250837Brian Paul */ 1167f614a6190562e550257afca0d04e3846648942e8Brian Paulstatic INLINE void 116861c89be3135cedc795e48d36283769298e250837Brian Paulshade_texture_span(GLcontext *ctx, SWspan *span) 116961c89be3135cedc795e48d36283769298e250837Brian Paul{ 1170c000843a14e73d593d87ff6674d0295d2cb64a12Brian GLbitfield inputsRead; 1171c000843a14e73d593d87ff6674d0295d2cb64a12Brian 1172c000843a14e73d593d87ff6674d0295d2cb64a12Brian /* Determine which fragment attributes are actually needed */ 1173c000843a14e73d593d87ff6674d0295d2cb64a12Brian if (ctx->FragmentProgram._Current) { 1174c000843a14e73d593d87ff6674d0295d2cb64a12Brian inputsRead = ctx->FragmentProgram._Current->Base.InputsRead; 1175c000843a14e73d593d87ff6674d0295d2cb64a12Brian } 1176c000843a14e73d593d87ff6674d0295d2cb64a12Brian else { 1177c000843a14e73d593d87ff6674d0295d2cb64a12Brian /* XXX we could be a bit smarter about this */ 1178c000843a14e73d593d87ff6674d0295d2cb64a12Brian inputsRead = ~0; 1179c000843a14e73d593d87ff6674d0295d2cb64a12Brian } 1180c000843a14e73d593d87ff6674d0295d2cb64a12Brian 118112ef1fbefcee964b715783d3ade6b69b2c699ed8Brian if (ctx->FragmentProgram._Current || 118261c89be3135cedc795e48d36283769298e250837Brian Paul ctx->ATIFragmentShader._Enabled) { 11839e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian /* programmable shading */ 1184171dcdfa27dda30916a7f9bfed89577feee5d350Brian if (span->primitive == GL_BITMAP && span->array->ChanType != GL_FLOAT) { 1185171dcdfa27dda30916a7f9bfed89577feee5d350Brian convert_color_type(span, GL_FLOAT, 0); 1186b9080dd5493eb23af6c5c494550c7b1cb481ca7bBrian } 1187bff94a91c6852157a8251652cb61dc699cd8e4f1Xiang, Haihao if (span->primitive != GL_POINT || 1188bff94a91c6852157a8251652cb61dc699cd8e4f1Xiang, Haihao (span->interpMask & SPAN_RGBA) || 1189bff94a91c6852157a8251652cb61dc699cd8e4f1Xiang, Haihao ctx->Point.PointSprite) { 1190bff94a91c6852157a8251652cb61dc699cd8e4f1Xiang, Haihao /* for single-pixel points, we populated the arrays already */ 11911d52b6aaf41b32aaf8d1cdf5a3cd5ff4ecba28f4Brian interpolate_active_attribs(ctx, span, ~0); 11921d52b6aaf41b32aaf8d1cdf5a3cd5ff4ecba28f4Brian } 11939e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian span->array->ChanType = GL_FLOAT; 119461c89be3135cedc795e48d36283769298e250837Brian Paul 11959e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian if (!(span->arrayMask & SPAN_Z)) 119661c89be3135cedc795e48d36283769298e250837Brian Paul _swrast_span_interpolate_z (ctx, span); 119761c89be3135cedc795e48d36283769298e250837Brian Paul 119860d136f63c5a5a18b12952ec8e8532cbce086a4dBrian#if 0 1199c000843a14e73d593d87ff6674d0295d2cb64a12Brian if (inputsRead & FRAG_BIT_WPOS) 120060d136f63c5a5a18b12952ec8e8532cbce086a4dBrian#else 120160d136f63c5a5a18b12952ec8e8532cbce086a4dBrian /* XXX always interpolate wpos so that DDX/DDY work */ 120260d136f63c5a5a18b12952ec8e8532cbce086a4dBrian#endif 1203f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian interpolate_wpos(ctx, span); 1204f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian 120512ef1fbefcee964b715783d3ade6b69b2c699ed8Brian /* Run fragment program/shader now */ 120612ef1fbefcee964b715783d3ade6b69b2c699ed8Brian if (ctx->FragmentProgram._Current) { 120761c89be3135cedc795e48d36283769298e250837Brian Paul _swrast_exec_fragment_program(ctx, span); 120861c89be3135cedc795e48d36283769298e250837Brian Paul } 120961c89be3135cedc795e48d36283769298e250837Brian Paul else { 121061c89be3135cedc795e48d36283769298e250837Brian Paul ASSERT(ctx->ATIFragmentShader._Enabled); 121161c89be3135cedc795e48d36283769298e250837Brian Paul _swrast_exec_fragment_shader(ctx, span); 121261c89be3135cedc795e48d36283769298e250837Brian Paul } 121361c89be3135cedc795e48d36283769298e250837Brian Paul } 12149e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian else if (ctx->Texture._EnabledUnits) { 121561c89be3135cedc795e48d36283769298e250837Brian Paul /* conventional texturing */ 12169e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian 12179e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian#if CHAN_BITS == 32 12189e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian if ((span->arrayAttribs & FRAG_BIT_COL0) == 0) { 12199e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian interpolate_int_colors(ctx, span); 12209e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian } 12219e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian#else 12229e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian if (!(span->arrayMask & SPAN_RGBA)) 12239e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian interpolate_int_colors(ctx, span); 12249e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian#endif 12259e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian if ((span->arrayAttribs & FRAG_BITS_TEX_ANY) == 0x0) 12269e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian interpolate_texcoords(ctx, span); 12279e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian 122861c89be3135cedc795e48d36283769298e250837Brian Paul _swrast_texture_span(ctx, span); 122961c89be3135cedc795e48d36283769298e250837Brian Paul } 123061c89be3135cedc795e48d36283769298e250837Brian Paul} 123161c89be3135cedc795e48d36283769298e250837Brian Paul 123261c89be3135cedc795e48d36283769298e250837Brian Paul 123361c89be3135cedc795e48d36283769298e250837Brian Paul 123461c89be3135cedc795e48d36283769298e250837Brian Paul/** 1235a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul * Apply all the per-fragment operations to a span. 1236a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul * This now includes texturing (_swrast_write_texture_span() is history). 1237f1e236987829393c81dc86ea19cb49eefe190317Brian Paul * This function may modify any of the array values in the span. 12387956292a765910077f50352d7cd0174e1e66d26cBrian Paul * span->interpMask and span->arrayMask may be changed but will be restored 12397956292a765910077f50352d7cd0174e1e66d26cBrian Paul * to their original values before returning. 124078940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul */ 124178940758e90069ceaca2b6cddb6438488fbad5ccBrian Paulvoid 1242cdb27e8242215271364602995d85607cfc06d441Brian Paul_swrast_write_rgba_span( GLcontext *ctx, SWspan *span) 124378940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul{ 124461c89be3135cedc795e48d36283769298e250837Brian Paul const SWcontext *swrast = SWRAST_CONTEXT(ctx); 124578940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul const GLuint colorMask = *((GLuint *) ctx->Color.ColorMask); 1246e00ac11d4dd05c56584622dc2707bbdcfe4b2707Brian Paul const GLbitfield origInterpMask = span->interpMask; 1247e00ac11d4dd05c56584622dc2707bbdcfe4b2707Brian Paul const GLbitfield origArrayMask = span->arrayMask; 12489e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian const GLbitfield origArrayAttribs = span->arrayAttribs; 124993becd8a18f6ccf2f86e506ee36fc0bb75787c29Brian const GLenum origChanType = span->array->ChanType; 125093becd8a18f6ccf2f86e506ee36fc0bb75787c29Brian void * const origRgba = span->array->rgba; 125112ef1fbefcee964b715783d3ade6b69b2c699ed8Brian const GLboolean shader = (ctx->FragmentProgram._Current 125212ef1fbefcee964b715783d3ade6b69b2c699ed8Brian || ctx->ATIFragmentShader._Enabled); 125361c89be3135cedc795e48d36283769298e250837Brian Paul const GLboolean shaderOrTexture = shader || ctx->Texture._EnabledUnits; 12541c09bcfdda4083636a3ac27d804a34ef87875ce7Brian struct gl_framebuffer *fb = ctx->DrawBuffer; 125561c89be3135cedc795e48d36283769298e250837Brian Paul 1256bb19e64d12eaf27e2adc3faac7e09555bb66d724Brian Paul /* 1257bb19e64d12eaf27e2adc3faac7e09555bb66d724Brian Paul printf("%s() interp 0x%x array 0x%x\n", __FUNCTION__, 1258bb19e64d12eaf27e2adc3faac7e09555bb66d724Brian Paul span->interpMask, span->arrayMask); 1259bb19e64d12eaf27e2adc3faac7e09555bb66d724Brian Paul */ 1260f1e236987829393c81dc86ea19cb49eefe190317Brian Paul 126131293910b4e982f2ef54d79aff78f2f854121da1Brian Paul ASSERT(span->primitive == GL_POINT || 126231293910b4e982f2ef54d79aff78f2f854121da1Brian Paul span->primitive == GL_LINE || 126331293910b4e982f2ef54d79aff78f2f854121da1Brian Paul span->primitive == GL_POLYGON || 126431293910b4e982f2ef54d79aff78f2f854121da1Brian Paul span->primitive == GL_BITMAP); 1265733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul ASSERT(span->end <= MAX_WIDTH); 1266ceb39f4f8dc4863fde17d668c752533a2184476eBrian Paul 1267bb19e64d12eaf27e2adc3faac7e09555bb66d724Brian Paul /* Fragment write masks */ 1268733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (span->arrayMask & SPAN_MASK) { 1269733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* mask was initialized by caller, probably glBitmap */ 1270733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->writeAll = GL_FALSE; 1271733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul } 1272733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul else { 1273a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul _mesa_memset(span->array->mask, 1, span->end); 1274733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->writeAll = GL_TRUE; 127578940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul } 127678940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul 1277a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul /* Clip to window/scissor box */ 1278b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul if ((swrast->_RasterMask & CLIP_BIT) || (span->primitive != GL_POLYGON)) { 1279733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (!clip_span(ctx, span)) { 1280733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul return; 128178940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul } 128278940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul } 128378940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul 1284b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul#ifdef DEBUG 1285a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul /* Make sure all fragments are within window bounds */ 1286b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul if (span->arrayMask & SPAN_XY) { 1287a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul GLuint i; 1288b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul for (i = 0; i < span->end; i++) { 128977df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul if (span->array->mask[i]) { 12901c09bcfdda4083636a3ac27d804a34ef87875ce7Brian assert(span->array->x[i] >= fb->_Xmin); 12911c09bcfdda4083636a3ac27d804a34ef87875ce7Brian assert(span->array->x[i] < fb->_Xmax); 12921c09bcfdda4083636a3ac27d804a34ef87875ce7Brian assert(span->array->y[i] >= fb->_Ymin); 12931c09bcfdda4083636a3ac27d804a34ef87875ce7Brian assert(span->array->y[i] < fb->_Ymax); 1294b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul } 1295b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul } 1296b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul } 1297b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul#endif 1298b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul 129978940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul /* Polygon Stippling */ 1300b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul if (ctx->Polygon.StippleFlag && span->primitive == GL_POLYGON) { 1301733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul stipple_polygon_span(ctx, span); 130278940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul } 130378940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul 13049e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian /* This is the normal place to compute the fragment color/Z 13059e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian * from texturing or shading. 1306a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul */ 13079e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian if (shaderOrTexture && !swrast->_DeferredTexture) { 130861c89be3135cedc795e48d36283769298e250837Brian Paul shade_texture_span(ctx, span); 130961c89be3135cedc795e48d36283769298e250837Brian Paul } 1310c3caaa3dd45809e672177ab322445fe51d03af25Brian Paul 131161c89be3135cedc795e48d36283769298e250837Brian Paul /* Do the alpha test */ 131261c89be3135cedc795e48d36283769298e250837Brian Paul if (ctx->Color.AlphaEnabled) { 131361c89be3135cedc795e48d36283769298e250837Brian Paul if (!_swrast_alpha_test(ctx, span)) { 131461c89be3135cedc795e48d36283769298e250837Brian Paul goto end; 131578940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul } 131678940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul } 131778940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul 1318f1e236987829393c81dc86ea19cb49eefe190317Brian Paul /* Stencil and Z testing */ 1319f1e236987829393c81dc86ea19cb49eefe190317Brian Paul if (ctx->Stencil.Enabled || ctx->Depth.Test) { 13209e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian if (!(span->arrayMask & SPAN_Z)) 132145bc887da226403f2c41077e40ca38b6f60f1359Brian Paul _swrast_span_interpolate_z(ctx, span); 132278940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul 13231c09bcfdda4083636a3ac27d804a34ef87875ce7Brian if (ctx->Stencil.Enabled && fb->Visual.stencilBits > 0) { 1324a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul /* Combined Z/stencil tests */ 132545bc887da226403f2c41077e40ca38b6f60f1359Brian Paul if (!_swrast_stencil_and_ztest_span(ctx, span)) { 1326c3caaa3dd45809e672177ab322445fe51d03af25Brian Paul goto end; 1327f1e236987829393c81dc86ea19cb49eefe190317Brian Paul } 132871340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 13291c09bcfdda4083636a3ac27d804a34ef87875ce7Brian else if (fb->Visual.depthBits > 0) { 1330a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul /* Just regular depth testing */ 1331f1e236987829393c81dc86ea19cb49eefe190317Brian Paul ASSERT(ctx->Depth.Test); 1332f1e236987829393c81dc86ea19cb49eefe190317Brian Paul ASSERT(span->arrayMask & SPAN_Z); 133345bc887da226403f2c41077e40ca38b6f60f1359Brian Paul if (!_swrast_depth_test_span(ctx, span)) { 1334c3caaa3dd45809e672177ab322445fe51d03af25Brian Paul goto end; 1335f1e236987829393c81dc86ea19cb49eefe190317Brian Paul } 133671340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 133771340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 133871340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul 1339b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul#if FEATURE_ARB_occlusion_query 134023ffc3a85d6172f8a98d17d7f23610bab808d84eBrian Paul if (ctx->Query.CurrentOcclusionObject) { 1341939dd17653245621bf7488803f09418244b7b0b7Brian Paul /* update count of 'passed' fragments */ 134223ffc3a85d6172f8a98d17d7f23610bab808d84eBrian Paul struct gl_query_object *q = ctx->Query.CurrentOcclusionObject; 1343b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul GLuint i; 1344b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul for (i = 0; i < span->end; i++) 134523ffc3a85d6172f8a98d17d7f23610bab808d84eBrian Paul q->Result += span->array->mask[i]; 1346b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul } 1347b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul#endif 1348b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul 1349a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul /* We had to wait until now to check for glColorMask(0,0,0,0) because of 1350f1e236987829393c81dc86ea19cb49eefe190317Brian Paul * the occlusion test. 1351f1e236987829393c81dc86ea19cb49eefe190317Brian Paul */ 1352f1e236987829393c81dc86ea19cb49eefe190317Brian Paul if (colorMask == 0x0) { 1353c3caaa3dd45809e672177ab322445fe51d03af25Brian Paul goto end; 135471340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 135571340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul 135632340aea1308153dad5c105fc0748aea1e4c37eeBrian Paul /* If we were able to defer fragment color computation to now, there's 135732340aea1308153dad5c105fc0748aea1e4c37eeBrian Paul * a good chance that many fragments will have already been killed by 135832340aea1308153dad5c105fc0748aea1e4c37eeBrian Paul * Z/stencil testing. 1359a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul */ 13609e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian if (shaderOrTexture && swrast->_DeferredTexture) { 136161c89be3135cedc795e48d36283769298e250837Brian Paul shade_texture_span(ctx, span); 136261c89be3135cedc795e48d36283769298e250837Brian Paul } 1363d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul 13649e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian#if CHAN_BITS == 32 13659e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian if ((span->arrayAttribs & FRAG_BIT_COL0) == 0) { 136651b728cf9aff383142a2a1e220a7d8963d1ca189Brian interpolate_active_attribs(ctx, span, FRAG_BIT_COL0); 13679e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian } 13689e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian#else 136961c89be3135cedc795e48d36283769298e250837Brian Paul if ((span->arrayMask & SPAN_RGBA) == 0) { 13709e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian interpolate_int_colors(ctx, span); 137171340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 13729e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian#endif 137371340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul 1374f1e236987829393c81dc86ea19cb49eefe190317Brian Paul ASSERT(span->arrayMask & SPAN_RGBA); 13752ef866d1fc0a5cc5ef8543d65744dfd4da4dbbafBrian Paul 137661c89be3135cedc795e48d36283769298e250837Brian Paul if (!shader) { 1377dfe508ca7af1a6d1099cd65e257512ed1e17d893Brian Paul /* Add base and specular colors */ 1378dfe508ca7af1a6d1099cd65e257512ed1e17d893Brian Paul if (ctx->Fog.ColorSumEnabled || 1379dfe508ca7af1a6d1099cd65e257512ed1e17d893Brian Paul (ctx->Light.Enabled && 1380dfe508ca7af1a6d1099cd65e257512ed1e17d893Brian Paul ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR)) { 13819e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian add_specular(ctx, span); 138271340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 138371340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 138471340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul 13856e1666437ea091ecc50ab2b56d87129318f641d2Brian Paul /* Fog */ 138609da0b8e6621a831e3eeb9381430f2bed18a22adBrian Paul if (swrast->_FogEnabled) { 138745bc887da226403f2c41077e40ca38b6f60f1359Brian Paul _swrast_fog_rgba_span(ctx, span); 138871340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 1389f1e236987829393c81dc86ea19cb49eefe190317Brian Paul 139071340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul /* Antialias coverage application */ 13912a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul if (span->arrayMask & SPAN_COVERAGE) { 1392b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul apply_aa_coverage(span); 139371340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 139471340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul 1395ba3da6154c324cc916845bc5de3de077d0b59ffcBrian Paul /* Clamp color/alpha values over the range [0.0, 1.0] before storage */ 13960b26e826bda0da7aeec9a79ee07fe21d54bb1263Brian Paul if (ctx->Color.ClampFragmentColor == GL_TRUE && 139731293910b4e982f2ef54d79aff78f2f854121da1Brian Paul span->array->ChanType == GL_FLOAT) { 139831293910b4e982f2ef54d79aff78f2f854121da1Brian Paul clamp_colors(span); 1399ba3da6154c324cc916845bc5de3de077d0b59ffcBrian Paul } 1400ba3da6154c324cc916845bc5de3de077d0b59ffcBrian Paul 1401ba001224a18fa12792696ef393e708e90092127eBrian Paul /* 1402ba001224a18fa12792696ef393e708e90092127eBrian Paul * Write to renderbuffers 1403ba001224a18fa12792696ef393e708e90092127eBrian Paul */ 1404ff73c783cc47361ff0dd819c82d067b4b85870ddBrian { 1405ff73c783cc47361ff0dd819c82d067b4b85870ddBrian const GLuint numBuffers = fb->_NumColorDrawBuffers; 1406bbb042f0b809ebb754547397b8f22a5751c275daBrian const GLboolean multiFragOutputs = numBuffers > 1; 1407ff73c783cc47361ff0dd819c82d067b4b85870ddBrian GLuint buf; 1408ff73c783cc47361ff0dd819c82d067b4b85870ddBrian 1409ff73c783cc47361ff0dd819c82d067b4b85870ddBrian for (buf = 0; buf < numBuffers; buf++) { 1410ff73c783cc47361ff0dd819c82d067b4b85870ddBrian struct gl_renderbuffer *rb = fb->_ColorDrawBuffers[buf]; 1411ff73c783cc47361ff0dd819c82d067b4b85870ddBrian 1412ff73c783cc47361ff0dd819c82d067b4b85870ddBrian /* color[fragOutput] will be written to buffer[buf] */ 1413ff73c783cc47361ff0dd819c82d067b4b85870ddBrian 1414ff73c783cc47361ff0dd819c82d067b4b85870ddBrian if (rb) { 1415ff73c783cc47361ff0dd819c82d067b4b85870ddBrian GLchan rgbaSave[MAX_WIDTH][4]; 1416ff73c783cc47361ff0dd819c82d067b4b85870ddBrian const GLuint fragOutput = multiFragOutputs ? buf : 0; 1417ff73c783cc47361ff0dd819c82d067b4b85870ddBrian 1418ff73c783cc47361ff0dd819c82d067b4b85870ddBrian if (rb->DataType != span->array->ChanType || fragOutput > 0) { 1419ff73c783cc47361ff0dd819c82d067b4b85870ddBrian convert_color_type(span, rb->DataType, fragOutput); 1420ff73c783cc47361ff0dd819c82d067b4b85870ddBrian } 1421ff73c783cc47361ff0dd819c82d067b4b85870ddBrian 1422ff73c783cc47361ff0dd819c82d067b4b85870ddBrian if (!multiFragOutputs && numBuffers > 1) { 1423ff73c783cc47361ff0dd819c82d067b4b85870ddBrian /* save colors for second, third renderbuffer writes */ 1424ff73c783cc47361ff0dd819c82d067b4b85870ddBrian _mesa_memcpy(rgbaSave, span->array->rgba, 1425ff73c783cc47361ff0dd819c82d067b4b85870ddBrian 4 * span->end * sizeof(GLchan)); 1426ff73c783cc47361ff0dd819c82d067b4b85870ddBrian } 1427ff73c783cc47361ff0dd819c82d067b4b85870ddBrian 1428ff73c783cc47361ff0dd819c82d067b4b85870ddBrian ASSERT(rb->_BaseFormat == GL_RGBA || rb->_BaseFormat == GL_RGB); 1429ff73c783cc47361ff0dd819c82d067b4b85870ddBrian 1430ff73c783cc47361ff0dd819c82d067b4b85870ddBrian if (ctx->Color._LogicOpEnabled) { 1431ff73c783cc47361ff0dd819c82d067b4b85870ddBrian _swrast_logicop_rgba_span(ctx, rb, span); 1432ff73c783cc47361ff0dd819c82d067b4b85870ddBrian } 1433ff73c783cc47361ff0dd819c82d067b4b85870ddBrian else if (ctx->Color.BlendEnabled) { 1434ff73c783cc47361ff0dd819c82d067b4b85870ddBrian _swrast_blend_span(ctx, rb, span); 1435ff73c783cc47361ff0dd819c82d067b4b85870ddBrian } 1436ff73c783cc47361ff0dd819c82d067b4b85870ddBrian 1437ff73c783cc47361ff0dd819c82d067b4b85870ddBrian if (colorMask != 0xffffffff) { 1438ff73c783cc47361ff0dd819c82d067b4b85870ddBrian _swrast_mask_rgba_span(ctx, rb, span); 1439ff73c783cc47361ff0dd819c82d067b4b85870ddBrian } 1440ff73c783cc47361ff0dd819c82d067b4b85870ddBrian 1441ff73c783cc47361ff0dd819c82d067b4b85870ddBrian if (span->arrayMask & SPAN_XY) { 1442ff73c783cc47361ff0dd819c82d067b4b85870ddBrian /* array of pixel coords */ 1443ff73c783cc47361ff0dd819c82d067b4b85870ddBrian ASSERT(rb->PutValues); 1444ff73c783cc47361ff0dd819c82d067b4b85870ddBrian rb->PutValues(ctx, rb, span->end, 1445ff73c783cc47361ff0dd819c82d067b4b85870ddBrian span->array->x, span->array->y, 1446ff73c783cc47361ff0dd819c82d067b4b85870ddBrian span->array->rgba, span->array->mask); 1447ff73c783cc47361ff0dd819c82d067b4b85870ddBrian } 1448ff73c783cc47361ff0dd819c82d067b4b85870ddBrian else { 1449ff73c783cc47361ff0dd819c82d067b4b85870ddBrian /* horizontal run of pixels */ 1450ff73c783cc47361ff0dd819c82d067b4b85870ddBrian ASSERT(rb->PutRow); 1451ff73c783cc47361ff0dd819c82d067b4b85870ddBrian rb->PutRow(ctx, rb, span->end, span->x, span->y, 1452ff73c783cc47361ff0dd819c82d067b4b85870ddBrian span->array->rgba, 1453ff73c783cc47361ff0dd819c82d067b4b85870ddBrian span->writeAll ? NULL: span->array->mask); 1454ff73c783cc47361ff0dd819c82d067b4b85870ddBrian } 1455ff73c783cc47361ff0dd819c82d067b4b85870ddBrian 1456ff73c783cc47361ff0dd819c82d067b4b85870ddBrian if (!multiFragOutputs && numBuffers > 1) { 1457ff73c783cc47361ff0dd819c82d067b4b85870ddBrian /* restore original span values */ 1458ff73c783cc47361ff0dd819c82d067b4b85870ddBrian _mesa_memcpy(span->array->rgba, rgbaSave, 1459ff73c783cc47361ff0dd819c82d067b4b85870ddBrian 4 * span->end * sizeof(GLchan)); 1460ff73c783cc47361ff0dd819c82d067b4b85870ddBrian } 1461ff73c783cc47361ff0dd819c82d067b4b85870ddBrian 1462ff73c783cc47361ff0dd819c82d067b4b85870ddBrian } /* if rb */ 1463ff73c783cc47361ff0dd819c82d067b4b85870ddBrian } /* for buf */ 1464ff73c783cc47361ff0dd819c82d067b4b85870ddBrian } 146571340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul 1466c3caaa3dd45809e672177ab322445fe51d03af25Brian Paulend: 146761c89be3135cedc795e48d36283769298e250837Brian Paul /* restore these values before returning */ 1468e5b244ff7f984805c1bcc020342f1300f2639c71Brian Paul span->interpMask = origInterpMask; 1469f1e236987829393c81dc86ea19cb49eefe190317Brian Paul span->arrayMask = origArrayMask; 14709e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian span->arrayAttribs = origArrayAttribs; 147193becd8a18f6ccf2f86e506ee36fc0bb75787c29Brian span->array->ChanType = origChanType; 147293becd8a18f6ccf2f86e506ee36fc0bb75787c29Brian span->array->rgba = origRgba; 147310f30eb43835c57c00783390a02d72daf4f78e26Brian Paul} 147410f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 1475e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 147679c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/** 1477ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian * Read RGBA pixels from a renderbuffer. Clipping will be done to prevent 1478e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * reading ouside the buffer's boundaries. 1479ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian * \param dstType datatype for returned colors 148076e778dce59aa6f290db50242df945943fc47b05Brian Paul * \param rgba the returned colors 1481e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */ 14825071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paulvoid 1483e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul_swrast_read_rgba_span( GLcontext *ctx, struct gl_renderbuffer *rb, 148476e778dce59aa6f290db50242df945943fc47b05Brian Paul GLuint n, GLint x, GLint y, GLenum dstType, 148576e778dce59aa6f290db50242df945943fc47b05Brian Paul GLvoid *rgba) 1486e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell{ 1487e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul const GLint bufWidth = (GLint) rb->Width; 1488e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul const GLint bufHeight = (GLint) rb->Height; 1489a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul 1490a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul if (y < 0 || y >= bufHeight || x + (GLint) n < 0 || x >= bufWidth) { 1491e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* completely above, below, or right */ 1492e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul /* XXX maybe leave rgba values undefined? */ 14936ec6b845fdf3c44436028ad6fff9471d18928719Brian Paul _mesa_bzero(rgba, 4 * n * sizeof(GLchan)); 1494e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1495e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell else { 1496e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell GLint skip, length; 1497e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell if (x < 0) { 14987e152b83cbc3af028175a52450c60101cb16acf8Brian Paul /* left edge clipping */ 1499e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell skip = -x; 1500e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell length = (GLint) n - skip; 1501e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell if (length < 0) { 1502e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* completely left of window */ 1503e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell return; 1504e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1505a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul if (length > bufWidth) { 1506a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul length = bufWidth; 1507e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1508e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1509a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul else if ((GLint) (x + n) > bufWidth) { 1510e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* right edge clipping */ 1511e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell skip = 0; 1512a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul length = bufWidth - x; 1513e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell if (length < 0) { 1514e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* completely to right of window */ 1515e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell return; 1516e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1517e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1518e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell else { 1519e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* no clipping */ 1520e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell skip = 0; 1521e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell length = (GLint) n; 1522e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1523e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 1524bb8b302dbce4f830d060efecd8a9f75b10e25abbBrian Paul ASSERT(rb); 1525bb8b302dbce4f830d060efecd8a9f75b10e25abbBrian Paul ASSERT(rb->GetRow); 1526bb8b302dbce4f830d060efecd8a9f75b10e25abbBrian Paul ASSERT(rb->_BaseFormat == GL_RGB || rb->_BaseFormat == GL_RGBA); 152776e778dce59aa6f290db50242df945943fc47b05Brian Paul 152876e778dce59aa6f290db50242df945943fc47b05Brian Paul if (rb->DataType == dstType) { 152976e778dce59aa6f290db50242df945943fc47b05Brian Paul rb->GetRow(ctx, rb, length, x + skip, y, 153076e778dce59aa6f290db50242df945943fc47b05Brian Paul (GLubyte *) rgba + skip * RGBA_PIXEL_SIZE(rb->DataType)); 153176e778dce59aa6f290db50242df945943fc47b05Brian Paul } 153276e778dce59aa6f290db50242df945943fc47b05Brian Paul else { 153376e778dce59aa6f290db50242df945943fc47b05Brian Paul GLuint temp[MAX_WIDTH * 4]; 153476e778dce59aa6f290db50242df945943fc47b05Brian Paul rb->GetRow(ctx, rb, length, x + skip, y, temp); 153576e778dce59aa6f290db50242df945943fc47b05Brian Paul _mesa_convert_colors(rb->DataType, temp, 153676e778dce59aa6f290db50242df945943fc47b05Brian Paul dstType, (GLubyte *) rgba + skip * RGBA_PIXEL_SIZE(dstType), 153776e778dce59aa6f290db50242df945943fc47b05Brian Paul length, NULL); 153876e778dce59aa6f290db50242df945943fc47b05Brian Paul } 1539e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1540e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell} 1541e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 1542e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 154379c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/** 1544ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian * Read CI pixels from a renderbuffer. Clipping will be done to prevent 1545e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * reading ouside the buffer's boundaries. 1546e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */ 15475071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paulvoid 1548e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul_swrast_read_index_span( GLcontext *ctx, struct gl_renderbuffer *rb, 1549e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul GLuint n, GLint x, GLint y, GLuint index[] ) 1550e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell{ 1551e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul const GLint bufWidth = (GLint) rb->Width; 1552e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul const GLint bufHeight = (GLint) rb->Height; 1553a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul 1554a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul if (y < 0 || y >= bufHeight || x + (GLint) n < 0 || x >= bufWidth) { 1555e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* completely above, below, or right */ 1556e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul _mesa_bzero(index, n * sizeof(GLuint)); 1557e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1558e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell else { 1559e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell GLint skip, length; 1560e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell if (x < 0) { 15617e152b83cbc3af028175a52450c60101cb16acf8Brian Paul /* left edge clipping */ 1562e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell skip = -x; 1563e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell length = (GLint) n - skip; 1564e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell if (length < 0) { 1565e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* completely left of window */ 1566e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell return; 1567e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1568a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul if (length > bufWidth) { 1569a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul length = bufWidth; 1570e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1571e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1572a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul else if ((GLint) (x + n) > bufWidth) { 1573e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* right edge clipping */ 1574e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell skip = 0; 1575a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul length = bufWidth - x; 1576e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell if (length < 0) { 1577e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* completely to right of window */ 1578e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell return; 1579e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1580e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1581e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell else { 1582e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* no clipping */ 1583e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell skip = 0; 1584e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell length = (GLint) n; 1585e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1586e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 1587e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul ASSERT(rb->GetRow); 1588e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul ASSERT(rb->_BaseFormat == GL_COLOR_INDEX); 1589e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul 1590e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul if (rb->DataType == GL_UNSIGNED_BYTE) { 1591e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul GLubyte index8[MAX_WIDTH]; 1592e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul GLint i; 1593e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul rb->GetRow(ctx, rb, length, x + skip, y, index8); 1594e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul for (i = 0; i < length; i++) 1595e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul index[skip + i] = index8[i]; 1596e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul } 1597e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul else if (rb->DataType == GL_UNSIGNED_SHORT) { 1598e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul GLushort index16[MAX_WIDTH]; 1599e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul GLint i; 1600e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul rb->GetRow(ctx, rb, length, x + skip, y, index16); 1601e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul for (i = 0; i < length; i++) 1602e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul index[skip + i] = index16[i]; 1603e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul } 1604e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul else if (rb->DataType == GL_UNSIGNED_INT) { 1605e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul rb->GetRow(ctx, rb, length, x + skip, y, index + skip); 1606e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul } 1607e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1608e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell} 160967074332728acba86da7630353673b458713bb8aBrian Paul 161067074332728acba86da7630353673b458713bb8aBrian Paul 161167074332728acba86da7630353673b458713bb8aBrian Paul/** 161267074332728acba86da7630353673b458713bb8aBrian Paul * Wrapper for gl_renderbuffer::GetValues() which does clipping to avoid 161367074332728acba86da7630353673b458713bb8aBrian Paul * reading values outside the buffer bounds. 161467074332728acba86da7630353673b458713bb8aBrian Paul * We can use this for reading any format/type of renderbuffer. 1615ba001224a18fa12792696ef393e708e90092127eBrian Paul * \param valueSize is the size in bytes of each value (pixel) put into the 161667074332728acba86da7630353673b458713bb8aBrian Paul * values array. 161767074332728acba86da7630353673b458713bb8aBrian Paul */ 161867074332728acba86da7630353673b458713bb8aBrian Paulvoid 161967074332728acba86da7630353673b458713bb8aBrian Paul_swrast_get_values(GLcontext *ctx, struct gl_renderbuffer *rb, 162067074332728acba86da7630353673b458713bb8aBrian Paul GLuint count, const GLint x[], const GLint y[], 162167074332728acba86da7630353673b458713bb8aBrian Paul void *values, GLuint valueSize) 162267074332728acba86da7630353673b458713bb8aBrian Paul{ 162367074332728acba86da7630353673b458713bb8aBrian Paul GLuint i, inCount = 0, inStart = 0; 162467074332728acba86da7630353673b458713bb8aBrian Paul 162567074332728acba86da7630353673b458713bb8aBrian Paul for (i = 0; i < count; i++) { 1626ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian if (x[i] >= 0 && y[i] >= 0 && 1627ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian x[i] < (GLint) rb->Width && y[i] < (GLint) rb->Height) { 162867074332728acba86da7630353673b458713bb8aBrian Paul /* inside */ 162967074332728acba86da7630353673b458713bb8aBrian Paul if (inCount == 0) 163067074332728acba86da7630353673b458713bb8aBrian Paul inStart = i; 163167074332728acba86da7630353673b458713bb8aBrian Paul inCount++; 163267074332728acba86da7630353673b458713bb8aBrian Paul } 163367074332728acba86da7630353673b458713bb8aBrian Paul else { 163467074332728acba86da7630353673b458713bb8aBrian Paul if (inCount > 0) { 163567074332728acba86da7630353673b458713bb8aBrian Paul /* read [inStart, inStart + inCount) */ 163667074332728acba86da7630353673b458713bb8aBrian Paul rb->GetValues(ctx, rb, inCount, x + inStart, y + inStart, 163767074332728acba86da7630353673b458713bb8aBrian Paul (GLubyte *) values + inStart * valueSize); 163867074332728acba86da7630353673b458713bb8aBrian Paul inCount = 0; 163967074332728acba86da7630353673b458713bb8aBrian Paul } 164067074332728acba86da7630353673b458713bb8aBrian Paul } 164167074332728acba86da7630353673b458713bb8aBrian Paul } 164267074332728acba86da7630353673b458713bb8aBrian Paul if (inCount > 0) { 164367074332728acba86da7630353673b458713bb8aBrian Paul /* read last values */ 164467074332728acba86da7630353673b458713bb8aBrian Paul rb->GetValues(ctx, rb, inCount, x + inStart, y + inStart, 164567074332728acba86da7630353673b458713bb8aBrian Paul (GLubyte *) values + inStart * valueSize); 164667074332728acba86da7630353673b458713bb8aBrian Paul } 164767074332728acba86da7630353673b458713bb8aBrian Paul} 16483fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul 16493fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul 16503fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul/** 16513fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul * Wrapper for gl_renderbuffer::PutRow() which does clipping. 1652a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul * \param valueSize size of each value (pixel) in bytes 16533fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul */ 16543fd819aef8139761ce86cb8d763de83a11c81b33Brian Paulvoid 16553fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul_swrast_put_row(GLcontext *ctx, struct gl_renderbuffer *rb, 16563fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul GLuint count, GLint x, GLint y, 16573fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul const GLvoid *values, GLuint valueSize) 16583fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul{ 16593fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul GLint skip = 0; 16603fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul 1661ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian if (y < 0 || y >= (GLint) rb->Height) 16623fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul return; /* above or below */ 16633fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul 1664ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian if (x + (GLint) count <= 0 || x >= (GLint) rb->Width) 16653fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul return; /* entirely left or right */ 16663fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul 1667ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian if ((GLint) (x + count) > (GLint) rb->Width) { 16683fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul /* right clip */ 16693fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul GLint clip = x + count - rb->Width; 16703fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul count -= clip; 16713fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul } 16723fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul 16733fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul if (x < 0) { 16743fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul /* left clip */ 16753fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul skip = -x; 16763fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul x = 0; 16773fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul count -= skip; 16783fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul } 16793fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul 16803fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul rb->PutRow(ctx, rb, count, x, y, 16813fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul (const GLubyte *) values + skip * valueSize, NULL); 16823fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul} 1683f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul 1684f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul 1685f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul/** 1686f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul * Wrapper for gl_renderbuffer::GetRow() which does clipping. 1687a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul * \param valueSize size of each value (pixel) in bytes 1688f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul */ 1689f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paulvoid 1690f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul_swrast_get_row(GLcontext *ctx, struct gl_renderbuffer *rb, 1691f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul GLuint count, GLint x, GLint y, 1692f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul GLvoid *values, GLuint valueSize) 1693f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul{ 1694f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul GLint skip = 0; 1695f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul 1696ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian if (y < 0 || y >= (GLint) rb->Height) 1697f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul return; /* above or below */ 1698f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul 1699ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian if (x + (GLint) count <= 0 || x >= (GLint) rb->Width) 1700f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul return; /* entirely left or right */ 1701f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul 1702f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul if (x + count > rb->Width) { 1703f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul /* right clip */ 1704f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul GLint clip = x + count - rb->Width; 1705f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul count -= clip; 1706f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul } 1707f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul 1708f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul if (x < 0) { 1709f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul /* left clip */ 1710f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul skip = -x; 1711f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul x = 0; 1712f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul count -= skip; 1713f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul } 1714f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul 1715f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul rb->GetRow(ctx, rb, count, x, y, (GLubyte *) values + skip * valueSize); 1716f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul} 1717a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul 1718a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul 1719a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul/** 1720a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul * Get RGBA pixels from the given renderbuffer. Put the pixel colors into 1721a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul * the span's specular color arrays. The specular color arrays should no 1722a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul * longer be needed by time this function is called. 1723a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul * Used by blending, logicop and masking functions. 1724a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul * \return pointer to the colors we read. 1725a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul */ 1726a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paulvoid * 1727a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul_swrast_get_dest_rgba(GLcontext *ctx, struct gl_renderbuffer *rb, 1728cdb27e8242215271364602995d85607cfc06d441Brian Paul SWspan *span) 1729a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul{ 173076e778dce59aa6f290db50242df945943fc47b05Brian Paul const GLuint pixelSize = RGBA_PIXEL_SIZE(span->array->ChanType); 1731a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul void *rbPixels; 1732a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul 1733a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul /* 1734a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul * Point rbPixels to a temporary space (use specular color arrays). 1735a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul */ 17369e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian rbPixels = span->array->attribs[FRAG_ATTRIB_COL1]; 1737a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul 1738a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul /* Get destination values from renderbuffer */ 1739a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul if (span->arrayMask & SPAN_XY) { 1740a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul _swrast_get_values(ctx, rb, span->end, span->array->x, span->array->y, 1741a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul rbPixels, pixelSize); 1742a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul } 1743a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul else { 1744a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul _swrast_get_row(ctx, rb, span->end, span->x, span->y, 1745a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul rbPixels, pixelSize); 1746a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul } 1747a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul 1748a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul return rbPixels; 1749a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul} 1750