overhaul point rasterization, no longer use s_pointtemp.h
authorBrian <brian.paul@tungstengraphics.com>
Sat, 30 Jun 2007 03:12:46 +0000 (21:12 -0600)
committerBrian <brian.paul@tungstengraphics.com>
Sat, 30 Jun 2007 03:12:46 +0000 (21:12 -0600)
src/mesa/swrast/s_points.c

index b91ce73d7a32dfd2f74af163c3697ae571c1a09c..ade1eab89178824d82a6bf44a6ea101c66ef7b69 100644 (file)
 #include "s_span.h"
 
 
-#define RGBA       0x1
-#define INDEX      0x2
-#define SMOOTH     0x4
-#define ATTRIBS    0x8
-#define SPECULAR  0x10
-#define LARGE     0x20
-#define ATTENUATE 0x40
-#define SPRITE    0x80
-
-
-/*
- * CI points with size == 1.0
- */
-#define FLAGS (INDEX)
-#define NAME size1_ci_point
-#include "s_pointtemp.h"
-
-
-/*
- * General CI points.
+/**
+ * Used to cull points with invalid coords
  */
-#define FLAGS (INDEX | LARGE)
-#define NAME general_ci_point
-#include "s_pointtemp.h"
+#define CULL_INVALID(V)                              \
+   do {                                              \
+      float tmp = (V)->attrib[FRAG_ATTRIB_WPOS][0]   \
+                + (V)->attrib[FRAG_ATTRIB_WPOS][1];  \
+      if (IS_INF_OR_NAN(tmp))                        \
+        return;                                     \
+   } while(0)
 
 
-/*
- * Antialiased CI points.
+/**
+ * Draw a point sprite
  */
