Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

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