Home | History | Annotate | Download | only in swrast
      1 /*
      2  * Mesa 3-D graphics library
      3  *
      4  * Copyright (C) 1999-2008  Brian Paul   All Rights Reserved.
      5  * Copyright (C) 2009  VMware, Inc.  All Rights Reserved.
      6  *
      7  * Permission is hereby granted, free of charge, to any person obtaining a
      8  * copy of this software and associated documentation files (the "Software"),
      9  * to deal in the Software without restriction, including without limitation
     10  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
     11  * and/or sell copies of the Software, and to permit persons to whom the
     12  * Software is furnished to do so, subject to the following conditions:
     13  *
     14  * The above copyright notice and this permission notice shall be included
     15  * in all copies or substantial portions of the Software.
     16  *
     17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
     18  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     20  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
     21  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
     22  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
     23  * OTHER DEALINGS IN THE SOFTWARE.
     24  */
     25 
     26 
     27 /**
     28  * \file swrast/s_span.c
     29  * \brief Span processing functions used by all rasterization functions.
     30  * This is where all the per-fragment tests are performed
     31  * \author Brian Paul
     32  */
     33 
     34 #include "c99_math.h"
     35 #include "main/glheader.h"
     36 #include "main/format_pack.h"
     37 #include "main/format_unpack.h"
     38 #include "main/macros.h"
     39 #include "main/imports.h"
     40 #include "main/image.h"
     41 #include "main/samplerobj.h"
     42 #include "main/teximage.h"
     43 
     44 #include "s_atifragshader.h"
     45 #include "s_alpha.h"
     46 #include "s_blend.h"
     47 #include "s_context.h"
     48 #include "s_depth.h"
     49 #include "s_fog.h"
     50 #include "s_logic.h"
     51 #include "s_masking.h"
     52 #include "s_fragprog.h"
     53 #include "s_span.h"
     54 #include "s_stencil.h"
     55 #include "s_texcombine.h"
     56 
     57 #include <stdbool.h>
     58 
     59 /**
     60  * Set default fragment attributes for the span using the
     61  * current raster values.  Used prior to glDraw/CopyPixels
     62  * and glBitmap.
     63  */
     64 void
     65 _swrast_span_default_attribs(struct gl_context *ctx, SWspan *span)
     66 {
     67    GLchan r, g, b, a;
     68    /* Z*/
     69    {
     70       const GLfloat depthMax = ctx->DrawBuffer->_DepthMaxF;
     71       if (ctx->DrawBuffer->Visual.depthBits <= 16)
     72          span->z = FloatToFixed(ctx->Current.RasterPos[2] * depthMax + 0.5F);
     73       else {
     74          GLfloat tmpf = ctx->Current.RasterPos[2] * depthMax;
     75          tmpf = MIN2(tmpf, depthMax);
     76          span->z = (GLint)tmpf;
     77       }
     78       span->zStep = 0;
     79       span->interpMask |= SPAN_Z;
     80    }
     81 
     82    /* W (for perspective correction) */
     83    span->attrStart[VARYING_SLOT_POS][3] = 1.0;
     84    span->attrStepX[VARYING_SLOT_POS][3] = 0.0;
     85    span->attrStepY[VARYING_SLOT_POS][3] = 0.0;
     86 
     87    /* primary color, or color index */
     88    UNCLAMPED_FLOAT_TO_CHAN(r, ctx->Current.RasterColor[0]);
     89    UNCLAMPED_FLOAT_TO_CHAN(g, ctx->Current.RasterColor[1]);
     90    UNCLAMPED_FLOAT_TO_CHAN(b, ctx->Current.RasterColor[2]);
     91    UNCLAMPED_FLOAT_TO_CHAN(a, ctx->Current.RasterColor[3]);
     92 #if CHAN_TYPE == GL_FLOAT
     93    span->red = r;
     94    span->green = g;
     95    span->blue = b;
     96    span->alpha = a;
     97 #else
     98    span->red   = IntToFixed(r);
     99    span->green = IntToFixed(g);
    100    span->blue  = IntToFixed(b);
    101    span->alpha = IntToFixed(a);
    102 #endif
    103    span->redStep = 0;
    104    span->greenStep = 0;
    105    span->blueStep = 0;
    106    span->alphaStep = 0;
    107    span->interpMask |= SPAN_RGBA;
    108 
    109    COPY_4V(span->attrStart[VARYING_SLOT_COL0], ctx->Current.RasterColor);
    110    ASSIGN_4V(span->attrStepX[VARYING_SLOT_COL0], 0.0, 0.0, 0.0, 0.0);
    111    ASSIGN_4V(span->attrStepY[VARYING_SLOT_COL0], 0.0, 0.0, 0.0, 0.0);
    112 
    113    /* Secondary color */
    114    if (ctx->Light.Enabled || ctx->Fog.ColorSumEnabled)
    115    {
    116       COPY_4V(span->attrStart[VARYING_SLOT_COL1], ctx->Current.RasterSecondaryColor);
    117       ASSIGN_4V(span->attrStepX[VARYING_SLOT_COL1], 0.0, 0.0, 0.0, 0.0);
    118       ASSIGN_4V(span->attrStepY[VARYING_SLOT_COL1], 0.0, 0.0, 0.0, 0.0);
    119    }
    120 
    121    /* fog */
    122    {
    123       const SWcontext *swrast = SWRAST_CONTEXT(ctx);
    124       GLfloat fogVal; /* a coord or a blend factor */
    125       if (swrast->_PreferPixelFog) {
    126          /* fog blend factors will be computed from fog coordinates per pixel */
    127          fogVal = ctx->Current.RasterDistance;
    128       }
    129       else {
    130          /* fog blend factor should be computed from fogcoord now */
    131          fogVal = _swrast_z_to_fogfactor(ctx, ctx->Current.RasterDistance);
    132       }
    133       span->attrStart[VARYING_SLOT_FOGC][0] = fogVal;
    134       span->attrStepX[VARYING_SLOT_FOGC][0] = 0.0;
    135       span->attrStepY[VARYING_SLOT_FOGC][0] = 0.0;
    136    }
    137 
    138    /* texcoords */
    139    {
    140       GLuint i;
    141       for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) {
    142          const GLuint attr = VARYING_SLOT_TEX0 + i;
    143          const GLfloat *tc = ctx->Current.RasterTexCoords[i];
    144          if (_swrast_use_fragment_program(ctx) ||
    145              ctx->ATIFragmentShader._Enabled) {
    146             COPY_4V(span->attrStart[attr], tc);
    147          }
    148          else if (tc[3] > 0.0F) {
    149             /* use (s/q, t/q, r/q, 1) */
    150             span->attrStart[attr][0] = tc[0] / tc[3];
    151             span->attrStart[attr][1] = tc[1] / tc[3];
    152             span->attrStart[attr][2] = tc[2] / tc[3];
    153             span->attrStart[attr][3] = 1.0;
    154          }
    155          else {
    156             ASSIGN_4V(span->attrStart[attr], 0.0F, 0.0F, 0.0F, 1.0F);
    157          }
    158          ASSIGN_4V(span->attrStepX[attr], 0.0F, 0.0F, 0.0F, 0.0F);
    159          ASSIGN_4V(span->attrStepY[attr], 0.0F, 0.0F, 0.0F, 0.0F);
    160       }
    161    }
    162 }
    163 
    164 
    165 /**
    166  * Interpolate the active attributes (and'd with attrMask) to
    167  * fill in span->array->attribs[].
    168  * Perspective correction will be done.  The point/line/triangle function
    169  * should have computed attrStart/Step values for VARYING_SLOT_POS[3]!
    170  */
    171 static inline void
    172 interpolate_active_attribs(struct gl_context *ctx, SWspan *span,
    173                            GLbitfield64 attrMask)
    174 {
    175    const SWcontext *swrast = SWRAST_CONTEXT(ctx);
    176 
    177    /*
    178     * Don't overwrite existing array values, such as colors that may have
    179     * been produced by glDraw/CopyPixels.
    180     */
    181    attrMask &= ~span->arrayAttribs;
    182 
    183    ATTRIB_LOOP_BEGIN
    184       if (attrMask & BITFIELD64_BIT(attr)) {
    185          const GLfloat dwdx = span->attrStepX[VARYING_SLOT_POS][3];
    186          GLfloat w = span->attrStart[VARYING_SLOT_POS][3];
    187          const GLfloat dv0dx = span->attrStepX[attr][0];
    188          const GLfloat dv1dx = span->attrStepX[attr][1];
    189          const GLfloat dv2dx = span->attrStepX[attr][2];
    190          const GLfloat dv3dx = span->attrStepX[attr][3];
    191          GLfloat v0 = span->attrStart[attr][0] + span->leftClip * dv0dx;
    192          GLfloat v1 = span->attrStart[attr][1] + span->leftClip * dv1dx;
    193          GLfloat v2 = span->attrStart[attr][2] + span->leftClip * dv2dx;
    194          GLfloat v3 = span->attrStart[attr][3] + span->leftClip * dv3dx;
    195          GLuint k;
    196          for (k = 0; k < span->end; k++) {
    197             const GLfloat invW = 1.0f / w;
    198             span->array->attribs[attr][k][0] = v0 * invW;
    199             span->array->attribs[attr][k][1] = v1 * invW;
    200             span->array->attribs[attr][k][2] = v2 * invW;
    201             span->array->attribs[attr][k][3] = v3 * invW;
    202             v0 += dv0dx;
    203             v1 += dv1dx;
    204             v2 += dv2dx;
    205             v3 += dv3dx;
    206             w += dwdx;
    207          }
    208          assert((span->arrayAttribs & BITFIELD64_BIT(attr)) == 0);
    209          span->arrayAttribs |= BITFIELD64_BIT(attr);
    210       }
    211    ATTRIB_LOOP_END
    212 }
    213 
    214 
    215 /**
    216  * Interpolate primary colors to fill in the span->array->rgba8 (or rgb16)
    217  * color array.
    218  */
    219 static inline void
    220 interpolate_int_colors(struct gl_context *ctx, SWspan *span)
    221 {
    222 #if CHAN_BITS != 32
    223    const GLuint n = span->end;
    224    GLuint i;
    225 
    226    assert(!(span->arrayMask & SPAN_RGBA));
    227 #endif
    228 
    229    switch (span->array->ChanType) {
    230 #if CHAN_BITS != 32
    231    case GL_UNSIGNED_BYTE:
    232       {
    233          GLubyte (*rgba)[4] = span->array->rgba8;
    234          if (span->interpMask & SPAN_FLAT) {
    235             GLubyte color[4];
    236             color[RCOMP] = FixedToInt(span->red);
    237             color[GCOMP] = FixedToInt(span->green);
    238             color[BCOMP] = FixedToInt(span->blue);
    239             color[ACOMP] = FixedToInt(span->alpha);
    240             for (i = 0; i < n; i++) {
    241                COPY_4UBV(rgba[i], color);
    242             }
    243          }
    244          else {
    245             GLfixed r = span->red;
    246             GLfixed g = span->green;
    247             GLfixed b = span->blue;
    248             GLfixed a = span->alpha;
    249             GLint dr = span->redStep;
    250             GLint dg = span->greenStep;
    251             GLint db = span->blueStep;
    252             GLint da = span->alphaStep;
    253             for (i = 0; i < n; i++) {
    254                rgba[i][RCOMP] = FixedToChan(r);
    255                rgba[i][GCOMP] = FixedToChan(g);
    256                rgba[i][BCOMP] = FixedToChan(b);
    257                rgba[i][ACOMP] = FixedToChan(a);
    258                r += dr;
    259                g += dg;
    260                b += db;
    261                a += da;
    262             }
    263          }
    264       }
    265       break;
    266    case GL_UNSIGNED_SHORT:
    267       {
    268          GLushort (*rgba)[4] = span->array->rgba16;
    269          if (span->interpMask & SPAN_FLAT) {
    270             GLushort color[4];
    271             color[RCOMP] = FixedToInt(span->red);
    272             color[GCOMP] = FixedToInt(span->green);
    273             color[BCOMP] = FixedToInt(span->blue);
    274             color[ACOMP] = FixedToInt(span->alpha);
    275             for (i = 0; i < n; i++) {
    276                COPY_4V(rgba[i], color);
    277             }
    278          }
    279          else {
    280             GLushort (*rgba)[4] = span->array->rgba16;
    281             GLfixed r, g, b, a;
    282             GLint dr, dg, db, da;
    283             r = span->red;
    284             g = span->green;
    285             b = span->blue;
    286             a = span->alpha;
    287             dr = span->redStep;
    288             dg = span->greenStep;
    289             db = span->blueStep;
    290             da = span->alphaStep;
    291             for (i = 0; i < n; i++) {
    292                rgba[i][RCOMP] = FixedToChan(r);
    293                rgba[i][GCOMP] = FixedToChan(g);
    294                rgba[i][BCOMP] = FixedToChan(b);
    295                rgba[i][ACOMP] = FixedToChan(a);
    296                r += dr;
    297                g += dg;
    298                b += db;
    299                a += da;
    300             }
    301          }
    302       }
    303       break;
    304 #endif
    305    case GL_FLOAT:
    306       interpolate_active_attribs(ctx, span, VARYING_BIT_COL0);
    307       break;
    308    default:
    309       _mesa_problem(ctx, "bad datatype 0x%x in interpolate_int_colors",
    310                     span->array->ChanType);
    311    }
    312    span->arrayMask |= SPAN_RGBA;
    313 }
    314 
    315 
    316 /**
    317  * Populate the VARYING_SLOT_COL0 array.
    318  */
    319 static inline void
    320 interpolate_float_colors(SWspan *span)
    321 {
    322    GLfloat (*col0)[4] = span->array->attribs[VARYING_SLOT_COL0];
    323    const GLuint n = span->end;
    324    GLuint i;
    325 
    326    assert(!(span->arrayAttribs & VARYING_BIT_COL0));
    327 
    328    if (span->arrayMask & SPAN_RGBA) {
    329       /* convert array of int colors */
    330       for (i = 0; i < n; i++) {
    331          col0[i][0] = UBYTE_TO_FLOAT(span->array->rgba8[i][0]);
    332          col0[i][1] = UBYTE_TO_FLOAT(span->array->rgba8[i][1]);
    333          col0[i][2] = UBYTE_TO_FLOAT(span->array->rgba8[i][2]);
    334          col0[i][3] = UBYTE_TO_FLOAT(span->array->rgba8[i][3]);
    335       }
    336    }
    337    else {
    338       /* interpolate red/green/blue/alpha to get float colors */
    339       assert(span->interpMask & SPAN_RGBA);
    340       if (span->interpMask & SPAN_FLAT) {
    341          GLfloat r = FixedToFloat(span->red);
    342          GLfloat g = FixedToFloat(span->green);
    343          GLfloat b = FixedToFloat(span->blue);
    344          GLfloat a = FixedToFloat(span->alpha);
    345          for (i = 0; i < n; i++) {
    346             ASSIGN_4V(col0[i], r, g, b, a);
    347          }
    348       }
    349       else {
    350          GLfloat r = FixedToFloat(span->red);
    351          GLfloat g = FixedToFloat(span->green);
    352          GLfloat b = FixedToFloat(span->blue);
    353          GLfloat a = FixedToFloat(span->alpha);
    354          GLfloat dr = FixedToFloat(span->redStep);
    355          GLfloat dg = FixedToFloat(span->greenStep);
    356          GLfloat db = FixedToFloat(span->blueStep);
    357          GLfloat da = FixedToFloat(span->alphaStep);
    358          for (i = 0; i < n; i++) {
    359             col0[i][0] = r;
    360             col0[i][1] = g;
    361             col0[i][2] = b;
    362             col0[i][3] = a;
    363             r += dr;
    364             g += dg;
    365             b += db;
    366             a += da;
    367          }
    368       }
    369    }
    370 
    371    span->arrayAttribs |= VARYING_BIT_COL0;
    372    span->array->ChanType = GL_FLOAT;
    373 }
    374 
    375 
    376 
    377 /**
    378  * Fill in the span.zArray array from the span->z, zStep values.
    379  */
    380 void
    381 _swrast_span_interpolate_z( const struct gl_context *ctx, SWspan *span )
    382 {
    383    const GLuint n = span->end;
    384    GLuint i;
    385 
    386    assert(!(span->arrayMask & SPAN_Z));
    387 
    388    if (ctx->DrawBuffer->Visual.depthBits <= 16) {
    389       GLfixed zval = span->z;
    390       GLuint *z = span->array->z;
    391       for (i = 0; i < n; i++) {
    392          z[i] = FixedToInt(zval);
    393          zval += span->zStep;
    394       }
    395    }
    396    else {
    397       /* Deep Z buffer, no fixed->int shift */
    398       GLuint zval = span->z;
    399       GLuint *z = span->array->z;
    400       for (i = 0; i < n; i++) {
    401          z[i] = zval;
    402          zval += span->zStep;
    403       }
    404    }
    405    span->interpMask &= ~SPAN_Z;
    406    span->arrayMask |= SPAN_Z;
    407 }
    408 
    409 
    410 /**
    411  * Compute mipmap LOD from partial derivatives.
    412  * This the ideal solution, as given in the OpenGL spec.
    413  */
    414 GLfloat
    415 _swrast_compute_lambda(GLfloat dsdx, GLfloat dsdy, GLfloat dtdx, GLfloat dtdy,
    416                        GLfloat dqdx, GLfloat dqdy, GLfloat texW, GLfloat texH,
    417                        GLfloat s, GLfloat t, GLfloat q, GLfloat invQ)
    418 {
    419    GLfloat dudx = texW * ((s + dsdx) / (q + dqdx) - s * invQ);
    420    GLfloat dvdx = texH * ((t + dtdx) / (q + dqdx) - t * invQ);
    421    GLfloat dudy = texW * ((s + dsdy) / (q + dqdy) - s * invQ);
    422    GLfloat dvdy = texH * ((t + dtdy) / (q + dqdy) - t * invQ);
    423    GLfloat x = sqrtf(dudx * dudx + dvdx * dvdx);
    424    GLfloat y = sqrtf(dudy * dudy + dvdy * dvdy);
    425    GLfloat rho = MAX2(x, y);
    426    GLfloat lambda = LOG2(rho);
    427    return lambda;
    428 }
    429 
    430 
    431 /**
    432  * Compute mipmap LOD from partial derivatives.
    433  * This is a faster approximation than above function.
    434  */
    435 #if 0
    436 GLfloat
    437 _swrast_compute_lambda(GLfloat dsdx, GLfloat dsdy, GLfloat dtdx, GLfloat dtdy,
    438                      GLfloat dqdx, GLfloat dqdy, GLfloat texW, GLfloat texH,
    439                      GLfloat s, GLfloat t, GLfloat q, GLfloat invQ)
    440 {
    441    GLfloat dsdx2 = (s + dsdx) / (q + dqdx) - s * invQ;
    442    GLfloat dtdx2 = (t + dtdx) / (q + dqdx) - t * invQ;
    443    GLfloat dsdy2 = (s + dsdy) / (q + dqdy) - s * invQ;
    444    GLfloat dtdy2 = (t + dtdy) / (q + dqdy) - t * invQ;
    445    GLfloat maxU, maxV, rho, lambda;
    446    dsdx2 = fabsf(dsdx2);
    447    dsdy2 = fabsf(dsdy2);
    448    dtdx2 = fabsf(dtdx2);
    449    dtdy2 = fabsf(dtdy2);
    450    maxU = MAX2(dsdx2, dsdy2) * texW;
    451    maxV = MAX2(dtdx2, dtdy2) * texH;
    452    rho = MAX2(maxU, maxV);
    453    lambda = LOG2(rho);
    454    return lambda;
    455 }
    456 #endif
    457 
    458 
    459 /**
    460  * Fill in the span.array->attrib[VARYING_SLOT_TEXn] arrays from the
    461  * using the attrStart/Step values.
    462  *
    463  * This function only used during fixed-function fragment processing.
    464  *
    465  * Note: in the places where we divide by Q (or mult by invQ) we're
    466  * really doing two things: perspective correction and texcoord
    467  * projection.  Remember, for texcoord (s,t,r,q) we need to index
    468  * texels with (s/q, t/q, r/q).
    469  */
    470 static void
    471 interpolate_texcoords(struct gl_context *ctx, SWspan *span)
    472 {
    473    const GLuint maxUnit
    474       = (ctx->Texture._EnabledCoordUnits > 1) ? ctx->Const.MaxTextureUnits : 1;
    475    GLuint u;
    476 
    477    /* XXX CoordUnits vs. ImageUnits */
    478    for (u = 0; u < maxUnit; u++) {
    479       if (ctx->Texture._EnabledCoordUnits & (1 << u)) {
    480          const GLuint attr = VARYING_SLOT_TEX0 + u;
    481          const struct gl_texture_object *obj = ctx->Texture.Unit[u]._Current;
    482          GLfloat texW, texH;
    483          GLboolean needLambda;
    484          GLfloat (*texcoord)[4] = span->array->attribs[attr];
    485          GLfloat *lambda = span->array->lambda[u];
    486          const GLfloat dsdx = span->attrStepX[attr][0];
    487          const GLfloat dsdy = span->attrStepY[attr][0];
    488          const GLfloat dtdx = span->attrStepX[attr][1];
    489          const GLfloat dtdy = span->attrStepY[attr][1];
    490          const GLfloat drdx = span->attrStepX[attr][2];
    491          const GLfloat dqdx = span->attrStepX[attr][3];
    492          const GLfloat dqdy = span->attrStepY[attr][3];
    493          GLfloat s = span->attrStart[attr][0] + span->leftClip * dsdx;
    494          GLfloat t = span->attrStart[attr][1] + span->leftClip * dtdx;
    495          GLfloat r = span->attrStart[attr][2] + span->leftClip * drdx;
    496          GLfloat q = span->attrStart[attr][3] + span->leftClip * dqdx;
    497 
    498          if (obj) {
    499             const struct gl_texture_image *img = _mesa_base_tex_image(obj);
    500             const struct swrast_texture_image *swImg =
    501                swrast_texture_image_const(img);
    502             const struct gl_sampler_object *samp = _mesa_get_samplerobj(ctx, u);
    503 
    504             needLambda = (samp->MinFilter != samp->MagFilter)
    505                || _swrast_use_fragment_program(ctx);
    506             /* LOD is calculated directly in the ansiotropic filter, we can
    507              * skip the normal lambda function as the result is ignored.
    508              */
    509             if (samp->MaxAnisotropy > 1.0F &&
    510                 samp->MinFilter == GL_LINEAR_MIPMAP_LINEAR) {
    511                needLambda = GL_FALSE;
    512             }
    513             texW = swImg->WidthScale;
    514             texH = swImg->HeightScale;
    515          }
    516          else {
    517             /* using a fragment program */
    518             texW = 1.0;
    519             texH = 1.0;
    520             needLambda = GL_FALSE;
    521          }
    522 
    523          if (needLambda) {
    524             GLuint i;
    525             if (_swrast_use_fragment_program(ctx)
    526                 || ctx->ATIFragmentShader._Enabled) {
    527                /* do perspective correction but don't divide s, t, r by q */
    528                const GLfloat dwdx = span->attrStepX[VARYING_SLOT_POS][3];
    529                GLfloat w = span->attrStart[VARYING_SLOT_POS][3] + span->leftClip * dwdx;
    530                for (i = 0; i < span->end; i++) {
    531                   const GLfloat invW = 1.0F / w;
    532                   texcoord[i][0] = s * invW;
    533                   texcoord[i][1] = t * invW;
    534                   texcoord[i][2] = r * invW;
    535                   texcoord[i][3] = q * invW;
    536                   lambda[i] = _swrast_compute_lambda(dsdx, dsdy, dtdx, dtdy,
    537                                                      dqdx, dqdy, texW, texH,
    538                                                      s, t, q, invW);
    539                   s += dsdx;
    540                   t += dtdx;
    541                   r += drdx;
    542                   q += dqdx;
    543                   w += dwdx;
    544                }
    545             }
    546             else {
    547                for (i = 0; i < span->end; i++) {
    548                   const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q);
    549                   texcoord[i][0] = s * invQ;
    550                   texcoord[i][1] = t * invQ;
    551                   texcoord[i][2] = r * invQ;
    552                   texcoord[i][3] = q;
    553                   lambda[i] = _swrast_compute_lambda(dsdx, dsdy, dtdx, dtdy,
    554                                                      dqdx, dqdy, texW, texH,
    555                                                      s, t, q, invQ);
    556                   s += dsdx;
    557                   t += dtdx;
    558                   r += drdx;
    559                   q += dqdx;
    560                }
    561             }
    562             span->arrayMask |= SPAN_LAMBDA;
    563          }
    564          else {
    565             GLuint i;
    566             if (_swrast_use_fragment_program(ctx) ||
    567                 ctx->ATIFragmentShader._Enabled) {
    568                /* do perspective correction but don't divide s, t, r by q */
    569                const GLfloat dwdx = span->attrStepX[VARYING_SLOT_POS][3];
    570                GLfloat w = span->attrStart[VARYING_SLOT_POS][3] + span->leftClip * dwdx;
    571                for (i = 0; i < span->end; i++) {
    572                   const GLfloat invW = 1.0F / w;
    573                   texcoord[i][0] = s * invW;
    574                   texcoord[i][1] = t * invW;
    575                   texcoord[i][2] = r * invW;
    576                   texcoord[i][3] = q * invW;
    577                   lambda[i] = 0.0;
    578                   s += dsdx;
    579                   t += dtdx;
    580                   r += drdx;
    581                   q += dqdx;
    582                   w += dwdx;
    583                }
    584             }
    585             else if (dqdx == 0.0F) {
    586                /* Ortho projection or polygon's parallel to window X axis */
    587                const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q);
    588                for (i = 0; i < span->end; i++) {
    589                   texcoord[i][0] = s * invQ;
    590                   texcoord[i][1] = t * invQ;
    591                   texcoord[i][2] = r * invQ;
    592                   texcoord[i][3] = q;
    593                   lambda[i] = 0.0;
    594                   s += dsdx;
    595                   t += dtdx;
    596                   r += drdx;
    597                }
    598             }
    599             else {
    600                for (i = 0; i < span->end; i++) {
    601                   const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q);
    602                   texcoord[i][0] = s * invQ;
    603                   texcoord[i][1] = t * invQ;
    604                   texcoord[i][2] = r * invQ;
    605                   texcoord[i][3] = q;
    606                   lambda[i] = 0.0;
    607                   s += dsdx;
    608                   t += dtdx;
    609                   r += drdx;
    610                   q += dqdx;
    611                }
    612             }
    613          } /* lambda */
    614       } /* if */
    615    } /* for */
    616 }
    617 
    618 
    619 /**
    620  * Fill in the arrays->attribs[VARYING_SLOT_POS] array.
    621  */
    622 static inline void
    623 interpolate_wpos(struct gl_context *ctx, SWspan *span)
    624 {
    625    GLfloat (*wpos)[4] = span->array->attribs[VARYING_SLOT_POS];
    626    GLuint i;
    627    const GLfloat zScale = 1.0F / ctx->DrawBuffer->_DepthMaxF;
    628    GLfloat w, dw;
    629 
    630    if (span->arrayMask & SPAN_XY) {
    631       for (i = 0; i < span->end; i++) {
    632          wpos[i][0] = (GLfloat) span->array->x[i];
    633          wpos[i][1] = (GLfloat) span->array->y[i];
    634       }
    635    }
    636    else {
    637       for (i = 0; i < span->end; i++) {
    638          wpos[i][0] = (GLfloat) span->x + i;
    639          wpos[i][1] = (GLfloat) span->y;
    640       }
    641    }
    642 
    643    dw = span->attrStepX[VARYING_SLOT_POS][3];
    644    w = span->attrStart[VARYING_SLOT_POS][3] + span->leftClip * dw;
    645    for (i = 0; i < span->end; i++) {
    646       wpos[i][2] = (GLfloat) span->array->z[i] * zScale;
    647       wpos[i][3] = w;
    648       w += dw;
    649    }
    650 }
    651 
    652 
    653 /**
    654  * Apply the current polygon stipple pattern to a span of pixels.
    655  */
    656 static inline void
    657 stipple_polygon_span(struct gl_context *ctx, SWspan *span)
    658 {
    659    GLubyte *mask = span->array->mask;
    660 
    661    assert(ctx->Polygon.StippleFlag);
    662 
    663    if (span->arrayMask & SPAN_XY) {
    664       /* arrays of x/y pixel coords */
    665       GLuint i;
    666       for (i = 0; i < span->end; i++) {
    667          const GLint col = span->array->x[i] % 32;
    668          const GLint row = span->array->y[i] % 32;
    669          const GLuint stipple = ctx->PolygonStipple[row];
    670          if (((1 << col) & stipple) == 0) {
    671             mask[i] = 0;
    672          }
    673       }
    674    }
    675    else {
    676       /* horizontal span of pixels */
    677       const GLuint highBit = 1 << 31;
    678       const GLuint stipple = ctx->PolygonStipple[span->y % 32];
    679       GLuint i, m = highBit >> (GLuint) (span->x % 32);
    680       for (i = 0; i < span->end; i++) {
    681          if ((m & stipple) == 0) {
    682             mask[i] = 0;
    683          }
    684          m = m >> 1;
    685          if (m == 0) {
    686             m = highBit;
    687          }
    688       }
    689    }
    690    span->writeAll = GL_FALSE;
    691 }
    692 
    693 
    694 /**
    695  * Clip a pixel span to the current buffer/window boundaries:
    696  * DrawBuffer->_Xmin, _Xmax, _Ymin, _Ymax.  This will accomplish
    697  * window clipping and scissoring.
    698  * Return:   GL_TRUE   some pixels still visible
    699  *           GL_FALSE  nothing visible
    700  */
    701 static inline GLuint
    702 clip_span( struct gl_context *ctx, SWspan *span )
    703 {
    704    const GLint xmin = ctx->DrawBuffer->_Xmin;
    705    const GLint xmax = ctx->DrawBuffer->_Xmax;
    706    const GLint ymin = ctx->DrawBuffer->_Ymin;
    707    const GLint ymax = ctx->DrawBuffer->_Ymax;
    708 
    709    span->leftClip = 0;
    710 
    711    if (span->arrayMask & SPAN_XY) {
    712       /* arrays of x/y pixel coords */
    713       const GLint *x = span->array->x;
    714       const GLint *y = span->array->y;
    715       const GLint n = span->end;
    716       GLubyte *mask = span->array->mask;
    717       GLint i;
    718       GLuint passed = 0;
    719       if (span->arrayMask & SPAN_MASK) {
    720          /* note: using & intead of && to reduce branches */
    721          for (i = 0; i < n; i++) {
    722             mask[i] &= (x[i] >= xmin) & (x[i] < xmax)
    723                      & (y[i] >= ymin) & (y[i] < ymax);
    724             passed += mask[i];
    725          }
    726       }
    727       else {
    728          /* note: using & intead of && to reduce branches */
    729          for (i = 0; i < n; i++) {
    730             mask[i] = (x[i] >= xmin) & (x[i] < xmax)
    731                     & (y[i] >= ymin) & (y[i] < ymax);
    732             passed += mask[i];
    733          }
    734       }
    735       return passed > 0;
    736    }
    737    else {
    738       /* horizontal span of pixels */
    739       const GLint x = span->x;
    740       const GLint y = span->y;
    741       GLint n = span->end;
    742 
    743       /* Trivial rejection tests */
    744       if (y < ymin || y >= ymax || x + n <= xmin || x >= xmax) {
    745          span->end = 0;
    746          return GL_FALSE;  /* all pixels clipped */
    747       }
    748 
    749       /* Clip to right */
    750       if (x + n > xmax) {
    751          assert(x < xmax);
    752          n = span->end = xmax - x;
    753       }
    754 
    755       /* Clip to the left */
    756       if (x < xmin) {
    757          const GLint leftClip = xmin - x;
    758          GLuint i;
    759 
    760          assert(leftClip > 0);
    761          assert(x + n > xmin);
    762 
    763          /* Clip 'leftClip' pixels from the left side.
    764           * The span->leftClip field will be applied when we interpolate
    765           * fragment attributes.
    766           * For arrays of values, shift them left.
    767           */
    768          for (i = 0; i < VARYING_SLOT_MAX; i++) {
    769             if (span->interpMask & (1 << i)) {
    770                GLuint j;
    771                for (j = 0; j < 4; j++) {
    772                   span->attrStart[i][j] += leftClip * span->attrStepX[i][j];
    773                }
    774             }
    775          }
    776 
    777          span->red += leftClip * span->redStep;
    778          span->green += leftClip * span->greenStep;
    779          span->blue += leftClip * span->blueStep;
    780          span->alpha += leftClip * span->alphaStep;
    781          span->index += leftClip * span->indexStep;
    782          span->z += leftClip * span->zStep;
    783          span->intTex[0] += leftClip * span->intTexStep[0];
    784          span->intTex[1] += leftClip * span->intTexStep[1];
    785 
    786 #define SHIFT_ARRAY(ARRAY, SHIFT, LEN) \
    787          memmove(ARRAY, ARRAY + (SHIFT), (LEN) * sizeof(ARRAY[0]))
    788 
    789          for (i = 0; i < VARYING_SLOT_MAX; i++) {
    790             if (span->arrayAttribs & BITFIELD64_BIT(i)) {
    791                /* shift array elements left by 'leftClip' */
    792                SHIFT_ARRAY(span->array->attribs[i], leftClip, n - leftClip);
    793             }
    794          }
    795 
    796          SHIFT_ARRAY(span->array->mask, leftClip, n - leftClip);
    797          SHIFT_ARRAY(span->array->rgba8, leftClip, n - leftClip);
    798          SHIFT_ARRAY(span->array->rgba16, leftClip, n - leftClip);
    799          SHIFT_ARRAY(span->array->x, leftClip, n - leftClip);
    800          SHIFT_ARRAY(span->array->y, leftClip, n - leftClip);
    801          SHIFT_ARRAY(span->array->z, leftClip, n - leftClip);
    802          SHIFT_ARRAY(span->array->index, leftClip, n - leftClip);
    803          for (i = 0; i < MAX_TEXTURE_COORD_UNITS; i++) {
    804             SHIFT_ARRAY(span->array->lambda[i], leftClip, n - leftClip);
    805          }
    806          SHIFT_ARRAY(span->array->coverage, leftClip, n - leftClip);
    807 
    808 #undef SHIFT_ARRAY
    809 
    810          span->leftClip = leftClip;
    811          span->x = xmin;
    812          span->end -= leftClip;
    813          span->writeAll = GL_FALSE;
    814       }
    815 
    816       assert(span->x >= xmin);
    817       assert(span->x + span->end <= xmax);
    818       assert(span->y >= ymin);
    819       assert(span->y < ymax);
    820 
    821       return GL_TRUE;  /* some pixels visible */
    822    }
    823 }
    824 
    825 
    826 /**
    827  * Add specular colors to primary colors.
    828  * Only called during fixed-function operation.
    829  * Result is float color array (VARYING_SLOT_COL0).
    830  */
    831 static inline void
    832 add_specular(struct gl_context *ctx, SWspan *span)
    833 {
    834    const SWcontext *swrast = SWRAST_CONTEXT(ctx);
    835    const GLubyte *mask = span->array->mask;
    836    GLfloat (*col0)[4] = span->array->attribs[VARYING_SLOT_COL0];
    837    GLfloat (*col1)[4] = span->array->attribs[VARYING_SLOT_COL1];
    838    GLuint i;
    839 
    840    assert(!_swrast_use_fragment_program(ctx));
    841    assert(span->arrayMask & SPAN_RGBA);
    842    assert(swrast->_ActiveAttribMask & VARYING_BIT_COL1);
    843    (void) swrast; /* silence warning */
    844 
    845    if (span->array->ChanType == GL_FLOAT) {
    846       if ((span->arrayAttribs & VARYING_BIT_COL0) == 0) {
    847          interpolate_active_attribs(ctx, span, VARYING_BIT_COL0);
    848       }
    849    }
    850    else {
    851       /* need float colors */
    852       if ((span->arrayAttribs & VARYING_BIT_COL0) == 0) {
    853          interpolate_float_colors(span);
    854       }
    855    }
    856 
    857    if ((span->arrayAttribs & VARYING_BIT_COL1) == 0) {
    858       /* XXX could avoid this and interpolate COL1 in the loop below */
    859       interpolate_active_attribs(ctx, span, VARYING_BIT_COL1);
    860    }
    861 
    862    assert(span->arrayAttribs & VARYING_BIT_COL0);
    863    assert(span->arrayAttribs & VARYING_BIT_COL1);
    864 
    865    for (i = 0; i < span->end; i++) {
    866       if (mask[i]) {
    867          col0[i][0] += col1[i][0];
    868          col0[i][1] += col1[i][1];
    869          col0[i][2] += col1[i][2];
    870       }
    871    }
    872 
    873    span->array->ChanType = GL_FLOAT;
    874 }
    875 
    876 
    877 /**
    878  * Apply antialiasing coverage value to alpha values.
    879  */
    880 static inline void
    881 apply_aa_coverage(SWspan *span)
    882 {
    883    const GLfloat *coverage = span->array->coverage;
    884    GLuint i;
    885    if (span->array->ChanType == GL_UNSIGNED_BYTE) {
    886       GLubyte (*rgba)[4] = span->array->rgba8;
    887       for (i = 0; i < span->end; i++) {
    888          const GLfloat a = rgba[i][ACOMP] * coverage[i];
    889          rgba[i][ACOMP] = (GLubyte) CLAMP(a, 0.0F, 255.0F);
    890          assert(coverage[i] >= 0.0F);
    891          assert(coverage[i] <= 1.0F);
    892       }
    893    }
    894    else if (span->array->ChanType == GL_UNSIGNED_SHORT) {
    895       GLushort (*rgba)[4] = span->array->rgba16;
    896       for (i = 0; i < span->end; i++) {
    897          const GLfloat a = rgba[i][ACOMP] * coverage[i];
    898          rgba[i][ACOMP] = (GLushort) CLAMP(a, 0.0F, 65535.0F);
    899       }
    900    }
    901    else {
    902       GLfloat (*rgba)[4] = span->array->attribs[VARYING_SLOT_COL0];
    903       for (i = 0; i < span->end; i++) {
    904          rgba[i][ACOMP] = rgba[i][ACOMP] * coverage[i];
    905          /* clamp later */
    906       }
    907    }
    908 }
    909 
    910 
    911 /**
    912  * Clamp span's float colors to [0,1]
    913  */
    914 static inline void
    915 clamp_colors(SWspan *span)
    916 {
    917    GLfloat (*rgba)[4] = span->array->attribs[VARYING_SLOT_COL0];
    918    GLuint i;
    919    assert(span->array->ChanType == GL_FLOAT);
    920    for (i = 0; i < span->end; i++) {
    921       rgba[i][RCOMP] = CLAMP(rgba[i][RCOMP], 0.0F, 1.0F);
    922       rgba[i][GCOMP] = CLAMP(rgba[i][GCOMP], 0.0F, 1.0F);
    923       rgba[i][BCOMP] = CLAMP(rgba[i][BCOMP], 0.0F, 1.0F);
    924       rgba[i][ACOMP] = CLAMP(rgba[i][ACOMP], 0.0F, 1.0F);
    925    }
    926 }
    927 
    928 
    929 /**
    930  * Convert the span's color arrays to the given type.
    931  * The only way 'output' can be greater than zero is when we have a fragment
    932  * program that writes to gl_FragData[1] or higher.
    933  * \param output  which fragment program color output is being processed
    934  */
    935 static inline void
    936 convert_color_type(SWspan *span, GLenum srcType, GLenum newType, GLuint output)
    937 {
    938    GLvoid *src, *dst;
    939 
    940    if (output > 0 || srcType == GL_FLOAT) {
    941       src = span->array->attribs[VARYING_SLOT_COL0 + output];
    942       span->array->ChanType = GL_FLOAT;
    943    }
    944    else if (srcType == GL_UNSIGNED_BYTE) {
    945       src = span->array->rgba8;
    946    }
    947    else {
    948       assert(srcType == GL_UNSIGNED_SHORT);
    949       src = span->array->rgba16;
    950    }
    951 
    952    if (newType == GL_UNSIGNED_BYTE) {
    953       dst = span->array->rgba8;
    954    }
    955    else if (newType == GL_UNSIGNED_SHORT) {
    956       dst = span->array->rgba16;
    957    }
    958    else {
    959       dst = span->array->attribs[VARYING_SLOT_COL0];
    960    }
    961 
    962    _mesa_convert_colors(span->array->ChanType, src,
    963                         newType, dst,
    964                         span->end, span->array->mask);
    965 
    966    span->array->ChanType = newType;
    967    span->array->rgba = dst;
    968 }
    969 
    970 
    971 
    972 /**
    973  * Apply fragment shader, fragment program or normal texturing to span.
    974  */
    975 static inline void
    976 shade_texture_span(struct gl_context *ctx, SWspan *span)
    977 {
    978    if (_swrast_use_fragment_program(ctx) ||
    979        ctx->ATIFragmentShader._Enabled) {
    980       /* programmable shading */
    981       if (span->primitive == GL_BITMAP && span->array->ChanType != GL_FLOAT) {
    982          convert_color_type(span, span->array->ChanType, GL_FLOAT, 0);
    983       }
    984       else {
    985          span->array->rgba = (void *) span->array->attribs[VARYING_SLOT_COL0];
    986       }
    987 
    988       if (span->primitive != GL_POINT ||
    989 	  (span->interpMask & SPAN_RGBA) ||
    990 	  ctx->Point.PointSprite) {
    991          /* for single-pixel points, we populated the arrays already */
    992          interpolate_active_attribs(ctx, span, ~0);
    993       }
    994       span->array->ChanType = GL_FLOAT;
    995 
    996       if (!(span->arrayMask & SPAN_Z))
    997          _swrast_span_interpolate_z (ctx, span);
    998 
    999 #if 0
   1000       if (inputsRead & VARYING_BIT_POS)
   1001 #else
   1002       /* XXX always interpolate wpos so that DDX/DDY work */
   1003 #endif
   1004          interpolate_wpos(ctx, span);
   1005 
   1006       /* Run fragment program/shader now */
   1007       if (_swrast_use_fragment_program(ctx)) {
   1008          _swrast_exec_fragment_program(ctx, span);
   1009       }
   1010       else {
   1011          assert(ctx->ATIFragmentShader._Enabled);
   1012          _swrast_exec_fragment_shader(ctx, span);
   1013       }
   1014    }
   1015    else if (ctx->Texture._EnabledCoordUnits) {
   1016       /* conventional texturing */
   1017 
   1018 #if CHAN_BITS == 32
   1019       if ((span->arrayAttribs & VARYING_BIT_COL0) == 0) {
   1020          interpolate_int_colors(ctx, span);
   1021       }
   1022 #else
   1023       if (!(span->arrayMask & SPAN_RGBA))
   1024          interpolate_int_colors(ctx, span);
   1025 #endif
   1026       if ((span->arrayAttribs & VARYING_BITS_TEX_ANY) == 0x0)
   1027          interpolate_texcoords(ctx, span);
   1028 
   1029       _swrast_texture_span(ctx, span);
   1030    }
   1031 }
   1032 
   1033 
   1034 /** Put colors at x/y locations into a renderbuffer */
   1035 static void
   1036 put_values(struct gl_context *ctx, struct gl_renderbuffer *rb,
   1037            GLenum datatype,
   1038            GLuint count, const GLint x[], const GLint y[],
   1039            const void *values, const GLubyte *mask)
   1040 {
   1041    gl_pack_ubyte_rgba_func pack_ubyte = NULL;
   1042    gl_pack_float_rgba_func pack_float = NULL;
   1043    GLuint i;
   1044 
   1045    if (datatype == GL_UNSIGNED_BYTE)
   1046       pack_ubyte = _mesa_get_pack_ubyte_rgba_function(rb->Format);
   1047    else
   1048       pack_float = _mesa_get_pack_float_rgba_function(rb->Format);
   1049 
   1050    for (i = 0; i < count; i++) {
   1051       if (mask[i]) {
   1052          GLubyte *dst = _swrast_pixel_address(rb, x[i], y[i]);
   1053 
   1054          if (datatype == GL_UNSIGNED_BYTE) {
   1055             pack_ubyte((const GLubyte *) values + 4 * i, dst);
   1056          }
   1057          else {
   1058             assert(datatype == GL_FLOAT);
   1059             pack_float((const GLfloat *) values + 4 * i, dst);
   1060          }
   1061       }
   1062    }
   1063 }
   1064 
   1065 
   1066 /** Put row of colors into renderbuffer */
   1067 void
   1068 _swrast_put_row(struct gl_context *ctx, struct gl_renderbuffer *rb,
   1069                 GLenum datatype,
   1070                 GLuint count, GLint x, GLint y,
   1071                 const void *values, const GLubyte *mask)
   1072 {
   1073    GLubyte *dst = _swrast_pixel_address(rb, x, y);
   1074 
   1075    if (!mask) {
   1076       if (datatype == GL_UNSIGNED_BYTE) {
   1077          _mesa_pack_ubyte_rgba_row(rb->Format, count,
   1078                                    (const GLubyte (*)[4]) values, dst);
   1079       }
   1080       else {
   1081          assert(datatype == GL_FLOAT);
   1082          _mesa_pack_float_rgba_row(rb->Format, count,
   1083                                    (const GLfloat (*)[4]) values, dst);
   1084       }
   1085    }
   1086    else {
   1087       const GLuint bpp = _mesa_get_format_bytes(rb->Format);
   1088       GLuint i, runLen, runStart;
   1089       /* We can't pass a 'mask' array to the _mesa_pack_rgba_row() functions
   1090        * so look for runs where mask=1...
   1091        */
   1092       runLen = runStart = 0;
   1093       for (i = 0; i < count; i++) {
   1094          if (mask[i]) {
   1095             if (runLen == 0)
   1096                runStart = i;
   1097             runLen++;
   1098          }
   1099 
   1100          if (!mask[i] || i == count - 1) {
   1101             /* might be the end of a run of pixels */
   1102             if (runLen > 0) {
   1103                if (datatype == GL_UNSIGNED_BYTE) {
   1104                   _mesa_pack_ubyte_rgba_row(rb->Format, runLen,
   1105                                      (const GLubyte (*)[4]) values + runStart,
   1106                                      dst + runStart * bpp);
   1107                }
   1108                else {
   1109                   assert(datatype == GL_FLOAT);
   1110                   _mesa_pack_float_rgba_row(rb->Format, runLen,
   1111                                    (const GLfloat (*)[4]) values + runStart,
   1112                                    dst + runStart * bpp);
   1113                }
   1114                runLen = 0;
   1115             }
   1116          }
   1117       }
   1118    }
   1119 }
   1120 
   1121 
   1122 
   1123 /**
   1124  * Apply all the per-fragment operations to a span.
   1125  * This now includes texturing (_swrast_write_texture_span() is history).
   1126  * This function may modify any of the array values in the span.
   1127  * span->interpMask and span->arrayMask may be changed but will be restored
   1128  * to their original values before returning.
   1129  */
   1130 void
   1131 _swrast_write_rgba_span( struct gl_context *ctx, SWspan *span)
   1132 {
   1133    const SWcontext *swrast = SWRAST_CONTEXT(ctx);
   1134    const GLuint *colorMask = (GLuint *) ctx->Color.ColorMask;
   1135    const GLbitfield origInterpMask = span->interpMask;
   1136    const GLbitfield origArrayMask = span->arrayMask;
   1137    const GLbitfield64 origArrayAttribs = span->arrayAttribs;
   1138    const GLenum origChanType = span->array->ChanType;
   1139    void * const origRgba = span->array->rgba;
   1140    const GLboolean shader = (_swrast_use_fragment_program(ctx)
   1141                              || ctx->ATIFragmentShader._Enabled);
   1142    const GLboolean shaderOrTexture = shader || ctx->Texture._EnabledCoordUnits;
   1143    struct gl_framebuffer *fb = ctx->DrawBuffer;
   1144 
   1145    /*
   1146    printf("%s()  interp 0x%x  array 0x%x\n", __func__,
   1147           span->interpMask, span->arrayMask);
   1148    */
   1149 
   1150    assert(span->primitive == GL_POINT ||
   1151           span->primitive == GL_LINE ||
   1152 	  span->primitive == GL_POLYGON ||
   1153           span->primitive == GL_BITMAP);
   1154 
   1155    /* Fragment write masks */
   1156    if (span->arrayMask & SPAN_MASK) {
   1157       /* mask was initialized by caller, probably glBitmap */
   1158       span->writeAll = GL_FALSE;
   1159    }
   1160    else {
   1161       memset(span->array->mask, 1, span->end);
   1162       span->writeAll = GL_TRUE;
   1163    }
   1164 
   1165    /* Clip to window/scissor box */
   1166    if (!clip_span(ctx, span)) {
   1167       return;
   1168    }
   1169 
   1170    assert(span->end <= SWRAST_MAX_WIDTH);
   1171 
   1172    /* Depth bounds test */
   1173    if (ctx->Depth.BoundsTest && fb->Visual.depthBits > 0) {
   1174       if (!_swrast_depth_bounds_test(ctx, span)) {
   1175          return;
   1176       }
   1177    }
   1178 
   1179 #ifdef DEBUG
   1180    /* Make sure all fragments are within window bounds */
   1181    if (span->arrayMask & SPAN_XY) {
   1182       /* array of pixel locations */
   1183       GLuint i;
   1184       for (i = 0; i < span->end; i++) {
   1185          if (span->array->mask[i]) {
   1186             assert(span->array->x[i] >= fb->_Xmin);
   1187             assert(span->array->x[i] < fb->_Xmax);
   1188             assert(span->array->y[i] >= fb->_Ymin);
   1189             assert(span->array->y[i] < fb->_Ymax);
   1190          }
   1191       }
   1192    }
   1193 #endif
   1194 
   1195    /* Polygon Stippling */
   1196    if (ctx->Polygon.StippleFlag && span->primitive == GL_POLYGON) {
   1197       stipple_polygon_span(ctx, span);
   1198    }
   1199 
   1200    /* This is the normal place to compute the fragment color/Z
   1201     * from texturing or shading.
   1202     */
   1203    if (shaderOrTexture && !swrast->_DeferredTexture) {
   1204       shade_texture_span(ctx, span);
   1205    }
   1206 
   1207    /* Do the alpha test */
   1208    if (ctx->Color.AlphaEnabled) {
   1209       if (!_swrast_alpha_test(ctx, span)) {
   1210          /* all fragments failed test */
   1211          goto end;
   1212       }
   1213    }
   1214 
   1215    /* Stencil and Z testing */
   1216    if (ctx->Stencil._Enabled || ctx->Depth.Test) {
   1217       if (!(span->arrayMask & SPAN_Z))
   1218          _swrast_span_interpolate_z(ctx, span);
   1219 
   1220       if (ctx->Transform.DepthClamp)
   1221 	 _swrast_depth_clamp_span(ctx, span);
   1222 
   1223       if (ctx->Stencil._Enabled) {
   1224          /* Combined Z/stencil tests */
   1225          if (!_swrast_stencil_and_ztest_span(ctx, span)) {
   1226             /* all fragments failed test */
   1227             goto end;
   1228          }
   1229       }
   1230       else if (fb->Visual.depthBits > 0) {
   1231          /* Just regular depth testing */
   1232          assert(ctx->Depth.Test);
   1233          assert(span->arrayMask & SPAN_Z);
   1234          if (!_swrast_depth_test_span(ctx, span)) {
   1235             /* all fragments failed test */
   1236             goto end;
   1237          }
   1238       }
   1239    }
   1240 
   1241    if (ctx->Query.CurrentOcclusionObject) {
   1242       /* update count of 'passed' fragments */
   1243       struct gl_query_object *q = ctx->Query.CurrentOcclusionObject;
   1244       GLuint i;
   1245       for (i = 0; i < span->end; i++)
   1246          q->Result += span->array->mask[i];
   1247    }
   1248 
   1249    /* We had to wait until now to check for glColorMask(0,0,0,0) because of
   1250     * the occlusion test.
   1251     */
   1252    if (fb->_NumColorDrawBuffers == 1 && colorMask[0] == 0x0) {
   1253       /* no colors to write */
   1254       goto end;
   1255    }
   1256 
   1257    /* If we were able to defer fragment color computation to now, there's
   1258     * a good chance that many fragments will have already been killed by
   1259     * Z/stencil testing.
   1260     */
   1261    if (shaderOrTexture && swrast->_DeferredTexture) {
   1262       shade_texture_span(ctx, span);
   1263    }
   1264 
   1265 #if CHAN_BITS == 32
   1266    if ((span->arrayAttribs & VARYING_BIT_COL0) == 0) {
   1267       interpolate_active_attribs(ctx, span, VARYING_BIT_COL0);
   1268    }
   1269 #else
   1270    if ((span->arrayMask & SPAN_RGBA) == 0) {
   1271       interpolate_int_colors(ctx, span);
   1272    }
   1273 #endif
   1274 
   1275    assert(span->arrayMask & SPAN_RGBA);
   1276 
   1277    if (span->primitive == GL_BITMAP || !swrast->SpecularVertexAdd) {
   1278       /* Add primary and specular (diffuse + specular) colors */
   1279       if (!shader) {
   1280          if (ctx->Fog.ColorSumEnabled ||
   1281              (ctx->Light.Enabled &&
   1282               ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR)) {
   1283             add_specular(ctx, span);
   1284          }
   1285       }
   1286    }
   1287 
   1288    /* Fog */
   1289    if (swrast->_FogEnabled) {
   1290       _swrast_fog_rgba_span(ctx, span);
   1291    }
   1292 
   1293    /* Antialias coverage application */
   1294    if (span->arrayMask & SPAN_COVERAGE) {
   1295       apply_aa_coverage(span);
   1296    }
   1297 
   1298    /* Clamp color/alpha values over the range [0.0, 1.0] before storage */
   1299    if (ctx->Color.ClampFragmentColor == GL_TRUE &&
   1300        span->array->ChanType == GL_FLOAT) {
   1301       clamp_colors(span);
   1302    }
   1303 
   1304    /*
   1305     * Write to renderbuffers.
   1306     * Depending on glDrawBuffer() state and the which color outputs are
   1307     * written by the fragment shader, we may either replicate one color to
   1308     * all renderbuffers or write a different color to each renderbuffer.
   1309     * multiFragOutputs=TRUE for the later case.
   1310     */
   1311    {
   1312       const GLuint numBuffers = fb->_NumColorDrawBuffers;
   1313       const struct gl_program *fp = ctx->FragmentProgram._Current;
   1314       const GLboolean multiFragOutputs =
   1315          _swrast_use_fragment_program(ctx)
   1316          && fp->info.outputs_written >= (1 << FRAG_RESULT_DATA0);
   1317       /* Save srcColorType because convert_color_type() can change it */
   1318       const GLenum srcColorType = span->array->ChanType;
   1319       GLuint buf;
   1320 
   1321       for (buf = 0; buf < numBuffers; buf++) {
   1322          struct gl_renderbuffer *rb = fb->_ColorDrawBuffers[buf];
   1323 
   1324          /* color[fragOutput] will be written to buffer[buf] */
   1325 
   1326          if (rb) {
   1327             /* re-use one of the attribute array buffers for rgbaSave */
   1328             GLchan (*rgbaSave)[4] = (GLchan (*)[4]) span->array->attribs[0];
   1329             struct swrast_renderbuffer *srb = swrast_renderbuffer(rb);
   1330             const GLenum dstColorType = srb->ColorType;
   1331 
   1332             assert(dstColorType == GL_UNSIGNED_BYTE ||
   1333                    dstColorType == GL_FLOAT);
   1334 
   1335             /* set span->array->rgba to colors for renderbuffer's datatype */
   1336             if (srcColorType != dstColorType) {
   1337                convert_color_type(span, srcColorType, dstColorType,
   1338                                   multiFragOutputs ? buf : 0);
   1339             }
   1340             else {
   1341                if (srcColorType == GL_UNSIGNED_BYTE) {
   1342                   span->array->rgba = span->array->rgba8;
   1343                }
   1344                else {
   1345                   span->array->rgba = (void *)
   1346                      span->array->attribs[VARYING_SLOT_COL0];
   1347                }
   1348             }
   1349 
   1350             if (!multiFragOutputs && numBuffers > 1) {
   1351                /* save colors for second, third renderbuffer writes */
   1352                memcpy(rgbaSave, span->array->rgba,
   1353                       4 * span->end * sizeof(GLchan));
   1354             }
   1355 
   1356             assert(rb->_BaseFormat == GL_RGBA ||
   1357                    rb->_BaseFormat == GL_RGB ||
   1358                    rb->_BaseFormat == GL_RED ||
   1359                    rb->_BaseFormat == GL_RG ||
   1360 		   rb->_BaseFormat == GL_ALPHA);
   1361 
   1362             if (ctx->Color.ColorLogicOpEnabled) {
   1363                _swrast_logicop_rgba_span(ctx, rb, span);
   1364             }
   1365             else if ((ctx->Color.BlendEnabled >> buf) & 1) {
   1366                _swrast_blend_span(ctx, rb, span);
   1367             }
   1368 
   1369             if (colorMask[buf] != 0xffffffff) {
   1370                _swrast_mask_rgba_span(ctx, rb, span, buf);
   1371             }
   1372 
   1373             if (span->arrayMask & SPAN_XY) {
   1374                /* array of pixel coords */
   1375                put_values(ctx, rb,
   1376                           span->array->ChanType, span->end,
   1377                           span->array->x, span->array->y,
   1378                           span->array->rgba, span->array->mask);
   1379             }
   1380             else {
   1381                /* horizontal run of pixels */
   1382                _swrast_put_row(ctx, rb,
   1383                                span->array->ChanType,
   1384                                span->end, span->x, span->y,
   1385                                span->array->rgba,
   1386                                span->writeAll ? NULL: span->array->mask);
   1387             }
   1388 
   1389             if (!multiFragOutputs && numBuffers > 1) {
   1390                /* restore original span values */
   1391                memcpy(span->array->rgba, rgbaSave,
   1392                       4 * span->end * sizeof(GLchan));
   1393             }
   1394 
   1395          } /* if rb */
   1396       } /* for buf */
   1397    }
   1398 
   1399 end:
   1400    /* restore these values before returning */
   1401    span->interpMask = origInterpMask;
   1402    span->arrayMask = origArrayMask;
   1403    span->arrayAttribs = origArrayAttribs;
   1404    span->array->ChanType = origChanType;
   1405    span->array->rgba = origRgba;
   1406 }
   1407 
   1408 
   1409 /**
   1410  * Read float RGBA pixels from a renderbuffer.  Clipping will be done to
   1411  * prevent reading ouside the buffer's boundaries.
   1412  * \param rgba  the returned colors
   1413  */
   1414 void
   1415 _swrast_read_rgba_span( struct gl_context *ctx, struct gl_renderbuffer *rb,
   1416                         GLuint n, GLint x, GLint y,
   1417                         GLvoid *rgba)
   1418 {
   1419    struct swrast_renderbuffer *srb = swrast_renderbuffer(rb);
   1420    GLenum dstType = GL_FLOAT;
   1421    const GLint bufWidth = (GLint) rb->Width;
   1422    const GLint bufHeight = (GLint) rb->Height;
   1423 
   1424    if (y < 0 || y >= bufHeight || x + (GLint) n < 0 || x >= bufWidth) {
   1425       /* completely above, below, or right */
   1426       /* XXX maybe leave rgba values undefined? */
   1427       memset(rgba, 0, 4 * n * sizeof(GLchan));
   1428    }
   1429    else {
   1430       GLint skip, length;
   1431       GLubyte *src;
   1432 
   1433       if (x < 0) {
   1434          /* left edge clipping */
   1435          skip = -x;
   1436          length = (GLint) n - skip;
   1437          if (length < 0) {
   1438             /* completely left of window */
   1439             return;
   1440          }
   1441          if (length > bufWidth) {
   1442             length = bufWidth;
   1443          }
   1444       }
   1445       else if ((GLint) (x + n) > bufWidth) {
   1446          /* right edge clipping */
   1447          skip = 0;
   1448          length = bufWidth - x;
   1449          if (length < 0) {
   1450             /* completely to right of window */
   1451             return;
   1452          }
   1453       }
   1454       else {
   1455          /* no clipping */
   1456          skip = 0;
   1457          length = (GLint) n;
   1458       }
   1459 
   1460       assert(rb);
   1461       assert(rb->_BaseFormat == GL_RGBA ||
   1462 	     rb->_BaseFormat == GL_RGB ||
   1463 	     rb->_BaseFormat == GL_RG ||
   1464 	     rb->_BaseFormat == GL_RED ||
   1465 	     rb->_BaseFormat == GL_LUMINANCE ||
   1466 	     rb->_BaseFormat == GL_INTENSITY ||
   1467 	     rb->_BaseFormat == GL_LUMINANCE_ALPHA ||
   1468 	     rb->_BaseFormat == GL_ALPHA);
   1469 
   1470       assert(srb->Map);
   1471       (void) srb; /* silence unused var warning */
   1472 
   1473       src = _swrast_pixel_address(rb, x + skip, y);
   1474 
   1475       if (dstType == GL_UNSIGNED_BYTE) {
   1476          _mesa_unpack_ubyte_rgba_row(rb->Format, length, src,
   1477                                      (GLubyte (*)[4]) rgba + skip);
   1478       }
   1479       else if (dstType == GL_FLOAT) {
   1480          _mesa_unpack_rgba_row(rb->Format, length, src,
   1481                                (GLfloat (*)[4]) rgba + skip);
   1482       }
   1483       else {
   1484          _mesa_problem(ctx, "unexpected type in _swrast_read_rgba_span()");
   1485       }
   1486    }
   1487 }
   1488 
   1489 
   1490 /**
   1491  * Get colors at x/y positions with clipping.
   1492  * \param type  type of values to return
   1493  */
   1494 static void
   1495 get_values(struct gl_context *ctx, struct gl_renderbuffer *rb,
   1496            GLuint count, const GLint x[], const GLint y[],
   1497            void *values, GLenum type)
   1498 {
   1499    GLuint i;
   1500 
   1501    for (i = 0; i < count; i++) {
   1502       if (x[i] >= 0 && y[i] >= 0 &&
   1503 	  x[i] < (GLint) rb->Width && y[i] < (GLint) rb->Height) {
   1504          /* inside */
   1505          const GLubyte *src = _swrast_pixel_address(rb, x[i], y[i]);
   1506 
   1507          if (type == GL_UNSIGNED_BYTE) {
   1508             _mesa_unpack_ubyte_rgba_row(rb->Format, 1, src,
   1509                                         (GLubyte (*)[4]) values + i);
   1510          }
   1511          else if (type == GL_FLOAT) {
   1512             _mesa_unpack_rgba_row(rb->Format, 1, src,
   1513                                   (GLfloat (*)[4]) values + i);
   1514          }
   1515          else {
   1516             _mesa_problem(ctx, "unexpected type in get_values()");
   1517          }
   1518       }
   1519    }
   1520 }
   1521 
   1522 
   1523 /**
   1524  * Get row of colors with clipping.
   1525  * \param type  type of values to return
   1526  */
   1527 static void
   1528 get_row(struct gl_context *ctx, struct gl_renderbuffer *rb,
   1529         GLuint count, GLint x, GLint y,
   1530         GLvoid *values, GLenum type)
   1531 {
   1532    GLint skip = 0;
   1533    GLubyte *src;
   1534 
   1535    if (y < 0 || y >= (GLint) rb->Height)
   1536       return; /* above or below */
   1537 
   1538    if (x + (GLint) count <= 0 || x >= (GLint) rb->Width)
   1539       return; /* entirely left or right */
   1540 
   1541    if (x + count > rb->Width) {
   1542       /* right clip */
   1543       GLint clip = x + count - rb->Width;
   1544       count -= clip;
   1545    }
   1546 
   1547    if (x < 0) {
   1548       /* left clip */
   1549       skip = -x;
   1550       x = 0;
   1551       count -= skip;
   1552    }
   1553 
   1554    src = _swrast_pixel_address(rb, x, y);
   1555 
   1556    if (type == GL_UNSIGNED_BYTE) {
   1557       _mesa_unpack_ubyte_rgba_row(rb->Format, count, src,
   1558                                   (GLubyte (*)[4]) values + skip);
   1559    }
   1560    else if (type == GL_FLOAT) {
   1561       _mesa_unpack_rgba_row(rb->Format, count, src,
   1562                             (GLfloat (*)[4]) values + skip);
   1563    }
   1564    else {
   1565       _mesa_problem(ctx, "unexpected type in get_row()");
   1566    }
   1567 }
   1568 
   1569 
   1570 /**
   1571  * Get RGBA pixels from the given renderbuffer.
   1572  * Used by blending, logicop and masking functions.
   1573  * \return pointer to the colors we read.
   1574  */
   1575 void *
   1576 _swrast_get_dest_rgba(struct gl_context *ctx, struct gl_renderbuffer *rb,
   1577                       SWspan *span)
   1578 {
   1579    void *rbPixels;
   1580 
   1581    /* Point rbPixels to a temporary space */
   1582    rbPixels = span->array->attribs[VARYING_SLOT_MAX - 1];
   1583 
   1584    /* Get destination values from renderbuffer */
   1585    if (span->arrayMask & SPAN_XY) {
   1586       get_values(ctx, rb, span->end, span->array->x, span->array->y,
   1587                  rbPixels, span->array->ChanType);
   1588    }
   1589    else {
   1590       get_row(ctx, rb, span->end, span->x, span->y,
   1591               rbPixels, span->array->ChanType);
   1592    }
   1593 
   1594    return rbPixels;
   1595 }
   1596