-#define FLAGS (INDEX | SMOOTH)
-#define NAME antialiased_ci_point
-#include "s_pointtemp.h"
+static void
+sprite_point(GLcontext *ctx, const SWvertex *vert)
+{
+   SWcontext *swrast = SWRAST_CONTEXT(ctx);
+   SWspan span;
+   GLfloat size;
+   GLuint tCoords[MAX_TEXTURE_COORD_UNITS];
+   GLuint numTcoords = 0;
+   GLfloat t0, dtdy;
+
+   CULL_INVALID(vert);
+
+   /* z coord */
+   if (ctx->DrawBuffer->Visual.depthBits <= 16)
+      span.z = FloatToFixed(vert->attrib[FRAG_ATTRIB_WPOS][2] + 0.5F);
+   else
+      span.z = (GLuint) (vert->attrib[FRAG_ATTRIB_WPOS][2] + 0.5F);
+   span.zStep = 0;
+
+   /* compute size */
+   if (ctx->Point._Attenuated || ctx->VertexProgram.PointSizeEnabled) {
+      /* use vertex's point size */
+      /* first, clamp attenuated size to the user-specifed range */
+      size = CLAMP(vert->pointSize, ctx->Point.MinSize, ctx->Point.MaxSize);
+   }
+   else {
+      /* use constant point size */
+      size = ctx->Point._Size; /* already clamped to user range */
+   }
+   /* clamp to non-AA implementation limits */
+   size = CLAMP(size, ctx->Const.MinPointSize, ctx->Const.MaxPointSize);
+
+   /* span init */
+   INIT_SPAN(span, GL_POINT, 0, 0, 0);
+   span.interpMask = SPAN_Z | SPAN_RGBA;
+
+   span.red   = ChanToFixed(vert->color[0]);
+   span.green = ChanToFixed(vert->color[1]);
+   span.blue  = ChanToFixed(vert->color[2]);
+   span.alpha = ChanToFixed(vert->color[3]);
+   span.redStep = 0;
+   span.greenStep = 0;
+   span.blueStep = 0;
+   span.alphaStep = 0;
+
+   /* need these for fragment programs */
+   span.attrStart[FRAG_ATTRIB_WPOS][3] = 1.0F;
+   span.attrStepX[FRAG_ATTRIB_WPOS][3] = 0.0F;
+   span.attrStepY[FRAG_ATTRIB_WPOS][3] = 0.0F;
+
+   ATTRIB_LOOP_BEGIN
+      if (attr >= FRAG_ATTRIB_TEX0 && attr < FRAG_ATTRIB_VAR0) {
+         const GLuint u = attr - FRAG_ATTRIB_TEX0;
+         /* a texcoord */
+         if (ctx->Point.CoordReplace[u]) {
+            GLfloat s, r, dsdx;
+
+            s = 0.0;
+            dsdx = 1.0 / size;
+
+            if (ctx->Point.SpriteOrigin == GL_LOWER_LEFT) {
+               t0 = 0.0;
+               dtdy = 1.0 / size;
+            }
+            else {
+               /* GL_UPPER_LEFT */
+               t0 = 1.0;
+               dtdy = -1.0 / size;
+            }
+            tCoords[numTcoords++] = attr;
+
+            if (ctx->Point.SpriteRMode == GL_ZERO)
+               r = 0.0F;
+            else if (ctx->Point.SpriteRMode == GL_S)
+               r = vert->attrib[attr][0];
+            else /* GL_R */
+               r = vert->attrib[attr][2];
+
+            span.attrStart[attr][0] = s;
+            span.attrStart[attr][1] = 0.0; /* overwritten below */
+            span.attrStart[attr][2] = r;
+            span.attrStart[attr][3] = 1.0;
+
+            span.attrStepX[attr][0] = dsdx;
+            span.attrStepX[attr][1] = 0.0;
+            span.attrStepX[attr][2] = 0.0;
+            span.attrStepX[attr][3] = 0.0;
+
+            span.attrStepY[attr][0] = 0.0;
+            span.attrStepY[attr][1] = dtdy;
+            span.attrStepY[attr][2] = 0.0;
+            span.attrStepY[attr][3] = 0.0;
+
+            continue;
+         }
+      }
+      /* use vertex's texcoord/attrib */
+      COPY_4V(span.attrStart[attr], vert->attrib[attr]);
+      ASSIGN_4V(span.attrStepX[attr], 0, 0, 0, 0);
+      ASSIGN_4V(span.attrStepY[attr], 0, 0, 0, 0);
+   ATTRIB_LOOP_END
+
+   /* compute pos, bounds and render */
+   {
+      const GLfloat x = vert->attrib[FRAG_ATTRIB_WPOS][0];
+      const GLfloat y = vert->attrib[FRAG_ATTRIB_WPOS][1];
+      GLint iSize = (GLint) (size + 0.5F);
+      GLint xmin, xmax, ymin, ymax, iy;
+      GLint iRadius;
+      GLfloat tcoord = t0;
+
+      iSize = MAX2(1, iSize);
+      iRadius = iSize / 2;
+
+      if (iSize & 1) {
+         /* odd size */
+         xmin = (GLint) (x - iRadius);
+         xmax = (GLint) (x + iRadius);
+         ymin = (GLint) (y - iRadius);
+         ymax = (GLint) (y + iRadius);
+      }
+      else {
+         /* even size */
+         xmin = (GLint) x - iRadius + 1;
+         xmax = xmin + iSize - 1;
+         ymin = (GLint) y - iRadius + 1;
+         ymax = ymin + iSize - 1;
+      }
 
+      /* render spans */
+      for (iy = ymin; iy <= ymax; iy++) {
+         GLuint i;
+         /* setup texcoord T for this row */
+         for (i = 0; i < numTcoords; i++) {
+            span.attrStart[tCoords[i]][1] = tcoord;
+         }
 
-/*
- * Distance attenuated, general CI points.
- */
-#define FLAGS (INDEX | ATTENUATE)
-#define NAME atten_general_ci_point
-#include "s_pointtemp.h"
+         /* these might get changed by span clipping */
+         span.x = xmin;
+         span.y = iy;
+         span.end = xmax - xmin + 1;
 
+         _swrast_write_rgba_span(ctx, &span);
 
-/*
- * RGBA points with size == 1.0
- */
-#define FLAGS (RGBA)
-#define NAME size1_rgba_point
-#include "s_pointtemp.h"
+         tcoord += dtdy;
+      }
+   }
+}
 
 
-/*
- * General RGBA points.
+/**
+ * Draw smooth/antialiased point.  RGB or CI mode.
  */
