Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Mesa 3-D graphics library
  3.  *
  4.  * Copyright (C) 1999-2007  Brian Paul   All Rights Reserved.
  5.  *
  6.  * Permission is hereby granted, free of charge, to any person obtaining a
  7.  * copy of this software and associated documentation files (the "Software"),
  8.  * to deal in the Software without restriction, including without limitation
  9.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  10.  * and/or sell copies of the Software, and to permit persons to whom the
  11.  * Software is furnished to do so, subject to the following conditions:
  12.  *
  13.  * The above copyright notice and this permission notice shall be included
  14.  * in all copies or substantial portions of the Software.
  15.  *
  16.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  17.  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  19.  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
  20.  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  21.  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  22.  * OTHER DEALINGS IN THE SOFTWARE.
  23.  */
  24.  
  25.  
  26. #include "main/glheader.h"
  27. #include "main/macros.h"
  28. #include "s_context.h"
  29. #include "s_feedback.h"
  30. #include "s_points.h"
  31. #include "s_span.h"
  32.  
  33.  
  34. /**
  35.  * Used to cull points with invalid coords
  36.  */
  37. #define CULL_INVALID(V)                              \
  38.    do {                                              \
  39.       float tmp = (V)->attrib[VARYING_SLOT_POS][0]   \
  40.                 + (V)->attrib[VARYING_SLOT_POS][1];  \
  41.       if (IS_INF_OR_NAN(tmp))                        \
  42.          return;                                     \
  43.    } while(0)
  44.  
  45.  
  46.  
  47. /**
  48.  * Get/compute the point size.
  49.  * The size may come from a vertex shader, or computed with attentuation
  50.  * or just the glPointSize value.
  51.  * Must also clamp to user-defined range and implmentation limits.
  52.  */
  53. static inline GLfloat
  54. get_size(const struct gl_context *ctx, const SWvertex *vert, GLboolean smoothed)
  55. {
  56.    GLfloat size;
  57.  
  58.    if (ctx->Point._Attenuated || ctx->VertexProgram.PointSizeEnabled) {
  59.       /* use vertex's point size */
  60.       size = vert->pointSize;
  61.    }
  62.    else {
  63.       /* use constant point size */
  64.       size = ctx->Point.Size;
  65.    }
  66.    /* always clamp to user-specified limits */
  67.    size = CLAMP(size, ctx->Point.MinSize, ctx->Point.MaxSize);
  68.    /* clamp to implementation limits */
  69.    if (smoothed)
  70.       size = CLAMP(size, ctx->Const.MinPointSizeAA, ctx->Const.MaxPointSizeAA);
  71.    else
  72.       size = CLAMP(size, ctx->Const.MinPointSize, ctx->Const.MaxPointSize);
  73.  
  74.    return size;
  75. }
  76.  
  77.  
  78. /**
  79.  * Draw a point sprite
  80.  */
  81. static void
  82. sprite_point(struct gl_context *ctx, const SWvertex *vert)
  83. {
  84.    SWcontext *swrast = SWRAST_CONTEXT(ctx);
  85.    SWspan span;
  86.    GLfloat size;
  87.    GLuint tCoords[MAX_TEXTURE_COORD_UNITS + 1];
  88.    GLuint numTcoords = 0;
  89.    GLfloat t0, dtdy;
  90.  
  91.    CULL_INVALID(vert);
  92.  
  93.    /* z coord */
  94.    if (ctx->DrawBuffer->Visual.depthBits <= 16)
  95.       span.z = FloatToFixed(vert->attrib[VARYING_SLOT_POS][2] + 0.5F);
  96.    else
  97.       span.z = (GLuint) (vert->attrib[VARYING_SLOT_POS][2] + 0.5F);
  98.    span.zStep = 0;
  99.  
  100.    size = get_size(ctx, vert, GL_FALSE);
  101.  
  102.    /* span init */
  103.    INIT_SPAN(span, GL_POINT);
  104.    span.interpMask = SPAN_Z | SPAN_RGBA;
  105.  
  106.    span.facing = swrast->PointLineFacing;
  107.  
  108.    span.red   = ChanToFixed(vert->color[0]);
  109.    span.green = ChanToFixed(vert->color[1]);
  110.    span.blue  = ChanToFixed(vert->color[2]);
  111.    span.alpha = ChanToFixed(vert->color[3]);
  112.    span.redStep = 0;
  113.    span.greenStep = 0;
  114.    span.blueStep = 0;
  115.    span.alphaStep = 0;
  116.  
  117.    /* need these for fragment programs */
  118.    span.attrStart[VARYING_SLOT_POS][3] = 1.0F;
  119.    span.attrStepX[VARYING_SLOT_POS][3] = 0.0F;
  120.    span.attrStepY[VARYING_SLOT_POS][3] = 0.0F;
  121.  
  122.    {
  123.       GLfloat s, r, dsdx;
  124.  
  125.       /* texcoord / pointcoord interpolants */
  126.       s = 0.0F;
  127.       dsdx = 1.0F / size;
  128.       if (ctx->Point.SpriteOrigin == GL_LOWER_LEFT) {
  129.          dtdy = 1.0F / size;
  130.          t0 = 0.5F * dtdy;
  131.       }
  132.       else {
  133.          /* GL_UPPER_LEFT */
  134.          dtdy = -1.0F / size;
  135.          t0 = 1.0F + 0.5F * dtdy;
  136.       }
  137.  
  138.       ATTRIB_LOOP_BEGIN
  139.          if (attr >= VARYING_SLOT_TEX0 && attr <= VARYING_SLOT_TEX7) {
  140.             /* a texcoord attribute */
  141.             const GLuint u = attr - VARYING_SLOT_TEX0;
  142.             assert(u < ARRAY_SIZE(ctx->Point.CoordReplace));
  143.             if (ctx->Point.CoordReplace[u]) {
  144.                tCoords[numTcoords++] = attr;
  145.  
  146.                if (ctx->Point.SpriteRMode == GL_ZERO)
  147.                   r = 0.0F;
  148.                else if (ctx->Point.SpriteRMode == GL_S)
  149.                   r = vert->attrib[attr][0];
  150.                else /* GL_R */
  151.                   r = vert->attrib[attr][2];
  152.  
  153.                span.attrStart[attr][0] = s;
  154.                span.attrStart[attr][1] = 0.0; /* overwritten below */
  155.                span.attrStart[attr][2] = r;
  156.                span.attrStart[attr][3] = 1.0;
  157.  
  158.                span.attrStepX[attr][0] = dsdx;
  159.                span.attrStepX[attr][1] = 0.0;
  160.                span.attrStepX[attr][2] = 0.0;
  161.                span.attrStepX[attr][3] = 0.0;
  162.  
  163.                span.attrStepY[attr][0] = 0.0;
  164.                span.attrStepY[attr][1] = dtdy;
  165.                span.attrStepY[attr][2] = 0.0;
  166.                span.attrStepY[attr][3] = 0.0;
  167.  
  168.                continue;
  169.             }
  170.          }
  171.          else if (attr == VARYING_SLOT_PNTC) {
  172.             /* GLSL gl_PointCoord.xy (.zw undefined) */
  173.             span.attrStart[VARYING_SLOT_PNTC][0] = 0.0;
  174.             span.attrStart[VARYING_SLOT_PNTC][1] = 0.0; /* t0 set below */
  175.             span.attrStepX[VARYING_SLOT_PNTC][0] = dsdx;
  176.             span.attrStepX[VARYING_SLOT_PNTC][1] = 0.0;
  177.             span.attrStepY[VARYING_SLOT_PNTC][0] = 0.0;
  178.             span.attrStepY[VARYING_SLOT_PNTC][1] = dtdy;
  179.             tCoords[numTcoords++] = VARYING_SLOT_PNTC;
  180.             continue;
  181.          }
  182.          /* use vertex's texcoord/attrib */
  183.          COPY_4V(span.attrStart[attr], vert->attrib[attr]);
  184.          ASSIGN_4V(span.attrStepX[attr], 0, 0, 0, 0);
  185.          ASSIGN_4V(span.attrStepY[attr], 0, 0, 0, 0);
  186.       ATTRIB_LOOP_END;
  187.    }
  188.  
  189.    /* compute pos, bounds and render */
  190.    {
  191.       const GLfloat x = vert->attrib[VARYING_SLOT_POS][0];
  192.       const GLfloat y = vert->attrib[VARYING_SLOT_POS][1];
  193.       GLint iSize = (GLint) (size + 0.5F);
  194.       GLint xmin, xmax, ymin, ymax, iy;
  195.       GLint iRadius;
  196.       GLfloat tcoord = t0;
  197.  
  198.       iSize = MAX2(1, iSize);
  199.       iRadius = iSize / 2;
  200.  
  201.       if (iSize & 1) {
  202.          /* odd size */
  203.          xmin = (GLint) (x - iRadius);
  204.          xmax = (GLint) (x + iRadius);
  205.          ymin = (GLint) (y - iRadius);
  206.          ymax = (GLint) (y + iRadius);
  207.       }
  208.       else {
  209.          /* even size */
  210.          /* 0.501 factor allows conformance to pass */
  211.          xmin = (GLint) (x + 0.501) - iRadius;
  212.          xmax = xmin + iSize - 1;
  213.          ymin = (GLint) (y + 0.501) - iRadius;
  214.          ymax = ymin + iSize - 1;
  215.       }
  216.  
  217.       /* render spans */
  218.       for (iy = ymin; iy <= ymax; iy++) {
  219.          GLuint i;
  220.          /* setup texcoord T for this row */
  221.          for (i = 0; i < numTcoords; i++) {
  222.             span.attrStart[tCoords[i]][1] = tcoord;
  223.          }
  224.  
  225.          /* these might get changed by span clipping */
  226.          span.x = xmin;
  227.          span.y = iy;
  228.          span.end = xmax - xmin + 1;
  229.  
  230.          _swrast_write_rgba_span(ctx, &span);
  231.  
  232.          tcoord += dtdy;
  233.       }
  234.    }
  235. }
  236.  
  237.  
  238. /**
  239.  * Draw smooth/antialiased point.  RGB or CI mode.
  240.  */
  241. static void
  242. smooth_point(struct gl_context *ctx, const SWvertex *vert)
  243. {
  244.    SWcontext *swrast = SWRAST_CONTEXT(ctx);
  245.    SWspan span;
  246.    GLfloat size, alphaAtten;
  247.  
  248.    CULL_INVALID(vert);
  249.  
  250.    /* z coord */
  251.    if (ctx->DrawBuffer->Visual.depthBits <= 16)
  252.       span.z = FloatToFixed(vert->attrib[VARYING_SLOT_POS][2] + 0.5F);
  253.    else
  254.       span.z = (GLuint) (vert->attrib[VARYING_SLOT_POS][2] + 0.5F);
  255.    span.zStep = 0;
  256.  
  257.    size = get_size(ctx, vert, GL_TRUE);
  258.  
  259.    /* alpha attenuation / fade factor */
  260.    if (ctx->Multisample._Enabled) {
  261.       if (vert->pointSize >= ctx->Point.Threshold) {
  262.          alphaAtten = 1.0F;
  263.       }
  264.       else {
  265.          GLfloat dsize = vert->pointSize / ctx->Point.Threshold;
  266.          alphaAtten = dsize * dsize;
  267.       }
  268.    }
  269.    else {
  270.       alphaAtten = 1.0;
  271.    }
  272.    (void) alphaAtten; /* not used */
  273.  
  274.    /* span init */
  275.    INIT_SPAN(span, GL_POINT);
  276.    span.interpMask = SPAN_Z | SPAN_RGBA;
  277.    span.arrayMask = SPAN_COVERAGE | SPAN_MASK;
  278.  
  279.    span.facing = swrast->PointLineFacing;
  280.  
  281.    span.red   = ChanToFixed(vert->color[0]);
  282.    span.green = ChanToFixed(vert->color[1]);
  283.    span.blue  = ChanToFixed(vert->color[2]);
  284.    span.alpha = ChanToFixed(vert->color[3]);
  285.    span.redStep = 0;
  286.    span.greenStep = 0;
  287.    span.blueStep = 0;
  288.    span.alphaStep = 0;
  289.  
  290.    /* need these for fragment programs */
  291.    span.attrStart[VARYING_SLOT_POS][3] = 1.0F;
  292.    span.attrStepX[VARYING_SLOT_POS][3] = 0.0F;
  293.    span.attrStepY[VARYING_SLOT_POS][3] = 0.0F;
  294.  
  295.    ATTRIB_LOOP_BEGIN
  296.       COPY_4V(span.attrStart[attr], vert->attrib[attr]);
  297.       ASSIGN_4V(span.attrStepX[attr], 0, 0, 0, 0);
  298.       ASSIGN_4V(span.attrStepY[attr], 0, 0, 0, 0);
  299.    ATTRIB_LOOP_END
  300.  
  301.    /* compute pos, bounds and render */
  302.    {
  303.       const GLfloat x = vert->attrib[VARYING_SLOT_POS][0];
  304.       const GLfloat y = vert->attrib[VARYING_SLOT_POS][1];
  305.       const GLfloat radius = 0.5F * size;
  306.       const GLfloat rmin = radius - 0.7071F;  /* 0.7071 = sqrt(2)/2 */
  307.       const GLfloat rmax = radius + 0.7071F;
  308.       const GLfloat rmin2 = MAX2(0.0F, rmin * rmin);
  309.       const GLfloat rmax2 = rmax * rmax;
  310.       const GLfloat cscale = 1.0F / (rmax2 - rmin2);
  311.       const GLint xmin = (GLint) (x - radius);
  312.       const GLint xmax = (GLint) (x + radius);
  313.       const GLint ymin = (GLint) (y - radius);
  314.       const GLint ymax = (GLint) (y + radius);
  315.       GLint ix, iy;
  316.  
  317.       for (iy = ymin; iy <= ymax; iy++) {
  318.  
  319.          /* these might get changed by span clipping */
  320.          span.x = xmin;
  321.          span.y = iy;
  322.          span.end = xmax - xmin + 1;
  323.  
  324.          /* compute coverage for each pixel in span */
  325.          for (ix = xmin; ix <= xmax; ix++) {
  326.             const GLfloat dx = ix - x + 0.5F;
  327.             const GLfloat dy = iy - y + 0.5F;
  328.             const GLfloat dist2 = dx * dx + dy * dy;
  329.             GLfloat coverage;
  330.  
  331.             if (dist2 < rmax2) {
  332.                if (dist2 >= rmin2) {
  333.                   /* compute partial coverage */
  334.                   coverage = 1.0F - (dist2 - rmin2) * cscale;
  335.                }
  336.                else {
  337.                   /* full coverage */
  338.                   coverage = 1.0F;
  339.                }
  340.                span.array->mask[ix - xmin] = 1;
  341.             }
  342.             else {
  343.                /* zero coverage - fragment outside the radius */
  344.                coverage = 0.0;
  345.                span.array->mask[ix - xmin] = 0;
  346.             }
  347.             span.array->coverage[ix - xmin] = coverage;
  348.          }
  349.  
  350.          /* render span */
  351.          _swrast_write_rgba_span(ctx, &span);
  352.  
  353.       }
  354.    }
  355. }
  356.  
  357.  
  358. /**
  359.  * Draw large (size >= 1) non-AA point.  RGB or CI mode.
  360.  */
  361. static void
  362. large_point(struct gl_context *ctx, const SWvertex *vert)
  363. {
  364.    SWcontext *swrast = SWRAST_CONTEXT(ctx);
  365.    SWspan span;
  366.    GLfloat size;
  367.  
  368.    CULL_INVALID(vert);
  369.  
  370.    /* z coord */
  371.    if (ctx->DrawBuffer->Visual.depthBits <= 16)
  372.       span.z = FloatToFixed(vert->attrib[VARYING_SLOT_POS][2] + 0.5F);
  373.    else
  374.       span.z = (GLuint) (vert->attrib[VARYING_SLOT_POS][2] + 0.5F);
  375.    span.zStep = 0;
  376.  
  377.    size = get_size(ctx, vert, GL_FALSE);
  378.  
  379.    /* span init */
  380.    INIT_SPAN(span, GL_POINT);
  381.    span.arrayMask = SPAN_XY;
  382.    span.facing = swrast->PointLineFacing;
  383.  
  384.    span.interpMask = SPAN_Z | SPAN_RGBA;
  385.    span.red   = ChanToFixed(vert->color[0]);
  386.    span.green = ChanToFixed(vert->color[1]);
  387.    span.blue  = ChanToFixed(vert->color[2]);
  388.    span.alpha = ChanToFixed(vert->color[3]);
  389.    span.redStep = 0;
  390.    span.greenStep = 0;
  391.    span.blueStep = 0;
  392.    span.alphaStep = 0;
  393.  
  394.    /* need these for fragment programs */
  395.    span.attrStart[VARYING_SLOT_POS][3] = 1.0F;
  396.    span.attrStepX[VARYING_SLOT_POS][3] = 0.0F;
  397.    span.attrStepY[VARYING_SLOT_POS][3] = 0.0F;
  398.  
  399.    ATTRIB_LOOP_BEGIN
  400.       COPY_4V(span.attrStart[attr], vert->attrib[attr]);
  401.       ASSIGN_4V(span.attrStepX[attr], 0, 0, 0, 0);
  402.       ASSIGN_4V(span.attrStepY[attr], 0, 0, 0, 0);
  403.    ATTRIB_LOOP_END
  404.  
  405.    /* compute pos, bounds and render */
  406.    {
  407.       const GLfloat x = vert->attrib[VARYING_SLOT_POS][0];
  408.       const GLfloat y = vert->attrib[VARYING_SLOT_POS][1];
  409.       GLint iSize = (GLint) (size + 0.5F);
  410.       GLint xmin, xmax, ymin, ymax, ix, iy;
  411.       GLint iRadius;
  412.  
  413.       iSize = MAX2(1, iSize);
  414.       iRadius = iSize / 2;
  415.  
  416.       if (iSize & 1) {
  417.          /* odd size */
  418.          xmin = (GLint) (x - iRadius);
  419.          xmax = (GLint) (x + iRadius);
  420.          ymin = (GLint) (y - iRadius);
  421.          ymax = (GLint) (y + iRadius);
  422.       }
  423.       else {
  424.          /* even size */
  425.          /* 0.501 factor allows conformance to pass */
  426.          xmin = (GLint) (x + 0.501) - iRadius;
  427.          xmax = xmin + iSize - 1;
  428.          ymin = (GLint) (y + 0.501) - iRadius;
  429.          ymax = ymin + iSize - 1;
  430.       }
  431.  
  432.       /* generate fragments */
  433.       span.end = 0;
  434.       for (iy = ymin; iy <= ymax; iy++) {
  435.          for (ix = xmin; ix <= xmax; ix++) {
  436.             span.array->x[span.end] = ix;
  437.             span.array->y[span.end] = iy;
  438.             span.end++;
  439.          }
  440.       }
  441.       assert(span.end <= SWRAST_MAX_WIDTH);
  442.       _swrast_write_rgba_span(ctx, &span);
  443.    }
  444. }
  445.  
  446.  
  447. /**
  448.  * Draw size=1, single-pixel point
  449.  */
  450. static void
  451. pixel_point(struct gl_context *ctx, const SWvertex *vert)
  452. {
  453.    SWcontext *swrast = SWRAST_CONTEXT(ctx);
  454.    /*
  455.     * Note that unlike the other functions, we put single-pixel points
  456.     * into a special span array in order to render as many points as
  457.     * possible with a single _swrast_write_rgba_span() call.
  458.     */
  459.    SWspan *span = &(swrast->PointSpan);
  460.    GLuint count;
  461.  
  462.    CULL_INVALID(vert);
  463.  
  464.    /* Span init */
  465.    span->interpMask = 0;
  466.    span->arrayMask = SPAN_XY | SPAN_Z;
  467.    span->arrayMask |= SPAN_RGBA;
  468.    /*span->arrayMask |= SPAN_LAMBDA;*/
  469.    span->arrayAttribs = swrast->_ActiveAttribMask; /* we'll produce these vals */
  470.  
  471.    /* need these for fragment programs */
  472.    span->attrStart[VARYING_SLOT_POS][3] = 1.0F;
  473.    span->attrStepX[VARYING_SLOT_POS][3] = 0.0F;
  474.    span->attrStepY[VARYING_SLOT_POS][3] = 0.0F;
  475.  
  476.    /* check if we need to flush */
  477.    if (span->end >= SWRAST_MAX_WIDTH ||
  478.        (swrast->_RasterMask & (BLEND_BIT | LOGIC_OP_BIT | MASKING_BIT)) ||
  479.        span->facing != swrast->PointLineFacing) {
  480.       if (span->end > 0) {
  481.          _swrast_write_rgba_span(ctx, span);
  482.          span->end = 0;
  483.       }
  484.    }
  485.  
  486.    count = span->end;
  487.  
  488.    span->facing = swrast->PointLineFacing;
  489.  
  490.    /* fragment attributes */
  491.    span->array->rgba[count][RCOMP] = vert->color[0];
  492.    span->array->rgba[count][GCOMP] = vert->color[1];
  493.    span->array->rgba[count][BCOMP] = vert->color[2];
  494.    span->array->rgba[count][ACOMP] = vert->color[3];
  495.  
  496.    ATTRIB_LOOP_BEGIN
  497.       COPY_4V(span->array->attribs[attr][count], vert->attrib[attr]);
  498.    ATTRIB_LOOP_END
  499.  
  500.    /* fragment position */
  501.    span->array->x[count] = (GLint) vert->attrib[VARYING_SLOT_POS][0];
  502.    span->array->y[count] = (GLint) vert->attrib[VARYING_SLOT_POS][1];
  503.    span->array->z[count] = (GLint) (vert->attrib[VARYING_SLOT_POS][2] + 0.5F);
  504.  
  505.    span->end = count + 1;
  506.    assert(span->end <= SWRAST_MAX_WIDTH);
  507. }
  508.  
  509.  
  510. /**
  511.  * Add specular color to primary color, draw point, restore original
  512.  * primary color.
  513.  */
  514. void
  515. _swrast_add_spec_terms_point(struct gl_context *ctx, const SWvertex *v0)
  516. {
  517.    SWvertex *ncv0 = (SWvertex *) v0; /* cast away const */
  518.    GLfloat rSum, gSum, bSum;
  519.    GLchan cSave[4];
  520.  
  521.    /* save */
  522.    COPY_CHAN4(cSave, ncv0->color);
  523.    /* sum */
  524.    rSum = CHAN_TO_FLOAT(ncv0->color[0]) + ncv0->attrib[VARYING_SLOT_COL1][0];
  525.    gSum = CHAN_TO_FLOAT(ncv0->color[1]) + ncv0->attrib[VARYING_SLOT_COL1][1];
  526.    bSum = CHAN_TO_FLOAT(ncv0->color[2]) + ncv0->attrib[VARYING_SLOT_COL1][2];
  527.    UNCLAMPED_FLOAT_TO_CHAN(ncv0->color[0], rSum);
  528.    UNCLAMPED_FLOAT_TO_CHAN(ncv0->color[1], gSum);
  529.    UNCLAMPED_FLOAT_TO_CHAN(ncv0->color[2], bSum);
  530.    /* draw */
  531.    SWRAST_CONTEXT(ctx)->SpecPoint(ctx, ncv0);
  532.    /* restore */
  533.    COPY_CHAN4(ncv0->color, cSave);
  534. }
  535.  
  536.  
  537. /**
  538.  * Examine current state to determine which point drawing function to use.
  539.  */
  540. void
  541. _swrast_choose_point(struct gl_context *ctx)
  542. {
  543.    SWcontext *swrast = SWRAST_CONTEXT(ctx);
  544.    const GLfloat size = CLAMP(ctx->Point.Size,
  545.                               ctx->Point.MinSize,
  546.                               ctx->Point.MaxSize);
  547.  
  548.    if (ctx->RenderMode == GL_RENDER) {
  549.       if (ctx->Point.PointSprite) {
  550.          swrast->Point = sprite_point;
  551.       }
  552.       else if (ctx->Point.SmoothFlag) {
  553.          swrast->Point = smooth_point;
  554.       }
  555.       else if (size > 1.0 ||
  556.                ctx->Point._Attenuated ||
  557.                ctx->VertexProgram.PointSizeEnabled) {
  558.          swrast->Point = large_point;
  559.       }
  560.       else {
  561.          swrast->Point = pixel_point;
  562.       }
  563.    }
  564.    else if (ctx->RenderMode == GL_FEEDBACK) {
  565.       swrast->Point = _swrast_feedback_point;
  566.    }
  567.    else {
  568.       /* GL_SELECT mode */
  569.       swrast->Point = _swrast_select_point;
  570.    }
  571. }
  572.