ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

s_span.c
Go to the documentation of this file.
00001 /*
00002  * Mesa 3-D graphics library
00003  * Version:  7.1
00004  *
00005  * Copyright (C) 1999-2007  Brian Paul   All Rights Reserved.
00006  *
00007  * Permission is hereby granted, free of charge, to any person obtaining a
00008  * copy of this software and associated documentation files (the "Software"),
00009  * to deal in the Software without restriction, including without limitation
00010  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
00011  * and/or sell copies of the Software, and to permit persons to whom the
00012  * Software is furnished to do so, subject to the following conditions:
00013  *
00014  * The above copyright notice and this permission notice shall be included
00015  * in all copies or substantial portions of the Software.
00016  *
00017  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
00018  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00019  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
00020  * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
00021  * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
00022  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00023  */
00024 
00025 
00033 #include "main/glheader.h"
00034 #include "main/colormac.h"
00035 #include "main/context.h"
00036 #include "main/macros.h"
00037 #include "main/imports.h"
00038 #include "main/image.h"
00039 
00040 #include "s_atifragshader.h"
00041 #include "s_alpha.h"
00042 #include "s_blend.h"
00043 #include "s_context.h"
00044 #include "s_depth.h"
00045 #include "s_fog.h"
00046 #include "s_logic.h"
00047 #include "s_masking.h"
00048 #include "s_fragprog.h"
00049 #include "s_span.h"
00050 #include "s_stencil.h"
00051 #include "s_texcombine.h"
00052 
00053 
00059 void
00060 _swrast_span_default_attribs(GLcontext *ctx, SWspan *span)
00061 {
00062    /* Z*/
00063    {
00064       const GLfloat depthMax = ctx->DrawBuffer->_DepthMaxF;
00065       if (ctx->DrawBuffer->Visual.depthBits <= 16)
00066          span->z = FloatToFixed(ctx->Current.RasterPos[2] * depthMax + 0.5F);
00067       else {
00068          GLfloat tmpf = ctx->Current.RasterPos[2] * depthMax; 
00069          tmpf = MIN2(tmpf, depthMax);
00070          span->z = (GLint)tmpf;
00071       }
00072       span->zStep = 0;
00073       span->interpMask |= SPAN_Z;
00074    }
00075 
00076    /* W (for perspective correction) */
00077    span->attrStart[FRAG_ATTRIB_WPOS][3] = 1.0;
00078    span->attrStepX[FRAG_ATTRIB_WPOS][3] = 0.0;
00079    span->attrStepY[FRAG_ATTRIB_WPOS][3] = 0.0;
00080 
00081    /* primary color, or color index */
00082    if (ctx->Visual.rgbMode) {
00083       GLchan r, g, b, a;
00084       UNCLAMPED_FLOAT_TO_CHAN(r, ctx->Current.RasterColor[0]);
00085       UNCLAMPED_FLOAT_TO_CHAN(g, ctx->Current.RasterColor[1]);
00086       UNCLAMPED_FLOAT_TO_CHAN(b, ctx->Current.RasterColor[2]);
00087       UNCLAMPED_FLOAT_TO_CHAN(a, ctx->Current.RasterColor[3]);
00088 #if CHAN_TYPE == GL_FLOAT
00089       span->red = r;
00090       span->green = g;
00091       span->blue = b;
00092       span->alpha = a;
00093 #else
00094       span->red   = IntToFixed(r);
00095       span->green = IntToFixed(g);
00096       span->blue  = IntToFixed(b);
00097       span->alpha = IntToFixed(a);
00098 #endif
00099       span->redStep = 0;
00100       span->greenStep = 0;
00101       span->blueStep = 0;
00102       span->alphaStep = 0;
00103       span->interpMask |= SPAN_RGBA;
00104 
00105       COPY_4V(span->attrStart[FRAG_ATTRIB_COL0], ctx->Current.RasterColor);
00106       ASSIGN_4V(span->attrStepX[FRAG_ATTRIB_COL0], 0.0, 0.0, 0.0, 0.0);
00107       ASSIGN_4V(span->attrStepY[FRAG_ATTRIB_COL0], 0.0, 0.0, 0.0, 0.0);
00108    }
00109    else {
00110       span->index = FloatToFixed(ctx->Current.RasterIndex);
00111       span->indexStep = 0;
00112       span->interpMask |= SPAN_INDEX;
00113    }
00114 
00115    /* Secondary color */
00116    if (ctx->Visual.rgbMode && (ctx->Light.Enabled || ctx->Fog.ColorSumEnabled))
00117    {
00118       COPY_4V(span->attrStart[FRAG_ATTRIB_COL1], ctx->Current.RasterSecondaryColor);
00119       ASSIGN_4V(span->attrStepX[FRAG_ATTRIB_COL1], 0.0, 0.0, 0.0, 0.0);
00120       ASSIGN_4V(span->attrStepY[FRAG_ATTRIB_COL1], 0.0, 0.0, 0.0, 0.0);
00121    }
00122 
00123    /* fog */
00124    {
00125       const SWcontext *swrast = SWRAST_CONTEXT(ctx);
00126       GLfloat fogVal; /* a coord or a blend factor */
00127       if (swrast->_PreferPixelFog) {
00128          /* fog blend factors will be computed from fog coordinates per pixel */
00129          fogVal = ctx->Current.RasterDistance;
00130       }
00131       else {
00132          /* fog blend factor should be computed from fogcoord now */
00133          fogVal = _swrast_z_to_fogfactor(ctx, ctx->Current.RasterDistance);
00134       }
00135       span->attrStart[FRAG_ATTRIB_FOGC][0] = fogVal;
00136       span->attrStepX[FRAG_ATTRIB_FOGC][0] = 0.0;
00137       span->attrStepY[FRAG_ATTRIB_FOGC][0] = 0.0;
00138    }
00139 
00140    /* texcoords */
00141    {
00142       GLuint i;
00143       for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) {
00144          const GLuint attr = FRAG_ATTRIB_TEX0 + i;
00145          const GLfloat *tc = ctx->Current.RasterTexCoords[i];
00146          if (ctx->FragmentProgram._Current || ctx->ATIFragmentShader._Enabled) {
00147             COPY_4V(span->attrStart[attr], tc);
00148          }
00149          else if (tc[3] > 0.0F) {
00150             /* use (s/q, t/q, r/q, 1) */
00151             span->attrStart[attr][0] = tc[0] / tc[3];
00152             span->attrStart[attr][1] = tc[1] / tc[3];
00153             span->attrStart[attr][2] = tc[2] / tc[3];
00154             span->attrStart[attr][3] = 1.0;
00155          }
00156          else {
00157             ASSIGN_4V(span->attrStart[attr], 0.0F, 0.0F, 0.0F, 1.0F);
00158          }
00159          ASSIGN_4V(span->attrStepX[attr], 0.0F, 0.0F, 0.0F, 0.0F);
00160          ASSIGN_4V(span->attrStepY[attr], 0.0F, 0.0F, 0.0F, 0.0F);
00161       }
00162    }
00163 }
00164 
00165 
00172 static INLINE void
00173 interpolate_active_attribs(GLcontext *ctx, SWspan *span, GLbitfield attrMask)
00174 {
00175    const SWcontext *swrast = SWRAST_CONTEXT(ctx);
00176 
00177    /*
00178     * Don't overwrite existing array values, such as colors that may have
00179     * been produced by glDraw/CopyPixels.
00180     */
00181    attrMask &= ~span->arrayAttribs;
00182 
00183    ATTRIB_LOOP_BEGIN
00184       if (attrMask & (1 << attr)) {
00185          const GLfloat dwdx = span->attrStepX[FRAG_ATTRIB_WPOS][3];
00186          GLfloat w = span->attrStart[FRAG_ATTRIB_WPOS][3];
00187          const GLfloat dv0dx = span->attrStepX[attr][0];
00188          const GLfloat dv1dx = span->attrStepX[attr][1];
00189          const GLfloat dv2dx = span->attrStepX[attr][2];
00190          const GLfloat dv3dx = span->attrStepX[attr][3];
00191          GLfloat v0 = span->attrStart[attr][0];
00192          GLfloat v1 = span->attrStart[attr][1];
00193          GLfloat v2 = span->attrStart[attr][2];
00194          GLfloat v3 = span->attrStart[attr][3];
00195          GLuint k;
00196          for (k = 0; k < span->end; k++) {
00197             const GLfloat invW = 1.0f / w;
00198             span->array->attribs[attr][k][0] = v0 * invW;
00199             span->array->attribs[attr][k][1] = v1 * invW;
00200             span->array->attribs[attr][k][2] = v2 * invW;
00201             span->array->attribs[attr][k][3] = v3 * invW;
00202             v0 += dv0dx;
00203             v1 += dv1dx;
00204             v2 += dv2dx;
00205             v3 += dv3dx;
00206             w += dwdx;
00207          }
00208          ASSERT((span->arrayAttribs & (1 << attr)) == 0);
00209          span->arrayAttribs |= (1 << attr);
00210       }
00211    ATTRIB_LOOP_END
00212 }
00213 
00214 
00219 static INLINE void
00220 interpolate_int_colors(GLcontext *ctx, SWspan *span)
00221 {
00222    const GLuint n = span->end;
00223    GLuint i;
00224 
00225 #if CHAN_BITS != 32
00226    ASSERT(!(span->arrayMask & SPAN_RGBA));
00227 #endif
00228 
00229    switch (span->array->ChanType) {
00230 #if CHAN_BITS != 32
00231    case GL_UNSIGNED_BYTE:
00232       {
00233          GLubyte (*rgba)[4] = span->array->rgba8;
00234          if (span->interpMask & SPAN_FLAT) {
00235             GLubyte color[4];
00236             color[RCOMP] = FixedToInt(span->red);
00237             color[GCOMP] = FixedToInt(span->green);
00238             color[BCOMP] = FixedToInt(span->blue);
00239             color[ACOMP] = FixedToInt(span->alpha);
00240             for (i = 0; i < n; i++) {
00241                COPY_4UBV(rgba[i], color);
00242             }
00243          }
00244          else {
00245             GLfixed r = span->red;
00246             GLfixed g = span->green;
00247             GLfixed b = span->blue;
00248             GLfixed a = span->alpha;
00249             GLint dr = span->redStep;
00250             GLint dg = span->greenStep;
00251             GLint db = span->blueStep;
00252             GLint da = span->alphaStep;
00253             for (i = 0; i < n; i++) {
00254                rgba[i][RCOMP] = FixedToChan(r);
00255                rgba[i][GCOMP] = FixedToChan(g);
00256                rgba[i][BCOMP] = FixedToChan(b);
00257                rgba[i][ACOMP] = FixedToChan(a);
00258                r += dr;
00259                g += dg;
00260                b += db;
00261                a += da;
00262             }
00263          }
00264       }
00265       break;
00266    case GL_UNSIGNED_SHORT:
00267       {
00268          GLushort (*rgba)[4] = span->array->rgba16;
00269          if (span->interpMask & SPAN_FLAT) {
00270             GLushort color[4];
00271             color[RCOMP] = FixedToInt(span->red);
00272             color[GCOMP] = FixedToInt(span->green);
00273             color[BCOMP] = FixedToInt(span->blue);
00274             color[ACOMP] = FixedToInt(span->alpha);
00275             for (i = 0; i < n; i++) {
00276                COPY_4V(rgba[i], color);
00277             }
00278          }
00279          else {
00280             GLushort (*rgba)[4] = span->array->rgba16;
00281             GLfixed r, g, b, a;
00282             GLint dr, dg, db, da;
00283             r = span->red;
00284             g = span->green;
00285             b = span->blue;
00286             a = span->alpha;
00287             dr = span->redStep;
00288             dg = span->greenStep;
00289             db = span->blueStep;
00290             da = span->alphaStep;
00291             for (i = 0; i < n; i++) {
00292                rgba[i][RCOMP] = FixedToChan(r);
00293                rgba[i][GCOMP] = FixedToChan(g);
00294                rgba[i][BCOMP] = FixedToChan(b);
00295                rgba[i][ACOMP] = FixedToChan(a);
00296                r += dr;
00297                g += dg;
00298                b += db;
00299                a += da;
00300             }
00301          }
00302       }
00303       break;
00304 #endif
00305    case GL_FLOAT:
00306       interpolate_active_attribs(ctx, span, FRAG_BIT_COL0);
00307       break;
00308    default:
00309       _mesa_problem(NULL, "bad datatype in interpolate_int_colors");
00310    }
00311    span->arrayMask |= SPAN_RGBA;
00312 }
00313 
00314 
00318 static INLINE void
00319 interpolate_float_colors(SWspan *span)
00320 {
00321    GLfloat (*col0)[4] = span->array->attribs[FRAG_ATTRIB_COL0];
00322    const GLuint n = span->end;
00323    GLuint i;
00324 
00325    assert(!(span->arrayAttribs & FRAG_BIT_COL0));
00326 
00327    if (span->arrayMask & SPAN_RGBA) {
00328       /* convert array of int colors */
00329       for (i = 0; i < n; i++) {
00330          col0[i][0] = UBYTE_TO_FLOAT(span->array->rgba8[i][0]);
00331          col0[i][1] = UBYTE_TO_FLOAT(span->array->rgba8[i][1]);
00332          col0[i][2] = UBYTE_TO_FLOAT(span->array->rgba8[i][2]);
00333          col0[i][3] = UBYTE_TO_FLOAT(span->array->rgba8[i][3]);
00334       }
00335    }
00336    else {
00337       /* interpolate red/green/blue/alpha to get float colors */
00338       ASSERT(span->interpMask & SPAN_RGBA);
00339       if (span->interpMask & SPAN_FLAT) {
00340          GLfloat r = FixedToFloat(span->red);
00341          GLfloat g = FixedToFloat(span->green);
00342          GLfloat b = FixedToFloat(span->blue);
00343          GLfloat a = FixedToFloat(span->alpha);
00344          for (i = 0; i < n; i++) {
00345             ASSIGN_4V(col0[i], r, g, b, a);
00346          }
00347       }
00348       else {
00349          GLfloat r = FixedToFloat(span->red);
00350          GLfloat g = FixedToFloat(span->green);
00351          GLfloat b = FixedToFloat(span->blue);
00352          GLfloat a = FixedToFloat(span->alpha);
00353          GLfloat dr = FixedToFloat(span->redStep);
00354          GLfloat dg = FixedToFloat(span->greenStep);
00355          GLfloat db = FixedToFloat(span->blueStep);
00356          GLfloat da = FixedToFloat(span->alphaStep);
00357          for (i = 0; i < n; i++) {
00358             col0[i][0] = r;
00359             col0[i][1] = g;
00360             col0[i][2] = b;
00361             col0[i][3] = a;
00362             r += dr;
00363             g += dg;
00364             b += db;
00365             a += da;
00366          }
00367       }
00368    }
00369 
00370    span->arrayAttribs |= FRAG_BIT_COL0;
00371    span->array->ChanType = GL_FLOAT;
00372 }
00373 
00374 
00375 
00376 /* Fill in the span.color.index array from the interpolation values */
00377 static INLINE void
00378 interpolate_indexes(GLcontext *ctx, SWspan *span)
00379 {
00380    GLfixed index = span->index;
00381    const GLint indexStep = span->indexStep;
00382    const GLuint n = span->end;
00383    GLuint *indexes = span->array->index;
00384    GLuint i;
00385    (void) ctx;
00386 
00387    ASSERT(!(span->arrayMask & SPAN_INDEX));
00388 
00389    if ((span->interpMask & SPAN_FLAT) || (indexStep == 0)) {
00390       /* constant color */
00391       index = FixedToInt(index);
00392       for (i = 0; i < n; i++) {
00393          indexes[i] = index;
00394       }
00395    }
00396    else {
00397       /* interpolate */
00398       for (i = 0; i < n; i++) {
00399          indexes[i] = FixedToInt(index);
00400          index += indexStep;
00401       }
00402    }
00403    span->arrayMask |= SPAN_INDEX;
00404    span->interpMask &= ~SPAN_INDEX;
00405 }
00406 
00407 
00411 void
00412 _swrast_span_interpolate_z( const GLcontext *ctx, SWspan *span )
00413 {
00414    const GLuint n = span->end;
00415    GLuint i;
00416 
00417    ASSERT(!(span->arrayMask & SPAN_Z));
00418 
00419    if (ctx->DrawBuffer->Visual.depthBits <= 16) {
00420       GLfixed zval = span->z;
00421       GLuint *z = span->array->z; 
00422       for (i = 0; i < n; i++) {
00423          z[i] = FixedToInt(zval);
00424          zval += span->zStep;
00425       }
00426    }
00427    else {
00428       /* Deep Z buffer, no fixed->int shift */
00429       GLuint zval = span->z;
00430       GLuint *z = span->array->z;
00431       for (i = 0; i < n; i++) {
00432          z[i] = zval;
00433          zval += span->zStep;
00434       }
00435    }
00436    span->interpMask &= ~SPAN_Z;
00437    span->arrayMask |= SPAN_Z;
00438 }
00439 
00440 
00445 GLfloat
00446 _swrast_compute_lambda(GLfloat dsdx, GLfloat dsdy, GLfloat dtdx, GLfloat dtdy,
00447                        GLfloat dqdx, GLfloat dqdy, GLfloat texW, GLfloat texH,
00448                        GLfloat s, GLfloat t, GLfloat q, GLfloat invQ)
00449 {
00450    GLfloat dudx = texW * ((s + dsdx) / (q + dqdx) - s * invQ);
00451    GLfloat dvdx = texH * ((t + dtdx) / (q + dqdx) - t * invQ);
00452    GLfloat dudy = texW * ((s + dsdy) / (q + dqdy) - s * invQ);
00453    GLfloat dvdy = texH * ((t + dtdy) / (q + dqdy) - t * invQ);
00454    GLfloat x = SQRTF(dudx * dudx + dvdx * dvdx);
00455    GLfloat y = SQRTF(dudy * dudy + dvdy * dvdy);
00456    GLfloat rho = MAX2(x, y);
00457    GLfloat lambda = LOG2(rho);
00458    return lambda;
00459 }
00460 
00461 
00466 #if 0
00467 GLfloat
00468 _swrast_compute_lambda(GLfloat dsdx, GLfloat dsdy, GLfloat dtdx, GLfloat dtdy,
00469                      GLfloat dqdx, GLfloat dqdy, GLfloat texW, GLfloat texH,
00470                      GLfloat s, GLfloat t, GLfloat q, GLfloat invQ)
00471 {
00472    GLfloat dsdx2 = (s + dsdx) / (q + dqdx) - s * invQ;
00473    GLfloat dtdx2 = (t + dtdx) / (q + dqdx) - t * invQ;
00474    GLfloat dsdy2 = (s + dsdy) / (q + dqdy) - s * invQ;
00475    GLfloat dtdy2 = (t + dtdy) / (q + dqdy) - t * invQ;
00476    GLfloat maxU, maxV, rho, lambda;
00477    dsdx2 = FABSF(dsdx2);
00478    dsdy2 = FABSF(dsdy2);
00479    dtdx2 = FABSF(dtdx2);
00480    dtdy2 = FABSF(dtdy2);
00481    maxU = MAX2(dsdx2, dsdy2) * texW;
00482    maxV = MAX2(dtdx2, dtdy2) * texH;
00483    rho = MAX2(maxU, maxV);
00484    lambda = LOG2(rho);
00485    return lambda;
00486 }
00487 #endif
00488 
00489 
00501 static void
00502 interpolate_texcoords(GLcontext *ctx, SWspan *span)
00503 {
00504    const GLuint maxUnit
00505       = (ctx->Texture._EnabledCoordUnits > 1) ? ctx->Const.MaxTextureUnits : 1;
00506    GLuint u;
00507 
00508    /* XXX CoordUnits vs. ImageUnits */
00509    for (u = 0; u < maxUnit; u++) {
00510       if (ctx->Texture._EnabledCoordUnits & (1 << u)) {
00511          const GLuint attr = FRAG_ATTRIB_TEX0 + u;
00512          const struct gl_texture_object *obj = ctx->Texture.Unit[u]._Current;
00513          GLfloat texW, texH;
00514          GLboolean needLambda;
00515          GLfloat (*texcoord)[4] = span->array->attribs[attr];
00516          GLfloat *lambda = span->array->lambda[u];
00517          const GLfloat dsdx = span->attrStepX[attr][0];
00518          const GLfloat dsdy = span->attrStepY[attr][0];
00519          const GLfloat dtdx = span->attrStepX[attr][1];
00520          const GLfloat dtdy = span->attrStepY[attr][1];
00521          const GLfloat drdx = span->attrStepX[attr][2];
00522          const GLfloat dqdx = span->attrStepX[attr][3];
00523          const GLfloat dqdy = span->attrStepY[attr][3];
00524          GLfloat s = span->attrStart[attr][0];
00525          GLfloat t = span->attrStart[attr][1];
00526          GLfloat r = span->attrStart[attr][2];
00527          GLfloat q = span->attrStart[attr][3];
00528 
00529          if (obj) {
00530             const struct gl_texture_image *img = obj->Image[0][obj->BaseLevel];
00531             needLambda = (obj->MinFilter != obj->MagFilter)
00532                || ctx->FragmentProgram._Current;
00533             texW = img->WidthScale;
00534             texH = img->HeightScale;
00535          }
00536          else {
00537             /* using a fragment program */
00538             texW = 1.0;
00539             texH = 1.0;
00540             needLambda = GL_FALSE;
00541          }
00542 
00543          if (needLambda) {
00544             GLuint i;
00545             if (ctx->FragmentProgram._Current
00546                 || ctx->ATIFragmentShader._Enabled) {
00547                /* do perspective correction but don't divide s, t, r by q */
00548                const GLfloat dwdx = span->attrStepX[FRAG_ATTRIB_WPOS][3];
00549                GLfloat w = span->attrStart[FRAG_ATTRIB_WPOS][3];
00550                for (i = 0; i < span->end; i++) {
00551                   const GLfloat invW = 1.0F / w;
00552                   texcoord[i][0] = s * invW;
00553                   texcoord[i][1] = t * invW;
00554                   texcoord[i][2] = r * invW;
00555                   texcoord[i][3] = q * invW;
00556                   lambda[i] = _swrast_compute_lambda(dsdx, dsdy, dtdx, dtdy,
00557                                                      dqdx, dqdy, texW, texH,
00558                                                      s, t, q, invW);
00559                   s += dsdx;
00560                   t += dtdx;
00561                   r += drdx;
00562                   q += dqdx;
00563                   w += dwdx;
00564                }
00565             }
00566             else {
00567                for (i = 0; i < span->end; i++) {
00568                   const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q);
00569                   texcoord[i][0] = s * invQ;
00570                   texcoord[i][1] = t * invQ;
00571                   texcoord[i][2] = r * invQ;
00572                   texcoord[i][3] = q;
00573                   lambda[i] = _swrast_compute_lambda(dsdx, dsdy, dtdx, dtdy,
00574                                                      dqdx, dqdy, texW, texH,
00575                                                      s, t, q, invQ);
00576                   s += dsdx;
00577                   t += dtdx;
00578                   r += drdx;
00579                   q += dqdx;
00580                }
00581             }
00582             span->arrayMask |= SPAN_LAMBDA;
00583          }
00584          else {
00585             GLuint i;
00586             if (ctx->FragmentProgram._Current ||
00587                 ctx->ATIFragmentShader._Enabled) {
00588                /* do perspective correction but don't divide s, t, r by q */
00589                const GLfloat dwdx = span->attrStepX[FRAG_ATTRIB_WPOS][3];
00590                GLfloat w = span->attrStart[FRAG_ATTRIB_WPOS][3];
00591                for (i = 0; i < span->end; i++) {
00592                   const GLfloat invW = 1.0F / w;
00593                   texcoord[i][0] = s * invW;
00594                   texcoord[i][1] = t * invW;
00595                   texcoord[i][2] = r * invW;
00596                   texcoord[i][3] = q * invW;
00597                   lambda[i] = 0.0;
00598                   s += dsdx;
00599                   t += dtdx;
00600                   r += drdx;
00601                   q += dqdx;
00602                   w += dwdx;
00603                }
00604             }
00605             else if (dqdx == 0.0F) {
00606                /* Ortho projection or polygon's parallel to window X axis */
00607                const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q);
00608                for (i = 0; i < span->end; i++) {
00609                   texcoord[i][0] = s * invQ;
00610                   texcoord[i][1] = t * invQ;
00611                   texcoord[i][2] = r * invQ;
00612                   texcoord[i][3] = q;
00613                   lambda[i] = 0.0;
00614                   s += dsdx;
00615                   t += dtdx;
00616                   r += drdx;
00617                }
00618             }
00619             else {
00620                for (i = 0; i < span->end; i++) {
00621                   const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q);
00622                   texcoord[i][0] = s * invQ;
00623                   texcoord[i][1] = t * invQ;
00624                   texcoord[i][2] = r * invQ;
00625                   texcoord[i][3] = q;
00626                   lambda[i] = 0.0;
00627                   s += dsdx;
00628                   t += dtdx;
00629                   r += drdx;
00630                   q += dqdx;
00631                }
00632             }
00633          } /* lambda */
00634       } /* if */
00635    } /* for */
00636 }
00637 
00638 
00642 static INLINE void
00643 interpolate_wpos(GLcontext *ctx, SWspan *span)
00644 {
00645    GLfloat (*wpos)[4] = span->array->attribs[FRAG_ATTRIB_WPOS];
00646    GLuint i;
00647    const GLfloat zScale = 1.0 / ctx->DrawBuffer->_DepthMaxF;
00648    GLfloat w, dw;
00649 
00650    if (span->arrayMask & SPAN_XY) {
00651       for (i = 0; i < span->end; i++) {
00652          wpos[i][0] = (GLfloat) span->array->x[i];
00653          wpos[i][1] = (GLfloat) span->array->y[i];
00654       }
00655    }
00656    else {
00657       for (i = 0; i < span->end; i++) {
00658          wpos[i][0] = (GLfloat) span->x + i;
00659          wpos[i][1] = (GLfloat) span->y;
00660       }
00661    }
00662 
00663    w = span->attrStart[FRAG_ATTRIB_WPOS][3];
00664    dw = span->attrStepX[FRAG_ATTRIB_WPOS][3];
00665    for (i = 0; i < span->end; i++) {
00666       wpos[i][2] = (GLfloat) span->array->z[i] * zScale;
00667       wpos[i][3] = w;
00668       w += dw;
00669    }
00670 }
00671 
00672 
00676 static INLINE void
00677 stipple_polygon_span(GLcontext *ctx, SWspan *span)
00678 {
00679    GLubyte *mask = span->array->mask;
00680 
00681    ASSERT(ctx->Polygon.StippleFlag);
00682 
00683    if (span->arrayMask & SPAN_XY) {
00684       /* arrays of x/y pixel coords */
00685       GLuint i;
00686       for (i = 0; i < span->end; i++) {
00687          const GLint col = span->array->x[i] % 32;
00688          const GLint row = span->array->y[i] % 32;
00689          const GLuint stipple = ctx->PolygonStipple[row];
00690          if (((1 << col) & stipple) == 0) {
00691             mask[i] = 0;
00692          }
00693       }
00694    }
00695    else {
00696       /* horizontal span of pixels */
00697       const GLuint highBit = 1 << 31;
00698       const GLuint stipple = ctx->PolygonStipple[span->y % 32];
00699       GLuint i, m = highBit >> (GLuint) (span->x % 32);
00700       for (i = 0; i < span->end; i++) {
00701          if ((m & stipple) == 0) {
00702             mask[i] = 0;
00703          }
00704          m = m >> 1;
00705          if (m == 0) {
00706             m = highBit;
00707          }
00708       }
00709    }
00710    span->writeAll = GL_FALSE;
00711 }
00712 
00713 
00721 static INLINE GLuint
00722 clip_span( GLcontext *ctx, SWspan *span )
00723 {
00724    const GLint xmin = ctx->DrawBuffer->_Xmin;
00725    const GLint xmax = ctx->DrawBuffer->_Xmax;
00726    const GLint ymin = ctx->DrawBuffer->_Ymin;
00727    const GLint ymax = ctx->DrawBuffer->_Ymax;
00728 
00729    if (span->arrayMask & SPAN_XY) {
00730       /* arrays of x/y pixel coords */
00731       const GLint *x = span->array->x;
00732       const GLint *y = span->array->y;
00733       const GLint n = span->end;
00734       GLubyte *mask = span->array->mask;
00735       GLint i;
00736       if (span->arrayMask & SPAN_MASK) {
00737          /* note: using & intead of && to reduce branches */
00738          for (i = 0; i < n; i++) {
00739             mask[i] &= (x[i] >= xmin) & (x[i] < xmax)
00740                      & (y[i] >= ymin) & (y[i] < ymax);
00741          }
00742       }
00743       else {
00744          /* note: using & intead of && to reduce branches */
00745          for (i = 0; i < n; i++) {
00746             mask[i] = (x[i] >= xmin) & (x[i] < xmax)
00747                     & (y[i] >= ymin) & (y[i] < ymax);
00748          }
00749       }
00750       return GL_TRUE;  /* some pixels visible */
00751    }
00752    else {
00753       /* horizontal span of pixels */
00754       const GLint x = span->x;
00755       const GLint y = span->y;
00756       const GLint n = span->end;
00757 
00758       /* Trivial rejection tests */
00759       if (y < ymin || y >= ymax || x + n <= xmin || x >= xmax) {
00760          span->end = 0;
00761          return GL_FALSE;  /* all pixels clipped */
00762       }
00763 
00764       /* Clip to the left */
00765       if (x < xmin) {
00766          ASSERT(x + n > xmin);
00767          span->writeAll = GL_FALSE;
00768          _mesa_bzero(span->array->mask, (xmin - x) * sizeof(GLubyte));
00769       }
00770 
00771       /* Clip to right */
00772       if (x + n > xmax) {
00773          ASSERT(x < xmax);
00774          span->end = xmax - x;
00775       }
00776 
00777       return GL_TRUE;  /* some pixels visible */
00778    }
00779 }
00780 
00781 
00789 void
00790 _swrast_write_index_span( GLcontext *ctx, SWspan *span)
00791 {
00792    const SWcontext *swrast = SWRAST_CONTEXT(ctx);
00793    const GLbitfield origInterpMask = span->interpMask;
00794    const GLbitfield origArrayMask = span->arrayMask;
00795    struct gl_framebuffer *fb = ctx->DrawBuffer;
00796 
00797    ASSERT(span->end <= MAX_WIDTH);
00798    ASSERT(span->primitive == GL_POINT  ||  span->primitive == GL_LINE ||
00799       span->primitive == GL_POLYGON  ||  span->primitive == GL_BITMAP);
00800    ASSERT((span->interpMask | span->arrayMask) & SPAN_INDEX);
00801    /*
00802    ASSERT((span->interpMask & span->arrayMask) == 0);
00803    */
00804 
00805    if (span->arrayMask & SPAN_MASK) {
00806       /* mask was initialized by caller, probably glBitmap */
00807       span->writeAll = GL_FALSE;
00808    }
00809    else {
00810       _mesa_memset(span->array->mask, 1, span->end);
00811       span->writeAll = GL_TRUE;
00812    }
00813 
00814    /* Clipping */
00815    if ((swrast->_RasterMask & CLIP_BIT) || (span->primitive != GL_POLYGON)) {
00816       if (!clip_span(ctx, span)) {
00817          return;
00818       }
00819    }
00820 
00821    /* Depth bounds test */
00822    if (ctx->Depth.BoundsTest && fb->Visual.depthBits > 0) {
00823       if (!_swrast_depth_bounds_test(ctx, span)) {
00824          return;
00825       }
00826    }
00827 
00828 #ifdef DEBUG
00829    /* Make sure all fragments are within window bounds */
00830    if (span->arrayMask & SPAN_XY) {
00831       GLuint i;
00832       for (i = 0; i < span->end; i++) {
00833          if (span->array->mask[i]) {
00834             assert(span->array->x[i] >= fb->_Xmin);
00835             assert(span->array->x[i] < fb->_Xmax);
00836             assert(span->array->y[i] >= fb->_Ymin);
00837             assert(span->array->y[i] < fb->_Ymax);
00838          }
00839       }
00840    }
00841 #endif
00842 
00843    /* Polygon Stippling */
00844    if (ctx->Polygon.StippleFlag && span->primitive == GL_POLYGON) {
00845       stipple_polygon_span(ctx, span);
00846    }
00847 
00848    /* Stencil and Z testing */
00849    if (ctx->Depth.Test || ctx->Stencil.Enabled) {
00850       if (!(span->arrayMask & SPAN_Z))
00851          _swrast_span_interpolate_z(ctx, span);
00852 
00853       if (ctx->Stencil.Enabled) {
00854          if (!_swrast_stencil_and_ztest_span(ctx, span)) {
00855             span->arrayMask = origArrayMask;
00856             return;
00857          }
00858       }
00859       else {
00860          ASSERT(ctx->Depth.Test);
00861          if (!_swrast_depth_test_span(ctx, span)) {
00862             span->interpMask = origInterpMask;
00863             span->arrayMask = origArrayMask;
00864             return;
00865          }
00866       }
00867    }
00868 
00869 #if FEATURE_ARB_occlusion_query
00870    if (ctx->Query.CurrentOcclusionObject) {
00871       /* update count of 'passed' fragments */
00872       struct gl_query_object *q = ctx->Query.CurrentOcclusionObject;
00873       GLuint i;
00874       for (i = 0; i < span->end; i++)
00875          q->Result += span->array->mask[i];
00876    }
00877 #endif
00878 
00879    /* we have to wait until after occlusion to do this test */
00880    if (ctx->Color.IndexMask == 0) {
00881       /* write no pixels */
00882       span->arrayMask = origArrayMask;
00883       return;
00884    }
00885 
00886    /* Interpolate the color indexes if needed */
00887    if (swrast->_FogEnabled ||
00888        ctx->Color.IndexLogicOpEnabled ||
00889        ctx->Color.IndexMask != 0xffffffff ||
00890        (span->arrayMask & SPAN_COVERAGE)) {
00891       if (!(span->arrayMask & SPAN_INDEX) /*span->interpMask & SPAN_INDEX*/) {
00892          interpolate_indexes(ctx, span);
00893       }
00894    }
00895 
00896    /* Fog */
00897    if (swrast->_FogEnabled) {
00898       _swrast_fog_ci_span(ctx, span);
00899    }
00900 
00901    /* Antialias coverage application */
00902    if (span->arrayMask & SPAN_COVERAGE) {
00903       const GLfloat *coverage = span->array->coverage;
00904       GLuint *index = span->array->index;
00905       GLuint i;
00906       for (i = 0; i < span->end; i++) {
00907          ASSERT(coverage[i] < 16);
00908          index[i] = (index[i] & ~0xf) | ((GLuint) coverage[i]);
00909       }
00910    }
00911 
00912    /*
00913     * Write to renderbuffers
00914     */
00915    {
00916       const GLuint numBuffers = fb->_NumColorDrawBuffers;
00917       GLuint buf;
00918 
00919       for (buf = 0; buf < numBuffers; buf++) {
00920          struct gl_renderbuffer *rb = fb->_ColorDrawBuffers[buf];
00921          GLuint indexSave[MAX_WIDTH];
00922 
00923          ASSERT(rb->_BaseFormat == GL_COLOR_INDEX);
00924 
00925          if (numBuffers > 1) {
00926             /* save indexes for second, third renderbuffer writes */
00927             _mesa_memcpy(indexSave, span->array->index,
00928                          span->end * sizeof(indexSave[0]));
00929          }
00930 
00931          if (ctx->Color.IndexLogicOpEnabled) {
00932             _swrast_logicop_ci_span(ctx, rb, span);
00933          }
00934 
00935          if (ctx->Color.IndexMask != 0xffffffff) {
00936             _swrast_mask_ci_span(ctx, rb, span);
00937          }
00938 
00939          if (!(span->arrayMask & SPAN_INDEX) && span->indexStep == 0) {
00940             /* all fragments have same color index */
00941             GLubyte index8;
00942             GLushort index16;
00943             GLuint index32;
00944             void *value;
00945 
00946             if (rb->DataType == GL_UNSIGNED_BYTE) {
00947                index8 = FixedToInt(span->index);
00948                value = &index8;
00949             }
00950             else if (rb->DataType == GL_UNSIGNED_SHORT) {
00951                index16 = FixedToInt(span->index);
00952                value = &index16;
00953             }
00954             else {
00955                ASSERT(rb->DataType == GL_UNSIGNED_INT);
00956                index32 = FixedToInt(span->index);
00957                value = &index32;
00958             }
00959 
00960             if (span->arrayMask & SPAN_XY) {
00961                rb->PutMonoValues(ctx, rb, span->end, span->array->x, 
00962                                  span->array->y, value, span->array->mask);
00963             }
00964             else {
00965                rb->PutMonoRow(ctx, rb, span->end, span->x, span->y,
00966                               value, span->array->mask);
00967             }
00968          }
00969          else {
00970             /* each fragment is a different color */
00971             GLubyte index8[MAX_WIDTH];
00972             GLushort index16[MAX_WIDTH];
00973             void *values;
00974 
00975             if (rb->DataType == GL_UNSIGNED_BYTE) {
00976                GLuint k;
00977                for (k = 0; k < span->end; k++) {
00978                   index8[k] = (GLubyte) span->array->index[k];
00979                }
00980                values = index8;
00981             }
00982             else if (rb->DataType == GL_UNSIGNED_SHORT) {
00983                GLuint k;
00984                for (k = 0; k < span->end; k++) {
00985                   index16[k] = (GLushort) span->array->index[k];
00986                }
00987                values = index16;
00988             }
00989             else {
00990                ASSERT(rb->DataType == GL_UNSIGNED_INT);
00991                values = span->array->index;
00992             }
00993 
00994             if (span->arrayMask & SPAN_XY) {
00995                rb->PutValues(ctx, rb, span->end,
00996                              span->array->x, span->array->y,
00997                              values, span->array->mask);
00998             }
00999             else {
01000                rb->PutRow(ctx, rb, span->end, span->x, span->y,
01001                           values, span->array->mask);
01002             }
01003          }
01004 
01005          if (buf + 1 < numBuffers) {
01006             /* restore original span values */
01007             _mesa_memcpy(span->array->index, indexSave,
01008                          span->end * sizeof(indexSave[0]));
01009          }
01010       } /* for buf */
01011    }
01012 
01013    span->interpMask = origInterpMask;
01014    span->arrayMask = origArrayMask;
01015 }
01016 
01017 
01023 static INLINE void
01024 add_specular(GLcontext *ctx, SWspan *span)
01025 {
01026    const SWcontext *swrast = SWRAST_CONTEXT(ctx);
01027    const GLubyte *mask = span->array->mask;
01028    GLfloat (*col0)[4] = span->array->attribs[FRAG_ATTRIB_COL0];
01029    GLfloat (*col1)[4] = span->array->attribs[FRAG_ATTRIB_COL1];
01030    GLuint i;
01031 
01032    ASSERT(!ctx->FragmentProgram._Current);
01033    ASSERT(span->arrayMask & SPAN_RGBA);
01034    ASSERT(swrast->_ActiveAttribMask & FRAG_BIT_COL1);
01035    (void) swrast; /* silence warning */
01036 
01037    if (span->array->ChanType == GL_FLOAT) {
01038       if ((span->arrayAttribs & FRAG_BIT_COL0) == 0) {
01039          interpolate_active_attribs(ctx, span, FRAG_BIT_COL0);
01040       }
01041    }
01042    else {
01043       /* need float colors */
01044       if ((span->arrayAttribs & FRAG_BIT_COL0) == 0) {
01045          interpolate_float_colors(span);
01046       }
01047    }
01048 
01049    if ((span->arrayAttribs & FRAG_BIT_COL1) == 0) {
01050       /* XXX could avoid this and interpolate COL1 in the loop below */
01051       interpolate_active_attribs(ctx, span, FRAG_BIT_COL1);
01052    }
01053 
01054    ASSERT(span->arrayAttribs & FRAG_BIT_COL0);
01055    ASSERT(span->arrayAttribs & FRAG_BIT_COL1);
01056 
01057    for (i = 0; i < span->end; i++) {
01058       if (mask[i]) {
01059          col0[i][0] += col1[i][0];
01060          col0[i][1] += col1[i][1];
01061          col0[i][2] += col1[i][2];
01062       }
01063    }
01064 
01065    span->array->ChanType = GL_FLOAT;
01066 }
01067 
01068 
01072 static INLINE void
01073 apply_aa_coverage(SWspan *span)
01074 {
01075    const GLfloat *coverage = span->array->coverage;
01076    GLuint i;
01077    if (span->array->ChanType == GL_UNSIGNED_BYTE) {
01078       GLubyte (*rgba)[4] = span->array->rgba8;
01079       for (i = 0; i < span->end; i++) {
01080          const GLfloat a = rgba[i][ACOMP] * coverage[i];
01081          rgba[i][ACOMP] = (GLubyte) CLAMP(a, 0.0, 255.0);
01082          ASSERT(coverage[i] >= 0.0);
01083          ASSERT(coverage[i] <= 1.0);
01084       }
01085    }
01086    else if (span->array->ChanType == GL_UNSIGNED_SHORT) {
01087       GLushort (*rgba)[4] = span->array->rgba16;
01088       for (i = 0; i < span->end; i++) {
01089          const GLfloat a = rgba[i][ACOMP] * coverage[i];
01090          rgba[i][ACOMP] = (GLushort) CLAMP(a, 0.0, 65535.0);
01091       }
01092    }
01093    else {
01094       GLfloat (*rgba)[4] = span->array->attribs[FRAG_ATTRIB_COL0];
01095       for (i = 0; i < span->end; i++) {
01096          rgba[i][ACOMP] = rgba[i][ACOMP] * coverage[i];
01097          /* clamp later */
01098       }
01099    }
01100 }
01101 
01102 
01106 static INLINE void
01107 clamp_colors(SWspan *span)
01108 {
01109    GLfloat (*rgba)[4] = span->array->attribs[FRAG_ATTRIB_COL0];
01110    GLuint i;
01111    ASSERT(span->array->ChanType == GL_FLOAT);
01112    for (i = 0; i < span->end; i++) {
01113       rgba[i][RCOMP] = CLAMP(rgba[i][RCOMP], 0.0F, 1.0F);
01114       rgba[i][GCOMP] = CLAMP(rgba[i][GCOMP], 0.0F, 1.0F);
01115       rgba[i][BCOMP] = CLAMP(rgba[i][BCOMP], 0.0F, 1.0F);
01116       rgba[i][ACOMP] = CLAMP(rgba[i][ACOMP], 0.0F, 1.0F);
01117    }
01118 }
01119 
01120 
01127 static INLINE void
01128 convert_color_type(SWspan *span, GLenum newType, GLuint output)
01129 {
01130    GLvoid *src, *dst;
01131 
01132    if (output > 0 || span->array->ChanType == GL_FLOAT) {
01133       src = span->array->attribs[FRAG_ATTRIB_COL0 + output];
01134       span->array->ChanType = GL_FLOAT;
01135    }
01136    else if (span->array->ChanType == GL_UNSIGNED_BYTE) {
01137       src = span->array->rgba8;
01138    }
01139    else {
01140       ASSERT(span->array->ChanType == GL_UNSIGNED_SHORT);
01141       src = span->array->rgba16;
01142    }
01143 
01144    if (newType == GL_UNSIGNED_BYTE) {
01145       dst = span->array->rgba8;
01146    }
01147    else if (newType == GL_UNSIGNED_SHORT) {
01148       dst = span->array->rgba16;
01149    }
01150    else {
01151       dst = span->array->attribs[FRAG_ATTRIB_COL0];
01152    }
01153 
01154    _mesa_convert_colors(span->array->ChanType, src,
01155                         newType, dst,
01156                         span->end, span->array->mask);
01157 
01158    span->array->ChanType = newType;
01159    span->array->rgba = dst;
01160 }
01161 
01162 
01163 
01167 static INLINE void
01168 shade_texture_span(GLcontext *ctx, SWspan *span)
01169 {
01170    GLbitfield inputsRead;
01171 
01172    /* Determine which fragment attributes are actually needed */
01173    if (ctx->FragmentProgram._Current) {
01174       inputsRead = ctx->FragmentProgram._Current->Base.InputsRead;
01175    }
01176    else {
01177       /* XXX we could be a bit smarter about this */
01178       inputsRead = ~0;
01179    }
01180 
01181    if (ctx->FragmentProgram._Current ||
01182        ctx->ATIFragmentShader._Enabled) {
01183       /* programmable shading */
01184       if (span->primitive == GL_BITMAP && span->array->ChanType != GL_FLOAT) {
01185          convert_color_type(span, GL_FLOAT, 0);
01186       }
01187       if (span->primitive != GL_POINT ||
01188       (span->interpMask & SPAN_RGBA) ||
01189       ctx->Point.PointSprite) {
01190          /* for single-pixel points, we populated the arrays already */
01191          interpolate_active_attribs(ctx, span, ~0);
01192       }
01193       span->array->ChanType = GL_FLOAT;
01194 
01195       if (!(span->arrayMask & SPAN_Z))
01196          _swrast_span_interpolate_z (ctx, span);
01197 
01198 #if 0
01199       if (inputsRead & FRAG_BIT_WPOS)
01200 #else
01201       /* XXX always interpolate wpos so that DDX/DDY work */
01202 #endif
01203          interpolate_wpos(ctx, span);
01204 
01205       /* Run fragment program/shader now */
01206       if (ctx->FragmentProgram._Current) {
01207          _swrast_exec_fragment_program(ctx, span);
01208       }
01209       else {
01210          ASSERT(ctx->ATIFragmentShader._Enabled);
01211          _swrast_exec_fragment_shader(ctx, span);
01212       }
01213    }
01214    else if (ctx->Texture._EnabledUnits) {
01215       /* conventional texturing */
01216 
01217 #if CHAN_BITS == 32
01218       if ((span->arrayAttribs & FRAG_BIT_COL0) == 0) {
01219          interpolate_int_colors(ctx, span);
01220       }
01221 #else
01222       if (!(span->arrayMask & SPAN_RGBA))
01223          interpolate_int_colors(ctx, span);
01224 #endif
01225       if ((span->arrayAttribs & FRAG_BITS_TEX_ANY) == 0x0)
01226          interpolate_texcoords(ctx, span);
01227 
01228       _swrast_texture_span(ctx, span);
01229    }
01230 }
01231 
01232 
01233 
01241 void
01242 _swrast_write_rgba_span( GLcontext *ctx, SWspan *span)
01243 {
01244    const SWcontext *swrast = SWRAST_CONTEXT(ctx);
01245    const GLuint colorMask = *((GLuint *) ctx->Color.ColorMask);
01246    const GLbitfield origInterpMask = span->interpMask;
01247    const GLbitfield origArrayMask = span->arrayMask;
01248    const GLbitfield origArrayAttribs = span->arrayAttribs;
01249    const GLenum origChanType = span->array->ChanType;
01250    void * const origRgba = span->array->rgba;
01251    const GLboolean shader = (ctx->FragmentProgram._Current
01252                              || ctx->ATIFragmentShader._Enabled);
01253    const GLboolean shaderOrTexture = shader || ctx->Texture._EnabledUnits;
01254    struct gl_framebuffer *fb = ctx->DrawBuffer;
01255 
01256    /*
01257    printf("%s()  interp 0x%x  array 0x%x\n", __FUNCTION__,
01258           span->interpMask, span->arrayMask);
01259    */
01260 
01261    ASSERT(span->primitive == GL_POINT ||
01262           span->primitive == GL_LINE ||
01263       span->primitive == GL_POLYGON ||
01264           span->primitive == GL_BITMAP);
01265    ASSERT(span->end <= MAX_WIDTH);
01266 
01267    /* Fragment write masks */
01268    if (span->arrayMask & SPAN_MASK) {
01269       /* mask was initialized by caller, probably glBitmap */
01270       span->writeAll = GL_FALSE;
01271    }
01272    else {
01273       _mesa_memset(span->array->mask, 1, span->end);
01274       span->writeAll = GL_TRUE;
01275    }
01276 
01277    /* Clip to window/scissor box */
01278    if ((swrast->_RasterMask & CLIP_BIT) || (span->primitive != GL_POLYGON)) {
01279       if (!clip_span(ctx, span)) {
01280      return;
01281       }
01282    }
01283 
01284 #ifdef DEBUG
01285    /* Make sure all fragments are within window bounds */
01286    if (span->arrayMask & SPAN_XY) {
01287       GLuint i;
01288       for (i = 0; i < span->end; i++) {
01289          if (span->array->mask[i]) {
01290             assert(span->array->x[i] >= fb->_Xmin);
01291             assert(span->array->x[i] < fb->_Xmax);
01292             assert(span->array->y[i] >= fb->_Ymin);
01293             assert(span->array->y[i] < fb->_Ymax);
01294          }
01295       }
01296    }
01297 #endif
01298 
01299    /* Polygon Stippling */
01300    if (ctx->Polygon.StippleFlag && span->primitive == GL_POLYGON) {
01301       stipple_polygon_span(ctx, span);
01302    }
01303 
01304    /* This is the normal place to compute the fragment color/Z
01305     * from texturing or shading.
01306     */
01307    if (shaderOrTexture && !swrast->_DeferredTexture) {
01308       shade_texture_span(ctx, span);
01309    }
01310 
01311    /* Do the alpha test */
01312    if (ctx->Color.AlphaEnabled) {
01313       if (!_swrast_alpha_test(ctx, span)) {
01314          goto end;
01315       }
01316    }
01317 
01318    /* Stencil and Z testing */
01319    if (ctx->Stencil.Enabled || ctx->Depth.Test) {
01320       if (!(span->arrayMask & SPAN_Z))
01321          _swrast_span_interpolate_z(ctx, span);
01322 
01323       if (ctx->Stencil.Enabled && fb->Visual.stencilBits > 0) {
01324          /* Combined Z/stencil tests */
01325          if (!_swrast_stencil_and_ztest_span(ctx, span)) {
01326             goto end;
01327          }
01328       }
01329       else if (fb->Visual.depthBits > 0) {
01330          /* Just regular depth testing */
01331          ASSERT(ctx->Depth.Test);
01332          ASSERT(span->arrayMask & SPAN_Z);
01333          if (!_swrast_depth_test_span(ctx, span)) {
01334             goto end;
01335          }
01336       }
01337    }
01338 
01339 #if FEATURE_ARB_occlusion_query
01340    if (ctx->Query.CurrentOcclusionObject) {
01341       /* update count of 'passed' fragments */
01342       struct gl_query_object *q = ctx->Query.CurrentOcclusionObject;
01343       GLuint i;
01344       for (i = 0; i < span->end; i++)
01345          q->Result += span->array->mask[i];
01346    }
01347 #endif
01348 
01349    /* We had to wait until now to check for glColorMask(0,0,0,0) because of
01350     * the occlusion test.
01351     */
01352    if (colorMask == 0x0) {
01353       goto end;
01354    }
01355 
01356    /* If we were able to defer fragment color computation to now, there's
01357     * a good chance that many fragments will have already been killed by
01358     * Z/stencil testing.
01359     */
01360    if (shaderOrTexture && swrast->_DeferredTexture) {
01361       shade_texture_span(ctx, span);
01362    }
01363 
01364 #if CHAN_BITS == 32
01365    if ((span->arrayAttribs & FRAG_BIT_COL0) == 0) {
01366       interpolate_active_attribs(ctx, span, FRAG_BIT_COL0);
01367    }
01368 #else
01369    if ((span->arrayMask & SPAN_RGBA) == 0) {
01370       interpolate_int_colors(ctx, span);
01371    }
01372 #endif
01373 
01374    ASSERT(span->arrayMask & SPAN_RGBA);
01375 
01376    if (!shader) {
01377       /* Add base and specular colors */
01378       if (ctx->Fog.ColorSumEnabled ||
01379           (ctx->Light.Enabled &&
01380            ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR)) {
01381          add_specular(ctx, span);
01382       }
01383    }
01384 
01385    /* Fog */
01386    if (swrast->_FogEnabled) {
01387       _swrast_fog_rgba_span(ctx, span);
01388    }
01389 
01390    /* Antialias coverage application */
01391    if (span->arrayMask & SPAN_COVERAGE) {
01392       apply_aa_coverage(span);
01393    }
01394 
01395    /* Clamp color/alpha values over the range [0.0, 1.0] before storage */
01396    if (ctx->Color.ClampFragmentColor == GL_TRUE &&
01397        span->array->ChanType == GL_FLOAT) {
01398       clamp_colors(span);
01399    }
01400 
01401    /*
01402     * Write to renderbuffers
01403     */
01404    {
01405       const GLuint numBuffers = fb->_NumColorDrawBuffers;
01406       const GLboolean multiFragOutputs = numBuffers > 1;
01407       GLuint buf;
01408 
01409       for (buf = 0; buf < numBuffers; buf++) {
01410          struct gl_renderbuffer *rb = fb->_ColorDrawBuffers[buf];
01411 
01412          /* color[fragOutput] will be written to buffer[buf] */
01413 
01414          if (rb) {
01415             GLchan rgbaSave[MAX_WIDTH][4];
01416             const GLuint fragOutput = multiFragOutputs ? buf : 0;
01417 
01418             if (rb->DataType != span->array->ChanType || fragOutput > 0) {
01419                convert_color_type(span, rb->DataType, fragOutput);
01420             }
01421 
01422             if (!multiFragOutputs && numBuffers > 1) {
01423                /* save colors for second, third renderbuffer writes */
01424                _mesa_memcpy(rgbaSave, span->array->rgba,
01425                             4 * span->end * sizeof(GLchan));
01426             }
01427 
01428             ASSERT(rb->_BaseFormat == GL_RGBA || rb->_BaseFormat == GL_RGB);
01429 
01430             if (ctx->Color._LogicOpEnabled) {
01431                _swrast_logicop_rgba_span(ctx, rb, span);
01432             }
01433             else if (ctx->Color.BlendEnabled) {
01434                _swrast_blend_span(ctx, rb, span);
01435             }
01436 
01437             if (colorMask != 0xffffffff) {
01438                _swrast_mask_rgba_span(ctx, rb, span);
01439             }
01440 
01441             if (span->arrayMask & SPAN_XY) {
01442                /* array of pixel coords */
01443                ASSERT(rb->PutValues);
01444                rb->PutValues(ctx, rb, span->end,
01445                              span->array->x, span->array->y,
01446                              span->array->rgba, span->array->mask);
01447             }
01448             else {
01449                /* horizontal run of pixels */
01450                ASSERT(rb->PutRow);
01451                rb->PutRow(ctx, rb, span->end, span->x, span->y,
01452                           span->array->rgba,
01453                           span->writeAll ? NULL: span->array->mask);
01454             }
01455 
01456             if (!multiFragOutputs && numBuffers > 1) {
01457                /* restore original span values */
01458                _mesa_memcpy(span->array->rgba, rgbaSave,
01459                             4 * span->end * sizeof(GLchan));
01460             }
01461 
01462          } /* if rb */
01463       } /* for buf */
01464    }
01465 
01466 end:
01467    /* restore these values before returning */
01468    span->interpMask = origInterpMask;
01469    span->arrayMask = origArrayMask;
01470    span->arrayAttribs = origArrayAttribs;
01471    span->array->ChanType = origChanType;
01472    span->array->rgba = origRgba;
01473 }
01474 
01475 
01482 void
01483 _swrast_read_rgba_span( GLcontext *ctx, struct gl_renderbuffer *rb,
01484                         GLuint n, GLint x, GLint y, GLenum dstType,
01485                         GLvoid *rgba)
01486 {
01487    const GLint bufWidth = (GLint) rb->Width;
01488    const GLint bufHeight = (GLint) rb->Height;
01489 
01490    if (y < 0 || y >= bufHeight || x + (GLint) n < 0 || x >= bufWidth) {
01491       /* completely above, below, or right */
01492       /* XXX maybe leave rgba values undefined? */
01493       _mesa_bzero(rgba, 4 * n * sizeof(GLchan));
01494    }
01495    else {
01496       GLint skip, length;
01497       if (x < 0) {
01498          /* left edge clipping */
01499          skip = -x;
01500          length = (GLint) n - skip;
01501          if (length < 0) {
01502             /* completely left of window */
01503             return;
01504          }
01505          if (length > bufWidth) {
01506             length = bufWidth;
01507          }
01508       }
01509       else if ((GLint) (x + n) > bufWidth) {
01510          /* right edge clipping */
01511          skip = 0;
01512          length = bufWidth - x;
01513          if (length < 0) {
01514             /* completely to right of window */
01515             return;
01516          }
01517       }
01518       else {
01519          /* no clipping */
01520          skip = 0;
01521          length = (GLint) n;
01522       }
01523 
01524       ASSERT(rb);
01525       ASSERT(rb->GetRow);
01526       ASSERT(rb->_BaseFormat == GL_RGB || rb->_BaseFormat == GL_RGBA);
01527 
01528       if (rb->DataType == dstType) {
01529          rb->GetRow(ctx, rb, length, x + skip, y,
01530                     (GLubyte *) rgba + skip * RGBA_PIXEL_SIZE(rb->DataType));
01531       }
01532       else {
01533          GLuint temp[MAX_WIDTH * 4];
01534          rb->GetRow(ctx, rb, length, x + skip, y, temp);
01535          _mesa_convert_colors(rb->DataType, temp,
01536                    dstType, (GLubyte *) rgba + skip * RGBA_PIXEL_SIZE(dstType),
01537                    length, NULL);
01538       }
01539    }
01540 }
01541 
01542 
01547 void
01548 _swrast_read_index_span( GLcontext *ctx, struct gl_renderbuffer *rb,
01549                          GLuint n, GLint x, GLint y, GLuint index[] )
01550 {
01551    const GLint bufWidth = (GLint) rb->Width;
01552    const GLint bufHeight = (GLint) rb->Height;
01553 
01554    if (y < 0 || y >= bufHeight || x + (GLint) n < 0 || x >= bufWidth) {
01555       /* completely above, below, or right */
01556       _mesa_bzero(index, n * sizeof(GLuint));
01557    }
01558    else {
01559       GLint skip, length;
01560       if (x < 0) {
01561          /* left edge clipping */
01562          skip = -x;
01563          length = (GLint) n - skip;
01564          if (length < 0) {
01565             /* completely left of window */
01566             return;
01567          }
01568          if (length > bufWidth) {
01569             length = bufWidth;
01570          }
01571       }
01572       else if ((GLint) (x + n) > bufWidth) {
01573          /* right edge clipping */
01574          skip = 0;
01575          length = bufWidth - x;
01576          if (length < 0) {
01577             /* completely to right of window */
01578             return;
01579          }
01580       }
01581       else {
01582          /* no clipping */
01583          skip = 0;
01584          length = (GLint) n;
01585       }
01586 
01587       ASSERT(rb->GetRow);
01588       ASSERT(rb->_BaseFormat == GL_COLOR_INDEX);
01589 
01590       if (rb->DataType == GL_UNSIGNED_BYTE) {
01591          GLubyte index8[MAX_WIDTH];
01592          GLint i;
01593          rb->GetRow(ctx, rb, length, x + skip, y, index8);
01594          for (i = 0; i < length; i++)
01595             index[skip + i] = index8[i];
01596       }
01597       else if (rb->DataType == GL_UNSIGNED_SHORT) {
01598          GLushort index16[MAX_WIDTH];
01599          GLint i;
01600          rb->GetRow(ctx, rb, length, x + skip, y, index16);
01601          for (i = 0; i < length; i++)
01602             index[skip + i] = index16[i];
01603       }
01604       else if (rb->DataType == GL_UNSIGNED_INT) {
01605          rb->GetRow(ctx, rb, length, x + skip, y, index + skip);
01606       }
01607    }
01608 }
01609 
01610 
01618 void
01619 _swrast_get_values(GLcontext *ctx, struct gl_renderbuffer *rb,
01620                    GLuint count, const GLint x[], const GLint y[],
01621                    void *values, GLuint valueSize)
01622 {
01623    GLuint i, inCount = 0, inStart = 0;
01624 
01625    for (i = 0; i < count; i++) {
01626       if (x[i] >= 0 && y[i] >= 0 &&
01627       x[i] < (GLint) rb->Width && y[i] < (GLint) rb->Height) {
01628          /* inside */
01629          if (inCount == 0)
01630             inStart = i;
01631          inCount++;
01632       }
01633       else {
01634          if (inCount > 0) {
01635             /* read [inStart, inStart + inCount) */
01636             rb->GetValues(ctx, rb, inCount, x + inStart, y + inStart,
01637                           (GLubyte *) values + inStart * valueSize);
01638             inCount = 0;
01639          }
01640       }
01641    }
01642    if (inCount > 0) {
01643       /* read last values */
01644       rb->GetValues(ctx, rb, inCount, x + inStart, y + inStart,
01645                     (GLubyte *) values + inStart * valueSize);
01646    }
01647 }
01648 
01649 
01654 void
01655 _swrast_put_row(GLcontext *ctx, struct gl_renderbuffer *rb,
01656                 GLuint count, GLint x, GLint y,
01657                 const GLvoid *values, GLuint valueSize)
01658 {
01659    GLint skip = 0;
01660 
01661    if (y < 0 || y >= (GLint) rb->Height)
01662       return; /* above or below */
01663 
01664    if (x + (GLint) count <= 0 || x >= (GLint) rb->Width)
01665       return; /* entirely left or right */
01666 
01667    if ((GLint) (x + count) > (GLint) rb->Width) {
01668       /* right clip */
01669       GLint clip = x + count - rb->Width;
01670       count -= clip;
01671    }
01672 
01673    if (x < 0) {
01674       /* left clip */
01675       skip = -x;
01676       x = 0;
01677       count -= skip;
01678    }
01679 
01680    rb->PutRow(ctx, rb, count, x, y,
01681               (const GLubyte *) values + skip * valueSize, NULL);
01682 }
01683 
01684 
01689 void
01690 _swrast_get_row(GLcontext *ctx, struct gl_renderbuffer *rb,
01691                 GLuint count, GLint x, GLint y,
01692                 GLvoid *values, GLuint valueSize)
01693 {
01694    GLint skip = 0;
01695 
01696    if (y < 0 || y >= (GLint) rb->Height)
01697       return; /* above or below */
01698 
01699    if (x + (GLint) count <= 0 || x >= (GLint) rb->Width)
01700       return; /* entirely left or right */
01701 
01702    if (x + count > rb->Width) {
01703       /* right clip */
01704       GLint clip = x + count - rb->Width;
01705       count -= clip;
01706    }
01707 
01708    if (x < 0) {
01709       /* left clip */
01710       skip = -x;
01711       x = 0;
01712       count -= skip;
01713    }
01714 
01715    rb->GetRow(ctx, rb, count, x, y, (GLubyte *) values + skip * valueSize);
01716 }
01717 
01718 
01726 void *
01727 _swrast_get_dest_rgba(GLcontext *ctx, struct gl_renderbuffer *rb,
01728                       SWspan *span)
01729 {
01730    const GLuint pixelSize = RGBA_PIXEL_SIZE(span->array->ChanType);
01731    void *rbPixels;
01732 
01733    /*
01734     * Point rbPixels to a temporary space (use specular color arrays).
01735     */
01736    rbPixels = span->array->attribs[FRAG_ATTRIB_COL1];
01737 
01738    /* Get destination values from renderbuffer */
01739    if (span->arrayMask & SPAN_XY) {
01740       _swrast_get_values(ctx, rb, span->end, span->array->x, span->array->y,
01741                          rbPixels, pixelSize);
01742    }
01743    else {
01744       _swrast_get_row(ctx, rb, span->end, span->x, span->y,
01745                       rbPixels, pixelSize);
01746    }
01747 
01748    return rbPixels;
01749 }

Generated on Sun May 27 2012 04:20:43 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.