-#define FLAGS (RGBA | LARGE)
-#define NAME general_rgba_point
-#include "s_pointtemp.h"
-
+static void
+smooth_point(GLcontext *ctx, const SWvertex *vert)
+{
+   SWcontext *swrast = SWRAST_CONTEXT(ctx);
+   const GLboolean ciMode = !ctx->Visual.rgbMode;
+   SWspan span;
+   GLfloat size, alphaAtten;
+
+   CULL_INVALID(vert);
+
+   /* z coord */
+   if (ctx->DrawBuffer->Visual.depthBits <= 16)
+      span.z = FloatToFixed(vert->attrib[FRAG_ATTRIB_WPOS][2] + 0.5F);
+   else
+      span.z = (GLuint) (vert->attrib[FRAG_ATTRIB_WPOS][2] + 0.5F);
+   span.zStep = 0;
+
+   /* compute size */
+   if (ctx->Point._Attenuated || ctx->VertexProgram.PointSizeEnabled) {
+      /* use vertex's point size */
+      /* first, clamp attenuated size to the user-specifed range */
+      size = CLAMP(vert->pointSize, ctx->Point.MinSize, ctx->Point.MaxSize);
+   }
+   else {
+      /* use constant point size */
+      size = ctx->Point._Size; /* this is already clamped */
+   }
+   /* clamp to AA implementation limits */
+   size = CLAMP(size, ctx->Const.MinPointSizeAA, ctx->Const.MaxPointSizeAA);
 
-/*
- * Antialiased RGBA points.
- */
-#define FLAGS (RGBA | SMOOTH)
-#define NAME antialiased_rgba_point
-#include "s_pointtemp.h"
+   /* alpha attenuation / fade factor */
+   if (ctx->Multisample.Enabled) {
+      if (vert->pointSize >= ctx->Point.Threshold) {
+         alphaAtten = 1.0F;
+      }
+      else {
+         GLfloat dsize = vert->pointSize / ctx->Point.Threshold;
+         alphaAtten = dsize * dsize;
+      }
+   }
+   else {
+      alphaAtten = 1.0;
+   }
+   (void) alphaAtten; /* not used */
+
+   /* span init */
+   INIT_SPAN(span, GL_POINT, 0, 0, 0);
+   span.interpMask = SPAN_Z | SPAN_RGBA;
+   span.arrayMask = SPAN_COVERAGE | SPAN_MASK;
+
+   span.red   = ChanToFixed(vert->color[0]);
+   span.green = ChanToFixed(vert->color[1]);
+   span.blue  = ChanToFixed(vert->color[2]);
+   span.alpha = ChanToFixed(vert->color[3]);
+   span.redStep = 0;
+   span.greenStep = 0;
+   span.blueStep = 0;
+   span.alphaStep = 0;
+
+   /* need these for fragment programs */
+   span.attrStart[FRAG_ATTRIB_WPOS][3] = 1.0F;
+   span.attrStepX[FRAG_ATTRIB_WPOS][3] = 0.0F;
+   span.attrStepY[FRAG_ATTRIB_WPOS][3] = 0.0F;
+
+   ATTRIB_LOOP_BEGIN
+      COPY_4V(span.attrStart[attr], vert->attrib[attr]);
+      ASSIGN_4V(span.attrStepX[attr], 0, 0, 0, 0);
+      ASSIGN_4V(span.attrStepY[attr], 0, 0, 0, 0);
+   ATTRIB_LOOP_END
+
+   /* compute pos, bounds and render */
+   {
+      const GLfloat x = vert->attrib[FRAG_ATTRIB_WPOS][0];
+      const GLfloat y = vert->attrib[FRAG_ATTRIB_WPOS][1];
+      const GLfloat radius = 0.5F * size;
+      const GLfloat rmin = radius - 0.7071F;  /* 0.7071 = sqrt(2)/2 */
+      const GLfloat rmax = radius + 0.7071F;
+      const GLfloat rmin2 = MAX2(0.0F, rmin * rmin);
+      const GLfloat rmax2 = rmax * rmax;
+      const GLfloat cscale = 1.0F / (rmax2 - rmin2);
+      const GLint xmin = (GLint) (x - radius);
+      const GLint xmax = (GLint) (x + radius);
+      const GLint ymin = (GLint) (y - radius);
+      const GLint ymax = (GLint) (y + radius);
+      GLint ix, iy;
+
+      for (iy = ymin; iy <= ymax; iy++) {
+
+         /* these might get changed by span clipping */
+         span.x = xmin;
+         span.y = iy;
+         span.end = xmax - xmin + 1;
+
+         /* compute coverage for each pixel in span */
+         for (ix = xmin; ix <= xmax; ix++) {
+            const GLfloat dx = ix - x + 0.5F;
+            const GLfloat dy = iy - y + 0.5F;
+            const GLfloat dist2 = dx * dx + dy * dy;
+            GLfloat coverage;
+
+            if (dist2 < rmax2) {
+               if (dist2 >= rmin2) {
+                  /* compute partial coverage */
+                  coverage = 1.0F - (dist2 - rmin2) * cscale;
+                  if (ciMode) {
+                     /* coverage in [0,15] */
+                     coverage *= 15.0;
+                  }
+               }
+               else {
+                  /* full coverage */
+                  coverage = 1.0F;
+               }
+               span.array->mask[ix - xmin] = 1;
+            }
+            else {
+               /* zero coverage - fragment outside the radius */
+               coverage = 0.0;
+               span.array->mask[ix - xmin] = 0;
+            }
+            span.array->coverage[ix - xmin] = coverage;
+         }
 
+         /* render span */
+         _swrast_write_rgba_span(ctx, &span);
 
-/*
- * Textured RGBA points.
- */
-#define FLAGS (RGBA | LARGE | ATTRIBS | SPECULAR)
-#define NAME textured_rgba_point
-#include "s_pointtemp.h"
+      }
+   }
+}
 
 
-/*
- * Antialiased points with texture mapping.
+/**
+ * Draw large (size >= 1) non-AA point.  RGB or CI mode.
  */
