From 3ad9c551b95c6fd8787f6f007bda34df446b53ab Mon Sep 17 00:00:00 2001
From: Roland Scheidegger <sroland@tungstengraphics.com>
Date: Sat, 19 May 2007 00:45:38 +0200
Subject: fix small s3tc mipmaps (#10968)

make sure that always whole blocks are uploaded.
(May still not work correctly if the top mip map is not at least a full block,
that is 4 pixels wide - not sure, but probably doesn't happen in real world)
---
 src/mesa/drivers/dri/i915/i915_texstate.c |  8 ++-----
 src/mesa/drivers/dri/i915/intel_tex.c     | 35 ++++++++++++++++---------------
 2 files changed, 20 insertions(+), 23 deletions(-)

(limited to 'src/mesa/drivers')

diff --git a/src/mesa/drivers/dri/i915/i915_texstate.c b/src/mesa/drivers/dri/i915/i915_texstate.c
index 3b639e7144..9f0c9491b2 100644
--- a/src/mesa/drivers/dri/i915/i915_texstate.c
+++ b/src/mesa/drivers/dri/i915/i915_texstate.c
@@ -172,12 +172,8 @@ static void i915LayoutTextureImages( i915ContextPtr i915,
 	 
 	 t->intel.image[0][i].offset = total_height * pitch;
 	 t->intel.image[0][i].internalFormat = baseImage->_BaseFormat;
-	 if (t->intel.image[0][i].image->IsCompressed)
-	 {
-	   if (t->intel.image[0][i].image->Height > 4)
-	     total_height += t->intel.image[0][i].image->Height/4;
-	   else
-	     total_height += 1;
+	 if (t->intel.image[0][i].image->IsCompressed) {
+	    total_height += (t->intel.image[0][i].image->Height + 3) / 4;
 	 }
 	 else
 	   total_height += MAX2(2, t->intel.image[0][i].image->Height);
diff --git a/src/mesa/drivers/dri/i915/intel_tex.c b/src/mesa/drivers/dri/i915/intel_tex.c
index 6012d3e799..46f49e74e5 100644
--- a/src/mesa/drivers/dri/i915/intel_tex.c
+++ b/src/mesa/drivers/dri/i915/intel_tex.c
@@ -634,18 +634,12 @@ static void intelUploadTexImage( intelContextPtr intel,
 			       image->Height);
    }
    else if (image->IsCompressed) {
-      GLuint row_len = image->Width * 2;
+      GLuint row_len = 0;
       GLubyte *dst = (GLubyte *)(t->BufAddr + offset);
       GLubyte *src = (GLubyte *)image->Data;
       GLuint j;
 
-      if (INTEL_DEBUG & DEBUG_TEXTURE)
-	 fprintf(stderr, 
-		 "Upload image %dx%dx%d offset %xm row_len %x "
-		 "pitch %x depth_pitch %x\n",
-		 image->Width, image->Height, image->Depth, offset,
-		 row_len, t->Pitch, t->depth_pitch);
-
+      /* must always copy whole blocks (8/16 bytes) */
       switch (image->InternalFormat) {
 	case GL_COMPRESSED_RGB_FXT1_3DFX:
 	case GL_COMPRESSED_RGBA_FXT1_3DFX:
@@ -653,24 +647,31 @@ static void intelUploadTexImage( intelContextPtr intel,
 	case GL_RGB4_S3TC:
 	case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
 	case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
-	  for (j = 0 ; j < image->Height/4 ; j++, dst += (t->Pitch)) {
-	    __memcpy(dst, src, row_len );
-	    src += row_len;
-	  }
+	  row_len = (image->Width * 2 + 7) & ~7;
 	  break;
 	case GL_RGBA_S3TC:
 	case GL_RGBA4_S3TC:
 	case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
-	case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
-	  for (j = 0 ; j < image->Height/4 ; j++, dst += (t->Pitch)) {
-	    __memcpy(dst, src, (image->Width*4) );
-	    src += image->Width*4;
-	  }
+	  row_len = (image->Width * 4 + 15) & ~15;
 	  break;
 	default:
 	  fprintf(stderr,"Internal Compressed format not supported %d\n", image->InternalFormat);
 	  break;
       }
+
+      if (INTEL_DEBUG & DEBUG_TEXTURE)
+	 fprintf(stderr, 
+		 "Upload image %dx%dx%d offset %xm row_len %x "
+		 "pitch %x depth_pitch %x\n",
+		 image->Width, image->Height, image->Depth, offset,
+		 row_len, t->Pitch, t->depth_pitch);
+
+      if (row_len) {
+	 for (j = 0 ; j < (image->Height + 3)/4 ; j++, dst += (t->Pitch)) {
+	   __memcpy(dst, src, row_len );
+	   src += row_len;
+	 }
+      }
    }
    /* Time for another vtbl entry:
     */
-- 
cgit v1.2.3


From 28f53ace336706912fda6cc6877f72bffdcae330 Mon Sep 17 00:00:00 2001
From: Roland Scheidegger <sroland@tungstengraphics.com>
Date: Sat, 19 May 2007 00:59:06 +0200
Subject: fix miptree comparison with compressed textures

TexelBytes is always 0 with compressed textures, thus would never match
mt->cpp. This caused constant blitting around of textures, and it fixes at
least the horrible performance of Q3 if compressed textures are enabled.
---
 src/mesa/drivers/dri/i915tex/intel_tex_validate.c | 17 ++++++++++-------
 1 file changed, 10 insertions(+), 7 deletions(-)

(limited to 'src/mesa/drivers')

diff --git a/src/mesa/drivers/dri/i915tex/intel_tex_validate.c b/src/mesa/drivers/dri/i915tex/intel_tex_validate.c
index 79d587a174..0ae4fee1ba 100644
--- a/src/mesa/drivers/dri/i915tex/intel_tex_validate.c
+++ b/src/mesa/drivers/dri/i915tex/intel_tex_validate.c
@@ -105,6 +105,8 @@ intel_finalize_mipmap_tree(struct intel_context *intel, GLuint unit)
 {
    struct gl_texture_object *tObj = intel->ctx.Texture.Unit[unit]._Current;
    struct intel_texture_object *intelObj = intel_texture_object(tObj);
+   int comp_byte = 0;
+   int cpp;
 
    GLuint face, i;
    GLuint nr_faces = 0;
@@ -148,6 +150,12 @@ intel_finalize_mipmap_tree(struct intel_context *intel, GLuint unit)
       intel_miptree_reference(&intelObj->mt, firstImage->mt);
    }
 
+   if (firstImage->base.IsCompressed) {
+      comp_byte = intel_compressed_num_bytes(firstImage->base.TexFormat->MesaFormat);
+      cpp = comp_byte;
+   }
+   else cpp = firstImage->base.TexFormat->TexelBytes;
+
    /* Check tree can hold all active levels.  Check tree matches
     * target, imageFormat, etc.
     * 
@@ -165,7 +173,7 @@ intel_finalize_mipmap_tree(struct intel_context *intel, GLuint unit)
 	intelObj->mt->width0 != firstImage->base.Width ||
 	intelObj->mt->height0 != firstImage->base.Height ||
 	intelObj->mt->depth0 != firstImage->base.Depth ||
-	intelObj->mt->cpp != firstImage->base.TexFormat->TexelBytes ||
+	intelObj->mt->cpp != cpp ||
 	intelObj->mt->compressed != firstImage->base.IsCompressed)) {
       intel_miptree_release(intel, &intelObj->mt);
    }
@@ -174,10 +182,6 @@ intel_finalize_mipmap_tree(struct intel_context *intel, GLuint unit)
    /* May need to create a new tree:
     */
    if (!intelObj->mt) {
-      int comp_byte = 0;
-      
-      if (firstImage->base.IsCompressed)
-	 comp_byte = intel_compressed_num_bytes(firstImage->base.TexFormat->MesaFormat);
       intelObj->mt = intel_miptree_create(intel,
                                           intelObj->base.Target,
                                           firstImage->base.InternalFormat,
@@ -186,8 +190,7 @@ intel_finalize_mipmap_tree(struct intel_context *intel, GLuint unit)
                                           firstImage->base.Width,
                                           firstImage->base.Height,
                                           firstImage->base.Depth,
-                                          firstImage->base.TexFormat->
-                                          TexelBytes,
+                                          cpp,
                                           comp_byte);
    }
 
-- 
cgit v1.2.3


From 25551bdfad8541337a4e59e7e3764fa9b876cb19 Mon Sep 17 00:00:00 2001
From: Roland Scheidegger <sroland@tungstengraphics.com>
Date: Sat, 19 May 2007 03:08:45 +0200
Subject: fix copy & paste bug of previous commit, breaking dxt5 formats

---
 src/mesa/drivers/dri/i915/intel_tex.c | 1 +
 1 file changed, 1 insertion(+)

(limited to 'src/mesa/drivers')

diff --git a/src/mesa/drivers/dri/i915/intel_tex.c b/src/mesa/drivers/dri/i915/intel_tex.c
index 46f49e74e5..98ddc79672 100644
--- a/src/mesa/drivers/dri/i915/intel_tex.c
+++ b/src/mesa/drivers/dri/i915/intel_tex.c
@@ -652,6 +652,7 @@ static void intelUploadTexImage( intelContextPtr intel,
 	case GL_RGBA_S3TC:
 	case GL_RGBA4_S3TC:
 	case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
+	case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
 	  row_len = (image->Width * 4 + 15) & ~15;
 	  break;
 	default:
-- 
cgit v1.2.3


From eb6418b8952f335b6cf58232b5f282fc3e325c7a Mon Sep 17 00:00:00 2001
From: Roland Scheidegger <sroland@tungstengraphics.com>
Date: Sat, 19 May 2007 04:38:55 +0200
Subject: fix miptree layout (i915) for small compressed mipmaps

This seems to work now. Also fix i945 set_level_info, need to match i915
behaviour for storing mip height, as it's assumed to be the mip width
(in texels) elsewhere and the division by 4 is done later (untested).
---
 src/mesa/drivers/dri/i915tex/i915_tex_layout.c | 4 +---
 src/mesa/drivers/dri/intel/intel_tex_layout.c  | 2 +-
 2 files changed, 2 insertions(+), 4 deletions(-)

(limited to 'src/mesa/drivers')

diff --git a/src/mesa/drivers/dri/i915tex/i915_tex_layout.c b/src/mesa/drivers/dri/i915tex/i915_tex_layout.c
index 2e1600cfdf..9f40706c36 100644
--- a/src/mesa/drivers/dri/i915tex/i915_tex_layout.c
+++ b/src/mesa/drivers/dri/i915tex/i915_tex_layout.c
@@ -161,11 +161,9 @@ i915_miptree_layout(struct intel_mipmap_tree * mt)
             if (mt->compressed)
                img_height = MAX2(1, height / 4);
             else
-               img_height = MAX2(2, height);
+               img_height = (MAX2(2, height) + 1) & ~1;
 
 	    mt->total_height += img_height;
-	    mt->total_height += 1;
-	    mt->total_height &= ~1;
 
             width = minify(width);
             height = minify(height);
diff --git a/src/mesa/drivers/dri/intel/intel_tex_layout.c b/src/mesa/drivers/dri/intel/intel_tex_layout.c
index f356480217..fcb5cc3906 100644
--- a/src/mesa/drivers/dri/intel/intel_tex_layout.c
+++ b/src/mesa/drivers/dri/intel/intel_tex_layout.c
@@ -74,7 +74,7 @@ void i945_miptree_layout_2d( struct intel_mipmap_tree *mt )
       GLuint img_height;
 
       intel_miptree_set_level_info(mt, level, 1, x, y, width, 
-				   mt->compressed ? height/4 : height, 1);
+				   height, 1);
 
       if (mt->compressed)
 	 img_height = MAX2(1, height/4);
-- 
cgit v1.2.3


From fd54564f78d4aeae2c39ada7502ec659c14b3eca Mon Sep 17 00:00:00 2001
From: Brian <brian@yutani.localnet.net>
Date: Sat, 19 May 2007 08:27:35 -0600
Subject: Implement GLX_EXT_texture_from_pixmap.

Could be done more efficiently... but works.
---
 src/mesa/drivers/x11/fakeglx.c | 186 +++++++++++++++++++++++++++++--
 src/mesa/drivers/x11/glxapi.c  |  32 +++++-
 src/mesa/drivers/x11/glxapi.h  |   5 +
 src/mesa/drivers/x11/xm_api.c  | 247 +++++++++++++++++++++++++++++++++++++++--
 src/mesa/drivers/x11/xmesaP.h  |   9 +-
 5 files changed, 454 insertions(+), 25 deletions(-)

(limited to 'src/mesa/drivers')

diff --git a/src/mesa/drivers/x11/fakeglx.c b/src/mesa/drivers/x11/fakeglx.c
index 86a4deabc6..ef22a3f03e 100644
--- a/src/mesa/drivers/x11/fakeglx.c
+++ b/src/mesa/drivers/x11/fakeglx.c
@@ -1,8 +1,8 @@
 /*
  * Mesa 3-D graphics library
- * Version:  6.5.2
+ * Version:  7.1
  *
- * Copyright (C) 1999-2006  Brian Paul   All Rights Reserved.
+ * Copyright (C) 1999-2007  Brian Paul   All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -78,6 +78,7 @@
    "GLX_MESA_pixmap_colormap " \
    "GLX_MESA_release_buffers " \
    "GLX_ARB_get_proc_address " \
+   "GLX_EXT_texture_from_pixmap " \
    "GLX_EXT_visual_info " \
    "GLX_EXT_visual_rating " \
    /*"GLX_SGI_video_sync "*/ \
@@ -1223,6 +1224,30 @@ choose_visual( Display *dpy, int screen, const int *list, GLboolean fbConfig )
             /* ignore */
             break;
 
+#ifdef GLX_EXT_texture_from_pixmap
+         case GLX_BIND_TO_TEXTURE_RGB_EXT:
+            parselist++; /*skip*/
+            break;
+         case GLX_BIND_TO_TEXTURE_RGBA_EXT:
+            parselist++; /*skip*/
+            break;
+         case GLX_BIND_TO_MIPMAP_TEXTURE_EXT:
+            parselist++; /*skip*/
+            break;
+         case GLX_BIND_TO_TEXTURE_TARGETS_EXT:
+            parselist++;
+            if (*parselist & ~(GLX_TEXTURE_1D_BIT_EXT |
+                               GLX_TEXTURE_2D_BIT_EXT |
+                               GLX_TEXTURE_RECTANGLE_BIT_EXT)) {
+               /* invalid bit */
+               return NULL;
+            }
+            break;
+         case GLX_Y_INVERTED_EXT:
+            parselist++; /*skip*/
+            break;
+#endif
+
 	 case None:
             /* end of list */
 	    break;
@@ -1878,6 +1903,27 @@ get_config( XMesaVisual xmvis, int attrib, int *value, GLboolean fbconfig )
          *value = xmvis->visinfo->visualid;
          break;
 
+#ifdef GLX_EXT_texture_from_pixmap
+      case GLX_BIND_TO_TEXTURE_RGB_EXT:
+         *value = True; /*XXX*/
+         break;
+      case GLX_BIND_TO_TEXTURE_RGBA_EXT:
+         /* XXX review */
+         *value = xmvis->mesa_visual.alphaBits > 0 ? True : False;
+         break;
+      case GLX_BIND_TO_MIPMAP_TEXTURE_EXT:
+         *value = True; /*XXX*/
+         break;
+      case GLX_BIND_TO_TEXTURE_TARGETS_EXT:
+         *value = (GLX_TEXTURE_1D_BIT_EXT |
+                   GLX_TEXTURE_2D_BIT_EXT |
+                   GLX_TEXTURE_RECTANGLE_BIT_EXT); /*XXX*/
+         break;
+      case GLX_Y_INVERTED_EXT:
+         *value = False; /*XXX*/
+         break;
+#endif
+
       default:
 	 return GLX_BAD_ATTRIBUTE;
    }
@@ -2145,16 +2191,102 @@ Fake_glXCreatePixmap( Display *dpy, GLXFBConfig config, Pixmap pixmap,
 {
    XMesaVisual v = (XMesaVisual) config;
    XMesaBuffer b;
-
-   (void) dpy;
-   (void) config;
-   (void) pixmap;
-   (void) attribList;  /* Ignored in GLX 1.3 */
+   const int *attr;
+   int target = 0, format = 0, mipmap = 0;
+   int value;
 
    if (!dpy || !config || !pixmap)
       return 0;
 
-   b = XMesaCreatePixmapBuffer( v, pixmap, 0 );
+   for (attr = attribList; *attr; attr++) {
+      switch (*attr) {
+      case GLX_TEXTURE_FORMAT_EXT:
+         attr++;
+         switch (*attr) {
+         case GLX_TEXTURE_FORMAT_NONE_EXT:
+         case GLX_TEXTURE_FORMAT_RGB_EXT:
+         case GLX_TEXTURE_FORMAT_RGBA_EXT:
+            format = *attr;
+            break;
+         default:
+            /* error */
+            return 0;
+         }
+         break;
+      case GLX_TEXTURE_TARGET_EXT:
+         attr++;
+         switch (*attr) {
+         case GLX_TEXTURE_1D_EXT:
+         case GLX_TEXTURE_2D_EXT:
+         case GLX_TEXTURE_RECTANGLE_EXT:
+            target = *attr;
+            break;
+         default:
+            /* error */
+            return 0;
+         }
+         break;
+      case GLX_MIPMAP_TEXTURE_EXT:
+         attr++;
+         if (*attr)
+            mipmap = 1;
+         break;
+      default:
+         /* error */
+         return 0;
+      }
+   }
+
+   if (format == GLX_TEXTURE_FORMAT_RGB_EXT) {
+      if (get_config(v, GLX_BIND_TO_TEXTURE_RGB_EXT,
+                     &value, GL_TRUE) != Success
+          || !value) {
+         return 0; /* error! */
+      }
+   }
+   else if (format == GLX_TEXTURE_FORMAT_RGBA_EXT) {
+      if (get_config(v, GLX_BIND_TO_TEXTURE_RGBA_EXT,
+                     &value, GL_TRUE) != Success
+          || !value) {
+         return 0; /* error! */
+      }
+   }
+   if (mipmap) {
+      if (get_config(v, GLX_BIND_TO_MIPMAP_TEXTURE_EXT,
+                     &value, GL_TRUE) != Success
+          || !value) {
+         return 0; /* error! */
+      }
+   }
+   if (target == GLX_TEXTURE_1D_EXT) {
+      if (get_config(v, GLX_BIND_TO_TEXTURE_TARGETS_EXT,
+                     &value, GL_TRUE) != Success
+          || (value & GLX_TEXTURE_1D_BIT_EXT) == 0) {
+         return 0; /* error! */
+      }
+   }
+   else if (target == GLX_TEXTURE_2D_EXT) {
+      if (get_config(v, GLX_BIND_TO_TEXTURE_TARGETS_EXT,
+                     &value, GL_TRUE) != Success
+          || (value & GLX_TEXTURE_2D_BIT_EXT) == 0) {
+         return 0; /* error! */
+      }
+   }
+   if (target == GLX_TEXTURE_RECTANGLE_EXT) {
+      if (get_config(v, GLX_BIND_TO_TEXTURE_TARGETS_EXT,
+                     &value, GL_TRUE) != Success
+          || (value & GLX_TEXTURE_RECTANGLE_BIT_EXT) == 0) {
+         return 0; /* error! */
+      }
+   }
+
+   if (format || target || mipmap) {
+      /* texture from pixmap */
+      b = XMesaCreatePixmapTextureBuffer(v, pixmap, 0, format, target, mipmap);
+   }
+   else {
+      b = XMesaCreatePixmapBuffer( v, pixmap, 0 );
+   }
    if (!b) {
       return 0;
    }
@@ -2260,8 +2392,20 @@ Fake_glXQueryDrawable( Display *dpy, GLXDrawable draw, int attribute,
       case GLX_FBCONFIG_ID:
          *value = xmbuf->xm_visual->visinfo->visualid;
          return;
+#ifdef GLX_EXT_texture_from_pixmap
+      case GLX_TEXTURE_FORMAT_EXT:
+         *value = xmbuf->TextureFormat;
+         break;
+      case GLX_TEXTURE_TARGET_EXT:
+         *value = xmbuf->TextureTarget;
+         break;
+      case GLX_MIPMAP_TEXTURE_EXT:
+         *value = xmbuf->TextureMipmap;
+         break;
+#endif
+
       default:
-         return;  /* GLX_BAD_ATTRIBUTE? */
+         return; /* raise BadValue error */
    }
 }
 
@@ -2854,6 +2998,26 @@ Fake_glXGetAGPOffsetMESA( const GLvoid *pointer )
 }
 
 
+/*** GLX_EXT_texture_from_pixmap ***/
+
+static void
+Fake_glXBindTexImageEXT(Display *dpy, GLXDrawable drawable, int buffer,
+                        const int *attrib_list)
+{
+   XMesaBuffer b = XMesaFindBuffer(dpy, drawable);
+   if (b)
+      XMesaBindTexImage(dpy, b, buffer, attrib_list);
+}
+
+static void
+Fake_glXReleaseTexImageEXT(Display *dpy, GLXDrawable drawable, int buffer)
+{
+   XMesaBuffer b = XMesaFindBuffer(dpy, drawable);
+   if (b)
+      XMesaReleaseTexImage(dpy, b, buffer);
+}
+
+
 /* silence warning */
 extern struct _glxapi_table *_mesa_GetGLXDispatchTable(void);
 
@@ -3009,5 +3173,9 @@ _mesa_GetGLXDispatchTable(void)
    /*** GLX_MESA_agp_offset ***/
    glx.GetAGPOffsetMESA = Fake_glXGetAGPOffsetMESA;
 
+   /*** GLX_EXT_texture_from_pixmap ***/
+   glx.BindTexImageEXT = Fake_glXBindTexImageEXT;
+   glx.ReleaseTexImageEXT = Fake_glXReleaseTexImageEXT;
+
    return &glx;
 }
diff --git a/src/mesa/drivers/x11/glxapi.c b/src/mesa/drivers/x11/glxapi.c
index 973f394045..5f11c90c13 100644
--- a/src/mesa/drivers/x11/glxapi.c
+++ b/src/mesa/drivers/x11/glxapi.c
@@ -1,8 +1,8 @@
 /*
  * Mesa 3-D graphics library
- * Version:  6.5
+ * Version:  7.1
  * 
- * Copyright (C) 1999-2006  Brian Paul   All Rights Reserved.
+ * Copyright (C) 1999-2007  Brian Paul   All Rights Reserved.
  * 
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -1104,6 +1104,27 @@ glXGetMemoryOffsetMESA(Display *dpy, int scrn, const void *pointer)
 }
 
 
+/*** GLX_EXT_texture_from_pixmap */
+
+void
+glXBindTexImageEXT(Display *dpy, GLXDrawable drawable, int buffer,
+                   const int *attrib_list)
+{
+   struct _glxapi_table *t;
+   GET_DISPATCH(dpy, t);
+   if (t)
+      t->BindTexImageEXT(dpy, drawable, buffer, attrib_list);
+}
+
+void
+glXReleaseTexImageEXT(Display *dpy, GLXDrawable drawable, int buffer)
+{
+   struct _glxapi_table *t;
+   GET_DISPATCH(dpy, t);
+   if (t)
+      t->ReleaseTexImageEXT(dpy, drawable, buffer);
+}
+
 
 /**********************************************************************/
 /* GLX API management functions                                       */
@@ -1147,6 +1168,9 @@ _glxapi_get_extensions(void)
 #endif
 #ifdef GLX_SGIX_pbuffer
       "GLX_SGIX_pbuffer",
+#endif
+#ifdef GLX_EXT_texture_from_pixmap,
+      "GLX_EXT_texture_from_pixmap",
 #endif
       NULL
    };
@@ -1333,6 +1357,10 @@ static struct name_address_pair GLX_functions[] = {
    { "glXFreeMemoryMESA", (__GLXextFuncPtr) glXFreeMemoryMESA },
    { "glXGetMemoryOffsetMESA", (__GLXextFuncPtr) glXGetMemoryOffsetMESA },
 
+   /*** GLX_EXT_texture_from_pixmap ***/
+   { "glXBindTexImageEXT", (__GLXextFuncPtr) glXBindTexImageEXT },
+   { "glXReleaseTexImageEXT", (__GLXextFuncPtr) glXReleaseTexImageEXT },
+
    { NULL, NULL }   /* end of list */
 };
 
diff --git a/src/mesa/drivers/x11/glxapi.h b/src/mesa/drivers/x11/glxapi.h
index 3187534c9a..37de81e55a 100644
--- a/src/mesa/drivers/x11/glxapi.h
+++ b/src/mesa/drivers/x11/glxapi.h
@@ -196,6 +196,11 @@ struct _glxapi_table {
 
    /*** GLX_MESA_agp_offset ***/
    GLuint (*GetAGPOffsetMESA)( const GLvoid *pointer );
+
+   /*** GLX_EXT_texture_from_pixmap ***/
+   void (*BindTexImageEXT)(Display *dpy, GLXDrawable drawable, int buffer,
+                           const int *attrib_list);
+   void (*ReleaseTexImageEXT)(Display *dpy, GLXDrawable drawable, int buffer);
 };
 
 
diff --git a/src/mesa/drivers/x11/xm_api.c b/src/mesa/drivers/x11/xm_api.c
index a07d0a90cf..edaa71508f 100644
--- a/src/mesa/drivers/x11/xm_api.c
+++ b/src/mesa/drivers/x11/xm_api.c
@@ -1,8 +1,8 @@
 /*
  * Mesa 3-D graphics library
- * Version:  6.5.2
+ * Version:  7.1
  *
- * Copyright (C) 1999-2006  Brian Paul   All Rights Reserved.
+ * Copyright (C) 1999-2007  Brian Paul   All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -72,6 +72,7 @@
 #include "imports.h"
 #include "macros.h"
 #include "renderbuffer.h"
+#include "teximage.h"
 #include "swrast/swrast.h"
 #include "swrast_setup/swrast_setup.h"
 #include "vbo/vbo.h"
@@ -295,6 +296,19 @@ static GLboolean window_exists( XMesaDisplay *dpy, Window win )
 #endif
 
 
+static Status
+get_drawable_size(Display *dpy, Drawable d, GLuint *width, GLuint *height)
+{
+   Window root;
+   Status stat;
+   int xpos, ypos;
+   unsigned int w, h, bw, depth;
+   stat = XGetGeometry(dpy, d, &root, &xpos, &ypos, &w, &h, &bw, &depth);
+   *width = w;
+   *height = h;
+   return stat;
+}
+
 
 /**
  * Return the size of the window (or pixmap) that corresponds to the
@@ -310,22 +324,14 @@ xmesa_get_window_size(XMesaDisplay *dpy, XMesaBuffer b,
    *width = MIN2(b->frontxrb->drawable->width, MAX_WIDTH);
    *height = MIN2(b->frontxrb->drawable->height, MAX_HEIGHT);
 #else
-   Window root;
    Status stat;
-   int xpos, ypos;
-   unsigned int w, h, bw, depth;
 
    _glthread_LOCK_MUTEX(_xmesa_lock);
    XSync(b->xm_visual->display, 0); /* added for Chromium */
-   stat = XGetGeometry(dpy, b->frontxrb->pixmap, &root, &xpos, &ypos,
-                       &w, &h, &bw, &depth);
+   stat = get_drawable_size(dpy, b->frontxrb->pixmap, width, height);
    _glthread_UNLOCK_MUTEX(_xmesa_lock);
 
-   if (stat) {
-      *width = w;
-      *height = h;
-   }
-   else {
+   if (!stat) {
       /* probably querying a window that's recently been destroyed */
       _mesa_warning(NULL, "XGetGeometry failed!\n");
       *width = *height = 1;
@@ -431,6 +437,11 @@ create_xmesa_buffer(XMesaDrawable d, BufferType type,
                                 b->swAlpha,
                                 vis->mesa_visual.numAuxBuffers > 0 );
 
+   /* GLX_EXT_texture_from_pixmap */
+   b->TextureTarget = 0;
+   b->TextureFormat = GLX_TEXTURE_FORMAT_NONE_EXT;
+   b->TextureMipmap = 0;
+
    /* insert buffer into linked list */
    b->Next = XMesaBufferList;
    XMesaBufferList = b;
@@ -1673,6 +1684,67 @@ XMesaCreatePixmapBuffer(XMesaVisual v, XMesaPixmap p, XMesaColormap cmap)
 }
 
 
+/**
+ * For GLX_EXT_texture_from_pixmap
+ */
+XMesaBuffer
+XMesaCreatePixmapTextureBuffer(XMesaVisual v, XMesaPixmap p,
+                               XMesaColormap cmap,
+                               int format, int target, int mipmap)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   XMesaBuffer b;
+   GLuint width, height;
+
+   assert(v);
+
+   b = create_xmesa_buffer((XMesaDrawable) p, PIXMAP, v, cmap);
+   if (!b)
+      return NULL;
+
+   /* get pixmap size, update framebuffer/renderbuffer dims */
+   get_drawable_size(v->display, p, &width, &height);
+   _mesa_resize_framebuffer(NULL, &(b->mesa_buffer), width, height);
+
+   if (target == 0) {
+      /* examine dims */
+      if (ctx->Extensions.ARB_texture_non_power_of_two) {
+         target = GLX_TEXTURE_2D_EXT;
+      }
+      else if (   _mesa_bitcount(width)  == 1
+               && _mesa_bitcount(height) == 1) {
+         /* power of two size */
+         if (height == 1) {
+            target = GLX_TEXTURE_1D_EXT;
+         }
+         else {
+            target = GLX_TEXTURE_2D_EXT;
+         }
+      }
+      else if (ctx->Extensions.NV_texture_rectangle) {
+         target = GLX_TEXTURE_RECTANGLE_EXT;
+      }
+      else {
+         /* non power of two textures not supported */
+         XMesaDestroyBuffer(b);
+         return 0;
+      }
+   }
+
+   b->TextureTarget = target;
+   b->TextureFormat = format;
+   b->TextureMipmap = mipmap;
+
+   if (!initialize_visual_and_buffer(v, b, v->mesa_visual.rgbMode,
+				     (XMesaDrawable) p, cmap)) {
+      xmesa_free_buffer(b);
+      return NULL;
+   }
+
+   return b;
+}
+
+
 
 XMesaBuffer
 XMesaCreatePBuffer(XMesaVisual v, XMesaColormap cmap,
@@ -2254,3 +2326,154 @@ XMesaResizeBuffers( XMesaBuffer b )
    xmesa_check_and_update_buffer_size(xmctx, b);
 }
 
+
+static GLint
+xbuffer_to_renderbuffer(int buffer)
+{
+   assert(MAX_AUX_BUFFERS <= 4);
+
+   switch (buffer) {
+   case GLX_FRONT_LEFT_EXT:
+      return BUFFER_FRONT_LEFT;
+   case GLX_FRONT_RIGHT_EXT:
+      return BUFFER_FRONT_RIGHT;
+   case GLX_BACK_LEFT_EXT:
+      return BUFFER_BACK_LEFT;
+   case GLX_BACK_RIGHT_EXT:
+      return BUFFER_BACK_RIGHT;
+   case GLX_AUX0_EXT:
+      return BUFFER_AUX0;
+   case GLX_AUX1_EXT:
+      return BUFFER_AUX1;
+   case GLX_AUX2_EXT:
+      return BUFFER_AUX2;
+   case GLX_AUX3_EXT:
+      return BUFFER_AUX3;
+   case GLX_AUX4_EXT:
+   case GLX_AUX5_EXT:
+   case GLX_AUX6_EXT:
+   case GLX_AUX7_EXT:
+   case GLX_AUX8_EXT:
+   case GLX_AUX9_EXT:
+   default:
+      /* BadValue error */
+      return -1;
+   }
+}
+
+
+PUBLIC void
+XMesaBindTexImage(Display *dpy, XMesaBuffer drawable, int buffer,
+                  const int *attrib_list)
+{
+#if 0
+   GET_CURRENT_CONTEXT(ctx);
+   const GLuint unit = ctx->Texture.CurrentUnit;
+   struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
+   struct gl_texture_object *texObj;
+#endif
+   struct gl_renderbuffer *rb;
+   struct xmesa_renderbuffer *xrb;
+   GLint b;
+   XMesaImage *img;
+   GLboolean freeImg = GL_FALSE;
+
+   b = xbuffer_to_renderbuffer(buffer);
+   if (b < 0)
+      return;
+
+   if (drawable->TextureFormat == GLX_TEXTURE_FORMAT_NONE_EXT)
+      return; /* BadMatch error */
+
+   rb = drawable->mesa_buffer.Attachment[b].Renderbuffer;
+   if (!rb) {
+      /* invalid buffer */
+      return;
+   }
+   xrb = xmesa_renderbuffer(rb);
+
+#if 0
+   switch (drawable->TextureTarget) {
+   case GLX_TEXTURE_1D_EXT:
+      texObj = texUnit->Current1D;
+      break;
+   case GLX_TEXTURE_2D_EXT:
+      texObj = texUnit->Current2D;
+      break;
+   case GLX_TEXTURE_RECTANGLE_EXT:
+      texObj = texUnit->CurrentRect;
+      break;
+   default:
+      return; /* BadMatch error */
+   }
+#endif
+
+   /*
+    * The following is a quick and simple way to implement
+    * BindTexImage.  The better way is to write some new FetchTexel()
+    * functions which would extract texels from XImages.  We'd still
+    * need to use XGetImage when texturing from a Pixmap (front buffer)
+    * but texturing from a back buffer (XImage) would avoid an image
+    * copy.
+    */
+
+   /* get XImage */
+   if (xrb->pixmap) {
+      img = XGetImage(dpy, xrb->pixmap, 0, 0, rb->Width, rb->Height,
+                      AllPlanes, ZPixmap );
+      freeImg = GL_TRUE;
+   }
+   else if (xrb->ximage) {
+      img = xrb->ximage;
+   }
+
+   /* store the XImage as a new texture image */
+   if (img) {
+      GLenum format, type, intFormat;
+      if (img->bits_per_pixel == 32) {
+         format = GL_BGRA;
+         type = GL_UNSIGNED_BYTE;
+         intFormat = GL_RGBA;
+      }
+      else if (img->bits_per_pixel == 24) {
+         format = GL_BGR;
+         type = GL_UNSIGNED_BYTE;
+         intFormat = GL_RGB;
+      }
+      else if (img->bits_per_pixel == 16) {
+         format = GL_BGR;
+         type = GL_UNSIGNED_SHORT_5_6_5;
+         intFormat = GL_RGB;
+      }
+      else {
+         _mesa_problem(NULL, "Unexpected XImage format in XMesaBindTexImage");
+         return;
+      }
+      if (drawable->TextureFormat == GLX_TEXTURE_FORMAT_RGBA_EXT) {
+         intFormat = GL_RGBA;
+      }
+      else if (drawable->TextureFormat == GLX_TEXTURE_FORMAT_RGB_EXT) {
+         intFormat = GL_RGB;
+      }
+
+      _mesa_TexImage2D(GL_TEXTURE_2D, 0, intFormat, rb->Width, rb->Height, 0,
+                       format, type, img->data);
+
+      if (freeImg) {
+	 XMesaDestroyImage(img);
+      }
+   }
+}
+
+
+
+PUBLIC void
+XMesaReleaseTexImage(Display *dpy, XMesaBuffer drawable, int buffer)
+{
+   const GLint b = xbuffer_to_renderbuffer(buffer);
+   if (b < 0)
+      return;
+
+   /* no-op for now */
+}
+
diff --git a/src/mesa/drivers/x11/xmesaP.h b/src/mesa/drivers/x11/xmesaP.h
index 0198886747..e3d7cf381f 100644
--- a/src/mesa/drivers/x11/xmesaP.h
+++ b/src/mesa/drivers/x11/xmesaP.h
@@ -1,8 +1,8 @@
 /*
  * Mesa 3-D graphics library
- * Version:  6.5
+ * Version:  7.1
  *
- * Copyright (C) 1999-2006  Brian Paul   All Rights Reserved.
+ * Copyright (C) 1999-2007  Brian Paul   All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -267,6 +267,11 @@ struct xmesa_buffer {
    fxMesaContext FXctx;
 #endif
 
+   /* GLX_EXT_texture_from_pixmap */
+   GLint TextureTarget; /** GLX_TEXTURE_1D_EXT, for example */
+   GLint TextureFormat; /** GLX_TEXTURE_FORMAT_RGB_EXT, for example */
+   GLint TextureMipmap; /** 0 or 1 */
+
    struct xmesa_buffer *Next;	/* Linked list pointer: */
 };
 
-- 
cgit v1.2.3


From 62b6eef0d72f42fa73210a67f2afc37547e7b8b5 Mon Sep 17 00:00:00 2001
From: Oliver McFadden <z3ro.geek@gmail.com>
Date: Sat, 19 May 2007 05:41:55 +0000
Subject: r300: Just use "inline" rather than "__inline__".

---
 src/mesa/drivers/dri/r300/r300_cmdbuf.c   |  2 +-
 src/mesa/drivers/dri/r300/r300_cmdbuf.h   |  6 +++---
 src/mesa/drivers/dri/r300/r300_context.h  |  4 ++--
 src/mesa/drivers/dri/r300/r300_emit.h     | 12 ++++++------
 src/mesa/drivers/dri/r300/r300_vertprog.c |  2 +-
 5 files changed, 13 insertions(+), 13 deletions(-)

(limited to 'src/mesa/drivers')

diff --git a/src/mesa/drivers/dri/r300/r300_cmdbuf.c b/src/mesa/drivers/dri/r300/r300_cmdbuf.c
index d13649ddc0..0351989b2e 100644
--- a/src/mesa/drivers/dri/r300/r300_cmdbuf.c
+++ b/src/mesa/drivers/dri/r300/r300_cmdbuf.c
@@ -148,7 +148,7 @@ static void r300PrintStateAtom(r300ContextPtr r300, struct r300_state_atom *stat
  * The caller must have ensured that there is enough space in the command
  * buffer.
  */
-static __inline__ void r300EmitAtoms(r300ContextPtr r300, GLboolean dirty)
+static inline void r300EmitAtoms(r300ContextPtr r300, GLboolean dirty)
 {
 	struct r300_state_atom *atom;
 	uint32_t *dest;
diff --git a/src/mesa/drivers/dri/r300/r300_cmdbuf.h b/src/mesa/drivers/dri/r300/r300_cmdbuf.h
index bfb2eda26f..acb6e38c6d 100644
--- a/src/mesa/drivers/dri/r300/r300_cmdbuf.h
+++ b/src/mesa/drivers/dri/r300/r300_cmdbuf.h
@@ -52,7 +52,7 @@ extern void r300DestroyCmdBuf(r300ContextPtr r300);
  *
  * \param dwords The number of dwords we need to be free on the command buffer
  */
-static __inline__ void r300EnsureCmdBufSpace(r300ContextPtr r300,
+static inline void r300EnsureCmdBufSpace(r300ContextPtr r300,
 					     int dwords, const char *caller)
 {
 	assert(dwords < r300->cmdbuf.size);
@@ -68,7 +68,7 @@ static __inline__ void r300EnsureCmdBufSpace(r300ContextPtr r300,
  * causes state reemission after a flush. This is necessary to ensure
  * correct hardware state after an unlock.
  */
-static __inline__ uint32_t *r300RawAllocCmdBuf(r300ContextPtr r300,
+static inline uint32_t *r300RawAllocCmdBuf(r300ContextPtr r300,
 					       int dwords, const char *caller)
 {
 	uint32_t *ptr;
@@ -80,7 +80,7 @@ static __inline__ uint32_t *r300RawAllocCmdBuf(r300ContextPtr r300,
 	return ptr;
 }
 
-static __inline__ uint32_t *r300AllocCmdBuf(r300ContextPtr r300,
+static inline uint32_t *r300AllocCmdBuf(r300ContextPtr r300,
 					    int dwords, const char *caller)
 {
 	uint32_t *ptr;
diff --git a/src/mesa/drivers/dri/r300/r300_context.h b/src/mesa/drivers/dri/r300/r300_context.h
index dbcd5d04d6..261c87f2f0 100644
--- a/src/mesa/drivers/dri/r300/r300_context.h
+++ b/src/mesa/drivers/dri/r300/r300_context.h
@@ -80,7 +80,7 @@ typedef struct r300_context *r300ContextPtr;
 /**
  * This function takes a float and packs it into a uint32_t
  */
-static __inline__ uint32_t r300PackFloat32(float fl)
+static inline uint32_t r300PackFloat32(float fl)
 {
 	union {
 		float fl;
@@ -97,7 +97,7 @@ static __inline__ uint32_t r300PackFloat32(float fl)
  * But it works for most things.  I'll fix it later if someone
  * else with a better clue doesn't
  */
-static __inline__ uint32_t r300PackFloat24(float f)
+static inline uint32_t r300PackFloat24(float f)
 {
 	float mantissa;
 	int exponent;
diff --git a/src/mesa/drivers/dri/r300/r300_emit.h b/src/mesa/drivers/dri/r300/r300_emit.h
index 7be098f743..4f841a5413 100644
--- a/src/mesa/drivers/dri/r300/r300_emit.h
+++ b/src/mesa/drivers/dri/r300/r300_emit.h
@@ -59,7 +59,7 @@
 
 #define CP_PACKET0(reg, n)	(RADEON_CP_PACKET0 | ((n)<<16) | ((reg)>>2))
 
-static __inline__ uint32_t cmdpacket0(int reg, int count)
+static inline uint32_t cmdpacket0(int reg, int count)
 {
 	drm_r300_cmd_header_t cmd;
 
@@ -71,7 +71,7 @@ static __inline__ uint32_t cmdpacket0(int reg, int count)
 	return cmd.u;
 }
 
-static __inline__ uint32_t cmdvpu(int addr, int count)
+static inline uint32_t cmdvpu(int addr, int count)
 {
 	drm_r300_cmd_header_t cmd;
 
@@ -83,7 +83,7 @@ static __inline__ uint32_t cmdvpu(int addr, int count)
 	return cmd.u;
 }
 
-static __inline__ uint32_t cmdpacket3(int packet)
+static inline uint32_t cmdpacket3(int packet)
 {
 	drm_r300_cmd_header_t cmd;
 
@@ -93,7 +93,7 @@ static __inline__ uint32_t cmdpacket3(int packet)
 	return cmd.u;
 }
 
-static __inline__ uint32_t cmdcpdelay(unsigned short count)
+static inline uint32_t cmdcpdelay(unsigned short count)
 {
 	drm_r300_cmd_header_t cmd;
 
@@ -103,7 +103,7 @@ static __inline__ uint32_t cmdcpdelay(unsigned short count)
 	return cmd.u;
 }
 
-static __inline__ uint32_t cmdwait(unsigned char flags)
+static inline uint32_t cmdwait(unsigned char flags)
 {
 	drm_r300_cmd_header_t cmd;
 
@@ -113,7 +113,7 @@ static __inline__ uint32_t cmdwait(unsigned char flags)
 	return cmd.u;
 }
 
-static __inline__ uint32_t cmdpacify(void)
+static inline uint32_t cmdpacify(void)
 {
 	drm_r300_cmd_header_t cmd;
 
diff --git a/src/mesa/drivers/dri/r300/r300_vertprog.c b/src/mesa/drivers/dri/r300/r300_vertprog.c
index 1d90ade2ed..16dddf6557 100644
--- a/src/mesa/drivers/dri/r300/r300_vertprog.c
+++ b/src/mesa/drivers/dri/r300/r300_vertprog.c
@@ -222,7 +222,7 @@ static unsigned long t_src_class(enum register_file file)
 	}
 }
 
-static __inline unsigned long t_swizzle(GLubyte swizzle)
+static inline unsigned long t_swizzle(GLubyte swizzle)
 {
 /* this is in fact a NOP as the Mesa SWIZZLE_* are all identical to VSF_IN_COMPONENT_* */
 	return swizzle;
-- 
cgit v1.2.3


From 9df4f842d593b5ea0cdc3d9a515afbe638b9051e Mon Sep 17 00:00:00 2001
From: Oliver McFadden <z3ro.geek@gmail.com>
Date: Sun, 20 May 2007 17:20:10 +0000
Subject: r300: Added TODO comment regarding immediate mode implementation.

---
 src/mesa/drivers/dri/r300/r300_render.c | 3 +++
 1 file changed, 3 insertions(+)

(limited to 'src/mesa/drivers')

diff --git a/src/mesa/drivers/dri/r300/r300_render.c b/src/mesa/drivers/dri/r300/r300_render.c
index 6cec2bb1ea..143fe9fd35 100644
--- a/src/mesa/drivers/dri/r300/r300_render.c
+++ b/src/mesa/drivers/dri/r300/r300_render.c
@@ -45,6 +45,9 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
  * obviously this does work... Further investigation is needed.
  *
  * \author Nicolai Haehnle <prefect_@gmx.net>
+ *
+ * \todo Add immediate implementation back? Perhaps this is useful if there are
+ * no bugs...
  */
 
 #include "glheader.h"
-- 
cgit v1.2.3


From aa133a9dae53bc6aa50b88ee43deb8b34e8d0029 Mon Sep 17 00:00:00 2001
From: Brian <brian@yutani.localnet.net>
Date: Sun, 20 May 2007 12:17:21 -0600
Subject: add missing right-paren

---
 src/mesa/drivers/dri/Makefile | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'src/mesa/drivers')

diff --git a/src/mesa/drivers/dri/Makefile b/src/mesa/drivers/dri/Makefile
index 4abcc16c1b..f466ce6c3c 100644
--- a/src/mesa/drivers/dri/Makefile
+++ b/src/mesa/drivers/dri/Makefile
@@ -32,7 +32,7 @@ install:
 clean:
 	@for dir in $(DRI_DIRS) ; do \
 		if [ -d $$dir ] ; then \
-			(cd $$dir && $(MAKE) clean ; \
+			(cd $$dir && $(MAKE) clean) ; \
 		fi \
 	done
 	-rm -f common/*.o
-- 
cgit v1.2.3


From 9e8a961dd7d7b717a9fb4ecdea1c1b60ea355efe Mon Sep 17 00:00:00 2001
From: Brian <brian@yutani.localnet.net>
Date: Sun, 20 May 2007 12:27:39 -0600
Subject: Overhaul/simplify SWvertex and SWspan attribute handling.

Instead of separate fog/specular/texcoord/varying code, just treat all of
them as generic attributes.  Simplifies the point/line/triangle functions.
---
 src/mesa/drivers/dri/ffb/ffb_tris.c            |   8 +-
 src/mesa/drivers/dri/mach64/mach64_native_vb.c |  18 +-
 src/mesa/drivers/dri/s3v/s3v_tritmp.h          |  46 +-
 src/mesa/drivers/dri/tdfx/tdfx_tris.c          |  16 +-
 src/mesa/drivers/x11/xm_line.c                 |   8 +-
 src/mesa/swrast/s_aaline.c                     |  39 +-
 src/mesa/swrast/s_aalinetemp.h                 | 107 ++--
 src/mesa/swrast/s_aatriangle.c                 |  89 +--
 src/mesa/swrast/s_aatritemp.h                  | 249 +++------
 src/mesa/swrast/s_alpha.c                      |   4 +-
 src/mesa/swrast/s_bitmap.c                     |  19 +-
 src/mesa/swrast/s_context.c                    | 114 ++--
 src/mesa/swrast/s_context.h                    |   5 +
 src/mesa/swrast/s_copypix.c                    |  29 +-
 src/mesa/swrast/s_drawpix.c                    |  43 +-
 src/mesa/swrast/s_feedback.c                   |  23 +-
 src/mesa/swrast/s_fog.c                        | 335 +++++-------
 src/mesa/swrast/s_lines.c                      | 112 ++--
 src/mesa/swrast/s_linetemp.h                   | 128 ++---
 src/mesa/swrast/s_logic.c                      |   4 +-
 src/mesa/swrast/s_masking.c                    |   4 +-
 src/mesa/swrast/s_points.c                     |  39 +-
 src/mesa/swrast/s_pointtemp.h                  | 115 ++--
 src/mesa/swrast/s_span.c                       | 725 +++++++++----------------
 src/mesa/swrast/s_span.h                       |  98 +---
 src/mesa/swrast/s_texcombine.c                 |   1 -
 src/mesa/swrast/s_triangle.c                   | 111 ++--
 src/mesa/swrast/s_tritemp.h                    | 630 ++++++---------------
 src/mesa/swrast/s_zoom.c                       |  32 +-
 src/mesa/swrast/swrast.h                       |  23 +-
 src/mesa/swrast_setup/ss_context.c             |  42 +-
 src/mesa/swrast_setup/ss_triangle.c            |  52 +-
 src/mesa/swrast_setup/ss_tritmp.h              |  88 +--
 src/mesa/tnl_dd/t_dd_vb.c                      |  48 +-
 34 files changed, 1273 insertions(+), 2131 deletions(-)

(limited to 'src/mesa/drivers')

diff --git a/src/mesa/drivers/dri/ffb/ffb_tris.c b/src/mesa/drivers/dri/ffb/ffb_tris.c
index ca0e514dc0..9fae8c8283 100644
--- a/src/mesa/drivers/dri/ffb/ffb_tris.c
+++ b/src/mesa/drivers/dri/ffb/ffb_tris.c
@@ -138,10 +138,10 @@ static void ffb_translate_vertex(GLcontext *ctx, const ffb_vertex *src,
 	const GLfloat ty = m[13];
 	const GLfloat tz = m[14];
 
-	dst->win[0] = sx * src->x + tx;
-	dst->win[1] = sy * src->y + ty;
-	dst->win[2] = sz * src->z + tz;
-	dst->win[3] = 1.0;
+	dst->attrib[FRAG_ATTRIB_WPOS][0] = sx * src->x + tx;
+	dst->attrib[FRAG_ATTRIB_WPOS][1] = sy * src->y + ty;
+	dst->attrib[FRAG_ATTRIB_WPOS][2] = sz * src->z + tz;
+	dst->attrib[FRAG_ATTRIB_WPOS][3] = 1.0;
       
 	dst->color[0] = FFB_UBYTE_FROM_COLOR(src->color[0].red);
 	dst->color[1] = FFB_UBYTE_FROM_COLOR(src->color[0].green);
diff --git a/src/mesa/drivers/dri/mach64/mach64_native_vb.c b/src/mesa/drivers/dri/mach64/mach64_native_vb.c
index 81bcf802c7..75cf0e2ed2 100644
--- a/src/mesa/drivers/dri/mach64/mach64_native_vb.c
+++ b/src/mesa/drivers/dri/mach64/mach64_native_vb.c
@@ -44,7 +44,7 @@ void TAG(translate_vertex)(GLcontext *ctx,
    UNVIEWPORT_VARS;
    CARD32 *p = (CARD32 *)src + 10 - mmesa->vertex_size;
 
-   dst->win[3] = 1.0;
+   dst->attrib[FRAG_ATTRIB_WPOS][3] = 1.0;
    
    switch ( format ) {
       case TEX1_VERTEX_FORMAT:
@@ -75,17 +75,17 @@ void TAG(translate_vertex)(GLcontext *ctx,
 	 dst->attrib[FRAG_ATTRIB_TEX0][1] = LE32_IN_FLOAT( p++ );
 #endif
 	 dst->attrib[FRAG_ATTRIB_TEX0][3] = 1.0;
-	 dst->win[3] = LE32_IN_FLOAT( p++ );
+	 dst->attrib[FRAG_ATTRIB_WPOS][3] = LE32_IN_FLOAT( p++ );
 	
       case NOTEX_VERTEX_FORMAT:
-	 dst->specular[2] = ((GLubyte *)p)[0];
-	 dst->specular[1] = ((GLubyte *)p)[1];
-	 dst->specular[0] = ((GLubyte *)p)[2];
-	 dst->attrib[FRAG_ATTRIB_FOGC][0] = ((GLubyte *)p)[3];
+	 dst->attrib[FRAG_ATTRIB_COL1][2] = UBYTE_TO_FLOAT(((GLubyte *)p)[0]);
+	 dst->attrib[FRAG_ATTRIB_COL1][1] = UBYTE_TO_FLOAT(((GLubyte *)p)[1]);
+	 dst->attrib[FRAG_ATTRIB_COL1][0] = UBYTE_TO_FLOAT(((GLubyte *)p)[2]);
+	 dst->attrib[FRAG_ATTRIB_FOGC][0] = ((GLubyte *)p)[3]; /*XXX int->float?*/
 	 p++;
 
       case TINY_VERTEX_FORMAT:
-	 dst->win[2] = UNVIEWPORT_Z( LE32_IN( p++ ) );
+	 dst->attrib[FRAG_ATTRIB_WPOS][2] = UNVIEWPORT_Z( LE32_IN( p++ ) );
 
 	 dst->color[2] = ((GLubyte *)p)[0];
 	 dst->color[1] = ((GLubyte *)p)[1];
@@ -96,8 +96,8 @@ void TAG(translate_vertex)(GLcontext *ctx,
 	 {
 	    GLuint xy = LE32_IN( p );
 	    
-	    dst->win[0] = UNVIEWPORT_X( (GLfloat)(GLshort)( xy >> 16 ) );
-	    dst->win[1] = UNVIEWPORT_Y( (GLfloat)(GLshort)( xy & 0xffff ) );
+	    dst->attrib[FRAG_ATTRIB_WPOS][0] = UNVIEWPORT_X( (GLfloat)(GLshort)( xy >> 16 ) );
+	    dst->attrib[FRAG_ATTRIB_WPOS][1] = UNVIEWPORT_Y( (GLfloat)(GLshort)( xy & 0xffff ) );
 	 }
    }
 
diff --git a/src/mesa/drivers/dri/s3v/s3v_tritmp.h b/src/mesa/drivers/dri/s3v/s3v_tritmp.h
index 696fc02250..2321bd414f 100644
--- a/src/mesa/drivers/dri/s3v/s3v_tritmp.h
+++ b/src/mesa/drivers/dri/s3v/s3v_tritmp.h
@@ -43,12 +43,12 @@
 
 #define SORT_LINE_VERT() \
 do { \
-	if(v[0].win[1] <= v[1].win[1]) { \
+	if(v[0].attrib[FRAG_ATTRIB_WPOS][1] <= v[1].attrib[FRAG_ATTRIB_WPOS][1]) { \
 \
                 idx[0] = 0; \
                 idx[1] = 1; \
 \
-        } else if (v[0].win[1] > v[1].win[1]) { \
+        } else if (v[0].attrib[FRAG_ATTRIB_WPOS][1] > v[1].attrib[FRAG_ATTRIB_WPOS][1]) { \
 \
                 idx[0] = 1; \
                 idx[1] = 0; \
@@ -58,19 +58,19 @@ do { \
 
 #define SET_LINE_VERT() \
 do { \
-        x[0] = (v[idx[0]].win[0] * 1024.0f * 1024.0f); /* 0x100000 */ \
-        y[0] = fy[0] = dPriv->h - v[idx[0]].win[1]; \
-        z[0] = (v[idx[0]].win[2]) * 1024.0f * 32.0f; /* 0x8000; */ \
+        x[0] = (v[idx[0]].attrib[FRAG_ATTRIB_WPOS][0] * 1024.0f * 1024.0f); /* 0x100000 */ \
+        y[0] = fy[0] = dPriv->h - v[idx[0]].attrib[FRAG_ATTRIB_WPOS][1]; \
+        z[0] = (v[idx[0]].attrib[FRAG_ATTRIB_WPOS][2]) * 1024.0f * 32.0f; /* 0x8000; */ \
 \
-        x[1] = (v[idx[1]].win[0] * 1024.0f * 1024.0f); /* 0x100000 */ \
-        y[1] = dPriv->h - v[idx[1]].win[1]; \
-        z[1] = (v[idx[1]].win[2]) * 1024.0f * 32.0f; /* 0x8000 */ \
+        x[1] = (v[idx[1]].attrib[FRAG_ATTRIB_WPOS][0] * 1024.0f * 1024.0f); /* 0x100000 */ \
+        y[1] = dPriv->h - v[idx[1]].attrib[FRAG_ATTRIB_WPOS][1]; \
+        z[1] = (v[idx[1]].attrib[FRAG_ATTRIB_WPOS][2]) * 1024.0f * 32.0f; /* 0x8000 */ \
 } while(0)
 
 #define SET_LINE_XY() \
 do { \
-	tmp = v[idx[0]].win[0]; \
-        tmp2 = v[idx[1]].win[0]; \
+	tmp = v[idx[0]].attrib[FRAG_ATTRIB_WPOS][0]; \
+        tmp2 = v[idx[1]].attrib[FRAG_ATTRIB_WPOS][0]; \
 \
 	dx01 = x[0] - x[1]; \
         dy01 = y[0] - y[1]; \
@@ -265,7 +265,7 @@ do { \
 #define SORT_VERT() \
 do { \
 	for (i=0; i<3; i++) \
-		fy[i] = v[i].win[1]; \
+		fy[i] = v[i].attrib[FRAG_ATTRIB_WPOS][1]; \
 \
 		if (fy[1] > fy[0]) {  /* (fy[1] > fy[0]) */ \
 \
@@ -305,9 +305,9 @@ do { \
 do { \
 	for (i=0; i<3; i++) \
 	{ \
-		x[i] = ((v[idx[i]].win[0]) * /* 0x100000*/  1024.0 * 1024.0); \
-		y[i] = fy[i] = (dPriv->h - v[idx[i]].win[1]); \
-		z[i] = ((v[idx[i]].win[2]) * /* 0x8000 */ 1024.0 * 32.0); \
+		x[i] = ((v[idx[i]].attrib[FRAG_ATTRIB_WPOS][0]) * /* 0x100000*/  1024.0 * 1024.0); \
+		y[i] = fy[i] = (dPriv->h - v[idx[i]].attrib[FRAG_ATTRIB_WPOS][1]); \
+		z[i] = ((v[idx[i]].attrib[FRAG_ATTRIB_WPOS][2]) * /* 0x8000 */ 1024.0 * 32.0); \
 	} \
 \
 	ydiff = fy[0] - (float)y[0]; \
@@ -420,9 +420,9 @@ do { \
         v2 = (v[idx[2]].attrib[FRAG_ATTRIB_TEX0][1] \
                 * (GLfloat)(t->globj->Image[0][0]->Height) * 256.0); \
 \
-        w0 = (v[idx[0]].win[3]); \
-        w1 = (v[idx[1]].win[3]); \
-        w2 = (v[idx[2]].win[3]); \
+        w0 = (v[idx[0]].attrib[FRAG_ATTRIB_WPOS][3]); \
+        w1 = (v[idx[1]].attrib[FRAG_ATTRIB_WPOS][3]); \
+        w2 = (v[idx[2]].attrib[FRAG_ATTRIB_WPOS][3]); \
 } while (0)
 
 #define SET_BASEUV() \
@@ -732,8 +732,8 @@ DEBUG(("***\n"));
 
 #if (IND & S3V_RAST_CULL_BIT)
 	cull = vmesa->backface_sign *
-		((v[1].win[0] - v[0].win[0]) * (v[0].win[1] - v[2].win[1]) +
-		 (v[1].win[1] - v[0].win[1]) * (v[2].win[0] - v[0].win[0]));
+		((v[1].attrib[FRAG_ATTRIB_WPOS][0] - v[0].attrib[FRAG_ATTRIB_WPOS][0]) * (v[0].attrib[FRAG_ATTRIB_WPOS][1] - v[2].attrib[FRAG_ATTRIB_WPOS][1]) +
+		 (v[1].attrib[FRAG_ATTRIB_WPOS][1] - v[0].attrib[FRAG_ATTRIB_WPOS][1]) * (v[2].attrib[FRAG_ATTRIB_WPOS][0] - v[0].attrib[FRAG_ATTRIB_WPOS][0]));
 
 	if (cull < vmesa->cull_zero /* -0.02f */) return;
 #endif
@@ -842,8 +842,8 @@ static void TAG(s3v_quad)( s3vContextPtr vmesa,
 
 #if (IND & S3V_RAST_CULL_BIT)
 	cull = vmesa->backface_sign *
-		((v[1].win[0] - v[0].win[0]) * (v[0].win[1] - v[2].win[1]) +
-		 (v[1].win[1] - v[0].win[1]) * (v[2].win[0] - v[0].win[0]));
+		((v[1].attrib[FRAG_ATTRIB_WPOS][0] - v[0].attrib[FRAG_ATTRIB_WPOS][0]) * (v[0].attrib[FRAG_ATTRIB_WPOS][1] - v[2].attrib[FRAG_ATTRIB_WPOS][1]) +
+		 (v[1].attrib[FRAG_ATTRIB_WPOS][1] - v[0].attrib[FRAG_ATTRIB_WPOS][1]) * (v[2].attrib[FRAG_ATTRIB_WPOS][0] - v[0].attrib[FRAG_ATTRIB_WPOS][0]));
 
 	if (cull < vmesa->cull_zero /* -0.02f */) goto second; /* return; */ /* (a) */
 #endif
@@ -897,8 +897,8 @@ second:
 
 #if (IND & S3V_RAST_CULL_BIT)
 	cull = vmesa->backface_sign *
-		((v[1].win[0] - v[0].win[0]) * (v[0].win[1] - v[2].win[1]) +
-		 (v[1].win[1] - v[0].win[1]) * (v[2].win[0] - v[0].win[0]));
+		((v[1].attrib[FRAG_ATTRIB_WPOS][0] - v[0].attrib[FRAG_ATTRIB_WPOS][0]) * (v[0].attrib[FRAG_ATTRIB_WPOS][1] - v[2].attrib[FRAG_ATTRIB_WPOS][1]) +
+		 (v[1].attrib[FRAG_ATTRIB_WPOS][1] - v[0].attrib[FRAG_ATTRIB_WPOS][1]) * (v[2].attrib[FRAG_ATTRIB_WPOS][0] - v[0].attrib[FRAG_ATTRIB_WPOS][0]));
 		 
 	if (cull < /* -0.02f */ vmesa->cull_zero) return;
 #endif
diff --git a/src/mesa/drivers/dri/tdfx/tdfx_tris.c b/src/mesa/drivers/dri/tdfx/tdfx_tris.c
index 4ba2f40b9e..96f9ae27fc 100644
--- a/src/mesa/drivers/dri/tdfx/tdfx_tris.c
+++ b/src/mesa/drivers/dri/tdfx/tdfx_tris.c
@@ -142,10 +142,10 @@ tdfx_translate_vertex( GLcontext *ctx, const tdfxVertex *src, SWvertex *dst)
    tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
 
    if (fxMesa->vertexFormat == TDFX_LAYOUT_TINY) {
-      dst->win[0] = src->x - fxMesa->x_offset;
-      dst->win[1] = src->y - (fxMesa->screen_height - fxMesa->height - fxMesa->y_offset);
-      dst->win[2] = src->z;
-      dst->win[3] = 1.0;
+      dst->attrib[FRAG_ATTRIB_WPOS][0] = src->x - fxMesa->x_offset;
+      dst->attrib[FRAG_ATTRIB_WPOS][1] = src->y - (fxMesa->screen_height - fxMesa->height - fxMesa->y_offset);
+      dst->attrib[FRAG_ATTRIB_WPOS][2] = src->z;
+      dst->attrib[FRAG_ATTRIB_WPOS][3] = 1.0;
 
       dst->color[0] = src->color[2];
       dst->color[1] = src->color[1];
@@ -155,10 +155,10 @@ tdfx_translate_vertex( GLcontext *ctx, const tdfxVertex *src, SWvertex *dst)
    else {
       GLfloat w = 1.0 / src->rhw;
 
-      dst->win[0] = src->x - fxMesa->x_offset;
-      dst->win[1] = src->y - (fxMesa->screen_height - fxMesa->height - fxMesa->y_offset);
-      dst->win[2] = src->z;
-      dst->win[3] = src->rhw;
+      dst->attrib[FRAG_ATTRIB_WPOS][0] = src->x - fxMesa->x_offset;
+      dst->attrib[FRAG_ATTRIB_WPOS][1] = src->y - (fxMesa->screen_height - fxMesa->height - fxMesa->y_offset);
+      dst->attrib[FRAG_ATTRIB_WPOS][2] = src->z;
+      dst->attrib[FRAG_ATTRIB_WPOS][3] = src->rhw;
 
       dst->color[0] = src->color[2];
       dst->color[1] = src->color[1];
diff --git a/src/mesa/drivers/x11/xm_line.c b/src/mesa/drivers/x11/xm_line.c
index 8537256d2e..deeae5019c 100644
--- a/src/mesa/drivers/x11/xm_line.c
+++ b/src/mesa/drivers/x11/xm_line.c
@@ -556,10 +556,10 @@ xor_line(GLcontext *ctx, const SWvertex *vert0, const SWvertex *vert1)
                                               vert1->color[0], vert1->color[1],
                                               vert1->color[2], vert1->color[3],
                                               xmesa->pixelformat);
-   int x0 = (int) vert0->win[0];
-   int y0 = YFLIP(xrb, (GLint) vert0->win[1]);
-   int x1 = (int) vert1->win[0];
-   int y1 = YFLIP(xrb, (GLint) vert1->win[1]);
+   int x0 =            (GLint) vert0->attrib[FRAG_ATTRIB_WPOS][0];
+   int y0 = YFLIP(xrb, (GLint) vert0->attrib[FRAG_ATTRIB_WPOS][1]);
+   int x1 =            (GLint) vert1->attrib[FRAG_ATTRIB_WPOS][0];
+   int y1 = YFLIP(xrb, (GLint) vert1->attrib[FRAG_ATTRIB_WPOS][1]);
    XMesaSetForeground(dpy, gc, pixel);
    XMesaSetFunction(dpy, gc, GXxor);
    XSetLineAttributes(dpy, gc, (int) ctx->Line.Width,
diff --git a/src/mesa/swrast/s_aaline.c b/src/mesa/swrast/s_aaline.c
index 3bb53dc2d7..d6a9afb421 100644
--- a/src/mesa/swrast/s_aaline.c
+++ b/src/mesa/swrast/s_aaline.c
@@ -59,19 +59,13 @@ struct LineInfo
 
    /* DO_Z */
    GLfloat zPlane[4];
-   /* DO_FOG */
-   GLfloat fPlane[4];
    /* DO_RGBA */
    GLfloat rPlane[4], gPlane[4], bPlane[4], aPlane[4];
    /* DO_INDEX */
    GLfloat iPlane[4];
-   /* DO_SPEC */
-   GLfloat srPlane[4], sgPlane[4], sbPlane[4];
    /* DO_ATTRIBS */
-   GLfloat sPlane[FRAG_ATTRIB_MAX][4];
-   GLfloat tPlane[FRAG_ATTRIB_MAX][4];
-   GLfloat uPlane[FRAG_ATTRIB_MAX][4];
-   GLfloat vPlane[FRAG_ATTRIB_MAX][4];
+   GLfloat wPlane[4];
+   GLfloat attrPlane[FRAG_ATTRIB_MAX][4][4];
    GLfloat lambda[FRAG_ATTRIB_MAX];
    GLfloat texWidth[FRAG_ATTRIB_MAX];
    GLfloat texHeight[FRAG_ATTRIB_MAX];
@@ -483,35 +477,24 @@ segment(GLcontext *ctx,
 
 #define NAME(x) aa_ci_##x
 #define DO_Z
-#define DO_FOG
+#define DO_ATTRIBS /* for fog */
 #define DO_INDEX
 #include "s_aalinetemp.h"
 
 
 #define NAME(x) aa_rgba_##x
 #define DO_Z
-#define DO_FOG
 #define DO_RGBA
 #include "s_aalinetemp.h"
 
 
-#define NAME(x)  aa_tex_rgba_##x
+#define NAME(x)  aa_general_rgba_##x
 #define DO_Z
-#define DO_FOG
 #define DO_RGBA
 #define DO_ATTRIBS
 #include "s_aalinetemp.h"
 
 
-#define NAME(x)  aa_multitex_spec_##x
-#define DO_Z
-#define DO_FOG
-#define DO_RGBA
-#define DO_ATTRIBS
-#define DO_SPEC
-#include "s_aalinetemp.h"
-
-
 
 void
 _swrast_choose_aa_line_function(GLcontext *ctx)
@@ -523,14 +506,12 @@ _swrast_choose_aa_line_function(GLcontext *ctx)
    if (ctx->Visual.rgbMode) {
       /* RGBA */
       if (ctx->Texture._EnabledCoordUnits != 0
-          || ctx->FragmentProgram._Current) {
-
-         if (ctx->Light.Model.ColorControl==GL_SEPARATE_SPECULAR_COLOR || 
-             ctx->Fog.ColorSumEnabled)
-            swrast->Line = aa_multitex_spec_line;
-         else
-            swrast->Line = aa_tex_rgba_line;
-
+          || ctx->FragmentProgram._Current
+          || (ctx->Light.Enabled &&
+              ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR)
+          || ctx->Fog.ColorSumEnabled
+          || swrast->_FogEnabled) {
+         swrast->Line = aa_general_rgba_line;
       }
       else {
          swrast->Line = aa_rgba_line;
diff --git a/src/mesa/swrast/s_aalinetemp.h b/src/mesa/swrast/s_aalinetemp.h
index 80cec0b31d..8756f122d0 100644
--- a/src/mesa/swrast/s_aalinetemp.h
+++ b/src/mesa/swrast/s_aalinetemp.h
@@ -63,9 +63,6 @@ NAME(plot)(GLcontext *ctx, struct LineInfo *line, int ix, int iy)
 #ifdef DO_Z
    line->span.array->z[i] = (GLuint) solve_plane(fx, fy, line->zPlane);
 #endif
-#ifdef DO_FOG
-   line->span.array->attribs[FRAG_ATTRIB_FOGC][i][0] = solve_plane(fx, fy, line->fPlane);
-#endif
 #ifdef DO_RGBA
    line->span.array->rgba[i][RCOMP] = solve_plane_chan(fx, fy, line->rPlane);
    line->span.array->rgba[i][GCOMP] = solve_plane_chan(fx, fy, line->gPlane);
@@ -75,31 +72,31 @@ NAME(plot)(GLcontext *ctx, struct LineInfo *line, int ix, int iy)
 #ifdef DO_INDEX
    line->span.array->index[i] = (GLint) solve_plane(fx, fy, line->iPlane);
 #endif
-#ifdef DO_SPEC
-   line->span.array->spec[i][RCOMP] = solve_plane_chan(fx, fy, line->srPlane);
-   line->span.array->spec[i][GCOMP] = solve_plane_chan(fx, fy, line->sgPlane);
-   line->span.array->spec[i][BCOMP] = solve_plane_chan(fx, fy, line->sbPlane);
-#endif
 #if defined(DO_ATTRIBS)
    ATTRIB_LOOP_BEGIN
       GLfloat (*attribArray)[4] = line->span.array->attribs[attr];
-      GLfloat invQ;
-      if (ctx->FragmentProgram._Active) {
-         invQ = 1.0F;
-      }
-      else {
-         invQ = solve_plane_recip(fx, fy, line->vPlane[attr]);
-      }
-      attribArray[i][0] = solve_plane(fx, fy, line->sPlane[attr]) * invQ;
-      attribArray[i][1] = solve_plane(fx, fy, line->tPlane[attr]) * invQ;
-      attribArray[i][2] = solve_plane(fx, fy, line->uPlane[attr]) * invQ;
-      if (attr < FRAG_ATTRIB_VAR0 && attr >= FRAG_ATTRIB_TEX0) {
+      if (attr >= FRAG_ATTRIB_TEX0 && attr < FRAG_ATTRIB_VAR0
+          && !ctx->FragmentProgram._Active) {
+         /* texcoord w/ divide by Q */
          const GLuint unit = attr - FRAG_ATTRIB_TEX0;
+         const GLfloat invQ = solve_plane_recip(fx, fy, line->attrPlane[attr][3]);
+         GLuint c;
+         for (c = 0; c < 3; c++) {
+            attribArray[i][c] = solve_plane(fx, fy, line->attrPlane[attr][c]) * invQ;
+         }
          line->span.array->lambda[unit][i]
-            = compute_lambda(line->sPlane[attr],
-                             line->tPlane[attr], invQ,
+            = compute_lambda(line->attrPlane[attr][0],
+                             line->attrPlane[attr][1], invQ,
                              line->texWidth[attr], line->texHeight[attr]);
       }
+      else {
+         /* non-texture attrib */
+         const GLfloat invW = solve_plane_recip(fx, fy, line->wPlane);
+         GLuint c;
+         for (c = 0; c < 4; c++) {
+            attribArray[i][c] = solve_plane(fx, fy, line->attrPlane[attr][c]) * invW;
+         }
+      }
    ATTRIB_LOOP_END
 #endif
 
@@ -128,10 +125,10 @@ NAME(line)(GLcontext *ctx, const SWvertex *v0, const SWvertex *v1)
 
    /* Init the LineInfo struct */
    struct LineInfo line;
-   line.x0 = v0->win[0];
-   line.y0 = v0->win[1];
-   line.x1 = v1->win[0];
-   line.y1 = v1->win[1];
+   line.x0 = v0->attrib[FRAG_ATTRIB_WPOS][0];
+   line.y0 = v0->attrib[FRAG_ATTRIB_WPOS][1];
+   line.x1 = v1->attrib[FRAG_ATTRIB_WPOS][0];
+   line.y1 = v1->attrib[FRAG_ATTRIB_WPOS][1];
    line.dx = line.x1 - line.x0;
    line.dy = line.y1 - line.y0;
    line.len = SQRTF(line.dx * line.dx + line.dy * line.dy);
@@ -148,14 +145,7 @@ NAME(line)(GLcontext *ctx, const SWvertex *v0, const SWvertex *v1)
 #ifdef DO_Z
    line.span.arrayMask |= SPAN_Z;
    compute_plane(line.x0, line.y0, line.x1, line.y1,
-                 v0->win[2], v1->win[2], line.zPlane);
-#endif
-#ifdef DO_FOG
-   line.span.arrayMask |= SPAN_FOG;
-   compute_plane(line.x0, line.y0, line.x1, line.y1,
-                 v0->attrib[FRAG_ATTRIB_FOGC][0],
-                 v1->attrib[FRAG_ATTRIB_FOGC][0],
-                 line.fPlane);
+                 v0->attrib[FRAG_ATTRIB_WPOS][2], v1->attrib[FRAG_ATTRIB_WPOS][2], line.zPlane);
 #endif
 #ifdef DO_RGBA
    line.span.arrayMask |= SPAN_RGBA;
@@ -176,51 +166,32 @@ NAME(line)(GLcontext *ctx, const SWvertex *v0, const SWvertex *v1)
       constant_plane(v1->color[ACOMP], line.aPlane);
    }
 #endif
-#ifdef DO_SPEC
-   line.span.arrayMask |= SPAN_SPEC;
-   if (ctx->Light.ShadeModel == GL_SMOOTH) {
-      compute_plane(line.x0, line.y0, line.x1, line.y1,
-                    v0->specular[RCOMP], v1->specular[RCOMP], line.srPlane);
-      compute_plane(line.x0, line.y0, line.x1, line.y1,
-                    v0->specular[GCOMP], v1->specular[GCOMP], line.sgPlane);
-      compute_plane(line.x0, line.y0, line.x1, line.y1,
-                    v0->specular[BCOMP], v1->specular[BCOMP], line.sbPlane);
-   }
-   else {
-      constant_plane(v1->specular[RCOMP], line.srPlane);
-      constant_plane(v1->specular[GCOMP], line.sgPlane);
-      constant_plane(v1->specular[BCOMP], line.sbPlane);
-   }
-#endif
 #ifdef DO_INDEX
    line.span.arrayMask |= SPAN_INDEX;
    if (ctx->Light.ShadeModel == GL_SMOOTH) {
       compute_plane(line.x0, line.y0, line.x1, line.y1,
-                    v0->index, v1->index, line.iPlane);
+                    v0->attrib[FRAG_ATTRIB_CI][0],
+                    v1->attrib[FRAG_ATTRIB_CI][0], line.iPlane);
    }
    else {
-      constant_plane(v1->index, line.iPlane);
+      constant_plane(v1->attrib[FRAG_ATTRIB_CI][0], line.iPlane);
    }
 #endif
 #if defined(DO_ATTRIBS)
    {
-      const GLfloat invW0 = v0->win[3];
-      const GLfloat invW1 = v1->win[3];
-      line.span.arrayMask |= (SPAN_TEXTURE | SPAN_LAMBDA | SPAN_VARYING);
+      const GLfloat invW0 = v0->attrib[FRAG_ATTRIB_WPOS][3];
+      const GLfloat invW1 = v1->attrib[FRAG_ATTRIB_WPOS][3];
+      line.span.arrayMask |= SPAN_LAMBDA;
+      compute_plane(line.x0, line.y0, line.x1, line.y1, invW0, invW1, line.wPlane);
       ATTRIB_LOOP_BEGIN
-         const GLfloat s0 = v0->attrib[attr][0] * invW0;
-         const GLfloat s1 = v1->attrib[attr][0] * invW1;
-         const GLfloat t0 = v0->attrib[attr][1] * invW0;
-         const GLfloat t1 = v1->attrib[attr][1] * invW1;
-         const GLfloat r0 = v0->attrib[attr][2] * invW0;
-         const GLfloat r1 = v1->attrib[attr][2] * invW1;
-         const GLfloat q0 = v0->attrib[attr][3] * invW0;
-         const GLfloat q1 = v1->attrib[attr][3] * invW1;
-         compute_plane(line.x0, line.y0, line.x1, line.y1, s0, s1, line.sPlane[attr]);
-         compute_plane(line.x0, line.y0, line.x1, line.y1, t0, t1, line.tPlane[attr]);
-         compute_plane(line.x0, line.y0, line.x1, line.y1, r0, r1, line.uPlane[attr]);
-         compute_plane(line.x0, line.y0, line.x1, line.y1, q0, q1, line.vPlane[attr]);
-         if (attr < FRAG_ATTRIB_VAR0 && attr >= FRAG_ATTRIB_TEX0) {
+         GLuint c;
+         for (c = 0; c < 4; c++) {
+            const GLfloat a0 = v0->attrib[attr][c] * invW0;
+            const GLfloat a1 = v1->attrib[attr][c] * invW1;
+            compute_plane(line.x0, line.y0, line.x1, line.y1, a0, a1, line.attrPlane[attr][c]);
+         }
+         line.span.arrayAttribs |= (1 << attr);
+         if (attr >= FRAG_ATTRIB_TEX0 && attr < FRAG_ATTRIB_VAR0) {
             const GLuint u = attr - FRAG_ATTRIB_TEX0;
             const struct gl_texture_object *obj = ctx->Texture.Unit[u]._Current;
             const struct gl_texture_image *texImage = obj->Image[0][obj->BaseLevel];
@@ -286,9 +257,7 @@ NAME(line)(GLcontext *ctx, const SWvertex *v0, const SWvertex *v1)
 
 
 #undef DO_Z
-#undef DO_FOG
 #undef DO_RGBA
 #undef DO_INDEX
-#undef DO_SPEC
 #undef DO_ATTRIBS
 #undef NAME
diff --git a/src/mesa/swrast/s_aatriangle.c b/src/mesa/swrast/s_aatriangle.c
index 0d95f06a9d..66891f9fec 100644
--- a/src/mesa/swrast/s_aatriangle.c
+++ b/src/mesa/swrast/s_aatriangle.c
@@ -144,6 +144,19 @@ solve_plane_chan(GLfloat x, GLfloat y, const GLfloat plane[4])
 }
 
 
+static INLINE GLfloat
+plane_dx(const GLfloat plane[4])
+{
+   return -plane[0] / plane[2];
+}
+
+static INLINE GLfloat
+plane_dy(const GLfloat plane[4])
+{
+   return -plane[1] / plane[2];
+}
+
+
 
 /*
  * Compute how much (area) of the given pixel is inside the triangle.
@@ -337,7 +350,6 @@ compute_coveragei(const GLfloat v0[3], const GLfloat v1[3],
 }
 
 
-
 static void
 rgba_aa_tri(GLcontext *ctx,
 	    const SWvertex *v0,
@@ -345,7 +357,6 @@ rgba_aa_tri(GLcontext *ctx,
 	    const SWvertex *v2)
 {
 #define DO_Z
-#define DO_FOG
 #define DO_RGBA
 #include "s_aatritemp.h"
 }
@@ -358,72 +369,21 @@ index_aa_tri(GLcontext *ctx,
 	     const SWvertex *v2)
 {
 #define DO_Z
-#define DO_FOG
-#define DO_INDEX
-#include "s_aatritemp.h"
-}
-
-
-/*
- * Compute mipmap level of detail.
- * XXX we should really include the R coordinate in this computation
- * in order to do 3-D texture mipmapping.
- */
-static INLINE GLfloat
-compute_lambda(const GLfloat sPlane[4], const GLfloat tPlane[4],
-               const GLfloat qPlane[4], GLfloat cx, GLfloat cy,
-               GLfloat invQ, GLfloat texWidth, GLfloat texHeight)
-{
-   const GLfloat s = solve_plane(cx, cy, sPlane);
-   const GLfloat t = solve_plane(cx, cy, tPlane);
-   const GLfloat invQ_x1 = solve_plane_recip(cx+1.0F, cy, qPlane);
-   const GLfloat invQ_y1 = solve_plane_recip(cx, cy+1.0F, qPlane);
-   const GLfloat s_x1 = s - sPlane[0] / sPlane[2];
-   const GLfloat s_y1 = s - sPlane[1] / sPlane[2];
-   const GLfloat t_x1 = t - tPlane[0] / tPlane[2];
-   const GLfloat t_y1 = t - tPlane[1] / tPlane[2];
-   GLfloat dsdx = s_x1 * invQ_x1 - s * invQ;
-   GLfloat dsdy = s_y1 * invQ_y1 - s * invQ;
-   GLfloat dtdx = t_x1 * invQ_x1 - t * invQ;
-   GLfloat dtdy = t_y1 * invQ_y1 - t * invQ;
-   GLfloat maxU, maxV, rho, lambda;
-   dsdx = FABSF(dsdx);
-   dsdy = FABSF(dsdy);
-   dtdx = FABSF(dtdx);
-   dtdy = FABSF(dtdy);
-   maxU = MAX2(dsdx, dsdy) * texWidth;
-   maxV = MAX2(dtdx, dtdy) * texHeight;
-   rho = MAX2(maxU, maxV);
-   lambda = LOG2(rho);
-   return lambda;
-}
-
-
-static void
-tex_aa_tri(GLcontext *ctx,
-	   const SWvertex *v0,
-	   const SWvertex *v1,
-	   const SWvertex *v2)
-{
-#define DO_Z
-#define DO_FOG
-#define DO_RGBA
 #define DO_ATTRIBS
+#define DO_INDEX
 #include "s_aatritemp.h"
 }
 
 
 static void
-spec_tex_aa_tri(GLcontext *ctx,
-		const SWvertex *v0,
-		const SWvertex *v1,
-		const SWvertex *v2)
+general_aa_tri(GLcontext *ctx,
+               const SWvertex *v0,
+               const SWvertex *v1,
+               const SWvertex *v2)
 {
 #define DO_Z
-#define DO_FOG
 #define DO_RGBA
 #define DO_ATTRIBS
-#define DO_SPEC
 #include "s_aatritemp.h"
 }
 
@@ -436,16 +396,15 @@ spec_tex_aa_tri(GLcontext *ctx,
 void
 _swrast_set_aa_triangle_function(GLcontext *ctx)
 {
+   SWcontext *swrast = SWRAST_CONTEXT(ctx);
+
    ASSERT(ctx->Polygon.SmoothFlag);
 
    if (ctx->Texture._EnabledCoordUnits != 0
-       || ctx->FragmentProgram._Current) {
-      if (NEED_SECONDARY_COLOR(ctx)) {
-         SWRAST_CONTEXT(ctx)->Triangle = spec_tex_aa_tri;
-      }
-      else {
-         SWRAST_CONTEXT(ctx)->Triangle = tex_aa_tri;
-      }
+       || ctx->FragmentProgram._Current
+       || swrast->_FogEnabled
+       || NEED_SECONDARY_COLOR(ctx)) {
+      SWRAST_CONTEXT(ctx)->Triangle = general_aa_tri;
    }
    else if (ctx->Visual.rgbMode) {
       SWRAST_CONTEXT(ctx)->Triangle = rgba_aa_tri;
diff --git a/src/mesa/swrast/s_aatritemp.h b/src/mesa/swrast/s_aatritemp.h
index 4162ed6853..34a2305b39 100644
--- a/src/mesa/swrast/s_aatritemp.h
+++ b/src/mesa/swrast/s_aatritemp.h
@@ -35,16 +35,15 @@
  *    DO_Z         - if defined, compute Z values
  *    DO_RGBA      - if defined, compute RGBA values
  *    DO_INDEX     - if defined, compute color index values
- *    DO_SPEC      - if defined, compute specular RGB values
  *    DO_ATTRIBS   - if defined, compute texcoords, varying, etc.
  */
 
 /*void triangle( GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2, GLuint pv )*/
 {
    const SWcontext *swrast = SWRAST_CONTEXT(ctx);
-   const GLfloat *p0 = v0->win;
-   const GLfloat *p1 = v1->win;
-   const GLfloat *p2 = v2->win;
+   const GLfloat *p0 = v0->attrib[FRAG_ATTRIB_WPOS];
+   const GLfloat *p1 = v1->attrib[FRAG_ATTRIB_WPOS];
+   const GLfloat *p2 = v2->attrib[FRAG_ATTRIB_WPOS];
    const SWvertex *vMin, *vMid, *vMax;
    GLint iyMin, iyMax;
    GLfloat yMin, yMax;
@@ -56,27 +55,15 @@
 #ifdef DO_Z
    GLfloat zPlane[4];
 #endif
-#ifdef DO_FOG
-   GLfloat fogPlane[4];
-#else
-   GLfloat *fog = NULL;
-#endif
 #ifdef DO_RGBA
    GLfloat rPlane[4], gPlane[4], bPlane[4], aPlane[4];
 #endif
 #ifdef DO_INDEX
    GLfloat iPlane[4];
 #endif
-#ifdef DO_SPEC
-   GLfloat srPlane[4], sgPlane[4], sbPlane[4];
-#endif
 #if defined(DO_ATTRIBS)
-   GLfloat sPlane[FRAG_ATTRIB_MAX][4];  /* texture S */
-   GLfloat tPlane[FRAG_ATTRIB_MAX][4];  /* texture T */
-   GLfloat uPlane[FRAG_ATTRIB_MAX][4];  /* texture R */
-   GLfloat vPlane[FRAG_ATTRIB_MAX][4];  /* texture Q */
-   GLfloat texWidth[FRAG_ATTRIB_MAX];
-   GLfloat texHeight[FRAG_ATTRIB_MAX];
+   GLfloat attrPlane[FRAG_ATTRIB_MAX][4][4];
+   GLfloat wPlane[4];  /* win[3] */
 #endif
    GLfloat bf = SWRAST_CONTEXT(ctx)->_BackfaceSign;
    
@@ -86,9 +73,9 @@
 
    /* determine bottom to top order of vertices */
    {
-      GLfloat y0 = v0->win[1];
-      GLfloat y1 = v1->win[1];
-      GLfloat y2 = v2->win[1];
+      GLfloat y0 = v0->attrib[FRAG_ATTRIB_WPOS][1];
+      GLfloat y1 = v1->attrib[FRAG_ATTRIB_WPOS][1];
+      GLfloat y2 = v2->attrib[FRAG_ATTRIB_WPOS][1];
       if (y0 <= y1) {
 	 if (y1 <= y2) {
 	    vMin = v0;   vMid = v1;   vMax = v2;   /* y0<=y1<=y2 */
@@ -113,12 +100,12 @@
       }
    }
 
-   majDx = vMax->win[0] - vMin->win[0];
-   majDy = vMax->win[1] - vMin->win[1];
+   majDx = vMax->attrib[FRAG_ATTRIB_WPOS][0] - vMin->attrib[FRAG_ATTRIB_WPOS][0];
+   majDy = vMax->attrib[FRAG_ATTRIB_WPOS][1] - vMin->attrib[FRAG_ATTRIB_WPOS][1];
 
    {
-      const GLfloat botDx = vMid->win[0] - vMin->win[0];
-      const GLfloat botDy = vMid->win[1] - vMin->win[1];
+      const GLfloat botDx = vMid->attrib[FRAG_ATTRIB_WPOS][0] - vMin->attrib[FRAG_ATTRIB_WPOS][0];
+      const GLfloat botDy = vMid->attrib[FRAG_ATTRIB_WPOS][1] - vMin->attrib[FRAG_ATTRIB_WPOS][1];
       const GLfloat area = majDx * botDy - botDx * majDy;
       /* Do backface culling */
       if (area * bf < 0 || area == 0 || IS_INF_OR_NAN(area))
@@ -135,14 +122,6 @@
    compute_plane(p0, p1, p2, p0[2], p1[2], p2[2], zPlane);
    span.arrayMask |= SPAN_Z;
 #endif
-#ifdef DO_FOG
-   compute_plane(p0, p1, p2,
-                 v0->attrib[FRAG_ATTRIB_FOGC][0],
-                 v1->attrib[FRAG_ATTRIB_FOGC][0],
-                 v2->attrib[FRAG_ATTRIB_FOGC][0],
-                 fogPlane);
-   span.arrayMask |= SPAN_FOG;
-#endif
 #ifdef DO_RGBA
    if (ctx->Light.ShadeModel == GL_SMOOTH) {
       compute_plane(p0, p1, p2, v0->color[RCOMP], v1->color[RCOMP], v2->color[RCOMP], rPlane);
@@ -160,62 +139,43 @@
 #endif
 #ifdef DO_INDEX
    if (ctx->Light.ShadeModel == GL_SMOOTH) {
-      compute_plane(p0, p1, p2, (GLfloat) v0->index,
-                    v1->index, v2->index, iPlane);
+      compute_plane(p0, p1, p2, (GLfloat) v0->attrib[FRAG_ATTRIB_CI][0],
+                    v1->attrib[FRAG_ATTRIB_CI][0], v2->attrib[FRAG_ATTRIB_CI][0], iPlane);
    }
    else {
-      constant_plane(v2->index, iPlane);
+      constant_plane(v2->attrib[FRAG_ATTRIB_CI][0], iPlane);
    }
    span.arrayMask |= SPAN_INDEX;
 #endif
-#ifdef DO_SPEC
-   if (ctx->Light.ShadeModel == GL_SMOOTH) {
-      compute_plane(p0, p1, p2, v0->specular[RCOMP], v1->specular[RCOMP], v2->specular[RCOMP], srPlane);
-      compute_plane(p0, p1, p2, v0->specular[GCOMP], v1->specular[GCOMP], v2->specular[GCOMP], sgPlane);
-      compute_plane(p0, p1, p2, v0->specular[BCOMP], v1->specular[BCOMP], v2->specular[BCOMP], sbPlane);
-   }
-   else {
-      constant_plane(v2->specular[RCOMP], srPlane);
-      constant_plane(v2->specular[GCOMP], sgPlane);
-      constant_plane(v2->specular[BCOMP], sbPlane);
-   }
-   span.arrayMask |= SPAN_SPEC;
-#endif
 #if defined(DO_ATTRIBS)
    {
-      const GLfloat invW0 = v0->win[3];
-      const GLfloat invW1 = v1->win[3];
-      const GLfloat invW2 = v2->win[3];
+      const GLfloat invW0 = v0->attrib[FRAG_ATTRIB_WPOS][3];
+      const GLfloat invW1 = v1->attrib[FRAG_ATTRIB_WPOS][3];
+      const GLfloat invW2 = v2->attrib[FRAG_ATTRIB_WPOS][3];
+      compute_plane(p0, p1, p2, invW0, invW1, invW2, wPlane);
+      span.attrStepX[FRAG_ATTRIB_WPOS][3] = plane_dx(wPlane);
+      span.attrStepY[FRAG_ATTRIB_WPOS][3] = plane_dy(wPlane);
       ATTRIB_LOOP_BEGIN
-         const GLfloat s0 = v0->attrib[attr][0] * invW0;
-         const GLfloat s1 = v1->attrib[attr][0] * invW1;
-         const GLfloat s2 = v2->attrib[attr][0] * invW2;
-         const GLfloat t0 = v0->attrib[attr][1] * invW0;
-         const GLfloat t1 = v1->attrib[attr][1] * invW1;
-         const GLfloat t2 = v2->attrib[attr][1] * invW2;
-         const GLfloat r0 = v0->attrib[attr][2] * invW0;
-         const GLfloat r1 = v1->attrib[attr][2] * invW1;
-         const GLfloat r2 = v2->attrib[attr][2] * invW2;
-         const GLfloat q0 = v0->attrib[attr][3] * invW0;
-         const GLfloat q1 = v1->attrib[attr][3] * invW1;
-         const GLfloat q2 = v2->attrib[attr][3] * invW2;
-         compute_plane(p0, p1, p2, s0, s1, s2, sPlane[attr]);
-         compute_plane(p0, p1, p2, t0, t1, t2, tPlane[attr]);
-         compute_plane(p0, p1, p2, r0, r1, r2, uPlane[attr]);
-         compute_plane(p0, p1, p2, q0, q1, q2, vPlane[attr]);
-         if (attr < FRAG_ATTRIB_VAR0 && attr >= FRAG_ATTRIB_TEX0) {
-            const GLuint u = attr - FRAG_ATTRIB_TEX0;
-            const struct gl_texture_object *obj = ctx->Texture.Unit[u]._Current;
-            const struct gl_texture_image *texImage = obj->Image[0][obj->BaseLevel];
-            texWidth[attr]  = (GLfloat) texImage->Width;
-            texHeight[attr] = (GLfloat) texImage->Height;
+         GLuint c;
+         if (swrast->_InterpMode[attr] == GL_FLAT) {
+            for (c = 0; c < 4; c++) {
+               constant_plane(v2->attrib[attr][c] * invW2, attrPlane[attr][c]);
+            }
          }
          else {
-            texWidth[attr] = texHeight[attr] = 1.0;
+            for (c = 0; c < 4; c++) {
+               const GLfloat a0 = v0->attrib[attr][c] * invW0;
+               const GLfloat a1 = v1->attrib[attr][c] * invW1;
+               const GLfloat a2 = v2->attrib[attr][c] * invW2;
+               compute_plane(p0, p1, p2, a0, a1, a2, attrPlane[attr][c]);
+            }
+         }
+         for (c = 0; c < 4; c++) {
+            span.attrStepX[attr][c] = plane_dx(attrPlane[attr][c]);
+            span.attrStepY[attr][c] = plane_dy(attrPlane[attr][c]);
          }
       ATTRIB_LOOP_END
    }
-   span.arrayMask |= (SPAN_TEXTURE | SPAN_LAMBDA | SPAN_VARYING);
 #endif
 
    /* Begin bottom-to-top scan over the triangle.
@@ -224,16 +184,16 @@
     * edges, stopping when we find that coverage = 0.  If the long edge
     * is on the left we scan left-to-right.  Else, we scan right-to-left.
     */
-   yMin = vMin->win[1];
-   yMax = vMax->win[1];
+   yMin = vMin->attrib[FRAG_ATTRIB_WPOS][1];
+   yMax = vMax->attrib[FRAG_ATTRIB_WPOS][1];
    iyMin = (GLint) yMin;
    iyMax = (GLint) yMax + 1;
 
    if (ltor) {
       /* scan left to right */
-      const GLfloat *pMin = vMin->win;
-      const GLfloat *pMid = vMid->win;
-      const GLfloat *pMax = vMax->win;
+      const GLfloat *pMin = vMin->attrib[FRAG_ATTRIB_WPOS];
+      const GLfloat *pMid = vMid->attrib[FRAG_ATTRIB_WPOS];
+      const GLfloat *pMax = vMax->attrib[FRAG_ATTRIB_WPOS];
       const GLfloat dxdy = majDx / majDy;
       const GLfloat xAdj = dxdy < 0.0F ? -dxdy : 0.0F;
       GLfloat x = pMin[0] - (yMin - iyMin) * dxdy;
@@ -253,6 +213,18 @@
 
          /* enter interior of triangle */
          ix = startX;
+
+#if defined(DO_ATTRIBS)
+         /* compute attributes at left-most fragment */
+         span.attrStart[FRAG_ATTRIB_WPOS][3] = solve_plane(ix + 0.5, iy + 0.5, wPlane);
+         ATTRIB_LOOP_BEGIN
+            GLuint c;
+            for (c = 0; c < 4; c++) {
+               span.attrStart[attr][c] = solve_plane(ix + 0.5, iy + 0.5, attrPlane[attr][c]);
+            }
+         ATTRIB_LOOP_END
+#endif
+
          count = 0;
          while (coverage > 0.0F) {
             /* (cx,cy) = center of fragment */
@@ -266,9 +238,6 @@
 #ifdef DO_Z
             array->z[count] = (GLuint) solve_plane(cx, cy, zPlane);
 #endif
-#ifdef DO_FOG
-	    array->attribs[FRAG_ATTRIB_FOGC][count][0] = solve_plane(cx, cy, fogPlane);
-#endif
 #ifdef DO_RGBA
             array->rgba[count][RCOMP] = solve_plane_chan(cx, cy, rPlane);
             array->rgba[count][GCOMP] = solve_plane_chan(cx, cy, gPlane);
@@ -277,25 +246,6 @@
 #endif
 #ifdef DO_INDEX
             array->index[count] = (GLint) solve_plane(cx, cy, iPlane);
-#endif
-#ifdef DO_SPEC
-            array->spec[count][RCOMP] = solve_plane_chan(cx, cy, srPlane);
-            array->spec[count][GCOMP] = solve_plane_chan(cx, cy, sgPlane);
-            array->spec[count][BCOMP] = solve_plane_chan(cx, cy, sbPlane);
-#endif
-#if defined(DO_ATTRIBS)
-            ATTRIB_LOOP_BEGIN
-               GLfloat invQ = solve_plane_recip(cx, cy, vPlane[attr]);
-               array->attribs[attr][count][0] = solve_plane(cx, cy, sPlane[attr]) * invQ;
-               array->attribs[attr][count][1] = solve_plane(cx, cy, tPlane[attr]) * invQ;
-               array->attribs[attr][count][2] = solve_plane(cx, cy, uPlane[attr]) * invQ;
-               if (attr < FRAG_ATTRIB_VAR0 && attr >= FRAG_ATTRIB_TEX0) {
-                  const GLuint unit = attr - FRAG_ATTRIB_TEX0;
-                  array->lambda[unit][count] = compute_lambda(sPlane[attr], tPlane[attr],
-                                                              vPlane[attr], cx, cy, invQ,
-                                                              texWidth[attr], texHeight[attr]);
-               }
-            ATTRIB_LOOP_END
 #endif
             ix++;
             count++;
@@ -308,7 +258,6 @@
          span.x = startX;
          span.y = iy;
          span.end = (GLuint) ix - (GLuint) startX;
-         ASSERT(span.interpMask == 0);
 #if defined(DO_RGBA)
          _swrast_write_rgba_span(ctx, &span);
 #else
@@ -318,9 +267,9 @@
    }
    else {
       /* scan right to left */
-      const GLfloat *pMin = vMin->win;
-      const GLfloat *pMid = vMid->win;
-      const GLfloat *pMax = vMax->win;
+      const GLfloat *pMin = vMin->attrib[FRAG_ATTRIB_WPOS];
+      const GLfloat *pMid = vMid->attrib[FRAG_ATTRIB_WPOS];
+      const GLfloat *pMax = vMax->attrib[FRAG_ATTRIB_WPOS];
       const GLfloat dxdy = majDx / majDy;
       const GLfloat xAdj = dxdy > 0 ? dxdy : 0.0F;
       GLfloat x = pMin[0] - (yMin - iyMin) * dxdy;
@@ -358,9 +307,6 @@
 #ifdef DO_Z
             array->z[ix] = (GLuint) solve_plane(cx, cy, zPlane);
 #endif
-#ifdef DO_FOG
-            array->attribs[FRAG_ATTRIB_FOGC][ix][0] = solve_plane(cx, cy, fogPlane);
-#endif
 #ifdef DO_RGBA
             array->rgba[ix][RCOMP] = solve_plane_chan(cx, cy, rPlane);
             array->rgba[ix][GCOMP] = solve_plane_chan(cx, cy, gPlane);
@@ -369,34 +315,23 @@
 #endif
 #ifdef DO_INDEX
             array->index[ix] = (GLint) solve_plane(cx, cy, iPlane);
-#endif
-#ifdef DO_SPEC
-            array->spec[ix][RCOMP] = solve_plane_chan(cx, cy, srPlane);
-            array->spec[ix][GCOMP] = solve_plane_chan(cx, cy, sgPlane);
-            array->spec[ix][BCOMP] = solve_plane_chan(cx, cy, sbPlane);
-#endif
-#if defined(DO_ATTRIBS)
-            ATTRIB_LOOP_BEGIN
-               GLfloat invQ = solve_plane_recip(cx, cy, vPlane[attr]);
-               array->attribs[attr][ix][0] = solve_plane(cx, cy, sPlane[attr]) * invQ;
-               array->attribs[attr][ix][1] = solve_plane(cx, cy, tPlane[attr]) * invQ;
-               array->attribs[attr][ix][2] = solve_plane(cx, cy, uPlane[attr]) * invQ;
-               if (attr < FRAG_ATTRIB_VAR0 && attr >= FRAG_ATTRIB_TEX0) {
-                  const GLuint unit = attr - FRAG_ATTRIB_TEX0;
-                  array->lambda[unit][ix] = compute_lambda(sPlane[attr],
-                                                           tPlane[attr],
-                                                           vPlane[attr],
-                                                           cx, cy, invQ,
-                                                           texWidth[attr],
-                                                           texHeight[attr]);
-               }
-            ATTRIB_LOOP_END
 #endif
             ix--;
             count++;
             coverage = compute_coveragef(pMin, pMax, pMid, ix, iy);
          }
          
+#if defined(DO_ATTRIBS)
+         /* compute attributes at left-most fragment */
+         span.attrStart[FRAG_ATTRIB_WPOS][3] = solve_plane(ix + 1.5, iy + 0.5, wPlane);
+         ATTRIB_LOOP_BEGIN
+            GLuint c;
+            for (c = 0; c < 4; c++) {
+               span.attrStart[attr][c] = solve_plane(ix + 1.5, iy + 0.5, attrPlane[attr][c]);
+            }
+         ATTRIB_LOOP_END
+#endif
+
          if (startX <= ix)
             continue;
 
@@ -410,48 +345,22 @@
             SWspanarrays *array = span.array;
             GLint j;
             for (j = 0; j < (GLint) n; j++) {
+               array->coverage[j] = array->coverage[j + left];
 #ifdef DO_RGBA
                COPY_CHAN4(array->rgba[j], array->rgba[j + left]);
 #endif
-#ifdef DO_SPEC
-               COPY_CHAN4(array->spec[j], array->spec[j + left]);
-#endif
 #ifdef DO_INDEX
                array->index[j] = array->index[j + left];
 #endif
 #ifdef DO_Z
                array->z[j] = array->z[j + left];
 #endif
-#ifdef DO_FOG
-               array->attribs[FRAG_ATTRIB_FOGC][j][0]
-                  = array->attribs[FRAG_ATTRIB_FOGC][j + left][0];
-#endif
-#if defined(DO_ATTRIBS)
-               array->lambda[0][j] = array->lambda[0][j + left];
-#endif
-               array->coverage[j] = array->coverage[j + left];
             }
          }
-#ifdef DO_ATTRIBS
-         /* shift texcoords, varying */
-         {
-            SWspanarrays *array = span.array;
-            ATTRIB_LOOP_BEGIN
-               GLint j;
-               for (j = 0; j < (GLint) n; j++) {
-                  array->attribs[attr][j][0] = array->attribs[attr][j + left][0];
-                  array->attribs[attr][j][1] = array->attribs[attr][j + left][1];
-                  array->attribs[attr][j][2] = array->attribs[attr][j + left][2];
-                  /*array->lambda[unit][j] = array->lambda[unit][j + left];*/
-               }
-            ATTRIB_LOOP_END
-         }
-#endif
 
          span.x = left;
          span.y = iy;
          span.end = n;
-         ASSERT(span.interpMask == 0);
 #if defined(DO_RGBA)
          _swrast_write_rgba_span(ctx, &span);
 #else
@@ -462,30 +371,8 @@
 }
 
 
-#ifdef DO_Z
 #undef DO_Z
-#endif
-
-#ifdef DO_FOG
-#undef DO_FOG
-#endif
-
-#ifdef DO_RGBA
 #undef DO_RGBA
-#endif
-
-#ifdef DO_INDEX
 #undef DO_INDEX
-#endif
-
-#ifdef DO_SPEC
-#undef DO_SPEC
-#endif
-
-#ifdef DO_ATTRIBS
 #undef DO_ATTRIBS
-#endif
-
-#ifdef DO_OCCLUSION_TEST
 #undef DO_OCCLUSION_TEST
-#endif
diff --git a/src/mesa/swrast/s_alpha.c b/src/mesa/swrast/s_alpha.c
index af8a6baddc..3c55d3e9e3 100644
--- a/src/mesa/swrast/s_alpha.c
+++ b/src/mesa/swrast/s_alpha.c
@@ -111,13 +111,13 @@ _swrast_alpha_test(const GLcontext *ctx, SWspan *span)
    if (span->arrayMask & SPAN_RGBA) {
       /* Use array's alpha values */
       if (span->array->ChanType == GL_UNSIGNED_BYTE) {
-         GLubyte (*rgba)[4] = span->array->color.sz1.rgba;
+         GLubyte (*rgba)[4] = span->array->rgba8;
          GLubyte ref;
          CLAMPED_FLOAT_TO_UBYTE(ref, ctx->Color.AlphaRef);
          ALPHA_TEST(rgba[i][ACOMP], ;);
       }
       else if (span->array->ChanType == GL_UNSIGNED_SHORT) {
-         GLushort (*rgba)[4] = span->array->color.sz2.rgba;
+         GLushort (*rgba)[4] = span->array->rgba16;
          GLushort ref;
          CLAMPED_FLOAT_TO_USHORT(ref, ctx->Color.AlphaRef);
          ALPHA_TEST(rgba[i][ACOMP], ;);
diff --git a/src/mesa/swrast/s_bitmap.c b/src/mesa/swrast/s_bitmap.c
index 4c23705245..563b5fe602 100644
--- a/src/mesa/swrast/s_bitmap.c
+++ b/src/mesa/swrast/s_bitmap.c
@@ -83,15 +83,7 @@ _swrast_Bitmap( GLcontext *ctx, GLint px, GLint py,
       _swrast_validate_derived( ctx );
 
    INIT_SPAN(span, GL_BITMAP, width, 0, SPAN_XY);
-
-   _swrast_span_default_color(ctx, &span);
-   _swrast_span_default_secondary_color(ctx, &span);
-   if (ctx->Depth.Test)
-      _swrast_span_default_z(ctx, &span);
-   if (swrast->_FogEnabled)
-      _swrast_span_default_fog(ctx, &span);
-   if (ctx->Texture._EnabledCoordUnits)
-      _swrast_span_default_texcoords(ctx, &span);
+   _swrast_span_default_attribs(ctx, &span);
 
    for (row = 0; row < height; row++) {
       const GLubyte *src = (const GLubyte *) _mesa_image_address2d(unpack,
@@ -189,20 +181,13 @@ _swrast_Bitmap( GLcontext *ctx, GLint px, GLint py,
       _swrast_validate_derived( ctx );
 
    INIT_SPAN(span, GL_BITMAP, width, 0, SPAN_MASK);
+   _swrast_span_default_attribs(ctx, &span);
 
    /*span.arrayMask |= SPAN_MASK;*/  /* we'll init span.mask[] */
    span.x = px;
    span.y = py;
    /*span.end = width;*/
 
-   _swrast_span_default_color(ctx, &span);
-   if (ctx->Depth.Test)
-      _swrast_span_default_z(ctx, &span);
-   if (swrast->_FogEnabled)
-      _swrast_span_default_fog(ctx, &span);
-   if (ctx->Texture._EnabledCoordUnits)
-      _swrast_span_default_texcoords(ctx, &span);
-
    for (row=0; row<height; row++, span.y++) {
       const GLubyte *src = (const GLubyte *) _mesa_image_address2d(unpack,
                  bitmap, width, height, GL_COLOR_INDEX, GL_BITMAP, row, 0);
diff --git a/src/mesa/swrast/s_context.c b/src/mesa/swrast/s_context.c
index 2f25edbd81..d4321194a0 100644
--- a/src/mesa/swrast/s_context.c
+++ b/src/mesa/swrast/s_context.c
@@ -188,6 +188,37 @@ _swrast_update_texture_env( GLcontext *ctx )
 }
 
 
+/**
+ * Determine if we can defer texturing/shading until after Z/stencil
+ * testing.  This potentially allows us to skip texturing/shading for
+ * lots of fragments.
+ */
+static void
+_swrast_update_deferred_texture(GLcontext *ctx)
+{
+   SWcontext *swrast = SWRAST_CONTEXT(ctx);
+   if (ctx->Color.AlphaEnabled) {
+      /* alpha test depends on post-texture/shader colors */
+      swrast->_DeferredTexture = GL_FALSE;
+   }
+   else {
+      const struct gl_fragment_program *fprog
+         = ctx->FragmentProgram._Current;
+      if (fprog && (fprog->Base.OutputsWritten & (1 << FRAG_RESULT_DEPR))) {
+         /* Z comes from fragment program/shader */
+         swrast->_DeferredTexture = GL_FALSE;
+      }
+      else if (ctx->Query.CurrentOcclusionObject) {
+         /* occlusion query depends on shader discard/kill results */
+         swrast->_DeferredTexture = GL_FALSE;
+      }
+      else {
+         swrast->_DeferredTexture = GL_TRUE;
+      }
+   }
+}
+
+
 /**
  * Update swrast->_FogColor and swrast->_FogEnable values.
  */
@@ -324,7 +355,6 @@ _swrast_validate_line( GLcontext *ctx, const SWvertex *v0, const SWvertex *v1 )
       swrast->Line = _swrast_add_spec_terms_line;
    }
 
-
    swrast->Line( ctx, v0, v1 );
 }
 
@@ -505,50 +535,58 @@ _swrast_update_texture_samplers(GLcontext *ctx)
 
 
 /**
- * Update swrast->_ActiveAttribs and swrast->_NumActiveAttribs
+ * Update swrast->_ActiveAttribs, swrast->_NumActiveAttribs, swrast->_ActiveAtttribMask.
  */
 static void
 _swrast_update_fragment_attribs(GLcontext *ctx)
 {
    SWcontext *swrast = SWRAST_CONTEXT(ctx);
    GLuint attribsMask;
-   
+
+   /*
+    * Compute _ActiveAttribsMask = which fragment attributes are needed.
+    */
    if (ctx->FragmentProgram._Current) {
+      /* fragment program/shader */
       attribsMask = ctx->FragmentProgram._Current->Base.InputsRead;
    }
+   else if (ctx->ATIFragmentShader._Enabled) {
+      attribsMask = ~0;  /* XXX fix me */
+   }
    else {
-      GLuint u;
+      /* fixed function */
       attribsMask = 0x0;
 
-#if 0 /* not yet */
-      if (ctx->Depth.Test)
-         attribsMask |= FRAG_BIT_WPOS;
-      if (NEED_SECONDARY_COLOR(ctx))
-         attribsMask |= FRAG_BIT_COL1;
+#if CHAN_TYPE == GL_FLOAT
+      attribsMask |= FRAG_BIT_COL0;
 #endif
+
+      if (ctx->Fog.ColorSumEnabled ||
+          (ctx->Light.Enabled &&
+           ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR)) {
+         attribsMask |= FRAG_BIT_COL1;
+      }
+
       if (swrast->_FogEnabled)
          attribsMask |= FRAG_BIT_FOGC;
 
-      for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
-         if (ctx->Texture.Unit[u]._ReallyEnabled) {
-            attribsMask |= FRAG_BIT_TEX(u);
-         }
-      }
+      attribsMask |= (ctx->Texture._EnabledUnits << FRAG_ATTRIB_TEX0);
    }
 
-   /* don't want to interpolate these generic attribs just yet */
-   /* XXX temporary */
-   attribsMask &= ~(FRAG_BIT_WPOS |
-                    FRAG_BIT_COL0 |
-                    FRAG_BIT_COL1 |
-                    FRAG_BIT_FOGC);
+   swrast->_ActiveAttribMask = attribsMask;
 
    /* Update _ActiveAttribs[] list */
    {
       GLuint i, num = 0;
       for (i = 0; i < FRAG_ATTRIB_MAX; i++) {
-         if (attribsMask & (1 << i))
+         if (attribsMask & (1 << i)) {
             swrast->_ActiveAttribs[num++] = i;
+            /* how should this attribute be interpolated? */
+            if (i == FRAG_ATTRIB_COL0 || i == FRAG_ATTRIB_COL1)
+               swrast->_InterpMode[i] = ctx->Light.ShadeModel;
+            else
+               swrast->_InterpMode[i] = GL_SMOOTH;
+         }
       }
       swrast->_NumActiveAttribs = num;
    }
@@ -627,14 +665,19 @@ _swrast_validate_derived( GLcontext *ctx )
       if (swrast->NewState & (_NEW_TEXTURE | _NEW_PROGRAM))
          _swrast_update_texture_samplers( ctx );
 
-      if (swrast->NewState & (_NEW_TEXTURE | _NEW_PROGRAM))
-         _swrast_validate_texture_images( ctx );
+      if (swrast->NewState & (_NEW_TEXTURE | _NEW_PROGRAM)) {
+         _swrast_validate_texture_images(ctx);
+         if (swrast->NewState & (_NEW_COLOR)) {
+            _swrast_update_deferred_texture(ctx);
+         }
+      }
 
       if (swrast->NewState & _SWRAST_NEW_RASTERMASK)
  	 _swrast_update_rasterflags( ctx );
 
       if (swrast->NewState & (_NEW_DEPTH |
                               _NEW_FOG |
+                              _NEW_LIGHT |
                               _NEW_PROGRAM |
                               _NEW_TEXTURE))
          _swrast_update_fragment_attribs(ctx);
@@ -787,14 +830,11 @@ _swrast_CreateContext( GLcontext *ctx )
    }
    swrast->SpanArrays->ChanType = CHAN_TYPE;
 #if CHAN_TYPE == GL_UNSIGNED_BYTE
-   swrast->SpanArrays->rgba = swrast->SpanArrays->color.sz1.rgba;
-   swrast->SpanArrays->spec = swrast->SpanArrays->color.sz1.spec;
+   swrast->SpanArrays->rgba = swrast->SpanArrays->rgba8;
 #elif CHAN_TYPE == GL_UNSIGNED_SHORT
-   swrast->SpanArrays->rgba = swrast->SpanArrays->color.sz2.rgba;
-   swrast->SpanArrays->spec = swrast->SpanArrays->color.sz2.spec;
+   swrast->SpanArrays->rgba = swrast->SpanArrays->rgba16;
 #else
    swrast->SpanArrays->rgba = swrast->SpanArrays->attribs[FRAG_ATTRIB_COL0];
-   swrast->SpanArrays->spec = swrast->SpanArrays->attribs[FRAG_ATTRIB_COL1];
 #endif
 
    /* init point span buffer */
@@ -896,7 +936,10 @@ _swrast_print_vertex( GLcontext *ctx, const SWvertex *v )
 
    if (SWRAST_DEBUG_VERTICES) {
       _mesa_debug(ctx, "win %f %f %f %f\n",
-                  v->win[0], v->win[1], v->win[2], v->win[3]);
+                  v->attrib[FRAG_ATTRIB_WPOS][0],
+                  v->attrib[FRAG_ATTRIB_WPOS][1],
+                  v->attrib[FRAG_ATTRIB_WPOS][2],
+                  v->attrib[FRAG_ATTRIB_WPOS][3]);
 
       for (i = 0 ; i < ctx->Const.MaxTextureCoordUnits ; i++)
 	 if (ctx->Texture.Unit[i]._ReallyEnabled)
@@ -909,18 +952,17 @@ _swrast_print_vertex( GLcontext *ctx, const SWvertex *v )
 #if CHAN_TYPE == GL_FLOAT
       _mesa_debug(ctx, "color %f %f %f %f\n",
                   v->color[0], v->color[1], v->color[2], v->color[3]);
-      _mesa_debug(ctx, "spec %f %f %f %f\n",
-                  v->specular[0], v->specular[1],
-                  v->specular[2], v->specular[3]);
 #else
       _mesa_debug(ctx, "color %d %d %d %d\n",
                   v->color[0], v->color[1], v->color[2], v->color[3]);
-      _mesa_debug(ctx, "spec %d %d %d %d\n",
-                  v->specular[0], v->specular[1],
-                  v->specular[2], v->specular[3]);
 #endif
+      _mesa_debug(ctx, "spec %g %g %g %g\n",
+                  v->attrib[FRAG_ATTRIB_COL1][0],
+                  v->attrib[FRAG_ATTRIB_COL1][1],
+                  v->attrib[FRAG_ATTRIB_COL1][2],
+                  v->attrib[FRAG_ATTRIB_COL1][3]);
       _mesa_debug(ctx, "fog %f\n", v->attrib[FRAG_ATTRIB_FOGC][0]);
-      _mesa_debug(ctx, "index %d\n", v->index);
+      _mesa_debug(ctx, "index %d\n", v->attrib[FRAG_ATTRIB_CI][0]);
       _mesa_debug(ctx, "pointsize %f\n", v->pointSize);
       _mesa_debug(ctx, "\n");
    }
diff --git a/src/mesa/swrast/s_context.h b/src/mesa/swrast/s_context.h
index c8333b8e0a..f118eb92ca 100644
--- a/src/mesa/swrast/s_context.h
+++ b/src/mesa/swrast/s_context.h
@@ -132,6 +132,7 @@ typedef struct
    GLboolean _PreferPixelFog;    /* Compute fog blend factor per fragment? */
    GLboolean _AnyTextureCombine;
    GLboolean _FogEnabled;
+   GLboolean _DeferredTexture;
    GLenum _FogMode;  /* either GL_FOG_MODE or fragment program's fog mode */
 
    /** Multiple render targets */
@@ -140,8 +141,12 @@ typedef struct
 
    /** List/array of the fragment attributes to interpolate */
    GLuint _ActiveAttribs[FRAG_ATTRIB_MAX];
+   /** Same info, but as a bitmask */
+   GLbitfield _ActiveAttribMask;
    /** Number of fragment attributes to interpolate */
    GLuint _NumActiveAttribs;
+   /** Indicates how each attrib is to be interpolated (lines/tris) */
+   GLenum _InterpMode[FRAG_ATTRIB_MAX]; /* GL_FLAT or GL_SMOOTH (for now) */
 
    /* Accum buffer temporaries.
     */
diff --git a/src/mesa/swrast/s_copypix.c b/src/mesa/swrast/s_copypix.c
index 012839cb88..53e584b3b6 100644
--- a/src/mesa/swrast/s_copypix.c
+++ b/src/mesa/swrast/s_copypix.c
@@ -94,7 +94,6 @@ static void
 copy_conv_rgba_pixels(GLcontext *ctx, GLint srcx, GLint srcy,
                       GLint width, GLint height, GLint destx, GLint desty)
 {
-   SWcontext *swrast = SWRAST_CONTEXT(ctx);
    GLint row;
    const GLboolean zoom = ctx->Pixel.ZoomX != 1.0F || ctx->Pixel.ZoomY != 1.0F;
    const GLbitfield transferOps = ctx->_ImageTransferState;
@@ -104,12 +103,7 @@ copy_conv_rgba_pixels(GLcontext *ctx, GLint srcx, GLint srcy,
    SWspan span;
 
    INIT_SPAN(span, GL_BITMAP, 0, 0, SPAN_RGBA);
-
-   if (ctx->Depth.Test)
-      _swrast_span_default_z(ctx, &span);
-   if (swrast->_FogEnabled)
-      _swrast_span_default_fog(ctx, &span);
-   _swrast_span_default_secondary_color(ctx, &span);
+   _swrast_span_default_attribs(ctx, &span);
 
    /* allocate space for GLfloat image */
    tmpImage = (GLfloat *) _mesa_malloc(width * height * 4 * sizeof(GLfloat));
@@ -194,7 +188,6 @@ static void
 copy_rgba_pixels(GLcontext *ctx, GLint srcx, GLint srcy,
                  GLint width, GLint height, GLint destx, GLint desty)
 {
-   SWcontext *swrast = SWRAST_CONTEXT(ctx);
    GLfloat *tmpImage, *p;
    GLint sy, dy, stepy, row;
    const GLboolean zoom = ctx->Pixel.ZoomX != 1.0F || ctx->Pixel.ZoomY != 1.0F;
@@ -240,11 +233,7 @@ copy_rgba_pixels(GLcontext *ctx, GLint srcx, GLint srcy,
    }
 
    INIT_SPAN(span, GL_BITMAP, 0, 0, SPAN_RGBA);
-   if (ctx->Depth.Test)
-      _swrast_span_default_z(ctx, &span);
-   if (swrast->_FogEnabled)
-      _swrast_span_default_fog(ctx, &span);
-   _swrast_span_default_secondary_color(ctx, &span);
+   _swrast_span_default_attribs(ctx, &span);
 
    if (overlapping) {
       tmpImage = (GLfloat *) _mesa_malloc(width * height * sizeof(GLfloat) * 4);
@@ -313,7 +302,6 @@ copy_ci_pixels( GLcontext *ctx, GLint srcx, GLint srcy,
                 GLint width, GLint height,
                 GLint destx, GLint desty )
 {
-   SWcontext *swrast = SWRAST_CONTEXT(ctx);
    GLuint *tmpImage,*p;
    GLint sy, dy, stepy;
    GLint j;
@@ -327,6 +315,7 @@ copy_ci_pixels( GLcontext *ctx, GLint srcx, GLint srcy,
    }
 
    INIT_SPAN(span, GL_BITMAP, 0, 0, SPAN_INDEX);
+   _swrast_span_default_attribs(ctx, &span);
 
    if (ctx->DrawBuffer == ctx->ReadBuffer) {
       overlapping = regions_overlap(srcx, srcy, destx, desty, width, height,
@@ -350,11 +339,6 @@ copy_ci_pixels( GLcontext *ctx, GLint srcx, GLint srcy,
       stepy = 1;
    }
 
-   if (ctx->Depth.Test)
-      _swrast_span_default_z(ctx, &span);
-   if (swrast->_FogEnabled)
-      _swrast_span_default_fog(ctx, &span);
-
    if (overlapping) {
       GLint ssy = sy;
       tmpImage = (GLuint *) _mesa_malloc(width * height * sizeof(GLuint));
@@ -450,7 +434,6 @@ copy_depth_pixels( GLcontext *ctx, GLint srcx, GLint srcy,
                    GLint width, GLint height,
                    GLint destx, GLint desty )
 {
-   SWcontext *swrast = SWRAST_CONTEXT(ctx);
    struct gl_framebuffer *fb = ctx->ReadBuffer;
    struct gl_renderbuffer *readRb = fb->_DepthBuffer;
    GLfloat *p, *tmpImage;
@@ -466,6 +449,7 @@ copy_depth_pixels( GLcontext *ctx, GLint srcx, GLint srcy,
    }
 
    INIT_SPAN(span, GL_BITMAP, 0, 0, SPAN_Z);
+   _swrast_span_default_attribs(ctx, &span);
 
    if (ctx->DrawBuffer == ctx->ReadBuffer) {
       overlapping = regions_overlap(srcx, srcy, destx, desty, width, height,
@@ -489,11 +473,6 @@ copy_depth_pixels( GLcontext *ctx, GLint srcx, GLint srcy,
       stepy = 1;
    }
 
-   _swrast_span_default_color(ctx, &span);
-   _swrast_span_default_secondary_color(ctx, &span);
-   if (swrast->_FogEnabled)
-      _swrast_span_default_fog(ctx, &span);
-
    if (overlapping) {
       GLint ssy = sy;
       tmpImage = (GLfloat *) _mesa_malloc(width * height * sizeof(GLfloat));
diff --git a/src/mesa/swrast/s_drawpix.c b/src/mesa/swrast/s_drawpix.c
index cd5b7bc293..d971d90fb9 100644
--- a/src/mesa/swrast/s_drawpix.c
+++ b/src/mesa/swrast/s_drawpix.c
@@ -71,13 +71,7 @@ fast_draw_rgba_pixels(GLcontext *ctx, GLint x, GLint y,
    }
 
    INIT_SPAN(span, GL_BITMAP, 0, 0, SPAN_RGBA);
-   _swrast_span_default_secondary_color(ctx, &span);
-   if (ctx->Depth.Test)
-      _swrast_span_default_z(ctx, &span);
-   if (swrast->_FogEnabled)
-      _swrast_span_default_fog(ctx, &span);
-   if (ctx->Texture._EnabledCoordUnits)
-      _swrast_span_default_texcoords(ctx, &span);
+   _swrast_span_default_attribs(ctx, &span);
 
    /* copy input params since clipping may change them */
    unpack = *userUnpack;
@@ -274,9 +268,9 @@ fast_draw_rgba_pixels(GLcontext *ctx, GLint x, GLint y,
             for (row = 0; row < drawHeight; row++) {
                ASSERT(drawWidth <= MAX_WIDTH);
                _mesa_map_ci8_to_rgba8(ctx, drawWidth, src,
-                                      span.array->color.sz1.rgba);
+                                      span.array->rgba8);
                rb->PutRow(ctx, rb, drawWidth, destX, destY,
-                          span.array->color.sz1.rgba, NULL);
+                          span.array->rgba8, NULL);
                src += unpack.RowLength;
                destY += yStep;
             }
@@ -287,12 +281,12 @@ fast_draw_rgba_pixels(GLcontext *ctx, GLint x, GLint y,
             for (row = 0; row < drawHeight; row++) {
                ASSERT(drawWidth <= MAX_WIDTH);
                _mesa_map_ci8_to_rgba8(ctx, drawWidth, src,
-                                      span.array->color.sz1.rgba);
+                                      span.array->rgba8);
                span.x = destX;
                span.y = destY;
                span.end = drawWidth;
                _swrast_write_zoomed_rgba_span(ctx, imgX, imgY, &span,
-                                              span.array->color.sz1.rgba);
+                                              span.array->rgba8);
                src += unpack.RowLength;
                destY++;
             }
@@ -333,18 +327,13 @@ draw_index_pixels( GLcontext *ctx, GLint x, GLint y,
                    const struct gl_pixelstore_attrib *unpack,
                    const GLvoid *pixels )
 {
-   SWcontext *swrast = SWRAST_CONTEXT(ctx);
    const GLint imgX = x, imgY = y;
    const GLboolean zoom = ctx->Pixel.ZoomX!=1.0 || ctx->Pixel.ZoomY!=1.0;
    GLint row, skipPixels;
    SWspan span;
 
    INIT_SPAN(span, GL_BITMAP, 0, 0, SPAN_INDEX);
-
-   if (ctx->Depth.Test)
-      _swrast_span_default_z(ctx, &span);
-   if (swrast->_FogEnabled)
-      _swrast_span_default_fog(ctx, &span);
+   _swrast_span_default_attribs(ctx, &span);
 
    /*
     * General solution
@@ -433,20 +422,13 @@ draw_depth_pixels( GLcontext *ctx, GLint x, GLint y,
                    const struct gl_pixelstore_attrib *unpack,
                    const GLvoid *pixels )
 {
-   SWcontext *swrast = SWRAST_CONTEXT(ctx);
    const GLboolean scaleOrBias
       = ctx->Pixel.DepthScale != 1.0 || ctx->Pixel.DepthBias != 0.0;
    const GLboolean zoom = ctx->Pixel.ZoomX != 1.0 || ctx->Pixel.ZoomY != 1.0;
    SWspan span;
 
    INIT_SPAN(span, GL_BITMAP, 0, 0, SPAN_Z);
-
-   _swrast_span_default_color(ctx, &span);
-   _swrast_span_default_secondary_color(ctx, &span);
-   if (swrast->_FogEnabled)
-      _swrast_span_default_fog(ctx, &span);
-   if (ctx->Texture._EnabledCoordUnits)
-      _swrast_span_default_texcoords(ctx, &span);
+   _swrast_span_default_attribs(ctx, &span);
 
    if (type == GL_UNSIGNED_SHORT
        && ctx->DrawBuffer->Visual.depthBits == 16
@@ -550,7 +532,6 @@ draw_rgba_pixels( GLcontext *ctx, GLint x, GLint y,
                   const struct gl_pixelstore_attrib *unpack,
                   const GLvoid *pixels )
 {
-   SWcontext *swrast = SWRAST_CONTEXT(ctx);
    const GLint imgX = x, imgY = y;
    const GLboolean zoom = ctx->Pixel.ZoomX!=1.0 || ctx->Pixel.ZoomY!=1.0;
    GLfloat *convImage = NULL;
@@ -562,14 +543,8 @@ draw_rgba_pixels( GLcontext *ctx, GLint x, GLint y,
                              unpack, pixels))
       return;
 
-   INIT_SPAN(span, GL_BITMAP, 0, 0, SPAN_RGBA);
-   _swrast_span_default_secondary_color(ctx, &span);
-   if (ctx->Depth.Test)
-      _swrast_span_default_z(ctx, &span);
-   if (swrast->_FogEnabled)
-      _swrast_span_default_fog(ctx, &span);
-   if (ctx->Texture._EnabledCoordUnits)
-      _swrast_span_default_texcoords(ctx, &span);
+   INIT_SPAN(span, GL_BITMAP, 0, 0x0, SPAN_RGBA);
+   _swrast_span_default_attribs(ctx, &span);
 
    if (ctx->Pixel.Convolution2DEnabled || ctx->Pixel.Separable2DEnabled) {
       /* Convolution has to be handled specially.  We'll create an
diff --git a/src/mesa/swrast/s_feedback.c b/src/mesa/swrast/s_feedback.c
index 3a15d0c367..606afc63ba 100644
--- a/src/mesa/swrast/s_feedback.c
+++ b/src/mesa/swrast/s_feedback.c
@@ -42,17 +42,17 @@ feedback_vertex(GLcontext * ctx, const SWvertex * v, const SWvertex * pv)
    GLfloat color[4];
    const GLfloat *vtc = v->attrib[FRAG_ATTRIB_TEX0];
 
-   win[0] = v->win[0];
-   win[1] = v->win[1];
-   win[2] = v->win[2] / ctx->DrawBuffer->_DepthMaxF;
-   win[3] = 1.0F / v->win[3];
+   win[0] = v->attrib[FRAG_ATTRIB_WPOS][0];
+   win[1] = v->attrib[FRAG_ATTRIB_WPOS][1];
+   win[2] = v->attrib[FRAG_ATTRIB_WPOS][2] / ctx->DrawBuffer->_DepthMaxF;
+   win[3] = 1.0F / v->attrib[FRAG_ATTRIB_WPOS][3];
 
    color[0] = CHAN_TO_FLOAT(pv->color[0]);
    color[1] = CHAN_TO_FLOAT(pv->color[1]);
    color[2] = CHAN_TO_FLOAT(pv->color[2]);
    color[3] = CHAN_TO_FLOAT(pv->color[3]);
 
-   _mesa_feedback_vertex(ctx, win, color, (GLfloat) v->index, vtc);
+   _mesa_feedback_vertex(ctx, win, color, v->attrib[FRAG_ATTRIB_CI][0], vtc);
 }
 
 
@@ -120,9 +120,10 @@ _swrast_select_triangle(GLcontext *ctx, const SWvertex *v0,
 {
    if (_swrast_culltriangle(ctx, v0, v1, v2)) {
       const GLfloat zs = 1.0F / ctx->DrawBuffer->_DepthMaxF;
-      _mesa_update_hitflag(ctx, v0->win[2] * zs);
-      _mesa_update_hitflag(ctx, v1->win[2] * zs);
-      _mesa_update_hitflag(ctx, v2->win[2] * zs);
+
+      _mesa_update_hitflag( ctx, v0->attrib[FRAG_ATTRIB_WPOS][2] * zs );
+      _mesa_update_hitflag( ctx, v1->attrib[FRAG_ATTRIB_WPOS][2] * zs );
+      _mesa_update_hitflag( ctx, v2->attrib[FRAG_ATTRIB_WPOS][2] * zs );
    }
 }
 
@@ -131,8 +132,8 @@ void
 _swrast_select_line(GLcontext *ctx, const SWvertex *v0, const SWvertex *v1)
 {
    const GLfloat zs = 1.0F / ctx->DrawBuffer->_DepthMaxF;
-   _mesa_update_hitflag(ctx, v0->win[2] * zs);
-   _mesa_update_hitflag(ctx, v1->win[2] * zs);
+   _mesa_update_hitflag( ctx, v0->attrib[FRAG_ATTRIB_WPOS][2] * zs );
+   _mesa_update_hitflag( ctx, v1->attrib[FRAG_ATTRIB_WPOS][2] * zs );
 }
 
 
@@ -140,5 +141,5 @@ void
 _swrast_select_point(GLcontext *ctx, const SWvertex *v)
 {
    const GLfloat zs = 1.0F / ctx->DrawBuffer->_DepthMaxF;
-   _mesa_update_hitflag(ctx, v->win[2] * zs);
+   _mesa_update_hitflag( ctx, v->attrib[FRAG_ATTRIB_WPOS][2] * zs );
 }
diff --git a/src/mesa/swrast/s_fog.c b/src/mesa/swrast/s_fog.c
index 433fc4a4d0..ed47964a66 100644
--- a/src/mesa/swrast/s_fog.c
+++ b/src/mesa/swrast/s_fog.c
@@ -65,30 +65,92 @@ _swrast_z_to_fogfactor(GLcontext *ctx, GLfloat z)
 }
 
 
+#define LINEAR_FOG(f, coord)  f = (fogEnd - coord) * fogScale
+
+#define EXP_FOG(f, coord)  f = EXPF(density * coord)
+
+#define EXP2_FOG(f, coord)				\
+do {							\
+   GLfloat tmp = negDensitySquared * coord * coord;	\
+   if (tmp < FLT_MIN_10_EXP)				\
+      tmp = FLT_MIN_10_EXP;				\
+   f = EXPF(tmp);					\
+ } while(0)
+
+
+#define BLEND_FOG(f, coord)  f = coord
+
+
+
 /**
  * Template code for computing fog blend factor and applying it to colors.
  * \param TYPE  either GLubyte, GLushort or GLfloat.
  * \param COMPUTE_F  code to compute the fog blend factor, f.
  */
-#define FOG_LOOP(TYPE, COMPUTE_F)					\
-do {									\
-   const GLfloat fogStep = span->attrStepX[FRAG_ATTRIB_FOGC][0];	\
-   GLfloat fogCoord = span->attrStart[FRAG_ATTRIB_FOGC][0];		\
-   const GLfloat wStep = haveW ? span->attrStepX[FRAG_ATTRIB_WPOS][3] : 0.0F;\
-   GLfloat w = haveW ? span->attrStart[FRAG_ATTRIB_WPOS][3] : 1.0F;	\
-   GLuint i;								\
-   for (i = 0; i < span->end; i++) {					\
-      GLfloat f, oneMinusF;						\
-      COMPUTE_F;							\
-      f = CLAMP(f, 0.0F, 1.0F);						\
-      oneMinusF = 1.0F - f;						\
-      rgba[i][RCOMP] = (TYPE) (f * rgba[i][RCOMP] + oneMinusF * rFog);	\
-      rgba[i][GCOMP] = (TYPE) (f * rgba[i][GCOMP] + oneMinusF * gFog);	\
-      rgba[i][BCOMP] = (TYPE) (f * rgba[i][BCOMP] + oneMinusF * bFog);	\
-      fogCoord += fogStep;						\
-      w += wStep;							\
-   }									\
-} while (0)
+#define FOG_LOOP(TYPE, FOG_FUNC)						\
+if (span->arrayAttribs & FRAG_BIT_FOGC) {					\
+   GLuint i;									\
+   for (i = 0; i < span->end; i++) {						\
+      const GLfloat fogCoord = span->array->attribs[FRAG_ATTRIB_FOGC][i][0];	\
+      const GLfloat c = FABSF(fogCoord);					\
+      GLfloat f, oneMinusF;							\
+      FOG_FUNC(f, c);								\
+      f = CLAMP(f, 0.0F, 1.0F);							\
+      oneMinusF = 1.0F - f;							\
+      rgba[i][RCOMP] = (TYPE) (f * rgba[i][RCOMP] + oneMinusF * rFog);		\
+      rgba[i][GCOMP] = (TYPE) (f * rgba[i][GCOMP] + oneMinusF * gFog);		\
+      rgba[i][BCOMP] = (TYPE) (f * rgba[i][BCOMP] + oneMinusF * bFog);		\
+   }										\
+}										\
+else {										\
+   const GLfloat fogStep = span->attrStepX[FRAG_ATTRIB_FOGC][0];		\
+   GLfloat fogCoord = span->attrStart[FRAG_ATTRIB_FOGC][0];			\
+   const GLfloat wStep = span->attrStepX[FRAG_ATTRIB_WPOS][3];			\
+   GLfloat w = span->attrStart[FRAG_ATTRIB_WPOS][3];				\
+   GLuint i;									\
+   for (i = 0; i < span->end; i++) {						\
+      const GLfloat c = FABSF(fogCoord) / w;					\
+      GLfloat f, oneMinusF;							\
+      FOG_FUNC(f, c);								\
+      f = CLAMP(f, 0.0F, 1.0F);							\
+      oneMinusF = 1.0F - f;							\
+      rgba[i][RCOMP] = (TYPE) (f * rgba[i][RCOMP] + oneMinusF * rFog);		\
+      rgba[i][GCOMP] = (TYPE) (f * rgba[i][GCOMP] + oneMinusF * gFog);		\
+      rgba[i][BCOMP] = (TYPE) (f * rgba[i][BCOMP] + oneMinusF * bFog);		\
+      fogCoord += fogStep;							\
+      w += wStep;								\
+   }										\
+}
+
+/* As above, but CI mode (XXX try to merge someday) */
+#define FOG_LOOP_CI(FOG_FUNC)							\
+if (span->arrayAttribs & FRAG_BIT_FOGC) {					\
+   GLuint i;									\
+   for (i = 0; i < span->end; i++) {						\
+      const GLfloat fogCoord = span->array->attribs[FRAG_ATTRIB_FOGC][i][0];	\
+      const GLfloat c = FABSF(fogCoord);					\
+      GLfloat f;								\
+      FOG_FUNC(f, c);								\
+      f = CLAMP(f, 0.0F, 1.0F);							\
+      index[i] = (GLuint) ((GLfloat) index[i] + (1.0F - f) * fogIndex);		\
+   }										\
+}										\
+else {										\
+   const GLfloat fogStep = span->attrStepX[FRAG_ATTRIB_FOGC][0];		\
+   GLfloat fogCoord = span->attrStart[FRAG_ATTRIB_FOGC][0];			\
+   const GLfloat wStep = span->attrStepX[FRAG_ATTRIB_WPOS][3];  		\
+   GLfloat w = span->attrStart[FRAG_ATTRIB_WPOS][3];				\
+   GLuint i;									\
+   for (i = 0; i < span->end; i++) {						\
+      const GLfloat c = FABSF(fogCoord) / w;					\
+      GLfloat f;								\
+      FOG_FUNC(f, c);								\
+      f = CLAMP(f, 0.0F, 1.0F);							\
+      index[i] = (GLuint) ((GLfloat) index[i] + (1.0F - f) * fogIndex);		\
+      fogCoord += fogStep;							\
+      w += wStep;								\
+   }										\
+}
 
 
 
@@ -104,12 +166,12 @@ _swrast_fog_rgba_span( const GLcontext *ctx, SWspan *span )
 {
    const SWcontext *swrast = SWRAST_CONTEXT(ctx);
    GLfloat rFog, gFog, bFog;
-   const GLuint haveW = (span->interpMask & SPAN_W);
 
    ASSERT(swrast->_FogEnabled);
-   ASSERT((span->interpMask | span->arrayMask) & SPAN_FOG);
+   ASSERT(swrast->_ActiveAttribMask & FRAG_BIT_FOGC);
    ASSERT(span->arrayMask & SPAN_RGBA);
 
+   /* compute (scaled) fog color */
    if (span->array->ChanType == GL_UNSIGNED_BYTE) {
       rFog = ctx->Fog.Color[RCOMP] * 255.0;
       gFog = ctx->Fog.Color[GCOMP] * 255.0;
@@ -126,79 +188,68 @@ _swrast_fog_rgba_span( const GLcontext *ctx, SWspan *span )
       bFog = ctx->Fog.Color[BCOMP];
    }
 
-
-   /* NOTE: if haveW is true, that means the fog start/step values are
-    * perspective-corrected and we have to divide each fog coord by W.
-    */
-
-   /* we need to compute fog blend factors */
    if (swrast->_PreferPixelFog) {
       /* The span's fog values are fog coordinates, now compute blend factors
        * and blend the fragment colors with the fog color.
        */
-      const GLfloat fogEnd = ctx->Fog.End;
-      const GLfloat fogScale = (ctx->Fog.Start == ctx->Fog.End)
-         ? 1.0F : 1.0F / (ctx->Fog.End - ctx->Fog.Start);
-      const GLfloat density = -ctx->Fog.Density;
-      const GLfloat negDensitySquared = -ctx->Fog.Density * ctx->Fog.Density;
-
       switch (swrast->_FogMode) {
       case GL_LINEAR:
-#define COMPUTE_F  f = (fogEnd - FABSF(fogCoord) / w) * fogScale;
-         if (span->array->ChanType == GL_UNSIGNED_BYTE) {
-            GLubyte (*rgba)[4] = span->array->color.sz1.rgba;
-            FOG_LOOP(GLubyte, COMPUTE_F);
-         }
-         else if (span->array->ChanType == GL_UNSIGNED_SHORT) {
-            GLushort (*rgba)[4] = span->array->color.sz2.rgba;
-            FOG_LOOP(GLushort, COMPUTE_F);
-         }
-         else {
-            GLfloat (*rgba)[4] = span->array->attribs[FRAG_ATTRIB_COL0];
-            ASSERT(span->array->ChanType == GL_FLOAT);
-            FOG_LOOP(GLfloat, COMPUTE_F);
+         {
+            const GLfloat fogEnd = ctx->Fog.End;
+            const GLfloat fogScale = (ctx->Fog.Start == ctx->Fog.End)
+               ? 1.0F : 1.0F / (ctx->Fog.End - ctx->Fog.Start);
+            if (span->array->ChanType == GL_UNSIGNED_BYTE) {
+               GLubyte (*rgba)[4] = span->array->rgba8;
+               FOG_LOOP(GLubyte, LINEAR_FOG);
+            }
+            else if (span->array->ChanType == GL_UNSIGNED_SHORT) {
+               GLushort (*rgba)[4] = span->array->rgba16;
+               FOG_LOOP(GLushort, LINEAR_FOG);
+            }
+            else {
+               GLfloat (*rgba)[4] = span->array->attribs[FRAG_ATTRIB_COL0];
+               ASSERT(span->array->ChanType == GL_FLOAT);
+               FOG_LOOP(GLfloat, LINEAR_FOG);
+            }
          }
-#undef COMPUTE_F
          break;
 
       case GL_EXP:
-#define COMPUTE_F  f = EXPF(density * FABSF(fogCoord) / w);
-         if (span->array->ChanType == GL_UNSIGNED_BYTE) {
-            GLubyte (*rgba)[4] = span->array->color.sz1.rgba;
-            FOG_LOOP(GLubyte, COMPUTE_F);
-         }
-         else if (span->array->ChanType == GL_UNSIGNED_SHORT) {
-            GLushort (*rgba)[4] = span->array->color.sz2.rgba;
-            FOG_LOOP(GLushort, COMPUTE_F);
-         }
-         else {
-            GLfloat (*rgba)[4] = span->array->attribs[FRAG_ATTRIB_COL0];
-            ASSERT(span->array->ChanType == GL_FLOAT);
-            FOG_LOOP(GLfloat, COMPUTE_F);
+         {
+            const GLfloat density = -ctx->Fog.Density;
+            if (span->array->ChanType == GL_UNSIGNED_BYTE) {
+               GLubyte (*rgba)[4] = span->array->rgba8;
+               FOG_LOOP(GLubyte, EXP_FOG);
+            }
+            else if (span->array->ChanType == GL_UNSIGNED_SHORT) {
+               GLushort (*rgba)[4] = span->array->rgba16;
+               FOG_LOOP(GLushort, EXP_FOG);
+            }
+            else {
+               GLfloat (*rgba)[4] = span->array->attribs[FRAG_ATTRIB_COL0];
+               ASSERT(span->array->ChanType == GL_FLOAT);
+               FOG_LOOP(GLfloat, EXP_FOG);
+            }
          }
-#undef COMPUTE_F
          break;
 
       case GL_EXP2:
-#define COMPUTE_F  const GLfloat coord = fogCoord / w; \
-                   GLfloat tmp = negDensitySquared * coord * coord; \
-                   if (tmp < FLT_MIN_10_EXP) \
-                      tmp = FLT_MIN_10_EXP; \
-                   f = EXPF(tmp);
-         if (span->array->ChanType == GL_UNSIGNED_BYTE) {
-            GLubyte (*rgba)[4] = span->array->color.sz1.rgba;
-            FOG_LOOP(GLubyte, COMPUTE_F);
-         }
-         else if (span->array->ChanType == GL_UNSIGNED_SHORT) {
-            GLushort (*rgba)[4] = span->array->color.sz2.rgba;
-            FOG_LOOP(GLushort, COMPUTE_F);
-         }
-         else {
-            GLfloat (*rgba)[4] = span->array->attribs[FRAG_ATTRIB_COL0];
-            ASSERT(span->array->ChanType == GL_FLOAT);
-            FOG_LOOP(GLfloat, COMPUTE_F);
+         {
+            const GLfloat negDensitySquared = -ctx->Fog.Density * ctx->Fog.Density;
+            if (span->array->ChanType == GL_UNSIGNED_BYTE) {
+               GLubyte (*rgba)[4] = span->array->rgba8;
+               FOG_LOOP(GLubyte, EXP2_FOG);
+            }
+            else if (span->array->ChanType == GL_UNSIGNED_SHORT) {
+               GLushort (*rgba)[4] = span->array->rgba16;
+               FOG_LOOP(GLushort, EXP2_FOG);
+            }
+            else {
+               GLfloat (*rgba)[4] = span->array->attribs[FRAG_ATTRIB_COL0];
+               ASSERT(span->array->ChanType == GL_FLOAT);
+               FOG_LOOP(GLfloat, EXP2_FOG);
+            }
          }
-#undef COMPUTE_F
          break;
 
       default:
@@ -206,63 +257,23 @@ _swrast_fog_rgba_span( const GLcontext *ctx, SWspan *span )
          return;
       }
    }
-   else if (span->arrayMask & SPAN_FOG) {
-      /* The span's fog array values are blend factors.
-       * They were previously computed per-vertex.
-       */
-      GLuint i;
-      if (span->array->ChanType == GL_UNSIGNED_BYTE) {
-         GLubyte (*rgba)[4] = span->array->color.sz1.rgba;
-         for (i = 0; i < span->end; i++) {
-            const GLfloat f = span->array->attribs[FRAG_ATTRIB_FOGC][i][0];
-            const GLfloat oneMinusF = 1.0F - f;
-            rgba[i][RCOMP] = (GLubyte) (f * rgba[i][RCOMP] + oneMinusF * rFog);
-            rgba[i][GCOMP] = (GLubyte) (f * rgba[i][GCOMP] + oneMinusF * gFog);
-            rgba[i][BCOMP] = (GLubyte) (f * rgba[i][BCOMP] + oneMinusF * bFog);
-         }
-      }
-      else if (span->array->ChanType == GL_UNSIGNED_SHORT) {
-         GLushort (*rgba)[4] = span->array->color.sz2.rgba;
-         for (i = 0; i < span->end; i++) {
-            const GLfloat f = span->array->attribs[FRAG_ATTRIB_FOGC][i][0];
-            const GLfloat oneMinusF = 1.0F - f;
-            rgba[i][RCOMP] = (GLushort) (f * rgba[i][RCOMP] + oneMinusF * rFog);
-            rgba[i][GCOMP] = (GLushort) (f * rgba[i][GCOMP] + oneMinusF * gFog);
-            rgba[i][BCOMP] = (GLushort) (f * rgba[i][BCOMP] + oneMinusF * bFog);
-         }
-      }
-      else {
-         GLfloat (*rgba)[4] = span->array->attribs[FRAG_ATTRIB_COL0];
-         ASSERT(span->array->ChanType == GL_FLOAT);
-         for (i = 0; i < span->end; i++) {
-            const GLfloat f = span->array->attribs[FRAG_ATTRIB_FOGC][i][0];
-            const GLfloat oneMinusF = 1.0F - f;
-            rgba[i][RCOMP] = f * rgba[i][RCOMP] + oneMinusF * rFog;
-            rgba[i][GCOMP] = f * rgba[i][GCOMP] + oneMinusF * gFog;
-            rgba[i][BCOMP] = f * rgba[i][BCOMP] + oneMinusF * bFog;
-         }
-      }
-
-   }
    else {
-      /* The span's fog start/step values are blend factors.
+      /* The span's fog start/step/array values are blend factors in [0,1].
        * They were previously computed per-vertex.
        */
-#define COMPUTE_F f = fogCoord / w;
       if (span->array->ChanType == GL_UNSIGNED_BYTE) {
-         GLubyte (*rgba)[4] = span->array->color.sz1.rgba;
-         FOG_LOOP(GLubyte, COMPUTE_F);
+         GLubyte (*rgba)[4] = span->array->rgba8;
+         FOG_LOOP(GLubyte, BLEND_FOG);
       }
       else if (span->array->ChanType == GL_UNSIGNED_SHORT) {
-         GLushort (*rgba)[4] = span->array->color.sz2.rgba;
-         FOG_LOOP(GLushort, COMPUTE_F);
+         GLushort (*rgba)[4] = span->array->rgba16;
+         FOG_LOOP(GLushort, BLEND_FOG);
       }
       else {
          GLfloat (*rgba)[4] = span->array->attribs[FRAG_ATTRIB_COL0];
          ASSERT(span->array->ChanType == GL_FLOAT);
-         FOG_LOOP(GLfloat, COMPUTE_F);
+         FOG_LOOP(GLfloat, BLEND_FOG);
       }
-#undef COMPUTE_F
    }
 }
 
@@ -274,13 +285,11 @@ void
 _swrast_fog_ci_span( const GLcontext *ctx, SWspan *span )
 {
    const SWcontext *swrast = SWRAST_CONTEXT(ctx);
-   const GLuint haveW = (span->interpMask & SPAN_W);
    const GLuint fogIndex = (GLuint) ctx->Fog.Index;
    GLuint *index = span->array->index;
 
    ASSERT(swrast->_FogEnabled);
    ASSERT(span->arrayMask & SPAN_INDEX);
-   ASSERT((span->interpMask | span->arrayMask) & SPAN_FOG);
 
    /* we need to compute fog blend factors */
    if (swrast->_PreferPixelFog) {
@@ -293,60 +302,19 @@ _swrast_fog_ci_span( const GLcontext *ctx, SWspan *span )
             const GLfloat fogEnd = ctx->Fog.End;
             const GLfloat fogScale = (ctx->Fog.Start == ctx->Fog.End)
                ? 1.0F : 1.0F / (ctx->Fog.End - ctx->Fog.Start);
-            const GLfloat fogStep = span->attrStepX[FRAG_ATTRIB_FOGC][0];
-            GLfloat fogCoord = span->attrStart[FRAG_ATTRIB_FOGC][0];
-            const GLfloat wStep = haveW ? span->attrStepX[FRAG_ATTRIB_WPOS][3] : 0.0F;
-            GLfloat w = haveW ? span->attrStart[FRAG_ATTRIB_WPOS][3] : 1.0F;
-            GLuint i;
-            for (i = 0; i < span->end; i++) {
-               GLfloat f = (fogEnd - fogCoord / w) * fogScale;
-               f = CLAMP(f, 0.0F, 1.0F);
-               index[i] = (GLuint) ((GLfloat) index[i] + (1.0F - f) * fogIndex);
-               fogCoord += fogStep;
-               w += wStep;
-            }
+            FOG_LOOP_CI(LINEAR_FOG);
          }
          break;
       case GL_EXP:
          {
             const GLfloat density = -ctx->Fog.Density;
-            const GLfloat fogStep = span->attrStepX[FRAG_ATTRIB_FOGC][0];
-            GLfloat fogCoord = span->attrStart[FRAG_ATTRIB_FOGC][0];
-            const GLfloat wStep = haveW ? span->attrStepX[FRAG_ATTRIB_WPOS][3] : 0.0F;
-            GLfloat w = haveW ? span->attrStart[FRAG_ATTRIB_WPOS][3] : 1.0F;
-            GLuint i;
-            for (i = 0; i < span->end; i++) {
-               GLfloat f = EXPF(density * fogCoord / w);
-               f = CLAMP(f, 0.0F, 1.0F);
-               index[i] = (GLuint) ((GLfloat) index[i] + (1.0F - f) * fogIndex);
-               fogCoord += fogStep;
-               w += wStep;
-            }
+            FOG_LOOP_CI(EXP_FOG);
          }
          break;
       case GL_EXP2:
          {
             const GLfloat negDensitySquared = -ctx->Fog.Density * ctx->Fog.Density;
-            const GLfloat fogStep = span->attrStepX[FRAG_ATTRIB_FOGC][0];
-            GLfloat fogCoord = span->attrStart[FRAG_ATTRIB_FOGC][0];
-            const GLfloat wStep = haveW ? span->attrStepX[FRAG_ATTRIB_WPOS][3] : 0.0F;
-            GLfloat w = haveW ? span->attrStart[FRAG_ATTRIB_WPOS][3] : 1.0F;
-            GLuint i;
-            for (i = 0; i < span->end; i++) {
-               const GLfloat coord = fogCoord / w;
-               GLfloat tmp = negDensitySquared * coord * coord;
-               GLfloat f;
-#if defined(__alpha__) || defined(__alpha)
-               /* XXX this underflow check may be needed for other systems*/
-               if (tmp < FLT_MIN_10_EXP)
-                  tmp = FLT_MIN_10_EXP;
-#endif
-               f = EXPF(tmp);
-               f = CLAMP(f, 0.0F, 1.0F);
-               index[i] = (GLuint) ((GLfloat) index[i] + (1.0F - f) * fogIndex);
-               fogCoord += fogStep;
-               w += wStep;
-            }
+            FOG_LOOP_CI(EXP2_FOG);
          }
          break;
       default:
@@ -354,31 +322,10 @@ _swrast_fog_ci_span( const GLcontext *ctx, SWspan *span )
          return;
       }
    }
-   else if (span->arrayMask & SPAN_FOG) {
-      /* The span's fog array values are blend factors.
-       * They were previously computed per-vertex.
-       */
-      GLuint i;
-      for (i = 0; i < span->end; i++) {
-         const GLfloat f = span->array->attribs[FRAG_ATTRIB_FOGC][i][0];
-         index[i] = (GLuint) ((GLfloat) index[i] + (1.0F - f) * fogIndex);
-      }
-   }
    else {
-      /* The span's fog start/step values are blend factors.
+      /* The span's fog start/step/array values are blend factors in [0,1].
        * They were previously computed per-vertex.
        */
-      const GLfloat fogStep = span->attrStepX[FRAG_ATTRIB_FOGC][0];
-      GLfloat fog = span->attrStart[FRAG_ATTRIB_FOGC][0];
-      const GLfloat wStep = haveW ? span->attrStepX[FRAG_ATTRIB_WPOS][3] : 0.0F;
-      GLfloat w = haveW ? span->attrStart[FRAG_ATTRIB_WPOS][3] : 1.0F;
-      GLuint i;
-      ASSERT(span->interpMask & SPAN_FOG);
-      for (i = 0; i < span->end; i++) {
-         const GLfloat f = fog / w;
-         index[i] = (GLuint) ((GLfloat) index[i] + (1.0F - f) * fogIndex);
-         fog += fogStep;
-         w += wStep;
-      }
+      FOG_LOOP_CI(BLEND_FOG);
    }
 }
diff --git a/src/mesa/swrast/s_lines.c b/src/mesa/swrast/s_lines.c
index 80702e41a3..781146e67f 100644
--- a/src/mesa/swrast/s_lines.c
+++ b/src/mesa/swrast/s_lines.c
@@ -121,29 +121,29 @@ draw_wide_line( GLcontext *ctx, SWspan *span, GLboolean xMajor )
 /**********************************************************************/
 
 /* Simple color index line (no stipple, width=1, no Z, no fog, no tex)*/
-#define NAME simple_ci_line
+#define NAME simple_no_z_ci_line
 #define INTERP_INDEX
 #define RENDER_SPAN(span) _swrast_write_index_span(ctx, &span)
 #include "s_linetemp.h"
 
 /* Simple RGBA index line (no stipple, width=1, no Z, no fog, no tex)*/
-#define NAME simple_rgba_line
+#define NAME simple_no_z_rgba_line
 #define INTERP_RGBA
 #define RENDER_SPAN(span) _swrast_write_rgba_span(ctx, &span);
 #include "s_linetemp.h"
 
 
 /* Z, fog, wide, stipple color index line */
-#define NAME general_ci_line
+#define NAME ci_line
 #define INTERP_INDEX
 #define INTERP_Z
-#define INTERP_FOG
+#define INTERP_ATTRIBS /* for fog */
 #define RENDER_SPAN(span)					\
    if (ctx->Line.StippleFlag) {					\
       span.arrayMask |= SPAN_MASK;				\
       compute_stipple_mask(ctx, span.end, span.array->mask);    \
    }								\
-   if (ctx->Line._Width > 1.0) {					\
+   if (ctx->Line._Width > 1.0) {				\
       draw_wide_line(ctx, &span, (GLboolean)(dx > dy));		\
    }								\
    else {							\
@@ -153,16 +153,15 @@ draw_wide_line( GLcontext *ctx, SWspan *span, GLboolean xMajor )
 
 
 /* Z, fog, wide, stipple RGBA line */
-#define NAME general_rgba_line
+#define NAME rgba_line
 #define INTERP_RGBA
 #define INTERP_Z
-#define INTERP_FOG
 #define RENDER_SPAN(span)					\
    if (ctx->Line.StippleFlag) {					\
       span.arrayMask |= SPAN_MASK;				\
       compute_stipple_mask(ctx, span.end, span.array->mask);	\
    }								\
-   if (ctx->Line._Width > 1.0) {					\
+   if (ctx->Line._Width > 1.0) {				\
       draw_wide_line(ctx, &span, (GLboolean)(dx > dy));		\
    }								\
    else {							\
@@ -171,19 +170,17 @@ draw_wide_line( GLcontext *ctx, SWspan *span, GLboolean xMajor )
 #include "s_linetemp.h"
 
 
-/* General-purpose textured line (any/all features). */
-#define NAME textured_line
+/* General-purpose line (any/all features). */
+#define NAME general_line
 #define INTERP_RGBA
-#define INTERP_SPEC
 #define INTERP_Z
-#define INTERP_FOG
 #define INTERP_ATTRIBS
 #define RENDER_SPAN(span)					\
    if (ctx->Line.StippleFlag) {					\
       span.arrayMask |= SPAN_MASK;				\
       compute_stipple_mask(ctx, span.end, span.array->mask);	\
    }								\
-   if (ctx->Line._Width > 1.0) {					\
+   if (ctx->Line._Width > 1.0) {				\
       draw_wide_line(ctx, &span, (GLboolean)(dx > dy));		\
    }								\
    else {							\
@@ -194,48 +191,39 @@ draw_wide_line( GLcontext *ctx, SWspan *span, GLboolean xMajor )
 
 
 void
-_swrast_add_spec_terms_line( GLcontext *ctx,
-                             const SWvertex *v0,
-                             const SWvertex *v1 )
+_swrast_add_spec_terms_line(GLcontext *ctx,
+                            const SWvertex *v0, const SWvertex *v1)
 {
    SWvertex *ncv0 = (SWvertex *)v0;
    SWvertex *ncv1 = (SWvertex *)v1;
-   GLchan c[2][4];
-   COPY_CHAN4( c[0], ncv0->color );
-   COPY_CHAN4( c[1], ncv1->color );
-   ACC_3V( ncv0->color, ncv0->specular );
-   ACC_3V( ncv1->color, ncv1->specular );
+   GLfloat rSum, gSum, bSum;
+   GLchan cSave[2][4];
+
+   /* save original colors */
+   COPY_CHAN4(cSave[0], ncv0->color);
+   COPY_CHAN4(cSave[1], ncv1->color);
+   /* sum v0 */
+   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];
+   bSum = CHAN_TO_FLOAT(ncv0->color[2]) + ncv0->attrib[FRAG_ATTRIB_COL1][2];
+   UNCLAMPED_FLOAT_TO_CHAN(ncv0->color[0], rSum);
+   UNCLAMPED_FLOAT_TO_CHAN(ncv0->color[1], gSum);
+   UNCLAMPED_FLOAT_TO_CHAN(ncv0->color[2], bSum);
+   /* sum v1 */
+   rSum = CHAN_TO_FLOAT(ncv1->color[0]) + ncv1->attrib[FRAG_ATTRIB_COL1][0];
+   gSum = CHAN_TO_FLOAT(ncv1->color[1]) + ncv1->attrib[FRAG_ATTRIB_COL1][1];
+   bSum = CHAN_TO_FLOAT(ncv1->color[2]) + ncv1->attrib[FRAG_ATTRIB_COL1][2];
+   UNCLAMPED_FLOAT_TO_CHAN(ncv1->color[0], rSum);
+   UNCLAMPED_FLOAT_TO_CHAN(ncv1->color[1], gSum);
+   UNCLAMPED_FLOAT_TO_CHAN(ncv1->color[2], bSum);
+   /* draw */
    SWRAST_CONTEXT(ctx)->SpecLine( ctx, ncv0, ncv1 );
-   COPY_CHAN4( ncv0->color, c[0] );
-   COPY_CHAN4( ncv1->color, c[1] );
+   /* restore original colors */
+   COPY_CHAN4( ncv0->attrib[FRAG_ATTRIB_COL0], cSave[0] );
+   COPY_CHAN4( ncv1->attrib[FRAG_ATTRIB_COL0], cSave[1] );
 }
 
 
-#ifdef DEBUG
-extern void
-_mesa_print_line_function(GLcontext *ctx);  /* silence compiler warning */
-void
-_mesa_print_line_function(GLcontext *ctx)
-{
-   SWcontext *swrast = SWRAST_CONTEXT(ctx);
-
-   _mesa_printf("Line Func == ");
-   if (swrast->Line == simple_ci_line)
-      _mesa_printf("simple_ci_line\n");
-   else if (swrast->Line == simple_rgba_line)
-      _mesa_printf("simple_rgba_line\n");
-   else if (swrast->Line == general_ci_line)
-      _mesa_printf("general_ci_line\n");
-   else if (swrast->Line == general_rgba_line)
-      _mesa_printf("general_rgba_line\n");
-   else if (swrast->Line == textured_line)
-      _mesa_printf("textured_line\n");
-   else
-      _mesa_printf("Driver func %p\n", (void *(*)()) swrast->Line);
-}
-#endif
-
-
 
 #ifdef DEBUG
 
@@ -257,7 +245,7 @@ do {                                    \
 
 
 
-/*
+/**
  * Determine which line drawing function to use given the current
  * rendering context.
  *
@@ -269,6 +257,9 @@ _swrast_choose_line( GLcontext *ctx )
 {
    SWcontext *swrast = SWRAST_CONTEXT(ctx);
    const GLboolean rgbmode = ctx->Visual.rgbMode;
+   GLboolean specular = (ctx->Fog.ColorSumEnabled ||
+                         (ctx->Light.Enabled &&
+                          ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR));
 
    if (ctx->RenderMode == GL_RENDER) {
       if (ctx->Line.SmoothFlag) {
@@ -277,24 +268,27 @@ _swrast_choose_line( GLcontext *ctx )
          ASSERT(swrast->Line);
       }
       else if (ctx->Texture._EnabledCoordUnits
-             || ctx->FragmentProgram._Current) {
-         /* textured lines */
-         USE(textured_line);
+               || ctx->FragmentProgram._Current
+               || swrast->_FogEnabled
+               || specular) {
+         USE(general_line);
       }
-      else if (ctx->Depth.Test || swrast->_FogEnabled || ctx->Line._Width != 1.0
+      else if (ctx->Depth.Test
+               || ctx->Line._Width != 1.0
                || ctx->Line.StippleFlag) {
          /* no texture, but Z, fog, width>1, stipple, etc. */
          if (rgbmode)
-            USE(general_rgba_line);
+            USE(rgba_line);
          else
-            USE(general_ci_line);
+            USE(ci_line);
       }
       else {
-         /* simplest lines */
+         ASSERT(!ctx->Depth.Test);
+         /* simple lines */
          if (rgbmode)
-            USE(simple_rgba_line);
+            USE(simple_no_z_rgba_line);
          else
-            USE(simple_ci_line);
+            USE(simple_no_z_ci_line);
       }
    }
    else if (ctx->RenderMode == GL_FEEDBACK) {
@@ -304,6 +298,4 @@ _swrast_choose_line( GLcontext *ctx )
       ASSERT(ctx->RenderMode == GL_SELECT);
       USE(_swrast_select_line);
    }
-
-   /*_mesa_print_line_function(ctx);*/
 }
diff --git a/src/mesa/swrast/s_linetemp.h b/src/mesa/swrast/s_linetemp.h
index b6e8f287f4..55548f27b0 100644
--- a/src/mesa/swrast/s_linetemp.h
+++ b/src/mesa/swrast/s_linetemp.h
@@ -1,6 +1,6 @@
 /*
  * Mesa 3-D graphics library
- * Version:  6.5.3
+ * Version:  7.0
  *
  * Copyright (C) 1999-2007  Brian Paul   All Rights Reserved.
  *
@@ -31,9 +31,7 @@
  * The following macros may be defined to indicate what auxillary information
  * must be interplated along the line:
  *    INTERP_Z        - if defined, interpolate Z values
- *    INTERP_FOG      - if defined, interpolate FOG values
  *    INTERP_RGBA     - if defined, interpolate RGBA values
- *    INTERP_SPEC     - if defined, interpolate specular RGB values
  *    INTERP_INDEX    - if defined, interpolate color index values
  *    INTERP_ATTRIBS  - if defined, interpolate attribs (texcoords, varying, etc)
  *
@@ -72,10 +70,10 @@ NAME( GLcontext *ctx, const SWvertex *vert0, const SWvertex *vert1 )
    const SWcontext *swrast = SWRAST_CONTEXT(ctx);
    SWspan span;
    GLuint interpFlags = 0;
-   GLint x0 = (GLint) vert0->win[0];
-   GLint x1 = (GLint) vert1->win[0];
-   GLint y0 = (GLint) vert0->win[1];
-   GLint y1 = (GLint) vert1->win[1];
+   GLint x0 = (GLint) vert0->attrib[FRAG_ATTRIB_WPOS][0];
+   GLint x1 = (GLint) vert1->attrib[FRAG_ATTRIB_WPOS][0];
+   GLint y0 = (GLint) vert0->attrib[FRAG_ATTRIB_WPOS][1];
+   GLint y1 = (GLint) vert1->attrib[FRAG_ATTRIB_WPOS][1];
    GLint dx, dy;
    GLint numPixels;
    GLint xstep, ystep;
@@ -104,8 +102,8 @@ NAME( GLcontext *ctx, const SWvertex *vert0, const SWvertex *vert1 )
    /* Cull primitives with malformed coordinates.
     */
    {
-      GLfloat tmp = vert0->win[0] + vert0->win[1]
-                  + vert1->win[0] + vert1->win[1];
+      GLfloat tmp = vert0->attrib[FRAG_ATTRIB_WPOS][0] + vert0->attrib[FRAG_ATTRIB_WPOS][1]
+                  + vert1->attrib[FRAG_ATTRIB_WPOS][0] + vert1->attrib[FRAG_ATTRIB_WPOS][1];
       if (IS_INF_OR_NAN(tmp))
 	 return;
    }
@@ -113,8 +111,12 @@ NAME( GLcontext *ctx, const SWvertex *vert0, const SWvertex *vert1 )
    /*
    printf("%s():\n", __FUNCTION__);
    printf(" (%f, %f, %f) -> (%f, %f, %f)\n",
-          vert0->win[0], vert0->win[1], vert0->win[2],
-          vert1->win[0], vert1->win[1], vert1->win[2]);
+          vert0->attrib[FRAG_ATTRIB_WPOS][0],
+          vert0->attrib[FRAG_ATTRIB_WPOS][1],
+          vert0->attrib[FRAG_ATTRIB_WPOS][2],
+          vert1->attrib[FRAG_ATTRIB_WPOS][0],
+          vert1->attrib[FRAG_ATTRIB_WPOS][1],
+          vert1->attrib[FRAG_ATTRIB_WPOS][2]);
    printf(" (%d, %d, %d) -> (%d, %d, %d)\n",
           vert0->color[0], vert0->color[1], vert0->color[2], 
           vert1->color[0], vert1->color[1], vert1->color[2]);
@@ -154,6 +156,18 @@ NAME( GLcontext *ctx, const SWvertex *vert0, const SWvertex *vert1 )
    if (dx == 0 && dy == 0)
       return;
 
+   /*
+   printf("%s %d,%d  %g %g %g %g  %g %g %g %g\n", __FUNCTION__, dx, dy,
+          vert0->attrib[FRAG_ATTRIB_COL1][0],
+          vert0->attrib[FRAG_ATTRIB_COL1][1],
+          vert0->attrib[FRAG_ATTRIB_COL1][2],
+          vert0->attrib[FRAG_ATTRIB_COL1][3],
+          vert1->attrib[FRAG_ATTRIB_COL1][0],
+          vert1->attrib[FRAG_ATTRIB_COL1][1],
+          vert1->attrib[FRAG_ATTRIB_COL1][2],
+          vert1->attrib[FRAG_ATTRIB_COL1][3]);
+   */
+
 #ifdef DEPTH_TYPE
    zPtr = (DEPTH_TYPE *) zrb->GetPointer(ctx, zrb, x0, y0);
 #endif
@@ -232,33 +246,15 @@ NAME( GLcontext *ctx, const SWvertex *vert0, const SWvertex *vert1 )
       span.alphaStep = 0;
    }
 #endif
-#ifdef INTERP_SPEC
-   interpFlags |= SPAN_SPEC;
-   if (ctx->Light.ShadeModel == GL_SMOOTH) {
-      span.specRed       = ChanToFixed(vert0->specular[0]);
-      span.specGreen     = ChanToFixed(vert0->specular[1]);
-      span.specBlue      = ChanToFixed(vert0->specular[2]);
-      span.specRedStep   = (ChanToFixed(vert1->specular[0]) - span.specRed) / numPixels;
-      span.specGreenStep = (ChanToFixed(vert1->specular[1]) - span.specBlue) / numPixels;
-      span.specBlueStep  = (ChanToFixed(vert1->specular[2]) - span.specGreen) / numPixels;
-   }
-   else {
-      span.specRed       = ChanToFixed(vert1->specular[0]);
-      span.specGreen     = ChanToFixed(vert1->specular[1]);
-      span.specBlue      = ChanToFixed(vert1->specular[2]);
-      span.specRedStep   = 0;
-      span.specGreenStep = 0;
-      span.specBlueStep  = 0;
-   }
-#endif
 #ifdef INTERP_INDEX
    interpFlags |= SPAN_INDEX;
    if (ctx->Light.ShadeModel == GL_SMOOTH) {
-      span.index = FloatToFixed(vert0->index);
-      span.indexStep = FloatToFixed(vert1->index - vert0->index) / numPixels;
+      span.index = FloatToFixed(vert0->attrib[FRAG_ATTRIB_CI][0]);
+      span.indexStep = FloatToFixed(  vert1->attrib[FRAG_ATTRIB_CI][0]
+                                    - vert0->attrib[FRAG_ATTRIB_CI][0]) / numPixels;
    }
    else {
-      span.index = FloatToFixed(vert1->index);
+      span.index = FloatToFixed(vert1->attrib[FRAG_ATTRIB_CI][0]);
       span.indexStep = 0;
    }
 #endif
@@ -266,57 +262,49 @@ NAME( GLcontext *ctx, const SWvertex *vert0, const SWvertex *vert1 )
    interpFlags |= SPAN_Z;
    {
       if (depthBits <= 16) {
-         span.z = FloatToFixed(vert0->win[2]) + FIXED_HALF;
-         span.zStep = FloatToFixed(vert1->win[2] - vert0->win[2]) / numPixels;
+         span.z = FloatToFixed(vert0->attrib[FRAG_ATTRIB_WPOS][2]) + FIXED_HALF;
+         span.zStep = FloatToFixed(  vert1->attrib[FRAG_ATTRIB_WPOS][2]
+                                   - vert0->attrib[FRAG_ATTRIB_WPOS][2]) / numPixels;
       }
       else {
          /* don't use fixed point */
-         span.z = (GLuint) vert0->win[2];
-         span.zStep = (GLint) ((vert1->win[2] - vert0->win[2]) / numPixels);
+         span.z = (GLuint) vert0->attrib[FRAG_ATTRIB_WPOS][2];
+         span.zStep = (GLint) ((  vert1->attrib[FRAG_ATTRIB_WPOS][2]
+                                - vert0->attrib[FRAG_ATTRIB_WPOS][2]) / numPixels);
       }
    }
 #endif
-#ifdef INTERP_FOG
-   interpFlags |= SPAN_FOG;
-   span.attrStart[FRAG_ATTRIB_FOGC][0] = vert0->attrib[FRAG_ATTRIB_FOGC][0];
-   span.attrStepX[FRAG_ATTRIB_FOGC][0] = (vert1->attrib[FRAG_ATTRIB_FOGC][0]
-                                          - vert0->attrib[FRAG_ATTRIB_FOGC][0]) / numPixels;
-#endif
 #if defined(INTERP_ATTRIBS)
-   interpFlags |= (SPAN_TEXTURE | SPAN_VARYING);
    {
       const GLfloat invLen = 1.0F / numPixels;
-      const GLfloat invw0 = vert0->win[3];
-      const GLfloat invw1 = vert1->win[3];
+      const GLfloat invw0 = vert0->attrib[FRAG_ATTRIB_WPOS][3];
+      const GLfloat invw1 = vert1->attrib[FRAG_ATTRIB_WPOS][3];
+
+      span.attrStart[FRAG_ATTRIB_WPOS][3] = invw0;
+      span.attrStepX[FRAG_ATTRIB_WPOS][3] = (invw1 - invw0) * invLen;
+      span.attrStepY[FRAG_ATTRIB_WPOS][3] = 0.0;
+
       ATTRIB_LOOP_BEGIN
-         GLfloat ds, dt, dr, dq;
-         span.attrStart[attr][0] = invw0 * vert0->attrib[attr][0];
-         span.attrStart[attr][1] = invw0 * vert0->attrib[attr][1];
-         span.attrStart[attr][2] = invw0 * vert0->attrib[attr][2];
-         span.attrStart[attr][3] = invw0 * vert0->attrib[attr][3];
-         ds = (invw1 * vert1->attrib[attr][0]) - span.attrStart[attr][0];
-         dt = (invw1 * vert1->attrib[attr][1]) - span.attrStart[attr][1];
-         dr = (invw1 * vert1->attrib[attr][2]) - span.attrStart[attr][2];
-         dq = (invw1 * vert1->attrib[attr][3]) - span.attrStart[attr][3];
-         span.attrStepX[attr][0] = ds * invLen;
-         span.attrStepX[attr][1] = dt * invLen;
-         span.attrStepX[attr][2] = dr * invLen;
-         span.attrStepX[attr][3] = dq * invLen;
-         span.attrStepY[attr][0] = 0.0F;
-         span.attrStepY[attr][1] = 0.0F;
-         span.attrStepY[attr][2] = 0.0F;
-         span.attrStepY[attr][3] = 0.0F;
+         if (swrast->_InterpMode[attr] == GL_FLAT) {
+            COPY_4V(span.attrStart[attr], vert1->attrib[attr]);
+            ASSIGN_4V(span.attrStepX[attr], 0.0, 0.0, 0.0, 0.0);
+         }
+         else {
+            GLuint c;
+            for (c = 0; c < 4; c++) {
+               float da;
+               span.attrStart[attr][c] = invw0 * vert0->attrib[attr][c];
+               da = (invw1 * vert1->attrib[attr][c]) - span.attrStart[attr][c];
+               span.attrStepX[attr][c] = da * invLen;
+            }
+         }
+         ASSIGN_4V(span.attrStepY[attr], 0.0, 0.0, 0.0, 0.0);
       ATTRIB_LOOP_END
    }
 #endif
 
    INIT_SPAN(span, GL_LINE, numPixels, interpFlags, SPAN_XY);
 
-   /* Need these for fragment prog texcoord interpolation */
-   span.attrStart[FRAG_ATTRIB_WPOS][3] = 1.0F;
-   span.attrStepX[FRAG_ATTRIB_WPOS][3] = 0.0F;
-   span.attrStepY[FRAG_ATTRIB_WPOS][3] = 0.0F;
-
    /*
     * Draw
     */
@@ -346,7 +334,7 @@ NAME( GLcontext *ctx, const SWvertex *vert0, const SWvertex *vert1 )
 #ifdef PIXEL_ADDRESS
          pixelPtr = (PIXEL_TYPE*) ((GLubyte*) pixelPtr + pixelXstep);
 #endif
-         if (error<0) {
+         if (error < 0) {
             error += errorInc;
          }
          else {
@@ -413,9 +401,7 @@ NAME( GLcontext *ctx, const SWvertex *vert0, const SWvertex *vert1 )
 
 #undef NAME
 #undef INTERP_Z
-#undef INTERP_FOG
 #undef INTERP_RGBA
-#undef INTERP_SPEC
 #undef INTERP_ATTRIBS
 #undef INTERP_INDEX
 #undef PIXEL_ADDRESS
diff --git a/src/mesa/swrast/s_logic.c b/src/mesa/swrast/s_logic.c
index e680732bee..0af9063968 100644
--- a/src/mesa/swrast/s_logic.c
+++ b/src/mesa/swrast/s_logic.c
@@ -229,13 +229,13 @@ _swrast_logicop_rgba_span(GLcontext *ctx, struct gl_renderbuffer *rb,
    if (span->array->ChanType == GL_UNSIGNED_BYTE) {
       /* treat 4*GLubyte as GLuint */
       logicop_uint1(ctx, span->end,
-                    (GLuint *) span->array->color.sz1.rgba,
+                    (GLuint *) span->array->rgba8,
                     (const GLuint *) rbPixels, span->array->mask);
    }
    else if (span->array->ChanType == GL_UNSIGNED_SHORT) {
       /* treat 2*GLushort as GLuint */
       logicop_uint2(ctx, 2 * span->end,
-                    (GLuint *) span->array->color.sz2.rgba,
+                    (GLuint *) span->array->rgba16,
                     (const GLuint *) rbPixels, span->array->mask);
    }
    else {
diff --git a/src/mesa/swrast/s_masking.c b/src/mesa/swrast/s_masking.c
index 8800f7d8e3..a69720e83a 100644
--- a/src/mesa/swrast/s_masking.c
+++ b/src/mesa/swrast/s_masking.c
@@ -61,7 +61,7 @@ _swrast_mask_rgba_span(GLcontext *ctx, struct gl_renderbuffer *rb,
       const GLuint srcMask = *((GLuint *) ctx->Color.ColorMask);
       const GLuint dstMask = ~srcMask;
       const GLuint *dst = (const GLuint *) rbPixels;
-      GLuint *src = (GLuint *) span->array->color.sz1.rgba;
+      GLuint *src = (GLuint *) span->array->rgba8;
       GLuint i;
       for (i = 0; i < n; i++) {
          src[i] = (src[i] & srcMask) | (dst[i] & dstMask);
@@ -75,7 +75,7 @@ _swrast_mask_rgba_span(GLcontext *ctx, struct gl_renderbuffer *rb,
       const GLushort bMask = ctx->Color.ColorMask[BCOMP] ? 0xffff : 0x0;
       const GLushort aMask = ctx->Color.ColorMask[ACOMP] ? 0xffff : 0x0;
       const GLushort (*dst)[4] = (const GLushort (*)[4]) rbPixels;
-      GLushort (*src)[4] = span->array->color.sz2.rgba;
+      GLushort (*src)[4] = span->array->rgba16;
       GLuint i;
       for (i = 0; i < n; i++) {
          src[i][RCOMP] = (src[i][RCOMP] & rMask) | (dst[i][RCOMP] & ~rMask);
diff --git a/src/mesa/swrast/s_points.c b/src/mesa/swrast/s_points.c
index 1401b772ca..02c9d9b425 100644
--- a/src/mesa/swrast/s_points.c
+++ b/src/mesa/swrast/s_points.c
@@ -34,7 +34,6 @@
 #include "s_span.h"
 
 
-
 #define RGBA       0x1
 #define INDEX      0x2
 #define SMOOTH     0x4
@@ -154,16 +153,26 @@
 #include "s_pointtemp.h"
 
 
-
-void _swrast_add_spec_terms_point( GLcontext *ctx,
-				   const SWvertex *v0 )
+void
+_swrast_add_spec_terms_point(GLcontext *ctx, const SWvertex *v0)
 {
-   SWvertex *ncv0 = (SWvertex *)v0;
-   GLchan c[1][4];
-   COPY_CHAN4( c[0], ncv0->color );
-   ACC_3V( ncv0->color, ncv0->specular );
-   SWRAST_CONTEXT(ctx)->SpecPoint( ctx, ncv0 );
-   COPY_CHAN4( ncv0->color, c[0] );
+   SWvertex *ncv0 = (SWvertex *) v0;
+   GLfloat rSum, gSum, bSum;
+   GLchan cSave[4];
+
+   /* save */
+   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];
+   bSum = CHAN_TO_FLOAT(ncv0->color[2]) + ncv0->attrib[FRAG_ATTRIB_COL1][2];
+   UNCLAMPED_FLOAT_TO_CHAN(ncv0->color[0], rSum);
+   UNCLAMPED_FLOAT_TO_CHAN(ncv0->color[1], gSum);
+   UNCLAMPED_FLOAT_TO_CHAN(ncv0->color[2], bSum);
+   /* draw */
+   SWRAST_CONTEXT(ctx)->SpecPoint(ctx, ncv0);
+   /* restore */
+   COPY_CHAN4(ncv0->color, cSave);
 }
 
 
@@ -196,6 +205,9 @@ _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));
 
    if (ctx->RenderMode==GL_RENDER) {
       if (ctx->Point.PointSprite) {
@@ -242,8 +254,10 @@ _swrast_choose_point( GLcontext *ctx )
             USE(atten_general_ci_point);
          }
       }
-      else if (ctx->Texture._EnabledCoordUnits && rgbMode) {
-         /* textured */
+      else if ((ctx->Texture._EnabledCoordUnits
+                || specular
+                || swrast->_FogEnabled) && rgbMode) {
+         /* textured, fogged */
          USE(textured_rgba_point);
       }
       else if (ctx->Point._Size != 1.0) {
@@ -258,6 +272,7 @@ _swrast_choose_point( GLcontext *ctx )
       else {
          /* single pixel points */
          if (rgbMode) {
+            assert((swrast->_ActiveAttribMask & FRAG_BIT_COL1) == 0);
             USE(size1_rgba_point);
          }
          else {
diff --git a/src/mesa/swrast/s_pointtemp.h b/src/mesa/swrast/s_pointtemp.h
index dddc2f7f40..206085b5b8 100644
--- a/src/mesa/swrast/s_pointtemp.h
+++ b/src/mesa/swrast/s_pointtemp.h
@@ -40,7 +40,6 @@
  *   RGBA = do rgba instead of color index
  *   SMOOTH = do antialiasing
  *   ATTRIBS = general attributes (texcoords, etc)
- *   SPECULAR = do separate specular color
  *   LARGE = do points with diameter > 1 pixel
  *   ATTENUATE = compute point size attenuation
  *   SPRITE = GL_ARB_point_sprite / GL_NV_point_sprite
@@ -78,13 +77,8 @@ NAME ( GLcontext *ctx, const SWvertex *vert )
    const GLchan blue  = vert->color[2];
    const GLchan alpha = vert->color[3];
 #endif
-#if FLAGS & SPECULAR
-   const GLchan specRed   = vert->specular[0];
-   const GLchan specGreen = vert->specular[1];
-   const GLchan specBlue  = vert->specular[2];
-#endif
 #if FLAGS & INDEX
-   const GLuint colorIndex = (GLuint) vert->index; /* XXX round? */
+   const GLuint colorIndex = (GLuint) vert->attrib[FRAG_ATTRIB_CI][0]; /* XXX round? */
 #endif
 #if FLAGS & ATTRIBS
    GLfloat attrib[FRAG_ATTRIB_MAX][4]; /* texture & varying */
@@ -92,10 +86,22 @@ NAME ( GLcontext *ctx, const SWvertex *vert )
    SWcontext *swrast = SWRAST_CONTEXT(ctx);
    SWspan *span = &(swrast->PointSpan);
 
+   /*
+   printf("%s  %g %g %g %g\n", __FUNCTION__,
+          vert->attrib[FRAG_ATTRIB_COL1][0],
+          vert->attrib[FRAG_ATTRIB_COL1][1],
+          vert->attrib[FRAG_ATTRIB_COL1][2],
+          vert->attrib[FRAG_ATTRIB_COL1][3]);
+   if ( vert->attrib[FRAG_ATTRIB_COL1][0] == 0.0 &&
+        vert->attrib[FRAG_ATTRIB_COL1][1] == 1.0 &&
+        vert->attrib[FRAG_ATTRIB_COL1][2] == 0.0)
+      foo();
+   */
+
    /* Cull primitives with malformed coordinates.
     */
    {
-      float tmp = vert->win[0] + vert->win[1];
+      float tmp = vert->attrib[FRAG_ATTRIB_WPOS][0] + vert->attrib[FRAG_ATTRIB_WPOS][1];
       if (IS_INF_OR_NAN(tmp))
 	 return;
    }
@@ -103,49 +109,37 @@ NAME ( GLcontext *ctx, const SWvertex *vert )
    /*
     * Span init
     */
-   span->interpMask = SPAN_FOG;
+   span->interpMask = 0;
    span->arrayMask = SPAN_XY | SPAN_Z;
-   span->attrStart[FRAG_ATTRIB_FOGC][0] = vert->attrib[FRAG_ATTRIB_FOGC][0];
-   span->attrStepX[FRAG_ATTRIB_FOGC][0] = 0.0;
-   span->attrStepY[FRAG_ATTRIB_FOGC][0] = 0.0;
 #if FLAGS & RGBA
    span->arrayMask |= SPAN_RGBA;
 #endif
-#if FLAGS & SPECULAR
-   span->arrayMask |= SPAN_SPEC;
-#endif
 #if FLAGS & INDEX
    span->arrayMask |= SPAN_INDEX;
 #endif
 #if FLAGS & ATTRIBS
-   span->arrayMask |= (SPAN_TEXTURE | SPAN_LAMBDA);
-   if (ctx->FragmentProgram._Active) {
-      /* Don't divide texture s,t,r by q (use TXP to do that) */
-      ATTRIB_LOOP_BEGIN
-         COPY_4V(attrib[attr], vert->attrib[attr]);
-      ATTRIB_LOOP_END
-   }
-   else {
-      /* Divide texture s,t,r by q here */
-      ATTRIB_LOOP_BEGIN
-         const GLfloat q = vert->attrib[attr][3];
-         const GLfloat invQ = (q == 0.0F || q == 1.0F) ? 1.0F : (1.0F / q);
-         attrib[attr][0] = vert->attrib[attr][0] * invQ;
-         attrib[attr][1] = vert->attrib[attr][1] * invQ;
-         attrib[attr][2] = vert->attrib[attr][2] * invQ;
-         attrib[attr][3] = q;
-      ATTRIB_LOOP_END
-   }
+   span->arrayMask |= SPAN_LAMBDA;
+
+   /* we're filling in the attrib arrays: */
+   span->arrayAttribs = swrast->_ActiveAttribMask;
+
+   ATTRIB_LOOP_BEGIN
+      COPY_4V(attrib[attr], vert->attrib[attr]);
+   ATTRIB_LOOP_END
+
    /* 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;
+#else
+   assert((swrast->_ActiveAttribMask & FRAG_BIT_COL1) == 0);
 #endif
+
 #if FLAGS & SMOOTH
    span->arrayMask |= SPAN_COVERAGE;
 #endif
 #if FLAGS & SPRITE
-   span->arrayMask |= (SPAN_TEXTURE | SPAN_LAMBDA);
+   span->arrayMask |= SPAN_LAMBDA;
 #endif
 
    /* Compute point size if not known to be one */
@@ -189,7 +183,7 @@ NAME ( GLcontext *ctx, const SWvertex *vert )
    {{
       GLint x, y;
       const GLfloat radius = 0.5F * size;
-      const GLuint z = (GLuint) (vert->win[2] + 0.5F);
+      const GLuint z = (GLuint) (vert->attrib[FRAG_ATTRIB_WPOS][2] + 0.5F);
       GLuint count;
 #if FLAGS & SMOOTH
       const GLfloat rmin = radius - 0.7071F;  /* 0.7071 = sqrt(2)/2 */
@@ -197,10 +191,10 @@ NAME ( GLcontext *ctx, const SWvertex *vert )
       const GLfloat rmin2 = MAX2(0.0F, rmin * rmin);
       const GLfloat rmax2 = rmax * rmax;
       const GLfloat cscale = 1.0F / (rmax2 - rmin2);
-      const GLint xmin = (GLint) (vert->win[0] - radius);
-      const GLint xmax = (GLint) (vert->win[0] + radius);
-      const GLint ymin = (GLint) (vert->win[1] - radius);
-      const GLint ymax = (GLint) (vert->win[1] + radius);
+      const GLint xmin = (GLint) (vert->attrib[FRAG_ATTRIB_WPOS][0] - radius);
+      const GLint xmax = (GLint) (vert->attrib[FRAG_ATTRIB_WPOS][0] + radius);
+      const GLint ymin = (GLint) (vert->attrib[FRAG_ATTRIB_WPOS][1] - radius);
+      const GLint ymax = (GLint) (vert->attrib[FRAG_ATTRIB_WPOS][1] + radius);
 #else
       /* non-smooth */
       GLint xmin, xmax, ymin, ymax;
@@ -210,16 +204,16 @@ NAME ( GLcontext *ctx, const SWvertex *vert )
       iRadius = iSize / 2;
       if (iSize & 1) {
          /* odd size */
-         xmin = (GLint) (vert->win[0] - iRadius);
-         xmax = (GLint) (vert->win[0] + iRadius);
-         ymin = (GLint) (vert->win[1] - iRadius);
-         ymax = (GLint) (vert->win[1] + iRadius);
+         xmin = (GLint) (vert->attrib[FRAG_ATTRIB_WPOS][0] - iRadius);
+         xmax = (GLint) (vert->attrib[FRAG_ATTRIB_WPOS][0] + iRadius);
+         ymin = (GLint) (vert->attrib[FRAG_ATTRIB_WPOS][1] - iRadius);
+         ymax = (GLint) (vert->attrib[FRAG_ATTRIB_WPOS][1] + iRadius);
       }
       else {
          /* even size */
-         xmin = (GLint) vert->win[0] - iRadius + 1;
+         xmin = (GLint) vert->attrib[FRAG_ATTRIB_WPOS][0] - iRadius + 1;
          xmax = xmin + iSize - 1;
-         ymin = (GLint) vert->win[1] - iRadius + 1;
+         ymin = (GLint) vert->attrib[FRAG_ATTRIB_WPOS][1] - iRadius + 1;
          ymax = ymin + iSize - 1;
       }
 #endif /*SMOOTH*/
@@ -264,29 +258,26 @@ NAME ( GLcontext *ctx, const SWvertex *vert )
             span->array->rgba[count][BCOMP] = blue;
             span->array->rgba[count][ACOMP] = alpha;
 #endif
-#if FLAGS & SPECULAR
-            span->array->spec[count][RCOMP] = specRed;
-            span->array->spec[count][GCOMP] = specGreen;
-            span->array->spec[count][BCOMP] = specBlue;
-#endif
 #if FLAGS & INDEX
             span->array->index[count] = colorIndex;
 #endif
 #if FLAGS & ATTRIBS
             ATTRIB_LOOP_BEGIN
                COPY_4V(span->array->attribs[attr][count], attrib[attr]);
-               if (attr < FRAG_ATTRIB_VAR0 && attr >= FRAG_ATTRIB_TEX0) {
+            /**
+               if (attr < FRAG_ATTRIB_VAR0) {
                   const GLuint u = attr - FRAG_ATTRIB_TEX0;
                   span->array->lambda[u][count] = 0.0;
                }
+            **/
             ATTRIB_LOOP_END
 #endif
 
 #if FLAGS & SMOOTH
             /* compute coverage */
             {
-               const GLfloat dx = x - vert->win[0] + 0.5F;
-               const GLfloat dy = y - vert->win[1] + 0.5F;
+               const GLfloat dx = x - vert->attrib[FRAG_ATTRIB_WPOS][0] + 0.5F;
+               const GLfloat dy = y - vert->attrib[FRAG_ATTRIB_WPOS][1] + 0.5F;
                const GLfloat dist2 = dx * dx + dy * dy;
                if (dist2 < rmax2) {
                   if (dist2 >= rmin2) {
@@ -327,12 +318,12 @@ NAME ( GLcontext *ctx, const SWvertex *vert )
                GLuint attr = FRAG_ATTRIB_TEX0 + u;
                if (ctx->Texture.Unit[u]._ReallyEnabled) {
                   if (ctx->Point.CoordReplace[u]) {
-                     GLfloat s = 0.5F + (x + 0.5F - vert->win[0]) / size;
+                     GLfloat s = 0.5F + (x + 0.5F - vert->attrib[FRAG_ATTRIB_WPOS][0]) / size;
                      GLfloat t, r;
                      if (ctx->Point.SpriteOrigin == GL_LOWER_LEFT)
-                        t = 0.5F + (y + 0.5F - vert->win[1]) / size;
+                        t = 0.5F + (y + 0.5F - vert->attrib[FRAG_ATTRIB_WPOS][1]) / size;
                      else /* GL_UPPER_LEFT */
-                        t = 0.5F - (y + 0.5F - vert->win[1]) / size;
+                        t = 0.5F - (y + 0.5F - vert->attrib[FRAG_ATTRIB_WPOS][1]) / size;
                      if (ctx->Point.SpriteRMode == GL_ZERO)
                         r = 0.0F;
                      else if (ctx->Point.SpriteRMode == GL_S)
@@ -389,11 +380,6 @@ NAME ( GLcontext *ctx, const SWvertex *vert )
       span->array->rgba[count][BCOMP] = blue;
       span->array->rgba[count][ACOMP] = alpha;
 #endif
-#if FLAGS & SPECULAR
-      span->array->spec[count][RCOMP] = specRed;
-      span->array->spec[count][GCOMP] = specGreen;
-      span->array->spec[count][BCOMP] = specBlue;
-#endif
 #if FLAGS & INDEX
       span->array->index[count] = colorIndex;
 #endif
@@ -403,9 +389,10 @@ NAME ( GLcontext *ctx, const SWvertex *vert )
       ATTRIB_LOOP_END
 #endif
 
-      span->array->x[count] = (GLint) vert->win[0];
-      span->array->y[count] = (GLint) vert->win[1];
-      span->array->z[count] = (GLint) (vert->win[2] + 0.5F);
+      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);
+
       span->end = count + 1;
    }}
 
diff --git a/src/mesa/swrast/s_span.c b/src/mesa/swrast/s_span.c
index 097d2c7b51..90a3d5545f 100644
--- a/src/mesa/swrast/s_span.c
+++ b/src/mesa/swrast/s_span.c
@@ -52,53 +52,30 @@
 
 
 /**
- * Init span's Z interpolation values to the RasterPos Z.
- * Used during setup for glDraw/CopyPixels.
+ * Set default fragment attributes for the span using the
+ * current raster values.  Used prior to glDraw/CopyPixels
+ * and glBitmap.
  */
 void
-_swrast_span_default_z( GLcontext *ctx, SWspan *span )
+_swrast_span_default_attribs(GLcontext *ctx, SWspan *span)
 {
-   const GLfloat depthMax = ctx->DrawBuffer->_DepthMaxF;
-   if (ctx->DrawBuffer->Visual.depthBits <= 16)
-      span->z = FloatToFixed(ctx->Current.RasterPos[2] * depthMax + 0.5F);
-   else
-      span->z = (GLint) (ctx->Current.RasterPos[2] * depthMax + 0.5F);
-   span->zStep = 0;
-   span->interpMask |= SPAN_Z;
-}
-
-
-/**
- * Init span's fogcoord interpolation values to the RasterPos fog.
- * Used during setup for glDraw/CopyPixels.
- */
-void
-_swrast_span_default_fog( GLcontext *ctx, SWspan *span )
-{
-   const SWcontext *swrast = SWRAST_CONTEXT(ctx);
-   GLfloat fogVal; /* a coord or a blend factor */
-   if (swrast->_PreferPixelFog) {
-      /* fog blend factors will be computed from fog coordinates per pixel */
-      fogVal = ctx->Current.RasterDistance;
-   }
-   else {
-      /* fog blend factor should be computed from fogcoord now */
-      fogVal = _swrast_z_to_fogfactor(ctx, ctx->Current.RasterDistance);
+   /* Z*/
+   {
+      const GLfloat depthMax = ctx->DrawBuffer->_DepthMaxF;
+      if (ctx->DrawBuffer->Visual.depthBits <= 16)
+         span->z = FloatToFixed(ctx->Current.RasterPos[2] * depthMax + 0.5F);
+      else
+         span->z = (GLint) (ctx->Current.RasterPos[2] * depthMax + 0.5F);
+      span->zStep = 0;
+      span->interpMask |= SPAN_Z;
    }
-   span->attrStart[FRAG_ATTRIB_FOGC][0] = fogVal;
-   span->attrStepX[FRAG_ATTRIB_FOGC][0] = 0.0;
-   span->attrStepY[FRAG_ATTRIB_FOGC][0] = 0.0;
-   span->interpMask |= SPAN_FOG;
-}
 
+   /* W (for perspective correction) */
+   span->attrStart[FRAG_ATTRIB_WPOS][3] = 1.0;
+   span->attrStepX[FRAG_ATTRIB_WPOS][3] = 0.0;
+   span->attrStepY[FRAG_ATTRIB_WPOS][3] = 0.0;
 
-/**
- * Init span's rgba or index interpolation values to the RasterPos color.
- * Used during setup for glDraw/CopyPixels.
- */
-void
-_swrast_span_default_color( GLcontext *ctx, SWspan *span )
-{
+   /* primary color, or color index */
    if (ctx->Visual.rgbMode) {
       GLchan r, g, b, a;
       UNCLAMPED_FLOAT_TO_CHAN(r, ctx->Current.RasterColor[0]);
@@ -121,97 +98,129 @@ _swrast_span_default_color( GLcontext *ctx, SWspan *span )
       span->blueStep = 0;
       span->alphaStep = 0;
       span->interpMask |= SPAN_RGBA;
+
+      COPY_4V(span->attrStart[FRAG_ATTRIB_COL0], ctx->Current.RasterColor);
+      ASSIGN_4V(span->attrStepX[FRAG_ATTRIB_COL0], 0.0, 0.0, 0.0, 0.0);
+      ASSIGN_4V(span->attrStepY[FRAG_ATTRIB_COL0], 0.0, 0.0, 0.0, 0.0);
    }
    else {
       span->index = FloatToFixed(ctx->Current.RasterIndex);
       span->indexStep = 0;
       span->interpMask |= SPAN_INDEX;
    }
-}
-
 
-/**
- * Set the span's secondary color info to the current raster position's
- * secondary color, when needed (lighting enabled or colorsum enabled).
- */
-void
-_swrast_span_default_secondary_color(GLcontext *ctx, SWspan *span)
-{
+   /* Secondary color */
    if (ctx->Visual.rgbMode && (ctx->Light.Enabled || ctx->Fog.ColorSumEnabled))
    {
-      GLchan r, g, b, a;
-      UNCLAMPED_FLOAT_TO_CHAN(r, ctx->Current.RasterSecondaryColor[0]);
-      UNCLAMPED_FLOAT_TO_CHAN(g, ctx->Current.RasterSecondaryColor[1]);
-      UNCLAMPED_FLOAT_TO_CHAN(b, ctx->Current.RasterSecondaryColor[2]);
-      UNCLAMPED_FLOAT_TO_CHAN(a, ctx->Current.RasterSecondaryColor[3]);
-#if CHAN_TYPE == GL_FLOAT
-      span->specRed = r;
-      span->specGreen = g;
-      span->specBlue = b;
-      /*span->specAlpha = a;*/
-#else
-      span->specRed   = IntToFixed(r);
-      span->specGreen = IntToFixed(g);
-      span->specBlue  = IntToFixed(b);
-      /*span->specAlpha = IntToFixed(a);*/
-#endif
-      span->specRedStep = 0;
-      span->specGreenStep = 0;
-      span->specBlueStep = 0;
-      /*span->specAlphaStep = 0;*/
-      span->interpMask |= SPAN_SPEC;
+      COPY_4V(span->attrStart[FRAG_ATTRIB_COL1], ctx->Current.RasterSecondaryColor);
+      ASSIGN_4V(span->attrStepX[FRAG_ATTRIB_COL1], 0.0, 0.0, 0.0, 0.0);
+      ASSIGN_4V(span->attrStepY[FRAG_ATTRIB_COL1], 0.0, 0.0, 0.0, 0.0);
+   }
+
+   /* fog */
+   {
+      const SWcontext *swrast = SWRAST_CONTEXT(ctx);
+      GLfloat fogVal; /* a coord or a blend factor */
+      if (swrast->_PreferPixelFog) {
+         /* fog blend factors will be computed from fog coordinates per pixel */
+         fogVal = ctx->Current.RasterDistance;
+      }
+      else {
+         /* fog blend factor should be computed from fogcoord now */
+         fogVal = _swrast_z_to_fogfactor(ctx, ctx->Current.RasterDistance);
+      }
+      span->attrStart[FRAG_ATTRIB_FOGC][0] = fogVal;
+      span->attrStepX[FRAG_ATTRIB_FOGC][0] = 0.0;
+      span->attrStepY[FRAG_ATTRIB_FOGC][0] = 0.0;
+   }
+
+   /* texcoords */
+   {
+      GLuint i;
+      for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) {
+         const GLuint attr = FRAG_ATTRIB_TEX0 + i;
+         const GLfloat *tc = ctx->Current.RasterTexCoords[i];
+         if (ctx->FragmentProgram._Current || ctx->ATIFragmentShader._Enabled) {
+            COPY_4V(span->attrStart[attr], tc);
+         }
+         else if (tc[3] > 0.0F) {
+            /* use (s/q, t/q, r/q, 1) */
+            span->attrStart[attr][0] = tc[0] / tc[3];
+            span->attrStart[attr][1] = tc[1] / tc[3];
+            span->attrStart[attr][2] = tc[2] / tc[3];
+            span->attrStart[attr][3] = 1.0;
+         }
+         else {
+            ASSIGN_4V(span->attrStart[attr], 0.0F, 0.0F, 0.0F, 1.0F);
+         }
+         ASSIGN_4V(span->attrStepX[attr], 0.0F, 0.0F, 0.0F, 0.0F);
+         ASSIGN_4V(span->attrStepY[attr], 0.0F, 0.0F, 0.0F, 0.0F);
+      }
    }
 }
 
 
 /**
- * Init span's texcoord interpolation values to the RasterPos texcoords.
- * Used during setup for glDraw/CopyPixels.
+ * Interpolate the active attributes (and'd with attrMask) to
+ * fill in span->array->attribs[].
+ * Perspective correction will be done.  The point/line/triangle function
+ * should have computed attrStart/Step values for FRAG_ATTRIB_WPOS[3]!
  */
-void
-_swrast_span_default_texcoords( GLcontext *ctx, SWspan *span )
+static INLINE void
+interpolate_active_attribs(GLcontext *ctx, SWspan *span, GLbitfield attrMask)
 {
-   GLuint i;
-   for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) {
-      const GLuint attr = FRAG_ATTRIB_TEX0 + i;
-      const GLfloat *tc = ctx->Current.RasterTexCoords[i];
-      if (ctx->FragmentProgram._Current || ctx->ATIFragmentShader._Enabled) {
-         COPY_4V(span->attrStart[attr], tc);
-      }
-      else if (tc[3] > 0.0F) {
-         /* use (s/q, t/q, r/q, 1) */
-         span->attrStart[attr][0] = tc[0] / tc[3];
-         span->attrStart[attr][1] = tc[1] / tc[3];
-         span->attrStart[attr][2] = tc[2] / tc[3];
-         span->attrStart[attr][3] = 1.0;
-      }
-      else {
-         ASSIGN_4V(span->attrStart[attr], 0.0F, 0.0F, 0.0F, 1.0F);
+   const SWcontext *swrast = SWRAST_CONTEXT(ctx);
+
+   ATTRIB_LOOP_BEGIN
+      if (attrMask & (1 << attr)) {
+         const GLfloat dwdx = span->attrStepX[FRAG_ATTRIB_WPOS][3];
+         GLfloat w = span->attrStart[FRAG_ATTRIB_WPOS][3];
+         const GLfloat dv0dx = span->attrStepX[attr][0];
+         const GLfloat dv1dx = span->attrStepX[attr][1];
+         const GLfloat dv2dx = span->attrStepX[attr][2];
+         const GLfloat dv3dx = span->attrStepX[attr][3];
+         GLfloat v0 = span->attrStart[attr][0];
+         GLfloat v1 = span->attrStart[attr][1];
+         GLfloat v2 = span->attrStart[attr][2];
+         GLfloat v3 = span->attrStart[attr][3];
+         GLuint k;
+         for (k = 0; k < span->end; k++) {
+            const GLfloat invW = 1.0f / w;
+            span->array->attribs[attr][k][0] = v0 * invW;
+            span->array->attribs[attr][k][1] = v1 * invW;
+            span->array->attribs[attr][k][2] = v2 * invW;
+            span->array->attribs[attr][k][3] = v3 * invW;
+            v0 += dv0dx;
+            v1 += dv1dx;
+            v2 += dv2dx;
+            v3 += dv3dx;
+            w += dwdx;
+         }
+         span->arrayAttribs |= (1 << attr);
       }
-      ASSIGN_4V(span->attrStepX[attr], 0.0F, 0.0F, 0.0F, 0.0F);
-      ASSIGN_4V(span->attrStepY[attr], 0.0F, 0.0F, 0.0F, 0.0F);
-   }
-   span->interpMask |= SPAN_TEXTURE;
+   ATTRIB_LOOP_END
 }
 
 
 /**
- * Interpolate primary colors to fill in the span->array->color array.
+ * Interpolate primary colors to fill in the span->array->rgba8 (or rgb16)
+ * color array.
  */
 static INLINE void
-interpolate_colors(SWspan *span)
+interpolate_int_colors(GLcontext *ctx, SWspan *span)
 {
    const GLuint n = span->end;
    GLuint i;
 
-   ASSERT((span->interpMask & SPAN_RGBA)  &&
-          !(span->arrayMask & SPAN_RGBA));
+#if CHAN_BITS != 32
+   ASSERT(!(span->arrayMask & SPAN_RGBA));
+#endif
 
    switch (span->array->ChanType) {
 #if CHAN_BITS != 32
    case GL_UNSIGNED_BYTE:
       {
-         GLubyte (*rgba)[4] = span->array->color.sz1.rgba;
+         GLubyte (*rgba)[4] = span->array->rgba8;
          if (span->interpMask & SPAN_FLAT) {
             GLubyte color[4];
             color[RCOMP] = FixedToInt(span->red);
@@ -246,7 +255,7 @@ interpolate_colors(SWspan *span)
       break;
    case GL_UNSIGNED_SHORT:
       {
-         GLushort (*rgba)[4] = span->array->color.sz2.rgba;
+         GLushort (*rgba)[4] = span->array->rgba16;
          if (span->interpMask & SPAN_FLAT) {
             GLushort color[4];
             color[RCOMP] = FixedToInt(span->red);
@@ -258,7 +267,7 @@ interpolate_colors(SWspan *span)
             }
          }
          else {
-            GLushort (*rgba)[4] = span->array->color.sz2.rgba;
+            GLushort (*rgba)[4] = span->array->rgba16;
             GLfixed r, g, b, a;
             GLint dr, dg, db, da;
             r = span->red;
@@ -284,162 +293,76 @@ interpolate_colors(SWspan *span)
       break;
 #endif
    case GL_FLOAT:
-      {
-         GLfloat (*rgba)[4] = span->array->attribs[FRAG_ATTRIB_COL0];
-         GLfloat r, g, b, a, dr, dg, db, da;
-         r = span->red;
-         g = span->green;
-         b = span->blue;
-         a = span->alpha;
-         if (span->interpMask & SPAN_FLAT) {
-            dr = dg = db = da = 0.0;
-         }
-         else {
-            dr = span->redStep;
-            dg = span->greenStep;
-            db = span->blueStep;
-            da = span->alphaStep;
-         }
-         for (i = 0; i < n; i++) {
-            rgba[i][RCOMP] = r;
-            rgba[i][GCOMP] = g;
-            rgba[i][BCOMP] = b;
-            rgba[i][ACOMP] = a;
-            r += dr;
-            g += dg;
-            b += db;
-            a += da;
-         }
-      }
+      interpolate_active_attribs(ctx, span, FRAG_BIT_COL0);
       break;
    default:
-      _mesa_problem(NULL, "bad datatype in interpolate_colors");
+      _mesa_problem(NULL, "bad datatype in interpolate_int_colors");
    }
    span->arrayMask |= SPAN_RGBA;
 }
 
 
 /**
- * Interpolate specular/secondary colors.
+ * Populate the FRAG_ATTRIB_COL0 array.
  */
 static INLINE void
-interpolate_specular(SWspan *span)
+interpolate_float_colors(SWspan *span)
 {
+   GLfloat (*col0)[4] = span->array->attribs[FRAG_ATTRIB_COL0];
    const GLuint n = span->end;
    GLuint i;
 
-   switch (span->array->ChanType) {
-#if CHAN_BITS != 32
-   case GL_UNSIGNED_BYTE:
-      {
-         GLubyte (*spec)[4] = span->array->color.sz1.spec;
-         if (span->interpMask & SPAN_FLAT) {
-            GLubyte color[4];
-            color[RCOMP] = FixedToInt(span->specRed);
-            color[GCOMP] = FixedToInt(span->specGreen);
-            color[BCOMP] = FixedToInt(span->specBlue);
-            color[ACOMP] = 0;
-            for (i = 0; i < n; i++) {
-               COPY_4UBV(spec[i], color);
-            }
-         }
-         else {
-            GLfixed r = span->specRed;
-            GLfixed g = span->specGreen;
-            GLfixed b = span->specBlue;
-            GLint dr = span->specRedStep;
-            GLint dg = span->specGreenStep;
-            GLint db = span->specBlueStep;
-            for (i = 0; i < n; i++) {
-               spec[i][RCOMP] = CLAMP(FixedToChan(r), 0, 255);
-               spec[i][GCOMP] = CLAMP(FixedToChan(g), 0, 255);
-               spec[i][BCOMP] = CLAMP(FixedToChan(b), 0, 255);
-               spec[i][ACOMP] = 0;
-               r += dr;
-               g += dg;
-               b += db;
-            }
-         }
+   assert(!(span->arrayAttribs & FRAG_BIT_COL0));
+
+   if (span->arrayMask & SPAN_RGBA) {
+      /* convert array of int colors */
+      for (i = 0; i < n; i++) {
+         col0[i][0] = UBYTE_TO_FLOAT(span->array->rgba8[i][0]);
+         col0[i][1] = UBYTE_TO_FLOAT(span->array->rgba8[i][1]);
+         col0[i][2] = UBYTE_TO_FLOAT(span->array->rgba8[i][2]);
+         col0[i][3] = UBYTE_TO_FLOAT(span->array->rgba8[i][3]);
       }
-      break;
-   case GL_UNSIGNED_SHORT:
-      {
-         GLushort (*spec)[4] = span->array->color.sz2.spec;
-         if (span->interpMask & SPAN_FLAT) {
-            GLushort color[4];
-            color[RCOMP] = FixedToInt(span->specRed);
-            color[GCOMP] = FixedToInt(span->specGreen);
-            color[BCOMP] = FixedToInt(span->specBlue);
-            color[ACOMP] = 0;
-            for (i = 0; i < n; i++) {
-               COPY_4V(spec[i], color);
-            }
-         }
-         else {
-            GLfixed r = FloatToFixed(span->specRed);
-            GLfixed g = FloatToFixed(span->specGreen);
-            GLfixed b = FloatToFixed(span->specBlue);
-            GLint dr = FloatToFixed(span->specRedStep);
-            GLint dg = FloatToFixed(span->specGreenStep);
-            GLint db = FloatToFixed(span->specBlueStep);
-            for (i = 0; i < n; i++) {
-               spec[i][RCOMP] = FixedToInt(r);
-               spec[i][GCOMP] = FixedToInt(g);
-               spec[i][BCOMP] = FixedToInt(b);
-               spec[i][ACOMP] = 0;
-               r += dr;
-               g += dg;
-               b += db;
-            }
+   }
+   else {
+      /* interpolate red/green/blue/alpha to get float colors */
+      ASSERT(span->interpMask & SPAN_RGBA);
+      if (span->interpMask & SPAN_FLAT) {
+         GLfloat r = FixedToFloat(span->red);
+         GLfloat g = FixedToFloat(span->green);
+         GLfloat b = FixedToFloat(span->blue);
+         GLfloat a = FixedToFloat(span->alpha);
+         for (i = 0; i < n; i++) {
+            ASSIGN_4V(col0[i], r, g, b, a);
          }
       }
-      break;
-#endif
-   case GL_FLOAT:
-      {
-         GLfloat (*spec)[4] = span->array->attribs[FRAG_ATTRIB_COL1];
-#if CHAN_BITS <= 16
-         GLfloat r = CHAN_TO_FLOAT(FixedToChan(span->specRed));
-         GLfloat g = CHAN_TO_FLOAT(FixedToChan(span->specGreen));
-         GLfloat b = CHAN_TO_FLOAT(FixedToChan(span->specBlue));
-#else
-         GLfloat r = span->specRed;
-         GLfloat g = span->specGreen;
-         GLfloat b = span->specBlue;
-#endif
-         GLfloat dr, dg, db;
-         if (span->interpMask & SPAN_FLAT) {
-            dr = dg = db = 0.0;
-         }
-         else {
-#if CHAN_BITS <= 16
-            dr = CHAN_TO_FLOAT(FixedToChan(span->specRedStep));
-            dg = CHAN_TO_FLOAT(FixedToChan(span->specGreenStep));
-            db = CHAN_TO_FLOAT(FixedToChan(span->specBlueStep));
-#else
-            dr = span->specRedStep;
-            dg = span->specGreenStep;
-            db = span->specBlueStep;
-#endif
-         }
+      else {
+         GLfloat r = FixedToFloat(span->red);
+         GLfloat g = FixedToFloat(span->green);
+         GLfloat b = FixedToFloat(span->blue);
+         GLfloat a = FixedToFloat(span->alpha);
+         GLfloat dr = FixedToFloat(span->redStep);
+         GLfloat dg = FixedToFloat(span->greenStep);
+         GLfloat db = FixedToFloat(span->blueStep);
+         GLfloat da = FixedToFloat(span->alphaStep);
          for (i = 0; i < n; i++) {
-            spec[i][RCOMP] = r;
-            spec[i][GCOMP] = g;
-            spec[i][BCOMP] = b;
-            spec[i][ACOMP] = 0.0F;
+            col0[i][0] = r;
+            col0[i][1] = g;
+            col0[i][2] = b;
+            col0[i][3] = a;
             r += dr;
             g += dg;
             b += db;
+            a += da;
          }
       }
-      break;
-   default:
-      _mesa_problem(NULL, "bad datatype in interpolate_specular");
    }
-   span->arrayMask |= SPAN_SPEC;
+
+   span->arrayAttribs |= FRAG_BIT_COL0;
+   span->array->ChanType = GL_FLOAT;
 }
 
 
+
 /* Fill in the span.color.index array from the interpolation values */
 static INLINE void
 interpolate_indexes(GLcontext *ctx, SWspan *span)
@@ -450,8 +373,8 @@ interpolate_indexes(GLcontext *ctx, SWspan *span)
    GLuint *indexes = span->array->index;
    GLuint i;
    (void) ctx;
-   ASSERT((span->interpMask & SPAN_INDEX)  &&
-	  !(span->arrayMask & SPAN_INDEX));
+
+   ASSERT(!(span->arrayMask & SPAN_INDEX));
 
    if ((span->interpMask & SPAN_FLAT) || (indexStep == 0)) {
       /* constant color */
@@ -472,35 +395,16 @@ interpolate_indexes(GLcontext *ctx, SWspan *span)
 }
 
 
-/* Fill in the span.array.fog values from the interpolation values */
-static INLINE void
-interpolate_fog(const GLcontext *ctx, SWspan *span)
-{
-   GLfloat (*fog)[4] = span->array->attribs[FRAG_ATTRIB_FOGC];
-   const GLfloat fogStep = span->attrStepX[FRAG_ATTRIB_FOGC][0];
-   GLfloat fogCoord = span->attrStart[FRAG_ATTRIB_FOGC][0];
-   const GLuint haveW = (span->interpMask & SPAN_W);
-   const GLfloat wStep = haveW ? span->attrStepX[FRAG_ATTRIB_WPOS][3] : 0.0F;
-   GLfloat w = haveW ? span->attrStart[FRAG_ATTRIB_WPOS][3] : 1.0F;
-   GLuint i;
-   for (i = 0; i < span->end; i++) {
-      fog[i][0] = fogCoord / w;
-      fogCoord += fogStep;
-      w += wStep;
-   }
-   span->arrayMask |= SPAN_FOG;
-}
-
-
-/* Fill in the span.zArray array from the interpolation values */
+/**
+ * Fill in the span.zArray array from the span->z, zStep values.
+ */
 void
 _swrast_span_interpolate_z( const GLcontext *ctx, SWspan *span )
 {
    const GLuint n = span->end;
    GLuint i;
 
-   ASSERT((span->interpMask & SPAN_Z)  &&
-	  !(span->arrayMask & SPAN_Z));
+   ASSERT(!(span->arrayMask & SPAN_Z));
 
    if (ctx->DrawBuffer->Visual.depthBits <= 16) {
       GLfixed zval = span->z;
@@ -524,7 +428,8 @@ _swrast_span_interpolate_z( const GLcontext *ctx, SWspan *span )
 }
 
 
-/*
+/**
+ * Compute mipmap LOD from partial derivatives.
  * This the ideal solution, as given in the OpenGL spec.
  */
 #if 0
@@ -546,8 +451,9 @@ compute_lambda(GLfloat dsdx, GLfloat dsdy, GLfloat dtdx, GLfloat dtdy,
 #endif
 
 
-/*
- * This is a faster approximation
+/**
+ * Compute mipmap LOD from partial derivatives.
+ * This is a faster approximation than above function.
  */
 GLfloat
 _swrast_compute_lambda(GLfloat dsdx, GLfloat dsdy, GLfloat dtdx, GLfloat dtdy,
@@ -572,14 +478,15 @@ _swrast_compute_lambda(GLfloat dsdx, GLfloat dsdy, GLfloat dtdx, GLfloat dtdy,
 
 
 /**
- * Fill in the span.texcoords array from the interpolation values.
+ * Fill in the span.array->attrib[FRAG_ATTRIB_TEXn] arrays from the
+ * using the attrStart/Step values.
+ *
+ * This function only used during fixed-function fragment processing.
+ *
  * Note: in the places where we divide by Q (or mult by invQ) we're
  * really doing two things: perspective correction and texcoord
  * projection.  Remember, for texcoord (s,t,r,q) we need to index
  * texels with (s/q, t/q, r/q).
- * If we're using a fragment program, we never do the division
- * for texcoord projection.  That's done by the TXP instruction
- * or user-written code.
  */
 static void
 interpolate_texcoords(GLcontext *ctx, SWspan *span)
@@ -588,11 +495,6 @@ interpolate_texcoords(GLcontext *ctx, SWspan *span)
       = (ctx->Texture._EnabledCoordUnits > 1) ? ctx->Const.MaxTextureUnits : 1;
    GLuint u;
 
-   ASSERT(span->interpMask & SPAN_TEXTURE);
-   ASSERT(!(span->arrayMask & SPAN_TEXTURE));
-
-   span->arrayMask |= SPAN_TEXTURE;
-
    /* XXX CoordUnits vs. ImageUnits */
    for (u = 0; u < maxUnit; u++) {
       if (ctx->Texture._EnabledCoordUnits & (1 << u)) {
@@ -724,55 +626,6 @@ interpolate_texcoords(GLcontext *ctx, SWspan *span)
 }
 
 
-
-/**
- * Fill in the arrays->attribs[FRAG_ATTRIB_VARx] arrays from the
- * interpolation values.
- * XXX since interpolants/arrays are getting uniformed, we might merge
- * this with interpolate_texcoords(), interpolate_Fog(), etc. someday.
- */
-static INLINE void
-interpolate_varying(GLcontext *ctx, SWspan *span)
-{
-   GLuint var;
-   const GLbitfield inputsUsed = ctx->FragmentProgram._Current->Base.InputsRead;
-
-   ASSERT(span->interpMask & SPAN_VARYING);
-   ASSERT(!(span->arrayMask & SPAN_VARYING));
-
-   span->arrayMask |= SPAN_VARYING;
-
-   for (var = 0; var < MAX_VARYING; var++) {
-      if (inputsUsed & FRAG_BIT_VAR(var)) {
-         const GLuint attr = FRAG_ATTRIB_VAR0 + var;
-         const GLfloat dwdx = span->attrStepX[FRAG_ATTRIB_WPOS][3];
-         GLfloat w = span->attrStart[FRAG_ATTRIB_WPOS][3];
-         const GLfloat dv0dx = span->attrStepX[attr][0];
-         const GLfloat dv1dx = span->attrStepX[attr][1];
-         const GLfloat dv2dx = span->attrStepX[attr][2];
-         const GLfloat dv3dx = span->attrStepX[attr][3];
-         GLfloat v0 = span->attrStart[attr][0];
-         GLfloat v1 = span->attrStart[attr][1];
-         GLfloat v2 = span->attrStart[attr][2];
-         GLfloat v3 = span->attrStart[attr][3];
-         GLuint k;
-         for (k = 0; k < span->end; k++) {
-            GLfloat invW = 1.0f / w;
-            span->array->attribs[attr][k][0] = v0 * invW;
-            span->array->attribs[attr][k][1] = v1 * invW;
-            span->array->attribs[attr][k][2] = v2 * invW;
-            span->array->attribs[attr][k][3] = v3 * invW;
-            v0 += dv0dx;
-            v1 += dv1dx;
-            v2 += dv2dx;
-            v3 += dv3dx;
-            w += dwdx;
-         }
-      }
-   }
-}
-
-
 /**
  * Fill in the arrays->attribs[FRAG_ATTRIB_WPOS] array.
  */
@@ -934,7 +787,9 @@ _swrast_write_index_span( GLcontext *ctx, SWspan *span)
    ASSERT(span->primitive == GL_POINT  ||  span->primitive == GL_LINE ||
 	  span->primitive == GL_POLYGON  ||  span->primitive == GL_BITMAP);
    ASSERT((span->interpMask | span->arrayMask) & SPAN_INDEX);
+   /*
    ASSERT((span->interpMask & span->arrayMask) == 0);
+   */
 
    if (span->arrayMask & SPAN_MASK) {
       /* mask was initialized by caller, probably glBitmap */
@@ -981,7 +836,7 @@ _swrast_write_index_span( GLcontext *ctx, SWspan *span)
 
    /* Stencil and Z testing */
    if (ctx->Depth.Test || ctx->Stencil.Enabled) {
-      if (span->interpMask & SPAN_Z)
+      if (!(span->arrayMask & SPAN_Z))
          _swrast_span_interpolate_z(ctx, span);
 
       if (ctx->Stencil.Enabled) {
@@ -1022,7 +877,7 @@ _swrast_write_index_span( GLcontext *ctx, SWspan *span)
        ctx->Color.IndexLogicOpEnabled ||
        ctx->Color.IndexMask != 0xffffffff ||
        (span->arrayMask & SPAN_COVERAGE)) {
-      if (span->interpMask & SPAN_INDEX) {
+      if (!(span->arrayMask & SPAN_INDEX) /*span->interpMask & SPAN_INDEX*/) {
          interpolate_indexes(ctx, span);
       }
    }
@@ -1071,7 +926,7 @@ _swrast_write_index_span( GLcontext *ctx, SWspan *span)
             _swrast_mask_ci_span(ctx, rb, span);
          }
 
-         if ((span->interpMask & SPAN_INDEX) && span->indexStep == 0) {
+         if (!(span->arrayMask & SPAN_INDEX) && span->indexStep == 0) {
             /* all fragments have same color index */
             GLubyte index8;
             GLushort index16;
@@ -1151,63 +1006,52 @@ _swrast_write_index_span( GLcontext *ctx, SWspan *span)
 
 
 /**
- * Add specular color to base color.  This is used only when
- * GL_LIGHT_MODEL_COLOR_CONTROL = GL_SEPARATE_SPECULAR_COLOR.
+ * Add specular colors to primary colors.
+ * Only called during fixed-function operation.
+ * Result is float color array (FRAG_ATTRIB_COL0).
  */
 static INLINE void
 add_specular(GLcontext *ctx, SWspan *span)
 {
-   switch (span->array->ChanType) {
-   case GL_UNSIGNED_BYTE:
-      {
-         GLubyte (*rgba)[4] = span->array->color.sz1.rgba;
-         GLubyte (*spec)[4] = span->array->color.sz1.spec;
-         GLuint i;
-         for (i = 0; i < span->end; i++) {
-            GLint r = rgba[i][RCOMP] + spec[i][RCOMP];
-            GLint g = rgba[i][GCOMP] + spec[i][GCOMP];
-            GLint b = rgba[i][BCOMP] + spec[i][BCOMP];
-            GLint a = rgba[i][ACOMP] + spec[i][ACOMP];
-            rgba[i][RCOMP] = MIN2(r, 255);
-            rgba[i][GCOMP] = MIN2(g, 255);
-            rgba[i][BCOMP] = MIN2(b, 255);
-            rgba[i][ACOMP] = MIN2(a, 255);
-         }
+   const SWcontext *swrast = SWRAST_CONTEXT(ctx);
+   const GLubyte *mask = span->array->mask;
+   GLfloat (*col0)[4] = span->array->attribs[FRAG_ATTRIB_COL0];
+   GLfloat (*col1)[4] = span->array->attribs[FRAG_ATTRIB_COL1];
+   GLuint i;
+
+   ASSERT(!ctx->FragmentProgram._Current);
+   ASSERT(span->arrayMask & SPAN_RGBA);
+   ASSERT(swrast->_ActiveAttribMask & FRAG_BIT_COL1);
+
+   if (span->array->ChanType == GL_FLOAT) {
+      if ((span->arrayAttribs & FRAG_BIT_COL0) == 0) {
+         interpolate_active_attribs(ctx, span, FRAG_BIT_COL0);
       }
-      break;
-   case GL_UNSIGNED_SHORT:
-      {
-         GLushort (*rgba)[4] = span->array->color.sz2.rgba;
-         GLushort (*spec)[4] = span->array->color.sz2.spec;
-         GLuint i;
-         for (i = 0; i < span->end; i++) {
-            GLint r = rgba[i][RCOMP] + spec[i][RCOMP];
-            GLint g = rgba[i][GCOMP] + spec[i][GCOMP];
-            GLint b = rgba[i][BCOMP] + spec[i][BCOMP];
-            GLint a = rgba[i][ACOMP] + spec[i][ACOMP];
-            rgba[i][RCOMP] = MIN2(r, 65535);
-            rgba[i][GCOMP] = MIN2(g, 65535);
-            rgba[i][BCOMP] = MIN2(b, 65535);
-            rgba[i][ACOMP] = MIN2(a, 65535);
-         }
+   }
+   else {
+      /* need float colors */
+      if ((span->arrayAttribs & FRAG_BIT_COL0) == 0) {
+         interpolate_float_colors(span);
       }
-      break;
-   case GL_FLOAT:
-      {
-         GLfloat (*rgba)[4] = span->array->attribs[FRAG_ATTRIB_COL0];
-         GLfloat (*spec)[4] = span->array->attribs[FRAG_ATTRIB_COL1];
-         GLuint i;
-         for (i = 0; i < span->end; i++) {
-            rgba[i][RCOMP] += spec[i][RCOMP];
-            rgba[i][GCOMP] += spec[i][GCOMP];
-            rgba[i][BCOMP] += spec[i][BCOMP];
-            rgba[i][ACOMP] += spec[i][ACOMP];
-         }
+   }
+
+   if ((span->arrayAttribs & FRAG_BIT_COL1) == 0) {
+      /* XXX could avoid this and interpolate COL1 in the loop below */
+      interpolate_active_attribs(ctx, span, FRAG_BIT_COL1);
+   }
+
+   ASSERT(span->arrayAttribs & FRAG_BIT_COL0);
+   ASSERT(span->arrayAttribs & FRAG_BIT_COL1);
+
+   for (i = 0; i < span->end; i++) {
+      if (mask[i]) {
+         col0[i][0] += col1[i][0];
+         col0[i][1] += col1[i][1];
+         col0[i][2] += col1[i][2];
       }
-      break;
-   default:
-      _mesa_problem(ctx, "Invalid datatype in add_specular");
    }
+
+   span->array->ChanType = GL_FLOAT;
 }
 
 
@@ -1220,7 +1064,7 @@ apply_aa_coverage(SWspan *span)
    const GLfloat *coverage = span->array->coverage;
    GLuint i;
    if (span->array->ChanType == GL_UNSIGNED_BYTE) {
-      GLubyte (*rgba)[4] = span->array->color.sz1.rgba;
+      GLubyte (*rgba)[4] = span->array->rgba8;
       for (i = 0; i < span->end; i++) {
          const GLfloat a = rgba[i][ACOMP] * coverage[i];
          rgba[i][ACOMP] = (GLubyte) CLAMP(a, 0.0, 255.0);
@@ -1229,7 +1073,7 @@ apply_aa_coverage(SWspan *span)
       }
    }
    else if (span->array->ChanType == GL_UNSIGNED_SHORT) {
-      GLushort (*rgba)[4] = span->array->color.sz2.rgba;
+      GLushort (*rgba)[4] = span->array->rgba16;
       for (i = 0; i < span->end; i++) {
          const GLfloat a = rgba[i][ACOMP] * coverage[i];
          rgba[i][ACOMP] = (GLushort) CLAMP(a, 0.0, 65535.0);
@@ -1239,6 +1083,7 @@ apply_aa_coverage(SWspan *span)
       GLfloat (*rgba)[4] = span->array->attribs[FRAG_ATTRIB_COL0];
       for (i = 0; i < span->end; i++) {
          rgba[i][ACOMP] = rgba[i][ACOMP] * coverage[i];
+         /* clamp later */
       }
    }
 }
@@ -1278,18 +1123,18 @@ convert_color_type(SWspan *span, GLenum newType, GLuint output)
       span->array->ChanType = GL_FLOAT;
    }
    else if (span->array->ChanType == GL_UNSIGNED_BYTE) {
-      src = span->array->color.sz1.rgba;
+      src = span->array->rgba8;
    }
    else {
       ASSERT(span->array->ChanType == GL_UNSIGNED_SHORT);
-      src = span->array->color.sz2.rgba;
+      src = span->array->rgba16;
    }
 
    if (newType == GL_UNSIGNED_BYTE) {
-      dst = span->array->color.sz1.rgba;
+      dst = span->array->rgba8;
    }
    else if (newType == GL_UNSIGNED_SHORT) {
-      dst = span->array->color.sz2.rgba;
+      dst = span->array->rgba16;
    }
    else {
       dst = span->array->attribs[FRAG_ATTRIB_COL0];
@@ -1321,42 +1166,16 @@ shade_texture_span(GLcontext *ctx, SWspan *span)
       inputsRead = ~0;
    }
 
-   if ((inputsRead & FRAG_BIT_COL0) && (span->interpMask & SPAN_RGBA))
-      interpolate_colors(span);
-
-   if (ctx->Texture._EnabledCoordUnits && (span->interpMask & SPAN_TEXTURE))
-      interpolate_texcoords(ctx, span);
-
    if (ctx->FragmentProgram._Current ||
        ctx->ATIFragmentShader._Enabled) {
-      /* use float colors if running a fragment program or shader */
-      const GLenum oldType = span->array->ChanType;
-      const GLenum newType = GL_FLOAT;
-
-      if ((inputsRead & FRAG_BIT_COL0) && (oldType != newType)) {
-         GLvoid *src = (oldType == GL_UNSIGNED_BYTE)
-            ? (GLvoid *) span->array->color.sz1.rgba
-            : (GLvoid *) span->array->color.sz2.rgba;
-         assert(span->arrayMask & SPAN_RGBA);
-         _mesa_convert_colors(oldType, src,
-                              newType, span->array->attribs[FRAG_ATTRIB_COL0],
-                              span->end, span->array->mask);
-      }
-      span->array->ChanType = newType;
-
-      /* fragment programs/shaders may need specular, fog and Z coords */
-      if ((inputsRead & FRAG_BIT_COL1) && (span->interpMask & SPAN_SPEC))
-         interpolate_specular(span);
+      /* programmable shading */
+      span->array->ChanType = GL_FLOAT;
 
-      if ((inputsRead & FRAG_BIT_FOGC) && (span->interpMask & SPAN_FOG))
-         interpolate_fog(ctx, span);
+      interpolate_active_attribs(ctx, span, ~0);
 
-      if (span->interpMask & SPAN_Z)
+      if (!(span->arrayMask & SPAN_Z))
          _swrast_span_interpolate_z (ctx, span);
 
-      if ((inputsRead >= FRAG_BIT_VAR0) && (span->interpMask & SPAN_VARYING))
-         interpolate_varying(ctx, span);
-
 #if 0
       if (inputsRead & FRAG_BIT_WPOS)
 #else
@@ -1373,8 +1192,20 @@ shade_texture_span(GLcontext *ctx, SWspan *span)
          _swrast_exec_fragment_shader(ctx, span);
       }
    }
-   else if (ctx->Texture._EnabledUnits && (span->arrayMask & SPAN_TEXTURE)) {
+   else if (ctx->Texture._EnabledUnits) {
       /* conventional texturing */
+
+#if CHAN_BITS == 32
+      if ((span->arrayAttribs & FRAG_BIT_COL0) == 0) {
+         interpolate_int_colors(ctx, span);
+      }
+#else
+      if (!(span->arrayMask & SPAN_RGBA))
+         interpolate_int_colors(ctx, span);
+#endif
+      if ((span->arrayAttribs & FRAG_BITS_TEX_ANY) == 0x0)
+         interpolate_texcoords(ctx, span);
+
       _swrast_texture_span(ctx, span);
    }
 }
@@ -1395,13 +1226,13 @@ _swrast_write_rgba_span( GLcontext *ctx, SWspan *span)
    const GLuint colorMask = *((GLuint *) ctx->Color.ColorMask);
    const GLbitfield origInterpMask = span->interpMask;
    const GLbitfield origArrayMask = span->arrayMask;
+   const GLbitfield origArrayAttribs = span->arrayAttribs;
    const GLenum chanType = span->array->ChanType;
    const GLboolean shader = (ctx->FragmentProgram._Current
                              || ctx->ATIFragmentShader._Enabled);
    const GLboolean shaderOrTexture = shader || ctx->Texture._EnabledUnits;
    struct gl_framebuffer *fb = ctx->DrawBuffer;
    GLuint output;
-   GLboolean deferredTexture;
 
    /*
    printf("%s()  interp 0x%x  array 0x%x\n", __FUNCTION__,
@@ -1413,41 +1244,6 @@ _swrast_write_rgba_span( GLcontext *ctx, SWspan *span)
 	  span->primitive == GL_POLYGON ||
           span->primitive == GL_BITMAP);
    ASSERT(span->end <= MAX_WIDTH);
-   ASSERT((span->interpMask & span->arrayMask) == 0);
-   ASSERT((span->interpMask & SPAN_RGBA) ^ (span->arrayMask & SPAN_RGBA));
-
-   /* check for conditions that prevent deferred shading (doing shading
-    * after stencil/ztest).
-    * XXX move this code into state validation.
-    */
-   if (ctx->Color.AlphaEnabled) {
-      /* alpha test depends on post-texture/shader colors */
-      deferredTexture = GL_FALSE;
-   }
-   else if (shaderOrTexture) {
-      if (ctx->FragmentProgram._Current) {
-         if (ctx->FragmentProgram._Current->Base.OutputsWritten
-             & (1 << FRAG_RESULT_DEPR)) {
-            /* Z comes from fragment program/shader */
-            deferredTexture = GL_FALSE;
-         }
-         else if (ctx->Query.CurrentOcclusionObject) {
-            /* occlusion query depends on shader discard/kill results */
-            deferredTexture = GL_FALSE;
-         }
-         else {
-            deferredTexture = GL_TRUE;
-         }
-      }
-      else {
-         /* ATI frag shader or conventional texturing */
-         deferredTexture = GL_TRUE;
-      }
-   }
-   else {
-      /* no texturing or shadering */
-      deferredTexture = GL_FALSE;
-   }
 
    /* Fragment write masks */
    if (span->arrayMask & SPAN_MASK) {
@@ -1486,12 +1282,10 @@ _swrast_write_rgba_span( GLcontext *ctx, SWspan *span)
       stipple_polygon_span(ctx, span);
    }
 
-   /* This is the normal place to compute the resulting fragment color/Z.
-    * As an optimization, we try to defer this until after Z/stencil
-    * testing in order to try to avoid computing colors that we won't
-    * actually need.
+   /* This is the normal place to compute the fragment color/Z
+    * from texturing or shading.
     */
-   if (shaderOrTexture && !deferredTexture) {
+   if (shaderOrTexture && !swrast->_DeferredTexture) {
       shade_texture_span(ctx, span);
    }
 
@@ -1504,7 +1298,7 @@ _swrast_write_rgba_span( GLcontext *ctx, SWspan *span)
 
    /* Stencil and Z testing */
    if (ctx->Stencil.Enabled || ctx->Depth.Test) {
-      if (span->interpMask & SPAN_Z)
+      if (!(span->arrayMask & SPAN_Z))
          _swrast_span_interpolate_z(ctx, span);
 
       if (ctx->Stencil.Enabled && fb->Visual.stencilBits > 0) {
@@ -1544,14 +1338,19 @@ _swrast_write_rgba_span( GLcontext *ctx, SWspan *span)
     * a good chance that many fragments will have already been killed by
     * Z/stencil testing.
     */
-   if (deferredTexture) {
-      ASSERT(shaderOrTexture);
+   if (shaderOrTexture && swrast->_DeferredTexture) {
       shade_texture_span(ctx, span);
    }
 
+#if CHAN_BITS == 32
+   if ((span->arrayAttribs & FRAG_BIT_COL0) == 0) {
+      interpolate_int_colors(ctx, span);
+   }
+#else
    if ((span->arrayMask & SPAN_RGBA) == 0) {
-      interpolate_colors(span);
+      interpolate_int_colors(ctx, span);
    }
+#endif
 
    ASSERT(span->arrayMask & SPAN_RGBA);
 
@@ -1560,17 +1359,7 @@ _swrast_write_rgba_span( GLcontext *ctx, SWspan *span)
       if (ctx->Fog.ColorSumEnabled ||
           (ctx->Light.Enabled &&
            ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR)) {
-         if (span->interpMask & SPAN_SPEC) {
-            interpolate_specular(span);
-         }
-         if (span->arrayMask & SPAN_SPEC) {
-            add_specular(ctx, span);
-         }
-         else {
-            /* We probably added the base/specular colors during the
-             * vertex stage!
-             */
-         }
+         add_specular(ctx, span);
       }
    }
 
@@ -1659,6 +1448,7 @@ end:
    /* restore these values before returning */
    span->interpMask = origInterpMask;
    span->arrayMask = origArrayMask;
+   span->arrayAttribs = origArrayAttribs;
    span->array->ChanType = chanType;
 }
 
@@ -1921,18 +1711,9 @@ _swrast_get_dest_rgba(GLcontext *ctx, struct gl_renderbuffer *rb,
    void *rbPixels;
 
    /*
-    * Determine pixel size (in bytes).
     * Point rbPixels to a temporary space (use specular color arrays).
     */
-   if (span->array->ChanType == GL_UNSIGNED_BYTE) {
-      rbPixels = span->array->color.sz1.spec;
-   }
-   else if (span->array->ChanType == GL_UNSIGNED_SHORT) {
-      rbPixels = span->array->color.sz2.spec;
-   }
-   else {
-      rbPixels = span->array->attribs[FRAG_ATTRIB_COL1];
-   }
+   rbPixels = span->array->attribs[FRAG_ATTRIB_COL1];
 
    /* Get destination values from renderbuffer */
    if (span->arrayMask & SPAN_XY) {
diff --git a/src/mesa/swrast/s_span.h b/src/mesa/swrast/s_span.h
index f650a27d66..585cce91ee 100644
--- a/src/mesa/swrast/s_span.h
+++ b/src/mesa/swrast/s_span.h
@@ -33,45 +33,24 @@
 
 /**
  * \defgroup SpanFlags
- * Bitflags used for interpMask and arrayMask fields below to indicate
- * which interpolant values and fragment arrays are in use, respectively.
+ * Special bitflags to describe span data.
  *
- * XXX We should replace these flags with the FRAG_BIT_ values someday...
+ * In general, the point/line/triangle functions interpolate/emit the
+ * attributes specified by swrast->_ActiveAttribs (i.e. FRAT_BIT_* values).
+ * Some things don't fit into that, though, so we have these flags.
  */
 /*@{*/
-#define SPAN_RGBA         0x001
-#define SPAN_SPEC         0x002
-#define SPAN_INDEX        0x004
-#define SPAN_Z            0x008
-#define SPAN_W            0x010
-#define SPAN_FOG          0x020
-#define SPAN_TEXTURE      0x040
-#define SPAN_INT_TEXTURE  0x080
-#define SPAN_LAMBDA       0x100
-#define SPAN_COVERAGE     0x200
-#define SPAN_FLAT         0x400  /**< flat shading? */
-#define SPAN_XY           0x800
-#define SPAN_MASK        0x1000
-#define SPAN_VARYING     0x2000
+#define SPAN_RGBA       0x01  /**< interpMask and arrayMask */
+#define SPAN_INDEX      0x02  /**< interpMask and arrayMask */
+#define SPAN_Z          0x04  /**< interpMask and arrayMask */
+#define SPAN_FLAT       0x08  /**< interpMask: flat shading? */
+#define SPAN_XY         0x10  /**< array.x[], y[] valid? */
+#define SPAN_MASK       0x20  /**< was array.mask[] filled in by caller? */
+#define SPAN_LAMBDA     0x40  /**< array.lambda[] valid? */
+#define SPAN_COVERAGE   0x80  /**< array.coverage[] valid? */
 /*@}*/
 
 
-#if 0
-/* alternate arrangement for code below */
-struct arrays2 {
-   union {
-      GLubyte  sz1[MAX_WIDTH][4]; /* primary color */
-      GLushort sz2[MAX_WIDTH][4];
-   } rgba;
-   union {
-      GLubyte  sz1[MAX_WIDTH][4]; /* specular color and temp storage */
-      GLushort sz2[MAX_WIDTH][4];
-   } spec;
-};
-#endif
-
-
-
 /**
  * \sw_span_arrays 
  * \brief Arrays of fragment values.
@@ -92,26 +71,19 @@ typedef struct sw_span_arrays
    GLubyte mask[MAX_WIDTH];
 
    GLenum ChanType; /**< Color channel type, GL_UNSIGNED_BYTE, GL_FLOAT */
-   union {
-      struct {
-         GLubyte rgba[MAX_WIDTH][4]; /**< primary color */
-         GLubyte spec[MAX_WIDTH][4]; /**< specular color and temp storage */
-      } sz1;
-      struct {
-         GLushort rgba[MAX_WIDTH][4];
-         GLushort spec[MAX_WIDTH][4];
-      } sz2;
-   } color;
-   /** XXX these are temporary fields, pointing into above color arrays */
-   GLchan (*rgba)[4];
-   GLchan (*spec)[4];
 
+   /** Attribute arrays that don't fit into attribs[] array above */
+   /*@{*/
+   GLubyte rgba8[MAX_WIDTH][4];
+   GLushort rgba16[MAX_WIDTH][4];
+   GLchan (*rgba)[4];  /** either == rgba8 or rgba16 */
    GLint   x[MAX_WIDTH];  /**< fragment X coords */
    GLint   y[MAX_WIDTH];  /**< fragment Y coords */
    GLuint  z[MAX_WIDTH];  /**< fragment Z coords */
    GLuint  index[MAX_WIDTH];  /**< Color indexes */
    GLfloat lambda[MAX_TEXTURE_COORD_UNITS][MAX_WIDTH]; /**< Texture LOD */
    GLfloat coverage[MAX_WIDTH];  /**< Fragment coverage for AA/smoothing */
+   /*@}*/
 } SWspanarrays;
 
 
@@ -160,26 +132,13 @@ typedef struct sw_span
    /* For horizontal spans, step is the partial derivative wrt X.
     * For lines, step is the delta from one fragment to the next.
     */
-#if CHAN_TYPE == GL_FLOAT
-   GLfloat red, redStep;
-   GLfloat green, greenStep;
-   GLfloat blue, blueStep;
-   GLfloat alpha, alphaStep;
-   GLfloat specRed, specRedStep;
-   GLfloat specGreen, specGreenStep;
-   GLfloat specBlue, specBlueStep;
-#else /* CHAN_TYPE == GL_UNSIGNED_BYTE or GL_UNSIGNED_SHORT */
    GLfixed red, redStep;
    GLfixed green, greenStep;
    GLfixed blue, blueStep;
    GLfixed alpha, alphaStep;
-   GLfixed specRed, specRedStep;
-   GLfixed specGreen, specGreenStep;
-   GLfixed specBlue, specBlueStep;
-#endif
    GLfixed index, indexStep;
-   GLfixed z, zStep;    /* XXX z should probably be GLuint */
-   GLfixed intTex[2], intTexStep[2];  /* s, t only */
+   GLfixed z, zStep;    /**< XXX z should probably be GLuint */
+   GLfixed intTex[2], intTexStep[2];  /**< (s,t) for unit[0] only */
 
    /**
     * This bitmask (of \link SpanFlags SPAN_* flags\endlink) indicates
@@ -187,6 +146,8 @@ typedef struct sw_span
     */
    GLbitfield arrayMask;
 
+   GLbitfield arrayAttribs;
+
    /**
     * We store the arrays of fragment values in a separate struct so
     * that we can allocate sw_span structs on the stack without using
@@ -203,6 +164,7 @@ do {								\
    (S).primitive = (PRIMITIVE);					\
    (S).interpMask = (INTERP_MASK);				\
    (S).arrayMask = (ARRAY_MASK);				\
+   (S).arrayAttribs = 0x0;					\
    (S).end = (END);						\
    (S).facing = 0;						\
    (S).array = SWRAST_CONTEXT(ctx)->SpanArrays;			\
@@ -211,23 +173,11 @@ do {								\
 
 
 extern void
-_swrast_span_default_z( GLcontext *ctx, SWspan *span );
+_swrast_span_default_attribs(GLcontext *ctx, SWspan *span);
 
 extern void
 _swrast_span_interpolate_z( const GLcontext *ctx, SWspan *span );
 
-extern void
-_swrast_span_default_fog( GLcontext *ctx, SWspan *span );
-
-extern void
-_swrast_span_default_color( GLcontext *ctx, SWspan *span );
-
-extern void
-_swrast_span_default_secondary_color(GLcontext *ctx, SWspan *span);
-
-extern void
-_swrast_span_default_texcoords( GLcontext *ctx, SWspan *span );
-
 extern GLfloat
 _swrast_compute_lambda(GLfloat dsdx, GLfloat dsdy, GLfloat dtdx, GLfloat dtdy,
                        GLfloat dqdx, GLfloat dqdy, GLfloat texW, GLfloat texH,
diff --git a/src/mesa/swrast/s_texcombine.c b/src/mesa/swrast/s_texcombine.c
index ebb4c0d936..4ac7222daa 100644
--- a/src/mesa/swrast/s_texcombine.c
+++ b/src/mesa/swrast/s_texcombine.c
@@ -1080,7 +1080,6 @@ _swrast_texture_span( GLcontext *ctx, SWspan *span )
    GLuint unit;
 
    ASSERT(span->end < MAX_WIDTH);
-   ASSERT(span->arrayMask & SPAN_TEXTURE);
 
    /*
     * Save copy of the incoming fragment colors (the GL_PRIMARY_COLOR)
diff --git a/src/mesa/swrast/s_triangle.c b/src/mesa/swrast/s_triangle.c
index fc9d29bbf7..c255545217 100644
--- a/src/mesa/swrast/s_triangle.c
+++ b/src/mesa/swrast/s_triangle.c
@@ -52,10 +52,10 @@ _swrast_culltriangle( GLcontext *ctx,
                       const SWvertex *v1,
                       const SWvertex *v2 )
 {
-   GLfloat ex = v1->win[0] - v0->win[0];
-   GLfloat ey = v1->win[1] - v0->win[1];
-   GLfloat fx = v2->win[0] - v0->win[0];
-   GLfloat fy = v2->win[1] - v0->win[1];
+   GLfloat ex = v1->attrib[FRAG_ATTRIB_WPOS][0] - v0->attrib[FRAG_ATTRIB_WPOS][0];
+   GLfloat ey = v1->attrib[FRAG_ATTRIB_WPOS][1] - v0->attrib[FRAG_ATTRIB_WPOS][1];
+   GLfloat fx = v2->attrib[FRAG_ATTRIB_WPOS][0] - v0->attrib[FRAG_ATTRIB_WPOS][0];
+   GLfloat fy = v2->attrib[FRAG_ATTRIB_WPOS][1] - v0->attrib[FRAG_ATTRIB_WPOS][1];
    GLfloat c = ex*fy-ey*fx;
 
    if (c * SWRAST_CONTEXT(ctx)->_BackfaceSign > 0)
@@ -71,7 +71,7 @@ _swrast_culltriangle( GLcontext *ctx,
  */
 #define NAME ci_triangle
 #define INTERP_Z 1
-#define INTERP_FOG 1
+#define INTERP_ATTRIBS 1  /* just for fog */
 #define INTERP_INDEX 1
 #define RENDER_SPAN( span )  _swrast_write_index_span(ctx, &span);
 #include "s_tritemp.h"
@@ -83,7 +83,6 @@ _swrast_culltriangle( GLcontext *ctx,
  */
 #define NAME flat_rgba_triangle
 #define INTERP_Z 1
-#define INTERP_FOG 1
 #define SETUP_CODE				\
    ASSERT(ctx->Texture._EnabledCoordUnits == 0);\
    ASSERT(ctx->Light.ShadeModel==GL_FLAT);	\
@@ -106,7 +105,6 @@ _swrast_culltriangle( GLcontext *ctx,
  */
 #define NAME smooth_rgba_triangle
 #define INTERP_Z 1
-#define INTERP_FOG 1
 #define INTERP_RGB 1
 #define INTERP_ALPHA 1
 #define SETUP_CODE				\
@@ -228,7 +226,6 @@ _swrast_culltriangle( GLcontext *ctx,
 #include "s_tritemp.h"
 
 
-
 #if CHAN_TYPE != GL_FLOAT
 
 struct affine_info
@@ -511,7 +508,6 @@ affine_span(GLcontext *ctx, SWspan *span,
  */
 #define NAME affine_textured_triangle
 #define INTERP_Z 1
-#define INTERP_FOG 1
 #define INTERP_RGB 1
 #define INTERP_ALPHA 1
 #define INTERP_INT_TEX 1
@@ -784,8 +780,6 @@ fast_persp_span(GLcontext *ctx, SWspan *span,
  */
 #define NAME persp_textured_triangle
 #define INTERP_Z 1
-#define INTERP_W 1
-#define INTERP_FOG 1
 #define INTERP_RGB 1
 #define INTERP_ALPHA 1
 #define INTERP_ATTRIBS 1
@@ -843,10 +837,8 @@ fast_persp_span(GLcontext *ctx, SWspan *span,
 
 #include "s_tritemp.h"
 
+#endif /*CHAN_TYPE != GL_FLOAT*/
 
-#endif /* CHAN_BITS != GL_FLOAT */
-
-                
 
 
 /*
@@ -854,10 +846,7 @@ fast_persp_span(GLcontext *ctx, SWspan *span,
  */
 #define NAME general_triangle
 #define INTERP_Z 1
-#define INTERP_W 1
-#define INTERP_FOG 1
 #define INTERP_RGB 1
-#define INTERP_SPEC 1
 #define INTERP_ALPHA 1
 #define INTERP_ATTRIBS 1
 #define RENDER_SPAN( span )   _swrast_write_rgba_span(ctx, &span);
@@ -924,51 +913,47 @@ nodraw_triangle( GLcontext *ctx,
  * draw the triangle, then restore the original primary color.
  * Inefficient, but seldom needed.
  */
-void _swrast_add_spec_terms_triangle( GLcontext *ctx,
-				      const SWvertex *v0,
-				      const SWvertex *v1,
-				      const SWvertex *v2 )
+void
+_swrast_add_spec_terms_triangle(GLcontext *ctx, const SWvertex *v0,
+                                const SWvertex *v1, const SWvertex *v2)
 {
    SWvertex *ncv0 = (SWvertex *)v0; /* drop const qualifier */
    SWvertex *ncv1 = (SWvertex *)v1;
    SWvertex *ncv2 = (SWvertex *)v2;
-#if CHAN_TYPE == GL_FLOAT
    GLfloat rSum, gSum, bSum;
-#else
-   GLint rSum, gSum, bSum;
-#endif
-   GLchan c[3][4];
+   GLchan cSave[3][4];
+
    /* save original colors */
-   COPY_CHAN4( c[0], ncv0->color );
-   COPY_CHAN4( c[1], ncv1->color );
-   COPY_CHAN4( c[2], ncv2->color );
+   COPY_CHAN4( cSave[0], ncv0->color );
+   COPY_CHAN4( cSave[1], ncv1->color );
+   COPY_CHAN4( cSave[2], ncv2->color );
    /* sum v0 */
-   rSum = ncv0->color[0] + ncv0->specular[0];
-   gSum = ncv0->color[1] + ncv0->specular[1];
-   bSum = ncv0->color[2] + ncv0->specular[2];
-   ncv0->color[0] = MIN2(rSum, CHAN_MAX);
-   ncv0->color[1] = MIN2(gSum, CHAN_MAX);
-   ncv0->color[2] = MIN2(bSum, CHAN_MAX);
+   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];
+   bSum = CHAN_TO_FLOAT(ncv0->color[2]) + ncv0->attrib[FRAG_ATTRIB_COL1][2];
+   UNCLAMPED_FLOAT_TO_CHAN(ncv0->color[0], rSum);
+   UNCLAMPED_FLOAT_TO_CHAN(ncv0->color[1], gSum);
+   UNCLAMPED_FLOAT_TO_CHAN(ncv0->color[2], bSum);
    /* sum v1 */
-   rSum = ncv1->color[0] + ncv1->specular[0];
-   gSum = ncv1->color[1] + ncv1->specular[1];
-   bSum = ncv1->color[2] + ncv1->specular[2];
-   ncv1->color[0] = MIN2(rSum, CHAN_MAX);
-   ncv1->color[1] = MIN2(gSum, CHAN_MAX);
-   ncv1->color[2] = MIN2(bSum, CHAN_MAX);
+   rSum = CHAN_TO_FLOAT(ncv1->color[0]) + ncv1->attrib[FRAG_ATTRIB_COL1][0];
+   gSum = CHAN_TO_FLOAT(ncv1->color[1]) + ncv1->attrib[FRAG_ATTRIB_COL1][1];
+   bSum = CHAN_TO_FLOAT(ncv1->color[2]) + ncv1->attrib[FRAG_ATTRIB_COL1][2];
+   UNCLAMPED_FLOAT_TO_CHAN(ncv1->color[0], rSum);
+   UNCLAMPED_FLOAT_TO_CHAN(ncv1->color[1], gSum);
+   UNCLAMPED_FLOAT_TO_CHAN(ncv1->color[2], bSum);
    /* sum v2 */
-   rSum = ncv2->color[0] + ncv2->specular[0];
-   gSum = ncv2->color[1] + ncv2->specular[1];
-   bSum = ncv2->color[2] + ncv2->specular[2];
-   ncv2->color[0] = MIN2(rSum, CHAN_MAX);
-   ncv2->color[1] = MIN2(gSum, CHAN_MAX);
-   ncv2->color[2] = MIN2(bSum, CHAN_MAX);
+   rSum = CHAN_TO_FLOAT(ncv2->color[0]) + ncv2->attrib[FRAG_ATTRIB_COL1][0];
+   gSum = CHAN_TO_FLOAT(ncv2->color[1]) + ncv2->attrib[FRAG_ATTRIB_COL1][1];
+   bSum = CHAN_TO_FLOAT(ncv2->color[2]) + ncv2->attrib[FRAG_ATTRIB_COL1][2];
+   UNCLAMPED_FLOAT_TO_CHAN(ncv2->color[0], rSum);
+   UNCLAMPED_FLOAT_TO_CHAN(ncv2->color[1], gSum);
+   UNCLAMPED_FLOAT_TO_CHAN(ncv2->color[2], bSum);
    /* draw */
    SWRAST_CONTEXT(ctx)->SpecTriangle( ctx, ncv0, ncv1, ncv2 );
    /* restore original colors */
-   COPY_CHAN4( ncv0->color, c[0] );
-   COPY_CHAN4( ncv1->color, c[1] );
-   COPY_CHAN4( ncv2->color, c[2] );
+   COPY_CHAN4( ncv0->color, cSave[0] );
+   COPY_CHAN4( ncv1->color, cSave[1] );
+   COPY_CHAN4( ncv2->color, cSave[2] );
 }
 
 
@@ -1044,9 +1029,15 @@ _swrast_choose_triangle( GLcontext *ctx )
          return;
       }
 
+      /*
+       * XXX should examine swrast->_ActiveAttribMask to determine what
+       * needs to be interpolated.
+       */
       if (ctx->Texture._EnabledCoordUnits ||
           ctx->FragmentProgram._Current ||
-          ctx->ATIFragmentShader._Enabled) {
+          ctx->ATIFragmentShader._Enabled ||
+          NEED_SECONDARY_COLOR(ctx) ||
+          swrast->_FogEnabled) {
          /* Ugh, we do a _lot_ of tests to pick the best textured tri func */
          const struct gl_texture_object *texObj2D;
          const struct gl_texture_image *texImg;
@@ -1072,6 +1063,7 @@ _swrast_choose_triangle( GLcontext *ctx )
              && (format == MESA_FORMAT_RGB || format == MESA_FORMAT_RGBA)
              && minFilter == magFilter
              && ctx->Light.Model.ColorControl == GL_SINGLE_COLOR
+             && !swrast->_FogEnabled
              && ctx->Texture.Unit[0].EnvMode != GL_COMBINE_EXT) {
 	    if (ctx->Hint.PerspectiveCorrection==GL_FASTEST) {
 	       if (minFilter == GL_NEAREST
@@ -1091,7 +1083,7 @@ _swrast_choose_triangle( GLcontext *ctx )
 		  }
 	       }
 	       else {
-#if (CHAN_BITS == 16 || CHAN_BITS == 32)
+#if CHAN_BITS != 8
                   USE(general_triangle);
 #else
                   USE(affine_textured_triangle);
@@ -1099,7 +1091,7 @@ _swrast_choose_triangle( GLcontext *ctx )
 	       }
 	    }
 	    else {
-#if (CHAN_BITS == 16 || CHAN_BITS == 32)
+#if CHAN_BITS != 8
                USE(general_triangle);
 #else
                USE(persp_textured_triangle);
@@ -1112,14 +1104,23 @@ _swrast_choose_triangle( GLcontext *ctx )
          }
       }
       else {
-         ASSERT(!ctx->Texture._EnabledCoordUnits);
+         ASSERT(!swrast->_FogEnabled);
+         ASSERT(!NEED_SECONDARY_COLOR(ctx));
 	 if (ctx->Light.ShadeModel==GL_SMOOTH) {
 	    /* smooth shaded, no texturing, stippled or some raster ops */
-            USE(smooth_rgba_triangle);
+#if CHAN_BITS != 8
+               USE(general_triangle);
+#else
+               USE(smooth_rgba_triangle);
+#endif
 	 }
 	 else {
 	    /* flat shaded, no texturing, stippled or some raster ops */
+#if CHAN_BITS != 8
+            USE(general_triangle);
+#else
             USE(flat_rgba_triangle);
+#endif
 	 }
       }
    }
diff --git a/src/mesa/swrast/s_tritemp.h b/src/mesa/swrast/s_tritemp.h
index dcc3e958cb..2a90ffd85f 100644
--- a/src/mesa/swrast/s_tritemp.h
+++ b/src/mesa/swrast/s_tritemp.h
@@ -29,18 +29,16 @@
  *
  * The following macros may be defined to indicate what auxillary information
  * must be interpolated across the triangle:
- *    INTERP_Z        - if defined, interpolate vertex Z values
- *    INTERP_W        - if defined, interpolate vertex W values
- *    INTERP_FOG      - if defined, interpolate fog values
- *    INTERP_RGB      - if defined, interpolate RGB values
- *    INTERP_ALPHA    - if defined, interpolate Alpha values (req's INTERP_RGB)
- *    INTERP_SPEC     - if defined, interpolate specular RGB values
+ *    INTERP_Z        - if defined, interpolate integer Z values
+ *    INTERP_RGB      - if defined, interpolate integer RGB values
+ *    INTERP_ALPHA    - if defined, interpolate integer Alpha values
  *    INTERP_INDEX    - if defined, interpolate color index values
  *    INTERP_INT_TEX  - if defined, interpolate integer ST texcoords
- *                         (fast, simple 2-D texture mapping)
+ *                         (fast, simple 2-D texture mapping, without
+ *                         perspective correction)
  *    INTERP_ATTRIBS  - if defined, interpolate arbitrary attribs (texcoords,
- *                         varying vars, etc)
- *                         NOTE:  OpenGL STRQ = Mesa STUV (R was taken for red)
+ *                         varying vars, etc)  This also causes W to be
+ *                         computed for perspective correction).
  *
  * When one can directly address pixels in the color buffer the following
  * macros can be defined and used to compute pixel addresses during
@@ -51,12 +49,11 @@
  *                          Y==0 at bottom of screen and increases upward.
  *
  * Similarly, for direct depth buffer access, this type is used for depth
- * buffer addressing:
+ * buffer addressing (see zRow):
  *    DEPTH_TYPE          - either GLushort or GLuint
  *
  * Optionally, one may provide one-time setup code per triangle:
  *    SETUP_CODE    - code which is to be executed once per triangle
- *    CLEANUP_CODE    - code to execute at end of triangle
  *
  * The following macro MUST be defined:
  *    RENDER_SPAN(span) - code to write a span of pixels.
@@ -94,29 +91,6 @@
  * SUB_PIXEL_BITS.
  */
 
-/*
- * ColorTemp is used for intermediate color values.
- */
-#if CHAN_TYPE == GL_FLOAT
-#define ColorTemp GLfloat
-#else
-#define ColorTemp GLint  /* same as GLfixed */
-#endif
-
-
-/*
- * Walk triangle edges with GLfixed or GLdouble
- */
-#if TRIANGLE_WALK_DOUBLE
-#define GLinterp        GLdouble
-#define InterpToInt(X)  ((GLint) (X))
-#define INTERP_ONE      1.0
-#else
-#define GLinterp        GLfixed
-#define InterpToInt(X)  FixedToInt(X)
-#define INTERP_ONE      FIXED_ONE
-#endif
-
 
 /*
  * Some code we unfortunately need to prevent negative interpolated colors.
@@ -141,15 +115,6 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
 {
    typedef struct {
       const SWvertex *v0, *v1;   /* Y(v0) < Y(v1) */
-#if TRIANGLE_WALK_DOUBLE
-      GLdouble dx;	/* X(v1) - X(v0) */
-      GLdouble dy;	/* Y(v1) - Y(v0) */
-      GLdouble dxdy;	/* dx/dy */
-      GLdouble adjy;	/* adjust from v[0]->fy to fsy, scaled */
-      GLdouble fsx;	/* first sample point x coord */
-      GLdouble fsy;
-      GLdouble fx0;	/*X of lower endpoint */
-#else
       GLfloat dx;	/* X(v1) - X(v0) */
       GLfloat dy;	/* Y(v1) - Y(v0) */
       GLfloat dxdy;	/* dx/dy */
@@ -158,7 +123,6 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
       GLfixed fsx;	/* first sample point x coord */
       GLfixed fsy;
       GLfixed fx0;	/* fixed pt X of lower endpoint */
-#endif
       GLint lines;	/* number of lines to be sampled on this edge */
    } EdgeT;
 
@@ -173,10 +137,8 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
    GLfloat oneOverArea;
    const SWvertex *vMin, *vMid, *vMax;  /* Y(vMin)<=Y(vMid)<=Y(vMax) */
    GLfloat bf = SWRAST_CONTEXT(ctx)->_BackfaceSign;
-#if !TRIANGLE_WALK_DOUBLE
    const GLint snapMask = ~((FIXED_ONE / (1 << SUB_PIXEL_BITS)) - 1); /* for x/y coord snapping */
-#endif
-   GLinterp vMin_fx, vMin_fy, vMid_fx, vMid_fy, vMax_fx, vMax_fy;
+   GLfixed vMin_fx, vMin_fy, vMid_fx, vMid_fy, vMax_fx, vMax_fy;
 
    SWspan span;
 
@@ -191,28 +153,27 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
 
    /*
    printf("%s()\n", __FUNCTION__);
-   printf("  %g, %g, %g\n", v0->win[0], v0->win[1], v0->win[2]);
-   printf("  %g, %g, %g\n", v1->win[0], v1->win[1], v1->win[2]);
-   printf("  %g, %g, %g\n", v2->win[0], v2->win[1], v2->win[2]);
-   */
-   /*
-   ASSERT(v0->win[2] >= 0.0);
-   ASSERT(v1->win[2] >= 0.0);
-   ASSERT(v2->win[2] >= 0.0);
+   printf("  %g, %g, %g\n",
+          v0->attrib[FRAG_ATTRIB_WPOS][0],
+          v0->attrib[FRAG_ATTRIB_WPOS][1],
+          v0->attrib[FRAG_ATTRIB_WPOS][2]);
+   printf("  %g, %g, %g\n",
+          v1->attrib[FRAG_ATTRIB_WPOS][0],
+          v1->attrib[FRAG_ATTRIB_WPOS][1],
+          v1->attrib[FRAG_ATTRIB_WPOS][2]);
+   printf("  %g, %g, %g\n",
+          v2->attrib[FRAG_ATTRIB_WPOS][0],
+          v2->attrib[FRAG_ATTRIB_WPOS][1],
+          v2->attrib[FRAG_ATTRIB_WPOS][2]);
    */
+
    /* Compute fixed point x,y coords w/ half-pixel offsets and snapping.
     * And find the order of the 3 vertices along the Y axis.
     */
    {
-#if TRIANGLE_WALK_DOUBLE
-      const GLdouble fy0 = v0->win[1] - 0.5;
-      const GLdouble fy1 = v1->win[1] - 0.5;
-      const GLdouble fy2 = v2->win[1] - 0.5;
-#else
-      const GLfixed fy0 = FloatToFixed(v0->win[1] - 0.5F) & snapMask;
-      const GLfixed fy1 = FloatToFixed(v1->win[1] - 0.5F) & snapMask;
-      const GLfixed fy2 = FloatToFixed(v2->win[1] - 0.5F) & snapMask;
-#endif
+      const GLfixed fy0 = FloatToFixed(v0->attrib[FRAG_ATTRIB_WPOS][1] - 0.5F) & snapMask;
+      const GLfixed fy1 = FloatToFixed(v1->attrib[FRAG_ATTRIB_WPOS][1] - 0.5F) & snapMask;
+      const GLfixed fy2 = FloatToFixed(v2->attrib[FRAG_ATTRIB_WPOS][1] - 0.5F) & snapMask;
       if (fy0 <= fy1) {
          if (fy1 <= fy2) {
             /* y0 <= y1 <= y2 */
@@ -252,15 +213,9 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
       }
 
       /* fixed point X coords */
-#if TRIANGLE_WALK_DOUBLE
-      vMin_fx = vMin->win[0] + 0.5;
-      vMid_fx = vMid->win[0] + 0.5;
-      vMax_fx = vMax->win[0] + 0.5;
-#else
-      vMin_fx = FloatToFixed(vMin->win[0] + 0.5F) & snapMask;
-      vMid_fx = FloatToFixed(vMid->win[0] + 0.5F) & snapMask;
-      vMax_fx = FloatToFixed(vMax->win[0] + 0.5F) & snapMask;
-#endif
+      vMin_fx = FloatToFixed(vMin->attrib[FRAG_ATTRIB_WPOS][0] + 0.5F) & snapMask;
+      vMid_fx = FloatToFixed(vMid->attrib[FRAG_ATTRIB_WPOS][0] + 0.5F) & snapMask;
+      vMax_fx = FloatToFixed(vMax->attrib[FRAG_ATTRIB_WPOS][0] + 0.5F) & snapMask;
    }
 
    /* vertex/edge relationship */
@@ -269,29 +224,16 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
    eBot.v0 = vMin;   eBot.v1 = vMid;
 
    /* compute deltas for each edge:  vertex[upper] - vertex[lower] */
-#if TRIANGLE_WALK_DOUBLE
-   eMaj.dx = vMax_fx - vMin_fx;
-   eMaj.dy = vMax_fy - vMin_fy;
-   eTop.dx = vMax_fx - vMid_fx;
-   eTop.dy = vMax_fy - vMid_fy;
-   eBot.dx = vMid_fx - vMin_fx;
-   eBot.dy = vMid_fy - vMin_fy;
-#else
    eMaj.dx = FixedToFloat(vMax_fx - vMin_fx);
    eMaj.dy = FixedToFloat(vMax_fy - vMin_fy);
    eTop.dx = FixedToFloat(vMax_fx - vMid_fx);
    eTop.dy = FixedToFloat(vMax_fy - vMid_fy);
    eBot.dx = FixedToFloat(vMid_fx - vMin_fx);
    eBot.dy = FixedToFloat(vMid_fy - vMin_fy);
-#endif
 
    /* compute area, oneOverArea and perform backface culling */
    {
-#if TRIANGLE_WALK_DOUBLE
-      const GLdouble area = eMaj.dx * eBot.dy - eBot.dx * eMaj.dy;
-#else
       const GLfloat area = eMaj.dx * eBot.dy - eBot.dx * eMaj.dy;
-#endif
       /* Do backface culling */
       if (area * bf < 0.0)
          return;
@@ -307,70 +249,37 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
 
    /* Edge setup.  For a triangle strip these could be reused... */
    {
-#if TRIANGLE_WALK_DOUBLE
-      eMaj.fsy = CEILF(vMin_fy);
-      eMaj.lines = (GLint) CEILF(vMax_fy - eMaj.fsy);
-#else
       eMaj.fsy = FixedCeil(vMin_fy);
       eMaj.lines = FixedToInt(FixedCeil(vMax_fy - eMaj.fsy));
-#endif
       if (eMaj.lines > 0) {
          eMaj.dxdy = eMaj.dx / eMaj.dy;
-#if TRIANGLE_WALK_DOUBLE
-         eMaj.adjy = (eMaj.fsy - vMin_fy) * FIXED_SCALE;  /* SCALED! */
-         eMaj.fx0 = vMin_fx;
-         eMaj.fsx = eMaj.fx0 + (eMaj.adjy * eMaj.dxdy) / (GLdouble) FIXED_SCALE;
-#else
          eMaj.fdxdy = SignedFloatToFixed(eMaj.dxdy);
          eMaj.adjy = (GLfloat) (eMaj.fsy - vMin_fy);  /* SCALED! */
          eMaj.fx0 = vMin_fx;
          eMaj.fsx = eMaj.fx0 + (GLfixed) (eMaj.adjy * eMaj.dxdy);
-#endif
       }
       else {
          return;  /*CULLED*/
       }
 
-#if TRIANGLE_WALK_DOUBLE
-      eTop.fsy = CEILF(vMid_fy);
-      eTop.lines = (GLint) CEILF(vMax_fy - eTop.fsy);
-#else
       eTop.fsy = FixedCeil(vMid_fy);
       eTop.lines = FixedToInt(FixedCeil(vMax_fy - eTop.fsy));
-#endif
       if (eTop.lines > 0) {
          eTop.dxdy = eTop.dx / eTop.dy;
-#if TRIANGLE_WALK_DOUBLE
-         eTop.adjy = (eTop.fsy - vMid_fy) * FIXED_SCALE; /* SCALED! */
-         eTop.fx0 = vMid_fx;
-         eTop.fsx = eTop.fx0 + (eTop.adjy * eTop.dxdy) / (GLdouble) FIXED_SCALE;
-#else
          eTop.fdxdy = SignedFloatToFixed(eTop.dxdy);
          eTop.adjy = (GLfloat) (eTop.fsy - vMid_fy); /* SCALED! */
          eTop.fx0 = vMid_fx;
          eTop.fsx = eTop.fx0 + (GLfixed) (eTop.adjy * eTop.dxdy);
-#endif
       }
 
-#if TRIANGLE_WALK_DOUBLE
-      eBot.fsy = CEILF(vMin_fy);
-      eBot.lines = (GLint) CEILF(vMid_fy - eBot.fsy);
-#else
       eBot.fsy = FixedCeil(vMin_fy);
       eBot.lines = FixedToInt(FixedCeil(vMid_fy - eBot.fsy));
-#endif
       if (eBot.lines > 0) {
          eBot.dxdy = eBot.dx / eBot.dy;
-#if TRIANGLE_WALK_DOUBLE
-         eBot.adjy = (eBot.fsy - vMin_fy) * FIXED_SCALE;  /* SCALED! */
-         eBot.fx0 = vMin_fx;
-         eBot.fsx = eBot.fx0 + (eBot.adjy * eBot.dxdy) / (GLdouble) FIXED_SCALE;
-#else
          eBot.fdxdy = SignedFloatToFixed(eBot.dxdy);
          eBot.adjy = (GLfloat) (eBot.fsy - vMin_fy);  /* SCALED! */
          eBot.fx0 = vMin_fx;
          eBot.fsx = eBot.fx0 + (GLfixed) (eBot.adjy * eBot.dxdy);
-#endif
       }
    }
 
@@ -428,10 +337,11 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
 #ifdef INTERP_Z
       span.interpMask |= SPAN_Z;
       {
-         GLfloat eMaj_dz = vMax->win[2] - vMin->win[2];
-         GLfloat eBot_dz = vMid->win[2] - vMin->win[2];
+         GLfloat eMaj_dz = vMax->attrib[FRAG_ATTRIB_WPOS][2] - vMin->attrib[FRAG_ATTRIB_WPOS][2];
+         GLfloat eBot_dz = vMid->attrib[FRAG_ATTRIB_WPOS][2] - vMin->attrib[FRAG_ATTRIB_WPOS][2];
          span.attrStepX[FRAG_ATTRIB_WPOS][2] = oneOverArea * (eMaj_dz * eBot.dy - eMaj.dy * eBot_dz);
-         if (span.attrStepX[FRAG_ATTRIB_WPOS][2] > maxDepth || span.attrStepX[FRAG_ATTRIB_WPOS][2] < -maxDepth) {
+         if (span.attrStepX[FRAG_ATTRIB_WPOS][2] > maxDepth ||
+             span.attrStepX[FRAG_ATTRIB_WPOS][2] < -maxDepth) {
             /* probably a sliver triangle */
             span.attrStepX[FRAG_ATTRIB_WPOS][2] = 0.0;
             span.attrStepY[FRAG_ATTRIB_WPOS][2] = 0.0;
@@ -445,42 +355,18 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
             span.zStep = (GLint) span.attrStepX[FRAG_ATTRIB_WPOS][2];
       }
 #endif
-#ifdef INTERP_W
-      span.interpMask |= SPAN_W;
-      {
-         const GLfloat eMaj_dw = vMax->win[3] - vMin->win[3];
-         const GLfloat eBot_dw = vMid->win[3] - vMin->win[3];
-         span.attrStepX[FRAG_ATTRIB_WPOS][3] = oneOverArea * (eMaj_dw * eBot.dy - eMaj.dy * eBot_dw);
-         span.attrStepY[FRAG_ATTRIB_WPOS][3] = oneOverArea * (eMaj.dx * eBot_dw - eMaj_dw * eBot.dx);
-      }
-#endif
-#ifdef INTERP_FOG
-      span.interpMask |= SPAN_FOG;
-      {
-#  ifdef INTERP_W
-         const GLfloat wMax = vMax->win[3], wMin = vMin->win[3], wMid = vMid->win[3];
-         const GLfloat eMaj_dfog = vMax->attrib[FRAG_ATTRIB_FOGC][0] * wMax - vMin->attrib[FRAG_ATTRIB_FOGC][0] * wMin;
-         const GLfloat eBot_dfog = vMid->attrib[FRAG_ATTRIB_FOGC][0] * wMid - vMin->attrib[FRAG_ATTRIB_FOGC][0] * wMin;
-#  else
-         const GLfloat eMaj_dfog = vMax->attrib[FRAG_ATTRIB_FOGC][0] - vMin->attrib[FRAG_ATTRIB_FOGC][0];
-         const GLfloat eBot_dfog = vMid->attrib[FRAG_ATTRIB_FOGC][0] - vMin->attrib[FRAG_ATTRIB_FOGC][0];
-#  endif
-         span.attrStepX[FRAG_ATTRIB_FOGC][0] = oneOverArea * (eMaj_dfog * eBot.dy - eMaj.dy * eBot_dfog);
-         span.attrStepY[FRAG_ATTRIB_FOGC][0] = oneOverArea * (eMaj.dx * eBot_dfog - eMaj_dfog * eBot.dx);
-      }
-#endif
 #ifdef INTERP_RGB
       span.interpMask |= SPAN_RGBA;
       if (ctx->Light.ShadeModel == GL_SMOOTH) {
-         GLfloat eMaj_dr = (GLfloat) ((ColorTemp) vMax->color[RCOMP] - (ColorTemp) vMin->color[RCOMP]);
-         GLfloat eBot_dr = (GLfloat) ((ColorTemp) vMid->color[RCOMP] - (ColorTemp) vMin->color[RCOMP]);
-         GLfloat eMaj_dg = (GLfloat) ((ColorTemp) vMax->color[GCOMP] - (ColorTemp) vMin->color[GCOMP]);
-         GLfloat eBot_dg = (GLfloat) ((ColorTemp) vMid->color[GCOMP] - (ColorTemp) vMin->color[GCOMP]);
-         GLfloat eMaj_db = (GLfloat) ((ColorTemp) vMax->color[BCOMP] - (ColorTemp) vMin->color[BCOMP]);
-         GLfloat eBot_db = (GLfloat) ((ColorTemp) vMid->color[BCOMP] - (ColorTemp) vMin->color[BCOMP]);
+         GLfloat eMaj_dr = (GLfloat) (vMax->color[RCOMP] - vMin->color[RCOMP]);
+         GLfloat eBot_dr = (GLfloat) (vMid->color[RCOMP] - vMin->color[RCOMP]);
+         GLfloat eMaj_dg = (GLfloat) (vMax->color[GCOMP] - vMin->color[GCOMP]);
+         GLfloat eBot_dg = (GLfloat) (vMid->color[GCOMP] - vMin->color[GCOMP]);
+         GLfloat eMaj_db = (GLfloat) (vMax->color[BCOMP] - vMin->color[BCOMP]);
+         GLfloat eBot_db = (GLfloat) (vMid->color[BCOMP] - vMin->color[BCOMP]);
 #  ifdef INTERP_ALPHA
-         GLfloat eMaj_da = (GLfloat) ((ColorTemp) vMax->color[ACOMP] - (ColorTemp) vMin->color[ACOMP]);
-         GLfloat eBot_da = (GLfloat) ((ColorTemp) vMid->color[ACOMP] - (ColorTemp) vMin->color[ACOMP]);
+         GLfloat eMaj_da = (GLfloat) (vMax->color[ACOMP] - vMin->color[ACOMP]);
+         GLfloat eBot_da = (GLfloat) (vMid->color[ACOMP] - vMin->color[ACOMP]);
 #  endif
          span.attrStepX[FRAG_ATTRIB_COL0][0] = oneOverArea * (eMaj_dr * eBot.dy - eMaj.dy * eBot_dr);
          span.attrStepY[FRAG_ATTRIB_COL0][0] = oneOverArea * (eMaj.dx * eBot_dr - eMaj_dr * eBot.dx);
@@ -488,23 +374,13 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
          span.attrStepY[FRAG_ATTRIB_COL0][1] = oneOverArea * (eMaj.dx * eBot_dg - eMaj_dg * eBot.dx);
          span.attrStepX[FRAG_ATTRIB_COL0][2] = oneOverArea * (eMaj_db * eBot.dy - eMaj.dy * eBot_db);
          span.attrStepY[FRAG_ATTRIB_COL0][2] = oneOverArea * (eMaj.dx * eBot_db - eMaj_db * eBot.dx);
-#  if CHAN_TYPE == GL_FLOAT
-         span.redStep   = span.attrStepX[FRAG_ATTRIB_COL0][0];
-         span.greenStep = span.attrStepX[FRAG_ATTRIB_COL0][1];
-         span.blueStep  = span.attrStepX[FRAG_ATTRIB_COL0][2];
-#  else
          span.redStep   = SignedFloatToFixed(span.attrStepX[FRAG_ATTRIB_COL0][0]);
          span.greenStep = SignedFloatToFixed(span.attrStepX[FRAG_ATTRIB_COL0][1]);
          span.blueStep  = SignedFloatToFixed(span.attrStepX[FRAG_ATTRIB_COL0][2]);
-#  endif /* GL_FLOAT */
 #  ifdef INTERP_ALPHA
          span.attrStepX[FRAG_ATTRIB_COL0][3] = oneOverArea * (eMaj_da * eBot.dy - eMaj.dy * eBot_da);
          span.attrStepY[FRAG_ATTRIB_COL0][3] = oneOverArea * (eMaj.dx * eBot_da - eMaj_da * eBot.dx);
-#    if CHAN_TYPE == GL_FLOAT
-         span.alphaStep = span.attrStepX[FRAG_ATTRIB_COL0][3];
-#    else
          span.alphaStep = SignedFloatToFixed(span.attrStepX[FRAG_ATTRIB_COL0][3]);
-#    endif /* GL_FLOAT */
 #  endif /* INTERP_ALPHA */
       }
       else {
@@ -513,70 +389,20 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
          span.attrStepX[FRAG_ATTRIB_COL0][0] = span.attrStepY[FRAG_ATTRIB_COL0][0] = 0.0F;
          span.attrStepX[FRAG_ATTRIB_COL0][1] = span.attrStepY[FRAG_ATTRIB_COL0][1] = 0.0F;
          span.attrStepX[FRAG_ATTRIB_COL0][2] = span.attrStepY[FRAG_ATTRIB_COL0][2] = 0.0F;
-#    if CHAN_TYPE == GL_FLOAT
-	 span.redStep   = 0.0F;
-	 span.greenStep = 0.0F;
-	 span.blueStep  = 0.0F;
-#    else
 	 span.redStep   = 0;
 	 span.greenStep = 0;
 	 span.blueStep  = 0;
-#    endif /* GL_FLOAT */
 #  ifdef INTERP_ALPHA
-         span.attrStepX[FRAG_ATTRIB_COL0][3] = span.attrStepY[FRAG_ATTRIB_COL0][3] = 0.0F;
-#    if CHAN_TYPE == GL_FLOAT
-	 span.alphaStep = 0.0F;
-#    else
+         span.attrStepX[FRAG_ATTRIB_COL0][3] = span.attrStepX[FRAG_ATTRIB_COL0][3] = 0.0F;
 	 span.alphaStep = 0;
-#    endif /* GL_FLOAT */
 #  endif
       }
 #endif /* INTERP_RGB */
-#ifdef INTERP_SPEC
-      span.interpMask |= SPAN_SPEC;
-      if (ctx->Light.ShadeModel == GL_SMOOTH) {
-         GLfloat eMaj_dsr = (GLfloat) ((ColorTemp) vMax->specular[RCOMP] - (ColorTemp) vMin->specular[RCOMP]);
-         GLfloat eBot_dsr = (GLfloat) ((ColorTemp) vMid->specular[RCOMP] - (ColorTemp) vMin->specular[RCOMP]);
-         GLfloat eMaj_dsg = (GLfloat) ((ColorTemp) vMax->specular[GCOMP] - (ColorTemp) vMin->specular[GCOMP]);
-         GLfloat eBot_dsg = (GLfloat) ((ColorTemp) vMid->specular[GCOMP] - (ColorTemp) vMin->specular[GCOMP]);
-         GLfloat eMaj_dsb = (GLfloat) ((ColorTemp) vMax->specular[BCOMP] - (ColorTemp) vMin->specular[BCOMP]);
-         GLfloat eBot_dsb = (GLfloat) ((ColorTemp) vMid->specular[BCOMP] - (ColorTemp) vMin->specular[BCOMP]);
-         span.attrStepX[FRAG_ATTRIB_COL1][0] = oneOverArea * (eMaj_dsr * eBot.dy - eMaj.dy * eBot_dsr);
-         span.attrStepY[FRAG_ATTRIB_COL1][0] = oneOverArea * (eMaj.dx * eBot_dsr - eMaj_dsr * eBot.dx);
-         span.attrStepX[FRAG_ATTRIB_COL1][1] = oneOverArea * (eMaj_dsg * eBot.dy - eMaj.dy * eBot_dsg);
-         span.attrStepY[FRAG_ATTRIB_COL1][1] = oneOverArea * (eMaj.dx * eBot_dsg - eMaj_dsg * eBot.dx);
-         span.attrStepX[FRAG_ATTRIB_COL1][2] = oneOverArea * (eMaj_dsb * eBot.dy - eMaj.dy * eBot_dsb);
-         span.attrStepY[FRAG_ATTRIB_COL1][2] = oneOverArea * (eMaj.dx * eBot_dsb - eMaj_dsb * eBot.dx);
-#  if CHAN_TYPE == GL_FLOAT
-         span.specRedStep   = span.attrStepX[FRAG_ATTRIB_COL1][0];
-         span.specGreenStep = span.attrStepX[FRAG_ATTRIB_COL1][1];
-         span.specBlueStep  = span.attrStepX[FRAG_ATTRIB_COL1][2];
-#  else
-         span.specRedStep   = SignedFloatToFixed(span.attrStepX[FRAG_ATTRIB_COL1][0]);
-         span.specGreenStep = SignedFloatToFixed(span.attrStepX[FRAG_ATTRIB_COL1][1]);
-         span.specBlueStep  = SignedFloatToFixed(span.attrStepX[FRAG_ATTRIB_COL1][2]);
-#  endif
-      }
-      else {
-         span.attrStepX[FRAG_ATTRIB_COL1][0] = span.attrStepY[FRAG_ATTRIB_COL1][0] = 0.0F;
-         span.attrStepX[FRAG_ATTRIB_COL1][1] = span.attrStepY[FRAG_ATTRIB_COL1][1] = 0.0F;
-         span.attrStepX[FRAG_ATTRIB_COL1][2] = span.attrStepY[FRAG_ATTRIB_COL1][2] = 0.0F;
-#  if CHAN_TYPE == GL_FLOAT
-	 span.specRedStep   = 0.0F;
-	 span.specGreenStep = 0.0F;
-	 span.specBlueStep  = 0.0F;
-#  else
-	 span.specRedStep   = 0;
-	 span.specGreenStep = 0;
-	 span.specBlueStep  = 0;
-#  endif
-      }
-#endif /* INTERP_SPEC */
 #ifdef INTERP_INDEX
       span.interpMask |= SPAN_INDEX;
       if (ctx->Light.ShadeModel == GL_SMOOTH) {
-         GLfloat eMaj_di = vMax->index - vMin->index;
-         GLfloat eBot_di = vMid->index - vMin->index;
+         GLfloat eMaj_di = vMax->attrib[FRAG_ATTRIB_CI][0] - vMin->attrib[FRAG_ATTRIB_CI][0];
+         GLfloat eBot_di = vMid->attrib[FRAG_ATTRIB_CI][0] - vMin->attrib[FRAG_ATTRIB_CI][0];
          didx = oneOverArea * (eMaj_di * eBot.dy - eMaj.dy * eBot_di);
          didy = oneOverArea * (eMaj.dx * eBot_di - eMaj_di * eBot.dx);
          span.indexStep = SignedFloatToFixed(didx);
@@ -588,7 +414,6 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
       }
 #endif
 #ifdef INTERP_INT_TEX
-      span.interpMask |= SPAN_INT_TEXTURE;
       {
          GLfloat eMaj_ds = (vMax->attrib[FRAG_ATTRIB_TEX0][0] - vMin->attrib[FRAG_ATTRIB_TEX0][0]) * S_SCALE;
          GLfloat eBot_ds = (vMid->attrib[FRAG_ATTRIB_TEX0][0] - vMin->attrib[FRAG_ATTRIB_TEX0][0]) * S_SCALE;
@@ -603,27 +428,31 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
       }
 #endif
 #ifdef INTERP_ATTRIBS
-      span.interpMask |= (SPAN_TEXTURE | SPAN_VARYING);
       {
-         /* win[3] is 1/W */
-         const GLfloat wMax = vMax->win[3], wMin = vMin->win[3], wMid = vMid->win[3];
+         /* attrib[FRAG_ATTRIB_WPOS][3] is 1/W */
+         const GLfloat wMax = vMax->attrib[FRAG_ATTRIB_WPOS][3];
+         const GLfloat wMin = vMin->attrib[FRAG_ATTRIB_WPOS][3];
+         const GLfloat wMid = vMid->attrib[FRAG_ATTRIB_WPOS][3];
+         {
+            const GLfloat eMaj_dw = wMax - wMin;
+            const GLfloat eBot_dw = wMid - wMin;
+            span.attrStepX[FRAG_ATTRIB_WPOS][3] = oneOverArea * (eMaj_dw * eBot.dy - eMaj.dy * eBot_dw);
+            span.attrStepY[FRAG_ATTRIB_WPOS][3] = oneOverArea * (eMaj.dx * eBot_dw - eMaj_dw * eBot.dx);
+         }
          ATTRIB_LOOP_BEGIN
-            GLfloat eMaj_ds = vMax->attrib[attr][0] * wMax - vMin->attrib[attr][0] * wMin;
-            GLfloat eBot_ds = vMid->attrib[attr][0] * wMid - vMin->attrib[attr][0] * wMin;
-            GLfloat eMaj_dt = vMax->attrib[attr][1] * wMax - vMin->attrib[attr][1] * wMin;
-            GLfloat eBot_dt = vMid->attrib[attr][1] * wMid - vMin->attrib[attr][1] * wMin;
-            GLfloat eMaj_du = vMax->attrib[attr][2] * wMax - vMin->attrib[attr][2] * wMin;
-            GLfloat eBot_du = vMid->attrib[attr][2] * wMid - vMin->attrib[attr][2] * wMin;
-            GLfloat eMaj_dv = vMax->attrib[attr][3] * wMax - vMin->attrib[attr][3] * wMin;
-            GLfloat eBot_dv = vMid->attrib[attr][3] * wMid - vMin->attrib[attr][3] * wMin;
-            span.attrStepX[attr][0] = oneOverArea * (eMaj_ds * eBot.dy - eMaj.dy * eBot_ds);
-            span.attrStepY[attr][0] = oneOverArea * (eMaj.dx * eBot_ds - eMaj_ds * eBot.dx);
-            span.attrStepX[attr][1] = oneOverArea * (eMaj_dt * eBot.dy - eMaj.dy * eBot_dt);
-            span.attrStepY[attr][1] = oneOverArea * (eMaj.dx * eBot_dt - eMaj_dt * eBot.dx);
-            span.attrStepX[attr][2] = oneOverArea * (eMaj_du * eBot.dy - eMaj.dy * eBot_du);
-            span.attrStepY[attr][2] = oneOverArea * (eMaj.dx * eBot_du - eMaj_du * eBot.dx);
-            span.attrStepX[attr][3] = oneOverArea * (eMaj_dv * eBot.dy - eMaj.dy * eBot_dv);
-            span.attrStepY[attr][3] = oneOverArea * (eMaj.dx * eBot_dv - eMaj_dv * eBot.dx);
+            if (swrast->_InterpMode[attr] == GL_FLAT) {
+               ASSIGN_4V(span.attrStepX[attr], 0.0, 0.0, 0.0, 0.0);
+               ASSIGN_4V(span.attrStepY[attr], 0.0, 0.0, 0.0, 0.0);
+            }
+            else {
+               GLuint c;
+               for (c = 0; c < 4; c++) {
+                  GLfloat eMaj_da = vMax->attrib[attr][c] * wMax - vMin->attrib[attr][c] * wMin;
+                  GLfloat eBot_da = vMid->attrib[attr][c] * wMid - vMin->attrib[attr][c] * wMin;
+                  span.attrStepX[attr][c] = oneOverArea * (eMaj_da * eBot.dy - eMaj.dy * eBot_da);
+                  span.attrStepY[attr][c] = oneOverArea * (eMaj.dx * eBot_da - eMaj_da * eBot.dx);
+               }
+            }
          ATTRIB_LOOP_END
       }
 #endif
@@ -677,9 +506,9 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
 
       {
          GLint subTriangle;
-         GLinterp fxLeftEdge = 0, fxRightEdge = 0;
-         GLinterp fdxLeftEdge = 0, fdxRightEdge = 0;
-         GLinterp fError = 0, fdError = 0;
+         GLfixed fxLeftEdge = 0, fxRightEdge = 0;
+         GLfixed fdxLeftEdge = 0, fdxRightEdge = 0;
+         GLfixed fError = 0, fdError = 0;
 #ifdef PIXEL_ADDRESS
          PIXEL_TYPE *pRow = NULL;
          GLint dPRowOuter = 0, dPRowInner;  /* offset in bytes */
@@ -694,24 +523,13 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
          GLuint zLeft = 0;
          GLfixed fdzOuter = 0, fdzInner;
 #endif
-#ifdef INTERP_W
-         GLfloat wLeft = 0, dwOuter = 0, dwInner;
-#endif
-#ifdef INTERP_FOG
-         GLfloat fogLeft = 0, dfogOuter = 0, dfogInner;
-#endif
 #ifdef INTERP_RGB
-         ColorTemp rLeft = 0, fdrOuter = 0, fdrInner;
-         ColorTemp gLeft = 0, fdgOuter = 0, fdgInner;
-         ColorTemp bLeft = 0, fdbOuter = 0, fdbInner;
+         GLint rLeft = 0, fdrOuter = 0, fdrInner;
+         GLint gLeft = 0, fdgOuter = 0, fdgInner;
+         GLint bLeft = 0, fdbOuter = 0, fdbInner;
 #endif
 #ifdef INTERP_ALPHA
-         ColorTemp aLeft = 0, fdaOuter = 0, fdaInner;
-#endif
-#ifdef INTERP_SPEC
-         ColorTemp srLeft=0, dsrOuter=0, dsrInner;
-         ColorTemp sgLeft=0, dsgOuter=0, dsgInner;
-         ColorTemp sbLeft=0, dsbOuter=0, dsbInner;
+         GLint aLeft = 0, fdaOuter = 0, fdaInner;
 #endif
 #ifdef INTERP_INDEX
          GLfixed iLeft=0, diOuter=0, diInner;
@@ -721,14 +539,9 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
          GLfixed tLeft=0, dtOuter=0, dtInner;
 #endif
 #ifdef INTERP_ATTRIBS
-         GLfloat sLeft[FRAG_ATTRIB_MAX];
-         GLfloat tLeft[FRAG_ATTRIB_MAX];
-         GLfloat uLeft[FRAG_ATTRIB_MAX];
-         GLfloat vLeft[FRAG_ATTRIB_MAX];
-         GLfloat dsOuter[FRAG_ATTRIB_MAX], dsInner[FRAG_ATTRIB_MAX];
-         GLfloat dtOuter[FRAG_ATTRIB_MAX], dtInner[FRAG_ATTRIB_MAX];
-         GLfloat duOuter[FRAG_ATTRIB_MAX], duInner[FRAG_ATTRIB_MAX];
-         GLfloat dvOuter[FRAG_ATTRIB_MAX], dvInner[FRAG_ATTRIB_MAX];
+         GLfloat wLeft = 0, dwOuter = 0, dwInner;
+         GLfloat attrLeft[FRAG_ATTRIB_MAX][4];
+         GLfloat daOuter[FRAG_ATTRIB_MAX][4], daInner[FRAG_ATTRIB_MAX][4];
 #endif
 
          for (subTriangle=0; subTriangle<=1; subTriangle++) {
@@ -775,30 +588,12 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
 
             if (setupLeft && eLeft->lines > 0) {
                const SWvertex *vLower = eLeft->v0;
-#if TRIANGLE_WALK_DOUBLE
-               const GLdouble fsy = eLeft->fsy;
-               const GLdouble fsx = eLeft->fsx;
-               const GLdouble fx = CEILF(fsx);
-               const GLdouble adjx = (fx - eLeft->fx0) * FIXED_SCALE;  /* SCALED! */
-#else
                const GLfixed fsy = eLeft->fsy;
                const GLfixed fsx = eLeft->fsx;  /* no fractional part */
                const GLfixed fx = FixedCeil(fsx);  /* no fractional part */
-               const GLfixed adjx = (GLinterp) (fx - eLeft->fx0); /* SCALED! */
-#endif
-               const GLinterp adjy = (GLinterp) eLeft->adjy;      /* SCALED! */
+               const GLfixed adjx = (GLfixed) (fx - eLeft->fx0); /* SCALED! */
+               const GLfixed adjy = (GLfixed) eLeft->adjy;      /* SCALED! */
                GLint idxOuter;
-#if TRIANGLE_WALK_DOUBLE
-               GLdouble dxOuter;
-
-               fError = fx - fsx - 1.0;
-               fxLeftEdge = fsx;
-               fdxLeftEdge = eLeft->dxdy;
-               dxOuter = FLOORF(fdxLeftEdge);
-               fdError = dxOuter - fdxLeftEdge + 1.0;
-               idxOuter = (GLint) dxOuter;
-               span.y = (GLint) fsy;
-#else
                GLfloat dxOuter;
                GLfixed fdxOuter;
 
@@ -810,7 +605,6 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
                idxOuter = FixedToInt(fdxOuter);
                dxOuter = (GLfloat) idxOuter;
                span.y = FixedToInt(fsy);
-#endif
 
                /* silence warnings on some compilers */
                (void) dxOuter;
@@ -820,7 +614,7 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
 
 #ifdef PIXEL_ADDRESS
                {
-                  pRow = (PIXEL_TYPE *) PIXEL_ADDRESS(InterpToInt(fxLeftEdge), span.y);
+                  pRow = (PIXEL_TYPE *) PIXEL_ADDRESS(FixedToInt(fxLeftEdge), span.y);
                   dPRowOuter = -((int)BYTES_PER_ROW) + idxOuter * sizeof(PIXEL_TYPE);
                   /* negative because Y=0 at bottom and increases upward */
                }
@@ -837,7 +631,7 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
 
 #ifdef INTERP_Z
                {
-                  GLfloat z0 = vLower->win[2];
+                  GLfloat z0 = vLower->attrib[FRAG_ATTRIB_WPOS][2];
                   if (depthBits <= 16) {
                      /* interpolate fixed-pt values */
                      GLfloat tmp = (z0 * FIXED_SCALE
@@ -847,129 +641,71 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
                         zLeft = (GLfixed) tmp;
                      else
                         zLeft = MAX_GLUINT / 2;
-                     fdzOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_WPOS][2] + dxOuter * span.attrStepX[FRAG_ATTRIB_WPOS][2]);
+                     fdzOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_WPOS][2] +
+                                                   dxOuter * span.attrStepX[FRAG_ATTRIB_WPOS][2]);
                   }
                   else {
                      /* interpolate depth values w/out scaling */
                      zLeft = (GLuint) (z0 + span.attrStepX[FRAG_ATTRIB_WPOS][2] * FixedToFloat(adjx)
                                           + span.attrStepY[FRAG_ATTRIB_WPOS][2] * FixedToFloat(adjy));
-                     fdzOuter = (GLint) (span.attrStepY[FRAG_ATTRIB_WPOS][2] + dxOuter * span.attrStepX[FRAG_ATTRIB_WPOS][2]);
+                     fdzOuter = (GLint) (span.attrStepY[FRAG_ATTRIB_WPOS][2] +
+                                         dxOuter * span.attrStepX[FRAG_ATTRIB_WPOS][2]);
                   }
 #  ifdef DEPTH_TYPE
                   zRow = (DEPTH_TYPE *)
-                    zrb->GetPointer(ctx, zrb, InterpToInt(fxLeftEdge), span.y);
+                    zrb->GetPointer(ctx, zrb, FixedToInt(fxLeftEdge), span.y);
                   dZRowOuter = (ctx->DrawBuffer->Width + idxOuter) * sizeof(DEPTH_TYPE);
 #  endif
                }
 #endif
-#ifdef INTERP_W
-               wLeft = vLower->win[3] + (span.attrStepX[FRAG_ATTRIB_WPOS][3] * adjx + span.attrStepY[FRAG_ATTRIB_WPOS][3] * adjy) * (1.0F/FIXED_SCALE);
-               dwOuter = span.attrStepY[FRAG_ATTRIB_WPOS][3] + dxOuter * span.attrStepX[FRAG_ATTRIB_WPOS][3];
-#endif
-#ifdef INTERP_FOG
-#  ifdef INTERP_W
-               fogLeft = vLower->attrib[FRAG_ATTRIB_FOGC][0] * vLower->win[3] + (span.attrStepX[FRAG_ATTRIB_FOGC][0] * adjx + span.attrStepY[FRAG_ATTRIB_FOGC][0] * adjy) * (1.0F/FIXED_SCALE);
-#  else
-               fogLeft = vLower->attrib[FRAG_ATTRIB_FOGC][0] + (span.attrStepX[FRAG_ATTRIB_FOGC][0] * adjx + span.attrStepY[FRAG_ATTRIB_FOGC][0] * adjy) * (1.0F/FIXED_SCALE);
-#  endif
-               dfogOuter = span.attrStepY[FRAG_ATTRIB_FOGC][0] + dxOuter * span.attrStepX[FRAG_ATTRIB_FOGC][0];
-#endif
 #ifdef INTERP_RGB
                if (ctx->Light.ShadeModel == GL_SMOOTH) {
-#  if CHAN_TYPE == GL_FLOAT
-                  rLeft = vLower->color[RCOMP] + (span.attrStepX[FRAG_ATTRIB_COL0][0] * adjx + span.attrStepY[FRAG_ATTRIB_COL0][0] * adjy) * (1.0F / FIXED_SCALE);
-                  gLeft = vLower->color[GCOMP] + (span.attrStepX[FRAG_ATTRIB_COL0][1] * adjx + span.attrStepY[FRAG_ATTRIB_COL0][1] * adjy) * (1.0F / FIXED_SCALE);
-                  bLeft = vLower->color[BCOMP] + (span.attrStepX[FRAG_ATTRIB_COL0][2] * adjx + span.attrStepY[FRAG_ATTRIB_COL0][2] * adjy) * (1.0F / FIXED_SCALE);
-                  fdrOuter = span.attrStepY[FRAG_ATTRIB_COL0][0] + dxOuter * span.attrStepX[FRAG_ATTRIB_COL0][0];
-                  fdgOuter = span.attrStepY[FRAG_ATTRIB_COL0][1] + dxOuter * span.attrStepX[FRAG_ATTRIB_COL0][1];
-                  fdbOuter = span.attrStepY[FRAG_ATTRIB_COL0][2] + dxOuter * span.attrStepX[FRAG_ATTRIB_COL0][2];
-#  else
-                  rLeft = (GLint)(ChanToFixed(vLower->color[RCOMP]) + span.attrStepX[FRAG_ATTRIB_COL0][0] * adjx + span.attrStepY[FRAG_ATTRIB_COL0][0] * adjy) + FIXED_HALF;
-                  gLeft = (GLint)(ChanToFixed(vLower->color[GCOMP]) + span.attrStepX[FRAG_ATTRIB_COL0][1] * adjx + span.attrStepY[FRAG_ATTRIB_COL0][1] * adjy) + FIXED_HALF;
-                  bLeft = (GLint)(ChanToFixed(vLower->color[BCOMP]) + span.attrStepX[FRAG_ATTRIB_COL0][2] * adjx + span.attrStepY[FRAG_ATTRIB_COL0][2] * adjy) + FIXED_HALF;
-                  fdrOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_COL0][0] + dxOuter * span.attrStepX[FRAG_ATTRIB_COL0][0]);
-                  fdgOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_COL0][1] + dxOuter * span.attrStepX[FRAG_ATTRIB_COL0][1]);
-                  fdbOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_COL0][2] + dxOuter * span.attrStepX[FRAG_ATTRIB_COL0][2]);
-#  endif
+                  rLeft = (GLint)(ChanToFixed(vLower->color[RCOMP])
+                                  + span.attrStepX[FRAG_ATTRIB_COL0][0] * adjx
+                                  + span.attrStepY[FRAG_ATTRIB_COL0][0] * adjy) + FIXED_HALF;
+                  gLeft = (GLint)(ChanToFixed(vLower->color[GCOMP])
+                                  + span.attrStepX[FRAG_ATTRIB_COL0][1] * adjx
+                                  + span.attrStepY[FRAG_ATTRIB_COL0][1] * adjy) + FIXED_HALF;
+                  bLeft = (GLint)(ChanToFixed(vLower->color[BCOMP])
+                                  + span.attrStepX[FRAG_ATTRIB_COL0][2] * adjx
+                                  + span.attrStepY[FRAG_ATTRIB_COL0][2] * adjy) + FIXED_HALF;
+                  fdrOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_COL0][0]
+                                                + dxOuter * span.attrStepX[FRAG_ATTRIB_COL0][0]);
+                  fdgOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_COL0][1]
+                                                + dxOuter * span.attrStepX[FRAG_ATTRIB_COL0][1]);
+                  fdbOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_COL0][2]
+                                                + dxOuter * span.attrStepX[FRAG_ATTRIB_COL0][2]);
 #  ifdef INTERP_ALPHA
-#    if CHAN_TYPE == GL_FLOAT
-                  aLeft = vLower->color[ACOMP] + (span.attrStepX[FRAG_ATTRIB_COL0][3] * adjx + span.attrStepY[FRAG_ATTRIB_COL0][3] * adjy) * (1.0F / FIXED_SCALE);
-                  fdaOuter = span.attrStepY[FRAG_ATTRIB_COL0][3] + dxOuter * span.attrStepX[FRAG_ATTRIB_COL0][3];
-#    else
-                  aLeft = (GLint)(ChanToFixed(vLower->color[ACOMP]) + span.attrStepX[FRAG_ATTRIB_COL0][3] * adjx + span.attrStepX[FRAG_ATTRIB_COL0][3] * adjy) + FIXED_HALF;
-                  fdaOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_COL0][3] + dxOuter * span.attrStepX[FRAG_ATTRIB_COL0][3]);
-#    endif
+                  aLeft = (GLint)(ChanToFixed(vLower->color[ACOMP])
+                                  + span.attrStepX[FRAG_ATTRIB_COL0][3] * adjx
+                                  + span.attrStepY[FRAG_ATTRIB_COL0][3] * adjy) + FIXED_HALF;
+                  fdaOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_COL0][3]
+                                                + dxOuter * span.attrStepX[FRAG_ATTRIB_COL0][3]);
 #  endif
                }
                else {
                   ASSERT(ctx->Light.ShadeModel == GL_FLAT);
-#  if CHAN_TYPE == GL_FLOAT
-                  rLeft = v2->color[RCOMP];
-                  gLeft = v2->color[GCOMP];
-                  bLeft = v2->color[BCOMP];
-                  fdrOuter = fdgOuter = fdbOuter = 0.0F;
-#  else
                   rLeft = ChanToFixed(v2->color[RCOMP]);
                   gLeft = ChanToFixed(v2->color[GCOMP]);
                   bLeft = ChanToFixed(v2->color[BCOMP]);
                   fdrOuter = fdgOuter = fdbOuter = 0;
-#  endif
 #  ifdef INTERP_ALPHA
-#    if CHAN_TYPE == GL_FLOAT
-                  aLeft = v2->color[ACOMP];
-                  fdaOuter = 0.0F;
-#    else
                   aLeft = ChanToFixed(v2->color[ACOMP]);
                   fdaOuter = 0;
-#    endif
 #  endif
                }
 #endif /* INTERP_RGB */
 
 
-#ifdef INTERP_SPEC
-               if (ctx->Light.ShadeModel == GL_SMOOTH) {
-#  if CHAN_TYPE == GL_FLOAT
-                  srLeft = vLower->specular[RCOMP] + (span.attrStepX[FRAG_ATTRIB_COL1][0] * adjx + span.attrStepY[FRAG_ATTRIB_COL1][0] * adjy) * (1.0F / FIXED_SCALE);
-                  sgLeft = vLower->specular[GCOMP] + (span.attrStepX[FRAG_ATTRIB_COL1][1] * adjx + span.attrStepY[FRAG_ATTRIB_COL1][1] * adjy) * (1.0F / FIXED_SCALE);
-                  sbLeft = vLower->specular[BCOMP] + (span.attrStepX[FRAG_ATTRIB_COL1][2] * adjx + span.attrStepY[FRAG_ATTRIB_COL1][2] * adjy) * (1.0F / FIXED_SCALE);
-                  dsrOuter = span.attrStepY[FRAG_ATTRIB_COL1][0] + dxOuter * span.attrStepX[FRAG_ATTRIB_COL1][0];
-                  dsgOuter = span.attrStepY[FRAG_ATTRIB_COL1][1] + dxOuter * span.attrStepX[FRAG_ATTRIB_COL1][1];
-                  dsbOuter = span.attrStepY[FRAG_ATTRIB_COL1][2] + dxOuter * span.attrStepX[FRAG_ATTRIB_COL1][2];
-#  else
-                  srLeft = (GLfixed) (ChanToFixed(vLower->specular[RCOMP]) + span.attrStepX[FRAG_ATTRIB_COL1][0] * adjx + span.attrStepY[FRAG_ATTRIB_COL1][0] * adjy) + FIXED_HALF;
-                  sgLeft = (GLfixed) (ChanToFixed(vLower->specular[GCOMP]) + span.attrStepX[FRAG_ATTRIB_COL1][1] * adjx + span.attrStepY[FRAG_ATTRIB_COL1][1] * adjy) + FIXED_HALF;
-                  sbLeft = (GLfixed) (ChanToFixed(vLower->specular[BCOMP]) + span.attrStepX[FRAG_ATTRIB_COL1][2] * adjx + span.attrStepY[FRAG_ATTRIB_COL1][2] * adjy) + FIXED_HALF;
-                  dsrOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_COL1][0] + dxOuter * span.attrStepX[FRAG_ATTRIB_COL1][0]);
-                  dsgOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_COL1][1] + dxOuter * span.attrStepX[FRAG_ATTRIB_COL1][1]);
-                  dsbOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_COL1][2] + dxOuter * span.attrStepX[FRAG_ATTRIB_COL1][2]);
-#  endif
-               }
-               else {
-                  ASSERT(ctx->Light.ShadeModel == GL_FLAT);
-#if  CHAN_TYPE == GL_FLOAT
-                  srLeft = v2->specular[RCOMP];
-                  sgLeft = v2->specular[GCOMP];
-                  sbLeft = v2->specular[BCOMP];
-                  dsrOuter = dsgOuter = dsbOuter = 0.0F;
-#  else
-                  srLeft = ChanToFixed(v2->specular[RCOMP]);
-                  sgLeft = ChanToFixed(v2->specular[GCOMP]);
-                  sbLeft = ChanToFixed(v2->specular[BCOMP]);
-                  dsrOuter = dsgOuter = dsbOuter = 0;
-#  endif
-               }
-#endif
-
 #ifdef INTERP_INDEX
                if (ctx->Light.ShadeModel == GL_SMOOTH) {
-                  iLeft = (GLfixed)(vLower->index * FIXED_SCALE
+                  iLeft = (GLfixed)(vLower->attrib[FRAG_ATTRIB_CI][0] * FIXED_SCALE
                                  + didx * adjx + didy * adjy) + FIXED_HALF;
                   diOuter = SignedFloatToFixed(didy + dxOuter * didx);
                }
                else {
                   ASSERT(ctx->Light.ShadeModel == GL_FLAT);
-                  iLeft = FloatToFixed(v2->index);
+                  iLeft = FloatToFixed(v2->attrib[FRAG_ATTRIB_CI][0]);
                   diOuter = 0;
                }
 #endif
@@ -979,42 +715,50 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
                   s0 = vLower->attrib[FRAG_ATTRIB_TEX0][0] * S_SCALE;
                   sLeft = (GLfixed)(s0 * FIXED_SCALE + span.attrStepX[FRAG_ATTRIB_TEX0][0] * adjx
                                  + span.attrStepY[FRAG_ATTRIB_TEX0][0] * adjy) + FIXED_HALF;
-                  dsOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_TEX0][0] + dxOuter * span.attrStepX[FRAG_ATTRIB_TEX0][0]);
+                  dsOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_TEX0][0]
+                                               + dxOuter * span.attrStepX[FRAG_ATTRIB_TEX0][0]);
 
                   t0 = vLower->attrib[FRAG_ATTRIB_TEX0][1] * T_SCALE;
                   tLeft = (GLfixed)(t0 * FIXED_SCALE + span.attrStepX[FRAG_ATTRIB_TEX0][1] * adjx
                                  + span.attrStepY[FRAG_ATTRIB_TEX0][1] * adjy) + FIXED_HALF;
-                  dtOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_TEX0][1] + dxOuter * span.attrStepX[FRAG_ATTRIB_TEX0][1]);
+                  dtOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_TEX0][1]
+                                               + dxOuter * span.attrStepX[FRAG_ATTRIB_TEX0][1]);
                }
 #endif
 #ifdef INTERP_ATTRIBS
+               {
+                  const GLuint attr = FRAG_ATTRIB_WPOS;
+                  wLeft = vLower->attrib[FRAG_ATTRIB_WPOS][3]
+                        + (span.attrStepX[attr][3] * adjx
+                           + span.attrStepY[attr][3] * adjy) * (1.0F/FIXED_SCALE);
+                  dwOuter = span.attrStepY[attr][3] + dxOuter * span.attrStepX[attr][3];
+               }
                ATTRIB_LOOP_BEGIN
-                  const GLfloat invW = vLower->win[3];
-                  const GLfloat s0 = vLower->attrib[attr][0] * invW;
-                  const GLfloat t0 = vLower->attrib[attr][1] * invW;
-                  const GLfloat u0 = vLower->attrib[attr][2] * invW;
-                  const GLfloat v0 = vLower->attrib[attr][3] * invW;
-                  sLeft[attr] = s0 + (span.attrStepX[attr][0] * adjx + span.attrStepY[attr][0] * adjy) * (1.0F/FIXED_SCALE);
-                  tLeft[attr] = t0 + (span.attrStepX[attr][1] * adjx + span.attrStepY[attr][1] * adjy) * (1.0F/FIXED_SCALE);
-                  uLeft[attr] = u0 + (span.attrStepX[attr][2] * adjx + span.attrStepY[attr][2] * adjy) * (1.0F/FIXED_SCALE);
-                  vLeft[attr] = v0 + (span.attrStepX[attr][3] * adjx + span.attrStepY[attr][3] * adjy) * (1.0F/FIXED_SCALE);
-                  dsOuter[attr] = span.attrStepY[attr][0] + dxOuter * span.attrStepX[attr][0];
-                  dtOuter[attr] = span.attrStepY[attr][1] + dxOuter * span.attrStepX[attr][1];
-                  duOuter[attr] = span.attrStepY[attr][2] + dxOuter * span.attrStepX[attr][2];
-                  dvOuter[attr] = span.attrStepY[attr][3] + dxOuter * span.attrStepX[attr][3];
+                  const GLfloat invW = vLower->attrib[FRAG_ATTRIB_WPOS][3];
+                  if (swrast->_InterpMode[attr] == GL_FLAT) {
+                     GLuint c;
+                     for (c = 0; c < 4; c++) {
+                        attrLeft[attr][c] = v2->attrib[attr][c] * invW;
+                        daOuter[attr][c] = 0.0;
+                     }
+                  }
+                  else {
+                     GLuint c;
+                     for (c = 0; c < 4; c++) {
+                        const GLfloat a = vLower->attrib[attr][c] * invW;
+                        attrLeft[attr][c] = a + (  span.attrStepX[attr][c] * adjx
+                                                 + span.attrStepY[attr][c] * adjy) * (1.0F/FIXED_SCALE);
+                        daOuter[attr][c] = span.attrStepY[attr][c] + dxOuter * span.attrStepX[attr][c];
+                     }
+                  }
                ATTRIB_LOOP_END
 #endif
             } /*if setupLeft*/
 
 
             if (setupRight && eRight->lines>0) {
-#if TRIANGLE_WALK_DOUBLE
-               fxRightEdge = eRight->fsx;
-               fdxRightEdge = eRight->dxdy;
-#else
                fxRightEdge = eRight->fsx - FIXED_EPSILON;
                fdxRightEdge = eRight->fdxdy;
-#endif
             }
 
             if (lines==0) {
@@ -1032,12 +776,6 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
 #  endif
             fdzInner = fdzOuter + span.zStep;
 #endif
-#ifdef INTERP_W
-            dwInner = dwOuter + span.attrStepX[FRAG_ATTRIB_WPOS][3];
-#endif
-#ifdef INTERP_FOG
-            dfogInner = dfogOuter + span.attrStepX[FRAG_ATTRIB_FOGC][0];
-#endif
 #ifdef INTERP_RGB
             fdrInner = fdrOuter + span.redStep;
             fdgInner = fdgOuter + span.greenStep;
@@ -1046,11 +784,6 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
 #ifdef INTERP_ALPHA
             fdaInner = fdaOuter + span.alphaStep;
 #endif
-#ifdef INTERP_SPEC
-            dsrInner = dsrOuter + span.specRedStep;
-            dsgInner = dsgOuter + span.specGreenStep;
-            dsbInner = dsbOuter + span.specBlueStep;
-#endif
 #ifdef INTERP_INDEX
             diInner = diOuter + span.indexStep;
 #endif
@@ -1059,19 +792,20 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
             dtInner = dtOuter + span.intTexStep[1];
 #endif
 #ifdef INTERP_ATTRIBS
+            dwInner = dwOuter + span.attrStepX[FRAG_ATTRIB_WPOS][3];
             ATTRIB_LOOP_BEGIN
-               dsInner[attr] = dsOuter[attr] + span.attrStepX[attr][0];
-               dtInner[attr] = dtOuter[attr] + span.attrStepX[attr][1];
-               duInner[attr] = duOuter[attr] + span.attrStepX[attr][2];
-               dvInner[attr] = dvOuter[attr] + span.attrStepX[attr][3];
+               GLuint c;
+               for (c = 0; c < 4; c++) {
+                  daInner[attr][c] = daOuter[attr][c] + span.attrStepX[attr][c];
+               }
             ATTRIB_LOOP_END
 #endif
 
             while (lines > 0) {
                /* initialize the span interpolants to the leftmost value */
                /* ff = fixed-pt fragment */
-               const GLint right = InterpToInt(fxRightEdge);
-               span.x = InterpToInt(fxLeftEdge);
+               const GLint right = FixedToInt(fxRightEdge);
+               span.x = FixedToInt(fxLeftEdge);
                if (right <= span.x)
                   span.end = 0;
                else
@@ -1080,12 +814,6 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
 #ifdef INTERP_Z
                span.z = zLeft;
 #endif
-#ifdef INTERP_W
-               span.attrStart[FRAG_ATTRIB_WPOS][3] = wLeft;
-#endif
-#ifdef INTERP_FOG
-               span.attrStart[FRAG_ATTRIB_FOGC][0] = fogLeft;
-#endif
 #ifdef INTERP_RGB
                span.red = rLeft;
                span.green = gLeft;
@@ -1094,11 +822,6 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
 #ifdef INTERP_ALPHA
                span.alpha = aLeft;
 #endif
-#ifdef INTERP_SPEC
-               span.specRed = srLeft;
-               span.specGreen = sgLeft;
-               span.specBlue = sbLeft;
-#endif
 #ifdef INTERP_INDEX
                span.index = iLeft;
 #endif
@@ -1108,11 +831,12 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
 #endif
 
 #ifdef INTERP_ATTRIBS
+               span.attrStart[FRAG_ATTRIB_WPOS][3] = wLeft;
                ATTRIB_LOOP_BEGIN
-                  span.attrStart[attr][0] = sLeft[attr];
-                  span.attrStart[attr][1] = tLeft[attr];
-                  span.attrStart[attr][2] = uLeft[attr];
-                  span.attrStart[attr][3] = vLeft[attr];
+                  GLuint c;
+                  for (c = 0; c < 4; c++) {
+                     span.attrStart[attr][c] = attrLeft[attr][c];
+                  }
                ATTRIB_LOOP_END
 #endif
 
@@ -1131,11 +855,6 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
 #ifdef INTERP_ALPHA
                   CLAMP_INTERPOLANT(alpha, alphaStep, len);
 #endif
-#ifdef INTERP_SPEC
-                  CLAMP_INTERPOLANT(specRed, specRedStep, len);
-                  CLAMP_INTERPOLANT(specGreen, specGreenStep, len);
-                  CLAMP_INTERPOLANT(specBlue, specBlueStep, len);
-#endif
 #ifdef INTERP_INDEX
                   CLAMP_INTERPOLANT(index, indexStep, len);
 #endif
@@ -1158,7 +877,7 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
 
                fError += fdError;
                if (fError >= 0) {
-                  fError -= INTERP_ONE;
+                  fError -= FIXED_ONE;
 
 #ifdef PIXEL_ADDRESS
                   pRow = (PIXEL_TYPE *) ((GLubyte *) pRow + dPRowOuter);
@@ -1169,12 +888,6 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
 #  endif
                   zLeft += fdzOuter;
 #endif
-#ifdef INTERP_W
-                  wLeft += dwOuter;
-#endif
-#ifdef INTERP_FOG
-                  fogLeft += dfogOuter;
-#endif
 #ifdef INTERP_RGB
                   rLeft += fdrOuter;
                   gLeft += fdgOuter;
@@ -1183,11 +896,6 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
 #ifdef INTERP_ALPHA
                   aLeft += fdaOuter;
 #endif
-#ifdef INTERP_SPEC
-                  srLeft += dsrOuter;
-                  sgLeft += dsgOuter;
-                  sbLeft += dsbOuter;
-#endif
 #ifdef INTERP_INDEX
                   iLeft += diOuter;
 #endif
@@ -1196,11 +904,12 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
                   tLeft += dtOuter;
 #endif
 #ifdef INTERP_ATTRIBS
+                  wLeft += dwOuter;
                   ATTRIB_LOOP_BEGIN
-                     sLeft[attr] += dsOuter[attr];
-                     tLeft[attr] += dtOuter[attr];
-                     uLeft[attr] += duOuter[attr];
-                     vLeft[attr] += dvOuter[attr];
+                     GLuint c;
+                     for (c = 0; c < 4; c++) {
+                        attrLeft[attr][c] += daOuter[attr][c];
+                     }
                   ATTRIB_LOOP_END
 #endif
                }
@@ -1214,12 +923,6 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
 #  endif
                   zLeft += fdzInner;
 #endif
-#ifdef INTERP_W
-                  wLeft += dwInner;
-#endif
-#ifdef INTERP_FOG
-                  fogLeft += dfogInner;
-#endif
 #ifdef INTERP_RGB
                   rLeft += fdrInner;
                   gLeft += fdgInner;
@@ -1228,11 +931,6 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
 #ifdef INTERP_ALPHA
                   aLeft += fdaInner;
 #endif
-#ifdef INTERP_SPEC
-                  srLeft += dsrInner;
-                  sgLeft += dsgInner;
-                  sbLeft += dsbInner;
-#endif
 #ifdef INTERP_INDEX
                   iLeft += diInner;
 #endif
@@ -1241,11 +939,12 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
                   tLeft += dtInner;
 #endif
 #ifdef INTERP_ATTRIBS
+                  wLeft += dwInner;
                   ATTRIB_LOOP_BEGIN
-                     sLeft[attr] += dsInner[attr];
-                     tLeft[attr] += dtInner[attr];
-                     uLeft[attr] += duInner[attr];
-                     vLeft[attr] += dvInner[attr];
+                     GLuint c;
+                     for (c = 0; c < 4; c++) {
+                        attrLeft[attr][c] += daInner[attr][c];
+                     }
                   ATTRIB_LOOP_END
 #endif
                }
@@ -1254,14 +953,10 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
          } /* for subTriangle */
 
       }
-#ifdef CLEANUP_CODE
-      CLEANUP_CODE
-#endif
    }
 }
 
 #undef SETUP_CODE
-#undef CLEANUP_CODE
 #undef RENDER_SPAN
 
 #undef PIXEL_TYPE
@@ -1270,24 +965,15 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
 #undef DEPTH_TYPE
 
 #undef INTERP_Z
-#undef INTERP_W
-#undef INTERP_FOG
 #undef INTERP_RGB
 #undef INTERP_ALPHA
-#undef INTERP_SPEC
 #undef INTERP_INDEX
 #undef INTERP_INT_TEX
 #undef INTERP_ATTRIBS
-#undef TEX_UNIT_LOOP
-#undef VARYING_LOOP
 
 #undef S_SCALE
 #undef T_SCALE
 
 #undef FixedToDepth
-#undef ColorTemp
-#undef GLinterp
-#undef InterpToInt
-#undef INTERP_ONE
 
 #undef NAME
diff --git a/src/mesa/swrast/s_zoom.c b/src/mesa/swrast/s_zoom.c
index 0908265fe9..78fa137d3f 100644
--- a/src/mesa/swrast/s_zoom.c
+++ b/src/mesa/swrast/s_zoom.c
@@ -155,14 +155,11 @@ zoom_span( GLcontext *ctx, GLint imgX, GLint imgY, const SWspan *span,
    zoomed_arrays.ChanType = span->array->ChanType;
    /* XXX temporary */
 #if CHAN_TYPE == GL_UNSIGNED_BYTE
-   zoomed_arrays.rgba = zoomed_arrays.color.sz1.rgba;
-   zoomed_arrays.spec = zoomed_arrays.color.sz1.spec;
+   zoomed_arrays.rgba = zoomed_arrays.rgba8;
 #elif CHAN_TYPE == GL_UNSIGNED_SHORT
-   zoomed_arrays.rgba = zoomed_arrays.color.sz2.rgba;
-   zoomed_arrays.spec = zoomed_arrays.color.sz2.spec;
+   zoomed_arrays.rgba = zoomed_arrays.rgba16;
 #else
    zoomed_arrays.rgba = zoomed_arrays.attribs[FRAG_ATTRIB_COL0];
-   zoomed_arrays.spec = zoomed_arrays.attribs[FRAG_ATTRIB_COL1];
 #endif
 
 
@@ -219,7 +216,7 @@ zoom_span( GLcontext *ctx, GLint imgX, GLint imgY, const SWspan *span,
             GLint j = unzoom_x(ctx->Pixel.ZoomX, imgX, x0 + i) - span->x;
             ASSERT(j >= 0);
             ASSERT(j < (GLint) span->end);
-            COPY_4UBV(zoomed.array->color.sz1.rgba[i], rgba[j]);
+            COPY_4UBV(zoomed.array->rgba8[i], rgba[j]);
          }
       }
       else if (zoomed.array->ChanType == GL_UNSIGNED_SHORT) {
@@ -229,7 +226,7 @@ zoom_span( GLcontext *ctx, GLint imgX, GLint imgY, const SWspan *span,
             GLint j = unzoom_x(ctx->Pixel.ZoomX, imgX, x0 + i) - span->x;
             ASSERT(j >= 0);
             ASSERT(j < (GLint) span->end);
-            COPY_4V(zoomed.array->color.sz2.rgba[i], rgba[j]);
+            COPY_4V(zoomed.array->rgba16[i], rgba[j]);
          }
       }
       else {
@@ -251,10 +248,10 @@ zoom_span( GLcontext *ctx, GLint imgX, GLint imgY, const SWspan *span,
             GLint j = unzoom_x(ctx->Pixel.ZoomX, imgX, x0 + i) - span->x;
             ASSERT(j >= 0);
             ASSERT(j < (GLint) span->end);
-            zoomed.array->color.sz1.rgba[i][0] = rgb[j][0];
-            zoomed.array->color.sz1.rgba[i][1] = rgb[j][1];
-            zoomed.array->color.sz1.rgba[i][2] = rgb[j][2];
-            zoomed.array->color.sz1.rgba[i][3] = 0xff;
+            zoomed.array->rgba8[i][0] = rgb[j][0];
+            zoomed.array->rgba8[i][1] = rgb[j][1];
+            zoomed.array->rgba8[i][2] = rgb[j][2];
+            zoomed.array->rgba8[i][3] = 0xff;
          }
       }
       else if (zoomed.array->ChanType == GL_UNSIGNED_SHORT) {
@@ -264,10 +261,10 @@ zoom_span( GLcontext *ctx, GLint imgX, GLint imgY, const SWspan *span,
             GLint j = unzoom_x(ctx->Pixel.ZoomX, imgX, x0 + i) - span->x;
             ASSERT(j >= 0);
             ASSERT(j < (GLint) span->end);
-            zoomed.array->color.sz2.rgba[i][0] = rgb[j][0];
-            zoomed.array->color.sz2.rgba[i][1] = rgb[j][1];
-            zoomed.array->color.sz2.rgba[i][2] = rgb[j][2];
-            zoomed.array->color.sz2.rgba[i][3] = 0xffff;
+            zoomed.array->rgba16[i][0] = rgb[j][0];
+            zoomed.array->rgba16[i][1] = rgb[j][1];
+            zoomed.array->rgba16[i][2] = rgb[j][2];
+            zoomed.array->rgba16[i][3] = 0xffff;
          }
       }
       else {
@@ -314,8 +311,7 @@ zoom_span( GLcontext *ctx, GLint imgX, GLint imgY, const SWspan *span,
        * Also, clipping may change the span end value, so store it as well.
        */
       const GLint end = zoomed.end; /* save */
-      /* use specular color array for temp storage */
-      void *rgbaSave = zoomed.array->spec;
+      GLuint rgbaSave[MAX_WIDTH][4];
       const GLint pixelSize =
          (zoomed.array->ChanType == GL_UNSIGNED_BYTE) ? 4 * sizeof(GLubyte) :
          ((zoomed.array->ChanType == GL_UNSIGNED_SHORT) ? 4 * sizeof(GLushort)
@@ -334,7 +330,7 @@ zoom_span( GLcontext *ctx, GLint imgX, GLint imgY, const SWspan *span,
    }
    else if (format == GL_COLOR_INDEX) {
       /* use specular color array for temp storage */
-      GLuint *indexSave = (GLuint *) zoomed.array->spec;
+      GLuint *indexSave = (GLuint *) zoomed.array->attribs[FRAG_ATTRIB_FOGC];
       const GLint end = zoomed.end; /* save */
       if (y1 - y0 > 1) {
          MEMCPY(indexSave, zoomed.array->index, zoomed.end * sizeof(GLuint));
diff --git a/src/mesa/swrast/swrast.h b/src/mesa/swrast/swrast.h
index 12264a159a..d101a9e2ae 100644
--- a/src/mesa/swrast/swrast.h
+++ b/src/mesa/swrast/swrast.h
@@ -45,6 +45,14 @@
  * improve its usefulness as a fallback mechanism for hardware
  * drivers.
  *
+ * wpos = attr[FRAG_ATTRIB_WPOS] and MUST BE THE FIRST values in the
+ * vertex because of the tnl clipping code.
+
+ * wpos[0] and [1] are the screen-coords of SWvertex.
+ * wpos[2] is the z-buffer coord (if 16-bit Z buffer, in range [0,65535]).
+ * wpos[3] is 1/w where w is the clip-space W coord.  This is the value
+ * that clip{XYZ} were multiplied by to get ndc{XYZ}.
+ *
  * Full software drivers:
  *   - Register the rastersetup and triangle functions from
  *     utils/software_helper.
@@ -61,20 +69,15 @@
  *     primitives unaccelerated), hook in swrast_setup instead.
  */
 typedef struct {
-   /** win[0], win[1] are the screen-coords of SWvertex.
-    * win[2] is the z-buffer coord (if 16-bit Z buffer, in range [0,65535]).
-    * win[3] is 1/w where w is the clip-space W coord.  This is the value
-    * that clip{XYZ} were multiplied by to get ndc{XYZ}.
-    */
-   GLfloat win[4];
-   GLchan color[4];
-   GLchan specular[4];
-   GLfloat index;
+   GLfloat attrib[FRAG_ATTRIB_MAX][4];
+   GLchan color[4];   /** integer color */
    GLfloat pointSize;
-   GLfloat attrib[FRAG_ATTRIB_MAX][4]; /**< texcoords & varying, more to come */
 } SWvertex;
 
 
+#define FRAG_ATTRIB_CI FRAG_ATTRIB_COL0
+
+
 struct swrast_device_driver;
 
 
diff --git a/src/mesa/swrast_setup/ss_context.c b/src/mesa/swrast_setup/ss_context.c
index 3f6d29403c..9f83fde1f5 100644
--- a/src/mesa/swrast_setup/ss_context.c
+++ b/src/mesa/swrast_setup/ss_context.c
@@ -120,16 +120,25 @@ setup_vertex_format(GLcontext *ctx)
 
       RENDERINPUTS_COPY( index_bitset, tnl->render_inputs_bitset );
 
-      EMIT_ATTR( _TNL_ATTRIB_POS, EMIT_4F_VIEWPORT, win );
-
-      if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_COLOR0 ))
-         EMIT_ATTR( _TNL_ATTRIB_COLOR0, EMIT_4CHAN_4F_RGBA, color );
+      EMIT_ATTR( _TNL_ATTRIB_POS, EMIT_4F_VIEWPORT, attrib[FRAG_ATTRIB_WPOS] );
+
+      if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_COLOR0 )) {
+         if (ctx->FragmentProgram._Current
+             || ctx->ATIFragmentShader._Enabled
+             || CHAN_TYPE == GL_FLOAT)
+            EMIT_ATTR( _TNL_ATTRIB_COLOR0, EMIT_4F, attrib[FRAG_ATTRIB_COL0]);
+         else
+            EMIT_ATTR( _TNL_ATTRIB_COLOR0, EMIT_4CHAN_4F_RGBA, color );
+      }
 
-      if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_COLOR1 ))
-         EMIT_ATTR( _TNL_ATTRIB_COLOR1, EMIT_4CHAN_4F_RGBA, specular);
+      if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_COLOR1 )) {
+         EMIT_ATTR( _TNL_ATTRIB_COLOR1, EMIT_4F, attrib[FRAG_ATTRIB_COL1]);
+      }
 
-      if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_COLOR_INDEX ))
-         EMIT_ATTR( _TNL_ATTRIB_COLOR_INDEX, EMIT_1F, index );
+      if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_COLOR_INDEX )) {
+         EMIT_ATTR( _TNL_ATTRIB_COLOR_INDEX, EMIT_1F,
+                    attrib[FRAG_ATTRIB_CI][0] );
+      }
 
       if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_FOG )) {
          const GLint emit = ctx->FragmentProgram._Current ? EMIT_4F : EMIT_1F;
@@ -184,6 +193,10 @@ _swsetup_RenderStart( GLcontext *ctx )
       _swsetup_choose_trifuncs(ctx);
    }
 
+   if (swsetup->NewState & _NEW_PROGRAM) {
+      RENDERINPUTS_ZERO( swsetup->last_index_bitset );
+   }
+
    swsetup->NewState = 0;
 
    _swrast_render_start(ctx);
@@ -258,10 +271,10 @@ _swsetup_Translate( GLcontext *ctx, const void *vertex, SWvertex *dest )
 
    _tnl_get_attr( ctx, vertex, _TNL_ATTRIB_POS, tmp );
 
-   dest->win[0] = m[0]  * tmp[0] + m[12];
-   dest->win[1] = m[5]  * tmp[1] + m[13];
-   dest->win[2] = m[10] * tmp[2] + m[14];
-   dest->win[3] =         tmp[3];
+   dest->attrib[FRAG_ATTRIB_WPOS][0] = m[0]  * tmp[0] + m[12];
+   dest->attrib[FRAG_ATTRIB_WPOS][1] = m[5]  * tmp[1] + m[13];
+   dest->attrib[FRAG_ATTRIB_WPOS][2] = m[10] * tmp[2] + m[14];
+   dest->attrib[FRAG_ATTRIB_WPOS][3] =         tmp[3];
 
    /** XXX try to limit these loops someday */
    for (i = 0 ; i < ctx->Const.MaxTextureCoordUnits ; i++)
@@ -276,13 +289,16 @@ _swsetup_Translate( GLcontext *ctx, const void *vertex, SWvertex *dest )
    UNCLAMPED_FLOAT_TO_RGBA_CHAN( dest->color, tmp );
 
    _tnl_get_attr( ctx, vertex, _TNL_ATTRIB_COLOR1, tmp );
+   COPY_4V(dest->attrib[FRAG_ATTRIB_COL1], tmp);
+   /*
    UNCLAMPED_FLOAT_TO_RGBA_CHAN( dest->specular, tmp );
+   */
 
    _tnl_get_attr( ctx, vertex, _TNL_ATTRIB_FOG, tmp );
    dest->attrib[FRAG_ATTRIB_FOGC][0] = tmp[0];
 
    _tnl_get_attr( ctx, vertex, _TNL_ATTRIB_COLOR_INDEX, tmp );
-   dest->index = tmp[0];
+   dest->attrib[FRAG_ATTRIB_CI][0] = tmp[0];
 
    /* XXX See _tnl_get_attr about pointsize ... */
    _tnl_get_attr( ctx, vertex, _TNL_ATTRIB_POINTSIZE, tmp );
diff --git a/src/mesa/swrast_setup/ss_triangle.c b/src/mesa/swrast_setup/ss_triangle.c
index 628e9288e8..b4207f2c64 100644
--- a/src/mesa/swrast_setup/ss_triangle.c
+++ b/src/mesa/swrast_setup/ss_triangle.c
@@ -57,7 +57,7 @@ static void _swsetup_render_line_tri( GLcontext *ctx,
    SWvertex *v1 = &verts[e1];
    SWvertex *v2 = &verts[e2];
    GLchan c[2][4];
-   GLchan s[2][4];
+   GLfloat s[2][4];
    GLfloat i[2];
 
    /* cull testing */
@@ -71,17 +71,17 @@ static void _swsetup_render_line_tri( GLcontext *ctx,
    if (ctx->Light.ShadeModel == GL_FLAT) {
       COPY_CHAN4(c[0], v0->color);
       COPY_CHAN4(c[1], v1->color);
-      COPY_CHAN4(s[0], v0->specular);
-      COPY_CHAN4(s[1], v1->specular);
-      i[0] = v0->index;
-      i[1] = v1->index;
+      COPY_4V(s[0], v0->attrib[FRAG_ATTRIB_COL1]);
+      COPY_4V(s[1], v1->attrib[FRAG_ATTRIB_COL1]);
+      i[0] = v0->attrib[FRAG_ATTRIB_CI][0];
+      i[1] = v1->attrib[FRAG_ATTRIB_CI][0];
 
       COPY_CHAN4(v0->color, v2->color);
       COPY_CHAN4(v1->color, v2->color);
-      COPY_CHAN4(v0->specular, v2->specular);
-      COPY_CHAN4(v1->specular, v2->specular);
-      v0->index = v2->index;
-      v1->index = v2->index;
+      COPY_4V(v0->attrib[FRAG_ATTRIB_COL1], v2->attrib[FRAG_ATTRIB_COL1]);
+      COPY_4V(v1->attrib[FRAG_ATTRIB_COL1], v2->attrib[FRAG_ATTRIB_COL1]);
+      v0->attrib[FRAG_ATTRIB_CI][0] = v2->attrib[FRAG_ATTRIB_CI][0];
+      v1->attrib[FRAG_ATTRIB_CI][0] = v2->attrib[FRAG_ATTRIB_CI][0];
    }
 
    if (swsetup->render_prim == GL_POLYGON) {
@@ -97,10 +97,10 @@ static void _swsetup_render_line_tri( GLcontext *ctx,
    if (ctx->Light.ShadeModel == GL_FLAT) {
       COPY_CHAN4(v0->color, c[0]);
       COPY_CHAN4(v1->color, c[1]);
-      COPY_CHAN4(v0->specular, s[0]);
-      COPY_CHAN4(v1->specular, s[1]);
-      v0->index = i[0];
-      v1->index = i[1];
+      COPY_4V(v0->attrib[FRAG_ATTRIB_COL1], s[0]);
+      COPY_4V(v1->attrib[FRAG_ATTRIB_COL1], s[1]);
+      v0->attrib[FRAG_ATTRIB_CI][0] = i[0];
+      v1->attrib[FRAG_ATTRIB_CI][0] = i[1];
    }
 }
 
@@ -116,7 +116,7 @@ static void _swsetup_render_point_tri( GLcontext *ctx,
    SWvertex *v1 = &verts[e1];
    SWvertex *v2 = &verts[e2];
    GLchan c[2][4];
-   GLchan s[2][4];
+   GLfloat s[2][4];
    GLfloat i[2];
 
    /* cull testing */
@@ -131,18 +131,18 @@ static void _swsetup_render_point_tri( GLcontext *ctx,
       /* save colors/indexes for v0, v1 vertices */
       COPY_CHAN4(c[0], v0->color);
       COPY_CHAN4(c[1], v1->color);
-      COPY_CHAN4(s[0], v0->specular);
-      COPY_CHAN4(s[1], v1->specular);
-      i[0] = v0->index;
-      i[1] = v1->index;
+      COPY_4V(s[0], v0->attrib[FRAG_ATTRIB_COL1]);
+      COPY_4V(s[1], v1->attrib[FRAG_ATTRIB_COL1]);
+      i[0] = v0->attrib[FRAG_ATTRIB_CI][0];
+      i[1] = v1->attrib[FRAG_ATTRIB_CI][0];
 
       /* copy v2 color/indexes to v0, v1 indexes */
       COPY_CHAN4(v0->color, v2->color);
       COPY_CHAN4(v1->color, v2->color);
-      COPY_CHAN4(v0->specular, v2->specular);
-      COPY_CHAN4(v1->specular, v2->specular);
-      v0->index = v2->index;
-      v1->index = v2->index;
+      COPY_4V(v0->attrib[FRAG_ATTRIB_COL1], v2->attrib[FRAG_ATTRIB_COL1]);
+      COPY_4V(v1->attrib[FRAG_ATTRIB_COL1], v2->attrib[FRAG_ATTRIB_COL1]);
+      v0->attrib[FRAG_ATTRIB_CI][0] = v2->attrib[FRAG_ATTRIB_CI][0];
+      v1->attrib[FRAG_ATTRIB_CI][0] = v2->attrib[FRAG_ATTRIB_CI][0];
    }
 
    if (ef[e0]) _swrast_Point( ctx, v0 );
@@ -153,10 +153,10 @@ static void _swsetup_render_point_tri( GLcontext *ctx,
       /* restore v0, v1 colores/indexes */
       COPY_CHAN4(v0->color, c[0]);
       COPY_CHAN4(v1->color, c[1]);
-      COPY_CHAN4(v0->specular, s[0]);
-      COPY_CHAN4(v1->specular, s[1]);
-      v0->index = i[0];
-      v1->index = i[1];
+      COPY_4V(v0->attrib[FRAG_ATTRIB_COL1], s[0]);
+      COPY_4V(v1->attrib[FRAG_ATTRIB_COL1], s[1]);
+      v0->attrib[FRAG_ATTRIB_CI][0] = i[0];
+      v1->attrib[FRAG_ATTRIB_CI][0] = i[1];
    }
    _swrast_flush(ctx);
 }
diff --git a/src/mesa/swrast_setup/ss_tritmp.h b/src/mesa/swrast_setup/ss_tritmp.h
index 1fdf0cb599..9fcde31644 100644
--- a/src/mesa/swrast_setup/ss_tritmp.h
+++ b/src/mesa/swrast_setup/ss_tritmp.h
@@ -36,7 +36,7 @@ static void TAG(triangle)(GLcontext *ctx, GLuint e0, GLuint e1, GLuint e2 )
    GLenum mode = GL_FILL;
    GLuint facing = 0;
    GLchan saved_color[3][4];
-   GLchan saved_spec[3][4];
+   GLfloat saved_spec[3][4];
    GLfloat saved_index[3];
 
    v[0] = &verts[e0];
@@ -46,10 +46,10 @@ static void TAG(triangle)(GLcontext *ctx, GLuint e0, GLuint e1, GLuint e2 )
 
    if (IND & (SS_TWOSIDE_BIT | SS_OFFSET_BIT | SS_UNFILLED_BIT))
    {
-      GLfloat ex = v[0]->win[0] - v[2]->win[0];
-      GLfloat ey = v[0]->win[1] - v[2]->win[1];
-      GLfloat fx = v[1]->win[0] - v[2]->win[0];
-      GLfloat fy = v[1]->win[1] - v[2]->win[1];
+      GLfloat ex = v[0]->attrib[FRAG_ATTRIB_WPOS][0] - v[2]->attrib[FRAG_ATTRIB_WPOS][0];
+      GLfloat ey = v[0]->attrib[FRAG_ATTRIB_WPOS][1] - v[2]->attrib[FRAG_ATTRIB_WPOS][1];
+      GLfloat fx = v[1]->attrib[FRAG_ATTRIB_WPOS][0] - v[2]->attrib[FRAG_ATTRIB_WPOS][0];
+      GLfloat fy = v[1]->attrib[FRAG_ATTRIB_WPOS][1] - v[2]->attrib[FRAG_ATTRIB_WPOS][1];
       GLfloat cc  = ex*fy - ey*fx;
 
       if (IND & (SS_TWOSIDE_BIT | SS_UNFILLED_BIT))
@@ -85,30 +85,30 @@ static void TAG(triangle)(GLcontext *ctx, GLuint e0, GLuint e1, GLuint e2 )
 		  if (VB->SecondaryColorPtr[1]) {
 		     GLfloat (*vbspec)[4] = VB->SecondaryColorPtr[1]->data;
 
-		     COPY_CHAN4(saved_spec[0], v[0]->specular);
-		     COPY_CHAN4(saved_spec[1], v[1]->specular);
-		     COPY_CHAN4(saved_spec[2], v[2]->specular);
+		     COPY_4V(saved_spec[0], v[0]->attrib[FRAG_ATTRIB_COL1]);
+		     COPY_4V(saved_spec[1], v[1]->attrib[FRAG_ATTRIB_COL1]);
+		     COPY_4V(saved_spec[2], v[2]->attrib[FRAG_ATTRIB_COL1]);
 
 		     if (VB->SecondaryColorPtr[1]->stride) {
-			SS_SPEC(v[0]->specular, vbspec[e0]);
-			SS_SPEC(v[1]->specular, vbspec[e1]);
-			SS_SPEC(v[2]->specular, vbspec[e2]);
+			SS_SPEC(v[0]->attrib[FRAG_ATTRIB_COL1], vbspec[e0]);
+			SS_SPEC(v[1]->attrib[FRAG_ATTRIB_COL1], vbspec[e1]);
+			SS_SPEC(v[2]->attrib[FRAG_ATTRIB_COL1], vbspec[e2]);
 		     }
 		     else {
-			SS_SPEC(v[0]->specular, vbspec[0]);
-			SS_SPEC(v[1]->specular, vbspec[0]);
-			SS_SPEC(v[2]->specular, vbspec[0]);
+			SS_SPEC(v[0]->attrib[FRAG_ATTRIB_COL1], vbspec[0]);
+			SS_SPEC(v[1]->attrib[FRAG_ATTRIB_COL1], vbspec[0]);
+			SS_SPEC(v[2]->attrib[FRAG_ATTRIB_COL1], vbspec[0]);
 		     }
 		  }
 	       } else {
 		  GLfloat *vbindex = (GLfloat *)VB->IndexPtr[1]->data;
-		  saved_index[0] = v[0]->index;
-		  saved_index[1] = v[1]->index;
-		  saved_index[2] = v[2]->index;
+		  saved_index[0] = v[0]->attrib[FRAG_ATTRIB_CI][0];
+		  saved_index[1] = v[1]->attrib[FRAG_ATTRIB_CI][0];
+		  saved_index[2] = v[2]->attrib[FRAG_ATTRIB_CI][0];
 		  
-		  SS_IND(v[0]->index, (GLuint) vbindex[e0]);
-		  SS_IND(v[1]->index, (GLuint) vbindex[e1]);
-		  SS_IND(v[2]->index, (GLuint) vbindex[e2]);
+		  SS_IND(v[0]->attrib[FRAG_ATTRIB_CI][0], (GLuint) vbindex[e0]);
+		  SS_IND(v[1]->attrib[FRAG_ATTRIB_CI][0], (GLuint) vbindex[e1]);
+		  SS_IND(v[2]->attrib[FRAG_ATTRIB_CI][0], (GLuint) vbindex[e2]);
 	       }
 	    }
 	 }
@@ -117,9 +117,9 @@ static void TAG(triangle)(GLcontext *ctx, GLuint e0, GLuint e1, GLuint e2 )
       if (IND & SS_OFFSET_BIT)
       {
 	 offset = ctx->Polygon.OffsetUnits * ctx->DrawBuffer->_MRD;
-	 z[0] = v[0]->win[2];
-	 z[1] = v[1]->win[2];
-	 z[2] = v[2]->win[2];
+	 z[0] = v[0]->attrib[FRAG_ATTRIB_WPOS][2];
+	 z[1] = v[1]->attrib[FRAG_ATTRIB_WPOS][2];
+	 z[2] = v[2]->attrib[FRAG_ATTRIB_WPOS][2];
 	 if (cc * cc > 1e-16) {
 	    const GLfloat ez = z[0] - z[2];
 	    const GLfloat fz = z[1] - z[2];
@@ -130,40 +130,40 @@ static void TAG(triangle)(GLcontext *ctx, GLuint e0, GLuint e1, GLuint e2 )
             /* Unfortunately, we need to clamp to prevent negative Zs below.
              * Technically, we should do the clamping per-fragment.
              */
-            offset = MAX2(offset, -v[0]->win[2]);
-            offset = MAX2(offset, -v[1]->win[2]);
-            offset = MAX2(offset, -v[2]->win[2]);
+            offset = MAX2(offset, -v[0]->attrib[FRAG_ATTRIB_WPOS][2]);
+            offset = MAX2(offset, -v[1]->attrib[FRAG_ATTRIB_WPOS][2]);
+            offset = MAX2(offset, -v[2]->attrib[FRAG_ATTRIB_WPOS][2]);
 	 }
       }
    }
 
    if (mode == GL_POINT) {
       if ((IND & SS_OFFSET_BIT) && ctx->Polygon.OffsetPoint) {
-	 v[0]->win[2] += offset;
-	 v[1]->win[2] += offset;
-	 v[2]->win[2] += offset;
+	 v[0]->attrib[FRAG_ATTRIB_WPOS][2] += offset;
+	 v[1]->attrib[FRAG_ATTRIB_WPOS][2] += offset;
+	 v[2]->attrib[FRAG_ATTRIB_WPOS][2] += offset;
       }
       _swsetup_render_point_tri( ctx, e0, e1, e2, facing );
    } else if (mode == GL_LINE) {
       if ((IND & SS_OFFSET_BIT) && ctx->Polygon.OffsetLine) {
-	 v[0]->win[2] += offset;
-	 v[1]->win[2] += offset;
-	 v[2]->win[2] += offset;
+	 v[0]->attrib[FRAG_ATTRIB_WPOS][2] += offset;
+	 v[1]->attrib[FRAG_ATTRIB_WPOS][2] += offset;
+	 v[2]->attrib[FRAG_ATTRIB_WPOS][2] += offset;
       }
       _swsetup_render_line_tri( ctx, e0, e1, e2, facing );
    } else {
       if ((IND & SS_OFFSET_BIT) && ctx->Polygon.OffsetFill) {
-	 v[0]->win[2] += offset;
-	 v[1]->win[2] += offset;
-	 v[2]->win[2] += offset;
+	 v[0]->attrib[FRAG_ATTRIB_WPOS][2] += offset;
+	 v[1]->attrib[FRAG_ATTRIB_WPOS][2] += offset;
+	 v[2]->attrib[FRAG_ATTRIB_WPOS][2] += offset;
       }
       _swrast_Triangle( ctx, v[0], v[1], v[2] );
    }
 
    if (IND & SS_OFFSET_BIT) {
-      v[0]->win[2] = z[0];
-      v[1]->win[2] = z[1];
-      v[2]->win[2] = z[2];
+      v[0]->attrib[FRAG_ATTRIB_WPOS][2] = z[0];
+      v[1]->attrib[FRAG_ATTRIB_WPOS][2] = z[1];
+      v[2]->attrib[FRAG_ATTRIB_WPOS][2] = z[2];
    }
 
    if (IND & SS_TWOSIDE_BIT) {
@@ -176,14 +176,14 @@ static void TAG(triangle)(GLcontext *ctx, GLuint e0, GLuint e1, GLuint e2 )
             }
 
 	    if (VB->SecondaryColorPtr[1]) {
-	       COPY_CHAN4(v[0]->specular, saved_spec[0]);
-	       COPY_CHAN4(v[1]->specular, saved_spec[1]);
-	       COPY_CHAN4(v[2]->specular, saved_spec[2]);
+	       COPY_4V(v[0]->attrib[FRAG_ATTRIB_COL1], saved_spec[0]);
+	       COPY_4V(v[1]->attrib[FRAG_ATTRIB_COL1], saved_spec[1]);
+	       COPY_4V(v[2]->attrib[FRAG_ATTRIB_COL1], saved_spec[2]);
 	    }
 	 } else {
-	    v[0]->index = saved_index[0];
-	    v[1]->index = saved_index[1];
-	    v[2]->index = saved_index[2];
+	    v[0]->attrib[FRAG_ATTRIB_CI][0] = saved_index[0];
+	    v[1]->attrib[FRAG_ATTRIB_CI][0] = saved_index[1];
+	    v[2]->attrib[FRAG_ATTRIB_CI][0] = saved_index[2];
 	 }
       }
    }
diff --git a/src/mesa/tnl_dd/t_dd_vb.c b/src/mesa/tnl_dd/t_dd_vb.c
index 6cdd1bc031..ab3bb37631 100644
--- a/src/mesa/tnl_dd/t_dd_vb.c
+++ b/src/mesa/tnl_dd/t_dd_vb.c
@@ -89,15 +89,15 @@ void TAG(translate_vertex)(GLcontext *ctx,
 
    if (format == TINY_VERTEX_FORMAT) {
       if (HAVE_HW_VIEWPORT) {
-	 dst->win[0] = s[0]  * src->v.x + s[12];
-	 dst->win[1] = s[5]  * src->v.y + s[13];
-	 dst->win[2] = s[10] * src->v.z + s[14];
-	 dst->win[3] = 1.0;
+	 dst->attrib[FRAG_ATTRIB_WPOS][0] = s[0]  * src->v.x + s[12];
+	 dst->attrib[FRAG_ATTRIB_WPOS][1] = s[5]  * src->v.y + s[13];
+	 dst->attrib[FRAG_ATTRIB_WPOS][2] = s[10] * src->v.z + s[14];
+	 dst->attrib[FRAG_ATTRIB_WPOS][3] = 1.0;
       } else {
-	 dst->win[0] = UNVIEWPORT_X( src->v.x );
-	 dst->win[1] = UNVIEWPORT_Y( src->v.y );
-	 dst->win[2] = UNVIEWPORT_Z( src->v.z );
-	 dst->win[3] = 1.0;
+	 dst->attrib[FRAG_ATTRIB_WPOS][0] = UNVIEWPORT_X( src->v.x );
+	 dst->attrib[FRAG_ATTRIB_WPOS][1] = UNVIEWPORT_Y( src->v.y );
+	 dst->attrib[FRAG_ATTRIB_WPOS][2] = UNVIEWPORT_Z( src->v.z );
+	 dst->attrib[FRAG_ATTRIB_WPOS][3] = 1.0;
       }
 
       dst->color[0] = src->tv.color.red;
@@ -109,21 +109,21 @@ void TAG(translate_vertex)(GLcontext *ctx,
       if (HAVE_HW_VIEWPORT) {
 	 if (HAVE_HW_DIVIDE && CHECK_HW_DIVIDE) {
 	    GLfloat oow = 1.0 / src->v.w;
-	    dst->win[0] = s[0]  * src->v.x * oow + s[12];
-	    dst->win[1] = s[5]  * src->v.y * oow + s[13];
-	    dst->win[2] = s[10] * src->v.z * oow + s[14];
-	    dst->win[3] = oow;
+	    dst->attrib[FRAG_ATTRIB_WPOS][0] = s[0]  * src->v.x * oow + s[12];
+	    dst->attrib[FRAG_ATTRIB_WPOS][1] = s[5]  * src->v.y * oow + s[13];
+	    dst->attrib[FRAG_ATTRIB_WPOS][2] = s[10] * src->v.z * oow + s[14];
+	    dst->attrib[FRAG_ATTRIB_WPOS][3] = oow;
 	 } else {
-	    dst->win[0] = s[0]  * src->v.x + s[12];
-	    dst->win[1] = s[5]  * src->v.y + s[13];
-	    dst->win[2] = s[10] * src->v.z + s[14];
-	    dst->win[3] = src->v.w;
+	    dst->attrib[FRAG_ATTRIB_WPOS][0] = s[0]  * src->v.x + s[12];
+	    dst->attrib[FRAG_ATTRIB_WPOS][1] = s[5]  * src->v.y + s[13];
+	    dst->attrib[FRAG_ATTRIB_WPOS][2] = s[10] * src->v.z + s[14];
+	    dst->attrib[FRAG_ATTRIB_WPOS][3] = src->v.w;
 	 }
       } else {
-	 dst->win[0] = UNVIEWPORT_X( src->v.x );
-	 dst->win[1] = UNVIEWPORT_Y( src->v.y );
-	 dst->win[2] = UNVIEWPORT_Z( src->v.z );
-	 dst->win[3] = src->v.w;
+	 dst->attrib[FRAG_ATTRIB_WPOS][0] = UNVIEWPORT_X( src->v.x );
+	 dst->attrib[FRAG_ATTRIB_WPOS][1] = UNVIEWPORT_Y( src->v.y );
+	 dst->attrib[FRAG_ATTRIB_WPOS][2] = UNVIEWPORT_Z( src->v.z );
+	 dst->attrib[FRAG_ATTRIB_WPOS][3] = src->v.w;
       }
 
       dst->color[0] = src->v.color.red;
@@ -131,11 +131,11 @@ void TAG(translate_vertex)(GLcontext *ctx,
       dst->color[2] = src->v.color.blue;
       dst->color[3] = src->v.color.alpha;
 
-      dst->specular[0] = src->v.specular.red;
-      dst->specular[1] = src->v.specular.green;
-      dst->specular[2] = src->v.specular.blue;
+      dst->attrib[FRAG_ATTRIB_COL1][0] = UBYTE_TO_FLOAT(src->v.specular.red);
+      dst->attrib[FRAG_ATTRIB_COL1][1] = UBYTE_TO_FLOAT(src->v.specular.green);
+      dst->attrib[FRAG_ATTRIB_COL1][2] = UBYTE_TO_FLOAT(src->v.specular.blue);
 
-      dst->attrib[FRAG_ATTRIB_FOGC][0] = src->v.specular.alpha/255.0;
+      dst->attrib[FRAG_ATTRIB_FOGC][0] = UBYTE_TO_FLOAT(src->v.specular.alpha);
 
       if (HAVE_PTEX_VERTICES &&
 	  ((HAVE_TEX2_VERTICES && format == PROJ_TEX3_VERTEX_FORMAT) ||
-- 
cgit v1.2.3


From b1c640deda326078b1b2b335646f32b52120be3c Mon Sep 17 00:00:00 2001
From: Roland Scheidegger <sroland@tungstengraphics.com>
Date: Mon, 21 May 2007 11:38:25 +0200
Subject: unbreak 3d textures (typo when setting tex layout)

---
 src/mesa/drivers/dri/i915tex/i915_tex_layout.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'src/mesa/drivers')

diff --git a/src/mesa/drivers/dri/i915tex/i915_tex_layout.c b/src/mesa/drivers/dri/i915tex/i915_tex_layout.c
index 9f40706c36..7b761a7b22 100644
--- a/src/mesa/drivers/dri/i915tex/i915_tex_layout.c
+++ b/src/mesa/drivers/dri/i915tex/i915_tex_layout.c
@@ -113,7 +113,7 @@ i915_miptree_layout(struct intel_mipmap_tree * mt)
           */
          for (level = mt->first_level; level <= MAX2(8, mt->last_level);
               level++) {
-            intel_miptree_set_level_info(mt, level, 1, 0, mt->total_height,
+            intel_miptree_set_level_info(mt, level, depth, 0, mt->total_height,
                                          width, height, depth);
 
 
-- 
cgit v1.2.3


From 1078ef83eb3458363bf9709a7c697b39020266ea Mon Sep 17 00:00:00 2001
From: Roland Scheidegger <sroland@tungstengraphics.com>
Date: Tue, 22 May 2007 02:50:08 +0200
Subject: i915/i915tex: minor cleanup (remove unneeded function call

---
 src/mesa/drivers/dri/i915/i915_fragprog.c    | 8 --------
 src/mesa/drivers/dri/i915tex/i915_fragprog.c | 8 --------
 2 files changed, 16 deletions(-)

(limited to 'src/mesa/drivers')

diff --git a/src/mesa/drivers/dri/i915/i915_fragprog.c b/src/mesa/drivers/dri/i915/i915_fragprog.c
index a28c8bb6fc..702b878828 100644
--- a/src/mesa/drivers/dri/i915/i915_fragprog.c
+++ b/src/mesa/drivers/dri/i915/i915_fragprog.c
@@ -857,11 +857,6 @@ static void i915BindProgram( GLcontext *ctx,
       assert(p->on_hardware == 0);
       assert(p->params_uptodate == 0);
 
-      /* Hack: make sure fog is correctly enabled according to this
-       * fragment program's fog options.
-       */
-      ctx->Driver.Enable( ctx, GL_FRAGMENT_PROGRAM_ARB, 
-			  ctx->FragmentProgram.Enabled );
    }
 }
 
@@ -935,9 +930,6 @@ static void i915ProgramStringNotify( GLcontext *ctx,
       /* Hack: make sure fog is correctly enabled according to this
        * fragment program's fog options.
        */
-      ctx->Driver.Enable( ctx, GL_FRAGMENT_PROGRAM_ARB, 
-			  ctx->FragmentProgram.Enabled );
-
       if (p->FragProg.FogOption) {
          /* add extra instructions to do fog, then turn off FogOption field */
          _mesa_append_fog_code(ctx, &p->FragProg);
diff --git a/src/mesa/drivers/dri/i915tex/i915_fragprog.c b/src/mesa/drivers/dri/i915tex/i915_fragprog.c
index cbea6092a8..a4b22a0c32 100644
--- a/src/mesa/drivers/dri/i915tex/i915_fragprog.c
+++ b/src/mesa/drivers/dri/i915tex/i915_fragprog.c
@@ -849,11 +849,6 @@ i915BindProgram(GLcontext * ctx, GLenum target, struct gl_program *prog)
       assert(p->on_hardware == 0);
       assert(p->params_uptodate == 0);
 
-      /* Hack: make sure fog is correctly enabled according to this
-       * fragment program's fog options.
-       */
-      ctx->Driver.Enable(ctx, GL_FRAGMENT_PROGRAM_ARB,
-                         ctx->FragmentProgram.Enabled);
    }
 }
 
@@ -926,9 +921,6 @@ i915ProgramStringNotify(GLcontext * ctx,
       /* Hack: make sure fog is correctly enabled according to this
        * fragment program's fog options.
        */
-      ctx->Driver.Enable(ctx, GL_FRAGMENT_PROGRAM_ARB,
-                         ctx->FragmentProgram.Enabled);
-
       if (p->FragProg.FogOption) {
          /* add extra instructions to do fog, then turn off FogOption field */
          _mesa_append_fog_code(ctx, &p->FragProg);
-- 
cgit v1.2.3


From 74a30c351fe98f41150dfe81a6aba05087997206 Mon Sep 17 00:00:00 2001
From: Roland Scheidegger <sroland@tungstengraphics.com>
Date: Tue, 22 May 2007 03:30:09 +0200
Subject: fog: fix potential issues with generated vp using fog

Change the generated vertex programs (tnl/brw) to follow the same logic as
the tnl fog wrt using absolute value, and sync them up a bit (untested).
---
 src/mesa/drivers/dri/i965/brw_vs_tnl.c | 22 ++++++++++++++--------
 src/mesa/tnl/t_vp_build.c              | 23 +++++++++++++++--------
 2 files changed, 29 insertions(+), 16 deletions(-)

(limited to 'src/mesa/drivers')

diff --git a/src/mesa/drivers/dri/i965/brw_vs_tnl.c b/src/mesa/drivers/dri/i965/brw_vs_tnl.c
index 35adc4846a..b69be350a9 100644
--- a/src/mesa/drivers/dri/i965/brw_vs_tnl.c
+++ b/src/mesa/drivers/dri/i965/brw_vs_tnl.c
@@ -1154,7 +1154,9 @@ static void build_fog( struct tnl_program *p )
 {
    struct ureg fog = register_output(p, VERT_RESULT_FOGC);
    struct ureg input;
-   
+   GLuint useabs = p->state->fog_source_is_depth && p->state->fog_option &&
+		   (p->state->fog_option != FOG_EXP2);
+
    if (p->state->fog_source_is_depth) {
       input = swizzle1(get_eye_position(p), Z);
    }
@@ -1171,26 +1173,30 @@ static void build_fog( struct tnl_program *p )
 
       emit_op1(p, OPCODE_MOV, fog, 0, id);
 
+      if (useabs) {
+	 emit_op1(p, OPCODE_ABS, tmp, 0, input);
+      }
+
       switch (p->state->fog_option) {
       case FOG_LINEAR: {
-	 emit_op1(p, OPCODE_ABS, tmp, 0, input);
-	 emit_op3(p, OPCODE_MAD, tmp, 0, tmp, swizzle1(params,X), swizzle1(params,Y));
+	 emit_op3(p, OPCODE_MAD, tmp, 0, useabs ? tmp : input,
+			swizzle1(params,X), swizzle1(params,Y));
 	 emit_op2(p, OPCODE_MAX, tmp, 0, tmp, swizzle1(id,X)); /* saturate */
 	 emit_op2(p, OPCODE_MIN, fog, WRITEMASK_X, tmp, swizzle1(id,W));
 	 break;
       }
       case FOG_EXP:
-	 emit_op1(p, OPCODE_ABS, tmp, 0, input); 
-	 emit_op2(p, OPCODE_MUL, tmp, 0, tmp, swizzle1(params,Z));
+	 emit_op2(p, OPCODE_MUL, tmp, 0, useabs ? tmp : input,
+			swizzle1(params,Z));
 	 emit_op1(p, OPCODE_EX2, fog, WRITEMASK_X, ureg_negate(tmp));
 	 break;
       case FOG_EXP2:
 	 emit_op2(p, OPCODE_MUL, tmp, 0, input, swizzle1(params,W));
-	 emit_op2(p, OPCODE_MUL, tmp, 0, tmp, tmp); 
+	 emit_op2(p, OPCODE_MUL, tmp, 0, tmp, tmp);
 	 emit_op1(p, OPCODE_EX2, fog, WRITEMASK_X, ureg_negate(tmp));
 	 break;
       }
-      
+
       release_temp(p, tmp);
    }
    else {
@@ -1198,7 +1204,7 @@ static void build_fog( struct tnl_program *p )
        *
        * KW:  Is it really necessary to do anything in this case?
        */
-      emit_op1(p, OPCODE_MOV, fog, 0, input);
+      emit_op1(p, useabs ? OPCODE_ABS : OPCODE_MOV, fog, 0, input);
    }
 }
  
diff --git a/src/mesa/tnl/t_vp_build.c b/src/mesa/tnl/t_vp_build.c
index dff062a417..2a1cae77f2 100644
--- a/src/mesa/tnl/t_vp_build.c
+++ b/src/mesa/tnl/t_vp_build.c
@@ -1103,7 +1103,9 @@ static void build_fog( struct tnl_program *p )
 {
    struct ureg fog = register_output(p, VERT_RESULT_FOGC);
    struct ureg input;
-   
+   GLuint useabs = p->state->fog_source_is_depth && p->state->fog_mode &&
+		   (p->state->fog_mode != FOG_EXP2);
+
    if (p->state->fog_source_is_depth) {
       input = swizzle1(get_eye_position(p), Z);
    }
@@ -1111,31 +1113,36 @@ static void build_fog( struct tnl_program *p )
       input = swizzle1(register_input(p, VERT_ATTRIB_FOG), X);
    }
 
-   if (p->state->tnl_do_vertex_fog) {
+   if (p->state->fog_mode && p->state->tnl_do_vertex_fog) {
       struct ureg params = register_param2(p, STATE_INTERNAL,
 					   STATE_FOG_PARAMS_OPTIMIZED);
       struct ureg tmp = get_temp(p);
 
+      if (useabs) {
+	 emit_op1(p, OPCODE_ABS, tmp, 0, input);
+      }
+
       switch (p->state->fog_mode) {
       case FOG_LINEAR: {
 	 struct ureg id = get_identity_param(p);
-	 emit_op3(p, OPCODE_MAD, tmp, 0, input, swizzle1(params,X), swizzle1(params,Y));
+	 emit_op3(p, OPCODE_MAD, tmp, 0, useabs ? tmp : input,
+			swizzle1(params,X), swizzle1(params,Y));
 	 emit_op2(p, OPCODE_MAX, tmp, 0, tmp, swizzle1(id,X)); /* saturate */
 	 emit_op2(p, OPCODE_MIN, fog, WRITEMASK_X, tmp, swizzle1(id,W));
 	 break;
       }
       case FOG_EXP:
-	 emit_op1(p, OPCODE_ABS, tmp, 0, input); 
-	 emit_op2(p, OPCODE_MUL, tmp, 0, tmp, swizzle1(params,Z));
+	 emit_op2(p, OPCODE_MUL, tmp, 0, useabs ? tmp : input,
+			swizzle1(params,Z));
 	 emit_op1(p, OPCODE_EX2, fog, WRITEMASK_X, negate(tmp));
 	 break;
       case FOG_EXP2:
 	 emit_op2(p, OPCODE_MUL, tmp, 0, input, swizzle1(params,W));
-	 emit_op2(p, OPCODE_MUL, tmp, 0, tmp, tmp); 
+	 emit_op2(p, OPCODE_MUL, tmp, 0, tmp, tmp);
 	 emit_op1(p, OPCODE_EX2, fog, WRITEMASK_X, negate(tmp));
 	 break;
       }
-      
+
       release_temp(p, tmp);
    }
    else {
@@ -1143,7 +1150,7 @@ static void build_fog( struct tnl_program *p )
        *
        * KW:  Is it really necessary to do anything in this case?
        */
-      emit_op1(p, OPCODE_MOV, fog, WRITEMASK_X, input);
+      emit_op1(p, useabs ? OPCODE_ABS : OPCODE_MOV, fog, WRITEMASK_X, input);
    }
 }
  
-- 
cgit v1.2.3


From a10ba38df7ac80e36db15aaae9f78e7223b2bfae Mon Sep 17 00:00:00 2001
From: Brian <brian.paul@tungstengraphics.com>
Date: Mon, 21 May 2007 20:56:35 -0600
Subject: return True for GLX_Y_INVERTED_EXT query

---
 src/mesa/drivers/x11/fakeglx.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'src/mesa/drivers')

diff --git a/src/mesa/drivers/x11/fakeglx.c b/src/mesa/drivers/x11/fakeglx.c
index ef22a3f03e..1587df66bc 100644
--- a/src/mesa/drivers/x11/fakeglx.c
+++ b/src/mesa/drivers/x11/fakeglx.c
@@ -1920,7 +1920,7 @@ get_config( XMesaVisual xmvis, int attrib, int *value, GLboolean fbconfig )
                    GLX_TEXTURE_RECTANGLE_BIT_EXT); /*XXX*/
          break;
       case GLX_Y_INVERTED_EXT:
-         *value = False; /*XXX*/
+         *value = True; /*XXX*/
          break;
 #endif
 
-- 
cgit v1.2.3


From 24d965fab52f790188e5de6e67e7387809b1f145 Mon Sep 17 00:00:00 2001
From: Michel Dänzer <michel@tungstengraphics.com>
Date: Tue, 22 May 2007 13:56:30 +0200
Subject: Fix xserver build after recent XMesa changes.

Only build tested.
---
 include/GL/xmesa.h              |  4 ++--
 include/GL/xmesa_x.h            |  1 +
 include/GL/xmesa_xf86.h         | 29 ++++++++++++++++++++++++++++-
 src/mesa/drivers/x11/xm_api.c   | 20 ++++++++++----------
 src/mesa/drivers/x11/xm_image.h |  7 -------
 5 files changed, 41 insertions(+), 20 deletions(-)

(limited to 'src/mesa/drivers')

diff --git a/include/GL/xmesa.h b/include/GL/xmesa.h
index 2199b08cf0..98139af833 100644
--- a/include/GL/xmesa.h
+++ b/include/GL/xmesa.h
@@ -402,11 +402,11 @@ extern XMesaBuffer XMesaCreatePBuffer(XMesaVisual v, XMesaColormap cmap,
  * New in Mesa 7.1
  */
 extern void
-XMesaBindTexImage(Display *dpy, XMesaBuffer drawable, int buffer,
+XMesaBindTexImage(XMesaDisplay *dpy, XMesaBuffer drawable, int buffer,
                   const int *attrib_list);
 
 extern void
-XMesaReleaseTexImage(Display *dpy, XMesaBuffer drawable, int buffer);
+XMesaReleaseTexImage(XMesaDisplay *dpy, XMesaBuffer drawable, int buffer);
 
 
 extern XMesaBuffer
diff --git a/include/GL/xmesa_x.h b/include/GL/xmesa_x.h
index 721d8b5107..865bab4313 100644
--- a/include/GL/xmesa_x.h
+++ b/include/GL/xmesa_x.h
@@ -66,6 +66,7 @@ typedef XColor       XMesaColor;
 #define XMesaDrawPoints        XDrawPoints
 #define XMesaDrawLine          XDrawLine
 #define XMesaFillRectangle     XFillRectangle
+#define XMesaGetImage          XGetImage
 #define XMesaPutImage          XPutImage
 #define XMesaCopyArea          XCopyArea
 
diff --git a/include/GL/xmesa_xf86.h b/include/GL/xmesa_xf86.h
index 0a15110f65..18908a133f 100644
--- a/include/GL/xmesa_xf86.h
+++ b/include/GL/xmesa_xf86.h
@@ -42,8 +42,15 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include "scrnintstr.h"
 #include "pixmapstr.h"
 #include "gcstruct.h"
+#include "servermd.h"
 
-typedef struct _XMesaImageRec XMesaImage;
+
+typedef struct _XMesaImageRec {
+    int width, height;
+    char *data;
+    int bytes_per_line; /* Padded to 32 bits */
+    int bits_per_pixel;
+} XMesaImage;
 
 typedef ScreenRec   XMesaDisplay;
 typedef PixmapPtr   XMesaPixmap;
@@ -120,6 +127,26 @@ do { \
     (*__gc->ops->PolyFillRect)((DrawablePtr)__b, __gc, 1, __r); \
 } while (0)
 
+static _X_INLINE XMesaImage *XMesaGetImage(XMesaDisplay *dpy, PixmapPtr p, int x,
+					int y, unsigned int width,
+					unsigned int height,
+					unsigned long plane_mask, int format)
+{
+    XMesaImage *img = Xcalloc(sizeof(*img));
+
+    img->width = p->drawable.width;
+    img->height = p->drawable.height;
+    img->bits_per_pixel = p->drawable.bitsPerPixel;
+    img->bytes_per_line = PixmapBytePad(width, p->drawable.depth);
+    img->data = malloc(height * img->bytes_per_line);
+
+    /* Assumes: Images are always in ZPixmap format */
+    (*p->drawable.pScreen->GetImage)(&p->drawable, x, y, width, height,
+				     plane_mask, ZPixmap, img->data);
+
+    return img;
+}
+
 #define XMesaPutImage(__d,__b,__gc,__i,__sx,__sy,__x,__y,__w,__h) \
 do { \
     /* Assumes: Images are always in ZPixmap format */ \
diff --git a/src/mesa/drivers/x11/xm_api.c b/src/mesa/drivers/x11/xm_api.c
index edaa71508f..cff64d17ad 100644
--- a/src/mesa/drivers/x11/xm_api.c
+++ b/src/mesa/drivers/x11/xm_api.c
@@ -63,6 +63,7 @@
 #endif
 
 #include "glxheader.h"
+#include "GL/glxtokens.h"
 #include "GL/xmesa.h"
 #include "xmesaP.h"
 #include "context.h"
@@ -293,11 +294,9 @@ static GLboolean window_exists( XMesaDisplay *dpy, Window win )
    XSetErrorHandler(old_handler);
    return WindowExistsFlag;
 }
-#endif
-
 
 static Status
-get_drawable_size(Display *dpy, Drawable d, GLuint *width, GLuint *height)
+get_drawable_size( XMesaDisplay *dpy, Drawable d, GLuint *width, GLuint *height )
 {
    Window root;
    Status stat;
@@ -308,6 +307,7 @@ get_drawable_size(Display *dpy, Drawable d, GLuint *width, GLuint *height)
    *height = h;
    return stat;
 }
+#endif
 
 
 /**
@@ -1703,7 +1703,7 @@ XMesaCreatePixmapTextureBuffer(XMesaVisual v, XMesaPixmap p,
       return NULL;
 
    /* get pixmap size, update framebuffer/renderbuffer dims */
-   get_drawable_size(v->display, p, &width, &height);
+   xmesa_get_window_size(v->display, b, &width, &height);
    _mesa_resize_framebuffer(NULL, &(b->mesa_buffer), width, height);
 
    if (target == 0) {
@@ -2363,7 +2363,7 @@ xbuffer_to_renderbuffer(int buffer)
 
 
 PUBLIC void
-XMesaBindTexImage(Display *dpy, XMesaBuffer drawable, int buffer,
+XMesaBindTexImage(XMesaDisplay *dpy, XMesaBuffer drawable, int buffer,
                   const int *attrib_list)
 {
 #if 0
@@ -2375,7 +2375,7 @@ XMesaBindTexImage(Display *dpy, XMesaBuffer drawable, int buffer,
    struct gl_renderbuffer *rb;
    struct xmesa_renderbuffer *xrb;
    GLint b;
-   XMesaImage *img;
+   XMesaImage *img = NULL;
    GLboolean freeImg = GL_FALSE;
 
    b = xbuffer_to_renderbuffer(buffer);
@@ -2412,15 +2412,15 @@ XMesaBindTexImage(Display *dpy, XMesaBuffer drawable, int buffer,
     * The following is a quick and simple way to implement
     * BindTexImage.  The better way is to write some new FetchTexel()
     * functions which would extract texels from XImages.  We'd still
-    * need to use XGetImage when texturing from a Pixmap (front buffer)
+    * need to use GetImage when texturing from a Pixmap (front buffer)
     * but texturing from a back buffer (XImage) would avoid an image
     * copy.
     */
 
    /* get XImage */
    if (xrb->pixmap) {
-      img = XGetImage(dpy, xrb->pixmap, 0, 0, rb->Width, rb->Height,
-                      AllPlanes, ZPixmap );
+      img = XMesaGetImage(dpy, xrb->pixmap, 0, 0, rb->Width, rb->Height, ~0L,
+			  ZPixmap);
       freeImg = GL_TRUE;
    }
    else if (xrb->ximage) {
@@ -2468,7 +2468,7 @@ XMesaBindTexImage(Display *dpy, XMesaBuffer drawable, int buffer,
 
 
 PUBLIC void
-XMesaReleaseTexImage(Display *dpy, XMesaBuffer drawable, int buffer)
+XMesaReleaseTexImage(XMesaDisplay *dpy, XMesaBuffer drawable, int buffer)
 {
    const GLint b = xbuffer_to_renderbuffer(buffer);
    if (b < 0)
diff --git a/src/mesa/drivers/x11/xm_image.h b/src/mesa/drivers/x11/xm_image.h
index 240ccee1af..2a5e0f3777 100644
--- a/src/mesa/drivers/x11/xm_image.h
+++ b/src/mesa/drivers/x11/xm_image.h
@@ -36,13 +36,6 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 #define XMESA_USE_PUTPIXEL_MACRO
 
-struct _XMesaImageRec {
-    int width, height;
-    char *data;
-    int bytes_per_line; /* Padded to 32 bits */
-    int bits_per_pixel;
-};
-
 extern XMesaImage *XMesaCreateImage(int bitsPerPixel, int width, int height,
 				    char *data);
 extern void XMesaDestroyImage(XMesaImage *image);
-- 
cgit v1.2.3


From 043d219b6da0636886f739613380cf44e334f268 Mon Sep 17 00:00:00 2001
From: Michel Dänzer <michel@tungstengraphics.com>
Date: Tue, 22 May 2007 14:08:10 +0200
Subject: Add interfaces for overriding texture images with driver specific
 'offsets'.

To be used by AIGLX for GLX_EXT_texture_from_pixmap without several
additional data copies.
---
 include/GL/internal/dri_interface.h    | 12 ++++++++++++
 src/mesa/drivers/dri/common/dri_util.c |  3 +++
 src/mesa/drivers/dri/common/dri_util.h |  6 ++++++
 3 files changed, 21 insertions(+)

(limited to 'src/mesa/drivers')

diff --git a/include/GL/internal/dri_interface.h b/include/GL/internal/dri_interface.h
index a3de2c6aab..8d24e311f8 100644
--- a/include/GL/internal/dri_interface.h
+++ b/include/GL/internal/dri_interface.h
@@ -361,6 +361,18 @@ struct __DRIscreenRec {
     void * (*createNewContext)(__DRInativeDisplay *dpy, const __GLcontextModes *modes,
 			       int render_type,
 			       void *sharedPrivate, __DRIcontext *pctx);
+
+    /**
+     * Method to override base texture image with a driver specific 'offset'.
+     * The depth passed in allows e.g. to ignore the alpha channel of texture
+     * images where the non-alpha components don't occupy a whole texel.
+     *
+     * For GLX_EXT_texture_from_pixmap with AIGLX.
+     *
+     * \since Internal API version 20070121.
+     */
+    void (*setTexOffset)(__DRIcontext *pDRICtx, GLint texname,
+			 unsigned long long offset, GLint depth, GLuint pitch);
 };
 
 /**
diff --git a/src/mesa/drivers/dri/common/dri_util.c b/src/mesa/drivers/dri/common/dri_util.c
index 07ac4c7cd5..dd52f7e915 100644
--- a/src/mesa/drivers/dri/common/dri_util.c
+++ b/src/mesa/drivers/dri/common/dri_util.c
@@ -995,6 +995,9 @@ __driUtilCreateNewScreen(__DRInativeDisplay *dpy, int scrn, __DRIscreen *psc,
     psc->getMSC            = driGetMSC;
     psc->createNewContext  = driCreateNewContext;
 
+    if (internal_api_version >= 20070121)
+	psc->setTexOffset  = psp->DriverAPI.setTexOffset;
+
     if ( (psp->DriverAPI.InitDriver != NULL)
 	 && !(*psp->DriverAPI.InitDriver)(psp) ) {
 	_mesa_free( psp );
diff --git a/src/mesa/drivers/dri/common/dri_util.h b/src/mesa/drivers/dri/common/dri_util.h
index 8639535abb..539d28d114 100644
--- a/src/mesa/drivers/dri/common/dri_util.h
+++ b/src/mesa/drivers/dri/common/dri_util.h
@@ -189,6 +189,12 @@ struct __DriverAPIRec {
     /*@}*/
     void (*CopySubBuffer)(__DRIdrawablePrivate *driDrawPriv,
 			  int x, int y, int w, int h);
+
+    /**
+     * See corresponding field in \c __DRIscreenRec.
+     */
+    void (*setTexOffset)(__DRIcontext *pDRICtx, GLint texname,
+			 unsigned long long offset, GLint depth, GLuint pitch);
 };
 
 
-- 
cgit v1.2.3


From 59a08923f51d4ed83effbfcd91473c9ee86465f1 Mon Sep 17 00:00:00 2001
From: Michel Dänzer <michel@tungstengraphics.com>
Date: Tue, 22 May 2007 14:08:11 +0200
Subject: r300: Implement SetTexOffset hook.

---
 src/mesa/drivers/dri/r300/r300_context.h    |  2 +
 src/mesa/drivers/dri/r300/r300_tex.h        |  4 ++
 src/mesa/drivers/dri/r300/r300_texmem.c     |  3 ++
 src/mesa/drivers/dri/r300/r300_texstate.c   | 73 ++++++++++++++++++++++++-----
 src/mesa/drivers/dri/radeon/radeon_screen.c |  4 ++
 5 files changed, 74 insertions(+), 12 deletions(-)

(limited to 'src/mesa/drivers')

diff --git a/src/mesa/drivers/dri/r300/r300_context.h b/src/mesa/drivers/dri/r300/r300_context.h
index 261c87f2f0..01caa61766 100644
--- a/src/mesa/drivers/dri/r300/r300_context.h
+++ b/src/mesa/drivers/dri/r300/r300_context.h
@@ -191,6 +191,8 @@ struct r300_tex_obj {
 	drm_radeon_tex_image_t image[6][RADEON_MAX_TEXTURE_LEVELS];
 	/* Six, for the cube faces */
 
+	GLboolean image_override;	/* Image overridden by GLX_EXT_tfp */
+
 	GLuint pitch;		/* this isn't sent to hardware just used in calculations */
 	/* hardware register values */
 	/* Note that R200 has 8 registers per texture and R300 only 7 */
diff --git a/src/mesa/drivers/dri/r300/r300_tex.h b/src/mesa/drivers/dri/r300/r300_tex.h
index 74fa08e97d..f67a8e6ba6 100644
--- a/src/mesa/drivers/dri/r300/r300_tex.h
+++ b/src/mesa/drivers/dri/r300/r300_tex.h
@@ -35,6 +35,10 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #ifndef __r300_TEX_H__
 #define __r300_TEX_H__
 
+extern void r300SetTexOffset(__DRIcontext *pDRICtx, GLint texname,
+			     unsigned long long offset, GLint depth,
+			     GLuint pitch);
+
 extern void r300UpdateTextureState(GLcontext * ctx);
 
 extern int r300UploadTexImages(r300ContextPtr rmesa, r300TexObjPtr t,
diff --git a/src/mesa/drivers/dri/r300/r300_texmem.c b/src/mesa/drivers/dri/r300/r300_texmem.c
index 60e7dc967b..e2e8355d27 100644
--- a/src/mesa/drivers/dri/r300/r300_texmem.c
+++ b/src/mesa/drivers/dri/r300/r300_texmem.c
@@ -508,6 +508,9 @@ int r300UploadTexImages(r300ContextPtr rmesa, r300TexObjPtr t, GLuint face)
 {
 	const int numLevels = t->base.lastLevel - t->base.firstLevel + 1;
 
+	if (t->image_override)
+		return 0;
+
 	if (RADEON_DEBUG & (DEBUG_TEXTURE | DEBUG_IOCTL)) {
 		fprintf(stderr, "%s( %p, %p ) sz=%d lvls=%d-%d\n", __FUNCTION__,
 			(void *)rmesa->radeon.glCtx, (void *)t->base.tObj,
diff --git a/src/mesa/drivers/dri/r300/r300_texstate.c b/src/mesa/drivers/dri/r300/r300_texstate.c
index 705502ebf2..8203189b7f 100644
--- a/src/mesa/drivers/dri/r300/r300_texstate.c
+++ b/src/mesa/drivers/dri/r300/r300_texstate.c
@@ -40,6 +40,8 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include "context.h"
 #include "macros.h"
 #include "texformat.h"
+#include "teximage.h"
+#include "texobj.h"
 #include "enums.h"
 
 #include "r300_context.h"
@@ -66,7 +68,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  * identically.  -- paulus
  */
 
-static const struct {
+static const struct tx_table {
 	GLuint format, filter, flag;
 } tx_table_be[] = {
 	/* *INDENT-OFF* */
@@ -109,15 +111,13 @@ static const struct {
 	/* *INDENT-ON* */
 };
 
-static const struct {
-	GLuint format, filter, flag;
-} tx_table_le[] = {
+static const struct tx_table tx_table_le[] = {
 	/* *INDENT-OFF* */
 	_ASSIGN(RGBA8888, R300_EASY_TX_FORMAT(Y, Z, W, X, W8Z8Y8X8)),
 	_ASSIGN(RGBA8888_REV, R300_EASY_TX_FORMAT(Z, Y, X, W, W8Z8Y8X8)),
 	_ASSIGN(ARGB8888, R300_EASY_TX_FORMAT(X, Y, Z, W, W8Z8Y8X8)),
 	_ASSIGN(ARGB8888_REV, R300_EASY_TX_FORMAT(W, Z, Y, X, W8Z8Y8X8)),
-	_ASSIGN(RGB888, 0xffffffff),
+	_ASSIGN(RGB888, R300_EASY_TX_FORMAT(X, Y, Z, ONE, W8Z8Y8X8)),
 	_ASSIGN(RGB565, R300_EASY_TX_FORMAT(X, Y, Z, ONE, Z5Y6X5)),
 	_ASSIGN(RGB565_REV, R300_EASY_TX_FORMAT(X, Y, Z, ONE, Z5Y6X5)),
 	_ASSIGN(ARGB4444, R300_EASY_TX_FORMAT(X, Y, Z, W, W4Z4Y4X4)),
@@ -178,7 +178,7 @@ static void r300SetTexImages(r300ContextPtr rmesa,
 
 	/* Set the hardware texture format
 	 */
-	if (VALID_FORMAT(baseImage->TexFormat->MesaFormat)) {
+	if (!t->image_override && VALID_FORMAT(baseImage->TexFormat->MesaFormat)) {
 		if (_mesa_little_endian()) {
 			t->format =
 			    tx_table_le[baseImage->TexFormat->MesaFormat].
@@ -194,7 +194,7 @@ static void r300SetTexImages(r300ContextPtr rmesa,
 			    tx_table_be[baseImage->TexFormat->MesaFormat].
 			    filter;
 		}
-	} else {
+	} else if (!t->image_override) {
 		_mesa_problem(NULL, "unexpected texture format in %s",
 			      __FUNCTION__);
 		return;
@@ -382,9 +382,10 @@ static void r300SetTexImages(r300ContextPtr rmesa,
 		t->pitch = ((tObj->Image[0][t->base.firstLevel]->Width *
 			     texelBytes) + 63) & ~(63);
 		t->size |= R300_TX_SIZE_TXPITCH_EN;
-		t->pitch_reg =
-		    (((tObj->Image[0][t->base.firstLevel]->Width) +
-		      align) & ~align) - 1;
+		if (!t->image_override)
+			t->pitch_reg =
+			    (((tObj->Image[0][t->base.firstLevel]->Width) +
+			      align) & ~align) - 1;
 	} else {
 		t->pitch =
 		    ((tObj->Image[0][t->base.firstLevel]->Width *
@@ -411,9 +412,10 @@ static GLboolean r300EnableTexture2D(GLcontext * ctx, int unit)
 
 	if (t->base.dirty_images[0]) {
 		R300_FIREVERTICES(rmesa);
+
 		r300SetTexImages(rmesa, tObj);
 		r300UploadTexImages(rmesa, (r300TexObjPtr) tObj->DriverData, 0);
-		if (!t->base.memBlock)
+		if (!t->base.memBlock && !t->image_override)
 			return GL_FALSE;
 	}
 
@@ -492,9 +494,11 @@ static GLboolean r300EnableTextureRect(GLcontext * ctx, int unit)
 
 	if (t->base.dirty_images[0]) {
 		R300_FIREVERTICES(rmesa);
+
 		r300SetTexImages(rmesa, tObj);
 		r300UploadTexImages(rmesa, (r300TexObjPtr) tObj->DriverData, 0);
-		if (!t->base.memBlock && !rmesa->prefer_gart_client_texturing)
+		if (!t->base.memBlock && !t->image_override &&
+		    !rmesa->prefer_gart_client_texturing)
 			return GL_FALSE;
 	}
 
@@ -534,6 +538,51 @@ static GLboolean r300UpdateTexture(GLcontext * ctx, int unit)
 	return !t->border_fallback;
 }
 
+void r300SetTexOffset(__DRIcontext *pDRICtx, GLint texname,
+		      unsigned long long offset, GLint depth, GLuint pitch)
+{
+	r300ContextPtr rmesa =
+		(r300ContextPtr)((__DRIcontextPrivate*)pDRICtx->private)->driverPrivate;
+	struct gl_texture_object *tObj =
+		_mesa_lookup_texture(rmesa->radeon.glCtx, texname);
+	r300TexObjPtr t;
+	int idx;
+
+	if (!tObj)
+		return;
+
+	t = (r300TexObjPtr) tObj->DriverData;
+
+	t->image_override = GL_TRUE;
+
+	if (!offset)
+		return;
+
+	t->offset = offset;
+	t->pitch_reg = pitch;
+
+	switch (depth) {
+	case 32:
+		idx = 2;
+		t->pitch_reg /= 4;
+		break;
+	case 24:
+	default:
+		idx = 4;
+		t->pitch_reg /= 4;
+		break;
+	case 16:
+		idx = 5;
+		t->pitch_reg /= 2;
+		break;
+	}
+
+	t->pitch_reg--;
+
+	t->format = tx_table_le[idx].format;
+	t->filter |= tx_table_le[idx].filter;
+}
+
 static GLboolean r300UpdateTextureUnit(GLcontext * ctx, int unit)
 {
 	struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
diff --git a/src/mesa/drivers/dri/radeon/radeon_screen.c b/src/mesa/drivers/dri/radeon/radeon_screen.c
index b476864d03..aa7fb633dd 100644
--- a/src/mesa/drivers/dri/radeon/radeon_screen.c
+++ b/src/mesa/drivers/dri/radeon/radeon_screen.c
@@ -56,6 +56,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #elif RADEON_COMMON && defined(RADEON_COMMON_FOR_R300)
 #include "r300_context.h"
 #include "r300_fragprog.h"
+#include "r300_tex.h"
 #include "radeon_span.h"
 #endif
 
@@ -952,6 +953,9 @@ static struct __DriverAPIRec radeonAPI = {
    .WaitForSBC      = NULL,
    .SwapBuffersMSC  = NULL,
    .CopySubBuffer   = radeonCopySubBuffer,
+#if RADEON_COMMON && defined(RADEON_COMMON_FOR_R300)
+   .setTexOffset    = r300SetTexOffset,
+#endif
 };
 #else
 static const struct __DriverAPIRec r200API = {
-- 
cgit v1.2.3


From e0885b84a0e10d6a3c976c8dc52a5fdc175635bb Mon Sep 17 00:00:00 2001
From: Michel Dänzer <michel@tungstengraphics.com>
Date: Tue, 22 May 2007 14:08:11 +0200
Subject: i915tex: Implement SetTexOffset hook.

Only build tested for I830 generation.
---
 src/mesa/drivers/dri/i915tex/i830_reg.h        |  1 +
 src/mesa/drivers/dri/i915tex/i830_texstate.c   | 41 +++++++++++++++------
 src/mesa/drivers/dri/i915tex/i915_texstate.c   | 49 ++++++++++++++++++--------
 src/mesa/drivers/dri/i915tex/i915_vtbl.c       |  6 ++--
 src/mesa/drivers/dri/i915tex/intel_context.h   |  4 +++
 src/mesa/drivers/dri/i915tex/intel_screen.c    |  3 +-
 src/mesa/drivers/dri/i915tex/intel_tex.h       |  3 ++
 src/mesa/drivers/dri/i915tex/intel_tex_image.c | 24 ++++++++++++-
 8 files changed, 103 insertions(+), 28 deletions(-)

(limited to 'src/mesa/drivers')

diff --git a/src/mesa/drivers/dri/i915tex/i830_reg.h b/src/mesa/drivers/dri/i915tex/i830_reg.h
index 24ac524500..41280bca7c 100644
--- a/src/mesa/drivers/dri/i915tex/i830_reg.h
+++ b/src/mesa/drivers/dri/i915tex/i830_reg.h
@@ -575,6 +575,7 @@
 #define    MT_16BIT_DIB_RGB565_8888	   (7<<3)
 #define    MT_32BIT_ARGB8888		   (0<<3)       /* SURFACE_32BIT */
 #define    MT_32BIT_ABGR8888		   (1<<3)
+#define    MT_32BIT_XRGB8888		   (2<<3)       /* XXX: Guess from i915_reg.h */
 #define    MT_32BIT_BUMP_XLDVDU_8888	   (6<<3)
 #define    MT_32BIT_DIB_8888		   (7<<3)
 #define    MT_411_YUV411		   (0<<3)       /* SURFACE_411 */
diff --git a/src/mesa/drivers/dri/i915tex/i830_texstate.c b/src/mesa/drivers/dri/i915tex/i830_texstate.c
index e3f34e3944..0d3f053226 100644
--- a/src/mesa/drivers/dri/i915tex/i830_texstate.c
+++ b/src/mesa/drivers/dri/i915tex/i830_texstate.c
@@ -117,7 +117,7 @@ i830_update_tex_unit(struct intel_context *intel, GLuint unit, GLuint ss3)
    struct gl_texture_object *tObj = ctx->Texture.Unit[unit]._Current;
    struct intel_texture_object *intelObj = intel_texture_object(tObj);
    struct gl_texture_image *firstImage;
-   GLuint *state = i830->state.Tex[unit];
+   GLuint *state = i830->state.Tex[unit], format, pitch;
 
    memset(state, 0, sizeof(state));
 
@@ -128,7 +128,7 @@ i830_update_tex_unit(struct intel_context *intel, GLuint unit, GLuint ss3)
        i830->state.tex_buffer[unit] = NULL;
    }
 
-   if (!intel_finalize_mipmap_tree(intel, unit))
+   if (!intelObj->imageOverride && !intel_finalize_mipmap_tree(intel, unit))
       return GL_FALSE;
 
    /* Get first image here, since intelObj->firstLevel will get set in
@@ -136,11 +136,34 @@ i830_update_tex_unit(struct intel_context *intel, GLuint unit, GLuint ss3)
     */
    firstImage = tObj->Image[0][intelObj->firstLevel];
 
-   i830->state.tex_buffer[unit] = driBOReference(intelObj->mt->region->buffer);
-   i830->state.tex_offset[unit] = intel_miptree_image_offset(intelObj->mt, 0,
-                                                             intelObj->
-                                                             firstLevel);
+   if (intelObj->imageOverride) {
+      i830->state.tex_buffer[unit] = NULL;
+      i830->state.tex_offset[unit] = intelObj->textureOffset;
 
+      switch (intelObj->depthOverride) {
+      case 32:
+	 format = MAPSURF_32BIT | MT_32BIT_ARGB8888;
+	 break;
+      case 24:
+      default:
+	 format = MAPSURF_32BIT | MT_32BIT_XRGB8888;
+	 break;
+      case 16:
+	 format = MAPSURF_16BIT | MT_16BIT_RGB565;
+	 break;
+      }
+
+      pitch = intelObj->pitchOverride;
+   } else {
+      i830->state.tex_buffer[unit] = driBOReference(intelObj->mt->region->
+						    buffer);
+      i830->state.tex_offset[unit] = intel_miptree_image_offset(intelObj->mt,
+								0, intelObj->
+								firstLevel);
+
+      format = translate_texture_format(firstImage->TexFormat->MesaFormat);
+      pitch = intelObj->mt->pitch * intelObj->mt->cpp;
+   }
 
    state[I830_TEXREG_TM0LI] = (_3DSTATE_LOAD_STATE_IMMEDIATE_2 |
                                (LOAD_TEXTURE_MAP0 << unit) | 4);
@@ -151,12 +174,10 @@ i830_update_tex_unit(struct intel_context *intel, GLuint unit, GLuint ss3)
 
    state[I830_TEXREG_TM0S1] =
       (((firstImage->Height - 1) << TM0S1_HEIGHT_SHIFT) |
-       ((firstImage->Width - 1) << TM0S1_WIDTH_SHIFT) |
-       translate_texture_format(firstImage->TexFormat->MesaFormat));
+       ((firstImage->Width - 1) << TM0S1_WIDTH_SHIFT) | format);
 
    state[I830_TEXREG_TM0S2] =
-      (((((intelObj->mt->pitch * intelObj->mt->cpp) / 4) -
-         1) << TM0S2_PITCH_SHIFT) | TM0S2_CUBE_FACE_ENA_MASK);
+      ((((pitch / 4) - 1) << TM0S2_PITCH_SHIFT) | TM0S2_CUBE_FACE_ENA_MASK);
 
    {
       if (tObj->Target == GL_TEXTURE_CUBE_MAP)
diff --git a/src/mesa/drivers/dri/i915tex/i915_texstate.c b/src/mesa/drivers/dri/i915tex/i915_texstate.c
index e0ecdfde24..3d68187cf8 100644
--- a/src/mesa/drivers/dri/i915tex/i915_texstate.c
+++ b/src/mesa/drivers/dri/i915tex/i915_texstate.c
@@ -122,7 +122,7 @@ i915_update_tex_unit(struct intel_context *intel, GLuint unit, GLuint ss3)
    struct gl_texture_object *tObj = ctx->Texture.Unit[unit]._Current;
    struct intel_texture_object *intelObj = intel_texture_object(tObj);
    struct gl_texture_image *firstImage;
-   GLuint *state = i915->state.Tex[unit];
+   GLuint *state = i915->state.Tex[unit], format, pitch;
 
    memset(state, 0, sizeof(state));
 
@@ -133,7 +133,7 @@ i915_update_tex_unit(struct intel_context *intel, GLuint unit, GLuint ss3)
        i915->state.tex_buffer[unit] = NULL;
    }
 
-   if (!intel_finalize_mipmap_tree(intel, unit))
+   if (!intelObj->imageOverride && !intel_finalize_mipmap_tree(intel, unit))
       return GL_FALSE;
 
    /* Get first image here, since intelObj->firstLevel will get set in
@@ -141,24 +141,45 @@ i915_update_tex_unit(struct intel_context *intel, GLuint unit, GLuint ss3)
     */
    firstImage = tObj->Image[0][intelObj->firstLevel];
 
-   i915->state.tex_buffer[unit] = driBOReference(intelObj->mt->region->buffer);
-   i915->state.tex_offset[unit] = intel_miptree_image_offset(intelObj->mt, 0,
-                                                             intelObj->
-                                                             firstLevel);
+   if (intelObj->imageOverride) {
+      i915->state.tex_buffer[unit] = NULL;
+      i915->state.tex_offset[unit] = intelObj->textureOffset;
+
+      switch (intelObj->depthOverride) {
+      case 32:
+	 format = MAPSURF_32BIT | MT_32BIT_ARGB8888;
+	 break;
+      case 24:
+      default:
+	 format = MAPSURF_32BIT | MT_32BIT_XRGB8888;
+	 break;
+      case 16:
+	 format = MAPSURF_16BIT | MT_16BIT_RGB565;
+	 break;
+      }
+
+      pitch = intelObj->pitchOverride;
+   } else {
+      i915->state.tex_buffer[unit] = driBOReference(intelObj->mt->region->
+						    buffer);
+      i915->state.tex_offset[unit] =  intel_miptree_image_offset(intelObj->mt,
+								 0, intelObj->
+								 firstLevel);
+
+      format = translate_texture_format(firstImage->TexFormat->MesaFormat);
+      pitch = intelObj->mt->pitch * intelObj->mt->cpp;
+   }
 
    state[I915_TEXREG_MS3] =
       (((firstImage->Height - 1) << MS3_HEIGHT_SHIFT) |
-       ((firstImage->Width - 1) << MS3_WIDTH_SHIFT) |
-       translate_texture_format(firstImage->TexFormat->MesaFormat) |
+       ((firstImage->Width - 1) << MS3_WIDTH_SHIFT) | format |
        MS3_USE_FENCE_REGS);
 
    state[I915_TEXREG_MS4] =
-      (((((intelObj->mt->pitch * intelObj->mt->cpp) / 4) -
-         1) << MS4_PITCH_SHIFT) | MS4_CUBE_FACE_ENA_MASK |
-       ((((intelObj->lastLevel -
-           intelObj->firstLevel) *
-          4)) << MS4_MAX_LOD_SHIFT) | ((firstImage->Depth -
-                                        1) << MS4_VOLUME_DEPTH_SHIFT));
+     ((((pitch / 4) - 1) << MS4_PITCH_SHIFT) | MS4_CUBE_FACE_ENA_MASK |
+       ((((intelObj->lastLevel - intelObj->firstLevel) * 4)) <<
+	MS4_MAX_LOD_SHIFT) | ((firstImage->Depth - 1) <<
+			      MS4_VOLUME_DEPTH_SHIFT));
 
 
    {
diff --git a/src/mesa/drivers/dri/i915tex/i915_vtbl.c b/src/mesa/drivers/dri/i915tex/i915_vtbl.c
index 52db9a95e6..f80e8d6327 100644
--- a/src/mesa/drivers/dri/i915tex/i915_vtbl.c
+++ b/src/mesa/drivers/dri/i915tex/i915_vtbl.c
@@ -381,11 +381,13 @@ i915_emit_state(struct intel_context *intel)
                          DRM_BO_MASK_MEM | DRM_BO_FLAG_READ,
                          state->tex_offset[i]);
             }
-            else {
+            else if (state == &i915->meta) {
                assert(i == 0);
-               assert(state == &i915->meta);
                OUT_BATCH(0);
             }
+            else {
+               OUT_BATCH(state->tex_offset[i]);
+            }
 
             OUT_BATCH(state->Tex[i][I915_TEXREG_MS3]);
             OUT_BATCH(state->Tex[i][I915_TEXREG_MS4]);
diff --git a/src/mesa/drivers/dri/i915tex/intel_context.h b/src/mesa/drivers/dri/i915tex/intel_context.h
index 44c20af7f8..bcbbb127b1 100644
--- a/src/mesa/drivers/dri/i915tex/intel_context.h
+++ b/src/mesa/drivers/dri/i915tex/intel_context.h
@@ -92,6 +92,10 @@ struct intel_texture_object
     * regions will be copied to this region and the old storage freed.
     */
    struct intel_mipmap_tree *mt;
+
+   GLboolean imageOverride;
+   GLint depthOverride;
+   GLuint pitchOverride;
 };
 
 
diff --git a/src/mesa/drivers/dri/i915tex/intel_screen.c b/src/mesa/drivers/dri/i915tex/intel_screen.c
index dd01161b5b..5e6df81950 100644
--- a/src/mesa/drivers/dri/i915tex/intel_screen.c
+++ b/src/mesa/drivers/dri/i915tex/intel_screen.c
@@ -776,7 +776,8 @@ static const struct __DriverAPIRec intelAPI = {
    .WaitForMSC = driWaitForMSC32,
    .WaitForSBC = NULL,
    .SwapBuffersMSC = NULL,
-   .CopySubBuffer = intelCopySubBuffer
+   .CopySubBuffer = intelCopySubBuffer,
+   .setTexOffset = intelSetTexOffset,
 };
 
 
diff --git a/src/mesa/drivers/dri/i915tex/intel_tex.h b/src/mesa/drivers/dri/i915tex/intel_tex.h
index 6e9938fe53..b77d7a1d8a 100644
--- a/src/mesa/drivers/dri/i915tex/intel_tex.h
+++ b/src/mesa/drivers/dri/i915tex/intel_tex.h
@@ -135,6 +135,9 @@ void intelGetCompressedTexImage(GLcontext *ctx, GLenum target, GLint level,
 				const struct gl_texture_object *texObj,
 				const struct gl_texture_image *texImage);
 
+void intelSetTexOffset(__DRIcontext *pDRICtx, GLint texname,
+		       unsigned long long offset, GLint depth, GLuint pitch);
+
 GLuint intel_finalize_mipmap_tree(struct intel_context *intel, GLuint unit);
 
 void intel_tex_map_images(struct intel_context *intel,
diff --git a/src/mesa/drivers/dri/i915tex/intel_tex_image.c b/src/mesa/drivers/dri/i915tex/intel_tex_image.c
index 42679ef9db..abab90cc06 100644
--- a/src/mesa/drivers/dri/i915tex/intel_tex_image.c
+++ b/src/mesa/drivers/dri/i915tex/intel_tex_image.c
@@ -378,6 +378,9 @@ intelTexImage(GLcontext * ctx,
       assert(!intelObj->mt);
    }
 
+   if (!pixels)
+      return;
+
    if (!intelObj->mt) {
       guess_and_alloc_mipmap_tree(intel, intelObj, intelImage);
       if (!intelObj->mt) {
@@ -385,7 +388,6 @@ intelTexImage(GLcontext * ctx,
       }
    }
 
-
    assert(!intelImage->mt);
 
    if (intelObj->mt &&
@@ -667,3 +669,23 @@ intelGetCompressedTexImage(GLcontext *ctx, GLenum target, GLint level,
 		       texObj, texImage, 1);
 
 }
+
+void
+intelSetTexOffset(__DRIcontext *pDRICtx, GLint texname,
+		  unsigned long long offset, GLint depth, GLuint pitch)
+{
+   struct intel_context *intel = (struct intel_context*)
+      ((__DRIcontextPrivate*)pDRICtx->private)->driverPrivate;
+   struct gl_texture_object *tObj = _mesa_lookup_texture(&intel->ctx, texname);
+   struct intel_texture_object *intelObj = intel_texture_object(tObj);
+
+   if (!intelObj)
+      return;
+
+   intelObj->imageOverride = GL_TRUE;
+   intelObj->depthOverride = depth;
+   intelObj->pitchOverride = pitch;
+
+   if (offset)
+      intelObj->textureOffset = offset;
+}
-- 
cgit v1.2.3


From 3a2ffadb7c98c040f01340d20289cffe753d48c2 Mon Sep 17 00:00:00 2001
From: Brian <brian.paul@tungstengraphics.com>
Date: Tue, 22 May 2007 16:50:05 -0600
Subject: include swrast_setup/swrast_setup.h to silence warning

---
 src/mesa/drivers/dri/i965/brw_draw.c | 1 +
 1 file changed, 1 insertion(+)

(limited to 'src/mesa/drivers')

diff --git a/src/mesa/drivers/dri/i965/brw_draw.c b/src/mesa/drivers/dri/i965/brw_draw.c
index c7798b14a9..0c64d7e756 100644
--- a/src/mesa/drivers/dri/i965/brw_draw.c
+++ b/src/mesa/drivers/dri/i965/brw_draw.c
@@ -47,6 +47,7 @@
 #include "tnl/tnl.h"
 #include "vbo/vbo_context.h"
 #include "swrast/swrast.h"
+#include "swrast_setup/swrast_setup.h"
 
 
 
-- 
cgit v1.2.3


From a99114a69f2b7963ca1f855a320aea8aa56755ac Mon Sep 17 00:00:00 2001
From: Brian <brian.paul@tungstengraphics.com>
Date: Tue, 22 May 2007 16:54:25 -0600
Subject: added _mesa_init_driver_state() to replace duplicated code in intel
 drivers

---
 src/mesa/drivers/common/driverfuncs.c | 96 ++++++++++++++++++++++++++++++++++-
 src/mesa/drivers/common/driverfuncs.h |  7 ++-
 2 files changed, 101 insertions(+), 2 deletions(-)

(limited to 'src/mesa/drivers')

diff --git a/src/mesa/drivers/common/driverfuncs.c b/src/mesa/drivers/common/driverfuncs.c
index adf9aafe59..9b1c3f1e06 100644
--- a/src/mesa/drivers/common/driverfuncs.c
+++ b/src/mesa/drivers/common/driverfuncs.c
@@ -1,6 +1,6 @@
 /*
  * Mesa 3-D graphics library
- * Version:  6.5.3
+ * Version:  7.1
  *
  * Copyright (C) 1999-2007  Brian Paul   All Rights Reserved.
  *
@@ -292,3 +292,97 @@ _mesa_init_glsl_driver_functions(struct dd_function_table *driver)
    driver->UseProgram = _mesa_use_program;
    driver->ValidateProgram = _mesa_validate_program;
 }
+
+
+/**
+ * Call the ctx->Driver.* state functions with current values to initialize
+ * driver state.
+ * Only the Intel drivers use this so far.
+ */
+void
+_mesa_init_driver_state(GLcontext *ctx)
+{
+   ctx->Driver.AlphaFunc(ctx, ctx->Color.AlphaFunc, ctx->Color.AlphaRef);
+
+   ctx->Driver.BlendColor(ctx, ctx->Color.BlendColor);
+
+   ctx->Driver.BlendEquationSeparate(ctx,
+                                     ctx->Color.BlendEquationRGB,
+                                     ctx->Color.BlendEquationA);
+
+   ctx->Driver.BlendFuncSeparate(ctx,
+                                 ctx->Color.BlendSrcRGB,
+                                 ctx->Color.BlendDstRGB,
+                                 ctx->Color.BlendSrcA, ctx->Color.BlendDstA);
+
+   ctx->Driver.ColorMask(ctx,
+                         ctx->Color.ColorMask[RCOMP],
+                         ctx->Color.ColorMask[GCOMP],
+                         ctx->Color.ColorMask[BCOMP],
+                         ctx->Color.ColorMask[ACOMP]);
+
+   ctx->Driver.CullFace(ctx, ctx->Polygon.CullFaceMode);
+   ctx->Driver.DepthFunc(ctx, ctx->Depth.Func);
+   ctx->Driver.DepthMask(ctx, ctx->Depth.Mask);
+
+   ctx->Driver.Enable(ctx, GL_ALPHA_TEST, ctx->Color.AlphaEnabled);
+   ctx->Driver.Enable(ctx, GL_BLEND, ctx->Color.BlendEnabled);
+   ctx->Driver.Enable(ctx, GL_COLOR_LOGIC_OP, ctx->Color.ColorLogicOpEnabled);
+   ctx->Driver.Enable(ctx, GL_COLOR_SUM, ctx->Fog.ColorSumEnabled);
+   ctx->Driver.Enable(ctx, GL_CULL_FACE, ctx->Polygon.CullFlag);
+   ctx->Driver.Enable(ctx, GL_DEPTH_TEST, ctx->Depth.Test);
+   ctx->Driver.Enable(ctx, GL_DITHER, ctx->Color.DitherFlag);
+   ctx->Driver.Enable(ctx, GL_FOG, ctx->Fog.Enabled);
+   ctx->Driver.Enable(ctx, GL_LIGHTING, ctx->Light.Enabled);
+   ctx->Driver.Enable(ctx, GL_LINE_SMOOTH, ctx->Line.SmoothFlag);
+   ctx->Driver.Enable(ctx, GL_POLYGON_STIPPLE, ctx->Polygon.StippleFlag);
+   ctx->Driver.Enable(ctx, GL_SCISSOR_TEST, ctx->Scissor.Enabled);
+   ctx->Driver.Enable(ctx, GL_STENCIL_TEST, ctx->Stencil.Enabled);
+   ctx->Driver.Enable(ctx, GL_TEXTURE_1D, GL_FALSE);
+   ctx->Driver.Enable(ctx, GL_TEXTURE_2D, GL_FALSE);
+   ctx->Driver.Enable(ctx, GL_TEXTURE_RECTANGLE_NV, GL_FALSE);
+   ctx->Driver.Enable(ctx, GL_TEXTURE_3D, GL_FALSE);
+   ctx->Driver.Enable(ctx, GL_TEXTURE_CUBE_MAP, GL_FALSE);
+
+   ctx->Driver.Fogfv(ctx, GL_FOG_COLOR, ctx->Fog.Color);
+   ctx->Driver.Fogfv(ctx, GL_FOG_MODE, 0);
+   ctx->Driver.Fogfv(ctx, GL_FOG_DENSITY, &ctx->Fog.Density);
+   ctx->Driver.Fogfv(ctx, GL_FOG_START, &ctx->Fog.Start);
+   ctx->Driver.Fogfv(ctx, GL_FOG_END, &ctx->Fog.End);
+
+   ctx->Driver.FrontFace(ctx, ctx->Polygon.FrontFace);
+
+   {
+      GLfloat f = (GLfloat) ctx->Light.Model.ColorControl;
+      ctx->Driver.LightModelfv(ctx, GL_LIGHT_MODEL_COLOR_CONTROL, &f);
+   }
+
+   ctx->Driver.LineWidth(ctx, ctx->Line.Width);
+   ctx->Driver.LogicOpcode(ctx, ctx->Color.LogicOp);
+   ctx->Driver.PointSize(ctx, ctx->Point.Size);
+   ctx->Driver.PolygonStipple(ctx, (const GLubyte *) ctx->PolygonStipple);
+   ctx->Driver.Scissor(ctx, ctx->Scissor.X, ctx->Scissor.Y,
+                       ctx->Scissor.Width, ctx->Scissor.Height);
+   ctx->Driver.ShadeModel(ctx, ctx->Light.ShadeModel);
+   ctx->Driver.StencilFuncSeparate(ctx, GL_FRONT,
+                                   ctx->Stencil.Function[0],
+                                   ctx->Stencil.Ref[0],
+                                   ctx->Stencil.ValueMask[0]);
+   ctx->Driver.StencilFuncSeparate(ctx, GL_BACK,
+                                   ctx->Stencil.Function[1],
+                                   ctx->Stencil.Ref[1],
+                                   ctx->Stencil.ValueMask[1]);
+   ctx->Driver.StencilMaskSeparate(ctx, GL_FRONT, ctx->Stencil.WriteMask[0]);
+   ctx->Driver.StencilMaskSeparate(ctx, GL_BACK, ctx->Stencil.WriteMask[1]);
+   ctx->Driver.StencilOpSeparate(ctx, GL_FRONT,
+                                 ctx->Stencil.FailFunc[0],
+                                 ctx->Stencil.ZFailFunc[0],
+                                 ctx->Stencil.ZPassFunc[0]);
+   ctx->Driver.StencilOpSeparate(ctx, GL_BACK,
+                                 ctx->Stencil.FailFunc[1],
+                                 ctx->Stencil.ZFailFunc[1],
+                                 ctx->Stencil.ZPassFunc[1]);
+
+
+   ctx->Driver.DrawBuffer(ctx, ctx->Color.DrawBuffer[0]);
+}
diff --git a/src/mesa/drivers/common/driverfuncs.h b/src/mesa/drivers/common/driverfuncs.h
index 50f2b4271d..6ed23c4520 100644
--- a/src/mesa/drivers/common/driverfuncs.h
+++ b/src/mesa/drivers/common/driverfuncs.h
@@ -1,6 +1,6 @@
 /*
  * Mesa 3-D graphics library
- * Version:  6.5.3
+ * Version:  7.1
  *
  * Copyright (C) 1999-2007  Brian Paul   All Rights Reserved.
  *
@@ -33,4 +33,9 @@ _mesa_init_driver_functions(struct dd_function_table *driver);
 extern void
 _mesa_init_glsl_driver_functions(struct dd_function_table *driver);
 
+
+extern void
+_mesa_init_driver_state(GLcontext *ctx);
+
+
 #endif
-- 
cgit v1.2.3


From a194bc3a8527ed41eead88632cc79ecabe4c81ac Mon Sep 17 00:00:00 2001
From: Brian <brian.paul@tungstengraphics.com>
Date: Tue, 22 May 2007 16:56:02 -0600
Subject: Replace initInitState() with _mesa_init_driver_state().

---
 src/mesa/drivers/dri/i915/i830_state.c       |  9 +--
 src/mesa/drivers/dri/i915/i915_state.c       | 11 +---
 src/mesa/drivers/dri/i915/intel_context.c    | 95 ---------------------------
 src/mesa/drivers/dri/i915/intel_context.h    |  1 -
 src/mesa/drivers/dri/i915tex/i830_state.c    |  4 +-
 src/mesa/drivers/dri/i915tex/i915_state.c    |  4 +-
 src/mesa/drivers/dri/i915tex/intel_context.h |  1 -
 src/mesa/drivers/dri/i915tex/intel_state.c   | 94 ---------------------------
 src/mesa/drivers/dri/i965/intel_context.h    |  1 -
 src/mesa/drivers/dri/i965/intel_state.c      | 96 ----------------------------
 10 files changed, 12 insertions(+), 304 deletions(-)

(limited to 'src/mesa/drivers')

diff --git a/src/mesa/drivers/dri/i915/i830_state.c b/src/mesa/drivers/dri/i915/i830_state.c
index 9512519010..f7980201f9 100644
--- a/src/mesa/drivers/dri/i915/i830_state.c
+++ b/src/mesa/drivers/dri/i915/i830_state.c
@@ -34,6 +34,8 @@
 
 #include "texmem.h"
 
+#include "drivers/common/driverfuncs.h"
+
 #include "intel_screen.h"
 #include "intel_batchbuffer.h"
 
@@ -1074,7 +1076,7 @@ void i830InitState( i830ContextPtr i830 )
 
    i830_init_packets( i830 );
 
-   intelInitState( ctx );
+   _mesa_init_driver_state(ctx);
 
    memcpy( &i830->initial, &i830->state, sizeof(i830->state) );
 
@@ -1085,8 +1087,3 @@ void i830InitState( i830ContextPtr i830 )
 			 I830_UPLOAD_CTX |
 			 I830_UPLOAD_BUFFERS);
 }
-
-
-
-
-
diff --git a/src/mesa/drivers/dri/i915/i915_state.c b/src/mesa/drivers/dri/i915/i915_state.c
index 0d5ca32969..1c4ec74755 100644
--- a/src/mesa/drivers/dri/i915/i915_state.c
+++ b/src/mesa/drivers/dri/i915/i915_state.c
@@ -36,6 +36,8 @@
 
 #include "texmem.h"
 
+#include "drivers/common/driverfuncs.h"
+
 #include "intel_screen.h"
 #include "intel_batchbuffer.h"
 
@@ -961,15 +963,8 @@ void i915InitState( i915ContextPtr i915 )
 
    i915_init_packets( i915 );
 
-   intelInitState( ctx );
+   _mesa_init_driver_state(ctx);
 
    memcpy( &i915->initial, &i915->state, sizeof(i915->state) );
    i915->current = &i915->state;
 }
-
-
-
-
-
-
-
diff --git a/src/mesa/drivers/dri/i915/intel_context.c b/src/mesa/drivers/dri/i915/intel_context.c
index e1e7cdb723..e747fc6991 100644
--- a/src/mesa/drivers/dri/i915/intel_context.c
+++ b/src/mesa/drivers/dri/i915/intel_context.c
@@ -766,98 +766,3 @@ void intelCopySubBuffer( __DRIdrawablePrivate *dPriv,
       fprintf(stderr, "%s: drawable has no context!\n", __FUNCTION__);
    }
 }
-
-void intelInitState( GLcontext *ctx )
-{
-   /* Mesa should do this for us:
-    */
-   ctx->Driver.AlphaFunc( ctx, 
-			  ctx->Color.AlphaFunc,
-			  ctx->Color.AlphaRef);
-
-   ctx->Driver.BlendColor( ctx,
-			   ctx->Color.BlendColor );
-
-   ctx->Driver.BlendEquationSeparate( ctx, 
-				      ctx->Color.BlendEquationRGB,
-				      ctx->Color.BlendEquationA);
-
-   ctx->Driver.BlendFuncSeparate( ctx,
-				  ctx->Color.BlendSrcRGB,
-				  ctx->Color.BlendDstRGB,
-				  ctx->Color.BlendSrcA,
-				  ctx->Color.BlendDstA);
-
-   ctx->Driver.ColorMask( ctx, 
-			  ctx->Color.ColorMask[RCOMP],
-			  ctx->Color.ColorMask[GCOMP],
-			  ctx->Color.ColorMask[BCOMP],
-			  ctx->Color.ColorMask[ACOMP]);
-
-   ctx->Driver.CullFace( ctx, ctx->Polygon.CullFaceMode );
-   ctx->Driver.DepthFunc( ctx, ctx->Depth.Func );
-   ctx->Driver.DepthMask( ctx, ctx->Depth.Mask );
-
-   ctx->Driver.Enable( ctx, GL_ALPHA_TEST, ctx->Color.AlphaEnabled );
-   ctx->Driver.Enable( ctx, GL_BLEND, ctx->Color.BlendEnabled );
-   ctx->Driver.Enable( ctx, GL_COLOR_LOGIC_OP, ctx->Color.ColorLogicOpEnabled );
-   ctx->Driver.Enable( ctx, GL_COLOR_SUM, ctx->Fog.ColorSumEnabled );
-   ctx->Driver.Enable( ctx, GL_CULL_FACE, ctx->Polygon.CullFlag );
-   ctx->Driver.Enable( ctx, GL_DEPTH_TEST, ctx->Depth.Test );
-   ctx->Driver.Enable( ctx, GL_DITHER, ctx->Color.DitherFlag );
-   ctx->Driver.Enable( ctx, GL_FOG, ctx->Fog.Enabled );
-   ctx->Driver.Enable( ctx, GL_LIGHTING, ctx->Light.Enabled );
-   ctx->Driver.Enable( ctx, GL_LINE_SMOOTH, ctx->Line.SmoothFlag );
-   ctx->Driver.Enable( ctx, GL_POLYGON_STIPPLE, ctx->Polygon.StippleFlag );
-   ctx->Driver.Enable( ctx, GL_SCISSOR_TEST, ctx->Scissor.Enabled );
-   ctx->Driver.Enable( ctx, GL_STENCIL_TEST, ctx->Stencil.Enabled );
-   ctx->Driver.Enable( ctx, GL_TEXTURE_1D, GL_FALSE );
-   ctx->Driver.Enable( ctx, GL_TEXTURE_2D, GL_FALSE );
-   ctx->Driver.Enable( ctx, GL_TEXTURE_RECTANGLE_NV, GL_FALSE );
-   ctx->Driver.Enable( ctx, GL_TEXTURE_3D, GL_FALSE );
-   ctx->Driver.Enable( ctx, GL_TEXTURE_CUBE_MAP, GL_FALSE );
-
-   ctx->Driver.Fogfv( ctx, GL_FOG_COLOR, ctx->Fog.Color );
-   ctx->Driver.Fogfv( ctx, GL_FOG_MODE, 0 );
-   ctx->Driver.Fogfv( ctx, GL_FOG_DENSITY, &ctx->Fog.Density );
-   ctx->Driver.Fogfv( ctx, GL_FOG_START, &ctx->Fog.Start );
-   ctx->Driver.Fogfv( ctx, GL_FOG_END, &ctx->Fog.End );
-
-   ctx->Driver.FrontFace( ctx, ctx->Polygon.FrontFace );
-
-   {
-      GLfloat f = (GLfloat)ctx->Light.Model.ColorControl;
-      ctx->Driver.LightModelfv( ctx, GL_LIGHT_MODEL_COLOR_CONTROL, &f );
-   }
-
-   ctx->Driver.LineWidth( ctx, ctx->Line.Width );
-   ctx->Driver.LogicOpcode( ctx, ctx->Color.LogicOp );
-   ctx->Driver.PointSize( ctx, ctx->Point.Size );
-   ctx->Driver.PolygonStipple( ctx, (const GLubyte *)ctx->PolygonStipple );
-   ctx->Driver.Scissor( ctx, ctx->Scissor.X, ctx->Scissor.Y,
-			ctx->Scissor.Width, ctx->Scissor.Height );
-   ctx->Driver.ShadeModel( ctx, ctx->Light.ShadeModel );
-   ctx->Driver.StencilFuncSeparate( ctx, GL_FRONT,
-                                    ctx->Stencil.Function[0],
-                                    ctx->Stencil.Ref[0],
-                                    ctx->Stencil.ValueMask[0] );
-   ctx->Driver.StencilFuncSeparate( ctx, GL_BACK,
-                                    ctx->Stencil.Function[1],
-                                    ctx->Stencil.Ref[1],
-                                    ctx->Stencil.ValueMask[1] );
-   ctx->Driver.StencilMaskSeparate( ctx, GL_FRONT, ctx->Stencil.WriteMask[0] );
-   ctx->Driver.StencilMaskSeparate( ctx, GL_BACK, ctx->Stencil.WriteMask[1] );
-   ctx->Driver.StencilOpSeparate( ctx, GL_FRONT,
-                                  ctx->Stencil.FailFunc[0],
-                                  ctx->Stencil.ZFailFunc[0],
-                                  ctx->Stencil.ZPassFunc[0]);
-   ctx->Driver.StencilOpSeparate( ctx, GL_BACK,
-                                  ctx->Stencil.FailFunc[1],
-                                  ctx->Stencil.ZFailFunc[1],
-                                  ctx->Stencil.ZPassFunc[1]);
-
-
-   ctx->Driver.DrawBuffer( ctx, ctx->Color.DrawBuffer[0] );
-}
-
-
diff --git a/src/mesa/drivers/dri/i915/intel_context.h b/src/mesa/drivers/dri/i915/intel_context.h
index 05195e76d6..c48b074cc5 100644
--- a/src/mesa/drivers/dri/i915/intel_context.h
+++ b/src/mesa/drivers/dri/i915/intel_context.h
@@ -473,7 +473,6 @@ extern void intelSetBackClipRects(intelContextPtr intel);
 extern void intelSetFrontClipRects(intelContextPtr intel);
 extern void intelWindowMoved( intelContextPtr intel );
 
-extern void intelInitState( GLcontext *ctx );
 extern const GLubyte *intelGetString( GLcontext *ctx, GLenum name );
 
 
diff --git a/src/mesa/drivers/dri/i915tex/i830_state.c b/src/mesa/drivers/dri/i915tex/i830_state.c
index 812daa6524..3c149e6905 100644
--- a/src/mesa/drivers/dri/i915tex/i830_state.c
+++ b/src/mesa/drivers/dri/i915tex/i830_state.c
@@ -34,6 +34,8 @@
 
 #include "texmem.h"
 
+#include "drivers/common/driverfuncs.h"
+
 #include "intel_screen.h"
 #include "intel_batchbuffer.h"
 #include "intel_fbo.h"
@@ -1101,7 +1103,7 @@ i830InitState(struct i830_context *i830)
 
    i830_init_packets(i830);
 
-   intelInitState(ctx);
+   _mesa_init_driver_state(ctx);
 
    memcpy(&i830->initial, &i830->state, sizeof(i830->state));
 
diff --git a/src/mesa/drivers/dri/i915tex/i915_state.c b/src/mesa/drivers/dri/i915tex/i915_state.c
index d3217fa0ca..e5d8d27993 100644
--- a/src/mesa/drivers/dri/i915tex/i915_state.c
+++ b/src/mesa/drivers/dri/i915tex/i915_state.c
@@ -36,6 +36,8 @@
 
 #include "texmem.h"
 
+#include "drivers/common/driverfuncs.h"
+
 #include "intel_fbo.h"
 #include "intel_screen.h"
 #include "intel_batchbuffer.h"
@@ -1005,7 +1007,7 @@ i915InitState(struct i915_context *i915)
 
    i915_init_packets(i915);
 
-   intelInitState(ctx);
+   _mesa_init_driver_state(ctx);
 
    memcpy(&i915->initial, &i915->state, sizeof(i915->state));
    i915->current = &i915->state;
diff --git a/src/mesa/drivers/dri/i915tex/intel_context.h b/src/mesa/drivers/dri/i915tex/intel_context.h
index bcbbb127b1..e61d72eaec 100644
--- a/src/mesa/drivers/dri/i915tex/intel_context.h
+++ b/src/mesa/drivers/dri/i915tex/intel_context.h
@@ -399,7 +399,6 @@ extern GLboolean intelInitContext(struct intel_context *intel,
 
 extern void intelGetLock(struct intel_context *intel, GLuint flags);
 
-extern void intelInitState(GLcontext * ctx);
 extern void intelFinish(GLcontext * ctx);
 extern void intelFlush(GLcontext * ctx);
 
diff --git a/src/mesa/drivers/dri/i915tex/intel_state.c b/src/mesa/drivers/dri/i915tex/intel_state.c
index f85d8ef835..271511037e 100644
--- a/src/mesa/drivers/dri/i915tex/intel_state.c
+++ b/src/mesa/drivers/dri/i915tex/intel_state.c
@@ -267,97 +267,3 @@ intelInitStateFuncs(struct dd_function_table *functions)
    functions->DepthRange = intelDepthRange;
    functions->ClearColor = intelClearColor;
 }
-
-
-
-
-void
-intelInitState(GLcontext * ctx)
-{
-   /* Mesa should do this for us:
-    */
-   ctx->Driver.AlphaFunc(ctx, ctx->Color.AlphaFunc, ctx->Color.AlphaRef);
-
-   ctx->Driver.BlendColor(ctx, ctx->Color.BlendColor);
-
-   ctx->Driver.BlendEquationSeparate(ctx,
-                                     ctx->Color.BlendEquationRGB,
-                                     ctx->Color.BlendEquationA);
-
-   ctx->Driver.BlendFuncSeparate(ctx,
-                                 ctx->Color.BlendSrcRGB,
-                                 ctx->Color.BlendDstRGB,
-                                 ctx->Color.BlendSrcA, ctx->Color.BlendDstA);
-
-   ctx->Driver.ColorMask(ctx,
-                         ctx->Color.ColorMask[RCOMP],
-                         ctx->Color.ColorMask[GCOMP],
-                         ctx->Color.ColorMask[BCOMP],
-                         ctx->Color.ColorMask[ACOMP]);
-
-   ctx->Driver.CullFace(ctx, ctx->Polygon.CullFaceMode);
-   ctx->Driver.DepthFunc(ctx, ctx->Depth.Func);
-   ctx->Driver.DepthMask(ctx, ctx->Depth.Mask);
-
-   ctx->Driver.Enable(ctx, GL_ALPHA_TEST, ctx->Color.AlphaEnabled);
-   ctx->Driver.Enable(ctx, GL_BLEND, ctx->Color.BlendEnabled);
-   ctx->Driver.Enable(ctx, GL_COLOR_LOGIC_OP, ctx->Color.ColorLogicOpEnabled);
-   ctx->Driver.Enable(ctx, GL_COLOR_SUM, ctx->Fog.ColorSumEnabled);
-   ctx->Driver.Enable(ctx, GL_CULL_FACE, ctx->Polygon.CullFlag);
-   ctx->Driver.Enable(ctx, GL_DEPTH_TEST, ctx->Depth.Test);
-   ctx->Driver.Enable(ctx, GL_DITHER, ctx->Color.DitherFlag);
-   ctx->Driver.Enable(ctx, GL_FOG, ctx->Fog.Enabled);
-   ctx->Driver.Enable(ctx, GL_LIGHTING, ctx->Light.Enabled);
-   ctx->Driver.Enable(ctx, GL_LINE_SMOOTH, ctx->Line.SmoothFlag);
-   ctx->Driver.Enable(ctx, GL_POLYGON_STIPPLE, ctx->Polygon.StippleFlag);
-   ctx->Driver.Enable(ctx, GL_SCISSOR_TEST, ctx->Scissor.Enabled);
-   ctx->Driver.Enable(ctx, GL_STENCIL_TEST, ctx->Stencil.Enabled);
-   ctx->Driver.Enable(ctx, GL_TEXTURE_1D, GL_FALSE);
-   ctx->Driver.Enable(ctx, GL_TEXTURE_2D, GL_FALSE);
-   ctx->Driver.Enable(ctx, GL_TEXTURE_RECTANGLE_NV, GL_FALSE);
-   ctx->Driver.Enable(ctx, GL_TEXTURE_3D, GL_FALSE);
-   ctx->Driver.Enable(ctx, GL_TEXTURE_CUBE_MAP, GL_FALSE);
-
-   ctx->Driver.Fogfv(ctx, GL_FOG_COLOR, ctx->Fog.Color);
-   ctx->Driver.Fogfv(ctx, GL_FOG_MODE, 0);
-   ctx->Driver.Fogfv(ctx, GL_FOG_DENSITY, &ctx->Fog.Density);
-   ctx->Driver.Fogfv(ctx, GL_FOG_START, &ctx->Fog.Start);
-   ctx->Driver.Fogfv(ctx, GL_FOG_END, &ctx->Fog.End);
-
-   ctx->Driver.FrontFace(ctx, ctx->Polygon.FrontFace);
-
-   {
-      GLfloat f = (GLfloat) ctx->Light.Model.ColorControl;
-      ctx->Driver.LightModelfv(ctx, GL_LIGHT_MODEL_COLOR_CONTROL, &f);
-   }
-
-   ctx->Driver.LineWidth(ctx, ctx->Line.Width);
-   ctx->Driver.LogicOpcode(ctx, ctx->Color.LogicOp);
-   ctx->Driver.PointSize(ctx, ctx->Point.Size);
-   ctx->Driver.PolygonStipple(ctx, (const GLubyte *) ctx->PolygonStipple);
-   ctx->Driver.Scissor(ctx, ctx->Scissor.X, ctx->Scissor.Y,
-                       ctx->Scissor.Width, ctx->Scissor.Height);
-   ctx->Driver.ShadeModel(ctx, ctx->Light.ShadeModel);
-   ctx->Driver.StencilFuncSeparate(ctx, GL_FRONT,
-                                   ctx->Stencil.Function[0],
-                                   ctx->Stencil.Ref[0],
-                                   ctx->Stencil.ValueMask[0]);
-   ctx->Driver.StencilFuncSeparate(ctx, GL_BACK,
-                                   ctx->Stencil.Function[1],
-                                   ctx->Stencil.Ref[1],
-                                   ctx->Stencil.ValueMask[1]);
-   ctx->Driver.StencilMaskSeparate(ctx, GL_FRONT, ctx->Stencil.WriteMask[0]);
-   ctx->Driver.StencilMaskSeparate(ctx, GL_BACK, ctx->Stencil.WriteMask[1]);
-   ctx->Driver.StencilOpSeparate(ctx, GL_FRONT,
-                                 ctx->Stencil.FailFunc[0],
-                                 ctx->Stencil.ZFailFunc[0],
-                                 ctx->Stencil.ZPassFunc[0]);
-   ctx->Driver.StencilOpSeparate(ctx, GL_BACK,
-                                 ctx->Stencil.FailFunc[1],
-                                 ctx->Stencil.ZFailFunc[1],
-                                 ctx->Stencil.ZPassFunc[1]);
-
-
-   /* XXX this isn't really needed */
-   ctx->Driver.DrawBuffer(ctx, ctx->Color.DrawBuffer[0]);
-}
diff --git a/src/mesa/drivers/dri/i965/intel_context.h b/src/mesa/drivers/dri/i965/intel_context.h
index 808512f7fd..a3c65b66e0 100644
--- a/src/mesa/drivers/dri/i965/intel_context.h
+++ b/src/mesa/drivers/dri/i965/intel_context.h
@@ -399,7 +399,6 @@ extern GLboolean intelInitContext( struct intel_context *intel,
 
 extern void intelGetLock(struct intel_context *intel, GLuint flags);
 
-extern void intelInitState( GLcontext *ctx );
 extern void intelFinish( GLcontext *ctx );
 extern void intelFlush( GLcontext *ctx );
 
diff --git a/src/mesa/drivers/dri/i965/intel_state.c b/src/mesa/drivers/dri/i965/intel_state.c
index ec6e0465d4..2e442db619 100644
--- a/src/mesa/drivers/dri/i965/intel_state.c
+++ b/src/mesa/drivers/dri/i965/intel_state.c
@@ -197,99 +197,3 @@ void intelInitStateFuncs( struct dd_function_table *functions )
    functions->RenderMode = intelRenderMode;
    functions->ClearColor = intelClearColor;
 }
-
-
-
-
-void intelInitState( GLcontext *ctx )
-{
-   /* Mesa should do this for us:
-    */
-   ctx->Driver.AlphaFunc( ctx, 
-			  ctx->Color.AlphaFunc,
-			  ctx->Color.AlphaRef);
-
-   ctx->Driver.BlendColor( ctx,
-			   ctx->Color.BlendColor );
-
-   ctx->Driver.BlendEquationSeparate( ctx, 
-				      ctx->Color.BlendEquationRGB,
-				      ctx->Color.BlendEquationA);
-
-   ctx->Driver.BlendFuncSeparate( ctx,
-				  ctx->Color.BlendSrcRGB,
-				  ctx->Color.BlendDstRGB,
-				  ctx->Color.BlendSrcA,
-				  ctx->Color.BlendDstA);
-
-   ctx->Driver.ColorMask( ctx, 
-			  ctx->Color.ColorMask[RCOMP],
-			  ctx->Color.ColorMask[GCOMP],
-			  ctx->Color.ColorMask[BCOMP],
-			  ctx->Color.ColorMask[ACOMP]);
-
-   ctx->Driver.CullFace( ctx, ctx->Polygon.CullFaceMode );
-   ctx->Driver.DepthFunc( ctx, ctx->Depth.Func );
-   ctx->Driver.DepthMask( ctx, ctx->Depth.Mask );
-
-   ctx->Driver.Enable( ctx, GL_ALPHA_TEST, ctx->Color.AlphaEnabled );
-   ctx->Driver.Enable( ctx, GL_BLEND, ctx->Color.BlendEnabled );
-   ctx->Driver.Enable( ctx, GL_COLOR_LOGIC_OP, ctx->Color.ColorLogicOpEnabled );
-   ctx->Driver.Enable( ctx, GL_COLOR_SUM, ctx->Fog.ColorSumEnabled );
-   ctx->Driver.Enable( ctx, GL_CULL_FACE, ctx->Polygon.CullFlag );
-   ctx->Driver.Enable( ctx, GL_DEPTH_TEST, ctx->Depth.Test );
-   ctx->Driver.Enable( ctx, GL_DITHER, ctx->Color.DitherFlag );
-   ctx->Driver.Enable( ctx, GL_FOG, ctx->Fog.Enabled );
-   ctx->Driver.Enable( ctx, GL_LIGHTING, ctx->Light.Enabled );
-   ctx->Driver.Enable( ctx, GL_LINE_SMOOTH, ctx->Line.SmoothFlag );
-   ctx->Driver.Enable( ctx, GL_POLYGON_STIPPLE, ctx->Polygon.StippleFlag );
-   ctx->Driver.Enable( ctx, GL_SCISSOR_TEST, ctx->Scissor.Enabled );
-   ctx->Driver.Enable( ctx, GL_STENCIL_TEST, ctx->Stencil.Enabled );
-   ctx->Driver.Enable( ctx, GL_TEXTURE_1D, GL_FALSE );
-   ctx->Driver.Enable( ctx, GL_TEXTURE_2D, GL_FALSE );
-   ctx->Driver.Enable( ctx, GL_TEXTURE_RECTANGLE_NV, GL_FALSE );
-   ctx->Driver.Enable( ctx, GL_TEXTURE_3D, GL_FALSE );
-   ctx->Driver.Enable( ctx, GL_TEXTURE_CUBE_MAP, GL_FALSE );
-
-   ctx->Driver.Fogfv( ctx, GL_FOG_COLOR, ctx->Fog.Color );
-   ctx->Driver.Fogfv( ctx, GL_FOG_MODE, 0 );
-   ctx->Driver.Fogfv( ctx, GL_FOG_DENSITY, &ctx->Fog.Density );
-   ctx->Driver.Fogfv( ctx, GL_FOG_START, &ctx->Fog.Start );
-   ctx->Driver.Fogfv( ctx, GL_FOG_END, &ctx->Fog.End );
-
-   ctx->Driver.FrontFace( ctx, ctx->Polygon.FrontFace );
-
-   {
-      GLfloat f = (GLfloat)ctx->Light.Model.ColorControl;
-      ctx->Driver.LightModelfv( ctx, GL_LIGHT_MODEL_COLOR_CONTROL, &f );
-   }
-
-   ctx->Driver.LineWidth( ctx, ctx->Line.Width );
-   ctx->Driver.LogicOpcode( ctx, ctx->Color.LogicOp );
-   ctx->Driver.PointSize( ctx, ctx->Point.Size );
-   ctx->Driver.PolygonStipple( ctx, (const GLubyte *)ctx->PolygonStipple );
-   ctx->Driver.Scissor( ctx, ctx->Scissor.X, ctx->Scissor.Y,
-			ctx->Scissor.Width, ctx->Scissor.Height );
-   ctx->Driver.ShadeModel( ctx, ctx->Light.ShadeModel );
-   ctx->Driver.StencilFuncSeparate( ctx, GL_FRONT,
-                                    ctx->Stencil.Function[0],
-                                    ctx->Stencil.Ref[0],
-                                    ctx->Stencil.ValueMask[0] );
-   ctx->Driver.StencilFuncSeparate( ctx, GL_BACK,
-                                    ctx->Stencil.Function[1],
-                                    ctx->Stencil.Ref[1],
-                                    ctx->Stencil.ValueMask[1] );
-   ctx->Driver.StencilMaskSeparate( ctx, GL_FRONT, ctx->Stencil.WriteMask[0] );
-   ctx->Driver.StencilMaskSeparate( ctx, GL_BACK, ctx->Stencil.WriteMask[1] );
-   ctx->Driver.StencilOpSeparate( ctx, GL_FRONT,
-                                  ctx->Stencil.FailFunc[0],
-                                  ctx->Stencil.ZFailFunc[0],
-                                  ctx->Stencil.ZPassFunc[0]);
-   ctx->Driver.StencilOpSeparate( ctx, GL_BACK,
-                                  ctx->Stencil.FailFunc[1],
-                                  ctx->Stencil.ZFailFunc[1],
-                                  ctx->Stencil.ZPassFunc[1]);
-
-
-   ctx->Driver.DrawBuffer( ctx, ctx->Color.DrawBuffer[0] );
-}
-- 
cgit v1.2.3


From bb3558e6517209086cf8426bbe4743da50351158 Mon Sep 17 00:00:00 2001
From: Oliver McFadden <z3ro.geek@gmail.com>
Date: Mon, 21 May 2007 15:51:38 +0000
Subject: r300: Removed the R300_RS_INTERP_[0-9]_UNKNOWN (magic) defines.

Supposedly you need to set these values for the interpolaters to work, but they
seem to work fine without these values.
---
 src/mesa/drivers/dri/r300/r300_reg.h   |  6 ------
 src/mesa/drivers/dri/r300/r300_state.c | 14 +-------------
 2 files changed, 1 insertion(+), 19 deletions(-)

(limited to 'src/mesa/drivers')

diff --git a/src/mesa/drivers/dri/r300/r300_reg.h b/src/mesa/drivers/dri/r300/r300_reg.h
index 0a31f0b978..e64f5095bc 100644
--- a/src/mesa/drivers/dri/r300/r300_reg.h
+++ b/src/mesa/drivers/dri/r300/r300_reg.h
@@ -628,17 +628,11 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
  * Set INTERP_USED on all interpolators that produce data used by
  * the fragment program. INTERP_USED looks like a swizzling mask,
  * but I haven't seen it used that way.
- *
- * Note: The _UNKNOWN constants are always set in their respective
- * register. I don't know if this is necessary.
  */
 #define R300_RS_INTERP_0                    0x4310
 #define R300_RS_INTERP_1                    0x4314
-#       define R300_RS_INTERP_1_UNKNOWN          0x40
 #define R300_RS_INTERP_2                    0x4318
-#       define R300_RS_INTERP_2_UNKNOWN          0x80
 #define R300_RS_INTERP_3                    0x431C
-#       define R300_RS_INTERP_3_UNKNOWN          0xC0
 #define R300_RS_INTERP_4                    0x4320
 #define R300_RS_INTERP_5                    0x4324
 #define R300_RS_INTERP_6                    0x4328
diff --git a/src/mesa/drivers/dri/r300/r300_state.c b/src/mesa/drivers/dri/r300/r300_state.c
index e8d67f9aec..8a85478f73 100644
--- a/src/mesa/drivers/dri/r300/r300_state.c
+++ b/src/mesa/drivers/dri/r300/r300_state.c
@@ -1442,17 +1442,6 @@ union r300_outputs_written {
 static void r300SetupRSUnit(GLcontext * ctx)
 {
 	r300ContextPtr r300 = R300_CONTEXT(ctx);
-	/* I'm still unsure if these are needed */
-	GLuint interp_magic[8] = {
-		0x00,
-		R300_RS_INTERP_1_UNKNOWN,
-		R300_RS_INTERP_2_UNKNOWN,
-		R300_RS_INTERP_3_UNKNOWN,
-		0x00,
-		0x00,
-		0x00,
-		0x00
-	};
 	union r300_outputs_written OutputsWritten;
 	GLuint InputsRead;
 	int fp_reg, high_rr;
@@ -1498,8 +1487,7 @@ static void r300SetupRSUnit(GLcontext * ctx)
 	for (i = 0; i < ctx->Const.MaxTextureUnits; i++) {
 		r300->hw.ri.cmd[R300_RI_INTERP_0 + i] = 0
 		    | R300_RS_INTERP_USED
-		    | (in_texcoords << R300_RS_INTERP_SRC_SHIFT)
-		    | interp_magic[i];
+		    | (in_texcoords << R300_RS_INTERP_SRC_SHIFT);
 
 		r300->hw.rr.cmd[R300_RR_ROUTE_0 + fp_reg] = 0;
 		if (InputsRead & (FRAG_BIT_TEX0 << i)) {
-- 
cgit v1.2.3


From 9b9a1602f9822c3e29a3dc4f9ed025a4c337b007 Mon Sep 17 00:00:00 2001
From: Oliver McFadden <z3ro.geek@gmail.com>
Date: Wed, 23 May 2007 17:56:47 +0000
Subject: r300: Corrected the RGB888 texture format entry.

I think this is correct, assuming no endian issues. See commmit
59a08923f51d4ed83effbfcd91473c9ee86465f1.
---
 src/mesa/drivers/dri/r300/r300_texstate.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'src/mesa/drivers')

diff --git a/src/mesa/drivers/dri/r300/r300_texstate.c b/src/mesa/drivers/dri/r300/r300_texstate.c
index 8203189b7f..5505eae21c 100644
--- a/src/mesa/drivers/dri/r300/r300_texstate.c
+++ b/src/mesa/drivers/dri/r300/r300_texstate.c
@@ -76,7 +76,7 @@ static const struct tx_table {
 	_ASSIGN(RGBA8888_REV, R300_EASY_TX_FORMAT(Y, Z, W, X, W8Z8Y8X8)),
 	_ASSIGN(ARGB8888, R300_EASY_TX_FORMAT(W, Z, Y, X, W8Z8Y8X8)),
 	_ASSIGN(ARGB8888_REV, R300_EASY_TX_FORMAT(X, Y, Z, W, W8Z8Y8X8)),
-	_ASSIGN(RGB888, 0xffffffff),
+	_ASSIGN(RGB888, R300_EASY_TX_FORMAT(X, Y, Z, ONE, W8Z8Y8X8)),
 	_ASSIGN(RGB565, R300_EASY_TX_FORMAT(X, Y, Z, ONE, Z5Y6X5)),
 	_ASSIGN(RGB565_REV, R300_EASY_TX_FORMAT(X, Y, Z, ONE, Z5Y6X5)),
 	_ASSIGN(ARGB4444, R300_EASY_TX_FORMAT(X, Y, Z, W, W4Z4Y4X4)),
-- 
cgit v1.2.3


From ba8d3fb13651fd7c7b68c4a0394545b3760fa9c2 Mon Sep 17 00:00:00 2001
From: Oliver McFadden <z3ro.geek@gmail.com>
Date: Wed, 23 May 2007 18:37:55 +0000
Subject: r300: Use a single texture format table; reduces duplication.

---
 src/mesa/drivers/dri/r300/r300_texstate.c | 83 +++++++------------------------
 1 file changed, 19 insertions(+), 64 deletions(-)

(limited to 'src/mesa/drivers')

diff --git a/src/mesa/drivers/dri/r300/r300_texstate.c b/src/mesa/drivers/dri/r300/r300_texstate.c
index 5505eae21c..18837e1e06 100644
--- a/src/mesa/drivers/dri/r300/r300_texstate.c
+++ b/src/mesa/drivers/dri/r300/r300_texstate.c
@@ -54,7 +54,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #define VALID_FORMAT(f) ( ((f) <= MESA_FORMAT_RGBA_DXT5			\
 			   || ((f) >= MESA_FORMAT_RGBA_FLOAT32 &&	\
 			       (f) <= MESA_FORMAT_INTENSITY_FLOAT16))	\
-			  && tx_table_le[f].flag )
+			  && tx_table[f].flag )
 
 #define _ASSIGN(entry, format)				\
 	[ MESA_FORMAT_ ## entry ] = { format, 0, 1}
@@ -70,53 +70,19 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 static const struct tx_table {
 	GLuint format, filter, flag;
-} tx_table_be[] = {
-	/* *INDENT-OFF* */
-	_ASSIGN(RGBA8888, R300_EASY_TX_FORMAT(Z, Y, X, W, W8Z8Y8X8)),
-	_ASSIGN(RGBA8888_REV, R300_EASY_TX_FORMAT(Y, Z, W, X, W8Z8Y8X8)),
-	_ASSIGN(ARGB8888, R300_EASY_TX_FORMAT(W, Z, Y, X, W8Z8Y8X8)),
-	_ASSIGN(ARGB8888_REV, R300_EASY_TX_FORMAT(X, Y, Z, W, W8Z8Y8X8)),
-	_ASSIGN(RGB888, R300_EASY_TX_FORMAT(X, Y, Z, ONE, W8Z8Y8X8)),
-	_ASSIGN(RGB565, R300_EASY_TX_FORMAT(X, Y, Z, ONE, Z5Y6X5)),
-	_ASSIGN(RGB565_REV, R300_EASY_TX_FORMAT(X, Y, Z, ONE, Z5Y6X5)),
-	_ASSIGN(ARGB4444, R300_EASY_TX_FORMAT(X, Y, Z, W, W4Z4Y4X4)),
-	_ASSIGN(ARGB4444_REV, R300_EASY_TX_FORMAT(X, Y, Z, W, W4Z4Y4X4)),
-	_ASSIGN(ARGB1555, R300_EASY_TX_FORMAT(X, Y, Z, W, W1Z5Y5X5)),
-	_ASSIGN(ARGB1555_REV, R300_EASY_TX_FORMAT(X, Y, Z, W, W1Z5Y5X5)),
-	_ASSIGN(AL88, R300_EASY_TX_FORMAT(X, X, X, Y, Y8X8)),
-	_ASSIGN(AL88_REV, R300_EASY_TX_FORMAT(X, X, X, Y, Y8X8)),
-	_ASSIGN(RGB332, R300_EASY_TX_FORMAT(X, Y, Z, ONE, Z3Y3X2)),
-	_ASSIGN(A8, R300_EASY_TX_FORMAT(ZERO, ZERO, ZERO, X, X8)),
-	_ASSIGN(L8, R300_EASY_TX_FORMAT(X, X, X, ONE, X8)),
-	_ASSIGN(I8, R300_EASY_TX_FORMAT(X, X, X, X, X8)),
-	_ASSIGN(CI8, R300_EASY_TX_FORMAT(X, X, X, X, X8)),
-	_ASSIGN(YCBCR, R300_EASY_TX_FORMAT(X, Y, Z, ONE, G8R8_G8B8)|R300_TX_FORMAT_YUV_MODE ),
-	_ASSIGN(YCBCR_REV, R300_EASY_TX_FORMAT(X, Y, Z, ONE, G8R8_G8B8)|R300_TX_FORMAT_YUV_MODE),
-	_ASSIGN(RGB_DXT1, R300_EASY_TX_FORMAT(X, Y, Z, ONE, DXT1)),
-	_ASSIGN(RGBA_DXT1, R300_EASY_TX_FORMAT(X, Y, Z, W, DXT1)),
-	_ASSIGN(RGBA_DXT3, R300_EASY_TX_FORMAT(X, Y, Z, W, DXT3)),
-	_ASSIGN(RGBA_DXT5, R300_EASY_TX_FORMAT(Y, Z, W, X, DXT5)),
-	_ASSIGN(RGBA_FLOAT32, R300_EASY_TX_FORMAT(Z, Y, X, W, FL_R32G32B32A32)),
-	_ASSIGN(RGBA_FLOAT16, R300_EASY_TX_FORMAT(Z, Y, X, W, FL_R16G16B16A16)),
-	_ASSIGN(RGB_FLOAT32, 0xffffffff),
-	_ASSIGN(RGB_FLOAT16, 0xffffffff),
-	_ASSIGN(ALPHA_FLOAT32, R300_EASY_TX_FORMAT(ZERO, ZERO, ZERO, X, FL_I32)),
-	_ASSIGN(ALPHA_FLOAT16, R300_EASY_TX_FORMAT(ZERO, ZERO, ZERO, X, FL_I16)),
-	_ASSIGN(LUMINANCE_FLOAT32, R300_EASY_TX_FORMAT(X, X, X, ONE, FL_I32)),
-	_ASSIGN(LUMINANCE_FLOAT16, R300_EASY_TX_FORMAT(X, X, X, ONE, FL_I16)),
-	_ASSIGN(LUMINANCE_ALPHA_FLOAT32, R300_EASY_TX_FORMAT(X, X, X, Y, FL_I32A32)),
-	_ASSIGN(LUMINANCE_ALPHA_FLOAT16, R300_EASY_TX_FORMAT(X, X, X, Y, FL_I16A16)),
-	_ASSIGN(INTENSITY_FLOAT32, R300_EASY_TX_FORMAT(X, X, X, X, FL_I32)),
-	_ASSIGN(INTENSITY_FLOAT16, R300_EASY_TX_FORMAT(X, X, X, X, FL_I16)),
-	/* *INDENT-ON* */
-};
-
-static const struct tx_table tx_table_le[] = {
+} tx_table[] = {
 	/* *INDENT-OFF* */
+#ifdef MESA_LITTLE_ENDIAN
 	_ASSIGN(RGBA8888, R300_EASY_TX_FORMAT(Y, Z, W, X, W8Z8Y8X8)),
 	_ASSIGN(RGBA8888_REV, R300_EASY_TX_FORMAT(Z, Y, X, W, W8Z8Y8X8)),
 	_ASSIGN(ARGB8888, R300_EASY_TX_FORMAT(X, Y, Z, W, W8Z8Y8X8)),
 	_ASSIGN(ARGB8888_REV, R300_EASY_TX_FORMAT(W, Z, Y, X, W8Z8Y8X8)),
+#else
+	_ASSIGN(RGBA8888, R300_EASY_TX_FORMAT(Z, Y, X, W, W8Z8Y8X8)),
+	_ASSIGN(RGBA8888_REV, R300_EASY_TX_FORMAT(Y, Z, W, X, W8Z8Y8X8)),
+	_ASSIGN(ARGB8888, R300_EASY_TX_FORMAT(W, Z, Y, X, W8Z8Y8X8)),
+	_ASSIGN(ARGB8888_REV, R300_EASY_TX_FORMAT(X, Y, Z, W, W8Z8Y8X8)),
+#endif
 	_ASSIGN(RGB888, R300_EASY_TX_FORMAT(X, Y, Z, ONE, W8Z8Y8X8)),
 	_ASSIGN(RGB565, R300_EASY_TX_FORMAT(X, Y, Z, ONE, Z5Y6X5)),
 	_ASSIGN(RGB565_REV, R300_EASY_TX_FORMAT(X, Y, Z, ONE, Z5Y6X5)),
@@ -178,22 +144,10 @@ static void r300SetTexImages(r300ContextPtr rmesa,
 
 	/* Set the hardware texture format
 	 */
-	if (!t->image_override && VALID_FORMAT(baseImage->TexFormat->MesaFormat)) {
-		if (_mesa_little_endian()) {
-			t->format =
-			    tx_table_le[baseImage->TexFormat->MesaFormat].
-			    format;
-			t->filter |=
-			    tx_table_le[baseImage->TexFormat->MesaFormat].
-			    filter;
-		} else {
-			t->format =
-			    tx_table_be[baseImage->TexFormat->MesaFormat].
-			    format;
-			t->filter |=
-			    tx_table_be[baseImage->TexFormat->MesaFormat].
-			    filter;
-		}
+	if (!t->image_override
+	    && VALID_FORMAT(baseImage->TexFormat->MesaFormat)) {
+		t->format = tx_table[baseImage->TexFormat->MesaFormat].format;
+		t->filter |= tx_table[baseImage->TexFormat->MesaFormat].filter;
 	} else if (!t->image_override) {
 		_mesa_problem(NULL, "unexpected texture format in %s",
 			      __FUNCTION__);
@@ -538,13 +492,14 @@ static GLboolean r300UpdateTexture(GLcontext * ctx, int unit)
 	return !t->border_fallback;
 }
 
-void r300SetTexOffset(__DRIcontext *pDRICtx, GLint texname,
+void r300SetTexOffset(__DRIcontext * pDRICtx, GLint texname,
 		      unsigned long long offset, GLint depth, GLuint pitch)
 {
 	r300ContextPtr rmesa =
-		(r300ContextPtr)((__DRIcontextPrivate*)pDRICtx->private)->driverPrivate;
+	    (r300ContextPtr) ((__DRIcontextPrivate *) pDRICtx->private)->
+	    driverPrivate;
 	struct gl_texture_object *tObj =
-		_mesa_lookup_texture(rmesa->radeon.glCtx, texname);
+	    _mesa_lookup_texture(rmesa->radeon.glCtx, texname);
 	r300TexObjPtr t;
 	int idx;
 
@@ -579,8 +534,8 @@ void r300SetTexOffset(__DRIcontext *pDRICtx, GLint texname,
 
 	t->pitch_reg--;
 
-	t->format = tx_table_le[idx].format;
-	t->filter |= tx_table_le[idx].filter;
+	t->format = tx_table[idx].format;
+	t->filter |= tx_table[idx].filter;
 }
 
 static GLboolean r300UpdateTextureUnit(GLcontext * ctx, int unit)
-- 
cgit v1.2.3


From f1441bbd180452e4eeab27545d6b9f48c0c54d11 Mon Sep 17 00:00:00 2001
From: Oliver McFadden <z3ro.geek@gmail.com>
Date: Wed, 23 May 2007 18:48:05 +0000
Subject: r300: Minor indenting corrections in the texture format table.

---
 src/mesa/drivers/dri/r300/r300_texstate.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

(limited to 'src/mesa/drivers')

diff --git a/src/mesa/drivers/dri/r300/r300_texstate.c b/src/mesa/drivers/dri/r300/r300_texstate.c
index 18837e1e06..eeaba584df 100644
--- a/src/mesa/drivers/dri/r300/r300_texstate.c
+++ b/src/mesa/drivers/dri/r300/r300_texstate.c
@@ -97,8 +97,8 @@ static const struct tx_table {
 	_ASSIGN(L8, R300_EASY_TX_FORMAT(X, X, X, ONE, X8)),
 	_ASSIGN(I8, R300_EASY_TX_FORMAT(X, X, X, X, X8)),
 	_ASSIGN(CI8, R300_EASY_TX_FORMAT(X, X, X, X, X8)),
-	_ASSIGN(YCBCR, R300_EASY_TX_FORMAT(X, Y, Z, ONE, G8R8_G8B8)|R300_TX_FORMAT_YUV_MODE ),
-	_ASSIGN(YCBCR_REV, R300_EASY_TX_FORMAT(X, Y, Z, ONE, G8R8_G8B8)|R300_TX_FORMAT_YUV_MODE),
+	_ASSIGN(YCBCR, R300_EASY_TX_FORMAT(X, Y, Z, ONE, G8R8_G8B8) | R300_TX_FORMAT_YUV_MODE),
+	_ASSIGN(YCBCR_REV, R300_EASY_TX_FORMAT(X, Y, Z, ONE, G8R8_G8B8) | R300_TX_FORMAT_YUV_MODE),
 	_ASSIGN(RGB_DXT1, R300_EASY_TX_FORMAT(X, Y, Z, ONE, DXT1)),
 	_ASSIGN(RGBA_DXT1, R300_EASY_TX_FORMAT(X, Y, Z, W, DXT1)),
 	_ASSIGN(RGBA_DXT3, R300_EASY_TX_FORMAT(X, Y, Z, W, DXT3)),
-- 
cgit v1.2.3


From 491618b33dcb388f5d2335862cba8cf110d72ae7 Mon Sep 17 00:00:00 2001
From: Oliver McFadden <z3ro.geek@gmail.com>
Date: Wed, 23 May 2007 21:12:11 +0000
Subject: r300: Use switch statements in r300ResetHwState, etc.

---
 src/mesa/drivers/dri/r300/r300_state.c | 71 ++++++++++++++++++----------------
 1 file changed, 38 insertions(+), 33 deletions(-)

(limited to 'src/mesa/drivers')

diff --git a/src/mesa/drivers/dri/r300/r300_state.c b/src/mesa/drivers/dri/r300/r300_state.c
index 8a85478f73..b3a6ce4c76 100644
--- a/src/mesa/drivers/dri/r300/r300_state.c
+++ b/src/mesa/drivers/dri/r300/r300_state.c
@@ -1813,12 +1813,6 @@ static void r300ResetHwState(r300ContextPtr r300)
 	if (RADEON_DEBUG & DEBUG_STATE)
 		fprintf(stderr, "%s\n", __FUNCTION__);
 
-	/* This is a place to initialize registers which
-	   have bitfields accessed by different functions
-	   and not all bits are used */
-
-	/* go and compute register values from GL state */
-
 	r300UpdateWindow(ctx);
 
 	r300ColorMask(ctx,
@@ -1848,13 +1842,11 @@ static void r300ResetHwState(r300ContextPtr r300)
 	r300AlphaFunc(ctx, ctx->Color.AlphaFunc, ctx->Color.AlphaRef);
 	r300Enable(ctx, GL_ALPHA_TEST, ctx->Color.AlphaEnabled);
 
-	/* Initialize magic registers
-	   TODO : learn what they really do, or get rid of
-	   those we don't have to touch */
 	if (!has_tcl)
 		r300->hw.vap_cntl.cmd[1] = 0x0014045a;
 	else
 		r300->hw.vap_cntl.cmd[1] = 0x0030045A;	//0x0030065a /* Dangerous */
+
 	r300->hw.vte.cmd[1] = R300_VPORT_X_SCALE_ENA
 	    | R300_VPORT_X_OFFSET_ENA
 	    | R300_VPORT_Y_SCALE_ENA
@@ -1883,11 +1875,15 @@ static void r300ResetHwState(r300ContextPtr r300)
 	r300->hw.unk2220.cmd[3] = r300PackFloat32(1.0);
 	r300->hw.unk2220.cmd[4] = r300PackFloat32(1.0);
 
-	/* what about other chips than r300 or rv350??? */
-	if (r300->radeon.radeonScreen->chip_family == CHIP_FAMILY_R300)
+	/* XXX: Other families? */
+	switch (r300->radeon.radeonScreen->chip_family) {
+	case CHIP_FAMILY_R300:
 		r300->hw.unk2288.cmd[1] = R300_2288_R300;
-	else
+		break;
+	default:
 		r300->hw.unk2288.cmd[1] = R300_2288_RV350;
+		break;
+	}
 
 	r300->hw.gb_enable.cmd[1] = R300_GB_POINT_STUFF_ENABLE
 	    | R300_GB_LINE_STUFF_ENABLE
@@ -1895,26 +1891,35 @@ static void r300ResetHwState(r300ContextPtr r300)
 
 	r300->hw.gb_misc.cmd[R300_GB_MISC_MSPOS_0] = 0x66666666;
 	r300->hw.gb_misc.cmd[R300_GB_MISC_MSPOS_1] = 0x06666666;
-	if ((r300->radeon.radeonScreen->chip_family == CHIP_FAMILY_R300) ||
-	    (r300->radeon.radeonScreen->chip_family == CHIP_FAMILY_R350))
-		r300->hw.gb_misc.cmd[R300_GB_MISC_TILE_CONFIG] =
-		    R300_GB_TILE_ENABLE | R300_GB_TILE_PIPE_COUNT_R300 |
-		    R300_GB_TILE_SIZE_16;
-	else if (r300->radeon.radeonScreen->chip_family == CHIP_FAMILY_RV410)
-		r300->hw.gb_misc.cmd[R300_GB_MISC_TILE_CONFIG] =
-		    R300_GB_TILE_ENABLE | R300_GB_TILE_PIPE_COUNT_RV410 |
-		    R300_GB_TILE_SIZE_16;
-	else if (r300->radeon.radeonScreen->chip_family == CHIP_FAMILY_R420)
-		r300->hw.gb_misc.cmd[R300_GB_MISC_TILE_CONFIG] =
-		    R300_GB_TILE_ENABLE | R300_GB_TILE_PIPE_COUNT_R420 |
-		    R300_GB_TILE_SIZE_16;
-	else
-		r300->hw.gb_misc.cmd[R300_GB_MISC_TILE_CONFIG] =
-		    R300_GB_TILE_ENABLE | R300_GB_TILE_PIPE_COUNT_RV300 |
-		    R300_GB_TILE_SIZE_16;
-	/* set to 0 when fog is disabled? */
+
+	/* XXX: Other families? */
+	r300->hw.gb_misc.cmd[R300_GB_MISC_TILE_CONFIG] =
+	    R300_GB_TILE_ENABLE | R300_GB_TILE_SIZE_16;
+	switch (r300->radeon.radeonScreen->chip_family) {
+	case CHIP_FAMILY_R300:
+	case CHIP_FAMILY_R350:
+		r300->hw.gb_misc.cmd[R300_GB_MISC_TILE_CONFIG] |=
+		    R300_GB_TILE_PIPE_COUNT_R300;
+		break;
+	case CHIP_FAMILY_RV410:
+		r300->hw.gb_misc.cmd[R300_GB_MISC_TILE_CONFIG] |=
+		    R300_GB_TILE_PIPE_COUNT_RV410;
+		break;
+	case CHIP_FAMILY_R420:
+		r300->hw.gb_misc.cmd[R300_GB_MISC_TILE_CONFIG] |=
+		    R300_GB_TILE_PIPE_COUNT_R420;
+		break;
+	default:
+		r300->hw.gb_misc.cmd[R300_GB_MISC_TILE_CONFIG] |=
+		    R300_GB_TILE_PIPE_COUNT_RV300;
+		break;
+	}
+
+	/* XXX: set to 0 when fog is disabled? */
 	r300->hw.gb_misc.cmd[R300_GB_MISC_SELECT] = R300_GB_FOG_SELECT_1_1_W;
-	r300->hw.gb_misc.cmd[R300_GB_MISC_AA_CONFIG] = R300_AA_DISABLE;	/* No antialiasing */
+
+	/* XXX: Enable anti-aliasing? */
+	r300->hw.gb_misc.cmd[R300_GB_MISC_AA_CONFIG] = R300_AA_DISABLE;
 
 	r300->hw.unk4200.cmd[1] = r300PackFloat32(0.0);
 	r300->hw.unk4200.cmd[2] = r300PackFloat32(0.0);
@@ -2035,7 +2040,7 @@ static void r300ResetHwState(r300ContextPtr r300)
 	r300->hw.zb.cmd[R300_ZB_PITCH] = r300->radeon.radeonScreen->depthPitch;
 
 	if (r300->radeon.sarea->tiling_enabled) {
-		/* Turn off when clearing buffers ? */
+		/* XXX: Turn off when clearing buffers ? */
 		r300->hw.zb.cmd[R300_ZB_PITCH] |= R300_DEPTH_TILE_ENABLE;
 
 		if (ctx->Visual.depthBits == 24)
@@ -2058,7 +2063,7 @@ static void r300ResetHwState(r300ContextPtr r300)
 		r300->hw.vps.cmd[R300_VPS_POINTSIZE] = r300PackFloat32(1.0);
 		r300->hw.vps.cmd[R300_VPS_ZERO_3] = 0;
 	}
-//END: TODO
+
 	r300->hw.all_dirty = GL_TRUE;
 }
 
-- 
cgit v1.2.3


From f2e99e6a581490b3dd412eb587f31bce43fc8c25 Mon Sep 17 00:00:00 2001
From: Oliver McFadden <z3ro.geek@gmail.com>
Date: Wed, 23 May 2007 21:26:35 +0000
Subject: r300: Call the r300Fogfv function directly within r300_state.c.

This required moving the r300Enable function but there are no actual changes.
---
 src/mesa/drivers/dri/r300/r300_state.c | 200 ++++++++++++++++-----------------
 1 file changed, 99 insertions(+), 101 deletions(-)

(limited to 'src/mesa/drivers')

diff --git a/src/mesa/drivers/dri/r300/r300_state.c b/src/mesa/drivers/dri/r300/r300_state.c
index b3a6ce4c76..b235baaf10 100644
--- a/src/mesa/drivers/dri/r300/r300_state.c
+++ b/src/mesa/drivers/dri/r300/r300_state.c
@@ -65,6 +65,9 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 #include "drirenderbuffer.h"
 
+extern int future_hw_tcl_on;
+extern void _tnl_UpdateFixedFunctionProgram(GLcontext * ctx);
+
 static void r300BlendColor(GLcontext * ctx, const GLfloat cf[4])
 {
 	GLubyte color[4];
@@ -462,97 +465,6 @@ static void r300SetDepthState(GLcontext * ctx)
 	r300SetEarlyZState(ctx);
 }
 
-/**
- * Handle glEnable()/glDisable().
- *
- * \note Mesa already filters redundant calls to glEnable/glDisable.
- */
-static void r300Enable(GLcontext * ctx, GLenum cap, GLboolean state)
-{
-	r300ContextPtr r300 = R300_CONTEXT(ctx);
-
-	if (RADEON_DEBUG & DEBUG_STATE)
-		fprintf(stderr, "%s( %s = %s )\n", __FUNCTION__,
-			_mesa_lookup_enum_by_nr(cap),
-			state ? "GL_TRUE" : "GL_FALSE");
-
-	switch (cap) {
-		/* Fast track this one...
-		 */
-	case GL_TEXTURE_1D:
-	case GL_TEXTURE_2D:
-	case GL_TEXTURE_3D:
-		break;
-
-	case GL_FOG:
-		R300_STATECHANGE(r300, fogs);
-		if (state) {
-			r300->hw.fogs.cmd[R300_FOGS_STATE] |= R300_FOG_ENABLE;
-
-			ctx->Driver.Fogfv(ctx, GL_FOG_MODE, NULL);
-			ctx->Driver.Fogfv(ctx, GL_FOG_DENSITY,
-					  &ctx->Fog.Density);
-			ctx->Driver.Fogfv(ctx, GL_FOG_START, &ctx->Fog.Start);
-			ctx->Driver.Fogfv(ctx, GL_FOG_END, &ctx->Fog.End);
-			ctx->Driver.Fogfv(ctx, GL_FOG_COLOR, ctx->Fog.Color);
-		} else {
-			r300->hw.fogs.cmd[R300_FOGS_STATE] &= ~R300_FOG_ENABLE;
-		}
-
-		break;
-
-	case GL_ALPHA_TEST:
-		r300SetAlphaState(ctx);
-		break;
-
-	case GL_BLEND:
-	case GL_COLOR_LOGIC_OP:
-		r300SetBlendState(ctx);
-		break;
-
-	case GL_DEPTH_TEST:
-		r300SetDepthState(ctx);
-		break;
-
-	case GL_STENCIL_TEST:
-		if (r300->state.stencil.hw_stencil) {
-			R300_STATECHANGE(r300, zs);
-			if (state) {
-				r300->hw.zs.cmd[R300_ZS_CNTL_0] |=
-				    R300_RB3D_STENCIL_ENABLE;
-			} else {
-				r300->hw.zs.cmd[R300_ZS_CNTL_0] &=
-				    ~R300_RB3D_STENCIL_ENABLE;
-			}
-		} else {
-#if R200_MERGED
-			FALLBACK(&r300->radeon, RADEON_FALLBACK_STENCIL, state);
-#endif
-		}
-		break;
-
-	case GL_CULL_FACE:
-		r300UpdateCulling(ctx);
-		break;
-
-	case GL_POLYGON_OFFSET_POINT:
-	case GL_POLYGON_OFFSET_LINE:
-		break;
-
-	case GL_POLYGON_OFFSET_FILL:
-		R300_STATECHANGE(r300, occlusion_cntl);
-		if (state) {
-			r300->hw.occlusion_cntl.cmd[1] |= (3 << 0);
-		} else {
-			r300->hw.occlusion_cntl.cmd[1] &= ~(3 << 0);
-		}
-		break;
-	default:
-		radeonEnable(ctx, cap, state);
-		return;
-	}
-}
-
 static void r300UpdatePolygonMode(GLcontext * ctx)
 {
 	r300ContextPtr r300 = R300_CONTEXT(ctx);
@@ -1799,6 +1711,96 @@ static void r300SetupVertexShader(r300ContextPtr rmesa)
 #endif
 }
 
+/**
+ * Enable/Disable states.
+ *
+ * \note Mesa already filters redundant calls to this function.
+ */
+static void r300Enable(GLcontext * ctx, GLenum cap, GLboolean state)
+{
+	r300ContextPtr r300 = R300_CONTEXT(ctx);
+
+	if (RADEON_DEBUG & DEBUG_STATE)
+		fprintf(stderr, "%s( %s = %s )\n", __FUNCTION__,
+			_mesa_lookup_enum_by_nr(cap),
+			state ? "GL_TRUE" : "GL_FALSE");
+
+	switch (cap) {
+		/* Fast track this one...
+		 */
+	case GL_TEXTURE_1D:
+	case GL_TEXTURE_2D:
+	case GL_TEXTURE_3D:
+		break;
+
+	case GL_FOG:
+		R300_STATECHANGE(r300, fogs);
+		if (state) {
+			r300->hw.fogs.cmd[R300_FOGS_STATE] |= R300_FOG_ENABLE;
+
+			r300Fogfv(ctx, GL_FOG_MODE, NULL);
+			r300Fogfv(ctx, GL_FOG_DENSITY, &ctx->Fog.Density);
+			r300Fogfv(ctx, GL_FOG_START, &ctx->Fog.Start);
+			r300Fogfv(ctx, GL_FOG_END, &ctx->Fog.End);
+			r300Fogfv(ctx, GL_FOG_COLOR, ctx->Fog.Color);
+		} else {
+			r300->hw.fogs.cmd[R300_FOGS_STATE] &= ~R300_FOG_ENABLE;
+		}
+
+		break;
+
+	case GL_ALPHA_TEST:
+		r300SetAlphaState(ctx);
+		break;
+
+	case GL_BLEND:
+	case GL_COLOR_LOGIC_OP:
+		r300SetBlendState(ctx);
+		break;
+
+	case GL_DEPTH_TEST:
+		r300SetDepthState(ctx);
+		break;
+
+	case GL_STENCIL_TEST:
+		if (r300->state.stencil.hw_stencil) {
+			R300_STATECHANGE(r300, zs);
+			if (state) {
+				r300->hw.zs.cmd[R300_ZS_CNTL_0] |=
+				    R300_RB3D_STENCIL_ENABLE;
+			} else {
+				r300->hw.zs.cmd[R300_ZS_CNTL_0] &=
+				    ~R300_RB3D_STENCIL_ENABLE;
+			}
+		} else {
+#if R200_MERGED
+			FALLBACK(&r300->radeon, RADEON_FALLBACK_STENCIL, state);
+#endif
+		}
+		break;
+
+	case GL_CULL_FACE:
+		r300UpdateCulling(ctx);
+		break;
+
+	case GL_POLYGON_OFFSET_POINT:
+	case GL_POLYGON_OFFSET_LINE:
+		break;
+
+	case GL_POLYGON_OFFSET_FILL:
+		R300_STATECHANGE(r300, occlusion_cntl);
+		if (state) {
+			r300->hw.occlusion_cntl.cmd[1] |= (3 << 0);
+		} else {
+			r300->hw.occlusion_cntl.cmd[1] &= ~(3 << 0);
+		}
+		break;
+	default:
+		radeonEnable(ctx, cap, state);
+		return;
+	}
+}
+
 /**
  * Completely recalculates hardware state based on the Mesa state.
  */
@@ -1970,12 +1972,12 @@ static void r300ResetHwState(r300ContextPtr r300)
 	r300->hw.unk46A4.cmd[5] = 0x00000001;
 
 	r300Enable(ctx, GL_FOG, ctx->Fog.Enabled);
-	ctx->Driver.Fogfv(ctx, GL_FOG_MODE, NULL);
-	ctx->Driver.Fogfv(ctx, GL_FOG_DENSITY, &ctx->Fog.Density);
-	ctx->Driver.Fogfv(ctx, GL_FOG_START, &ctx->Fog.Start);
-	ctx->Driver.Fogfv(ctx, GL_FOG_END, &ctx->Fog.End);
-	ctx->Driver.Fogfv(ctx, GL_FOG_COLOR, ctx->Fog.Color);
-	ctx->Driver.Fogfv(ctx, GL_FOG_COORDINATE_SOURCE_EXT, NULL);
+	r300Fogfv(ctx, GL_FOG_MODE, NULL);
+	r300Fogfv(ctx, GL_FOG_DENSITY, &ctx->Fog.Density);
+	r300Fogfv(ctx, GL_FOG_START, &ctx->Fog.Start);
+	r300Fogfv(ctx, GL_FOG_END, &ctx->Fog.End);
+	r300Fogfv(ctx, GL_FOG_COLOR, ctx->Fog.Color);
+	r300Fogfv(ctx, GL_FOG_COORDINATE_SOURCE_EXT, NULL);
 
 	r300->hw.at.cmd[R300_AT_UNKNOWN] = 0;
 	r300->hw.unk4BD8.cmd[1] = 0;
@@ -2067,10 +2069,6 @@ static void r300ResetHwState(r300ContextPtr r300)
 	r300->hw.all_dirty = GL_TRUE;
 }
 
-
-extern void _tnl_UpdateFixedFunctionProgram(GLcontext * ctx);
-
-extern int future_hw_tcl_on;
 void r300UpdateShaders(r300ContextPtr rmesa)
 {
 	GLcontext *ctx;
-- 
cgit v1.2.3