Subversion Repositories Kolibri OS

Rev

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 "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.0 &&
  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.0, 255.0);
  890.          assert(coverage[i] >= 0.0);
  891.          assert(coverage[i] <= 1.0);
  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.0, 65535.0);
  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_fragment_program *fp = ctx->FragmentProgram._Current;
  1314.       const GLboolean multiFragOutputs =
  1315.          _swrast_use_fragment_program(ctx)
  1316.          && fp->Base.OutputsWritten >= (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.