-#define FLAGS (RGBA | SMOOTH | ATTRIBS | SPECULAR)
-#define NAME antialiased_tex_rgba_point
-#include "s_pointtemp.h"
+static void
+large_point(GLcontext *ctx, const SWvertex *vert)
+{
+   SWcontext *swrast = SWRAST_CONTEXT(ctx);
+   const GLboolean ciMode = !ctx->Visual.rgbMode;
+   SWspan span;
+   GLfloat size;
+
+   CULL_INVALID(vert);
+
+   /* z coord */
+   if (ctx->DrawBuffer->Visual.depthBits <= 16)
+      span.z = FloatToFixed(vert->attrib[FRAG_ATTRIB_WPOS][2] + 0.5F);
+   else
+      span.z = (GLuint) (vert->attrib[FRAG_ATTRIB_WPOS][2] + 0.5F);
+   span.zStep = 0;
+
+   /* compute size */
+   if (ctx->Point._Attenuated || ctx->VertexProgram.PointSizeEnabled) {
+      /* use vertex's point size */
+      /* first, clamp attenuated size to the user-specifed range */
+      size = CLAMP(vert->pointSize, ctx->Point.MinSize, ctx->Point.MaxSize);
+   }
+   else {
+      /* use constant point size */
+      size = ctx->Point._Size; /* already clamped to user range */
+   }
+   /* clamp to non-AA implementation limits */
+   size = CLAMP(size, ctx->Const.MinPointSize, ctx->Const.MaxPointSize);
 
+   /* span init */
+   INIT_SPAN(span, GL_POINT, 0, 0, 0);
+   span.arrayMask = SPAN_XY;
 
-/*
- * Distance attenuated, general RGBA points.
- */
-#define FLAGS (RGBA | ATTENUATE)
-#define NAME atten_general_rgba_point
-#include "s_pointtemp.h"
+   if (ciMode) {
+      span.interpMask = SPAN_Z | SPAN_INDEX;
+      span.index = FloatToFixed(vert->attrib[FRAG_ATTRIB_CI][0]);
+      span.indexStep = 0;
+   }
+   else {
+      span.interpMask = SPAN_Z | SPAN_RGBA;
+      span.red   = ChanToFixed(vert->color[0]);
+      span.green = ChanToFixed(vert->color[1]);
+      span.blue  = ChanToFixed(vert->color[2]);
+      span.alpha = ChanToFixed(vert->color[3]);
+      span.redStep = 0;
+      span.greenStep = 0;
+      span.blueStep = 0;
+      span.alphaStep = 0;
+   }
 
+   /* need these for fragment programs */
+   span.attrStart[FRAG_ATTRIB_WPOS][3] = 1.0F;
+   span.attrStepX[FRAG_ATTRIB_WPOS][3] = 0.0F;
+   span.attrStepY[FRAG_ATTRIB_WPOS][3] = 0.0F;
+
+   ATTRIB_LOOP_BEGIN
+      COPY_4V(span.attrStart[attr], vert->attrib[attr]);
+      ASSIGN_4V(span.attrStepX[attr], 0, 0, 0, 0);
+      ASSIGN_4V(span.attrStepY[attr], 0, 0, 0, 0);
+   ATTRIB_LOOP_END
+
+   /* compute pos, bounds and render */
+   {
+      const GLfloat x = vert->attrib[FRAG_ATTRIB_WPOS][0];
+      const GLfloat y = vert->attrib[FRAG_ATTRIB_WPOS][1];
+      GLint iSize = (GLint) (size + 0.5F);
+      GLint xmin, xmax, ymin, ymax, ix, iy;
+      GLint iRadius;
+
+      iSize = MAX2(1, iSize);
+      iRadius = iSize / 2;
+
+      if (iSize & 1) {
+         /* odd size */
+         xmin = (GLint) (x - iRadius);
+         xmax = (GLint) (x + iRadius);
+         ymin = (GLint) (y - iRadius);
+         ymax = (GLint) (y + iRadius);
+      }
+      else {
+         /* even size */
+         xmin = (GLint) x - iRadius + 1;
+         xmax = xmin + iSize - 1;
+         ymin = (GLint) y - iRadius + 1;
+         ymax = ymin + iSize - 1;
+      }
 
-/*
- * Distance attenuated, textured RGBA points.
- */
-#define FLAGS (RGBA | ATTENUATE | ATTRIBS | SPECULAR)
-#define NAME atten_textured_rgba_point
-#include "s_pointtemp.h"
+      /* generate fragments */
+      span.end = 0;
+      for (iy = ymin; iy <= ymax; iy++) {
+         for (ix = xmin; ix <= xmax; ix++) {
+            span.array->x[span.end] = ix;
+            span.array->y[span.end] = iy;
+            span.end++;
+         }
+      }
+      assert(span.end <= MAX_WIDTH);
+      _swrast_write_rgba_span(ctx, &span);
+   }
+}
 
 
-/*
- * Distance attenuated, antialiased points with or without texture mapping.
+/**
+ * Draw size=1, single-pixel point
  */
