1e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell/* 2e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Mesa 3-D graphics library 36a3004b9ae58dafd1ce995df78b0f3183827a59dBrian Paul * Version: 7.5 422144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes * 56a3004b9ae58dafd1ce995df78b0f3183827a59dBrian Paul * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. 66a3004b9ae58dafd1ce995df78b0f3183827a59dBrian Paul * Copyright (C) 2009 VMware, Inc. All Rights Reserved. 722144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes * 8e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Permission is hereby granted, free of charge, to any person obtaining a 9e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * copy of this software and associated documentation files (the "Software"), 10e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * to deal in the Software without restriction, including without limitation 11e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * the rights to use, copy, modify, merge, publish, distribute, sublicense, 12e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * and/or sell copies of the Software, and to permit persons to whom the 13e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Software is furnished to do so, subject to the following conditions: 1422144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes * 15e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * The above copyright notice and this permission notice shall be included 16e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * in all copies or substantial portions of the Software. 1722144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes * 18e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 22e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 23e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */ 25e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 26e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 2779c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/** 28bcb148de9201c7f90a68c7c46434e7ebf7204000Brian Paul * \file swrast/s_span.c 2979c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul * \brief Span processing functions used by all rasterization functions. 3079c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul * This is where all the per-fragment tests are performed 3179c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul * \author Brian Paul 32e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */ 33e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 34bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul#include "main/glheader.h" 35bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul#include "main/colormac.h" 360ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul#include "main/format_pack.h" 370ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul#include "main/format_unpack.h" 38bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul#include "main/macros.h" 39bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul#include "main/imports.h" 40bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul#include "main/image.h" 41cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen#include "main/samplerobj.h" 42e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 437f752fed993e5e9423abac200dd59141edbada56Dave Airlie#include "s_atifragshader.h" 44bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol#include "s_alpha.h" 45e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_blend.h" 46cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell#include "s_context.h" 47e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_depth.h" 48e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_fog.h" 49e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_logic.h" 50e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_masking.h" 51c968d3d410a1897ecbb41d3557adaef69a4c627aBrian#include "s_fragprog.h" 52e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_span.h" 53e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_stencil.h" 5455187ea63e980b32c7a701855571332f4357d634Brian Paul#include "s_texcombine.h" 55e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 569be3be3c6654da18466626c2d45ff4d06b5fb953Ian Romanick#include <stdbool.h> 572a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 5879c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/** 599e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian * Set default fragment attributes for the span using the 609e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian * current raster values. Used prior to glDraw/CopyPixels 619e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian * and glBitmap. 622a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul */ 632a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paulvoid 64f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg_swrast_span_default_attribs(struct gl_context *ctx, SWspan *span) 652a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul{ 6660121c41ce9ee50ff8d8476d4eb04867adf9b8c5Karl Schultz GLchan r, g, b, a; 679e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian /* Z*/ 689e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian { 699e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian const GLfloat depthMax = ctx->DrawBuffer->_DepthMaxF; 709e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian if (ctx->DrawBuffer->Visual.depthBits <= 16) 719e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian span->z = FloatToFixed(ctx->Current.RasterPos[2] * depthMax + 0.5F); 726254be9b7144821e044d3fbade514fa0358db693Xiang, Haihao else { 736254be9b7144821e044d3fbade514fa0358db693Xiang, Haihao GLfloat tmpf = ctx->Current.RasterPos[2] * depthMax; 746254be9b7144821e044d3fbade514fa0358db693Xiang, Haihao tmpf = MIN2(tmpf, depthMax); 756254be9b7144821e044d3fbade514fa0358db693Xiang, Haihao span->z = (GLint)tmpf; 766254be9b7144821e044d3fbade514fa0358db693Xiang, Haihao } 779e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian span->zStep = 0; 789e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian span->interpMask |= SPAN_Z; 79884af408644e3fa9aa0ffc544f84ec4a7f3a93b9Brian } 802a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 819e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian /* W (for perspective correction) */ 829e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian span->attrStart[FRAG_ATTRIB_WPOS][3] = 1.0; 839e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian span->attrStepX[FRAG_ATTRIB_WPOS][3] = 0.0; 849e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian span->attrStepY[FRAG_ATTRIB_WPOS][3] = 0.0; 852a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 869e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian /* primary color, or color index */ 872b7911d37dc1518b9047b02acdc6f8476abad70fIan Romanick UNCLAMPED_FLOAT_TO_CHAN(r, ctx->Current.RasterColor[0]); 882b7911d37dc1518b9047b02acdc6f8476abad70fIan Romanick UNCLAMPED_FLOAT_TO_CHAN(g, ctx->Current.RasterColor[1]); 892b7911d37dc1518b9047b02acdc6f8476abad70fIan Romanick UNCLAMPED_FLOAT_TO_CHAN(b, ctx->Current.RasterColor[2]); 902b7911d37dc1518b9047b02acdc6f8476abad70fIan Romanick UNCLAMPED_FLOAT_TO_CHAN(a, ctx->Current.RasterColor[3]); 912a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul#if CHAN_TYPE == GL_FLOAT 922b7911d37dc1518b9047b02acdc6f8476abad70fIan Romanick span->red = r; 932b7911d37dc1518b9047b02acdc6f8476abad70fIan Romanick span->green = g; 942b7911d37dc1518b9047b02acdc6f8476abad70fIan Romanick span->blue = b; 952b7911d37dc1518b9047b02acdc6f8476abad70fIan Romanick span->alpha = a; 962a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul#else 972b7911d37dc1518b9047b02acdc6f8476abad70fIan Romanick span->red = IntToFixed(r); 982b7911d37dc1518b9047b02acdc6f8476abad70fIan Romanick span->green = IntToFixed(g); 992b7911d37dc1518b9047b02acdc6f8476abad70fIan Romanick span->blue = IntToFixed(b); 1002b7911d37dc1518b9047b02acdc6f8476abad70fIan Romanick span->alpha = IntToFixed(a); 1012a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul#endif 1022b7911d37dc1518b9047b02acdc6f8476abad70fIan Romanick span->redStep = 0; 1032b7911d37dc1518b9047b02acdc6f8476abad70fIan Romanick span->greenStep = 0; 1042b7911d37dc1518b9047b02acdc6f8476abad70fIan Romanick span->blueStep = 0; 1052b7911d37dc1518b9047b02acdc6f8476abad70fIan Romanick span->alphaStep = 0; 1062b7911d37dc1518b9047b02acdc6f8476abad70fIan Romanick span->interpMask |= SPAN_RGBA; 1079e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian 1082b7911d37dc1518b9047b02acdc6f8476abad70fIan Romanick COPY_4V(span->attrStart[FRAG_ATTRIB_COL0], ctx->Current.RasterColor); 1092b7911d37dc1518b9047b02acdc6f8476abad70fIan Romanick ASSIGN_4V(span->attrStepX[FRAG_ATTRIB_COL0], 0.0, 0.0, 0.0, 0.0); 1102b7911d37dc1518b9047b02acdc6f8476abad70fIan Romanick ASSIGN_4V(span->attrStepY[FRAG_ATTRIB_COL0], 0.0, 0.0, 0.0, 0.0); 1112a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 1129e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian /* Secondary color */ 1132b7911d37dc1518b9047b02acdc6f8476abad70fIan Romanick if (ctx->Light.Enabled || ctx->Fog.ColorSumEnabled) 114f793e90e823a58c0408771c38f3a6209f78a3617Brian { 1159e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian COPY_4V(span->attrStart[FRAG_ATTRIB_COL1], ctx->Current.RasterSecondaryColor); 1169e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian ASSIGN_4V(span->attrStepX[FRAG_ATTRIB_COL1], 0.0, 0.0, 0.0, 0.0); 1179e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian ASSIGN_4V(span->attrStepY[FRAG_ATTRIB_COL1], 0.0, 0.0, 0.0, 0.0); 1189e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian } 1199e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian 1209e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian /* fog */ 1219e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian { 1229e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian const SWcontext *swrast = SWRAST_CONTEXT(ctx); 1239e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian GLfloat fogVal; /* a coord or a blend factor */ 1249e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian if (swrast->_PreferPixelFog) { 1259e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian /* fog blend factors will be computed from fog coordinates per pixel */ 1269e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian fogVal = ctx->Current.RasterDistance; 1279e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian } 1289e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian else { 1299e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian /* fog blend factor should be computed from fogcoord now */ 1309e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian fogVal = _swrast_z_to_fogfactor(ctx, ctx->Current.RasterDistance); 1319e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian } 1329e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian span->attrStart[FRAG_ATTRIB_FOGC][0] = fogVal; 1339e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian span->attrStepX[FRAG_ATTRIB_FOGC][0] = 0.0; 1349e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian span->attrStepY[FRAG_ATTRIB_FOGC][0] = 0.0; 1359e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian } 1369e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian 1379e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian /* texcoords */ 1389e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian { 1399e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian GLuint i; 1409e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) { 1419e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian const GLuint attr = FRAG_ATTRIB_TEX0 + i; 1429e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian const GLfloat *tc = ctx->Current.RasterTexCoords[i]; 1431c0f1dd42a50464eeb81de4aad8eecf24b3d6c89Chad Versace if (_swrast_use_fragment_program(ctx) || 1441c0f1dd42a50464eeb81de4aad8eecf24b3d6c89Chad Versace ctx->ATIFragmentShader._Enabled) { 1459e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian COPY_4V(span->attrStart[attr], tc); 1469e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian } 1479e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian else if (tc[3] > 0.0F) { 1489e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian /* use (s/q, t/q, r/q, 1) */ 1499e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian span->attrStart[attr][0] = tc[0] / tc[3]; 1509e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian span->attrStart[attr][1] = tc[1] / tc[3]; 1519e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian span->attrStart[attr][2] = tc[2] / tc[3]; 1529e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian span->attrStart[attr][3] = 1.0; 1539e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian } 1549e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian else { 1559e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian ASSIGN_4V(span->attrStart[attr], 0.0F, 0.0F, 0.0F, 1.0F); 1569e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian } 1579e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian ASSIGN_4V(span->attrStepX[attr], 0.0F, 0.0F, 0.0F, 0.0F); 1589e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian ASSIGN_4V(span->attrStepY[attr], 0.0F, 0.0F, 0.0F, 0.0F); 1599e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian } 16038a1c2b4959d35236933c14d3944cce94283ca30Brian } 16138a1c2b4959d35236933c14d3944cce94283ca30Brian} 16238a1c2b4959d35236933c14d3944cce94283ca30Brian 16338a1c2b4959d35236933c14d3944cce94283ca30Brian 1644753d60dd070bb08d0116076bcc08025c86ce857Brian Paul/** 1659e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian * Interpolate the active attributes (and'd with attrMask) to 1669e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian * fill in span->array->attribs[]. 1679e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian * Perspective correction will be done. The point/line/triangle function 1689e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian * should have computed attrStart/Step values for FRAG_ATTRIB_WPOS[3]! 1694753d60dd070bb08d0116076bcc08025c86ce857Brian Paul */ 1709520f483b8f1e45fa474674b415554988de5d8d3Brian Paulstatic inline void 1718dffb6bdab25dcacf165851e9d1fdb3beb73099aBrian Paulinterpolate_active_attribs(struct gl_context *ctx, SWspan *span, 1728dffb6bdab25dcacf165851e9d1fdb3beb73099aBrian Paul GLbitfield64 attrMask) 1734753d60dd070bb08d0116076bcc08025c86ce857Brian Paul{ 1749e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian const SWcontext *swrast = SWRAST_CONTEXT(ctx); 1759e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian 1769dca42a4a10acbf1980c0f2eafb3e28e11ca1bf3Brian /* 1779dca42a4a10acbf1980c0f2eafb3e28e11ca1bf3Brian * Don't overwrite existing array values, such as colors that may have 1789dca42a4a10acbf1980c0f2eafb3e28e11ca1bf3Brian * been produced by glDraw/CopyPixels. 179171dcdfa27dda30916a7f9bfed89577feee5d350Brian */ 1809dca42a4a10acbf1980c0f2eafb3e28e11ca1bf3Brian attrMask &= ~span->arrayAttribs; 181171dcdfa27dda30916a7f9bfed89577feee5d350Brian 1829e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian ATTRIB_LOOP_BEGIN 183706400f0a7a59bba89eca8e97a1ada45445ee6dfBrian Paul if (attrMask & BITFIELD64_BIT(attr)) { 1849e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian const GLfloat dwdx = span->attrStepX[FRAG_ATTRIB_WPOS][3]; 1859e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian GLfloat w = span->attrStart[FRAG_ATTRIB_WPOS][3]; 1869e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian const GLfloat dv0dx = span->attrStepX[attr][0]; 1879e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian const GLfloat dv1dx = span->attrStepX[attr][1]; 1889e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian const GLfloat dv2dx = span->attrStepX[attr][2]; 1899e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian const GLfloat dv3dx = span->attrStepX[attr][3]; 1906a3004b9ae58dafd1ce995df78b0f3183827a59dBrian Paul GLfloat v0 = span->attrStart[attr][0] + span->leftClip * dv0dx; 1916a3004b9ae58dafd1ce995df78b0f3183827a59dBrian Paul GLfloat v1 = span->attrStart[attr][1] + span->leftClip * dv1dx; 1926a3004b9ae58dafd1ce995df78b0f3183827a59dBrian Paul GLfloat v2 = span->attrStart[attr][2] + span->leftClip * dv2dx; 1936a3004b9ae58dafd1ce995df78b0f3183827a59dBrian Paul GLfloat v3 = span->attrStart[attr][3] + span->leftClip * dv3dx; 1949e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian GLuint k; 1959e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian for (k = 0; k < span->end; k++) { 1969e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian const GLfloat invW = 1.0f / w; 1979e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian span->array->attribs[attr][k][0] = v0 * invW; 1989e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian span->array->attribs[attr][k][1] = v1 * invW; 1999e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian span->array->attribs[attr][k][2] = v2 * invW; 2009e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian span->array->attribs[attr][k][3] = v3 * invW; 2019e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian v0 += dv0dx; 2029e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian v1 += dv1dx; 2039e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian v2 += dv2dx; 2049e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian v3 += dv3dx; 2059e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian w += dwdx; 2069e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian } 207706400f0a7a59bba89eca8e97a1ada45445ee6dfBrian Paul ASSERT((span->arrayAttribs & BITFIELD64_BIT(attr)) == 0); 208706400f0a7a59bba89eca8e97a1ada45445ee6dfBrian Paul span->arrayAttribs |= BITFIELD64_BIT(attr); 209e63cb85cbc13c083f5d9f4640bb81ba9417a4f28Brian Paul } 2109e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian ATTRIB_LOOP_END 2114753d60dd070bb08d0116076bcc08025c86ce857Brian Paul} 2124753d60dd070bb08d0116076bcc08025c86ce857Brian Paul 2134753d60dd070bb08d0116076bcc08025c86ce857Brian Paul 214d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul/** 2159e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian * Interpolate primary colors to fill in the span->array->rgba8 (or rgb16) 2169e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian * color array. 217d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul */ 2189520f483b8f1e45fa474674b415554988de5d8d3Brian Paulstatic inline void 219f9995b30756140724f41daf963fa06167912be7fKristian Høgsberginterpolate_int_colors(struct gl_context *ctx, SWspan *span) 2202a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul{ 221afd1d857752b5c30a3082068f8bb9002e0c69699Fabio Pedretti#if CHAN_BITS != 32 2222a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul const GLuint n = span->end; 2232a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLuint i; 2242a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 2259e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian ASSERT(!(span->arrayMask & SPAN_RGBA)); 2269e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian#endif 2272a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 228e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul switch (span->array->ChanType) { 2291e3223c02a2f6155beb5784cadbea1f46703829aBrian Paul#if CHAN_BITS != 32 230e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul case GL_UNSIGNED_BYTE: 231e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul { 2329e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian GLubyte (*rgba)[4] = span->array->rgba8; 233e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul if (span->interpMask & SPAN_FLAT) { 234d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul GLubyte color[4]; 235e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul color[RCOMP] = FixedToInt(span->red); 236e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul color[GCOMP] = FixedToInt(span->green); 237e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul color[BCOMP] = FixedToInt(span->blue); 238e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul color[ACOMP] = FixedToInt(span->alpha); 239d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul for (i = 0; i < n; i++) { 240d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul COPY_4UBV(rgba[i], color); 241d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul } 242d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul } 243e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul else { 244e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul GLfixed r = span->red; 245e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul GLfixed g = span->green; 246e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul GLfixed b = span->blue; 247e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul GLfixed a = span->alpha; 248e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul GLint dr = span->redStep; 249e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul GLint dg = span->greenStep; 250e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul GLint db = span->blueStep; 251e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul GLint da = span->alphaStep; 252d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul for (i = 0; i < n; i++) { 253e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul rgba[i][RCOMP] = FixedToChan(r); 254e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul rgba[i][GCOMP] = FixedToChan(g); 255e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul rgba[i][BCOMP] = FixedToChan(b); 256e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul rgba[i][ACOMP] = FixedToChan(a); 257e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul r += dr; 258e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul g += dg; 259e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul b += db; 260e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul a += da; 261d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul } 262d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul } 263e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul } 264e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul break; 265e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul case GL_UNSIGNED_SHORT: 266e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul { 2679e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian GLushort (*rgba)[4] = span->array->rgba16; 268e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul if (span->interpMask & SPAN_FLAT) { 269e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul GLushort color[4]; 270e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul color[RCOMP] = FixedToInt(span->red); 271e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul color[GCOMP] = FixedToInt(span->green); 272e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul color[BCOMP] = FixedToInt(span->blue); 273e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul color[ACOMP] = FixedToInt(span->alpha); 274d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul for (i = 0; i < n; i++) { 275d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul COPY_4V(rgba[i], color); 276d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul } 277d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul } 278e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul else { 2799e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian GLushort (*rgba)[4] = span->array->rgba16; 280d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul GLfixed r, g, b, a; 281d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul GLint dr, dg, db, da; 282e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul r = span->red; 283e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul g = span->green; 284e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul b = span->blue; 285e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul a = span->alpha; 286e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul dr = span->redStep; 287e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul dg = span->greenStep; 288e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul db = span->blueStep; 289e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul da = span->alphaStep; 290d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul for (i = 0; i < n; i++) { 291d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul rgba[i][RCOMP] = FixedToChan(r); 292d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul rgba[i][GCOMP] = FixedToChan(g); 293d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul rgba[i][BCOMP] = FixedToChan(b); 294d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul rgba[i][ACOMP] = FixedToChan(a); 295d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul r += dr; 296d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul g += dg; 297d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul b += db; 298d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul a += da; 299d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul } 300d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul } 301e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul } 302e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul break; 303e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul#endif 304e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul case GL_FLOAT: 3059e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian interpolate_active_attribs(ctx, span, FRAG_BIT_COL0); 306e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul break; 307e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul default: 308147148fd50ec2db089a0fbcca9740146aa096be8Brian Paul _mesa_problem(ctx, "bad datatype 0x%x in interpolate_int_colors", 309147148fd50ec2db089a0fbcca9740146aa096be8Brian Paul span->array->ChanType); 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 */ 3189520f483b8f1e45fa474674b415554988de5d8d3Brian 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 3769e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian/** 3779e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian * Fill in the span.zArray array from the span->z, zStep values. 3789e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian */ 379711e27fda27e4235b20a4cf73c2767c984ab2b81Brian Paulvoid 380f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg_swrast_span_interpolate_z( const struct gl_context *ctx, SWspan *span ) 3812a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul{ 3822a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul const GLuint n = span->end; 3832a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLuint i; 3842a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 3859e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian ASSERT(!(span->arrayMask & SPAN_Z)); 3862a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 38731e739a18931fa48454f172818245b0927c8910fBrian Paul if (ctx->DrawBuffer->Visual.depthBits <= 16) { 3882a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul GLfixed zval = span->z; 3893e37bafab0a339021354b9c78f983d05d433d735Brian Paul GLuint *z = span->array->z; 390ad8cd6111e022c90c93df106c0fde6f64d205816Brian Paul for (i = 0; i < n; i++) { 39177df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul z[i] = FixedToInt(zval); 3922a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul zval += span->zStep; 3932a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 3942a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 3952a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul else { 3962a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul /* Deep Z buffer, no fixed->int shift */ 3977265556b9aa0367e9b5031e7cb15ed2a5d73866dBrian Paul GLuint zval = span->z; 3983e37bafab0a339021354b9c78f983d05d433d735Brian Paul GLuint *z = span->array->z; 3992a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul for (i = 0; i < n; i++) { 40077df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul z[i] = zval; 4012a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul zval += span->zStep; 4022a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 4032a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 40432340aea1308153dad5c105fc0748aea1e4c37eeBrian Paul span->interpMask &= ~SPAN_Z; 4052a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul span->arrayMask |= SPAN_Z; 4062a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul} 4072a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 4082a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 4099e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian/** 4109e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian * Compute mipmap LOD from partial derivatives. 41131f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul * This the ideal solution, as given in the OpenGL spec. 412c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul */ 413c334ce273e946733928339b1c7f9a02ccdef1b4bBrian PaulGLfloat 414c334ce273e946733928339b1c7f9a02ccdef1b4bBrian Paul_swrast_compute_lambda(GLfloat dsdx, GLfloat dsdy, GLfloat dtdx, GLfloat dtdy, 415c334ce273e946733928339b1c7f9a02ccdef1b4bBrian Paul GLfloat dqdx, GLfloat dqdy, GLfloat texW, GLfloat texH, 416c334ce273e946733928339b1c7f9a02ccdef1b4bBrian Paul GLfloat s, GLfloat t, GLfloat q, GLfloat invQ) 417c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul{ 41831f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat dudx = texW * ((s + dsdx) / (q + dqdx) - s * invQ); 41931f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat dvdx = texH * ((t + dtdx) / (q + dqdx) - t * invQ); 42031f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat dudy = texW * ((s + dsdy) / (q + dqdy) - s * invQ); 42131f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat dvdy = texH * ((t + dtdy) / (q + dqdy) - t * invQ); 422f9b1e5241facc8cf255c258082d5cb5b04783e93Brian Paul GLfloat x = SQRTF(dudx * dudx + dvdx * dvdx); 423f9b1e5241facc8cf255c258082d5cb5b04783e93Brian Paul GLfloat y = SQRTF(dudy * dudy + dvdy * dvdy); 42431f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat rho = MAX2(x, y); 42531f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat lambda = LOG2(rho); 42631f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul return lambda; 427c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul} 428c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul 42931f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul 4309e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian/** 4319e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian * Compute mipmap LOD from partial derivatives. 4329e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian * This is a faster approximation than above function. 433c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul */ 434c334ce273e946733928339b1c7f9a02ccdef1b4bBrian Paul#if 0 435350353adcd75f94fda63c787c86961716114e0bfBrian PaulGLfloat 43645bc887da226403f2c41077e40ca38b6f60f1359Brian Paul_swrast_compute_lambda(GLfloat dsdx, GLfloat dsdy, GLfloat dtdx, GLfloat dtdy, 437350353adcd75f94fda63c787c86961716114e0bfBrian Paul GLfloat dqdx, GLfloat dqdy, GLfloat texW, GLfloat texH, 438350353adcd75f94fda63c787c86961716114e0bfBrian Paul GLfloat s, GLfloat t, GLfloat q, GLfloat invQ) 439c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul{ 44031f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat dsdx2 = (s + dsdx) / (q + dqdx) - s * invQ; 44131f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat dtdx2 = (t + dtdx) / (q + dqdx) - t * invQ; 44231f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat dsdy2 = (s + dsdy) / (q + dqdy) - s * invQ; 44331f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat dtdy2 = (t + dtdy) / (q + dqdy) - t * invQ; 44431f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul GLfloat maxU, maxV, rho, lambda; 44531f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul dsdx2 = FABSF(dsdx2); 44631f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul dsdy2 = FABSF(dsdy2); 44731f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul dtdx2 = FABSF(dtdx2); 44831f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul dtdy2 = FABSF(dtdy2); 44931f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul maxU = MAX2(dsdx2, dsdy2) * texW; 45031f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul maxV = MAX2(dtdx2, dtdy2) * texH; 45131f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul rho = MAX2(maxU, maxV); 45231f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul lambda = LOG2(rho); 45331f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul return lambda; 454c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul} 455c334ce273e946733928339b1c7f9a02ccdef1b4bBrian Paul#endif 456c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul 457d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul 458d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul/** 4599e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian * Fill in the span.array->attrib[FRAG_ATTRIB_TEXn] arrays from the 4609e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian * using the attrStart/Step values. 4619e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian * 4629e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian * This function only used during fixed-function fragment processing. 4639e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian * 464d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul * Note: in the places where we divide by Q (or mult by invQ) we're 465d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul * really doing two things: perspective correction and texcoord 466d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul * projection. Remember, for texcoord (s,t,r,q) we need to index 467d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul * texels with (s/q, t/q, r/q). 468c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul */ 4692a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paulstatic void 470f9995b30756140724f41daf963fa06167912be7fKristian Høgsberginterpolate_texcoords(struct gl_context *ctx, SWspan *span) 4712a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul{ 472e4f976b8b9d74a74b5816146cb11880c3a493929Brian const GLuint maxUnit 473e4f976b8b9d74a74b5816146cb11880c3a493929Brian = (ctx->Texture._EnabledCoordUnits > 1) ? ctx->Const.MaxTextureUnits : 1; 474e4f976b8b9d74a74b5816146cb11880c3a493929Brian GLuint u; 475e4f976b8b9d74a74b5816146cb11880c3a493929Brian 476e4f976b8b9d74a74b5816146cb11880c3a493929Brian /* XXX CoordUnits vs. ImageUnits */ 477e4f976b8b9d74a74b5816146cb11880c3a493929Brian for (u = 0; u < maxUnit; u++) { 478e4f976b8b9d74a74b5816146cb11880c3a493929Brian if (ctx->Texture._EnabledCoordUnits & (1 << u)) { 479e4f976b8b9d74a74b5816146cb11880c3a493929Brian const GLuint attr = FRAG_ATTRIB_TEX0 + u; 480c000843a14e73d593d87ff6674d0295d2cb64a12Brian const struct gl_texture_object *obj = ctx->Texture.Unit[u]._Current; 481e4f976b8b9d74a74b5816146cb11880c3a493929Brian GLfloat texW, texH; 482e4f976b8b9d74a74b5816146cb11880c3a493929Brian GLboolean needLambda; 483e4f976b8b9d74a74b5816146cb11880c3a493929Brian GLfloat (*texcoord)[4] = span->array->attribs[attr]; 484e4f976b8b9d74a74b5816146cb11880c3a493929Brian GLfloat *lambda = span->array->lambda[u]; 485e4f976b8b9d74a74b5816146cb11880c3a493929Brian const GLfloat dsdx = span->attrStepX[attr][0]; 486e4f976b8b9d74a74b5816146cb11880c3a493929Brian const GLfloat dsdy = span->attrStepY[attr][0]; 487e4f976b8b9d74a74b5816146cb11880c3a493929Brian const GLfloat dtdx = span->attrStepX[attr][1]; 488e4f976b8b9d74a74b5816146cb11880c3a493929Brian const GLfloat dtdy = span->attrStepY[attr][1]; 489e4f976b8b9d74a74b5816146cb11880c3a493929Brian const GLfloat drdx = span->attrStepX[attr][2]; 490e4f976b8b9d74a74b5816146cb11880c3a493929Brian const GLfloat dqdx = span->attrStepX[attr][3]; 491e4f976b8b9d74a74b5816146cb11880c3a493929Brian const GLfloat dqdy = span->attrStepY[attr][3]; 4926a3004b9ae58dafd1ce995df78b0f3183827a59dBrian Paul GLfloat s = span->attrStart[attr][0] + span->leftClip * dsdx; 4936a3004b9ae58dafd1ce995df78b0f3183827a59dBrian Paul GLfloat t = span->attrStart[attr][1] + span->leftClip * dtdx; 4946a3004b9ae58dafd1ce995df78b0f3183827a59dBrian Paul GLfloat r = span->attrStart[attr][2] + span->leftClip * drdx; 4956a3004b9ae58dafd1ce995df78b0f3183827a59dBrian Paul GLfloat q = span->attrStart[attr][3] + span->leftClip * dqdx; 496e4f976b8b9d74a74b5816146cb11880c3a493929Brian 497e4f976b8b9d74a74b5816146cb11880c3a493929Brian if (obj) { 498e4f976b8b9d74a74b5816146cb11880c3a493929Brian const struct gl_texture_image *img = obj->Image[0][obj->BaseLevel]; 499980f6f1b37ca88529b3e000235156eab93254facBrian Paul const struct swrast_texture_image *swImg = 500980f6f1b37ca88529b3e000235156eab93254facBrian Paul swrast_texture_image_const(img); 501cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen const struct gl_sampler_object *samp = _mesa_get_samplerobj(ctx, u); 502980f6f1b37ca88529b3e000235156eab93254facBrian Paul 503cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen needLambda = (samp->MinFilter != samp->MagFilter) 5041c0f1dd42a50464eeb81de4aad8eecf24b3d6c89Chad Versace || _swrast_use_fragment_program(ctx); 5058a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger /* LOD is calculated directly in the ansiotropic filter, we can 5068a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger * skip the normal lambda function as the result is ignored. 5078a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger */ 508cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen if (samp->MaxAnisotropy > 1.0 && 509cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen samp->MinFilter == GL_LINEAR_MIPMAP_LINEAR) { 5108a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger needLambda = GL_FALSE; 5118a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger } 512980f6f1b37ca88529b3e000235156eab93254facBrian Paul texW = swImg->WidthScale; 513980f6f1b37ca88529b3e000235156eab93254facBrian Paul texH = swImg->HeightScale; 514e4f976b8b9d74a74b5816146cb11880c3a493929Brian } 515e4f976b8b9d74a74b5816146cb11880c3a493929Brian else { 516e4f976b8b9d74a74b5816146cb11880c3a493929Brian /* using a fragment program */ 517e4f976b8b9d74a74b5816146cb11880c3a493929Brian texW = 1.0; 518e4f976b8b9d74a74b5816146cb11880c3a493929Brian texH = 1.0; 519e4f976b8b9d74a74b5816146cb11880c3a493929Brian needLambda = GL_FALSE; 520e4f976b8b9d74a74b5816146cb11880c3a493929Brian } 521e4f976b8b9d74a74b5816146cb11880c3a493929Brian 522e4f976b8b9d74a74b5816146cb11880c3a493929Brian if (needLambda) { 523e4f976b8b9d74a74b5816146cb11880c3a493929Brian GLuint i; 5241c0f1dd42a50464eeb81de4aad8eecf24b3d6c89Chad Versace if (_swrast_use_fragment_program(ctx) 525e4f976b8b9d74a74b5816146cb11880c3a493929Brian || ctx->ATIFragmentShader._Enabled) { 526e4f976b8b9d74a74b5816146cb11880c3a493929Brian /* do perspective correction but don't divide s, t, r by q */ 527e4f976b8b9d74a74b5816146cb11880c3a493929Brian const GLfloat dwdx = span->attrStepX[FRAG_ATTRIB_WPOS][3]; 5286a3004b9ae58dafd1ce995df78b0f3183827a59dBrian Paul GLfloat w = span->attrStart[FRAG_ATTRIB_WPOS][3] + span->leftClip * dwdx; 529e4f976b8b9d74a74b5816146cb11880c3a493929Brian for (i = 0; i < span->end; i++) { 530e4f976b8b9d74a74b5816146cb11880c3a493929Brian const GLfloat invW = 1.0F / w; 531e4f976b8b9d74a74b5816146cb11880c3a493929Brian texcoord[i][0] = s * invW; 532e4f976b8b9d74a74b5816146cb11880c3a493929Brian texcoord[i][1] = t * invW; 533e4f976b8b9d74a74b5816146cb11880c3a493929Brian texcoord[i][2] = r * invW; 534e4f976b8b9d74a74b5816146cb11880c3a493929Brian texcoord[i][3] = q * invW; 535e4f976b8b9d74a74b5816146cb11880c3a493929Brian lambda[i] = _swrast_compute_lambda(dsdx, dsdy, dtdx, dtdy, 536e4f976b8b9d74a74b5816146cb11880c3a493929Brian dqdx, dqdy, texW, texH, 537e4f976b8b9d74a74b5816146cb11880c3a493929Brian s, t, q, invW); 538e4f976b8b9d74a74b5816146cb11880c3a493929Brian s += dsdx; 539e4f976b8b9d74a74b5816146cb11880c3a493929Brian t += dtdx; 540e4f976b8b9d74a74b5816146cb11880c3a493929Brian r += drdx; 541e4f976b8b9d74a74b5816146cb11880c3a493929Brian q += dqdx; 542e4f976b8b9d74a74b5816146cb11880c3a493929Brian w += dwdx; 5432a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 5442a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 54531f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul else { 546e4f976b8b9d74a74b5816146cb11880c3a493929Brian for (i = 0; i < span->end; i++) { 5472a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q); 548e4f976b8b9d74a74b5816146cb11880c3a493929Brian texcoord[i][0] = s * invQ; 549e4f976b8b9d74a74b5816146cb11880c3a493929Brian texcoord[i][1] = t * invQ; 550e4f976b8b9d74a74b5816146cb11880c3a493929Brian texcoord[i][2] = r * invQ; 551e4f976b8b9d74a74b5816146cb11880c3a493929Brian texcoord[i][3] = q; 552e4f976b8b9d74a74b5816146cb11880c3a493929Brian lambda[i] = _swrast_compute_lambda(dsdx, dsdy, dtdx, dtdy, 553e4f976b8b9d74a74b5816146cb11880c3a493929Brian dqdx, dqdy, texW, texH, 554e4f976b8b9d74a74b5816146cb11880c3a493929Brian s, t, q, invQ); 555e4f976b8b9d74a74b5816146cb11880c3a493929Brian s += dsdx; 556e4f976b8b9d74a74b5816146cb11880c3a493929Brian t += dtdx; 557e4f976b8b9d74a74b5816146cb11880c3a493929Brian r += drdx; 558e4f976b8b9d74a74b5816146cb11880c3a493929Brian q += dqdx; 5592a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul } 560d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul } 561e4f976b8b9d74a74b5816146cb11880c3a493929Brian span->arrayMask |= SPAN_LAMBDA; 562d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul } 563d8b82147c3cb17a06bf41e97141b8427b4580459Brian Paul else { 564e4f976b8b9d74a74b5816146cb11880c3a493929Brian GLuint i; 5651c0f1dd42a50464eeb81de4aad8eecf24b3d6c89Chad Versace if (_swrast_use_fragment_program(ctx) || 566e4f976b8b9d74a74b5816146cb11880c3a493929Brian ctx->ATIFragmentShader._Enabled) { 567e4f976b8b9d74a74b5816146cb11880c3a493929Brian /* do perspective correction but don't divide s, t, r by q */ 568e4f976b8b9d74a74b5816146cb11880c3a493929Brian const GLfloat dwdx = span->attrStepX[FRAG_ATTRIB_WPOS][3]; 5696a3004b9ae58dafd1ce995df78b0f3183827a59dBrian Paul GLfloat w = span->attrStart[FRAG_ATTRIB_WPOS][3] + span->leftClip * dwdx; 570e4f976b8b9d74a74b5816146cb11880c3a493929Brian for (i = 0; i < span->end; i++) { 571e4f976b8b9d74a74b5816146cb11880c3a493929Brian const GLfloat invW = 1.0F / w; 572e4f976b8b9d74a74b5816146cb11880c3a493929Brian texcoord[i][0] = s * invW; 573e4f976b8b9d74a74b5816146cb11880c3a493929Brian texcoord[i][1] = t * invW; 574e4f976b8b9d74a74b5816146cb11880c3a493929Brian texcoord[i][2] = r * invW; 575e4f976b8b9d74a74b5816146cb11880c3a493929Brian texcoord[i][3] = q * invW; 576e4f976b8b9d74a74b5816146cb11880c3a493929Brian lambda[i] = 0.0; 577e4f976b8b9d74a74b5816146cb11880c3a493929Brian s += dsdx; 578e4f976b8b9d74a74b5816146cb11880c3a493929Brian t += dtdx; 579e4f976b8b9d74a74b5816146cb11880c3a493929Brian r += drdx; 580e4f976b8b9d74a74b5816146cb11880c3a493929Brian q += dqdx; 581e4f976b8b9d74a74b5816146cb11880c3a493929Brian w += dwdx; 582e4f976b8b9d74a74b5816146cb11880c3a493929Brian } 583c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul } 584e4f976b8b9d74a74b5816146cb11880c3a493929Brian else if (dqdx == 0.0F) { 585e4f976b8b9d74a74b5816146cb11880c3a493929Brian /* Ortho projection or polygon's parallel to window X axis */ 586c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q); 587e4f976b8b9d74a74b5816146cb11880c3a493929Brian for (i = 0; i < span->end; i++) { 588e4f976b8b9d74a74b5816146cb11880c3a493929Brian texcoord[i][0] = s * invQ; 589e4f976b8b9d74a74b5816146cb11880c3a493929Brian texcoord[i][1] = t * invQ; 590e4f976b8b9d74a74b5816146cb11880c3a493929Brian texcoord[i][2] = r * invQ; 591e4f976b8b9d74a74b5816146cb11880c3a493929Brian texcoord[i][3] = q; 592e4f976b8b9d74a74b5816146cb11880c3a493929Brian lambda[i] = 0.0; 593e4f976b8b9d74a74b5816146cb11880c3a493929Brian s += dsdx; 594e4f976b8b9d74a74b5816146cb11880c3a493929Brian t += dtdx; 595e4f976b8b9d74a74b5816146cb11880c3a493929Brian r += drdx; 596e4f976b8b9d74a74b5816146cb11880c3a493929Brian } 597c14a5a6c6285b29860a722359faa11a16da4eac9Brian Paul } 598e4f976b8b9d74a74b5816146cb11880c3a493929Brian else { 599e4f976b8b9d74a74b5816146cb11880c3a493929Brian for (i = 0; i < span->end; i++) { 600e4f976b8b9d74a74b5816146cb11880c3a493929Brian const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q); 601e4f976b8b9d74a74b5816146cb11880c3a493929Brian texcoord[i][0] = s * invQ; 602e4f976b8b9d74a74b5816146cb11880c3a493929Brian texcoord[i][1] = t * invQ; 603e4f976b8b9d74a74b5816146cb11880c3a493929Brian texcoord[i][2] = r * invQ; 604e4f976b8b9d74a74b5816146cb11880c3a493929Brian texcoord[i][3] = q; 605e4f976b8b9d74a74b5816146cb11880c3a493929Brian lambda[i] = 0.0; 606e4f976b8b9d74a74b5816146cb11880c3a493929Brian s += dsdx; 607e4f976b8b9d74a74b5816146cb11880c3a493929Brian t += dtdx; 608e4f976b8b9d74a74b5816146cb11880c3a493929Brian r += drdx; 609e4f976b8b9d74a74b5816146cb11880c3a493929Brian q += dqdx; 610e4f976b8b9d74a74b5816146cb11880c3a493929Brian } 611e4f976b8b9d74a74b5816146cb11880c3a493929Brian } 612e4f976b8b9d74a74b5816146cb11880c3a493929Brian } /* lambda */ 613e4f976b8b9d74a74b5816146cb11880c3a493929Brian } /* if */ 614e4f976b8b9d74a74b5816146cb11880c3a493929Brian } /* for */ 61510f30eb43835c57c00783390a02d72daf4f78e26Brian Paul} 616e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 617e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 618bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol/** 619f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian * Fill in the arrays->attribs[FRAG_ATTRIB_WPOS] array. 620f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian */ 6219520f483b8f1e45fa474674b415554988de5d8d3Brian Paulstatic inline void 622f9995b30756140724f41daf963fa06167912be7fKristian Høgsberginterpolate_wpos(struct gl_context *ctx, SWspan *span) 623f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian{ 624f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian GLfloat (*wpos)[4] = span->array->attribs[FRAG_ATTRIB_WPOS]; 625f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian GLuint i; 626880411c72aee7c0ec81366bdf6ab8cf25bebb9d5Brian Paul const GLfloat zScale = 1.0F / ctx->DrawBuffer->_DepthMaxF; 6278e6207396c6314d07614c80670f4e3196e3a8551Brian GLfloat w, dw; 6288e6207396c6314d07614c80670f4e3196e3a8551Brian 629f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian if (span->arrayMask & SPAN_XY) { 630f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian for (i = 0; i < span->end; i++) { 631f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian wpos[i][0] = (GLfloat) span->array->x[i]; 632f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian wpos[i][1] = (GLfloat) span->array->y[i]; 633f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian } 634f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian } 635f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian else { 636f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian for (i = 0; i < span->end; i++) { 637f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian wpos[i][0] = (GLfloat) span->x + i; 638f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian wpos[i][1] = (GLfloat) span->y; 639f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian } 640f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian } 6418e6207396c6314d07614c80670f4e3196e3a8551Brian 6428e6207396c6314d07614c80670f4e3196e3a8551Brian dw = span->attrStepX[FRAG_ATTRIB_WPOS][3]; 6436a3004b9ae58dafd1ce995df78b0f3183827a59dBrian Paul w = span->attrStart[FRAG_ATTRIB_WPOS][3] + span->leftClip * dw; 644f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian for (i = 0; i < span->end; i++) { 6458e6207396c6314d07614c80670f4e3196e3a8551Brian wpos[i][2] = (GLfloat) span->array->z[i] * zScale; 6468e6207396c6314d07614c80670f4e3196e3a8551Brian wpos[i][3] = w; 6478e6207396c6314d07614c80670f4e3196e3a8551Brian w += dw; 648f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian } 649f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian} 650f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian 651f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian 652f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian/** 653e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Apply the current polygon stipple pattern to a span of pixels. 654e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */ 6559520f483b8f1e45fa474674b415554988de5d8d3Brian Paulstatic inline void 656f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergstipple_polygon_span(struct gl_context *ctx, SWspan *span) 65710f30eb43835c57c00783390a02d72daf4f78e26Brian Paul{ 65877df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul GLubyte *mask = span->array->mask; 659733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul 660733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul ASSERT(ctx->Polygon.StippleFlag); 66110f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 662ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian if (span->arrayMask & SPAN_XY) { 663ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian /* arrays of x/y pixel coords */ 664ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian GLuint i; 665ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian for (i = 0; i < span->end; i++) { 666ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian const GLint col = span->array->x[i] % 32; 667ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian const GLint row = span->array->y[i] % 32; 668ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian const GLuint stipple = ctx->PolygonStipple[row]; 669ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian if (((1 << col) & stipple) == 0) { 670ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian mask[i] = 0; 671ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian } 67210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 673ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian } 674ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian else { 675ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian /* horizontal span of pixels */ 676ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian const GLuint highBit = 1 << 31; 677ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian const GLuint stipple = ctx->PolygonStipple[span->y % 32]; 678ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian GLuint i, m = highBit >> (GLuint) (span->x % 32); 679ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian for (i = 0; i < span->end; i++) { 680ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian if ((m & stipple) == 0) { 681ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian mask[i] = 0; 682ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian } 683ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian m = m >> 1; 684ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian if (m == 0) { 685ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian m = highBit; 686ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian } 68710f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 68810f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 6892ef866d1fc0a5cc5ef8543d65744dfd4da4dbbafBrian Paul span->writeAll = GL_FALSE; 69010f30eb43835c57c00783390a02d72daf4f78e26Brian Paul} 69110f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 692e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 69379c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/** 694733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul * Clip a pixel span to the current buffer/window boundaries: 695733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul * DrawBuffer->_Xmin, _Xmax, _Ymin, _Ymax. This will accomplish 696733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul * window clipping and scissoring. 697733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul * Return: GL_TRUE some pixels still visible 69810f30eb43835c57c00783390a02d72daf4f78e26Brian Paul * GL_FALSE nothing visible 69910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul */ 7009520f483b8f1e45fa474674b415554988de5d8d3Brian Paulstatic inline GLuint 701f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergclip_span( struct gl_context *ctx, SWspan *span ) 70210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul{ 703733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul const GLint xmin = ctx->DrawBuffer->_Xmin; 704733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul const GLint xmax = ctx->DrawBuffer->_Xmax; 705733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul const GLint ymin = ctx->DrawBuffer->_Ymin; 706733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul const GLint ymax = ctx->DrawBuffer->_Ymax; 707733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul 7086a3004b9ae58dafd1ce995df78b0f3183827a59dBrian Paul span->leftClip = 0; 7096a3004b9ae58dafd1ce995df78b0f3183827a59dBrian Paul 710733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (span->arrayMask & SPAN_XY) { 711733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* arrays of x/y pixel coords */ 71277df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul const GLint *x = span->array->x; 71377df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul const GLint *y = span->array->y; 714733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul const GLint n = span->end; 71577df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul GLubyte *mask = span->array->mask; 716733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul GLint i; 717718cbe4ba95439c074144ea2ce06ebf0915a660cBrian Paul GLuint passed = 0; 718b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul if (span->arrayMask & SPAN_MASK) { 719b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul /* note: using & intead of && to reduce branches */ 720b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul for (i = 0; i < n; i++) { 721b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul mask[i] &= (x[i] >= xmin) & (x[i] < xmax) 722b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul & (y[i] >= ymin) & (y[i] < ymax); 723718cbe4ba95439c074144ea2ce06ebf0915a660cBrian Paul passed += mask[i]; 724b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul } 725b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul } 726b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul else { 727b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul /* note: using & intead of && to reduce branches */ 728b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul for (i = 0; i < n; i++) { 729b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul mask[i] = (x[i] >= xmin) & (x[i] < xmax) 730b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul & (y[i] >= ymin) & (y[i] < ymax); 731718cbe4ba95439c074144ea2ce06ebf0915a660cBrian Paul passed += mask[i]; 732b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul } 73310f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 734718cbe4ba95439c074144ea2ce06ebf0915a660cBrian Paul return passed > 0; 73510f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 736733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul else { 737733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* horizontal span of pixels */ 738733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul const GLint x = span->x; 739733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul const GLint y = span->y; 7406a3004b9ae58dafd1ce995df78b0f3183827a59dBrian Paul GLint n = span->end; 741733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul 742733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* Trivial rejection tests */ 743733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (y < ymin || y >= ymax || x + n <= xmin || x >= xmax) { 744733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->end = 0; 745733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul return GL_FALSE; /* all pixels clipped */ 746733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul } 74710f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 7486a3004b9ae58dafd1ce995df78b0f3183827a59dBrian Paul /* Clip to right */ 7496a3004b9ae58dafd1ce995df78b0f3183827a59dBrian Paul if (x + n > xmax) { 7506a3004b9ae58dafd1ce995df78b0f3183827a59dBrian Paul ASSERT(x < xmax); 7516a3004b9ae58dafd1ce995df78b0f3183827a59dBrian Paul n = span->end = xmax - x; 7526a3004b9ae58dafd1ce995df78b0f3183827a59dBrian Paul } 7536a3004b9ae58dafd1ce995df78b0f3183827a59dBrian Paul 754733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* Clip to the left */ 755733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (x < xmin) { 7566a3004b9ae58dafd1ce995df78b0f3183827a59dBrian Paul const GLint leftClip = xmin - x; 7576a3004b9ae58dafd1ce995df78b0f3183827a59dBrian Paul GLuint i; 7586a3004b9ae58dafd1ce995df78b0f3183827a59dBrian Paul 7596a3004b9ae58dafd1ce995df78b0f3183827a59dBrian Paul ASSERT(leftClip > 0); 760733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul ASSERT(x + n > xmin); 7616a3004b9ae58dafd1ce995df78b0f3183827a59dBrian Paul 7626a3004b9ae58dafd1ce995df78b0f3183827a59dBrian Paul /* Clip 'leftClip' pixels from the left side. 7636a3004b9ae58dafd1ce995df78b0f3183827a59dBrian Paul * The span->leftClip field will be applied when we interpolate 7646a3004b9ae58dafd1ce995df78b0f3183827a59dBrian Paul * fragment attributes. 7656a3004b9ae58dafd1ce995df78b0f3183827a59dBrian Paul * For arrays of values, shift them left. 7666a3004b9ae58dafd1ce995df78b0f3183827a59dBrian Paul */ 7676a3004b9ae58dafd1ce995df78b0f3183827a59dBrian Paul for (i = 0; i < FRAG_ATTRIB_MAX; i++) { 768a61dce363929bbc3520f91cefa3ba15bbe31c5bdBrian Paul if (span->interpMask & (1 << i)) { 769a61dce363929bbc3520f91cefa3ba15bbe31c5bdBrian Paul GLuint j; 770a61dce363929bbc3520f91cefa3ba15bbe31c5bdBrian Paul for (j = 0; j < 4; j++) { 771a61dce363929bbc3520f91cefa3ba15bbe31c5bdBrian Paul span->attrStart[i][j] += leftClip * span->attrStepX[i][j]; 772a61dce363929bbc3520f91cefa3ba15bbe31c5bdBrian Paul } 773a61dce363929bbc3520f91cefa3ba15bbe31c5bdBrian Paul } 774a61dce363929bbc3520f91cefa3ba15bbe31c5bdBrian Paul } 775a61dce363929bbc3520f91cefa3ba15bbe31c5bdBrian Paul 776a61dce363929bbc3520f91cefa3ba15bbe31c5bdBrian Paul span->red += leftClip * span->redStep; 777a61dce363929bbc3520f91cefa3ba15bbe31c5bdBrian Paul span->green += leftClip * span->greenStep; 778a61dce363929bbc3520f91cefa3ba15bbe31c5bdBrian Paul span->blue += leftClip * span->blueStep; 779a61dce363929bbc3520f91cefa3ba15bbe31c5bdBrian Paul span->alpha += leftClip * span->alphaStep; 780a61dce363929bbc3520f91cefa3ba15bbe31c5bdBrian Paul span->index += leftClip * span->indexStep; 781a61dce363929bbc3520f91cefa3ba15bbe31c5bdBrian Paul span->z += leftClip * span->zStep; 782a61dce363929bbc3520f91cefa3ba15bbe31c5bdBrian Paul span->intTex[0] += leftClip * span->intTexStep[0]; 783a61dce363929bbc3520f91cefa3ba15bbe31c5bdBrian Paul span->intTex[1] += leftClip * span->intTexStep[1]; 784a61dce363929bbc3520f91cefa3ba15bbe31c5bdBrian Paul 785a61dce363929bbc3520f91cefa3ba15bbe31c5bdBrian Paul#define SHIFT_ARRAY(ARRAY, SHIFT, LEN) \ 786a44d715d2b19dc2f8f48b01144cc38e4e2c5015aBrian Paul memmove(ARRAY, ARRAY + (SHIFT), (LEN) * sizeof(ARRAY[0])) 787a61dce363929bbc3520f91cefa3ba15bbe31c5bdBrian Paul 788a61dce363929bbc3520f91cefa3ba15bbe31c5bdBrian Paul for (i = 0; i < FRAG_ATTRIB_MAX; i++) { 7896a3004b9ae58dafd1ce995df78b0f3183827a59dBrian Paul if (span->arrayAttribs & (1 << i)) { 7906a3004b9ae58dafd1ce995df78b0f3183827a59dBrian Paul /* shift array elements left by 'leftClip' */ 791a61dce363929bbc3520f91cefa3ba15bbe31c5bdBrian Paul SHIFT_ARRAY(span->array->attribs[i], leftClip, n - leftClip); 7926a3004b9ae58dafd1ce995df78b0f3183827a59dBrian Paul } 7936a3004b9ae58dafd1ce995df78b0f3183827a59dBrian Paul } 7946a3004b9ae58dafd1ce995df78b0f3183827a59dBrian Paul 795a61dce363929bbc3520f91cefa3ba15bbe31c5bdBrian Paul SHIFT_ARRAY(span->array->mask, leftClip, n - leftClip); 796a61dce363929bbc3520f91cefa3ba15bbe31c5bdBrian Paul SHIFT_ARRAY(span->array->rgba8, leftClip, n - leftClip); 797a61dce363929bbc3520f91cefa3ba15bbe31c5bdBrian Paul SHIFT_ARRAY(span->array->rgba16, leftClip, n - leftClip); 798a61dce363929bbc3520f91cefa3ba15bbe31c5bdBrian Paul SHIFT_ARRAY(span->array->x, leftClip, n - leftClip); 799a61dce363929bbc3520f91cefa3ba15bbe31c5bdBrian Paul SHIFT_ARRAY(span->array->y, leftClip, n - leftClip); 800a61dce363929bbc3520f91cefa3ba15bbe31c5bdBrian Paul SHIFT_ARRAY(span->array->z, leftClip, n - leftClip); 801a61dce363929bbc3520f91cefa3ba15bbe31c5bdBrian Paul SHIFT_ARRAY(span->array->index, leftClip, n - leftClip); 802a61dce363929bbc3520f91cefa3ba15bbe31c5bdBrian Paul for (i = 0; i < MAX_TEXTURE_COORD_UNITS; i++) { 803a61dce363929bbc3520f91cefa3ba15bbe31c5bdBrian Paul SHIFT_ARRAY(span->array->lambda[i], leftClip, n - leftClip); 804a61dce363929bbc3520f91cefa3ba15bbe31c5bdBrian Paul } 805a61dce363929bbc3520f91cefa3ba15bbe31c5bdBrian Paul SHIFT_ARRAY(span->array->coverage, leftClip, n - leftClip); 806a61dce363929bbc3520f91cefa3ba15bbe31c5bdBrian Paul 807a61dce363929bbc3520f91cefa3ba15bbe31c5bdBrian Paul#undef SHIFT_ARRAY 808a61dce363929bbc3520f91cefa3ba15bbe31c5bdBrian Paul 8096a3004b9ae58dafd1ce995df78b0f3183827a59dBrian Paul span->leftClip = leftClip; 8106a3004b9ae58dafd1ce995df78b0f3183827a59dBrian Paul span->x = xmin; 8116a3004b9ae58dafd1ce995df78b0f3183827a59dBrian Paul span->end -= leftClip; 812733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->writeAll = GL_FALSE; 81310f30eb43835c57c00783390a02d72daf4f78e26Brian Paul } 814733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul 8156a3004b9ae58dafd1ce995df78b0f3183827a59dBrian Paul ASSERT(span->x >= xmin); 8166a3004b9ae58dafd1ce995df78b0f3183827a59dBrian Paul ASSERT(span->x + span->end <= xmax); 8176a3004b9ae58dafd1ce995df78b0f3183827a59dBrian Paul ASSERT(span->y >= ymin); 8186a3004b9ae58dafd1ce995df78b0f3183827a59dBrian Paul ASSERT(span->y < ymax); 81910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 820733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul return GL_TRUE; /* some pixels visible */ 821733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul } 82210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul} 82310f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 82410f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 82579c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/** 8269e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian * Add specular colors to primary colors. 8279e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian * Only called during fixed-function operation. 8289e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian * Result is float color array (FRAG_ATTRIB_COL0). 829e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */ 8309520f483b8f1e45fa474674b415554988de5d8d3Brian Paulstatic inline void 831f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergadd_specular(struct gl_context *ctx, SWspan *span) 832e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell{ 8339e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian const SWcontext *swrast = SWRAST_CONTEXT(ctx); 8349e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian const GLubyte *mask = span->array->mask; 8359e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian GLfloat (*col0)[4] = span->array->attribs[FRAG_ATTRIB_COL0]; 8369e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian GLfloat (*col1)[4] = span->array->attribs[FRAG_ATTRIB_COL1]; 8379e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian GLuint i; 8389e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian 8391c0f1dd42a50464eeb81de4aad8eecf24b3d6c89Chad Versace ASSERT(!_swrast_use_fragment_program(ctx)); 8409e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian ASSERT(span->arrayMask & SPAN_RGBA); 8419e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian ASSERT(swrast->_ActiveAttribMask & FRAG_BIT_COL1); 8429d216be8cfe57f88cd2d890c2334df8ff5c30436Brian Paul (void) swrast; /* silence warning */ 8439e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian 8449e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian if (span->array->ChanType == GL_FLOAT) { 8459e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian if ((span->arrayAttribs & FRAG_BIT_COL0) == 0) { 8469e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian interpolate_active_attribs(ctx, span, FRAG_BIT_COL0); 847d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul } 8489e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian } 8499e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian else { 8509e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian /* need float colors */ 8519e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian if ((span->arrayAttribs & FRAG_BIT_COL0) == 0) { 8529e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian interpolate_float_colors(span); 853d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul } 8549e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian } 8559e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian 8569e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian if ((span->arrayAttribs & FRAG_BIT_COL1) == 0) { 8579e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian /* XXX could avoid this and interpolate COL1 in the loop below */ 8589e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian interpolate_active_attribs(ctx, span, FRAG_BIT_COL1); 8599e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian } 8609e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian 8619e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian ASSERT(span->arrayAttribs & FRAG_BIT_COL0); 8629e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian ASSERT(span->arrayAttribs & FRAG_BIT_COL1); 8639e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian 8649e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian for (i = 0; i < span->end; i++) { 8659e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian if (mask[i]) { 8669e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian col0[i][0] += col1[i][0]; 8679e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian col0[i][1] += col1[i][1]; 8689e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian col0[i][2] += col1[i][2]; 869d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul } 870e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 8719e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian 8729e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian span->array->ChanType = GL_FLOAT; 873e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell} 874e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 875e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 87679c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/** 877b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul * Apply antialiasing coverage value to alpha values. 878b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul */ 8799520f483b8f1e45fa474674b415554988de5d8d3Brian Paulstatic inline void 880b88af5b4681d2085cd784b930dc259b66a55347eBrian Paulapply_aa_coverage(SWspan *span) 881b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul{ 882b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul const GLfloat *coverage = span->array->coverage; 883b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul GLuint i; 884b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul if (span->array->ChanType == GL_UNSIGNED_BYTE) { 8859e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian GLubyte (*rgba)[4] = span->array->rgba8; 886b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul for (i = 0; i < span->end; i++) { 887e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul const GLfloat a = rgba[i][ACOMP] * coverage[i]; 888e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul rgba[i][ACOMP] = (GLubyte) CLAMP(a, 0.0, 255.0); 889b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul ASSERT(coverage[i] >= 0.0); 890b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul ASSERT(coverage[i] <= 1.0); 891b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul } 892b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul } 893b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul else if (span->array->ChanType == GL_UNSIGNED_SHORT) { 8949e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian GLushort (*rgba)[4] = span->array->rgba16; 895b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul for (i = 0; i < span->end; i++) { 896e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul const GLfloat a = rgba[i][ACOMP] * coverage[i]; 897e9d7190bb2b1bf3a057e27ecd7e79302360961a1Brian Paul rgba[i][ACOMP] = (GLushort) CLAMP(a, 0.0, 65535.0); 898b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul } 899b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul } 900b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul else { 901f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian GLfloat (*rgba)[4] = span->array->attribs[FRAG_ATTRIB_COL0]; 902b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul for (i = 0; i < span->end; i++) { 903b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul rgba[i][ACOMP] = rgba[i][ACOMP] * coverage[i]; 9049e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian /* clamp later */ 905b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul } 906b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul } 907b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul} 908b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul 909b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul 910b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul/** 91131293910b4e982f2ef54d79aff78f2f854121da1Brian Paul * Clamp span's float colors to [0,1] 91231293910b4e982f2ef54d79aff78f2f854121da1Brian Paul */ 9139520f483b8f1e45fa474674b415554988de5d8d3Brian Paulstatic inline void 91431293910b4e982f2ef54d79aff78f2f854121da1Brian Paulclamp_colors(SWspan *span) 91531293910b4e982f2ef54d79aff78f2f854121da1Brian Paul{ 916f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian GLfloat (*rgba)[4] = span->array->attribs[FRAG_ATTRIB_COL0]; 91731293910b4e982f2ef54d79aff78f2f854121da1Brian Paul GLuint i; 91831293910b4e982f2ef54d79aff78f2f854121da1Brian Paul ASSERT(span->array->ChanType == GL_FLOAT); 91931293910b4e982f2ef54d79aff78f2f854121da1Brian Paul for (i = 0; i < span->end; i++) { 92031293910b4e982f2ef54d79aff78f2f854121da1Brian Paul rgba[i][RCOMP] = CLAMP(rgba[i][RCOMP], 0.0F, 1.0F); 92131293910b4e982f2ef54d79aff78f2f854121da1Brian Paul rgba[i][GCOMP] = CLAMP(rgba[i][GCOMP], 0.0F, 1.0F); 92231293910b4e982f2ef54d79aff78f2f854121da1Brian Paul rgba[i][BCOMP] = CLAMP(rgba[i][BCOMP], 0.0F, 1.0F); 92331293910b4e982f2ef54d79aff78f2f854121da1Brian Paul rgba[i][ACOMP] = CLAMP(rgba[i][ACOMP], 0.0F, 1.0F); 92431293910b4e982f2ef54d79aff78f2f854121da1Brian Paul } 92531293910b4e982f2ef54d79aff78f2f854121da1Brian Paul} 92631293910b4e982f2ef54d79aff78f2f854121da1Brian Paul 92731293910b4e982f2ef54d79aff78f2f854121da1Brian Paul 92831293910b4e982f2ef54d79aff78f2f854121da1Brian Paul/** 929d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul * Convert the span's color arrays to the given type. 930ff73c783cc47361ff0dd819c82d067b4b85870ddBrian * The only way 'output' can be greater than zero is when we have a fragment 9311c09bcfdda4083636a3ac27d804a34ef87875ce7Brian * program that writes to gl_FragData[1] or higher. 9321c09bcfdda4083636a3ac27d804a34ef87875ce7Brian * \param output which fragment program color output is being processed 933d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul */ 9349520f483b8f1e45fa474674b415554988de5d8d3Brian Paulstatic inline void 9351c09bcfdda4083636a3ac27d804a34ef87875ce7Brianconvert_color_type(SWspan *span, GLenum newType, GLuint output) 936d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul{ 937f971e24cf0341dd2779196a0836327b74fc82336Brian Paul GLvoid *src, *dst; 9381c09bcfdda4083636a3ac27d804a34ef87875ce7Brian 9391c09bcfdda4083636a3ac27d804a34ef87875ce7Brian if (output > 0 || span->array->ChanType == GL_FLOAT) { 9401c09bcfdda4083636a3ac27d804a34ef87875ce7Brian src = span->array->attribs[FRAG_ATTRIB_COL0 + output]; 9411c09bcfdda4083636a3ac27d804a34ef87875ce7Brian span->array->ChanType = GL_FLOAT; 942f971e24cf0341dd2779196a0836327b74fc82336Brian Paul } 943f971e24cf0341dd2779196a0836327b74fc82336Brian Paul else if (span->array->ChanType == GL_UNSIGNED_BYTE) { 9449e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian src = span->array->rgba8; 945f971e24cf0341dd2779196a0836327b74fc82336Brian Paul } 946f971e24cf0341dd2779196a0836327b74fc82336Brian Paul else { 9471c09bcfdda4083636a3ac27d804a34ef87875ce7Brian ASSERT(span->array->ChanType == GL_UNSIGNED_SHORT); 9489e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian src = span->array->rgba16; 949f971e24cf0341dd2779196a0836327b74fc82336Brian Paul } 9501c09bcfdda4083636a3ac27d804a34ef87875ce7Brian 951f971e24cf0341dd2779196a0836327b74fc82336Brian Paul if (newType == GL_UNSIGNED_BYTE) { 9529e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian dst = span->array->rgba8; 953f971e24cf0341dd2779196a0836327b74fc82336Brian Paul } 9541c09bcfdda4083636a3ac27d804a34ef87875ce7Brian else if (newType == GL_UNSIGNED_SHORT) { 9559e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian dst = span->array->rgba16; 956f971e24cf0341dd2779196a0836327b74fc82336Brian Paul } 957f971e24cf0341dd2779196a0836327b74fc82336Brian Paul else { 958f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian dst = span->array->attribs[FRAG_ATTRIB_COL0]; 959f971e24cf0341dd2779196a0836327b74fc82336Brian Paul } 960d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul 961f971e24cf0341dd2779196a0836327b74fc82336Brian Paul _mesa_convert_colors(span->array->ChanType, src, 962f971e24cf0341dd2779196a0836327b74fc82336Brian Paul newType, dst, 963f971e24cf0341dd2779196a0836327b74fc82336Brian Paul span->end, span->array->mask); 964d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul 965d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul span->array->ChanType = newType; 96693becd8a18f6ccf2f86e506ee36fc0bb75787c29Brian span->array->rgba = dst; 967d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul} 968d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul 969d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul 970d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul 971d92da49bae30be612efb6ea20bdfda232ee3d01dBrian Paul/** 97261c89be3135cedc795e48d36283769298e250837Brian Paul * Apply fragment shader, fragment program or normal texturing to span. 97361c89be3135cedc795e48d36283769298e250837Brian Paul */ 9749520f483b8f1e45fa474674b415554988de5d8d3Brian Paulstatic inline void 975f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergshade_texture_span(struct gl_context *ctx, SWspan *span) 97661c89be3135cedc795e48d36283769298e250837Brian Paul{ 9771c0f1dd42a50464eeb81de4aad8eecf24b3d6c89Chad Versace if (_swrast_use_fragment_program(ctx) || 97861c89be3135cedc795e48d36283769298e250837Brian Paul ctx->ATIFragmentShader._Enabled) { 9799e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian /* programmable shading */ 980171dcdfa27dda30916a7f9bfed89577feee5d350Brian if (span->primitive == GL_BITMAP && span->array->ChanType != GL_FLOAT) { 981171dcdfa27dda30916a7f9bfed89577feee5d350Brian convert_color_type(span, GL_FLOAT, 0); 982b9080dd5493eb23af6c5c494550c7b1cb481ca7bBrian } 983c8e714df013cdf360602f9cc96d26cb732b19a32M.Froehlich@science-computing.de else { 984c8e714df013cdf360602f9cc96d26cb732b19a32M.Froehlich@science-computing.de span->array->rgba = (void *) span->array->attribs[FRAG_ATTRIB_COL0]; 985c8e714df013cdf360602f9cc96d26cb732b19a32M.Froehlich@science-computing.de } 986c8e714df013cdf360602f9cc96d26cb732b19a32M.Froehlich@science-computing.de 987bff94a91c6852157a8251652cb61dc699cd8e4f1Xiang, Haihao if (span->primitive != GL_POINT || 988bff94a91c6852157a8251652cb61dc699cd8e4f1Xiang, Haihao (span->interpMask & SPAN_RGBA) || 989bff94a91c6852157a8251652cb61dc699cd8e4f1Xiang, Haihao ctx->Point.PointSprite) { 990bff94a91c6852157a8251652cb61dc699cd8e4f1Xiang, Haihao /* for single-pixel points, we populated the arrays already */ 9911d52b6aaf41b32aaf8d1cdf5a3cd5ff4ecba28f4Brian interpolate_active_attribs(ctx, span, ~0); 9921d52b6aaf41b32aaf8d1cdf5a3cd5ff4ecba28f4Brian } 9939e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian span->array->ChanType = GL_FLOAT; 99461c89be3135cedc795e48d36283769298e250837Brian Paul 9959e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian if (!(span->arrayMask & SPAN_Z)) 99661c89be3135cedc795e48d36283769298e250837Brian Paul _swrast_span_interpolate_z (ctx, span); 99761c89be3135cedc795e48d36283769298e250837Brian Paul 99860d136f63c5a5a18b12952ec8e8532cbce086a4dBrian#if 0 999c000843a14e73d593d87ff6674d0295d2cb64a12Brian if (inputsRead & FRAG_BIT_WPOS) 100060d136f63c5a5a18b12952ec8e8532cbce086a4dBrian#else 100160d136f63c5a5a18b12952ec8e8532cbce086a4dBrian /* XXX always interpolate wpos so that DDX/DDY work */ 100260d136f63c5a5a18b12952ec8e8532cbce086a4dBrian#endif 1003f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian interpolate_wpos(ctx, span); 1004f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian 100512ef1fbefcee964b715783d3ade6b69b2c699ed8Brian /* Run fragment program/shader now */ 10061c0f1dd42a50464eeb81de4aad8eecf24b3d6c89Chad Versace if (_swrast_use_fragment_program(ctx)) { 100761c89be3135cedc795e48d36283769298e250837Brian Paul _swrast_exec_fragment_program(ctx, span); 100861c89be3135cedc795e48d36283769298e250837Brian Paul } 100961c89be3135cedc795e48d36283769298e250837Brian Paul else { 101061c89be3135cedc795e48d36283769298e250837Brian Paul ASSERT(ctx->ATIFragmentShader._Enabled); 101161c89be3135cedc795e48d36283769298e250837Brian Paul _swrast_exec_fragment_shader(ctx, span); 101261c89be3135cedc795e48d36283769298e250837Brian Paul } 101361c89be3135cedc795e48d36283769298e250837Brian Paul } 101407e50058a5699fc9279de6bf5d1449d52ccdc476Brian Paul else if (ctx->Texture._EnabledCoordUnits) { 101561c89be3135cedc795e48d36283769298e250837Brian Paul /* conventional texturing */ 10169e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian 10179e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian#if CHAN_BITS == 32 10189e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian if ((span->arrayAttribs & FRAG_BIT_COL0) == 0) { 10199e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian interpolate_int_colors(ctx, span); 10209e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian } 10219e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian#else 10229e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian if (!(span->arrayMask & SPAN_RGBA)) 10239e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian interpolate_int_colors(ctx, span); 10249e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian#endif 10259e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian if ((span->arrayAttribs & FRAG_BITS_TEX_ANY) == 0x0) 10269e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian interpolate_texcoords(ctx, span); 10279e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian 102861c89be3135cedc795e48d36283769298e250837Brian Paul _swrast_texture_span(ctx, span); 102961c89be3135cedc795e48d36283769298e250837Brian Paul } 103061c89be3135cedc795e48d36283769298e250837Brian Paul} 103161c89be3135cedc795e48d36283769298e250837Brian Paul 103261c89be3135cedc795e48d36283769298e250837Brian Paul 10330ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul/** Put colors at x/y locations into a renderbuffer */ 10340ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paulstatic void 10350ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paulput_values(struct gl_context *ctx, struct gl_renderbuffer *rb, 1036f9874feef4d8952df5054bd8e8f4e0deda4ef44fBrian Paul GLenum datatype, 10370ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul GLuint count, const GLint x[], const GLint y[], 10380ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul const void *values, const GLubyte *mask) 10390ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul{ 104088e7f56dd7130077494ff36b9765dd48cd3d4a91Brian Paul gl_pack_ubyte_rgba_func pack_ubyte = NULL; 104188e7f56dd7130077494ff36b9765dd48cd3d4a91Brian Paul gl_pack_float_rgba_func pack_float = NULL; 10420ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul GLuint i; 10430ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul 1044881ef2a9db22cff4c7d07b873d23b0c324da555aBrian Paul if (datatype == GL_UNSIGNED_BYTE) 1045881ef2a9db22cff4c7d07b873d23b0c324da555aBrian Paul pack_ubyte = _mesa_get_pack_ubyte_rgba_function(rb->Format); 1046881ef2a9db22cff4c7d07b873d23b0c324da555aBrian Paul else 1047881ef2a9db22cff4c7d07b873d23b0c324da555aBrian Paul pack_float = _mesa_get_pack_float_rgba_function(rb->Format); 1048881ef2a9db22cff4c7d07b873d23b0c324da555aBrian Paul 10490ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul for (i = 0; i < count; i++) { 10500ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul if (mask[i]) { 10510ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul GLubyte *dst = _swrast_pixel_address(rb, x[i], y[i]); 10520ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul 1053f9874feef4d8952df5054bd8e8f4e0deda4ef44fBrian Paul if (datatype == GL_UNSIGNED_BYTE) { 1054881ef2a9db22cff4c7d07b873d23b0c324da555aBrian Paul pack_ubyte((const GLubyte *) values + 4 * i, dst); 10550ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul } 10560ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul else { 1057f9874feef4d8952df5054bd8e8f4e0deda4ef44fBrian Paul assert(datatype == GL_FLOAT); 1058881ef2a9db22cff4c7d07b873d23b0c324da555aBrian Paul pack_float((const GLfloat *) values + 4 * i, dst); 10590ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul } 10600ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul } 10610ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul } 10620ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul} 10630ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul 10640ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul 10650ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul/** Put row of colors into renderbuffer */ 10660ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paulvoid 10670ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul_swrast_put_row(struct gl_context *ctx, struct gl_renderbuffer *rb, 1068f9874feef4d8952df5054bd8e8f4e0deda4ef44fBrian Paul GLenum datatype, 10690ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul GLuint count, GLint x, GLint y, 10700ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul const void *values, const GLubyte *mask) 10710ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul{ 10720ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul GLubyte *dst = _swrast_pixel_address(rb, x, y); 10730ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul 10740ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul if (!mask) { 1075f9874feef4d8952df5054bd8e8f4e0deda4ef44fBrian Paul if (datatype == GL_UNSIGNED_BYTE) { 10760ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul _mesa_pack_ubyte_rgba_row(rb->Format, count, 10770ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul (const GLubyte (*)[4]) values, dst); 10780ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul } 10790ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul else { 1080f9874feef4d8952df5054bd8e8f4e0deda4ef44fBrian Paul assert(datatype == GL_FLOAT); 10810ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul _mesa_pack_float_rgba_row(rb->Format, count, 10820ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul (const GLfloat (*)[4]) values, dst); 10830ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul } 10840ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul } 10850ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul else { 10860ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul const GLuint bpp = _mesa_get_format_bytes(rb->Format); 10870ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul GLuint i, runLen, runStart; 10880ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul /* We can't pass a 'mask' array to the _mesa_pack_rgba_row() functions 10890ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul * so look for runs where mask=1... 10900ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul */ 1091ba151a333be7a23266b23ee6f65669bb19221546Brian Paul runLen = runStart = 0; 10920ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul for (i = 0; i < count; i++) { 10930ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul if (mask[i]) { 10940ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul if (runLen == 0) 10950ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul runStart = i; 10960ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul runLen++; 10970ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul } 10980ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul 10990ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul if (!mask[i] || i == count - 1) { 11000ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul /* might be the end of a run of pixels */ 11010ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul if (runLen > 0) { 1102f9874feef4d8952df5054bd8e8f4e0deda4ef44fBrian Paul if (datatype == GL_UNSIGNED_BYTE) { 11030ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul _mesa_pack_ubyte_rgba_row(rb->Format, runLen, 11040ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul (const GLubyte (*)[4]) values + runStart, 11050ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul dst + runStart * bpp); 11060ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul } 11070ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul else { 1108f9874feef4d8952df5054bd8e8f4e0deda4ef44fBrian Paul assert(datatype == GL_FLOAT); 11090ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul _mesa_pack_float_rgba_row(rb->Format, runLen, 11100ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul (const GLfloat (*)[4]) values + runStart, 11110ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul dst + runStart * bpp); 11120ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul } 11130ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul runLen = 0; 11140ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul } 11150ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul } 11160ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul } 11170ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul } 11180ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul} 11190ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul 11200ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul 112161c89be3135cedc795e48d36283769298e250837Brian Paul 112261c89be3135cedc795e48d36283769298e250837Brian Paul/** 1123a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul * Apply all the per-fragment operations to a span. 1124a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul * This now includes texturing (_swrast_write_texture_span() is history). 1125f1e236987829393c81dc86ea19cb49eefe190317Brian Paul * This function may modify any of the array values in the span. 11267956292a765910077f50352d7cd0174e1e66d26cBrian Paul * span->interpMask and span->arrayMask may be changed but will be restored 11277956292a765910077f50352d7cd0174e1e66d26cBrian Paul * to their original values before returning. 112878940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul */ 112978940758e90069ceaca2b6cddb6438488fbad5ccBrian Paulvoid 1130f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg_swrast_write_rgba_span( struct gl_context *ctx, SWspan *span) 113178940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul{ 113261c89be3135cedc795e48d36283769298e250837Brian Paul const SWcontext *swrast = SWRAST_CONTEXT(ctx); 1133fd5511d27fc44096117c47ab503fb5b47f993061Brian Paul const GLuint *colorMask = (GLuint *) ctx->Color.ColorMask; 1134e00ac11d4dd05c56584622dc2707bbdcfe4b2707Brian Paul const GLbitfield origInterpMask = span->interpMask; 1135e00ac11d4dd05c56584622dc2707bbdcfe4b2707Brian Paul const GLbitfield origArrayMask = span->arrayMask; 11368dffb6bdab25dcacf165851e9d1fdb3beb73099aBrian Paul const GLbitfield64 origArrayAttribs = span->arrayAttribs; 113793becd8a18f6ccf2f86e506ee36fc0bb75787c29Brian const GLenum origChanType = span->array->ChanType; 113893becd8a18f6ccf2f86e506ee36fc0bb75787c29Brian void * const origRgba = span->array->rgba; 11391c0f1dd42a50464eeb81de4aad8eecf24b3d6c89Chad Versace const GLboolean shader = (_swrast_use_fragment_program(ctx) 114012ef1fbefcee964b715783d3ade6b69b2c699ed8Brian || ctx->ATIFragmentShader._Enabled); 114107e50058a5699fc9279de6bf5d1449d52ccdc476Brian Paul const GLboolean shaderOrTexture = shader || ctx->Texture._EnabledCoordUnits; 11421c09bcfdda4083636a3ac27d804a34ef87875ce7Brian struct gl_framebuffer *fb = ctx->DrawBuffer; 114361c89be3135cedc795e48d36283769298e250837Brian Paul 1144bb19e64d12eaf27e2adc3faac7e09555bb66d724Brian Paul /* 1145bb19e64d12eaf27e2adc3faac7e09555bb66d724Brian Paul printf("%s() interp 0x%x array 0x%x\n", __FUNCTION__, 1146bb19e64d12eaf27e2adc3faac7e09555bb66d724Brian Paul span->interpMask, span->arrayMask); 1147bb19e64d12eaf27e2adc3faac7e09555bb66d724Brian Paul */ 1148f1e236987829393c81dc86ea19cb49eefe190317Brian Paul 114931293910b4e982f2ef54d79aff78f2f854121da1Brian Paul ASSERT(span->primitive == GL_POINT || 115031293910b4e982f2ef54d79aff78f2f854121da1Brian Paul span->primitive == GL_LINE || 115131293910b4e982f2ef54d79aff78f2f854121da1Brian Paul span->primitive == GL_POLYGON || 115231293910b4e982f2ef54d79aff78f2f854121da1Brian Paul span->primitive == GL_BITMAP); 1153ceb39f4f8dc4863fde17d668c752533a2184476eBrian Paul 1154bb19e64d12eaf27e2adc3faac7e09555bb66d724Brian Paul /* Fragment write masks */ 1155733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul if (span->arrayMask & SPAN_MASK) { 1156733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul /* mask was initialized by caller, probably glBitmap */ 1157733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->writeAll = GL_FALSE; 1158733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul } 1159733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul else { 116026f8fad1456fdc2b352cea9d3b4c32cb5f6ae947Kenneth Graunke memset(span->array->mask, 1, span->end); 1161733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul span->writeAll = GL_TRUE; 116278940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul } 116378940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul 1164a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul /* Clip to window/scissor box */ 1165f25e1007c2da21dc529811e9e1f4b4da6bda8be4Brian Paul if (!clip_span(ctx, span)) { 1166f25e1007c2da21dc529811e9e1f4b4da6bda8be4Brian Paul return; 116778940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul } 116878940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul 116947d88ef204b42a9220c6be3e98c92df9c9aa0860Brian Paul ASSERT(span->end <= SWRAST_MAX_WIDTH); 1170f25e1007c2da21dc529811e9e1f4b4da6bda8be4Brian Paul 11712c5aa02e2086f5e79630cdffec804a3e9de0d966Brian Paul /* Depth bounds test */ 11722c5aa02e2086f5e79630cdffec804a3e9de0d966Brian Paul if (ctx->Depth.BoundsTest && fb->Visual.depthBits > 0) { 11732c5aa02e2086f5e79630cdffec804a3e9de0d966Brian Paul if (!_swrast_depth_bounds_test(ctx, span)) { 11742c5aa02e2086f5e79630cdffec804a3e9de0d966Brian Paul return; 11752c5aa02e2086f5e79630cdffec804a3e9de0d966Brian Paul } 11762c5aa02e2086f5e79630cdffec804a3e9de0d966Brian Paul } 11772c5aa02e2086f5e79630cdffec804a3e9de0d966Brian Paul 1178b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul#ifdef DEBUG 1179a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul /* Make sure all fragments are within window bounds */ 1180b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul if (span->arrayMask & SPAN_XY) { 11816a3004b9ae58dafd1ce995df78b0f3183827a59dBrian Paul /* array of pixel locations */ 1182a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul GLuint i; 1183b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul for (i = 0; i < span->end; i++) { 118477df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul if (span->array->mask[i]) { 11851c09bcfdda4083636a3ac27d804a34ef87875ce7Brian assert(span->array->x[i] >= fb->_Xmin); 11861c09bcfdda4083636a3ac27d804a34ef87875ce7Brian assert(span->array->x[i] < fb->_Xmax); 11871c09bcfdda4083636a3ac27d804a34ef87875ce7Brian assert(span->array->y[i] >= fb->_Ymin); 11881c09bcfdda4083636a3ac27d804a34ef87875ce7Brian assert(span->array->y[i] < fb->_Ymax); 1189b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul } 1190b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul } 1191b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul } 1192b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul#endif 1193b37a084357dd08573b86d6d8c5ba43d65bdc1bd7Brian Paul 119478940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul /* Polygon Stippling */ 1195b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul if (ctx->Polygon.StippleFlag && span->primitive == GL_POLYGON) { 1196733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul stipple_polygon_span(ctx, span); 119778940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul } 119878940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul 11999e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian /* This is the normal place to compute the fragment color/Z 12009e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian * from texturing or shading. 1201a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul */ 12029e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian if (shaderOrTexture && !swrast->_DeferredTexture) { 120361c89be3135cedc795e48d36283769298e250837Brian Paul shade_texture_span(ctx, span); 120461c89be3135cedc795e48d36283769298e250837Brian Paul } 1205c3caaa3dd45809e672177ab322445fe51d03af25Brian Paul 120661c89be3135cedc795e48d36283769298e250837Brian Paul /* Do the alpha test */ 120761c89be3135cedc795e48d36283769298e250837Brian Paul if (ctx->Color.AlphaEnabled) { 120861c89be3135cedc795e48d36283769298e250837Brian Paul if (!_swrast_alpha_test(ctx, span)) { 12098962bac0a1e422afcd034f4ce00d45d8f3df46bfBrian Paul /* all fragments failed test */ 121061c89be3135cedc795e48d36283769298e250837Brian Paul goto end; 121178940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul } 121278940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul } 121378940758e90069ceaca2b6cddb6438488fbad5ccBrian Paul 1214f1e236987829393c81dc86ea19cb49eefe190317Brian Paul /* Stencil and Z testing */ 121591e61f435a71436c209934a0ece165b540aba3e0Brian Paul if (ctx->Stencil._Enabled || ctx->Depth.Test) { 12169e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian if (!(span->arrayMask & SPAN_Z)) 121745bc887da226403f2c41077e40ca38b6f60f1359Brian Paul _swrast_span_interpolate_z(ctx, span); 121832ec3f26731ac998b6fda7ce596ec568d6f76eebEric Anholt 121932ec3f26731ac998b6fda7ce596ec568d6f76eebEric Anholt if (ctx->Transform.DepthClamp) 122032ec3f26731ac998b6fda7ce596ec568d6f76eebEric Anholt _swrast_depth_clamp_span(ctx, span); 122132ec3f26731ac998b6fda7ce596ec568d6f76eebEric Anholt 122291e61f435a71436c209934a0ece165b540aba3e0Brian Paul if (ctx->Stencil._Enabled) { 1223a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul /* Combined Z/stencil tests */ 122445bc887da226403f2c41077e40ca38b6f60f1359Brian Paul if (!_swrast_stencil_and_ztest_span(ctx, span)) { 12258962bac0a1e422afcd034f4ce00d45d8f3df46bfBrian Paul /* all fragments failed test */ 1226c3caaa3dd45809e672177ab322445fe51d03af25Brian Paul goto end; 1227f1e236987829393c81dc86ea19cb49eefe190317Brian Paul } 122871340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 12291c09bcfdda4083636a3ac27d804a34ef87875ce7Brian else if (fb->Visual.depthBits > 0) { 1230a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul /* Just regular depth testing */ 1231f1e236987829393c81dc86ea19cb49eefe190317Brian Paul ASSERT(ctx->Depth.Test); 1232f1e236987829393c81dc86ea19cb49eefe190317Brian Paul ASSERT(span->arrayMask & SPAN_Z); 123345bc887da226403f2c41077e40ca38b6f60f1359Brian Paul if (!_swrast_depth_test_span(ctx, span)) { 12348962bac0a1e422afcd034f4ce00d45d8f3df46bfBrian Paul /* all fragments failed test */ 1235c3caaa3dd45809e672177ab322445fe51d03af25Brian Paul goto end; 1236f1e236987829393c81dc86ea19cb49eefe190317Brian Paul } 123771340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 123871340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 123971340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul 124023ffc3a85d6172f8a98d17d7f23610bab808d84eBrian Paul if (ctx->Query.CurrentOcclusionObject) { 1241939dd17653245621bf7488803f09418244b7b0b7Brian Paul /* update count of 'passed' fragments */ 124223ffc3a85d6172f8a98d17d7f23610bab808d84eBrian Paul struct gl_query_object *q = ctx->Query.CurrentOcclusionObject; 1243b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul GLuint i; 1244b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul for (i = 0; i < span->end; i++) 124523ffc3a85d6172f8a98d17d7f23610bab808d84eBrian Paul q->Result += span->array->mask[i]; 1246b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul } 1247b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul 1248a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul /* We had to wait until now to check for glColorMask(0,0,0,0) because of 1249f1e236987829393c81dc86ea19cb49eefe190317Brian Paul * the occlusion test. 1250f1e236987829393c81dc86ea19cb49eefe190317Brian Paul */ 1251fd5511d27fc44096117c47ab503fb5b47f993061Brian Paul if (fb->_NumColorDrawBuffers == 1 && colorMask[0] == 0x0) { 12528962bac0a1e422afcd034f4ce00d45d8f3df46bfBrian Paul /* no colors to write */ 1253c3caaa3dd45809e672177ab322445fe51d03af25Brian Paul goto end; 125471340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 125571340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul 125632340aea1308153dad5c105fc0748aea1e4c37eeBrian Paul /* If we were able to defer fragment color computation to now, there's 125732340aea1308153dad5c105fc0748aea1e4c37eeBrian Paul * a good chance that many fragments will have already been killed by 125832340aea1308153dad5c105fc0748aea1e4c37eeBrian Paul * Z/stencil testing. 1259a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul */ 12609e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian if (shaderOrTexture && swrast->_DeferredTexture) { 126161c89be3135cedc795e48d36283769298e250837Brian Paul shade_texture_span(ctx, span); 126261c89be3135cedc795e48d36283769298e250837Brian Paul } 1263d09df24082d69e534470f9a5f667b30c34ae6d74Brian Paul 12649e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian#if CHAN_BITS == 32 12659e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian if ((span->arrayAttribs & FRAG_BIT_COL0) == 0) { 126651b728cf9aff383142a2a1e220a7d8963d1ca189Brian interpolate_active_attribs(ctx, span, FRAG_BIT_COL0); 12679e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian } 12689e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian#else 126961c89be3135cedc795e48d36283769298e250837Brian Paul if ((span->arrayMask & SPAN_RGBA) == 0) { 12709e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian interpolate_int_colors(ctx, span); 127171340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 12729e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian#endif 127371340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul 1274f1e236987829393c81dc86ea19cb49eefe190317Brian Paul ASSERT(span->arrayMask & SPAN_RGBA); 12752ef866d1fc0a5cc5ef8543d65744dfd4da4dbbafBrian Paul 127676ac75af8e5481b498981c133836efa2101be2dcBrian Paul if (span->primitive == GL_BITMAP || !swrast->SpecularVertexAdd) { 127776ac75af8e5481b498981c133836efa2101be2dcBrian Paul /* Add primary and specular (diffuse + specular) colors */ 12783e79d650835b3431464de876699d04702df99806Brian Paul if (!shader) { 12793e79d650835b3431464de876699d04702df99806Brian Paul if (ctx->Fog.ColorSumEnabled || 12803e79d650835b3431464de876699d04702df99806Brian Paul (ctx->Light.Enabled && 12813e79d650835b3431464de876699d04702df99806Brian Paul ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR)) { 12823e79d650835b3431464de876699d04702df99806Brian Paul add_specular(ctx, span); 12833e79d650835b3431464de876699d04702df99806Brian Paul } 128471340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 128571340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 128671340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul 12876e1666437ea091ecc50ab2b56d87129318f641d2Brian Paul /* Fog */ 128809da0b8e6621a831e3eeb9381430f2bed18a22adBrian Paul if (swrast->_FogEnabled) { 128945bc887da226403f2c41077e40ca38b6f60f1359Brian Paul _swrast_fog_rgba_span(ctx, span); 129071340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 1291f1e236987829393c81dc86ea19cb49eefe190317Brian Paul 129271340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul /* Antialias coverage application */ 12932a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul if (span->arrayMask & SPAN_COVERAGE) { 1294b88af5b4681d2085cd784b930dc259b66a55347eBrian Paul apply_aa_coverage(span); 129571340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul } 129671340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul 1297ba3da6154c324cc916845bc5de3de077d0b59ffcBrian Paul /* Clamp color/alpha values over the range [0.0, 1.0] before storage */ 12980b26e826bda0da7aeec9a79ee07fe21d54bb1263Brian Paul if (ctx->Color.ClampFragmentColor == GL_TRUE && 129931293910b4e982f2ef54d79aff78f2f854121da1Brian Paul span->array->ChanType == GL_FLOAT) { 130031293910b4e982f2ef54d79aff78f2f854121da1Brian Paul clamp_colors(span); 1301ba3da6154c324cc916845bc5de3de077d0b59ffcBrian Paul } 1302ba3da6154c324cc916845bc5de3de077d0b59ffcBrian Paul 1303ba001224a18fa12792696ef393e708e90092127eBrian Paul /* 13049cc79fc2dcdd8e21d9616cc65a931f1f5859fc30Brian Paul * Write to renderbuffers. 13059cc79fc2dcdd8e21d9616cc65a931f1f5859fc30Brian Paul * Depending on glDrawBuffer() state and the which color outputs are 13069cc79fc2dcdd8e21d9616cc65a931f1f5859fc30Brian Paul * written by the fragment shader, we may either replicate one color to 13079cc79fc2dcdd8e21d9616cc65a931f1f5859fc30Brian Paul * all renderbuffers or write a different color to each renderbuffer. 13089cc79fc2dcdd8e21d9616cc65a931f1f5859fc30Brian Paul * multiFragOutputs=TRUE for the later case. 1309ba001224a18fa12792696ef393e708e90092127eBrian Paul */ 1310ff73c783cc47361ff0dd819c82d067b4b85870ddBrian { 1311ff73c783cc47361ff0dd819c82d067b4b85870ddBrian const GLuint numBuffers = fb->_NumColorDrawBuffers; 13129cc79fc2dcdd8e21d9616cc65a931f1f5859fc30Brian Paul const struct gl_fragment_program *fp = ctx->FragmentProgram._Current; 13139cc79fc2dcdd8e21d9616cc65a931f1f5859fc30Brian Paul const GLboolean multiFragOutputs = 13141c0f1dd42a50464eeb81de4aad8eecf24b3d6c89Chad Versace _swrast_use_fragment_program(ctx) 13151c0f1dd42a50464eeb81de4aad8eecf24b3d6c89Chad Versace && fp->Base.OutputsWritten >= (1 << FRAG_RESULT_DATA0); 1316ff73c783cc47361ff0dd819c82d067b4b85870ddBrian GLuint buf; 1317ff73c783cc47361ff0dd819c82d067b4b85870ddBrian 1318ff73c783cc47361ff0dd819c82d067b4b85870ddBrian for (buf = 0; buf < numBuffers; buf++) { 1319ff73c783cc47361ff0dd819c82d067b4b85870ddBrian struct gl_renderbuffer *rb = fb->_ColorDrawBuffers[buf]; 1320ff73c783cc47361ff0dd819c82d067b4b85870ddBrian 1321ff73c783cc47361ff0dd819c82d067b4b85870ddBrian /* color[fragOutput] will be written to buffer[buf] */ 1322ff73c783cc47361ff0dd819c82d067b4b85870ddBrian 1323ff73c783cc47361ff0dd819c82d067b4b85870ddBrian if (rb) { 1324ed65c5ccc3d15c350965f669d6891813c0ba8bccBrian Paul /* re-use one of the attribute array buffers for rgbaSave */ 1325ed65c5ccc3d15c350965f669d6891813c0ba8bccBrian Paul GLchan (*rgbaSave)[4] = (GLchan (*)[4]) span->array->attribs[0]; 1326bd1ae51b13535bc4438c663ffe91ded49db4890aBrian Paul struct swrast_renderbuffer *srb = swrast_renderbuffer(rb); 1327bd1ae51b13535bc4438c663ffe91ded49db4890aBrian Paul GLenum colorType = srb->ColorType; 1328ff73c783cc47361ff0dd819c82d067b4b85870ddBrian 1329bd1ae51b13535bc4438c663ffe91ded49db4890aBrian Paul assert(colorType == GL_UNSIGNED_BYTE || 1330bd1ae51b13535bc4438c663ffe91ded49db4890aBrian Paul colorType == GL_FLOAT); 1331660ed923ded3552e023ef8c3dd9f92e6792f1bd2Ian Romanick 1332bd1ae51b13535bc4438c663ffe91ded49db4890aBrian Paul /* set span->array->rgba to colors for renderbuffer's datatype */ 1333bd1ae51b13535bc4438c663ffe91ded49db4890aBrian Paul if (span->array->ChanType != colorType) { 1334bd1ae51b13535bc4438c663ffe91ded49db4890aBrian Paul convert_color_type(span, colorType, 0); 1335ff73c783cc47361ff0dd819c82d067b4b85870ddBrian } 1336c8e714df013cdf360602f9cc96d26cb732b19a32M.Froehlich@science-computing.de else { 1337660ed923ded3552e023ef8c3dd9f92e6792f1bd2Ian Romanick if (span->array->ChanType == GL_UNSIGNED_BYTE) { 1338660ed923ded3552e023ef8c3dd9f92e6792f1bd2Ian Romanick span->array->rgba = span->array->rgba8; 1339660ed923ded3552e023ef8c3dd9f92e6792f1bd2Ian Romanick } 1340660ed923ded3552e023ef8c3dd9f92e6792f1bd2Ian Romanick else { 1341660ed923ded3552e023ef8c3dd9f92e6792f1bd2Ian Romanick span->array->rgba = (void *) 1342660ed923ded3552e023ef8c3dd9f92e6792f1bd2Ian Romanick span->array->attribs[FRAG_ATTRIB_COL0]; 1343660ed923ded3552e023ef8c3dd9f92e6792f1bd2Ian Romanick } 1344c8e714df013cdf360602f9cc96d26cb732b19a32M.Froehlich@science-computing.de } 1345ff73c783cc47361ff0dd819c82d067b4b85870ddBrian 1346ff73c783cc47361ff0dd819c82d067b4b85870ddBrian if (!multiFragOutputs && numBuffers > 1) { 1347ff73c783cc47361ff0dd819c82d067b4b85870ddBrian /* save colors for second, third renderbuffer writes */ 1348c7ac486261ad30ef654f6d0b1608da4e8483cd40Kenneth Graunke memcpy(rgbaSave, span->array->rgba, 1349c7ac486261ad30ef654f6d0b1608da4e8483cd40Kenneth Graunke 4 * span->end * sizeof(GLchan)); 1350ff73c783cc47361ff0dd819c82d067b4b85870ddBrian } 1351ff73c783cc47361ff0dd819c82d067b4b85870ddBrian 1352b7f670655dc57ea90963888f95e22773ce0ad131Brian Paul ASSERT(rb->_BaseFormat == GL_RGBA || 1353b7f670655dc57ea90963888f95e22773ce0ad131Brian Paul rb->_BaseFormat == GL_RGB || 1354b7f670655dc57ea90963888f95e22773ce0ad131Brian Paul rb->_BaseFormat == GL_RED || 1355b7f670655dc57ea90963888f95e22773ce0ad131Brian Paul rb->_BaseFormat == GL_RG || 135650a3349bee04088bee3491622d6ef3c032d01eacEric Anholt rb->_BaseFormat == GL_ALPHA); 1357ff73c783cc47361ff0dd819c82d067b4b85870ddBrian 13582836aab2031d5b6926923fbc70f867ec638301bdIan Romanick if (ctx->Color.ColorLogicOpEnabled) { 1359ff73c783cc47361ff0dd819c82d067b4b85870ddBrian _swrast_logicop_rgba_span(ctx, rb, span); 1360ff73c783cc47361ff0dd819c82d067b4b85870ddBrian } 13613728673bd1b974e54858fbab6ff62d3607b0d3f0Brian Paul else if ((ctx->Color.BlendEnabled >> buf) & 1) { 1362ff73c783cc47361ff0dd819c82d067b4b85870ddBrian _swrast_blend_span(ctx, rb, span); 1363ff73c783cc47361ff0dd819c82d067b4b85870ddBrian } 1364ff73c783cc47361ff0dd819c82d067b4b85870ddBrian 1365fd5511d27fc44096117c47ab503fb5b47f993061Brian Paul if (colorMask[buf] != 0xffffffff) { 1366fd5511d27fc44096117c47ab503fb5b47f993061Brian Paul _swrast_mask_rgba_span(ctx, rb, span, buf); 1367ff73c783cc47361ff0dd819c82d067b4b85870ddBrian } 1368ff73c783cc47361ff0dd819c82d067b4b85870ddBrian 1369ff73c783cc47361ff0dd819c82d067b4b85870ddBrian if (span->arrayMask & SPAN_XY) { 1370ff73c783cc47361ff0dd819c82d067b4b85870ddBrian /* array of pixel coords */ 1371f9874feef4d8952df5054bd8e8f4e0deda4ef44fBrian Paul put_values(ctx, rb, 1372f9874feef4d8952df5054bd8e8f4e0deda4ef44fBrian Paul span->array->ChanType, span->end, 13730ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul span->array->x, span->array->y, 13740ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul span->array->rgba, span->array->mask); 1375ff73c783cc47361ff0dd819c82d067b4b85870ddBrian } 1376ff73c783cc47361ff0dd819c82d067b4b85870ddBrian else { 1377ff73c783cc47361ff0dd819c82d067b4b85870ddBrian /* horizontal run of pixels */ 1378f9874feef4d8952df5054bd8e8f4e0deda4ef44fBrian Paul _swrast_put_row(ctx, rb, 1379f9874feef4d8952df5054bd8e8f4e0deda4ef44fBrian Paul span->array->ChanType, 1380f9874feef4d8952df5054bd8e8f4e0deda4ef44fBrian Paul span->end, span->x, span->y, 13810ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul span->array->rgba, 13820ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul span->writeAll ? NULL: span->array->mask); 1383ff73c783cc47361ff0dd819c82d067b4b85870ddBrian } 1384ff73c783cc47361ff0dd819c82d067b4b85870ddBrian 1385ff73c783cc47361ff0dd819c82d067b4b85870ddBrian if (!multiFragOutputs && numBuffers > 1) { 1386ff73c783cc47361ff0dd819c82d067b4b85870ddBrian /* restore original span values */ 1387c7ac486261ad30ef654f6d0b1608da4e8483cd40Kenneth Graunke memcpy(span->array->rgba, rgbaSave, 1388c7ac486261ad30ef654f6d0b1608da4e8483cd40Kenneth Graunke 4 * span->end * sizeof(GLchan)); 1389ff73c783cc47361ff0dd819c82d067b4b85870ddBrian } 1390ff73c783cc47361ff0dd819c82d067b4b85870ddBrian 1391ff73c783cc47361ff0dd819c82d067b4b85870ddBrian } /* if rb */ 1392ff73c783cc47361ff0dd819c82d067b4b85870ddBrian } /* for buf */ 1393ff73c783cc47361ff0dd819c82d067b4b85870ddBrian } 139471340e861edf35bfdeb536718cd230fc33c41ee2Brian Paul 1395c3caaa3dd45809e672177ab322445fe51d03af25Brian Paulend: 139661c89be3135cedc795e48d36283769298e250837Brian Paul /* restore these values before returning */ 1397e5b244ff7f984805c1bcc020342f1300f2639c71Brian Paul span->interpMask = origInterpMask; 1398f1e236987829393c81dc86ea19cb49eefe190317Brian Paul span->arrayMask = origArrayMask; 13999e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian span->arrayAttribs = origArrayAttribs; 140093becd8a18f6ccf2f86e506ee36fc0bb75787c29Brian span->array->ChanType = origChanType; 140193becd8a18f6ccf2f86e506ee36fc0bb75787c29Brian span->array->rgba = origRgba; 140210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul} 140310f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 1404e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 140579c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/** 1406267fb178844d3f17503dd0f921791f3ab059c4e7Brian Paul * Read float RGBA pixels from a renderbuffer. Clipping will be done to 1407267fb178844d3f17503dd0f921791f3ab059c4e7Brian Paul * prevent reading ouside the buffer's boundaries. 140876e778dce59aa6f290db50242df945943fc47b05Brian Paul * \param rgba the returned colors 1409e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */ 14105071b0812fc73bcba92e2b6fcbad2f53f063fc32Brian Paulvoid 1411f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg_swrast_read_rgba_span( struct gl_context *ctx, struct gl_renderbuffer *rb, 1412267fb178844d3f17503dd0f921791f3ab059c4e7Brian Paul GLuint n, GLint x, GLint y, 141376e778dce59aa6f290db50242df945943fc47b05Brian Paul GLvoid *rgba) 1414e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell{ 14150c1862851f27c428a18ba5509636efcc2f0084f8Brian Paul struct swrast_renderbuffer *srb = swrast_renderbuffer(rb); 1416267fb178844d3f17503dd0f921791f3ab059c4e7Brian Paul GLenum dstType = GL_FLOAT; 1417e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul const GLint bufWidth = (GLint) rb->Width; 1418e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul const GLint bufHeight = (GLint) rb->Height; 1419a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul 1420a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul if (y < 0 || y >= bufHeight || x + (GLint) n < 0 || x >= bufWidth) { 1421e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* completely above, below, or right */ 1422e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul /* XXX maybe leave rgba values undefined? */ 14236bf1ea897fa470af58fe8916dff45e2da79634a3Brian Paul memset(rgba, 0, 4 * n * sizeof(GLchan)); 1424e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1425e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell else { 1426e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell GLint skip, length; 14270ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul GLubyte *src; 14280ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul 1429e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell if (x < 0) { 14307e152b83cbc3af028175a52450c60101cb16acf8Brian Paul /* left edge clipping */ 1431e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell skip = -x; 1432e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell length = (GLint) n - skip; 1433e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell if (length < 0) { 1434e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* completely left of window */ 1435e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell return; 1436e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1437a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul if (length > bufWidth) { 1438a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul length = bufWidth; 1439e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1440e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1441a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul else if ((GLint) (x + n) > bufWidth) { 1442e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* right edge clipping */ 1443e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell skip = 0; 1444a670c1280b78e6da3b298b61f623e4c733c6be94Brian Paul length = bufWidth - x; 1445e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell if (length < 0) { 1446e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* completely to right of window */ 1447e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell return; 1448e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1449e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1450e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell else { 1451e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* no clipping */ 1452e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell skip = 0; 1453e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell length = (GLint) n; 1454e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1455e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 1456bb8b302dbce4f830d060efecd8a9f75b10e25abbBrian Paul ASSERT(rb); 1457641dd899bd485c194c20a871633797a47e4f912dEric Anholt ASSERT(rb->_BaseFormat == GL_RGBA || 1458641dd899bd485c194c20a871633797a47e4f912dEric Anholt rb->_BaseFormat == GL_RGB || 1459641dd899bd485c194c20a871633797a47e4f912dEric Anholt rb->_BaseFormat == GL_RG || 1460641dd899bd485c194c20a871633797a47e4f912dEric Anholt rb->_BaseFormat == GL_RED || 1461a45b757f788d3a59a446fe2596065ec5f0d5eac2Eric Anholt rb->_BaseFormat == GL_LUMINANCE || 1462a45b757f788d3a59a446fe2596065ec5f0d5eac2Eric Anholt rb->_BaseFormat == GL_INTENSITY || 1463a45b757f788d3a59a446fe2596065ec5f0d5eac2Eric Anholt rb->_BaseFormat == GL_LUMINANCE_ALPHA || 146450a3349bee04088bee3491622d6ef3c032d01eacEric Anholt rb->_BaseFormat == GL_ALPHA); 146576e778dce59aa6f290db50242df945943fc47b05Brian Paul 14660c1862851f27c428a18ba5509636efcc2f0084f8Brian Paul assert(srb->Map); 14670ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul 14680ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul src = _swrast_pixel_address(rb, x + skip, y); 14690ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul 14700ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul if (dstType == GL_UNSIGNED_BYTE) { 14710ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul _mesa_unpack_ubyte_rgba_row(rb->Format, length, src, 14720ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul (GLubyte (*)[4]) rgba + skip); 14730ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul } 14740ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul else if (dstType == GL_FLOAT) { 14750ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul _mesa_unpack_rgba_row(rb->Format, length, src, 14760ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul (GLfloat (*)[4]) rgba + skip); 147776e778dce59aa6f290db50242df945943fc47b05Brian Paul } 147876e778dce59aa6f290db50242df945943fc47b05Brian Paul else { 14790ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul _mesa_problem(ctx, "unexpected type in _swrast_read_rgba_span()"); 148076e778dce59aa6f290db50242df945943fc47b05Brian Paul } 1481e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1482e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell} 1483e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 1484e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 148579c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/** 14860ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul * Get colors at x/y positions with clipping. 14870ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul * \param type type of values to return 148867074332728acba86da7630353673b458713bb8aBrian Paul */ 1489ff57b0f037a45b0d5ced38234f0a8b29d32e7f9dBrian Paulstatic void 1490ff57b0f037a45b0d5ced38234f0a8b29d32e7f9dBrian Paulget_values(struct gl_context *ctx, struct gl_renderbuffer *rb, 1491ff57b0f037a45b0d5ced38234f0a8b29d32e7f9dBrian Paul GLuint count, const GLint x[], const GLint y[], 14920ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul void *values, GLenum type) 149367074332728acba86da7630353673b458713bb8aBrian Paul{ 14940ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul GLuint i; 149567074332728acba86da7630353673b458713bb8aBrian Paul 149667074332728acba86da7630353673b458713bb8aBrian Paul for (i = 0; i < count; i++) { 1497ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian if (x[i] >= 0 && y[i] >= 0 && 1498ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian x[i] < (GLint) rb->Width && y[i] < (GLint) rb->Height) { 149967074332728acba86da7630353673b458713bb8aBrian Paul /* inside */ 15000ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul const GLubyte *src = _swrast_pixel_address(rb, x[i], y[i]); 15010ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul 15020ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul if (type == GL_UNSIGNED_BYTE) { 15030ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul _mesa_unpack_ubyte_rgba_row(rb->Format, 1, src, 15040ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul (GLubyte (*)[4]) values + i); 15050ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul } 15060ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul else if (type == GL_FLOAT) { 15070ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul _mesa_unpack_rgba_row(rb->Format, 1, src, 15080ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul (GLfloat (*)[4]) values + i); 15090ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul } 15100ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul else { 15110ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul _mesa_problem(ctx, "unexpected type in get_values()"); 151267074332728acba86da7630353673b458713bb8aBrian Paul } 151367074332728acba86da7630353673b458713bb8aBrian Paul } 151467074332728acba86da7630353673b458713bb8aBrian Paul } 151567074332728acba86da7630353673b458713bb8aBrian Paul} 15163fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul 15173fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul 15183fd819aef8139761ce86cb8d763de83a11c81b33Brian Paul/** 15190ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul * Get row of colors with clipping. 15200ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul * \param type type of values to return 1521f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul */ 1522ff57b0f037a45b0d5ced38234f0a8b29d32e7f9dBrian Paulstatic void 1523ff57b0f037a45b0d5ced38234f0a8b29d32e7f9dBrian Paulget_row(struct gl_context *ctx, struct gl_renderbuffer *rb, 1524ff57b0f037a45b0d5ced38234f0a8b29d32e7f9dBrian Paul GLuint count, GLint x, GLint y, 15250ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul GLvoid *values, GLenum type) 1526f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul{ 1527f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul GLint skip = 0; 15280ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul GLubyte *src; 1529f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul 1530ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian if (y < 0 || y >= (GLint) rb->Height) 1531f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul return; /* above or below */ 1532f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul 1533ea8b68e0f7e7a4025ce662d36380157273ce10a3Brian if (x + (GLint) count <= 0 || x >= (GLint) rb->Width) 1534f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul return; /* entirely left or right */ 1535f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul 1536f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul if (x + count > rb->Width) { 1537f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul /* right clip */ 1538f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul GLint clip = x + count - rb->Width; 1539f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul count -= clip; 1540f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul } 1541f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul 1542f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul if (x < 0) { 1543f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul /* left clip */ 1544f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul skip = -x; 1545f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul x = 0; 1546f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul count -= skip; 1547f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul } 1548f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul 15490ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul src = _swrast_pixel_address(rb, x, y); 15500ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul 15510ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul if (type == GL_UNSIGNED_BYTE) { 15520ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul _mesa_unpack_ubyte_rgba_row(rb->Format, count, src, 15530ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul (GLubyte (*)[4]) values + skip); 15540ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul } 15550ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul else if (type == GL_FLOAT) { 15560ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul _mesa_unpack_rgba_row(rb->Format, count, src, 15570ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul (GLfloat (*)[4]) values + skip); 15580ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul } 15590ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul else { 15600ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul _mesa_problem(ctx, "unexpected type in get_row()"); 15610ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul } 1562f493a04be0e004bb07f84b2e28124ed8cb6a9b38Brian Paul} 1563a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul 1564a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul 1565a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul/** 1566195e7657e2f15f7ad8b22042b86bcf33c5bba76bBrian Paul * Get RGBA pixels from the given renderbuffer. 1567a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul * Used by blending, logicop and masking functions. 1568a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul * \return pointer to the colors we read. 1569a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul */ 1570a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paulvoid * 1571f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg_swrast_get_dest_rgba(struct gl_context *ctx, struct gl_renderbuffer *rb, 1572cdb27e8242215271364602995d85607cfc06d441Brian Paul SWspan *span) 1573a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul{ 1574a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul void *rbPixels; 1575a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul 1576195e7657e2f15f7ad8b22042b86bcf33c5bba76bBrian Paul /* Point rbPixels to a temporary space */ 1577195e7657e2f15f7ad8b22042b86bcf33c5bba76bBrian Paul rbPixels = span->array->attribs[FRAG_ATTRIB_MAX - 1]; 1578a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul 1579a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul /* Get destination values from renderbuffer */ 1580a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul if (span->arrayMask & SPAN_XY) { 1581ff57b0f037a45b0d5ced38234f0a8b29d32e7f9dBrian Paul get_values(ctx, rb, span->end, span->array->x, span->array->y, 15820ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul rbPixels, span->array->ChanType); 1583a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul } 1584a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul else { 1585ff57b0f037a45b0d5ced38234f0a8b29d32e7f9dBrian Paul get_row(ctx, rb, span->end, span->x, span->y, 15860ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul rbPixels, span->array->ChanType); 1587a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul } 1588a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul 1589a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul return rbPixels; 1590a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul} 1591