-#define FLAGS (RGBA | ATTENUATE | ATTRIBS | SMOOTH)
-#define NAME atten_antialiased_rgba_point
-#include "s_pointtemp.h"
+static void
+pixel_point(GLcontext *ctx, const SWvertex *vert)
+{
+   SWcontext *swrast = SWRAST_CONTEXT(ctx);
+   const GLboolean ciMode = !ctx->Visual.rgbMode;
+   /*
+    * Note that unlike the other functions, we put single-pixel points
+    * into a special span array in order to render as many points as
+    * possible with a single _swrast_write_rgba_span() call.
+    */
+   SWspan *span = &(swrast->PointSpan);
+   GLuint count;
+
+   CULL_INVALID(vert);
+
+   /* Span init */
+   span->interpMask = 0;
+   span->arrayMask = SPAN_XY | SPAN_Z;
+   if (ciMode)
+      span->arrayMask |= SPAN_INDEX;
+   else
+      span->arrayMask |= SPAN_RGBA;
+   /*span->arrayMask |= SPAN_LAMBDA;*/
+   span->arrayAttribs = swrast->_ActiveAttribMask; /* we'll produce these vals */
+
+   /* need these for fragment programs */
+   span->attrStart[FRAG_ATTRIB_WPOS][3] = 1.0F;
+   span->attrStepX[FRAG_ATTRIB_WPOS][3] = 0.0F;
+   span->attrStepY[FRAG_ATTRIB_WPOS][3] = 0.0F;
+
+   /* check if we need to flush */
+   if (span->end >= MAX_WIDTH ||
+       (swrast->_RasterMask & (BLEND_BIT | LOGIC_OP_BIT | MASKING_BIT))) {
+      if (ciMode)
+         _swrast_write_index_span(ctx, span);
+      else
+         _swrast_write_rgba_span(ctx, span);
+      span->end = 0;
+   }
 
+   count = span->end;
 
-/*
- * Sprite (textured point)
- */
-#define FLAGS (RGBA | SPRITE | SPECULAR)
-#define NAME sprite_point
-#include "s_pointtemp.h"
+   /* fragment attributes */
+   if (ciMode) {
+      span->array->index[count] = (GLuint) vert->attrib[FRAG_ATTRIB_CI][0];
+   }
+   else {
+      span->array->rgba[count][RCOMP] = vert->color[0];
+      span->array->rgba[count][GCOMP] = vert->color[1];
+      span->array->rgba[count][BCOMP] = vert->color[2];
+      span->array->rgba[count][ACOMP] = vert->color[3];
+   }
+   ATTRIB_LOOP_BEGIN
+      COPY_4V(span->array->attribs[attr][count], vert->attrib[attr]);
+   ATTRIB_LOOP_END
 
+   /* fragment position */
+   span->array->x[count] = (GLint) vert->attrib[FRAG_ATTRIB_WPOS][0];
+   span->array->y[count] = (GLint) vert->attrib[FRAG_ATTRIB_WPOS][1];
+   span->array->z[count] = (GLint) (vert->attrib[FRAG_ATTRIB_WPOS][2] + 0.5F);
 
-#define FLAGS (RGBA | SPRITE | SPECULAR | ATTENUATE)
-#define NAME atten_sprite_point
-#include "s_pointtemp.h"
+   span->end = count + 1;
+   ASSERT(span->end <= MAX_WIDTH);
+}
 
 
+/**
+ * Add specular color to primary color, draw point, restore original
+ * primary color.
+ */
 void
 _swrast_add_spec_terms_point(GLcontext *ctx, const SWvertex *v0)
 {
-   SWvertex *ncv0 = (SWvertex *) v0;
+   SWvertex *ncv0 = (SWvertex *) v0; /* cast away const */
    GLfloat rSum, gSum, bSum;
    GLchan cSave[4];
 
    /* save */
-   COPY_CHAN4( cSave, ncv0->color );
+   COPY_CHAN4(cSave, ncv0->color);
    /* sum */
    rSum = CHAN_TO_FLOAT(ncv0->color[0]) + ncv0->attrib[FRAG_ATTRIB_COL1][0];
    gSum = CHAN_TO_FLOAT(ncv0->color[1]) + ncv0->attrib[FRAG_ATTRIB_COL1][1];
@@ -176,121 +535,35 @@ _swrast_add_spec_terms_point(GLcontext *ctx, const SWvertex *v0)
 }
 
 
-
-/* record the current point function name */
-#ifdef DEBUG
-
-static const char *pntFuncName = NULL;
-
-#define USE(pntFunc)                   \
-do {                                   \
-    pntFuncName = #pntFunc;            \
-    /*printf("%s\n", pntFuncName);*/   \
-    swrast->Point = pntFunc;           \
-} while (0)
-
-#else
-
-#define USE(pntFunc)  swrast->Point = pntFunc
-
-#endif
-
-
-/*
- * Examine the current context to determine which point drawing function
- * should be used.
+/**
+ * Examine current state to determine which point drawing function to use.
  */
 void
-_swrast_choose_point( GLcontext *ctx )
+_swrast_choose_point(GLcontext *ctx)
 {
    SWcontext *swrast = SWRAST_CONTEXT(ctx);
-   GLboolean rgbMode = ctx->Visual.rgbMode;
-   GLboolean specular = (ctx->Fog.ColorSumEnabled ||
-                         (ctx->Light.Enabled &&
-                          ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR));
-   GLboolean attribs = (ctx->FragmentProgram._Current ||
-                        ctx->Texture._EnabledCoordUnits ||
-                        swrast->_FogEnabled ||
-                        specular);
 
-   /*
-    * XXX this is a mess that should be cleaned up someday
-    */
-
-   if (ctx->RenderMode==GL_RENDER) {
+   if (ctx->RenderMode == GL_RENDER) {
       if (ctx->Point.PointSprite) {
-         /* GL_ARB_point_sprite / GL_NV_point_sprite */
-         /* XXX this might not be good enough */
-         if (ctx->Point._Attenuated)
-            USE(atten_sprite_point);
-         else
-            USE(sprite_point);
-      }
-      else if (ctx->Point.SmoothFlag && !attribs) {
-         /* Smooth points */
-         if (rgbMode) {
-            if (ctx->Point._Attenuated || ctx->VertexProgram.PointSizeEnabled) {
-               USE(atten_antialiased_rgba_point);
-            }
-            else if (ctx->Texture._EnabledCoordUnits) {
-               USE(antialiased_tex_rgba_point);
-            }
-            else {
-               USE(antialiased_rgba_point);
-            }
-         }
-         else {
-            USE(antialiased_ci_point);
-         }
+         swrast->Point = sprite_point;
       }
-      else if (ctx->Point._Attenuated || ctx->VertexProgram.PointSizeEnabled) {
-         if (rgbMode) {
-            if (attribs) {
-               if (ctx->Point.SmoothFlag) {
-                  USE(atten_antialiased_rgba_point);
-               }
-               else {
-                  USE(atten_textured_rgba_point);
-               }
-            }
-            else {
-               USE(atten_general_rgba_point);
-            }
-         }
-         else {
-            /* ci, atten */
-            USE(atten_general_ci_point);
-         }
+      else if (ctx->Point.SmoothFlag) {
+         swrast->Point = smooth_point;
       }
-      else if (attribs && rgbMode) {
-         /* textured, fogged */
-         USE(textured_rgba_point);
-      }
-      else if (ctx->Point._Size != 1.0) {
-         /* large points */
-         if (rgbMode) {
-            USE(general_rgba_point);
-         }
-         else {
-            USE(general_ci_point);
-         }
+      else if (ctx->Point._Size > 1.0 ||
+               ctx->Point._Attenuated ||
+               ctx->VertexProgram.PointSizeEnabled) {
+         swrast->Point = large_point;
       }
       else {
-         /* single pixel points */
-         if (rgbMode) {
-            assert((swrast->_ActiveAttribMask & FRAG_BIT_COL1) == 0);
-            USE(size1_rgba_point);
-         }
-         else {
-            USE(size1_ci_point);
-         }
+         swrast->Point = pixel_point;
       }
    }
-   else if (ctx->RenderMode==GL_FEEDBACK) {
-      USE(_swrast_feedback_point);
+   else if (ctx->RenderMode == GL_FEEDBACK) {
+      swrast->Point = _swrast_feedback_point;
    }
    else {
       /* GL_SELECT mode */
-      USE(_swrast_select_point);
+      swrast->Point = _swrast_select_point;
    }
 }