pingou / rpms / mesa

Forked from rpms/mesa 6 years ago
Clone
Blob Blame History Raw
Adam Jackson (1):
      Unbreak Linux builds with -fvisibility=hidden.

Andreas Micheler (1):
      faster write_rgba_span_front()

Brian (69):
      added md5 sums
      fix even-sized point positioning (bug 11874)
      Merge branch 'mesa_7_0_branch' of git+ssh://brianp@git.freedesktop.org/git/mesa/mesa into mesa_7_0_branch
      fix bug 9962 (vbo splitting) as in trunk
      initial 7.0.2 notes
      fix swizzle error test (bug 11881)
      fix potential NULL dereference (bug 11880)
      remove SHELL line, replace -e test with new logic (Daniel Stone)
      fix potential NULL dereference (bug 11879)
      move free() after dereference (bug 11878)
      fix byte swap bug for GLuint stencil indexes (bug 11909)
      fix link to 7.0.1 relnotes
      Implement mutex/locking around texture object reference counting.
      free any render/framebuffers left in hash tables when freeing shared state
      Add PCI IDs for the G33, Q33, and Q35 chipsets.
      added more i915/945 chipsets
      fix blending/banding bug
      Fix a few more problems with freeing FBOs/textures during context destruction.
      added some temporary texobj ref counting debug output
      more tex obj ref count debugging (temporary)
      Added _mesa_free_attrib_data() to free anything left in the attribute stack upon context destruction.
      copy Target in _mesa_copy_texture_object()
      Rewrite quite a bit of the code for glPush/PopAttrib() for texture state.
      more debug output (context destroy, fb destroy)
      log deleting/binding of FBOs
      Remove recent texobj refcount debug/logging code.
      don't map buffer in _mesa_validate_DrawElements() unless needed
      refactor bounds checking code
      remove unneeded CallStack array
      remove CallDepth++/-- accidentally removed in prev commit
      new __gluInvertMatrix() function (Mesa bug 6748)
      Fixed bugs 6748, 12141
      s/movaps/movups/ (see bug 12216)
      fix i965 bugs, x86-64 bugs
      sync with trunk, fixing bug 12239
      Use temporary matrix in __gluInvertMatrixd() to fix aliasing problem (see bugs 12269, 6748)
      updated VC7 project files
      clean-up (see bug 12317)
      fix comment
      Update depth test state when binding new framebuffer object
      In _mesa_make_current(), don't unbind FBOs from the old context.
      fix indirect rendering crash
      updated with pkg-config info
      added DSTDIR, pkg-config items
      added .pc.in files to tarballs
      Fix state.texgen parsing error (bug 12313).
      added program_error2() function for better error reporting
      fix ARB fp/vp parsing bug 12313
      fix copypixels overlap test bug (#12417)
      fix glCopyPixel/glPixelZoom bug 12417)
      updated link
      From trunk: mesa: bind VBO_ATTRIB_XXX to correct input array when executing a display list. fix #10604
      fix bug 10604
      Added bluegene-xlc-osmesa config (Alexander Neundorf)
      fixes for bluegene-xlc-osmesa config
      added bluegene-xlc-osmesa, fortran fixes
      fix for __IBMC__
      fix -D_BSD_SOURC
      fix DrawRangeElements error msg
      Restore old _TriangleCaps code to fix Blender problem (bug 12164)
      fix blend bug 12164
      bump versions to 7.0.2
      for Miniglx, use git sources
      prep for 7.0.2 release
      update the DRM/DRI instructions
      fix VBO-split infinite loop (bug 12164)
      updated glext.h license info (Khronos), plus other clean-ups
      replace 'brick' with correct program name in printfs
      fix fog, rescale_normals bugs (from gallium branch)

Christoph Kubisch (1):
      updated VC7 project files

Colin McDonald (1):
      fixed problem with big glDrawArrays (see bug 12141)

Dan Nicholson (4):
      DESTDIR support.
      pkg-config support
      add support for LDFLAGS env var
      Ignore more generated files in progs/

Dan Torop (1):
      fix spantmp2 READ_RGBA inline asm (#11931)

Dave Airlie (1):
      i965: fix vblank on 965gm laptops by bringing in code from i915

Michel Dänzer (3):
      i915tex: Make sure pitch is aligned properly for render-to-texture.
      i915tex: Unreference texture buffers on context destruction.
      i915tex: Work around texture pitch related performance drops on i915 at least.

Mrc Gran (1):
      fix force_s3tc_enable option

Roland Bär (1):
      [i965] Bug #11812: Fix fwrite return value checks in AUB file code.

Roland Scheidegger (6):
      suppress warning about ncon visuals (bug #6689)
      fix another occurence of movaps which might not be aligned
      unbreak 3d textures (typo when setting tex layout)
      make sure optimized fog params get updated
      fog: fix issues with negative fog coords (may fix #10529)
      minor fog calc cleanup

Wang Zhenyu (1):
      i915tex: Add support for 945GME

Xiang, Haihao (14):
      i965: flush batch buffer when getting the maximum. This makes
      i965: samplers group in fours in WM_STATE. fix bug#9415
      i965: check NULL pointer. fix bug#12193
      i965: store read drawable info in intel_context. Some OpenGL
      i965: Take the upper limitation on LOD into account.
      fix bug#11009
      i965: limit on LOD Bias, fix#11987
      i965: take the secondary color into account when drawing
      i965: fix #11378
      i965: fix bug#11925
      i965: The cube map texture coordinates must be devided by the
      i965: handle all unfilled mode in clip stage. fix bug #12453
      mesa: make sure the gotten value isn't greater than the
      Brian's fix for bug9829

Zou Nan hai (2):
      fix a bug in 965 ARB_occlusion_query,
      fix fd.o bug #12217, recalcuate urb when clip plane size change

diff --git a/Makefile b/Makefile
index 3cab262..e05e0e6 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,5 @@
 # Top-level Mesa makefile
 
-SHELL = /bin/bash
-
 TOP = .
 
 SUBDIRS = src progs
@@ -70,6 +68,7 @@ aix-gcc \
 aix-static \
 beos \
 bluegene-osmesa \
+bluegene-xlc-osmesa \
 darwin \
 darwin-static \
 darwin-static-x86ppc \
@@ -156,7 +155,7 @@ sunos5-v9 \
 sunos5-v9-static \
 sunos5-v9-cc-g++ \
 ultrix-gcc:
-	@ if [ -e configs/current ] ; then \
+	@ if test -f configs/current || test -L configs/current ; then \
 		echo "Please run 'make realclean' before changing configs" ; \
 		exit 1 ; \
 	fi
@@ -166,10 +165,10 @@ ultrix-gcc:
 
 # Rules for making release tarballs
 
-DIRECTORY = Mesa-7.0.1
-LIB_NAME = MesaLib-7.0.1
-DEMO_NAME = MesaDemos-7.0.1
-GLUT_NAME = MesaGLUT-7.0.1
+DIRECTORY = Mesa-7.0.2-rc1
+LIB_NAME = MesaLib-7.0.2-rc1
+DEMO_NAME = MesaDemos-7.0.2-rc1
+GLUT_NAME = MesaGLUT-7.0.2-rc1
 
 MAIN_FILES = \
 	$(DIRECTORY)/Makefile*						\
@@ -213,6 +212,7 @@ MAIN_FILES = \
 	$(DIRECTORY)/src/mesa/Makefile*					\
 	$(DIRECTORY)/src/mesa/sources					\
 	$(DIRECTORY)/src/mesa/descrip.mms				\
+	$(DIRECTORY)/src/mesa/gl.pc.in					\
 	$(DIRECTORY)/src/mesa/depend					\
 	$(DIRECTORY)/src/mesa/main/*.[chS]				\
 	$(DIRECTORY)/src/mesa/main/descrip.mms				\
@@ -320,6 +320,7 @@ DRI_FILES = \
 SGI_GLU_FILES = \
 	$(DIRECTORY)/src/glu/Makefile					\
 	$(DIRECTORY)/src/glu/descrip.mms				\
+	$(DIRECTORY)/src/glu/glu.pc.in					\
 	$(DIRECTORY)/src/glu/sgi/Makefile				\
 	$(DIRECTORY)/src/glu/sgi/Makefile.mgw				\
 	$(DIRECTORY)/src/glu/sgi/Makefile.win				\
@@ -396,6 +397,7 @@ GLUT_FILES = \
 	$(DIRECTORY)/include/GL/glutf90.h		\
 	$(DIRECTORY)/src/glut/glx/Makefile*		\
 	$(DIRECTORY)/src/glut/glx/depend		\
+	$(DIRECTORY)/src/glut/glx/glut.pc.in		\
 	$(DIRECTORY)/src/glut/glx/*def			\
 	$(DIRECTORY)/src/glut/glx/descrip.mms		\
 	$(DIRECTORY)/src/glut/glx/mms_depend		\
@@ -418,6 +420,7 @@ DEPEND_FILES = \
 	$(TOP)/src/mesa/depend		\
 	$(TOP)/src/glx/x11/depend	\
 	$(TOP)/src/glw/depend		\
+	$(TOP)/src/glw/glw.pc.in	\
 	$(TOP)/src/glut/glx/depend	\
 	$(TOP)/src/glu/sgi/depend
 
diff --git a/bin/mklib b/bin/mklib
index 8334595..499e789 100755
--- a/bin/mklib
+++ b/bin/mklib
@@ -34,6 +34,7 @@ MINOR=0
 PATCH=""
 DEPS=""
 LINK=""
+LDFLAGS=""
 CPLUSPLUS=0
 STATIC=0
 DLOPEN=0
@@ -63,6 +64,7 @@ do
 	    echo '  -LDIR         search in DIR for library dependencies'
 	    echo '  -linker L     explicity specify the linker program to use (eg: gcc, g++)'
 	    echo '                Not observed on all systems at this time.'
+	    echo '  -ldflags OPT  specify any additional linker flags in OPT'
 	    echo '  -cplusplus    link with C++ runtime'
 	    echo '  -static       make a static library (default is dynamic/shared)'
 	    echo '  -dlopen       make a shared library suitable for dynamic loading'
@@ -94,6 +96,10 @@ do
 	    shift 1;
 	    LINK=$1
 	    ;;
+	'-ldflags')
+	    shift 1;
+	    LDFLAGS=$1
+	    ;;
 	-l*)
 	    DEPS="$DEPS $1"
 	    ;;
@@ -216,7 +222,7 @@ case $ARCH in
 
             rm -f ${LIBNAME}
             # make lib
-            ${LINK} ${OPTS} -o ${LIBNAME} ${OBJECTS} ${DEPS}
+            ${LINK} ${OPTS} ${LDFLAGS} -o ${LIBNAME} ${OBJECTS} ${DEPS}
             # finish up
             FINAL_LIBS="${LIBNAME}"
         elif [ $STATIC = 1 ] ; then
@@ -274,7 +280,7 @@ case $ARCH in
             rm -f ${LIBNAME}.so
 
             # make lib
-            ${LINK} ${OPTS} -o ${LIBNAME}.so.${VERSION} ${OBJECTS} ${DEPS}
+            ${LINK} ${OPTS} ${LDFLAGS} -o ${LIBNAME}.so.${VERSION} ${OBJECTS} ${DEPS}
             # make usual symlinks
             ln -s ${LIBNAME}.so.${VERSION} ${LIBNAME}.so.${MAJOR}
             ln -s ${LIBNAME}.so.${MAJOR} ${LIBNAME}.so
@@ -346,10 +352,10 @@ case $ARCH in
 	    #echo "mklib: linker is" ${LINK} ${OPTS}
 	    if [ $NOPREFIX = 1 ] ; then
 		rm -f ${LIBNAME}
-		${LINK} ${OPTS} -o ${LIBNAME} ${OBJECTS} ${DEPS}
+		${LINK} ${OPTS} ${LDFLAGS} -o ${LIBNAME} ${OBJECTS} ${DEPS}
 	    else
 		rm -f ${LIBNAME}.${MAJOR} ${LIBNAME}
-		${LINK} ${OPTS} -o ${LIBNAME}.${MAJOR} ${OBJECTS} ${DEPS}
+		${LINK} ${OPTS} ${LDFLAGS} -o ${LIBNAME}.${MAJOR} ${OBJECTS} ${DEPS}
 		ln -s ${LIBNAME}.${MAJOR} ${LIBNAME}
 	    fi
 	    FINAL_LIBS="${LIBNAME}.${MAJOR} ${LIBNAME}"
@@ -373,7 +379,7 @@ case $ARCH in
 	    echo "mklib: Making FreeBSD shared library: " ${LIBNAME}
 	    OPTS="-shared"
 	    rm -f ${LIBNAME}
-	    ${LINK} ${OPTS} -o ${LIBNAME} ${OBJECTS} ${DEPS}
+	    ${LINK} ${OPTS} ${LDFLAGS} -o ${LIBNAME} ${OBJECTS} ${DEPS}
 	    FINAL_LIBS=${LIBNAME}
         elif [ $STATIC = 1 ] ; then
 	    STLIB="lib${LIBNAME}.a"
@@ -387,7 +393,7 @@ case $ARCH in
 	    OPTS="-shared -Wl,-soname,${SHLIB}"
 	    echo "mklib: Making FreeBSD shared library: " ${SHLIB}
 	    rm -f ${SHLIB}
-	    ${LINK} ${OPTS} -o ${SHLIB} ${OBJECTS} ${DEPS}
+	    ${LINK} ${OPTS} ${LDFLAGS} -o ${SHLIB} ${OBJECTS} ${DEPS}
 	    ln -sf ${SHLIB} "lib${LIBNAME}.so"
 	    FINAL_LIBS="${SHLIB} lib${LIBNAME}.so"
 	fi
@@ -445,7 +451,7 @@ case $ARCH in
 	    fi
 
 	    echo "mklib: Making IRIX " ${ABI} " shared library: " ${LIBNAME}
-	    ${LINK} ${OPTS} -o ${LIBNAME} ${OBJECTS} ${DEPS}
+	    ${LINK} ${OPTS} ${LDFLAGS} -o ${LIBNAME} ${OBJECTS} ${DEPS}
 	    FINAL_LIBS=${LIBNAME}
 	fi
 	;;
@@ -521,9 +527,9 @@ case $ARCH in
             # On AIX a shared library is linked differently when
             # you want to dlopen the file
 	    if [ $DLOPEN = "1" ] ; then
-		cc -G ${OPTS} -o ${LIBNAME} ${OBJECTS} ${DEPS}
+		cc -G ${OPTS} ${LDFLAGS} -o ${LIBNAME} ${OBJECTS} ${DEPS}
 	    else
-		cc ${OPTS} -o ${OFILE} ${OBJECTS} ${DEPS}
+		cc ${OPTS} ${LDFLAGS} -o ${OFILE} ${OBJECTS} ${DEPS}
 		ar ${X64} -r ${LIBNAME} ${OFILE}
 	    fi
 
@@ -605,7 +611,7 @@ case $ARCH in
 	    fi
 
             echo "mklib: Making Darwin shared library: " ${LIBNAME}
-            ${LINK} ${OPTS} -o ${LIBNAME} ${OBJECTS} ${DEPS}
+            ${LINK} ${OPTS} ${LDFLAGS} -o ${LIBNAME} ${OBJECTS} ${DEPS}
             ln -s ${LIBNAME} ${LINKNAME}
             FINAL_LIBS="${LIBNAME} ${LINKNAME}"
         fi
@@ -682,7 +688,7 @@ case $ARCH in
             rm -f ${LIBNAME}.so.${MAJOR}
             rm -f ${LIBNAME}.so
             # make lib
-            ${LINK} ${OPTS} -o ${LIBNAME}.so.${VERSION} ${OBJECTS} ${DEPS}
+            ${LINK} ${OPTS} ${LDFLAGS} -o ${LIBNAME}.so.${VERSION} ${OBJECTS} ${DEPS}
             # make usual symlinks
             ln -s ${LIBNAME}.so.${VERSION} ${LIBNAME}.so.${MAJOR}
             ln -s ${LIBNAME}.so.${MAJOR} ${LIBNAME}.so
@@ -754,7 +760,7 @@ case $ARCH in
             rm -f ${LIBNAME}.a
 
             # make lib
-            ${LINK} ${OPTS} -o ${CYGNAME}-${MAJOR}.dll ${OBJECTS} ${DEPS}
+            ${LINK} ${OPTS} ${LDFLAGS} -o ${CYGNAME}-${MAJOR}.dll ${OBJECTS} ${DEPS}
             # make usual symlinks
             ln -s ${LIBNAME}-${MAJOR}.dll.a ${LIBNAME}.dll.a
             # finish up
diff --git a/configs/bluegene-xlc-osmesa b/configs/bluegene-xlc-osmesa
new file mode 100644
index 0000000..b0c762d
--- /dev/null
+++ b/configs/bluegene-xlc-osmesa
@@ -0,0 +1,29 @@
+# Configuration for building only libOSMesa on BlueGene using the IBM xlc compiler
+# This doesn't really have a lot of dependencies, so it should be usable
+# on similar systems too.
+# It uses static linking and disables multithreading.
+
+include $(TOP)/configs/default
+
+CONFIG_NAME = bluegene-osmesa
+
+# Compiler and flags
+CC = /opt/ibmcmp/vacpp/bg/8.0/bin/blrts_xlc
+CXX = /opt/ibmcmp/vacpp/bg/8.0/bin/blrts_xlC
+CFLAGS = -O3 -pedantic -D_POSIX_SOURCE -D_POSIX_C_SOURCE=199309L -D_SVID_SOURCE -D_BSD_SOURCE
+CXXFLAGS = -O3 -pedantic -D_POSIX_SOURCE -D_POSIX_C_SOURCE=199309L -D_SVID_SOURCE -D_BSD_SOURCE
+
+MKLIB_OPTIONS = -static
+
+OSMESA_LIB_NAME = libOSMesa.a
+
+# Directories
+SRC_DIRS = mesa glu
+DRIVER_DIRS = osmesa
+PROGRAM_DIRS = osdemos
+
+
+# Dependencies
+OSMESA_LIB_DEPS = -lm
+GLU_LIB_DEPS = -L$(TOP)/$(LIB_DIR) -l$(OSMESA_LIB)
+APP_LIB_DEPS = -lOSMesa -lGLU -lm
diff --git a/configs/default b/configs/default
index 81f0338..2a08c16 100644
--- a/configs/default
+++ b/configs/default
@@ -10,7 +10,7 @@ CONFIG_NAME = default
 # Version info
 MESA_MAJOR=7
 MESA_MINOR=0
-MESA_TINY=1
+MESA_TINY=2
 
 # external projects.  This should be useless now that we use libdrm.
 DRM_SOURCE_PATH=$(TOP)/../drm
@@ -20,6 +20,7 @@ CC = cc
 CXX = CC
 CFLAGS = -O
 CXXFLAGS = -O
+LDFLAGS =
 GLU_CFLAGS = 
 
 # Misc tools and flags
diff --git a/docs/download.html b/docs/download.html
index 5c3989e..84451b8 100644
--- a/docs/download.html
+++ b/docs/download.html
@@ -9,7 +9,7 @@
 <H1>Downloading</H1>
 
 <p>
-Last stable release: <b>7.0.1</b>
+Last stable release: <b>7.0.2</b>
 </p>
 
 <p>
diff --git a/docs/fbdev-dri.html b/docs/fbdev-dri.html
index c7f59bb..0d9e52c 100644
--- a/docs/fbdev-dri.html
+++ b/docs/fbdev-dri.html
@@ -28,6 +28,12 @@ Xlib interfaces allowing some degree of application portability between
 the X and X-less environments.
 </p>
 
+<p>
+Some of the files needed for building this configuration are not included
+in the normal Mesa releases so you'll need to get the latest sources
+sources from the <a href="repository.html">git repository</a>.
+</p>
+
 
 <h1>2. Compilation</h1>
 
diff --git a/docs/install.html b/docs/install.html
index 804dee5..4cd0d4c 100644
--- a/docs/install.html
+++ b/docs/install.html
@@ -57,50 +57,31 @@ the DRI hardware drivers.
 
 <li>
 <p>
-DRM kernel modules and header files from the
-<a href="http://dri.sf.net/" target="_parent">DRI</a> project.
+For Mesa 7.0.2 <a href="http://dri.freedesktop.org/libdrm/">
+DRM version 2.3</a> is required.
 </p>
-
 <p>
-If you don't already have the DRM file, you can get the sources from
-CVS by doing:
-<pre>
-cvs -z3 -d:pserver:anonymous@anoncvs.freedesktop.org:/cvs/dri co drm
-</pre>
-<p>
-See the <a href="http://dri.freedesktop.org/wiki/Building" target="_parent">
-DRI Building Instructions</a> for the steps to build the DRM modules.  Mesa
-6.5 requires at least libdrm 2.0.1 or greater.
-</p>
-<p>
-You can verify that the DRM files have been properly installed by
-running <code>pkg-config --modversion libdrm</code>
-
-</li>
-
-<li>
-Recent /usr/include/GL/glxproto.h file.
-<p>You'll need this if you get any errors about _GLXvop_BindTexImageEXT
-being undefined.
+To check if you already have it, run:
+<br>
+<code>pkg-config --modversion libdrm</code>
 </p>
 <p>
-Download/install the
-<a href="http://gitweb.freedesktop.org/?p=xorg/proto/glproto.git">glproto</a>
-module from X.org git, or grab the
-<A href="http://webcvs.freedesktop.org/*checkout*/xorg/proto/GL/glxproto.h?rev=1.9&content-type=text%2Fplain">glxproto.h file</a> and put it in the
-Mesa/include/GL/ directory.
+You can download and install a <a href="http://dri.freedesktop.org/libdrm/">
+tarball release</a> or get the code from git with:
+<br>
+<code>git clone git://anongit.freedesktop.org/git/mesa/drm</code>
+<br>
+Then revert to the drm-2.3.0 tag with:
+<br>
+<code>git-reset --hard drm-2.3.0</code>
 </p>
-
 </li>
 
-<li>DRI-enabled X server.
-<p>Visit
-<a href="http://www.xfree86.org" target="_parent">XFree86</a>
-or
+<li>
+Relatively recent
 <a href="http://freedesktop.org/wiki/Software_2fXserver" target="_parent">
-X.org</a>
-for more information.
-</p>
+X.org</a> release.
+Mesa depends on a number of X header and library files.
 </li>
 
 </ol>
@@ -287,7 +268,15 @@ already installed, you'll have to choose different directories, like
 To install Mesa's headers and libraries, run <code>make install</code>.
 But first, check the Mesa/configs/default file and examine the values
 of the <b>INSTALL_DIR</b> and <b>DRI_DRIVER_INSTALL_DIR</b> variables.
-Change them if needed, then run <code>make install</code>
+Change them if needed, then run <code>make install</code>.
+</p>
+
+<p>
+The variable
+<b>DESTDIR</b> may also be used to install the contents to a temporary
+staging directory.
+This can be useful for package management.
+For example: <code>make install DESTDIR=/somepath/</code>
 </p>
 
 <p>
@@ -298,6 +287,26 @@ This is a handy way to compare multiple OpenGL implementations.
 </p>
 
 
+<H3>1.5 pkg-config support</H3>
+
+<p>
+Running <code>make install</code> will install package configuration files
+for the pkg-config utility.
+</p>
+
+<p>
+When compiling your OpenGL application you can use pkg-config to determine
+the proper compiler and linker flags.
+</p>
+
+<p>
+For example, compiling and linking a GLUT application can be done with:
+</p>
+<pre>
+   gcc `pkg-config --cflags --libs glut` mydemo.c -o mydemo
+</pre>
+
+<br>
 
 <a name="windows">
 <H2>2. Windows Compilation and Installation</H1>
diff --git a/docs/license.html b/docs/license.html
index 944a5dd..44b980d 100644
--- a/docs/license.html
+++ b/docs/license.html
@@ -86,29 +86,32 @@ and their respective licenses.
 <H1>Mesa Component Licenses</H1>
 
 <pre>
-Component         Location               Primary Author      License
-----------------------------------------------------------------------------
-Main Mesa code    src/mesa/              Brian Paul          Mesa (MIT)
+Component         Location               License
+------------------------------------------------------------------
+Main Mesa code    src/mesa/              Mesa (MIT)
 
-Device drivers    src/mesa/drivers/*     See drivers         See drivers
+Device drivers    src/mesa/drivers/*     MIT, generally
 
-Ext headers       include/GL/glext.h     SGI                 SGI Free B
+Ext headers       include/GL/glext.h     Khronos
                   include/GL/glxext.h
 
-GLUT              src/glut/              Mark Kilgard        Mark's copyright
+GLUT              src/glut/              Mark Kilgard's copyright
 
-Mesa GLU library  src/glu/mesa/          Brian Paul          GNU-LGPL
+SGI GLU library   src/glu/sgi/           SGI Free B
 
-SGI GLU library   src/glu/sgi/           SGI                 SGI Free B
+demo programs     progs/demos/           see source files
 
-demo programs     progs/demos/           various             see source files
+X demos           progs/xdemos/          see source files
 
-X demos           progs/xdemos/          Brian Paul          see source files
+SGI demos         progs/samples/         SGI license
 
-SGI demos         progs/samples/         SGI                 SGI copyright
-
-RedBook demos     progs/redbook/         SGI                 SGI copyright
+RedBook demos     progs/redbook/         SGI license
 </pre>
 
+<p>
+In general, consult the source files for license terms.
+</p>
+
+
 </body>
 </html>
diff --git a/docs/modelers.html b/docs/modelers.html
index b93f4d8..aae9686 100644
--- a/docs/modelers.html
+++ b/docs/modelers.html
@@ -28,7 +28,7 @@
 	</li><li><a href="http://innovation3d.sourceforge.net/" target="_parent">Innovation3D</a>
 	- 3D modeling program
 	</li><li><a href="http://mesa3d.sourceforge.net/notfound.html" target="_parent">KWRL</a> - VRML browser
-	</li><li><a href="http://www.vermontel.com/%7Ecmorley/vrml.html" target="_parent">LibVRML97/Lookat</a>
+	</li><li><a href="http://www.openvrml.org/" target="_parent">LibVRML97/Lookat</a>
 	- VRML viewer
 	</li><li><a href="http://aig.cs.man.ac.uk/systems/Maverik/" target="_parent">Maverik</a>
 	- VR graphics and interaction system
diff --git a/docs/news.html b/docs/news.html
index 1f66d4e..8694ce4 100644
--- a/docs/news.html
+++ b/docs/news.html
@@ -11,9 +11,16 @@
 <H1>News</H1>
 
 
+<h2>September ??, 2007</h2>
+<p>
+<a href="relnotes-7.0.2.html">Mesa 7.0.2</a> is released.
+This is a bug-fix release.
+</p>
+
+
 <h2>August 3, 2007</h2>
 <p>
-<a href="relnotes-7.0.html">Mesa 7.0.1</a> is released.
+<a href="relnotes-7.0.1.html">Mesa 7.0.1</a> is released.
 This is a bug-fix release.
 </p>
 
diff --git a/docs/relnotes-7.0.1.html b/docs/relnotes-7.0.1.html
index 47ee162..02713ad 100644
--- a/docs/relnotes-7.0.1.html
+++ b/docs/relnotes-7.0.1.html
@@ -17,6 +17,15 @@ Mesa 7.0.1 is a stable release with bug fixes since version 7.0.
 
 <h2>MD5 checksums</h2>
 <pre>
+db55141a44b902fcc61d9265b7862c06  MesaLib-7.0.1.tar.gz
+c056abd763e899114bf745c9eedbf9ad  MesaLib-7.0.1.tar.bz2
+ecc2637547fae2b38271ae362d013afa  MesaLib-7.0.1.zip
+b85a4a5be4e829f4a1165e4514b13183  MesaDemos-7.0.1.tar.gz
+3b66b3268df12ca8a6c4e0c4c457912c  MesaDemos-7.0.1.tar.bz2
+b1c18006f16e44e80fea66774c59b391  MesaDemos-7.0.1.zip
+b87a69986839ae43ce12fc8e3dc1ebb4  MesaGLUT-7.0.1.tar.gz
+25f30d0c1651997b4412366ba0572f7f  MesaGLUT-7.0.1.tar.bz2
+676ee6682a6ce78a5540554fd975c03e  MesaGLUT-7.0.1.zip
 </pre>
 
 
diff --git a/docs/relnotes-7.0.2.html b/docs/relnotes-7.0.2.html
new file mode 100644
index 0000000..46040e1
--- /dev/null
+++ b/docs/relnotes-7.0.2.html
@@ -0,0 +1,84 @@
+<HTML>
+
+<TITLE>Mesa Release Notes</TITLE>
+
+<head><link rel="stylesheet" type="text/css" href="mesa.css"></head>
+
+<BODY>
+
+<body bgcolor="#eeeeee">
+
+<H1>Mesa 7.0.2 Release Notes / (TBD) 2007</H1>
+
+<p>
+Mesa 7.0.2 is a stable release with bug fixes since version 7.0.
+</p>
+
+
+<h2>MD5 checksums</h2>
+<pre>
+</pre>
+
+
+<h2>New features</h2>
+<ul>
+<li>Updated Windows VC7 project files
+<li>Added DESTDIR variable for 'make install'
+<li>Added pkg-config files for gl, glu, glut and glw libraries
+<li>Added bluegene-xlc-osmesa config
+</ul>
+
+<h2>Bug fixes</h2>
+<ul>
+<li>Fixed a vertex buffer wrapping issue (bug 9962)
+<li>Added mutex protection around texture object reference counters
+<li>Added checking/support for additional chips in the i915/i945 family
+(see 11978)
+<li>Fixed a blending/banding issue (bug 11931)
+<li>Fixed a GLU matrix inversion bug (#6748)
+<li>Fixed problem with large glDrawArrays calls and indirect rendering (bug 12141)
+<li>Fixed an assortment of i965 driver bugs
+<li>Fixed and x86-64 vertex transformation bug (12216)
+<li>Fixed X server crash caused by multiple indirect rendering clients
+<li>Parsing of state.texgen in ARB vertex/fragment programs didn't work (bug 12313)
+<li>Fixed a glCopyPixels/glPixelZoom bug (12417)
+<li>Fixed a bug when using glMaterial in display lists (bug 10604)
+<li>Fixed a few GLUT/Fortran issues (Bill Mitchell)
+<li>Fixed Blender crash bug (12164)
+</ul>
+
+
+<h2>Changes</h2>
+<ul>
+</ul>
+
+
+<h2>To Do (someday) items</h2>
+<ul>
+<li>Switch to freeglut
+<li>Fix linux-glide target/driver.
+<li>Improved lambda and derivative calculation for frag progs.
+</ul>
+
+
+<h2>Driver Status</h2>
+
+<pre>
+Driver			Status
+----------------------	----------------------
+DRI drivers		varies with the driver
+XMesa/GLX (on Xlib)	implements OpenGL 2.1
+OSMesa (off-screen)	implements OpenGL 2.1
+Windows/Win32		implements OpenGL 2.1
+Glide (3dfx Voodoo1/2)	implements OpenGL 1.3
+SVGA			unsupported
+Wind River UGL		unsupported
+DJGPP			unsupported
+GGI			unsupported
+BeOS			unsupported
+Allegro			unsupported
+D3D			unsupported
+</pre>
+
+</body>
+</html>
diff --git a/docs/relnotes.html b/docs/relnotes.html
index 9a978d9..7464f5c 100644
--- a/docs/relnotes.html
+++ b/docs/relnotes.html
@@ -20,6 +20,7 @@ The release notes summarize what's new or changed in each Mesa release.
 </p>
 
 <UL>
+<LI><A HREF="relnotes-7.0.2.html">7.0.2 release notes</A>
 <LI><A HREF="relnotes-7.0.1.html">7.0.1 release notes</A>
 <LI><A HREF="relnotes-7.0.html">7.0 release notes</A>
 <LI><A HREF="relnotes-6.5.3.html">6.5.3 release notes</A>
diff --git a/include/GL/glu.h b/include/GL/glu.h
index d82103d..7db4b70 100644
--- a/include/GL/glu.h
+++ b/include/GL/glu.h
@@ -44,22 +44,17 @@
 #define GLAPIENTRYP GLAPIENTRY *
 #endif
 
-#ifdef GLAPI
-#undef GLAPI
-#endif
-
-#  if (defined(_MSC_VER) || defined(__MINGW32__)) && defined(BUILD_GLU32)
-#    define GLAPI __declspec(dllexport)
-#  elif (defined(_MSC_VER) || defined(__MINGW32__)) && defined(_DLL) /* tag specifying we're building for DLL runtime support */
-#    define GLAPI __declspec(dllimport)
-#  else /* for use with static link lib build of Win32 edition only */
-#    define GLAPI extern
-#  endif /* _STATIC_MESA support */
-
-
-#ifndef GLAPI
-#define GLAPI
-#endif
+#if (defined(_MSC_VER) || defined(__MINGW32__)) && defined(BUILD_GLU32)
+# undef GLAPI
+# define GLAPI __declspec(dllexport)
+#elif (defined(_MSC_VER) || defined(__MINGW32__)) && defined(_DLL)
+/* tag specifying we're building for DLL runtime support */
+# undef GLAPI
+# define GLAPI __declspec(dllimport)
+#elif !defined(GLAPI)
+/* for use with static link lib build of Win32 edition only */
+# define GLAPI extern
+#endif /* _STATIC_MESA support */
 
 #ifdef __cplusplus
 extern "C" {
diff --git a/progs/demos/Makefile b/progs/demos/Makefile
index cf96828..798de25 100644
--- a/progs/demos/Makefile
+++ b/progs/demos/Makefile
@@ -74,7 +74,7 @@ PROGS = \
 
 # make executable from .c file:
 .c: $(LIB_DEP) readtex.o
-	$(CC) -I$(INCDIR) $(CFLAGS) $< readtex.o $(APP_LIB_DEPS) -o $@
+	$(CC) -I$(INCDIR) $(CFLAGS) $(LDFLAGS) $< readtex.o $(APP_LIB_DEPS) -o $@
 
 
 ##### TARGETS #####
@@ -118,35 +118,35 @@ extfuncs.h:  $(TOP)/progs/util/extfuncs.h
 
 
 reflect: reflect.o showbuffer.o readtex.o
-	$(CC) reflect.o showbuffer.o readtex.o $(APP_LIB_DEPS) -o $@
+	$(CC) $(LDFLAGS) reflect.o showbuffer.o readtex.o $(APP_LIB_DEPS) -o $@
 
 reflect.o: reflect.c showbuffer.h
 	$(CC) -c -I$(INCDIR) $(CFLAGS) reflect.c
 
 
 shadowtex: shadowtex.o showbuffer.o
-	$(CC) shadowtex.o showbuffer.o $(APP_LIB_DEPS) -o $@
+	$(CC) $(LDFLAGS) shadowtex.o showbuffer.o $(APP_LIB_DEPS) -o $@
 
 shadowtex.o: shadowtex.c showbuffer.h
 	$(CC) -c -I$(INCDIR) $(CFLAGS) shadowtex.c
 
 
 gloss: gloss.o trackball.o readtex.o
-	$(CC) gloss.o trackball.o readtex.o $(APP_LIB_DEPS) -o $@
+	$(CC) $(LDFLAGS) gloss.o trackball.o readtex.o $(APP_LIB_DEPS) -o $@
 
 gloss.o: gloss.c trackball.h
 	$(CC) -c -I$(INCDIR) $(CFLAGS) gloss.c
 
 
 engine: engine.o trackball.o readtex.o
-	$(CC) engine.o trackball.o readtex.o $(APP_LIB_DEPS) -o $@
+	$(CC) $(LDFLAGS) engine.o trackball.o readtex.o $(APP_LIB_DEPS) -o $@
 
 engine.o: engine.c trackball.h
 	$(CC) -c -I$(INCDIR) $(CFLAGS) engine.c
 
 
 fslight: fslight.o
-	$(CC) fslight.o $(APP_LIB_DEPS) -o $@
+	$(CC) $(LDFLAGS) fslight.o $(APP_LIB_DEPS) -o $@
 
 fslight.o: fslight.c extfuncs.h
 	$(CC) -c -I$(INCDIR) $(CFLAGS) fslight.c
diff --git a/progs/fbdev/.gitignore b/progs/fbdev/.gitignore
new file mode 100644
index 0000000..b9ddf55
--- /dev/null
+++ b/progs/fbdev/.gitignore
@@ -0,0 +1 @@
+glfbdevtest
diff --git a/progs/fbdev/Makefile b/progs/fbdev/Makefile
index 0a0c779..92bfd04 100644
--- a/progs/fbdev/Makefile
+++ b/progs/fbdev/Makefile
@@ -22,7 +22,7 @@ INCLUDES = \
 .SUFFIXES: .c
 
 .c:
-	$(CC) $(INCLUDES) $(CFLAGS) $< $(APP_LIB_DEPS) -o $@
+	$(CC) $(INCLUDES) $(CFLAGS) $(LDFLAGS) $< $(APP_LIB_DEPS) -o $@
 
 .c.o:
 	$(CC) -c $(INCLUDES) $(CFLAGS) $< -o $@
diff --git a/progs/glsl/Makefile b/progs/glsl/Makefile
index 37fa312..a5ca1f3 100644
--- a/progs/glsl/Makefile
+++ b/progs/glsl/Makefile
@@ -25,7 +25,7 @@ PROGS = \
 
 # make executable from .c file:
 .c: $(LIB_DEP)
-	$(CC) -I$(INCDIR) $(CFLAGS) $< $(APP_LIB_DEPS) -o $@
+	$(CC) -I$(INCDIR) $(CFLAGS) $(LDFLAGS) $< $(APP_LIB_DEPS) -o $@
 
 
 ##### TARGETS #####
@@ -57,7 +57,7 @@ mandelbrot.c: extfuncs.h
 toyball.c: extfuncs.h
 
 texdemo1: texdemo1.o readtex.o
-	$(CC) -I$(INCDIR) $(CFLAGS) texdemo1.o readtex.o $(APP_LIB_DEPS) -o $@
+	$(CC) -I$(INCDIR) $(CFLAGS) $(LDFLAGS) texdemo1.o readtex.o $(APP_LIB_DEPS) -o $@
 
 texdemo1.o: texdemo1.c readtex.h extfuncs.h
 	$(CC) -c -I$(INCDIR) $(CFLAGS) texdemo1.c
diff --git a/progs/glsl/bump.c b/progs/glsl/bump.c
index a6846ac..11f87ab 100644
--- a/progs/glsl/bump.c
+++ b/progs/glsl/bump.c
@@ -247,7 +247,7 @@ LoadAndCompileShader(GLuint shader, const char *text)
       GLchar log[1000];
       GLsizei len;
       glGetShaderInfoLog_func(shader, 1000, &len, log);
-      fprintf(stderr, "brick: problem compiling shader: %s\n", log);
+      fprintf(stderr, "bump: problem compiling shader: %s\n", log);
       exit(1);
    }
    else {
@@ -267,12 +267,12 @@ ReadShader(GLuint shader, const char *filename)
    char *buffer = (char*) malloc(max);
    FILE *f = fopen(filename, "r");
    if (!f) {
-      fprintf(stderr, "brick: Unable to open shader file %s\n", filename);
+      fprintf(stderr, "bump: Unable to open shader file %s\n", filename);
       exit(1);
    }
 
    n = fread(buffer, 1, max, f);
-   printf("brick: read %d bytes from shader file %s\n", n, filename);
+   printf("bump: read %d bytes from shader file %s\n", n, filename);
    if (n > 0) {
       buffer[n] = 0;
       LoadAndCompileShader(shader, buffer);
diff --git a/progs/glsl/mandelbrot.c b/progs/glsl/mandelbrot.c
index 7a2bad6..e7b2b04 100644
--- a/progs/glsl/mandelbrot.c
+++ b/progs/glsl/mandelbrot.c
@@ -172,7 +172,7 @@ LoadAndCompileShader(GLuint shader, const char *text)
       GLchar log[1000];
       GLsizei len;
       glGetShaderInfoLog_func(shader, 1000, &len, log);
-      fprintf(stderr, "brick: problem compiling shader: %s\n", log);
+      fprintf(stderr, "mandelbrot: problem compiling shader: %s\n", log);
       exit(1);
    }
    else {
@@ -192,12 +192,12 @@ ReadShader(GLuint shader, const char *filename)
    char *buffer = (char*) malloc(max);
    FILE *f = fopen(filename, "r");
    if (!f) {
-      fprintf(stderr, "brick: Unable to open shader file %s\n", filename);
+      fprintf(stderr, "mandelbrot: Unable to open shader file %s\n", filename);
       exit(1);
    }
 
    n = fread(buffer, 1, max, f);
-   printf("brick: read %d bytes from shader file %s\n", n, filename);
+   printf("mandelbrot: read %d bytes from shader file %s\n", n, filename);
    if (n > 0) {
       buffer[n] = 0;
       LoadAndCompileShader(shader, buffer);
diff --git a/progs/glsl/noise.c b/progs/glsl/noise.c
index a26a805..adccd1a 100644
--- a/progs/glsl/noise.c
+++ b/progs/glsl/noise.c
@@ -188,7 +188,7 @@ LoadAndCompileShader(GLuint shader, const char *text)
       GLchar log[1000];
       GLsizei len;
       glGetShaderInfoLog_func(shader, 1000, &len, log);
-      fprintf(stderr, "brick: problem compiling shader: %s\n", log);
+      fprintf(stderr, "noise: problem compiling shader: %s\n", log);
       exit(1);
    }
    else {
diff --git a/progs/glsl/toyball.c b/progs/glsl/toyball.c
index cef52c0..3aa0961 100644
--- a/progs/glsl/toyball.c
+++ b/progs/glsl/toyball.c
@@ -185,7 +185,7 @@ LoadAndCompileShader(GLuint shader, const char *text)
       GLchar log[1000];
       GLsizei len;
       glGetShaderInfoLog_func(shader, 1000, &len, log);
-      fprintf(stderr, "brick: problem compiling shader: %s\n", log);
+      fprintf(stderr, "toyball: problem compiling shader: %s\n", log);
       exit(1);
    }
    else {
@@ -205,12 +205,12 @@ ReadShader(GLuint shader, const char *filename)
    char *buffer = (char*) malloc(max);
    FILE *f = fopen(filename, "r");
    if (!f) {
-      fprintf(stderr, "brick: Unable to open shader file %s\n", filename);
+      fprintf(stderr, "toyball: Unable to open shader file %s\n", filename);
       exit(1);
    }
 
    n = fread(buffer, 1, max, f);
-   printf("brick: read %d bytes from shader file %s\n", n, filename);
+   printf("toyball: read %d bytes from shader file %s\n", n, filename);
    if (n > 0) {
       buffer[n] = 0;
       LoadAndCompileShader(shader, buffer);
diff --git a/progs/miniglx/.gitignore b/progs/miniglx/.gitignore
new file mode 100644
index 0000000..f630f59
--- /dev/null
+++ b/progs/miniglx/.gitignore
@@ -0,0 +1,6 @@
+manytex
+miniglxsample
+miniglxtest
+sample_server
+sample_server2
+texline
diff --git a/progs/osdemos/.gitignore b/progs/osdemos/.gitignore
new file mode 100644
index 0000000..5c78f12
--- /dev/null
+++ b/progs/osdemos/.gitignore
@@ -0,0 +1,8 @@
+osdemo
+osdemo16
+osdemo32
+ostest1
+readtex.c
+readtex.h
+showbuffer.c
+showbuffer.h
diff --git a/progs/osdemos/Makefile b/progs/osdemos/Makefile
index f8cba9e..7e65774 100644
--- a/progs/osdemos/Makefile
+++ b/progs/osdemos/Makefile
@@ -26,7 +26,7 @@ PROGS = \
 
 # make executable from .c file:
 .c: $(LIB_DEP) readtex.o
-	$(CC) -I$(INCDIR) $(CFLAGS) $< readtex.o $(APP_LIB_DEPS) -o $@
+	$(CC) -I$(INCDIR) $(CFLAGS) $(LDFLAGS) $< readtex.o $(APP_LIB_DEPS) -o $@
 
 
 ##### TARGETS #####
@@ -56,19 +56,19 @@ showbuffer.o: showbuffer.c showbuffer.h
 
 # special case: need the -lOSMesa library:
 osdemo: osdemo.c
-	$(CC) -I$(INCDIR) $(CFLAGS) osdemo.c $(OSMESA_LIBS) -o $@
+	$(CC) -I$(INCDIR) $(CFLAGS) $(LDFLAGS) osdemo.c $(OSMESA_LIBS) -o $@
 
 # special case: need the -lOSMesa library:
 ostest1: ostest1.c
-	$(CC) -I$(INCDIR) $(CFLAGS) ostest1.c $(OSMESA_LIBS) -o $@
+	$(CC) -I$(INCDIR) $(CFLAGS) $(LDFLAGS) ostest1.c $(OSMESA_LIBS) -o $@
 
 # another special case: need the -lOSMesa16 library:
 osdemo16: osdemo16.c
-	$(CC) -I$(INCDIR) $(CFLAGS) osdemo16.c $(OSMESA16_LIBS) -o $@
+	$(CC) -I$(INCDIR) $(CFLAGS) $(LDFLAGS) osdemo16.c $(OSMESA16_LIBS) -o $@
 
 # another special case: need the -lOSMesa32 library:
 osdemo32: osdemo32.c
-	$(CC) -I$(INCDIR) $(CFLAGS) osdemo32.c $(OSMESA32_LIBS) -o $@
+	$(CC) -I$(INCDIR) $(CFLAGS) $(LDFLAGS) osdemo32.c $(OSMESA32_LIBS) -o $@
 
 
 
diff --git a/progs/redbook/Makefile b/progs/redbook/Makefile
index febc744..078f191 100644
--- a/progs/redbook/Makefile
+++ b/progs/redbook/Makefile
@@ -24,7 +24,7 @@ PROGS = aaindex aapoly aargb accanti accpersp alpha alpha3D anti \
 .SUFFIXES: .c
 
 .c: $(LIB_DEP)
-	$(CC) -I$(INCDIR) $(CFLAGS) $< $(APP_LIB_DEPS) -o $@
+	$(CC) -I$(INCDIR) $(CFLAGS) $(LDFLAGS) $< $(APP_LIB_DEPS) -o $@
 
 
 
diff --git a/src/glu/Makefile b/src/glu/Makefile
index 5ddc509..836baa6 100644
--- a/src/glu/Makefile
+++ b/src/glu/Makefile
@@ -13,9 +13,19 @@ default: $(TOP)/configs/current
 		(cd $$dir ; $(MAKE)) ; \
 	done
 
-install:
-	$(INSTALL) -d $(INSTALL_DIR)/$(LIB_DIR)
-	$(INSTALL) $(TOP)/$(LIB_DIR)/libGLU.* $(INSTALL_DIR)/$(LIB_DIR)
+# GLU pkg-config file
+pcedit = sed \
+	-e 's,@INSTALL_DIR@,$(INSTALL_DIR),' \
+	-e 's,@LIB_DIR@,$(LIB_DIR),' \
+	-e 's,@VERSION@,$(MESA_MAJOR).$(MESA_MINOR).$(MESA_TINY),'
+glu.pc: glu.pc.in
+	$(pcedit) $< > $@
+
+install: glu.pc
+	$(INSTALL) -d $(DESTDIR)$(INSTALL_DIR)/$(LIB_DIR)
+	$(INSTALL) -d $(DESTDIR)$(INSTALL_DIR)/$(LIB_DIR)/pkgconfig
+	$(INSTALL) $(TOP)/$(LIB_DIR)/libGLU.* $(DESTDIR)$(INSTALL_DIR)/$(LIB_DIR)
+	$(INSTALL) -m 644 glu.pc $(DESTDIR)$(INSTALL_DIR)/$(LIB_DIR)/pkgconfig
 
 clean:
 	@for dir in $(SUBDIRS) ; do \
diff --git a/src/glu/glu.pc.in b/src/glu/glu.pc.in
new file mode 100644
index 0000000..5d6e52a
--- /dev/null
+++ b/src/glu/glu.pc.in
@@ -0,0 +1,11 @@
+prefix=@INSTALL_DIR@
+exec_prefix=${prefix}
+libdir=${exec_prefix}/@LIB_DIR@
+includedir=${prefix}/include
+
+Name: glu
+Description: Mesa OpenGL Utility library
+Requires: gl
+Version: @VERSION@
+Libs: -L${libdir} -lGLU
+Cflags: -I${includedir}
diff --git a/src/glu/sgi/Makefile b/src/glu/sgi/Makefile
index 2ce6ac0..bb1c0a8 100644
--- a/src/glu/sgi/Makefile
+++ b/src/glu/sgi/Makefile
@@ -136,7 +136,7 @@ $(TOP)/$(LIB_DIR):
 
 # Make the library:
 $(TOP)/$(LIB_DIR)/$(GLU_LIB_NAME): $(OBJECTS)
-	$(TOP)/bin/mklib -o $(GLU_LIB) -linker '$(CXX)' \
+	$(TOP)/bin/mklib -o $(GLU_LIB) -linker '$(CXX)' -ldflags '$(LDFLAGS)' \
 		-major $(GLU_MAJOR) -minor $(GLU_MINOR) -patch $(GLU_TINY) \
 		-cplusplus $(MKLIB_OPTIONS) -install $(TOP)/$(LIB_DIR) \
 		$(GLU_LIB_DEPS) $(OBJECTS)
diff --git a/src/glu/sgi/libutil/project.c b/src/glu/sgi/libutil/project.c
index 2b20ad4..356b46b 100644
--- a/src/glu/sgi/libutil/project.c
+++ b/src/glu/sgi/libutil/project.c
@@ -168,74 +168,57 @@ static void __gluMultMatrixVecd(const GLdouble matrix[16], const GLdouble in[4],
 }
 
 /*
-** inverse = invert(src)
-** New, faster implementation by Shan Hao Bo, April 2006.
+** Invert 4x4 matrix.
+** Contributed by David Moore (See Mesa bug #6748)
 */
-static int __gluInvertMatrixd(const GLdouble src[16], GLdouble inverse[16])
+static int __gluInvertMatrixd(const GLdouble m[16], GLdouble invOut[16])
 {
-	int i, j, k;
-	double t;
-	GLdouble temp[4][4];
-	 
-	for (i=0; i<4; i++) {
-		for (j=0; j<4; j++) {
-		    temp[i][j] = src[i*4+j];
-		}
-	}
-	__gluMakeIdentityd(inverse);
-	
-	for (i = 0; i < 4; i++) {
-		if (temp[i][i] == 0.0f) {
-		    /*
-		    ** Look for non-zero element in column
-		    */
-		    for (j = i + 1; j < 4; j++) {
-				if (temp[j][i] != 0.0f) {
-				    break;
-				}
-		    }
-		
-		    if (j != 4) {
-				/*
-				 ** Swap rows.
-				 */
-				for (k = 0; k < 4; k++) {
-				    t = temp[i][k];
-				    temp[i][k] = temp[j][k];
-				    temp[j][k] = t;
-			
-				    t = inverse[i*4+k];
-				    inverse[i*4+k] = inverse[j*4+k];
-				    inverse[j*4+k] = t;
-				}
-		    }
-		    else {
-				/*
-				** No non-zero pivot.  The matrix is singular, 
-which shouldn't
-				** happen.  This means the user gave us a bad 
-matrix.
-				*/
-				return GL_FALSE;
-		    }
-		}
-		
-		t = 1.0f / temp[i][i];
-		for (k = 0; k < 4; k++) {
-		    temp[i][k] *= t;
-		    inverse[i*4+k] *= t;
-		}
-		for (j = 0; j < 4; j++) {
-		    if (j != i) {
-				t = temp[j][i];
-				for (k = 0; k < 4; k++) {
-					    temp[j][k] -= temp[i][k]*t;
-					    inverse[j*4+k] -= inverse[i*4+k]*t;
-				}
-		    }
-		}
-	}
-	return GL_TRUE;
+    double inv[16], det;
+    int i;
+
+    inv[0] =   m[5]*m[10]*m[15] - m[5]*m[11]*m[14] - m[9]*m[6]*m[15]
+             + m[9]*m[7]*m[14] + m[13]*m[6]*m[11] - m[13]*m[7]*m[10];
+    inv[4] =  -m[4]*m[10]*m[15] + m[4]*m[11]*m[14] + m[8]*m[6]*m[15]
+             - m[8]*m[7]*m[14] - m[12]*m[6]*m[11] + m[12]*m[7]*m[10];
+    inv[8] =   m[4]*m[9]*m[15] - m[4]*m[11]*m[13] - m[8]*m[5]*m[15]
+             + m[8]*m[7]*m[13] + m[12]*m[5]*m[11] - m[12]*m[7]*m[9];
+    inv[12] = -m[4]*m[9]*m[14] + m[4]*m[10]*m[13] + m[8]*m[5]*m[14]
+             - m[8]*m[6]*m[13] - m[12]*m[5]*m[10] + m[12]*m[6]*m[9];
+    inv[1] =  -m[1]*m[10]*m[15] + m[1]*m[11]*m[14] + m[9]*m[2]*m[15]
+             - m[9]*m[3]*m[14] - m[13]*m[2]*m[11] + m[13]*m[3]*m[10];
+    inv[5] =   m[0]*m[10]*m[15] - m[0]*m[11]*m[14] - m[8]*m[2]*m[15]
+             + m[8]*m[3]*m[14] + m[12]*m[2]*m[11] - m[12]*m[3]*m[10];
+    inv[9] =  -m[0]*m[9]*m[15] + m[0]*m[11]*m[13] + m[8]*m[1]*m[15]
+             - m[8]*m[3]*m[13] - m[12]*m[1]*m[11] + m[12]*m[3]*m[9];
+    inv[13] =  m[0]*m[9]*m[14] - m[0]*m[10]*m[13] - m[8]*m[1]*m[14]
+             + m[8]*m[2]*m[13] + m[12]*m[1]*m[10] - m[12]*m[2]*m[9];
+    inv[2] =   m[1]*m[6]*m[15] - m[1]*m[7]*m[14] - m[5]*m[2]*m[15]
+             + m[5]*m[3]*m[14] + m[13]*m[2]*m[7] - m[13]*m[3]*m[6];
+    inv[6] =  -m[0]*m[6]*m[15] + m[0]*m[7]*m[14] + m[4]*m[2]*m[15]
+             - m[4]*m[3]*m[14] - m[12]*m[2]*m[7] + m[12]*m[3]*m[6];
+    inv[10] =  m[0]*m[5]*m[15] - m[0]*m[7]*m[13] - m[4]*m[1]*m[15]
+             + m[4]*m[3]*m[13] + m[12]*m[1]*m[7] - m[12]*m[3]*m[5];
+    inv[14] = -m[0]*m[5]*m[14] + m[0]*m[6]*m[13] + m[4]*m[1]*m[14]
+             - m[4]*m[2]*m[13] - m[12]*m[1]*m[6] + m[12]*m[2]*m[5];
+    inv[3] =  -m[1]*m[6]*m[11] + m[1]*m[7]*m[10] + m[5]*m[2]*m[11]
+             - m[5]*m[3]*m[10] - m[9]*m[2]*m[7] + m[9]*m[3]*m[6];
+    inv[7] =   m[0]*m[6]*m[11] - m[0]*m[7]*m[10] - m[4]*m[2]*m[11]
+             + m[4]*m[3]*m[10] + m[8]*m[2]*m[7] - m[8]*m[3]*m[6];
+    inv[11] = -m[0]*m[5]*m[11] + m[0]*m[7]*m[9] + m[4]*m[1]*m[11]
+             - m[4]*m[3]*m[9] - m[8]*m[1]*m[7] + m[8]*m[3]*m[5];
+    inv[15] =  m[0]*m[5]*m[10] - m[0]*m[6]*m[9] - m[4]*m[1]*m[10]
+             + m[4]*m[2]*m[9] + m[8]*m[1]*m[6] - m[8]*m[2]*m[5];
+
+    det = m[0]*inv[0] + m[1]*inv[4] + m[2]*inv[8] + m[3]*inv[12];
+    if (det == 0)
+        return GL_FALSE;
+
+    det = 1.0 / det;
+
+    for (i = 0; i < 16; i++)
+        invOut[i] = inv[i] * det;
+
+    return GL_TRUE;
 }
 
 static void __gluMultMatricesd(const GLdouble a[16], const GLdouble b[16],
diff --git a/src/glw/Makefile b/src/glw/Makefile
index 5228cbb..727c583 100644
--- a/src/glw/Makefile
+++ b/src/glw/Makefile
@@ -25,11 +25,21 @@ OBJECTS = $(GLW_SOURCES:.c=.o)
 
 default: $(TOP)/$(LIB_DIR)/$(GLW_LIB_NAME)
 
-install:
-	$(INSTALL) -d $(INSTALL_DIR)/include/GL
-	$(INSTALL) -d $(INSTALL_DIR)/$(LIB_DIR)
-	$(INSTALL) -m 644 *.h $(INSTALL_DIR)/include/GL
-	$(INSTALL) $(TOP)/$(LIB_DIR)/libGLw.* $(INSTALL_DIR)/$(LIB_DIR)
+# GLU pkg-config file
+pcedit = sed \
+	-e 's,@INSTALL_DIR@,$(INSTALL_DIR),' \
+	-e 's,@LIB_DIR@,$(LIB_DIR),' \
+	-e 's,@VERSION@,$(MAJOR).$(MINOR).$(TINY),'
+glw.pc: glw.pc.in
+	$(pcedit) $< > $@
+
+install: glw.pc
+	$(INSTALL) -d $(DESTDIR)$(INSTALL_DIR)/include/GL
+	$(INSTALL) -d $(DESTDIR)$(INSTALL_DIR)/$(LIB_DIR)
+	$(INSTALL) -d $(DESTDIR)$(INSTALL_DIR)/$(LIB_DIR)/pkgconfig
+	$(INSTALL) -m 644 *.h $(DESTDIR)$(INSTALL_DIR)/include/GL
+	$(INSTALL) $(TOP)/$(LIB_DIR)/libGLw.* $(DESTDIR)$(INSTALL_DIR)/$(LIB_DIR)
+	$(INSTALL) -m 644 glw.pc $(DESTDIR)$(INSTALL_DIR)/$(LIB_DIR)/pkgconfig
 
 clean:
 	-rm depend depend.bak
@@ -38,7 +48,7 @@ clean:
 
 # Make the library
 $(TOP)/$(LIB_DIR)/$(GLW_LIB_NAME): $(OBJECTS)
-	$(TOP)/bin/mklib -o $(GLW_LIB) -linker '$(CC)' \
+	$(TOP)/bin/mklib -o $(GLW_LIB) -linker '$(CC)' -ldflags '$(LDFLAGS)' \
 		-major $(MAJOR) -minor $(MINOR) -patch $(TINY) \
 		$(MKLIB_OPTIONS) -install $(TOP)/$(LIB_DIR) \
 		$(GLW_LIB_DEPS) $(OBJECTS)
diff --git a/src/glw/glw.pc.in b/src/glw/glw.pc.in
new file mode 100644
index 0000000..951e2dc
--- /dev/null
+++ b/src/glw/glw.pc.in
@@ -0,0 +1,11 @@
+prefix=@INSTALL_DIR@
+exec_prefix=${prefix}
+libdir=${exec_prefix}/@LIB_DIR@
+includedir=${prefix}/include
+
+Name: glw
+Description: Mesa OpenGL widget library
+Requires: gl
+Version: @VERSION@
+Libs: -L${libdir} -lGLU
+Cflags: -I${includedir}
diff --git a/src/glx/x11/Makefile b/src/glx/x11/Makefile
index 296747e..9f0943a 100644
--- a/src/glx/x11/Makefile
+++ b/src/glx/x11/Makefile
@@ -64,7 +64,7 @@ default: depend $(TOP)/$(LIB_DIR)/$(GL_LIB_NAME)
 
 # Make libGL
 $(TOP)/$(LIB_DIR)/$(GL_LIB_NAME):  $(OBJECTS) Makefile
-	$(TOP)/bin/mklib -o $(GL_LIB) -linker '$(CC)' \
+	$(TOP)/bin/mklib -o $(GL_LIB) -linker '$(CC)' -ldflags '$(LDFLAGS)' \
 		-major 1 -minor 2 $(MKLIB_OPTIONS) \
 		-install $(TOP)/$(LIB_DIR) $(GL_LIB_DEPS) $(OBJECTS)
 
diff --git a/src/glx/x11/glxext.c b/src/glx/x11/glxext.c
index af3a516..8fe1033 100644
--- a/src/glx/x11/glxext.c
+++ b/src/glx/x11/glxext.c
@@ -672,8 +672,11 @@ filter_modes( __GLcontextModes ** server_modes,
 	if ( do_delete && (m->visualID != 0) ) {
 	    do_delete = GL_FALSE;
 
-	    fprintf(stderr, "libGL warning: 3D driver claims to not support "
-		    "visual 0x%02x\n", m->visualID);
+	    /* don't warn for this visual (Novell #247471 / X.Org #6689) */
+	    if (m->visualRating != GLX_NON_CONFORMANT_CONFIG) {
+		fprintf(stderr, "libGL warning: 3D driver claims to not "
+			"support visual 0x%02x\n", m->visualID);
+	    }
 	}
 
 	if ( do_delete ) {
diff --git a/src/glx/x11/indirect_vertex_array.c b/src/glx/x11/indirect_vertex_array.c
index 90ec277..120fd82 100644
--- a/src/glx/x11/indirect_vertex_array.c
+++ b/src/glx/x11/indirect_vertex_array.c
@@ -527,7 +527,7 @@ static GLubyte *
 emit_DrawArrays_header_old( __GLXcontext * gc,
 			    struct array_state_vector * arrays,
 			    size_t * elements_per_request,
-			    size_t * total_requests,
+			    unsigned int * total_requests,
 			    GLenum mode, GLsizei count )
 {
     size_t command_size;
@@ -640,7 +640,7 @@ emit_DrawArrays_old( GLenum mode, GLint first, GLsizei count )
 
     GLubyte * pc;
     size_t elements_per_request;
-    size_t total_requests = 0;
+    unsigned total_requests = 0;
     unsigned i;
     size_t total_sent = 0;
 
@@ -770,9 +770,10 @@ emit_DrawElements_old( GLenum mode, GLsizei count, GLenum type,
 
     GLubyte * pc;
     size_t elements_per_request;
-    size_t total_requests = 0;
+    unsigned total_requests = 0;
     unsigned i;
     unsigned req;
+    unsigned req_element=0;
 
 
     pc = emit_DrawArrays_header_old( gc, arrays, & elements_per_request,
@@ -790,7 +791,7 @@ emit_DrawElements_old( GLenum mode, GLsizei count, GLenum type,
 
 	switch( type ) {
 	case GL_UNSIGNED_INT: {
-	    const GLuint   * ui_ptr = (const GLuint   *) indices;
+	    const GLuint   * ui_ptr = (const GLuint   *) indices + req_element;
 
 	    for ( i = 0 ; i < elements_per_request ; i++ ) {
 		const GLint index = (GLint) *(ui_ptr++);
@@ -799,7 +800,7 @@ emit_DrawElements_old( GLenum mode, GLsizei count, GLenum type,
 	    break;
 	}
 	case GL_UNSIGNED_SHORT: {
-	    const GLushort * us_ptr = (const GLushort *) indices;
+	    const GLushort * us_ptr = (const GLushort *) indices + req_element;
 
 	    for ( i = 0 ; i < elements_per_request ; i++ ) {
 		const GLint index = (GLint) *(us_ptr++);
@@ -808,7 +809,7 @@ emit_DrawElements_old( GLenum mode, GLsizei count, GLenum type,
 	    break;
 	}
 	case GL_UNSIGNED_BYTE: {
-	    const GLubyte  * ub_ptr = (const GLubyte  *) indices;
+	    const GLubyte  * ub_ptr = (const GLubyte  *) indices + req_element;
 
 	    for ( i = 0 ; i < elements_per_request ; i++ ) {
 		const GLint index = (GLint) *(ub_ptr++);
@@ -826,6 +827,7 @@ emit_DrawElements_old( GLenum mode, GLsizei count, GLenum type,
 	}
 
 	count -= elements_per_request;
+	req_element += elements_per_request;
     }
 
 
diff --git a/src/mesa/Makefile b/src/mesa/Makefile
index eadd7f2..9f3406a 100644
--- a/src/mesa/Makefile
+++ b/src/mesa/Makefile
@@ -65,7 +65,7 @@ linux-solo: depend subdirs libmesa.a
 # Stand-alone Mesa libGL, no built-in drivers (DirectFB)
 
 libgl-core: $(CORE_OBJECTS)
-	@ $(TOP)/bin/mklib -o $(GL_LIB) -linker '$(CC)' \
+	@ $(TOP)/bin/mklib -o $(GL_LIB) -linker '$(CC)' -ldflags '$(LDFLAGS) \
 		-major $(MESA_MAJOR) -minor $(MESA_MINOR) -patch $(MESA_TINY) \
 		-install $(TOP)/$(LIB_DIR) $(MKLIB_OPTIONS) $(CORE_OBJECTS) \
 		$(GL_LIB_DEPS)
@@ -78,7 +78,7 @@ directfb: depend subdirs libgl-core
 # fbdev Mesa driver (libGL.so)
 
 fbdev: $(CORE_OBJECTS) $(FBDEV_DRIVER_OBJECTS) $(COMMON_DRIVER_OBJECTS)
-	@ $(TOP)/bin/mklib -o $(GL_LIB) -linker '$(CC)' \
+	@ $(TOP)/bin/mklib -o $(GL_LIB) -linker '$(CC)' -ldflags '$(LDFLAGS)' \
 		-major $(MESA_MAJOR) -minor $(MESA_MINOR) -patch $(MESA_TINY) \
 		-install $(TOP)/$(LIB_DIR) $(MKLIB_OPTIONS) \
 		$(CORE_OBJECTS) $(FBDEV_DRIVER_OBJECTS) \
@@ -111,7 +111,7 @@ osmesa-only: depend subdirs $(TOP)/$(LIB_DIR)/$(OSMESA_LIB_NAME)
 
 # Make the GL library
 $(TOP)/$(LIB_DIR)/$(GL_LIB_NAME): $(STAND_ALONE_OBJECTS)
-	@ $(TOP)/bin/mklib -o $(GL_LIB) -linker '$(CC)' \
+	@ $(TOP)/bin/mklib -o $(GL_LIB) -linker '$(CC)' -ldflags '$(LDFLAGS)' \
 		-major $(GL_MAJOR) -minor $(GL_MINOR) -patch $(GL_TINY) \
 		-install $(TOP)/$(LIB_DIR) \
 		$(MKLIB_OPTIONS) $(GL_LIB_DEPS) $(STAND_ALONE_OBJECTS)
@@ -121,11 +121,13 @@ $(TOP)/$(LIB_DIR)/$(GL_LIB_NAME): $(STAND_ALONE_OBJECTS)
 $(TOP)/$(LIB_DIR)/$(OSMESA_LIB_NAME): $(OSMESA_DRIVER_OBJECTS) $(OSMESA16_OBJECTS)
 	@ if [ "${DRIVER_DIRS}" = "osmesa" ] ; then \
 		$(TOP)/bin/mklib -o $(OSMESA_LIB) -linker '$(CC)' \
+			-ldflags '$(LDFLAGS)' \
 			-major 6 -minor 5 -patch 3 \
 			-install $(TOP)/$(LIB_DIR) $(MKLIB_OPTIONS) \
 			$(OSMESA_LIB_DEPS) $(OSMESA16_OBJECTS) ; \
 	else \
 		$(TOP)/bin/mklib -o $(OSMESA_LIB) -linker '$(CC)' \
+			-ldflags '$(LDFLAGS)' \
 			-major 6 -minor 5 -patch 3 \
 			-install $(TOP)/$(LIB_DIR) $(MKLIB_OPTIONS) \
 			$(OSMESA_LIB_DEPS) $(OSMESA_DRIVER_OBJECTS) ; \
@@ -133,6 +135,15 @@ $(TOP)/$(LIB_DIR)/$(OSMESA_LIB_NAME): $(OSMESA_DRIVER_OBJECTS) $(OSMESA16_OBJECT
 
 
 ######################################################################
+# libGL pkg-config file
+pcedit = sed \
+	-e 's,@INSTALL_DIR@,$(INSTALL_DIR),' \
+	-e 's,@LIB_DIR@,$(LIB_DIR),' \
+	-e 's,@VERSION@,$(MESA_MAJOR).$(MESA_MINOR).$(MESA_TINY),'
+gl.pc: gl.pc.in
+	$(pcedit) $< > $@
+
+######################################################################
 # Generic stuff
 
 depend: $(ALL_SOURCES)
@@ -147,23 +158,25 @@ subdirs:
 	@ (cd x86-64 ; $(MAKE))
 
 
-install: default
-	$(INSTALL) -d $(INSTALL_DIR)/include/GL
-	$(INSTALL) -d $(INSTALL_DIR)/$(LIB_DIR)
-	$(INSTALL) -m 644 $(TOP)/include/GL/*.h $(INSTALL_DIR)/include/GL
+install: default gl.pc
+	$(INSTALL) -d $(DESTDIR)$(INSTALL_DIR)/include/GL
+	$(INSTALL) -d $(DESTDIR)$(INSTALL_DIR)/$(LIB_DIR)
+	$(INSTALL) -d $(DESTDIR)$(INSTALL_DIR)/$(LIB_DIR)/pkgconfig
+	$(INSTALL) -m 644 $(TOP)/include/GL/*.h $(DESTDIR)$(INSTALL_DIR)/include/GL
 	@if [ -e $(TOP)/$(LIB_DIR)/$(GL_LIB_NAME) ]; then \
-		$(INSTALL) $(TOP)/$(LIB_DIR)/libGL* $(INSTALL_DIR)/$(LIB_DIR); \
+		$(INSTALL) $(TOP)/$(LIB_DIR)/libGL* $(DESTDIR)$(INSTALL_DIR)/$(LIB_DIR); \
 	fi
+	$(INSTALL) -m 644 gl.pc $(DESTDIR)$(INSTALL_DIR)/$(LIB_DIR)/pkgconfig
 	@if [ -e $(TOP)/$(LIB_DIR)/$(OSMESA_LIB_NAME) ]; then \
-		$(INSTALL) $(TOP)/$(LIB_DIR)/libOSMesa* $(INSTALL_DIR)/$(LIB_DIR); \
+		$(INSTALL) $(TOP)/$(LIB_DIR)/libOSMesa* $(DESTDIR)$(INSTALL_DIR)/$(LIB_DIR); \
 	fi
 	@if [ "${DRIVER_DIRS}" = "dri" ] ; then \
 		cd drivers/dri ; $(MAKE) install ; \
 	fi
 
 ## NOT INSTALLED YET:
-## $(INSTALL) -d $(INSTALL_DIR)/include/GLES
-## $(INSTALL) -m 644 include/GLES/*.h $(INSTALL_DIR)/include/GLES
+## $(INSTALL) -d $(DESTDIR)$(INSTALL_DIR)/include/GLES
+## $(INSTALL) -m 644 include/GLES/*.h $(DESTDIR)$(INSTALL_DIR)/include/GLES
 
 
 # Emacs tags
diff --git a/src/mesa/drivers/beos/Makefile b/src/mesa/drivers/beos/Makefile
index 1897d6a..9c7d6af 100644
--- a/src/mesa/drivers/beos/Makefile
+++ b/src/mesa/drivers/beos/Makefile
@@ -179,7 +179,8 @@ $(TOP)/$(LIB_DIR):
 	mkdir $(TOP)/$(LIB_DIR)
 
 $(TOP)/$(LIB_DIR)/$(GL_LIB_NAME): $(OBJECTS) $(MESA_MODULES) $(GLU_MODULES)
-	@$(TOP)/bin/mklib -o $(GL_LIB) -install $(TOP)/$(LIB_DIR) -major $(MESA_MAJOR) -minor $(MESA_MINOR) -patch $(MESA_TINY) \
+	@$(TOP)/bin/mklib -o $(GL_LIB) -ldflags '$(LDFLAGS)' -install $(TOP)/$(LIB_DIR) \
+		-major $(MESA_MAJOR) -minor $(MESA_MINOR) -patch $(MESA_TINY) \
 		$(MKLIB_OPTIONS) $(GL_LIB_DEPS) $(OBJECTS) $(MESA_MODULES) $(GLU_MODULES)
 
 # $(GLU_OBJECTS):
diff --git a/src/mesa/drivers/dri/Makefile.template b/src/mesa/drivers/dri/Makefile.template
index 6f2314e..9e84dbc 100644
--- a/src/mesa/drivers/dri/Makefile.template
+++ b/src/mesa/drivers/dri/Makefile.template
@@ -74,7 +74,7 @@ default: depend symlinks $(LIBNAME) $(TOP)/$(LIB_DIR)/$(LIBNAME)
 
 
 $(LIBNAME): $(OBJECTS) $(MESA_MODULES) $(WINOBJ) Makefile $(TOP)/src/mesa/drivers/dri/Makefile.template
-	$(TOP)/bin/mklib -noprefix -o $@ \
+	$(TOP)/bin/mklib -ldflags '$(LDFLAGS)' -noprefix -o $@ \
 		$(OBJECTS) $(MESA_MODULES) $(WINOBJ) $(DRI_LIB_DEPS)
 
 
@@ -100,8 +100,8 @@ clean:
 
 
 install: $(LIBNAME)
-	$(INSTALL) -d $(DRI_DRIVER_INSTALL_DIR)
-	$(INSTALL) -m 755 $(LIBNAME) $(DRI_DRIVER_INSTALL_DIR)
+	$(INSTALL) -d $(DESTDIR)$(DRI_DRIVER_INSTALL_DIR)
+	$(INSTALL) -m 755 $(LIBNAME) $(DESTDIR)$(DRI_DRIVER_INSTALL_DIR)
 
 
 include depend
diff --git a/src/mesa/drivers/dri/common/spantmp2.h b/src/mesa/drivers/dri/common/spantmp2.h
index 50f3cf5..53f5f84 100644
--- a/src/mesa/drivers/dri/common/spantmp2.h
+++ b/src/mesa/drivers/dri/common/spantmp2.h
@@ -114,7 +114,7 @@
     do {                                                                \
         GLuint p = *(volatile GLuint *) GET_PTR(_x, _y);                \
        __asm__ __volatile__( "bswap	%0; rorl $8, %0"                \
-				: "=r" (p) : "r" (p) );                 \
+				: "=r" (p) : "0" (p) );                 \
        ((GLuint *)rgba)[0] = p;                                         \
     } while (0)
 # elif defined( MESA_BIG_ENDIAN )
diff --git a/src/mesa/drivers/dri/glcore/Makefile b/src/mesa/drivers/dri/glcore/Makefile
index a9e9697..968190a 100644
--- a/src/mesa/drivers/dri/glcore/Makefile
+++ b/src/mesa/drivers/dri/glcore/Makefile
@@ -61,7 +61,8 @@ default: depend $(TOP)/$(LIB_DIR)/$(LIBNAME)
 
 
 $(TOP)/$(LIB_DIR)/$(LIBNAME): $(OBJECTS) $(MESA_MODULES) $(WINOBJ) Makefile
-	CC="$(CC)" CXX="$(CXX)" $(TOP)/bin/mklib -o $(LIBNAME) -noprefix -install $(TOP)/$(LIB_DIR) \
+	CC="$(CC)" CXX="$(CXX)" $(TOP)/bin/mklib -o $(LIBNAME) -noprefix \
+		-ldflags '$(LDFLAGS)' -install $(TOP)/$(LIB_DIR) \
 		$(OBJECTS) $(WINLIB) $(LIB_DEPS) $(WINOBJ) $(MESA_MODULES)
 
 
diff --git a/src/mesa/drivers/dri/i810/i810screen.c b/src/mesa/drivers/dri/i810/i810screen.c
index f64c10a..f8cf050 100644
--- a/src/mesa/drivers/dri/i810/i810screen.c
+++ b/src/mesa/drivers/dri/i810/i810screen.c
@@ -288,8 +288,8 @@ i810InitDriver(__DRIscreenPrivate *sPriv)
 	      i810Screen->depth.handle,
 	      i810Screen->depth.size,
 	      (drmAddress *)&i810Screen->depth.map) != 0) {
-      FREE(i810Screen);
       drmUnmap(i810Screen->back.map, i810Screen->back.size);
+      FREE(i810Screen);
       sPriv->private = NULL;
       __driUtilMessage("i810InitDriver: drmMap (2) failed");
       return GL_FALSE;
diff --git a/src/mesa/drivers/dri/i915/i915_texstate.c b/src/mesa/drivers/dri/i915/i915_texstate.c
index 9f0c949..a19d4b6 100644
--- a/src/mesa/drivers/dri/i915/i915_texstate.c
+++ b/src/mesa/drivers/dri/i915/i915_texstate.c
@@ -491,12 +491,19 @@ static void i915SetTexImages( i915ContextPtr i915,
       abort();
    }
 
-
-   if (i915->intel.intelScreen->deviceID == PCI_CHIP_I945_G ||
-       i915->intel.intelScreen->deviceID == PCI_CHIP_I945_GM)
-      i945LayoutTextureImages( i915, tObj );	 
-   else
-      i915LayoutTextureImages( i915, tObj );
+   switch (i915->intel.intelScreen->deviceID) {
+   case PCI_CHIP_I945_G:
+   case PCI_CHIP_I945_GM:
+   case PCI_CHIP_I945_GME:
+   case PCI_CHIP_G33_G:
+   case PCI_CHIP_Q33_G:
+   case PCI_CHIP_Q35_G:
+       i945LayoutTextureImages( i915, tObj );
+       break;
+   default:
+       i915LayoutTextureImages( i915, tObj );
+       break;
+   }
 
    t->Setup[I915_TEXREG_MS3] = 
       (((tObj->Image[0][t->intel.base.firstLevel]->Height - 1) << MS3_HEIGHT_SHIFT) |
diff --git a/src/mesa/drivers/dri/i915/intel_context.c b/src/mesa/drivers/dri/i915/intel_context.c
index e1e7cdb..bb5ce64 100644
--- a/src/mesa/drivers/dri/i915/intel_context.c
+++ b/src/mesa/drivers/dri/i915/intel_context.c
@@ -123,6 +123,14 @@ const GLubyte *intelGetString( GLcontext *ctx, GLenum name )
 	 chipset = "Intel(R) 945G"; break;
       case PCI_CHIP_I945_GM:
 	 chipset = "Intel(R) 945GM"; break;
+      case PCI_CHIP_I945_GME:
+	 chipset = "Intel(R) 945GME"; break;
+      case PCI_CHIP_G33_G:
+	 chipset = "Intel(R) G33"; break;
+      case PCI_CHIP_Q35_G:
+	 chipset = "Intel(R) Q35"; break;
+      case PCI_CHIP_Q33_G:
+	 chipset = "Intel(R) Q33"; break;
       default:
 	 chipset = "Unknown Intel Chipset"; break;
       }
diff --git a/src/mesa/drivers/dri/i915/intel_context.h b/src/mesa/drivers/dri/i915/intel_context.h
index 05195e7..50e6178 100644
--- a/src/mesa/drivers/dri/i915/intel_context.h
+++ b/src/mesa/drivers/dri/i915/intel_context.h
@@ -454,6 +454,10 @@ extern int INTEL_DEBUG;
 #define PCI_CHIP_I915_GM		0x2592
 #define PCI_CHIP_I945_G			0x2772
 #define PCI_CHIP_I945_GM		0x27A2
+#define PCI_CHIP_I945_GME		0x27AE
+#define PCI_CHIP_G33_G			0x29C2
+#define PCI_CHIP_Q35_G			0x29B2
+#define PCI_CHIP_Q33_G			0x29D2
 
 
 /* ================================================================
diff --git a/src/mesa/drivers/dri/i915/intel_screen.c b/src/mesa/drivers/dri/i915/intel_screen.c
index 67e176a..ca8610b 100644
--- a/src/mesa/drivers/dri/i915/intel_screen.c
+++ b/src/mesa/drivers/dri/i915/intel_screen.c
@@ -514,6 +514,10 @@ static GLboolean intelCreateContext( const __GLcontextModes *mesaVis,
    case PCI_CHIP_I915_GM:
    case PCI_CHIP_I945_G:
    case PCI_CHIP_I945_GM:
+   case PCI_CHIP_I945_GME:
+   case PCI_CHIP_G33_G:
+   case PCI_CHIP_Q35_G:
+   case PCI_CHIP_Q33_G:
       return i915CreateContext( mesaVis, driContextPriv, 
 			       sharedContextPrivate );
  
diff --git a/src/mesa/drivers/dri/i915/intel_tex.c b/src/mesa/drivers/dri/i915/intel_tex.c
index 98ddc79..5bd2806 100644
--- a/src/mesa/drivers/dri/i915/intel_tex.c
+++ b/src/mesa/drivers/dri/i915/intel_tex.c
@@ -677,7 +677,11 @@ static void intelUploadTexImage( intelContextPtr intel,
    /* Time for another vtbl entry:
     */
    else if (intel->intelScreen->deviceID == PCI_CHIP_I945_G ||
-            intel->intelScreen->deviceID == PCI_CHIP_I945_GM) {
+            intel->intelScreen->deviceID == PCI_CHIP_I945_GM ||
+            intel->intelScreen->deviceID == PCI_CHIP_I945_GME ||
+            intel->intelScreen->deviceID == PCI_CHIP_G33_G ||
+            intel->intelScreen->deviceID == PCI_CHIP_Q33_G ||
+            intel->intelScreen->deviceID == PCI_CHIP_Q35_G) {
       GLuint row_len = image->Width * image->TexFormat->TexelBytes;
       GLubyte *dst = (GLubyte *)(t->BufAddr + offset);
       GLubyte *src = (GLubyte *)image->Data;
diff --git a/src/mesa/drivers/dri/i915tex/i830_vtbl.c b/src/mesa/drivers/dri/i915tex/i830_vtbl.c
index e432648..5555b74 100644
--- a/src/mesa/drivers/dri/i915tex/i830_vtbl.c
+++ b/src/mesa/drivers/dri/i915tex/i830_vtbl.c
@@ -519,6 +519,16 @@ i830_emit_state(struct intel_context *intel)
 static void
 i830_destroy_context(struct intel_context *intel)
 {
+   GLuint i;
+   struct i830_context *i830 = i830_context(&intel->ctx);
+
+   for (i = 0; i < I830_TEX_UNITS; i++) {
+      if (i830->state.tex_buffer[i] != NULL) {
+	 driBOUnReference(i830->state.tex_buffer[i]);
+	 i830->state.tex_buffer[i] = NULL;
+      }
+   }
+
    _tnl_free_vertices(&intel->ctx);
 }
 
diff --git a/src/mesa/drivers/dri/i915tex/i915_metaops.c b/src/mesa/drivers/dri/i915tex/i915_metaops.c
index 3ab62bc..397ff75 100644
--- a/src/mesa/drivers/dri/i915tex/i915_metaops.c
+++ b/src/mesa/drivers/dri/i915tex/i915_metaops.c
@@ -95,7 +95,7 @@ meta_depth_replace(struct intel_context *intel)
    i915->meta.Ctx[I915_CTXREG_LIS6] |= (S6_DEPTH_TEST_ENABLE |
                                         S6_DEPTH_WRITE_ENABLE);
 
-   /* ctx->Driver.DepthFunc( ctx, GL_REPLACE )
+   /* ctx->Driver.DepthFunc( ctx, GL_ALWAYS )
     */
    i915->meta.Ctx[I915_CTXREG_LIS6] &= ~S6_DEPTH_TEST_FUNC_MASK;
    i915->meta.Ctx[I915_CTXREG_LIS6] |=
diff --git a/src/mesa/drivers/dri/i915tex/i915_tex_layout.c b/src/mesa/drivers/dri/i915tex/i915_tex_layout.c
index 9f40706..7b761a7 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);
 
 
diff --git a/src/mesa/drivers/dri/i915tex/i915_vtbl.c b/src/mesa/drivers/dri/i915tex/i915_vtbl.c
index ad333b4..e911fc4 100644
--- a/src/mesa/drivers/dri/i915tex/i915_vtbl.c
+++ b/src/mesa/drivers/dri/i915tex/i915_vtbl.c
@@ -430,6 +430,16 @@ i915_emit_state(struct intel_context *intel)
 static void
 i915_destroy_context(struct intel_context *intel)
 {
+   GLuint i;
+   struct i915_context *i915 = i915_context(&intel->ctx);
+
+   for (i = 0; i < I915_TEX_UNITS; i++) {
+      if (i915->state.tex_buffer[i] != NULL) {
+	 driBOUnReference(i915->state.tex_buffer[i]);
+	 i915->state.tex_buffer[i] = NULL;
+      }
+   }
+
    _tnl_free_vertices(&intel->ctx);
 }
 
diff --git a/src/mesa/drivers/dri/i915tex/intel_buffers.c b/src/mesa/drivers/dri/i915tex/intel_buffers.c
index 15d02f8..78fb720 100644
--- a/src/mesa/drivers/dri/i915tex/intel_buffers.c
+++ b/src/mesa/drivers/dri/i915tex/intel_buffers.c
@@ -1124,6 +1124,15 @@ intel_draw_buffer(GLcontext * ctx, struct gl_framebuffer *fb)
       ctx->Driver.Enable(ctx, GL_STENCIL_TEST, ctx->Stencil.Enabled);
    }
 
+   /*
+    * Update depth test state
+    */
+   if (ctx->Depth.Test && fb->Visual.depthBits > 0) {
+      ctx->Driver.Enable(ctx, GL_DEPTH_TEST, GL_TRUE);
+   }
+   else {
+      ctx->Driver.Enable(ctx, GL_DEPTH_TEST, GL_FALSE);
+   }
 
    /**
     ** Release old regions, reference new regions
diff --git a/src/mesa/drivers/dri/i915tex/intel_context.c b/src/mesa/drivers/dri/i915tex/intel_context.c
index 093b3b4..40ea756 100644
--- a/src/mesa/drivers/dri/i915tex/intel_context.c
+++ b/src/mesa/drivers/dri/i915tex/intel_context.c
@@ -130,6 +130,18 @@ intelGetString(GLcontext * ctx, GLenum name)
       case PCI_CHIP_I945_GM:
          chipset = "Intel(R) 945GM";
          break;
+      case PCI_CHIP_I945_GME:
+         chipset = "Intel(R) 945GME";
+         break;
+      case PCI_CHIP_G33_G:
+	 chipset = "Intel(R) G33";
+	 break;
+      case PCI_CHIP_Q35_G:
+	 chipset = "Intel(R) Q35";
+	 break;
+      case PCI_CHIP_Q33_G:
+	 chipset = "Intel(R) Q33";
+	 break;
       default:
          chipset = "Unknown Intel Chipset";
          break;
diff --git a/src/mesa/drivers/dri/i915tex/intel_context.h b/src/mesa/drivers/dri/i915tex/intel_context.h
index bcbbb12..5fc8eb3 100644
--- a/src/mesa/drivers/dri/i915tex/intel_context.h
+++ b/src/mesa/drivers/dri/i915tex/intel_context.h
@@ -385,6 +385,10 @@ extern int INTEL_DEBUG;
 #define PCI_CHIP_I915_GM		0x2592
 #define PCI_CHIP_I945_G			0x2772
 #define PCI_CHIP_I945_GM		0x27A2
+#define PCI_CHIP_I945_GME		0x27AE
+#define PCI_CHIP_G33_G			0x29C2
+#define PCI_CHIP_Q35_G			0x29B2
+#define PCI_CHIP_Q33_G			0x29D2
 
 
 /* ================================================================
diff --git a/src/mesa/drivers/dri/i915tex/intel_mipmap_tree.c b/src/mesa/drivers/dri/i915tex/intel_mipmap_tree.c
index 8e83028..564eb9e 100644
--- a/src/mesa/drivers/dri/i915tex/intel_mipmap_tree.c
+++ b/src/mesa/drivers/dri/i915tex/intel_mipmap_tree.c
@@ -79,6 +79,10 @@ intel_miptree_create(struct intel_context *intel,
    switch (intel->intelScreen->deviceID) {
    case PCI_CHIP_I945_G:
    case PCI_CHIP_I945_GM:
+   case PCI_CHIP_I945_GME:
+   case PCI_CHIP_G33_G:
+   case PCI_CHIP_Q33_G:
+   case PCI_CHIP_Q35_G:
       ok = i945_miptree_layout(mt);
       break;
    case PCI_CHIP_I915_G:
@@ -93,9 +97,28 @@ intel_miptree_create(struct intel_context *intel,
       break;
    }
 
-   if (ok)
+   if (ok) {
+      if (!mt->compressed) {
+	 /* XXX: Align pitch to multiple of 64 bytes for now to allow
+	  * render-to-texture to work in all cases. This should probably be
+	  * replaced at some point by some scheme to only do this when really
+	  * necessary.
+	  */
+	 mt->pitch = (mt->pitch * cpp + 63) & ~63;
+
+	 /* XXX: At least the i915 seems very upset when the pitch is a multiple
+	  * of 1024 and sometimes 512 bytes - performance can drop by several
+	  * times. Go to the next multiple of 64 for now.
+	  */
+	 if (!(mt->pitch & 511))
+	    mt->pitch += 64;
+
+	 mt->pitch /= cpp;
+      }
+
       mt->region = intel_region_alloc(intel->intelScreen,
                                       mt->cpp, mt->pitch, mt->total_height);
+   }
 
    if (!mt->region) {
       free(mt);
diff --git a/src/mesa/drivers/dri/i915tex/intel_screen.c b/src/mesa/drivers/dri/i915tex/intel_screen.c
index 5e6df81..2acdead 100644
--- a/src/mesa/drivers/dri/i915tex/intel_screen.c
+++ b/src/mesa/drivers/dri/i915tex/intel_screen.c
@@ -752,6 +752,10 @@ intelCreateContext(const __GLcontextModes * mesaVis,
    case PCI_CHIP_I915_GM:
    case PCI_CHIP_I945_G:
    case PCI_CHIP_I945_GM:
+   case PCI_CHIP_I945_GME:
+   case PCI_CHIP_G33_G:
+   case PCI_CHIP_Q35_G:
+   case PCI_CHIP_Q33_G:
       return i915CreateContext(mesaVis, driContextPriv, sharedContextPrivate);
 
    default:
diff --git a/src/mesa/drivers/dri/i965/brw_aub.c b/src/mesa/drivers/dri/i965/brw_aub.c
index f851a5b..c549f7a 100644
--- a/src/mesa/drivers/dri/i965/brw_aub.c
+++ b/src/mesa/drivers/dri/i965/brw_aub.c
@@ -80,7 +80,7 @@ static void init_aubfile( FILE *aub_file )
    fh.hour = (nr>>16) & 0xff;
    fh.comment_length = 0x0;   
 
-   if (fwrite(&fh, sizeof(fh), 1, aub_file) < 0) 
+   if (fwrite(&fh, sizeof(fh), 1, aub_file) < 1) 
       FAIL;
          
    /* Setup the GTT starting at main memory address zero (!):
@@ -96,12 +96,12 @@ static void init_aubfile( FILE *aub_file )
    bh.address = PGETBL_CTL;
    bh.length = 0x4;
 
-   if (fwrite(&bh, sizeof(bh), 1, aub_file) < 0) 
+   if (fwrite(&bh, sizeof(bh), 1, aub_file) < 1) 
       FAIL;
 
    data = 0x0 | PGETBL_ENABLED;
 
-   if (fwrite(&data, sizeof(data), 1, aub_file) < 0) 
+   if (fwrite(&data, sizeof(data), 1, aub_file) < 1) 
       FAIL;
 }
 
@@ -128,7 +128,7 @@ static void init_aub_gtt( struct brw_context *brw,
    bh.address =  start_offset / 4096 * 4;
    bh.length = size / 4096 * 4;
 
-   if (fwrite(&bh, sizeof(bh), 1, aub_file) < 0) 
+   if (fwrite(&bh, sizeof(bh), 1, aub_file) < 1) 
       FAIL;
 
    for (i = 0; i < size / 4096; i++) {
@@ -136,7 +136,7 @@ static void init_aub_gtt( struct brw_context *brw,
 
       brw->next_free_page += 4096;
 
-      if (fwrite(&data, sizeof(data), 1, aub_file) < 0) 
+      if (fwrite(&data, sizeof(data), 1, aub_file) < 1) 
 	 FAIL;
    }
 
@@ -149,10 +149,10 @@ static void write_block_header( FILE *aub_file,
 {
    sz = (sz + 3) & ~3;
 
-   if (fwrite(bh, sizeof(*bh), 1, aub_file) < 0) 
+   if (fwrite(bh, sizeof(*bh), 1, aub_file) < 1) 
       FAIL;
 
-   if (fwrite(data, sz, 1, aub_file) < 0) 
+   if (fwrite(data, sz, 1, aub_file) < 1) 
       FAIL;
 
    fflush(aub_file);
@@ -162,7 +162,7 @@ static void write_block_header( FILE *aub_file,
 static void write_dump_bmp( FILE *aub_file,
 			    struct aub_dump_bmp *db )
 {
-   if (fwrite(db, sizeof(*db), 1, aub_file) < 0) 
+   if (fwrite(db, sizeof(*db), 1, aub_file) < 1) 
       FAIL;
 
    fflush(aub_file);
diff --git a/src/mesa/drivers/dri/i965/brw_clip.c b/src/mesa/drivers/dri/i965/brw_clip.c
index 3bec153..8287fd9 100644
--- a/src/mesa/drivers/dri/i965/brw_clip.c
+++ b/src/mesa/drivers/dri/i965/brw_clip.c
@@ -212,6 +212,10 @@ static void upload_clip_prog( struct brw_context *brw )
 	    }
 	 }
 
+    if (brw->attribs.Polygon->BackMode != GL_FILL ||
+        brw->attribs.Polygon->FrontMode != GL_FILL)
+        key.do_unfilled = 1;
+
 	 /* Most cases the fixed function units will handle.  Cases where
 	  * one or more polygon faces are unfilled will require help:
 	  */
diff --git a/src/mesa/drivers/dri/i965/brw_curbe.c b/src/mesa/drivers/dri/i965/brw_curbe.c
index 3f0aaa1..5bf0ed5 100644
--- a/src/mesa/drivers/dri/i965/brw_curbe.c
+++ b/src/mesa/drivers/dri/i965/brw_curbe.c
@@ -90,7 +90,7 @@ static void calculate_curbe_offsets( struct brw_context *brw )
     */
    if (nr_fp_regs > brw->curbe.wm_size ||
        nr_vp_regs > brw->curbe.vs_size ||
-       nr_clip_regs > brw->curbe.clip_size ||
+       nr_clip_regs != brw->curbe.clip_size ||
        (total_regs < brw->curbe.total_size / 4 &&
 	brw->curbe.total_size > 16)) {
 
diff --git a/src/mesa/drivers/dri/i965/brw_draw.c b/src/mesa/drivers/dri/i965/brw_draw.c
index c7798b1..f796472 100644
--- a/src/mesa/drivers/dri/i965/brw_draw.c
+++ b/src/mesa/drivers/dri/i965/brw_draw.c
@@ -330,6 +330,7 @@ static GLboolean brw_try_draw_prims( GLcontext *ctx,
       else {
 	 /* Otherwise, explicitly do the cliprects at this point:
 	  */
+          GLuint nprims = 0;
 	 for (j = 0; j < brw->intel.numClipRects; j++) {
 	    brw_emit_cliprect(brw, &brw->intel.pClipRects[j]);
 
@@ -337,6 +338,11 @@ static GLboolean brw_try_draw_prims( GLcontext *ctx,
 	     */
 	    for (i = 0; i < nr_prims; i++) {
 	       brw_emit_prim(brw, &prim[i]);   
+
+          if (++nprims == VBO_MAX_PRIM) {
+              intel_batchbuffer_flush(brw->intel.batch);
+              nprims = 0;
+          }
 	    }
 	 }
       }
diff --git a/src/mesa/drivers/dri/i965/brw_sf_emit.c b/src/mesa/drivers/dri/i965/brw_sf_emit.c
index cbaf018..2ea9816 100644
--- a/src/mesa/drivers/dri/i965/brw_sf_emit.c
+++ b/src/mesa/drivers/dri/i965/brw_sf_emit.c
@@ -582,7 +582,9 @@ void brw_emit_anyprim_setup( struct brw_sf_compile *c )
 					       (1<<_3DPRIM_TRIFAN_NOSTIPPLE)));
    jmp = brw_JMPI(p, ip, ip, brw_imm_w(0));
    {
+      brw_push_insn_state(p);
       brw_emit_tri_setup( c );
+      brw_pop_insn_state(p);
       /* note - thread killed in subroutine */
    }
    brw_land_fwd_jump(p, jmp);
@@ -596,7 +598,9 @@ void brw_emit_anyprim_setup( struct brw_sf_compile *c )
 					       (1<<_3DPRIM_LINESTRIP_CONT_BF)));
    jmp = brw_JMPI(p, ip, ip, brw_imm_w(0));
    {
+      brw_push_insn_state(p); 
       brw_emit_line_setup( c );
+      brw_pop_insn_state(p);
       /* note - thread killed in subroutine */
    }
    brw_land_fwd_jump(p, jmp); 
diff --git a/src/mesa/drivers/dri/i965/brw_vs_tnl.c b/src/mesa/drivers/dri/i965/brw_vs_tnl.c
index 35adc48..14483b3 100644
--- a/src/mesa/drivers/dri/i965/brw_vs_tnl.c
+++ b/src/mesa/drivers/dri/i965/brw_vs_tnl.c
@@ -1000,13 +1000,19 @@ static void build_lighting( struct tnl_program *p )
 					       STATE_POSITION); 
 	    struct ureg V = get_eye_position(p);
 	    struct ureg dist = get_temp(p);
+       struct ureg tmpPpli = get_temp(p);
 
 	    VPpli = get_temp(p); 
 	    half = get_temp(p);
- 
+
+       /* In homogeneous object coordinates
+        */
+       emit_op1(p, OPCODE_RCP, dist, 0, swizzle1(Ppli, W));
+       emit_op2(p, OPCODE_MUL, tmpPpli, 0, Ppli, dist);
+
 	    /* Calulate VPpli vector
 	     */
-	    emit_op2(p, OPCODE_SUB, VPpli, 0, Ppli, V); 
+	    emit_op2(p, OPCODE_SUB, VPpli, 0, tmpPpli, V); 
 
 	    /* Normalize VPpli.  The dist value also used in
 	     * attenuation below.
@@ -1038,6 +1044,7 @@ static void build_lighting( struct tnl_program *p )
 	    emit_normalize_vec3(p, half, half);
 
 	    release_temp(p, dist);
+       release_temp(p, tmpPpli);
 	 }
 
 	 /* Calculate dot products:
diff --git a/src/mesa/drivers/dri/i965/brw_wm_fp.c b/src/mesa/drivers/dri/i965/brw_wm_fp.c
index ff97d87..dc57fd2 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_fp.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_fp.c
@@ -525,7 +525,57 @@ static void precalc_tex( struct brw_wm_compile *c,
    struct prog_src_register coord;
    struct prog_dst_register tmpcoord;
 
-   if (inst->TexSrcTarget == TEXTURE_RECT_INDEX) {
+   if (inst->TexSrcTarget == TEXTURE_CUBE_INDEX) {
+       struct prog_instruction *out;
+       struct prog_dst_register tmp0 = get_temp(c);
+       struct prog_src_register tmp0src = src_reg_from_dst(tmp0);
+       struct prog_dst_register tmp1 = get_temp(c);
+       struct prog_src_register tmp1src = src_reg_from_dst(tmp1);
+       struct prog_src_register src0 = inst->SrcReg[0];
+
+       tmpcoord = get_temp(c);
+       coord = src_reg_from_dst(tmpcoord);
+
+       out = emit_op(c, OPCODE_MOV,
+                     tmpcoord,
+                     0, 0, 0,
+                     src0,
+                     src_undef(),
+                     src_undef());
+       out->SrcReg[0].NegateBase = 0;
+       out->SrcReg[0].Abs = 1;
+
+       emit_op(c, OPCODE_MAX,
+               tmp0,
+               0, 0, 0,
+               src_swizzle1(coord, X),
+               src_swizzle1(coord, Y),
+               src_undef());
+
+       emit_op(c, OPCODE_MAX,
+               tmp1,
+               0, 0, 0,
+               tmp0src,
+               src_swizzle1(coord, Z),
+               src_undef());
+
+       emit_op(c, OPCODE_RCP,
+               tmp0,
+               0, 0, 0,
+               tmp1src,
+               src_undef(),
+               src_undef());
+
+       emit_op(c, OPCODE_MUL,
+               tmpcoord,
+               0, 0, 0,
+               src0,
+               tmp0src,
+               src_undef());
+
+       release_temp(c, tmp0);
+       release_temp(c, tmp1);
+   } else if (inst->TexSrcTarget == TEXTURE_RECT_INDEX) {
       struct prog_src_register scale = 
 	 search_or_add_param5( c, 
 			       STATE_INTERNAL, 
diff --git a/src/mesa/drivers/dri/i965/brw_wm_sampler_state.c b/src/mesa/drivers/dri/i965/brw_wm_sampler_state.c
index 93d4cfc..794c7d9 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_sampler_state.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_sampler_state.c
@@ -173,12 +173,12 @@ static void brw_update_sampler_state( struct gl_texture_unit *texUnit,
        * message (sample_c).  So need to recompile WM program when
        * shadow comparison is enabled on each/any texture unit.
        */
-      sampler->ss0.shadow_function = intel_translate_compare_func(texObj->CompareFunc);
+      sampler->ss0.shadow_function = intel_translate_shadow_compare_func(texObj->CompareFunc);
    }
 
    /* Set LOD bias: 
     */
-   sampler->ss0.lod_bias = S_FIXED(texUnit->LodBias + texObj->LodBias, 6);
+   sampler->ss0.lod_bias = S_FIXED(CLAMP(texUnit->LodBias + texObj->LodBias, -16, 15), 6);
 
    sampler->ss0.lod_preclamp = 1; /* OpenGL mode */
    sampler->ss0.default_color_mode = 0; /* OpenGL/DX10 mode */
@@ -192,8 +192,8 @@ static void brw_update_sampler_state( struct gl_texture_unit *texUnit,
     */
    sampler->ss0.base_level = U_FIXED(0, 1);
 
-   sampler->ss1.max_lod = U_FIXED(MAX2(texObj->MaxLod, 0), 6);
-   sampler->ss1.min_lod = U_FIXED(MAX2(texObj->MinLod, 0), 6);
+   sampler->ss1.max_lod = U_FIXED(MIN2(MAX2(texObj->MaxLod, 0), 13), 6);
+   sampler->ss1.min_lod = U_FIXED(MIN2(MAX2(texObj->MinLod, 0), 13), 6);
    
    sampler->ss2.default_color_pointer = sdc_gs_offset >> 5;
 }
diff --git a/src/mesa/drivers/dri/i965/brw_wm_state.c b/src/mesa/drivers/dri/i965/brw_wm_state.c
index ff5cb31..5b4f2ab 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_state.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_state.c
@@ -117,7 +117,7 @@ static void upload_wm_unit(struct brw_context *brw )
    wm.thread1.floating_point_mode = BRW_FLOATING_POINT_NON_IEEE_754;
 
    /* CACHE_NEW_SAMPLER */
-   wm.wm4.sampler_count = brw->wm.sampler_count;
+   wm.wm4.sampler_count = (brw->wm.sampler_count + 1) / 4;
    wm.wm4.sampler_state_pointer = brw->wm.sampler_gs_offset >> 5;
 
    /* BRW_NEW_FRAGMENT_PROGRAM */
diff --git a/src/mesa/drivers/dri/i965/intel_buffers.c b/src/mesa/drivers/dri/i965/intel_buffers.c
index d155c03..de6a867 100644
--- a/src/mesa/drivers/dri/i965/intel_buffers.c
+++ b/src/mesa/drivers/dri/i965/intel_buffers.c
@@ -31,7 +31,9 @@
 #include "intel_regions.h"
 #include "intel_batchbuffer.h"
 #include "context.h"
+#include "utils.h"
 #include "framebuffer.h"
+#include "vblank.h"
 #include "macros.h"
 #include "swrast/swrast.h"
 
@@ -190,8 +192,40 @@ void intelWindowMoved( struct intel_context *intel )
       }
    }
 
+   {
+      if (intel->intelScreen->driScrnPriv->ddxMinor >= 7) {
+	 volatile drmI830Sarea *sarea = intel->sarea;
+	 drm_clip_rect_t drw_rect = { .x1 = dPriv->x, .x2 = dPriv->x + dPriv->w,
+				      .y1 = dPriv->y, .y2 = dPriv->y + dPriv->h 
+	 };
+	 drm_clip_rect_t pipeA_rect = { .x1 = sarea->pipeA_x,
+					.x2 = sarea->pipeA_x + sarea->pipeA_w,
+					.y1 = sarea->pipeA_y,
+                                        .y2 = sarea->pipeA_y + sarea->pipeA_h };
+         drm_clip_rect_t pipeB_rect = { .x1 = sarea->pipeB_x,
+                                        .x2 = sarea->pipeB_x + sarea->pipeB_w,
+                                        .y1 = sarea->pipeB_y,
+                                        .y2 = sarea->pipeB_y + sarea->pipeB_h };
+         GLint areaA = driIntersectArea( drw_rect, pipeA_rect );
+         GLint areaB = driIntersectArea( drw_rect, pipeB_rect );
+         GLuint flags = intel->vblank_flags;
+	 
+         if (areaB > areaA || (areaA > 0 && areaB > 0)) {
+            flags = intel->vblank_flags | VBLANK_FLAG_SECONDARY;
+         } else {
+            flags = intel->vblank_flags & ~VBLANK_FLAG_SECONDARY;
+         }
+	 
+         if (flags != intel->vblank_flags) {
+            intel->vblank_flags = flags;
+            driGetCurrentVBlank(dPriv, intel->vblank_flags, &intel->vbl_seq);
+         }
+      } else {
+         intel->vblank_flags &= ~VBLANK_FLAG_SECONDARY;
+      }
+   }
    _mesa_resize_framebuffer(&intel->ctx,
-			    (GLframebuffer*)dPriv->driverPrivate,
+   			    (GLframebuffer*)dPriv->driverPrivate,
 			    dPriv->w, dPriv->h);
 
    /* Set state we know depends on drawable parameters:
diff --git a/src/mesa/drivers/dri/i965/intel_context.c b/src/mesa/drivers/dri/i965/intel_context.c
index 10eb9a2..33efed4 100644
--- a/src/mesa/drivers/dri/i965/intel_context.c
+++ b/src/mesa/drivers/dri/i965/intel_context.c
@@ -262,7 +262,7 @@ intelBeginQuery(GLcontext *ctx, GLenum target, struct gl_query_object *q)
 	};
 	intel->stats_wm++;
 	intelFinish(&intel->ctx);
-	drmCommandRead(intel->driFd, DRM_I830_MMIO, &io, sizeof(io));
+	drmCommandWrite(intel->driFd, DRM_I830_MMIO, &io, sizeof(io));
 }
 
 static void
@@ -276,7 +276,7 @@ intelEndQuery(GLcontext *ctx, GLenum target, struct gl_query_object *q)
 		.data = &tmp
 	};
 	intelFinish(&intel->ctx);
-	drmCommandRead(intel->driFd, DRM_I830_MMIO, &io, sizeof(io));
+	drmCommandWrite(intel->driFd, DRM_I830_MMIO, &io, sizeof(io));
 	q->Result = tmp - q->Result;
 	q->Ready = GL_TRUE;
 	intel->stats_wm--;
@@ -487,7 +487,7 @@ GLboolean intelInitContext( struct intel_context *intel,
       _mesa_enable_extension( ctx, "GL_EXT_texture_compression_s3tc" );
       _mesa_enable_extension( ctx, "GL_S3_s3tc" );
    }
-   else if (driQueryOptionb (&intelScreen->optionCache, "force_s3tc_enable")) {
+   else if (driQueryOptionb (&intel->optionCache, "force_s3tc_enable")) {
       _mesa_enable_extension( ctx, "GL_EXT_texture_compression_s3tc" );
    }
 
@@ -567,6 +567,10 @@ GLboolean intelMakeCurrent(__DRIcontextPrivate *driContextPriv,
    if (driContextPriv) {
       struct intel_context *intel = (struct intel_context *) driContextPriv->driverPrivate;
 
+      if (intel->driReadDrawable != driReadPriv) {
+          intel->driReadDrawable = driReadPriv;
+      }
+
       if ( intel->driDrawable != driDrawPriv ) {
 	 /* Shouldn't the readbuffer be stored also? */
 	 driDrawableInitVBlank( driDrawPriv, intel->vblank_flags,
diff --git a/src/mesa/drivers/dri/i965/intel_context.h b/src/mesa/drivers/dri/i965/intel_context.h
index 808512f..9f69f23 100644
--- a/src/mesa/drivers/dri/i965/intel_context.h
+++ b/src/mesa/drivers/dri/i965/intel_context.h
@@ -234,6 +234,7 @@ struct intel_context
    int driFd;
 
    __DRIdrawablePrivate *driDrawable;
+   __DRIdrawablePrivate *driReadDrawable;
    __DRIscreenPrivate *driScreen;
    intelScreenPrivate *intelScreen; 
    volatile drmI830Sarea *sarea; 
@@ -463,7 +464,7 @@ extern void intelInitStateFuncs( struct dd_function_table *functions );
 #define BLENDFACT_INV_CONST_ALPHA	0x0f
 #define BLENDFACT_MASK          	0x0f
 
-
+extern int intel_translate_shadow_compare_func( GLenum func );
 extern int intel_translate_compare_func( GLenum func );
 extern int intel_translate_stencil_op( GLenum op );
 extern int intel_translate_blend_factor( GLenum factor );
diff --git a/src/mesa/drivers/dri/i965/intel_pixel_bitmap.c b/src/mesa/drivers/dri/i965/intel_pixel_bitmap.c
index 421fcc5..df9d688 100644
--- a/src/mesa/drivers/dri/i965/intel_pixel_bitmap.c
+++ b/src/mesa/drivers/dri/i965/intel_pixel_bitmap.c
@@ -168,12 +168,15 @@ do_blit_bitmap( GLcontext *ctx,
 {
    struct intel_context *intel = intel_context(ctx);
    struct intel_region *dst = intel_drawbuf_region(intel);
-   
+   GLfloat tmpColor[4];
+
    union {
       GLuint ui;
       GLubyte ub[4];
    } color;
 
+   if (!dst)
+       return GL_FALSE;
 
    if (unpack->BufferObj->Name) {
       bitmap = map_pbo(ctx, width, height, unpack, bitmap);
@@ -181,10 +184,16 @@ do_blit_bitmap( GLcontext *ctx,
 	 return GL_TRUE;	/* even though this is an error, we're done */
    }
 
-   UNCLAMPED_FLOAT_TO_CHAN(color.ub[0], ctx->Current.RasterColor[2]);
-   UNCLAMPED_FLOAT_TO_CHAN(color.ub[1], ctx->Current.RasterColor[1]);
-   UNCLAMPED_FLOAT_TO_CHAN(color.ub[2], ctx->Current.RasterColor[0]);
-   UNCLAMPED_FLOAT_TO_CHAN(color.ub[3], ctx->Current.RasterColor[3]);
+   COPY_4V(tmpColor, ctx->Current.RasterColor);
+
+   if (NEED_SECONDARY_COLOR(ctx)) {
+       ADD_3V(tmpColor, tmpColor, ctx->Current.RasterSecondaryColor);
+   }
+
+   UNCLAMPED_FLOAT_TO_CHAN(color.ub[0], tmpColor[2]);
+   UNCLAMPED_FLOAT_TO_CHAN(color.ub[1], tmpColor[1]);
+   UNCLAMPED_FLOAT_TO_CHAN(color.ub[2], tmpColor[0]);
+   UNCLAMPED_FLOAT_TO_CHAN(color.ub[3], tmpColor[3]);
 
    /* Does zoom apply to bitmaps?
     */
diff --git a/src/mesa/drivers/dri/i965/intel_pixel_copy.c b/src/mesa/drivers/dri/i965/intel_pixel_copy.c
index 58dc495..3bdf2fb 100644
--- a/src/mesa/drivers/dri/i965/intel_pixel_copy.c
+++ b/src/mesa/drivers/dri/i965/intel_pixel_copy.c
@@ -231,6 +231,7 @@ do_blit_copypixels(GLcontext * ctx,
 
    if (intel->driDrawable->numClipRects) {
       __DRIdrawablePrivate *dPriv = intel->driDrawable;
+      __DRIdrawablePrivate *dReadPriv = intel->driReadDrawable;
       drm_clip_rect_t *box = dPriv->pClipRects;
       drm_clip_rect_t dest_rect;
       GLint nbox = dPriv->numClipRects;
@@ -262,8 +263,8 @@ do_blit_copypixels(GLcontext * ctx,
       srcy = dPriv->h - srcy - height;  
       dstx += dPriv->x;
       dsty += dPriv->y;
-      srcx += dPriv->x;
-      srcy += dPriv->y;
+      srcx += dReadPriv->x;
+      srcy += dReadPriv->y;
 
       /* Clip against the source region.  This is the only source
        * clipping we do.  Dst is clipped with cliprects below.
diff --git a/src/mesa/drivers/dri/i965/intel_state.c b/src/mesa/drivers/dri/i965/intel_state.c
index ec6e046..701b30c 100644
--- a/src/mesa/drivers/dri/i965/intel_state.c
+++ b/src/mesa/drivers/dri/i965/intel_state.c
@@ -38,6 +38,31 @@
 #include "intel_regions.h"
 #include "swrast/swrast.h"
 
+int intel_translate_shadow_compare_func( GLenum func )
+{
+   switch(func) {
+   case GL_NEVER: 
+       return COMPAREFUNC_ALWAYS; 
+   case GL_LESS: 
+       return COMPAREFUNC_LEQUAL; 
+   case GL_LEQUAL: 
+       return COMPAREFUNC_LESS;
+   case GL_GREATER: 
+       return COMPAREFUNC_GEQUAL; 
+   case GL_GEQUAL: 
+      return COMPAREFUNC_GREATER; 
+   case GL_NOTEQUAL: 
+      return COMPAREFUNC_EQUAL; 
+   case GL_EQUAL: 
+      return COMPAREFUNC_NOTEQUAL; 
+   case GL_ALWAYS: 
+       return COMPAREFUNC_NEVER; 
+   }
+
+   fprintf(stderr, "Unknown value in %s: %x\n", __FUNCTION__, func);
+   return COMPAREFUNC_NEVER; 
+}
+
 int intel_translate_compare_func( GLenum func )
 {
    switch(func) {
diff --git a/src/mesa/drivers/dri/i965/server/i830_common.h b/src/mesa/drivers/dri/i965/server/i830_common.h
index f320378..fe2b8e8 100644
--- a/src/mesa/drivers/dri/i965/server/i830_common.h
+++ b/src/mesa/drivers/dri/i965/server/i830_common.h
@@ -119,6 +119,16 @@ typedef struct {
         unsigned int depth_tiled;
         unsigned int rotated_tiled;
         unsigned int rotated2_tiled;
+
+	int pipeA_x;
+	int pipeA_y;
+	int pipeA_w;
+	int pipeA_h;
+	int pipeB_x;
+	int pipeB_y;
+	int pipeB_w;
+	int pipeB_h;
+
 } drmI830Sarea;
 
 /* Flags for perf_boxes
diff --git a/src/mesa/drivers/dri/unichrome/via_context.c b/src/mesa/drivers/dri/unichrome/via_context.c
index 4d25d32..7c73877 100644
--- a/src/mesa/drivers/dri/unichrome/via_context.c
+++ b/src/mesa/drivers/dri/unichrome/via_context.c
@@ -733,14 +733,15 @@ void viaXMesaWindowMoved(struct via_context *vmesa)
 {
    __DRIdrawablePrivate *const drawable = vmesa->driDrawable;
    __DRIdrawablePrivate *const readable = vmesa->driReadable;
-   struct via_renderbuffer *const draw_buffer = 
-     (struct via_renderbuffer *) drawable->driverPrivate;
-   struct via_renderbuffer *const read_buffer =
-     (struct via_renderbuffer *) readable->driverPrivate;
+   struct via_renderbuffer * draw_buffer;
+   struct via_renderbuffer * read_buffer;
    GLuint bytePerPixel = vmesa->viaScreen->bitsPerPixel >> 3;
 
    if (!drawable)
       return;
+
+   draw_buffer =  (struct via_renderbuffer *) drawable->driverPrivate;
+   read_buffer =  (struct via_renderbuffer *) readable->driverPrivate;
    
    switch (vmesa->glCtx->DrawBuffer->_ColorDrawBufferMask[0]) {
    case BUFFER_BIT_BACK_LEFT: 
diff --git a/src/mesa/drivers/windows/gdi/wmesa.c b/src/mesa/drivers/windows/gdi/wmesa.c
index 5b67439..c1d26a3 100644
--- a/src/mesa/drivers/windows/gdi/wmesa.c
+++ b/src/mesa/drivers/windows/gdi/wmesa.c
@@ -458,23 +458,84 @@ static void write_rgba_span_front(const GLcontext *ctx,
 				   const GLubyte rgba[][4], 
 				   const GLubyte mask[] )
 {
-    WMesaContext pwc = wmesa_context(ctx);
-    GLuint i;
-    
-    (void) ctx;
-    y=FLIP(y);
-    if (mask) {
-	for (i=0; i<n; i++)
-	    if (mask[i])
-		SetPixel(pwc->hDC, x+i, y, RGB(rgba[i][RCOMP], rgba[i][GCOMP], 
-					       rgba[i][BCOMP]));
-    }
-    else {
-	for (i=0; i<n; i++)
-	    SetPixel(pwc->hDC, x+i, y, RGB(rgba[i][RCOMP], rgba[i][GCOMP], 
-					   rgba[i][BCOMP]));
-    }
-    
+   WMesaContext pwc = wmesa_context(ctx);
+   WMesaFramebuffer pwfb = wmesa_lookup_framebuffer(pwc->hDC);
+   CONST BITMAPINFO bmi=
+   {
+      {
+         sizeof(BITMAPINFOHEADER),
+         n, 1, 1, 32, BI_RGB, 0, 1, 1, 0, 0
+      }
+   };
+   HBITMAP bmp=0;
+   HDC mdc=0;
+   typedef union
+   {
+      unsigned i;
+      struct {
+         unsigned b:8, g:8, r:8, a:8;
+      };
+   } BGRA;
+   BGRA *bgra, c;
+   int i;
+
+   if (n < 16) {   // the value 16 is just guessed
+      y=FLIP(y);
+      if (mask) {
+         for (i=0; i<n; i++)
+            if (mask[i])
+               SetPixel(pwc->hDC, x+i, y,
+                        RGB(rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]));
+      }
+      else {
+         for (i=0; i<n; i++)
+            SetPixel(pwc->hDC, x+i, y,
+                     RGB(rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]));
+      }
+   }
+   else {
+      if (!pwfb) {
+         _mesa_problem(NULL, "wmesa: write_rgba_span_front on unknown hdc");
+         return;
+      }
+      bgra=malloc(n*sizeof(BGRA));
+      if (!bgra) {
+         _mesa_problem(NULL, "wmesa: write_rgba_span_front: out of memory");
+         return;
+      }
+      c.a=0;
+      if (mask) {
+         for (i=0; i<n; i++) {
+            if (mask[i]) {
+               c.r=rgba[i][RCOMP];
+               c.g=rgba[i][GCOMP];
+               c.b=rgba[i][BCOMP];
+               c.a=rgba[i][ACOMP];
+               bgra[i]=c;
+            }
+            else
+               bgra[i].i=0;
+         }
+      }
+      else {
+         for (i=0; i<n; i++) {
+            c.r=rgba[i][RCOMP];
+            c.g=rgba[i][GCOMP];
+            c.b=rgba[i][BCOMP];
+            c.a=rgba[i][ACOMP];
+            bgra[i]=c;
+         }
+      }
+      bmp=CreateBitmap(n, 1,  1, 32, bgra);
+      mdc=CreateCompatibleDC(pwfb->hDC);
+      SelectObject(mdc, bmp);
+      y=FLIP(y);
+      BitBlt(pwfb->hDC, x, y, n, 1, mdc, 0, 0, SRCCOPY);
+      SelectObject(mdc, 0);
+      DeleteObject(bmp);
+      DeleteDC(mdc);
+      free(bgra);
+   }
 }
 
 /* Write a horizontal span of RGB color pixels with a boolean mask. */
diff --git a/src/mesa/gl.pc.in b/src/mesa/gl.pc.in
new file mode 100644
index 0000000..4b144ff
--- /dev/null
+++ b/src/mesa/gl.pc.in
@@ -0,0 +1,11 @@
+prefix=@INSTALL_DIR@
+exec_prefix=${prefix}
+libdir=${exec_prefix}/@LIB_DIR@
+includedir=${prefix}/include
+
+Name: gl
+Description: Mesa OpenGL library
+Requires:
+Version: @VERSION@
+Libs: -L${libdir} -lGL
+Cflags: -I${includedir}
diff --git a/src/mesa/main/api_validate.c b/src/mesa/main/api_validate.c
index 841c6a5..4544843 100644
--- a/src/mesa/main/api_validate.c
+++ b/src/mesa/main/api_validate.c
@@ -1,6 +1,6 @@
 /*
  * Mesa 3-D graphics library
- * Version:  7.0.1
+ * Version:  7.0.2
  *
  * Copyright (C) 1999-2007  Brian Paul   All Rights Reserved.
  *
@@ -30,6 +30,55 @@
 #include "state.h"
 
 
+/**
+ * Find the max index in the given element/index buffer
+ */
+static GLuint
+max_buffer_index(GLcontext *ctx, GLuint count, GLenum type,
+                 const void *indices,
+                 struct gl_buffer_object *elementBuf)
+{
+   const GLubyte *map = NULL;
+   GLuint max = 0;
+   GLint i;
+
+   if (elementBuf->Name) {
+      /* elements are in a user-defined buffer object.  need to map it */
+      map = ctx->Driver.MapBuffer(ctx,
+                                  GL_ELEMENT_ARRAY_BUFFER_ARB,
+                                  GL_READ_ONLY,
+                                  elementBuf);
+      /* Actual address is the sum of pointers */
+      indices = (const GLvoid *) ADD_POINTERS(map, (const GLubyte *) indices);
+   }
+
+   if (type == GL_UNSIGNED_INT) {
+      for (i = 0; i < count; i++)
+         if (((GLuint *) indices)[i] > max)
+            max = ((GLuint *) indices)[i];
+   }
+   else if (type == GL_UNSIGNED_SHORT) {
+      for (i = 0; i < count; i++)
+         if (((GLushort *) indices)[i] > max)
+            max = ((GLushort *) indices)[i];
+   }
+   else {
+      ASSERT(type == GL_UNSIGNED_BYTE);
+      for (i = 0; i < count; i++)
+         if (((GLubyte *) indices)[i] > max)
+            max = ((GLubyte *) indices)[i];
+   }
+
+   if (map) {
+      ctx->Driver.UnmapBuffer(ctx,
+                              GL_ELEMENT_ARRAY_BUFFER_ARB,
+                              ctx->Array.ElementArrayBufferObj);
+   }
+
+   return max;
+}
+
+
 GLboolean
 _mesa_validate_DrawElements(GLcontext *ctx,
 			    GLenum mode, GLsizei count, GLenum type,
@@ -61,20 +110,15 @@ _mesa_validate_DrawElements(GLcontext *ctx,
 
    /* Always need vertex positions */
    if (!ctx->Array.ArrayObj->Vertex.Enabled
-       && !(ctx->VertexProgram._Enabled && ctx->Array.ArrayObj->VertexAttrib[0].Enabled))
+       && !(ctx->VertexProgram._Enabled
+            && ctx->Array.ArrayObj->VertexAttrib[0].Enabled))
       return GL_FALSE;
 
    /* Vertex buffer object tests */
    if (ctx->Array.ElementArrayBufferObj->Name) {
-      GLuint indexBytes;
-
       /* use indices in the buffer object */
-      if (!ctx->Array.ElementArrayBufferObj->Data) {
-         _mesa_warning(ctx, "DrawElements with empty vertex elements buffer!");
-         return GL_FALSE;
-      }
+      GLuint indexBytes;
 
-      /* make sure count doesn't go outside buffer bounds */
       if (type == GL_UNSIGNED_INT) {
          indexBytes = count * sizeof(GLuint);
       }
@@ -86,19 +130,11 @@ _mesa_validate_DrawElements(GLcontext *ctx,
          indexBytes = count * sizeof(GLushort);
       }
 
-      if ((GLubyte *) indices + indexBytes >
-          ctx->Array.ElementArrayBufferObj->Data +
-          ctx->Array.ElementArrayBufferObj->Size) {
+      /* make sure count doesn't go outside buffer bounds */
+      if (indexBytes > ctx->Array.ElementArrayBufferObj->Size) {
          _mesa_warning(ctx, "glDrawElements index out of buffer bounds");
          return GL_FALSE;
       }
-
-      /* Actual address is the sum of pointers.  Indices may be used below. */
-      if (ctx->Const.CheckArrayBounds) {
-         indices = (const GLvoid *)
-            ADD_POINTERS(ctx->Array.ElementArrayBufferObj->Data,
-                         (const GLubyte *) indices);
-      }
    }
    else {
       /* not using a VBO */
@@ -108,24 +144,8 @@ _mesa_validate_DrawElements(GLcontext *ctx,
 
    if (ctx->Const.CheckArrayBounds) {
       /* find max array index */
-      GLuint max = 0;
-      GLint i;
-      if (type == GL_UNSIGNED_INT) {
-         for (i = 0; i < count; i++)
-            if (((GLuint *) indices)[i] > max)
-               max = ((GLuint *) indices)[i];
-      }
-      else if (type == GL_UNSIGNED_SHORT) {
-         for (i = 0; i < count; i++)
-            if (((GLushort *) indices)[i] > max)
-               max = ((GLushort *) indices)[i];
-      }
-      else {
-         ASSERT(type == GL_UNSIGNED_BYTE);
-         for (i = 0; i < count; i++)
-            if (((GLubyte *) indices)[i] > max)
-               max = ((GLubyte *) indices)[i];
-      }
+      GLuint max = max_buffer_index(ctx, count, type, indices,
+                                    ctx->Array.ElementArrayBufferObj);
       if (max >= ctx->Array._MaxElement) {
          /* the max element is out of bounds of one or more enabled arrays */
          return GL_FALSE;
@@ -172,41 +192,41 @@ _mesa_validate_DrawRangeElements(GLcontext *ctx, GLenum mode,
 
    /* Always need vertex positions */
    if (!ctx->Array.ArrayObj->Vertex.Enabled
-       && !(ctx->VertexProgram._Enabled && ctx->Array.ArrayObj->VertexAttrib[0].Enabled))
+       && !(ctx->VertexProgram._Enabled
+            && ctx->Array.ArrayObj->VertexAttrib[0].Enabled))
       return GL_FALSE;
 
    /* Vertex buffer object tests */
    if (ctx->Array.ElementArrayBufferObj->Name) {
-      /* XXX re-use code from above? */
+      /* use indices in the buffer object */
+      GLuint indexBytes;
+
+      if (type == GL_UNSIGNED_INT) {
+         indexBytes = count * sizeof(GLuint);
+      }
+      else if (type == GL_UNSIGNED_BYTE) {
+         indexBytes = count * sizeof(GLubyte);
+      }
+      else {
+         ASSERT(type == GL_UNSIGNED_SHORT);
+         indexBytes = count * sizeof(GLushort);
+      }
+
+      /* make sure count doesn't go outside buffer bounds */
+      if (indexBytes > ctx->Array.ElementArrayBufferObj->Size) {
+         _mesa_warning(ctx, "glDrawRangeElements index out of buffer bounds");
+         return GL_FALSE;
+      }
    }
    else {
-      /* not using VBO */
+      /* not using a VBO */
       if (!indices)
          return GL_FALSE;
    }
 
    if (ctx->Const.CheckArrayBounds) {
-      /* Find max array index.
-       * We don't trust the user's start and end values.
-       */
-      GLuint max = 0;
-      GLint i;
-      if (type == GL_UNSIGNED_INT) {
-         for (i = 0; i < count; i++)
-            if (((GLuint *) indices)[i] > max)
-               max = ((GLuint *) indices)[i];
-      }
-      else if (type == GL_UNSIGNED_SHORT) {
-         for (i = 0; i < count; i++)
-            if (((GLushort *) indices)[i] > max)
-               max = ((GLushort *) indices)[i];
-      }
-      else {
-         ASSERT(type == GL_UNSIGNED_BYTE);
-         for (i = 0; i < count; i++)
-            if (((GLubyte *) indices)[i] > max)
-               max = ((GLubyte *) indices)[i];
-      }
+      GLuint max = max_buffer_index(ctx, count, type, indices,
+                                    ctx->Array.ElementArrayBufferObj);
       if (max >= ctx->Array._MaxElement) {
          /* the max element is out of bounds of one or more enabled arrays */
          return GL_FALSE;
@@ -241,7 +261,8 @@ _mesa_validate_DrawArrays(GLcontext *ctx,
       _mesa_update_state(ctx);
 
    /* Always need vertex positions */
-   if (!ctx->Array.ArrayObj->Vertex.Enabled && !ctx->Array.ArrayObj->VertexAttrib[0].Enabled)
+   if (!ctx->Array.ArrayObj->Vertex.Enabled
+       && !ctx->Array.ArrayObj->VertexAttrib[0].Enabled)
       return GL_FALSE;
 
    if (ctx->Const.CheckArrayBounds) {
diff --git a/src/mesa/main/attrib.c b/src/mesa/main/attrib.c
index 0b821cf..427a6b0 100644
--- a/src/mesa/main/attrib.c
+++ b/src/mesa/main/attrib.c
@@ -1,6 +1,6 @@
 /*
  * Mesa 3-D graphics library
- * Version:  6.5.3
+ * Version:  7.0.2
  *
  * Copyright (C) 1999-2007  Brian Paul   All Rights Reserved.
  *
@@ -52,6 +52,32 @@
 
 
 /**
+ * Special struct for saving/restoring texture state (GL_TEXTURE_BIT)
+ */
+struct texture_state
+{
+   struct gl_texture_attrib Texture;  /**< The usual context state */
+
+   /** to save per texture object state (wrap modes, filters, etc): */
+   struct gl_texture_object Saved1D[MAX_TEXTURE_UNITS];
+   struct gl_texture_object Saved2D[MAX_TEXTURE_UNITS];
+   struct gl_texture_object Saved3D[MAX_TEXTURE_UNITS];
+   struct gl_texture_object SavedCube[MAX_TEXTURE_UNITS];
+   struct gl_texture_object SavedRect[MAX_TEXTURE_UNITS];
+
+   /**
+    * To save references to texture objects (so they don't get accidentally
+    * deleted while saved in the attribute stack).
+    */
+   struct gl_texture_object *SavedRef1D[MAX_TEXTURE_UNITS];
+   struct gl_texture_object *SavedRef2D[MAX_TEXTURE_UNITS];
+   struct gl_texture_object *SavedRef3D[MAX_TEXTURE_UNITS];
+   struct gl_texture_object *SavedRefCube[MAX_TEXTURE_UNITS];
+   struct gl_texture_object *SavedRefRect[MAX_TEXTURE_UNITS];
+};
+
+
+/**
  * Allocate a new attribute state node.  These nodes have a
  * "kind" value and a pointer to a struct of state data.
  */
@@ -335,40 +361,48 @@ _mesa_PushAttrib(GLbitfield mask)
    }
 
    if (mask & GL_TEXTURE_BIT) {
-      struct gl_texture_attrib *attr;
+      struct texture_state *texstate = CALLOC_STRUCT( texture_state );
       GLuint u;
 
+      if (!texstate) {
+         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushAttrib(GL_TEXTURE_BIT)");
+         goto end;
+      }
+
       _mesa_lock_context_textures(ctx);
-      /* Bump the texture object reference counts so that they don't
-       * inadvertantly get deleted.
+
+      /* copy/save the bulk of texture state here */
+      _mesa_memcpy(&texstate->Texture, &ctx->Texture, sizeof(ctx->Texture));
+
+      /* Save references to the currently bound texture objects so they don't
+       * accidentally get deleted while referenced in the attribute stack.
        */
       for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
-	 ctx->Texture.Unit[u].Current1D->RefCount++;
-	 ctx->Texture.Unit[u].Current2D->RefCount++;
-	 ctx->Texture.Unit[u].Current3D->RefCount++;
-	 ctx->Texture.Unit[u].CurrentCubeMap->RefCount++;
-	 ctx->Texture.Unit[u].CurrentRect->RefCount++;
+         _mesa_reference_texobj(&texstate->SavedRef1D[u], ctx->Texture.Unit[u].Current1D);
+         _mesa_reference_texobj(&texstate->SavedRef2D[u], ctx->Texture.Unit[u].Current2D);
+         _mesa_reference_texobj(&texstate->SavedRef3D[u], ctx->Texture.Unit[u].Current3D);
+         _mesa_reference_texobj(&texstate->SavedRefCube[u], ctx->Texture.Unit[u].CurrentCubeMap);
+         _mesa_reference_texobj(&texstate->SavedRefRect[u], ctx->Texture.Unit[u].CurrentRect);
       }
-      attr = MALLOC_STRUCT( gl_texture_attrib );
-      MEMCPY( attr, &ctx->Texture, sizeof(struct gl_texture_attrib) );
-      /* copy state of the currently bound texture objects */
+
+      /* copy state/contents of the currently bound texture objects */
       for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
-         _mesa_copy_texture_object(&attr->Unit[u].Saved1D,
-                                   attr->Unit[u].Current1D);
-         _mesa_copy_texture_object(&attr->Unit[u].Saved2D,
-                                   attr->Unit[u].Current2D);
-         _mesa_copy_texture_object(&attr->Unit[u].Saved3D,
-                                   attr->Unit[u].Current3D);
-         _mesa_copy_texture_object(&attr->Unit[u].SavedCubeMap,
-                                   attr->Unit[u].CurrentCubeMap);
-         _mesa_copy_texture_object(&attr->Unit[u].SavedRect,
-                                   attr->Unit[u].CurrentRect);
+         _mesa_copy_texture_object(&texstate->Saved1D[u],
+                                   ctx->Texture.Unit[u].Current1D);
+         _mesa_copy_texture_object(&texstate->Saved2D[u],
+                                   ctx->Texture.Unit[u].Current2D);
+         _mesa_copy_texture_object(&texstate->Saved3D[u],
+                                   ctx->Texture.Unit[u].Current3D);
+         _mesa_copy_texture_object(&texstate->SavedCube[u],
+                                   ctx->Texture.Unit[u].CurrentCubeMap);
+         _mesa_copy_texture_object(&texstate->SavedRect[u],
+                                   ctx->Texture.Unit[u].CurrentRect);
       }
 
       _mesa_unlock_context_textures(ctx);
 
       newnode = new_attrib_node( GL_TEXTURE_BIT );
-      newnode->data = attr;
+      newnode->data = texstate;
       newnode->next = head;
       head = newnode;
    }
@@ -404,6 +438,7 @@ _mesa_PushAttrib(GLbitfield mask)
       head = newnode;
    }
 
+end:
    ctx->AttribStack[ctx->AttribStackDepth] = head;
    ctx->AttribStackDepth++;
 }
@@ -613,14 +648,19 @@ pop_enable_group(GLcontext *ctx, const struct gl_enable_attrib *enable)
 }
 
 
+/**
+ * Pop/restore texture attribute/group state.
+ */
 static void
-pop_texture_group(GLcontext *ctx, const struct gl_texture_attrib *texAttrib)
+pop_texture_group(GLcontext *ctx, struct texture_state *texstate)
 {
    GLuint u;
 
+   _mesa_lock_context_textures(ctx);
+
    for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
-      const struct gl_texture_unit *unit = &texAttrib->Unit[u];
-      GLuint i;
+      const struct gl_texture_unit *unit = &texstate->Texture.Unit[u];
+      GLuint tgt;
 
       _mesa_ActiveTextureARB(GL_TEXTURE0_ARB + u);
       _mesa_set_enable(ctx, GL_TEXTURE_1D,
@@ -713,41 +753,44 @@ pop_texture_group(GLcontext *ctx, const struct gl_texture_attrib *texAttrib)
                        1 << unit->Combine.ScaleShiftA);
       }
 
-      /* Restore texture object state */
-      for (i = 0; i < NUM_TEXTURE_TARGETS; i++) {
-         GLenum target = 0;
+      /* Restore texture object state for each target */
+      for (tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++) {
          const struct gl_texture_object *obj = NULL;
          GLfloat bordColor[4];
+         GLenum target;
 
-         switch (i) {
-         case 0:
-            target = GL_TEXTURE_1D;
-            obj = &unit->Saved1D;
+         switch (tgt) {
+         case TEXTURE_1D_INDEX:
+            obj = &texstate->Saved1D[u];
+            ASSERT(obj->Target == GL_TEXTURE_1D);
             break;
-         case 1:
-            target = GL_TEXTURE_2D;
-            obj = &unit->Saved2D;
+         case TEXTURE_2D_INDEX:
+            obj = &texstate->Saved2D[u];
+            ASSERT(obj->Target == GL_TEXTURE_2D);
             break;
-         case 2:
-            target = GL_TEXTURE_3D;
-            obj = &unit->Saved3D;
+         case TEXTURE_3D_INDEX:
+            obj = &texstate->Saved3D[u];
+            ASSERT(obj->Target == GL_TEXTURE_3D);
             break;
-         case 3:
+         case TEXTURE_CUBE_INDEX:
             if (!ctx->Extensions.ARB_texture_cube_map)
                continue;
-            target = GL_TEXTURE_CUBE_MAP_ARB;
-            obj = &unit->SavedCubeMap;
+            obj = &texstate->SavedCube[u];
+            ASSERT(obj->Target == GL_TEXTURE_CUBE_MAP_ARB);
             break;
-         case 4:
+         case TEXTURE_RECT_INDEX:
             if (!ctx->Extensions.NV_texture_rectangle)
                continue;
-            target = GL_TEXTURE_RECTANGLE_NV;
-            obj = &unit->SavedRect;
+            obj = &texstate->SavedRect[u];
+            ASSERT(obj->Target == GL_TEXTURE_RECTANGLE_NV);
             break;
          default:
-            ; /* silence warnings */
+            _mesa_problem(ctx, "bad texture index in pop_texture_group");
+            continue;
          }
 
+         target = obj->Target;
+
          _mesa_BindTexture(target, obj->Name);
 
          bordColor[0] = CHAN_TO_FLOAT(obj->BorderColor[0]);
@@ -782,23 +825,19 @@ pop_texture_group(GLcontext *ctx, const struct gl_texture_attrib *texAttrib)
             _mesa_TexParameterf(target, GL_SHADOW_AMBIENT_SGIX,
                                 obj->ShadowAmbient);
          }
-
       }
-   }
-   _mesa_ActiveTextureARB(GL_TEXTURE0_ARB
-                          + texAttrib->CurrentUnit);
 
-   /* "un-bump" the texture object reference counts.  We did that so they
-    * wouldn't inadvertantly get deleted while they were still referenced
-    * inside the attribute state stack.
-    */
-   for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
-      ctx->Texture.Unit[u].Current1D->RefCount--;
-      ctx->Texture.Unit[u].Current2D->RefCount--;
-      ctx->Texture.Unit[u].Current3D->RefCount--;
-      ctx->Texture.Unit[u].CurrentCubeMap->RefCount--;
-      ctx->Texture.Unit[u].CurrentRect->RefCount--;
+      /* remove saved references to the texture objects */
+      _mesa_reference_texobj(&texstate->SavedRef1D[u], NULL);
+      _mesa_reference_texobj(&texstate->SavedRef2D[u], NULL);
+      _mesa_reference_texobj(&texstate->SavedRef3D[u], NULL);
+      _mesa_reference_texobj(&texstate->SavedRefCube[u], NULL);
+      _mesa_reference_texobj(&texstate->SavedRefRect[u], NULL);
    }
+
+   _mesa_ActiveTextureARB(GL_TEXTURE0_ARB + texstate->Texture.CurrentUnit);
+
+   _mesa_unlock_context_textures(ctx);
 }
 
 
@@ -1177,9 +1216,9 @@ _mesa_PopAttrib(void)
          case GL_TEXTURE_BIT:
             /* Take care of texture object reference counters */
             {
-               const struct gl_texture_attrib *texture;
-               texture = (const struct gl_texture_attrib *) attr->data;
-               pop_texture_group(ctx, texture);
+               struct texture_state *texstate
+                  = (struct texture_state *) attr->data;
+               pop_texture_group(ctx, texstate);
 	       ctx->NewState |= _NEW_TEXTURE;
             }
             break;
@@ -1401,6 +1440,41 @@ _mesa_PopClientAttrib(void)
 }
 
 
+void
+_mesa_free_attrib_data(GLcontext *ctx)
+{
+   while (ctx->AttribStackDepth > 0) {
+      struct gl_attrib_node *attr, *next;
+
+      ctx->AttribStackDepth--;
+      attr = ctx->AttribStack[ctx->AttribStackDepth];
+
+      while (attr) {
+         if (attr->kind == GL_TEXTURE_BIT) {
+            struct texture_state *texstate = (struct texture_state*)attr->data;
+            GLuint u;
+            /* clear references to the saved texture objects */
+            for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
+               _mesa_reference_texobj(&texstate->SavedRef1D[u], NULL);
+               _mesa_reference_texobj(&texstate->SavedRef2D[u], NULL);
+               _mesa_reference_texobj(&texstate->SavedRef3D[u], NULL);
+               _mesa_reference_texobj(&texstate->SavedRefCube[u], NULL);
+               _mesa_reference_texobj(&texstate->SavedRefRect[u], NULL);
+            }
+         }
+         else {
+            /* any other chunks of state that requires special handling? */
+         }
+
+         next = attr->next;
+         _mesa_free(attr->data);
+         _mesa_free(attr);
+         attr = next;
+      }
+   }
+}
+
+
 void _mesa_init_attrib( GLcontext *ctx )
 {
    /* Renderer and client attribute stacks */
diff --git a/src/mesa/main/attrib.h b/src/mesa/main/attrib.h
index 09d7519..ea28859 100644
--- a/src/mesa/main/attrib.h
+++ b/src/mesa/main/attrib.h
@@ -58,10 +58,14 @@ _mesa_PopClientAttrib( void );
 extern void 
 _mesa_init_attrib( GLcontext *ctx );
 
+extern void 
+_mesa_free_attrib_data( GLcontext *ctx );
+
 #else
 
 /** No-op */
 #define _mesa_init_attrib( c ) ((void)0)
+#define _mesa_free_attrib_data( c ) ((void)0)
 
 #endif
 
diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c
index e067840..754b1a7 100644
--- a/src/mesa/main/context.c
+++ b/src/mesa/main/context.c
@@ -6,7 +6,7 @@
 
 /*
  * Mesa 3-D graphics library
- * Version:  7.0
+ * Version:  7.0.2
  *
  * Copyright (C) 1999-2007  Brian Paul   All Rights Reserved.
  *
@@ -467,17 +467,12 @@ alloc_shared_state( GLcontext *ctx )
    if (!ss->DefaultRect)
       goto cleanup;
 
-   /* Effectively bind the default textures to all texture units */
-   ss->Default1D->RefCount += MAX_TEXTURE_IMAGE_UNITS;
-   ss->Default2D->RefCount += MAX_TEXTURE_IMAGE_UNITS;
-   ss->Default3D->RefCount += MAX_TEXTURE_IMAGE_UNITS;
-   ss->DefaultCubeMap->RefCount += MAX_TEXTURE_IMAGE_UNITS;
-   ss->DefaultRect->RefCount += MAX_TEXTURE_IMAGE_UNITS;
+   /* sanity check */
+   assert(ss->Default1D->RefCount == 1);
 
    _glthread_INIT_MUTEX(ss->TexMutex);
    ss->TextureStateStamp = 0;
 
-
 #if FEATURE_EXT_framebuffer_object
    ss->FrameBuffers = _mesa_NewHashTable();
    if (!ss->FrameBuffers)
@@ -487,10 +482,9 @@ alloc_shared_state( GLcontext *ctx )
       goto cleanup;
 #endif
 
-
    return GL_TRUE;
 
- cleanup:
+cleanup:
    /* Ran out of memory at some point.  Free everything and return NULL */
    if (ss->DisplayList)
       _mesa_DeleteHashTable(ss->DisplayList);
@@ -634,6 +628,33 @@ delete_shader_cb(GLuint id, void *data, void *userData)
    }
 }
 
+/**
+ * Callback for deleting a framebuffer object.  Called by _mesa_HashDeleteAll()
+ */
+static void
+delete_framebuffer_cb(GLuint id, void *data, void *userData)
+{
+   struct gl_framebuffer *fb = (struct gl_framebuffer *) data;
+   /* The fact that the framebuffer is in the hashtable means its refcount
+    * is one, but we're removing from the hashtable now.  So clear refcount.
+    */
+   /*assert(fb->RefCount == 1);*/
+   fb->RefCount = 0;
+   fb->Delete(fb);
+}
+
+/**
+ * Callback for deleting a renderbuffer object. Called by _mesa_HashDeleteAll()
+ */
+static void
+delete_renderbuffer_cb(GLuint id, void *data, void *userData)
+{
+   struct gl_renderbuffer *rb = (struct gl_renderbuffer *) data;
+   rb->RefCount = 0;  /* see comment for FBOs above */
+   rb->Delete(rb);
+}
+
+
 
 /**
  * Deallocate a shared state object and all children structures.
@@ -656,20 +677,6 @@ free_shared_state( GLcontext *ctx, struct gl_shared_state *ss )
    _mesa_HashDeleteAll(ss->DisplayList, delete_displaylist_cb, ctx);
    _mesa_DeleteHashTable(ss->DisplayList);
 
-   /*
-    * Free texture objects
-    */
-   ASSERT(ctx->Driver.DeleteTexture);
-   /* the default textures */
-   ctx->Driver.DeleteTexture(ctx, ss->Default1D);
-   ctx->Driver.DeleteTexture(ctx, ss->Default2D);
-   ctx->Driver.DeleteTexture(ctx, ss->Default3D);
-   ctx->Driver.DeleteTexture(ctx, ss->DefaultCubeMap);
-   ctx->Driver.DeleteTexture(ctx, ss->DefaultRect);
-   /* all other textures */
-   _mesa_HashDeleteAll(ss->TexObjects, delete_texture_cb, ctx);
-   _mesa_DeleteHashTable(ss->TexObjects);
-
 #if defined(FEATURE_NV_vertex_program) || defined(FEATURE_NV_fragment_program)
    _mesa_HashDeleteAll(ss->Programs, delete_program_cb, ctx);
    _mesa_DeleteHashTable(ss->Programs);
@@ -701,10 +708,27 @@ free_shared_state( GLcontext *ctx, struct gl_shared_state *ss )
 #endif
 
 #if FEATURE_EXT_framebuffer_object
+   _mesa_HashDeleteAll(ss->FrameBuffers, delete_framebuffer_cb, ctx);
    _mesa_DeleteHashTable(ss->FrameBuffers);
+   _mesa_HashDeleteAll(ss->RenderBuffers, delete_renderbuffer_cb, ctx);
    _mesa_DeleteHashTable(ss->RenderBuffers);
 #endif
 
+   /*
+    * Free texture objects (after FBOs since some textures might have
+    * been bound to FBOs).
+    */
+   ASSERT(ctx->Driver.DeleteTexture);
+   /* the default textures */
+   ctx->Driver.DeleteTexture(ctx, ss->Default1D);
+   ctx->Driver.DeleteTexture(ctx, ss->Default2D);
+   ctx->Driver.DeleteTexture(ctx, ss->Default3D);
+   ctx->Driver.DeleteTexture(ctx, ss->DefaultCubeMap);
+   ctx->Driver.DeleteTexture(ctx, ss->DefaultRect);
+   /* all other textures */
+   _mesa_HashDeleteAll(ss->TexObjects, delete_texture_cb, ctx);
+   _mesa_DeleteHashTable(ss->TexObjects);
+
    _glthread_DESTROY_MUTEX(ss->Mutex);
 
    _mesa_free(ss);
@@ -1157,18 +1181,20 @@ _mesa_create_context(const GLvisual *visual,
 void
 _mesa_free_context_data( GLcontext *ctx )
 {
-   /* if we're destroying the current context, unbind it first */
-   if (ctx == _mesa_get_current_context()) {
-      _mesa_make_current(NULL, NULL, NULL);
-   }
-   else {
-      /* unreference WinSysDraw/Read buffers */
-      _mesa_unreference_framebuffer(&ctx->WinSysDrawBuffer);
-      _mesa_unreference_framebuffer(&ctx->WinSysReadBuffer);
-      _mesa_unreference_framebuffer(&ctx->DrawBuffer);
-      _mesa_unreference_framebuffer(&ctx->ReadBuffer);
+   if (!_mesa_get_current_context()){
+      /* No current context, but we may need one in order to delete
+       * texture objs, etc.  So temporarily bind the context now.
+       */
+      _mesa_make_current(ctx, NULL, NULL);
    }
 
+   /* unreference WinSysDraw/Read buffers */
+   _mesa_unreference_framebuffer(&ctx->WinSysDrawBuffer);
+   _mesa_unreference_framebuffer(&ctx->WinSysReadBuffer);
+   _mesa_unreference_framebuffer(&ctx->DrawBuffer);
+   _mesa_unreference_framebuffer(&ctx->ReadBuffer);
+
+   _mesa_free_attrib_data(ctx);
    _mesa_free_lighting_data( ctx );
    _mesa_free_eval_data( ctx );
    _mesa_free_texture_data( ctx );
@@ -1200,6 +1226,11 @@ _mesa_free_context_data( GLcontext *ctx )
 
    if (ctx->Extensions.String)
       _mesa_free((void *) ctx->Extensions.String);
+
+   /* unbind the context if it's currently bound */
+   if (ctx == _mesa_get_current_context()) {
+      _mesa_make_current(NULL, NULL, NULL);
+   }
 }
 
 
@@ -1431,8 +1462,6 @@ void
 _mesa_make_current( GLcontext *newCtx, GLframebuffer *drawBuffer,
                     GLframebuffer *readBuffer )
 {
-   GET_CURRENT_CONTEXT(oldCtx);
-
    if (MESA_VERBOSE & VERBOSE_API)
       _mesa_debug(newCtx, "_mesa_make_current()\n");
 
@@ -1457,13 +1486,6 @@ _mesa_make_current( GLcontext *newCtx, GLframebuffer *drawBuffer,
    _glapi_set_context((void *) newCtx);
    ASSERT(_mesa_get_current_context() == newCtx);
 
-   if (oldCtx) {
-      _mesa_unreference_framebuffer(&oldCtx->WinSysDrawBuffer);
-      _mesa_unreference_framebuffer(&oldCtx->WinSysReadBuffer);
-      _mesa_unreference_framebuffer(&oldCtx->DrawBuffer);
-      _mesa_unreference_framebuffer(&oldCtx->ReadBuffer);
-   }
-         
    if (!newCtx) {
       _glapi_set_dispatch(NULL);  /* none current */
    }
diff --git a/src/mesa/main/dlist.c b/src/mesa/main/dlist.c
index 7813c7a..844db6b 100644
--- a/src/mesa/main/dlist.c
+++ b/src/mesa/main/dlist.c
@@ -1,6 +1,6 @@
 /*
  * Mesa 3-D graphics library
- * Version:  7.0.1
+ * Version:  7.0.2
  *
  * Copyright (C) 1999-2007  Brian Paul   All Rights Reserved.
  *
@@ -5737,7 +5737,7 @@ execute_list(GLcontext *ctx, GLuint list)
    if (!dlist)
       return;
 
-   ctx->ListState.CallStack[ctx->ListState.CallDepth++] = dlist;
+   ctx->ListState.CallDepth++;
 
    if (ctx->Driver.BeginCallList)
       ctx->Driver.BeginCallList(ctx, dlist);
@@ -6629,7 +6629,7 @@ execute_list(GLcontext *ctx, GLuint list)
    if (ctx->Driver.EndCallList)
       ctx->Driver.EndCallList(ctx);
 
-   ctx->ListState.CallStack[ctx->ListState.CallDepth--] = NULL;
+   ctx->ListState.CallDepth--;
 }
 
 
diff --git a/src/mesa/main/enable.c b/src/mesa/main/enable.c
index 0e14345..1c6167b 100644
--- a/src/mesa/main/enable.c
+++ b/src/mesa/main/enable.c
@@ -364,6 +364,10 @@ _mesa_set_enable(GLcontext *ctx, GLenum cap, GLboolean state)
       case GL_LIGHTING:
          if (ctx->Light.Enabled == state)
             return;
+         if (ctx->Light.Enabled && ctx->Light.Model.TwoSide)
+            ctx->_TriangleCaps |= DD_TRI_LIGHT_TWOSIDE;
+         else
+            ctx->_TriangleCaps &= ~DD_TRI_LIGHT_TWOSIDE;
          FLUSH_VERTICES(ctx, _NEW_LIGHT);
          ctx->Light.Enabled = state;
          break;
@@ -372,12 +376,14 @@ _mesa_set_enable(GLcontext *ctx, GLenum cap, GLboolean state)
             return;
          FLUSH_VERTICES(ctx, _NEW_LINE);
          ctx->Line.SmoothFlag = state;
+         ctx->_TriangleCaps ^= DD_LINE_SMOOTH;
          break;
       case GL_LINE_STIPPLE:
          if (ctx->Line.StippleFlag == state)
             return;
          FLUSH_VERTICES(ctx, _NEW_LINE);
          ctx->Line.StippleFlag = state;
+         ctx->_TriangleCaps ^= DD_LINE_STIPPLE;
          break;
       case GL_INDEX_LOGIC_OP:
          if (ctx->Color.IndexLogicOpEnabled == state)
@@ -516,18 +522,21 @@ _mesa_set_enable(GLcontext *ctx, GLenum cap, GLboolean state)
             return;
          FLUSH_VERTICES(ctx, _NEW_POINT);
          ctx->Point.SmoothFlag = state;
+         ctx->_TriangleCaps ^= DD_POINT_SMOOTH;
          break;
       case GL_POLYGON_SMOOTH:
          if (ctx->Polygon.SmoothFlag == state)
             return;
          FLUSH_VERTICES(ctx, _NEW_POLYGON);
          ctx->Polygon.SmoothFlag = state;
+         ctx->_TriangleCaps ^= DD_TRI_SMOOTH;
          break;
       case GL_POLYGON_STIPPLE:
          if (ctx->Polygon.StippleFlag == state)
             return;
          FLUSH_VERTICES(ctx, _NEW_POLYGON);
          ctx->Polygon.StippleFlag = state;
+         ctx->_TriangleCaps ^= DD_TRI_STIPPLE;
          break;
       case GL_POLYGON_OFFSET_POINT:
          if (ctx->Polygon.OffsetPoint == state)
@@ -877,6 +886,10 @@ _mesa_set_enable(GLcontext *ctx, GLenum cap, GLboolean state)
             return;
          FLUSH_VERTICES(ctx, _NEW_STENCIL);
          ctx->Stencil.TestTwoSide = state;
+         if (state)
+            ctx->_TriangleCaps |= DD_TRI_TWOSTENCIL;
+         else
+            ctx->_TriangleCaps &= ~DD_TRI_TWOSTENCIL;
          break;
 
 #if FEATURE_ARB_fragment_program
diff --git a/src/mesa/main/fbobject.c b/src/mesa/main/fbobject.c
index eac2f78..8e7d66c 100644
--- a/src/mesa/main/fbobject.c
+++ b/src/mesa/main/fbobject.c
@@ -150,22 +150,18 @@ _mesa_remove_attachment(GLcontext *ctx, struct gl_renderbuffer_attachment *att)
 {
    if (att->Type == GL_TEXTURE) {
       ASSERT(att->Texture);
-      att->Texture->RefCount--;
-      if (att->Texture->RefCount == 0) {
-	 ctx->Driver.DeleteTexture(ctx, att->Texture);
+      if (ctx->Driver.FinishRenderTexture) {
+         /* tell driver we're done rendering to this texobj */
+         ctx->Driver.FinishRenderTexture(ctx, att);
       }
-      else {
-         /* tell driver that we're done rendering to this texture. */
-         if (ctx->Driver.FinishRenderTexture) {
-            ctx->Driver.FinishRenderTexture(ctx, att);
-         }
-      }
-      att->Texture = NULL;
+      _mesa_reference_texobj(&att->Texture, NULL); /* unbind */
+      ASSERT(!att->Texture);
    }
    if (att->Type == GL_TEXTURE || att->Type == GL_RENDERBUFFER_EXT) {
       ASSERT(att->Renderbuffer);
       ASSERT(!att->Texture);
-      _mesa_reference_renderbuffer(&att->Renderbuffer, NULL);
+      _mesa_reference_renderbuffer(&att->Renderbuffer, NULL); /* unbind */
+      ASSERT(!att->Renderbuffer);
    }
    att->Type = GL_NONE;
    att->Complete = GL_TRUE;
@@ -191,8 +187,8 @@ _mesa_set_texture_attachment(GLcontext *ctx,
       /* new attachment */
       _mesa_remove_attachment(ctx, att);
       att->Type = GL_TEXTURE;
-      att->Texture = texObj;
-      texObj->RefCount++;
+      assert(!att->Texture);
+      _mesa_reference_texobj(&att->Texture, texObj);
    }
 
    /* always update these fields */
@@ -983,6 +979,7 @@ _mesa_BindFramebufferEXT(GLenum target, GLuint framebuffer)
 	    return;
 	 }
          _mesa_HashInsert(ctx->Shared->FrameBuffers, framebuffer, newFb);
+         ASSERT(newFb->RefCount == 1);
       }
    }
    else {
@@ -1006,8 +1003,10 @@ _mesa_BindFramebufferEXT(GLenum target, GLuint framebuffer)
    if (bindDrawBuf) {
       /* check if old FB had any texture attachments */
       check_end_texture_render(ctx, ctx->DrawBuffer);
-      /* check if time to delete this framebuffer */
+
+      /* bind new drawing buffer */
       _mesa_reference_framebuffer(&ctx->DrawBuffer, newFb);
+
       if (newFb->Name != 0) {
          /* check if newly bound framebuffer has any texture attachments */
          check_begin_texture_render(ctx, newFb);
diff --git a/src/mesa/main/framebuffer.c b/src/mesa/main/framebuffer.c
index 1fd31a5..8aeb369 100644
--- a/src/mesa/main/framebuffer.c
+++ b/src/mesa/main/framebuffer.c
@@ -38,6 +38,7 @@
 #include "fbobject.h"
 #include "framebuffer.h"
 #include "renderbuffer.h"
+#include "texobj.h"
 
 
 
@@ -190,17 +191,11 @@ _mesa_free_framebuffer_data(struct gl_framebuffer *fb)
          _mesa_reference_renderbuffer(&att->Renderbuffer, NULL);
       }
       if (att->Texture) {
-         /* render to texture */
-         att->Texture->RefCount--;
-         if (att->Texture->RefCount == 0) {
-            GET_CURRENT_CONTEXT(ctx);
-            if (ctx) {
-               ctx->Driver.DeleteTexture(ctx, att->Texture);
-            }
-         }
+         _mesa_reference_texobj(&att->Texture, NULL);
       }
+      ASSERT(!att->Renderbuffer);
+      ASSERT(!att->Texture);
       att->Type = GL_NONE;
-      att->Texture = NULL;
    }
 
    /* unbind _Depth/_StencilBuffer to decr ref counts */
diff --git a/src/mesa/main/glheader.h b/src/mesa/main/glheader.h
index fd41275..2d2da49 100644
--- a/src/mesa/main/glheader.h
+++ b/src/mesa/main/glheader.h
@@ -237,7 +237,7 @@
 #endif
 
 
-#if !defined __GNUC__ || __GNUC__ < 3
+#if (!defined(__GNUC__) || __GNUC__ < 3) && !defined(__IBMC__)
 #  define __builtin_expect(x, y) x
 #endif
 
diff --git a/src/mesa/main/image.c b/src/mesa/main/image.c
index 803f478..d7a96f7 100644
--- a/src/mesa/main/image.c
+++ b/src/mesa/main/image.c
@@ -3794,7 +3794,7 @@ _mesa_pack_stencil_span( const GLcontext *ctx, GLuint n,
          GLint *dst = (GLint *) dest;
          GLuint i;
          for (i=0;i<n;i++) {
-            *dst++ = (GLint) source[i];
+            dst[i] = (GLint) source[i];
          }
          if (dstPacking->SwapBytes) {
             _mesa_swap4( (GLuint *) dst, n );
diff --git a/src/mesa/main/light.c b/src/mesa/main/light.c
index 6e05761..6dd334e 100644
--- a/src/mesa/main/light.c
+++ b/src/mesa/main/light.c
@@ -53,6 +53,11 @@ _mesa_ShadeModel( GLenum mode )
 
    FLUSH_VERTICES(ctx, _NEW_LIGHT);
    ctx->Light.ShadeModel = mode;
+   if (mode == GL_FLAT)
+      ctx->_TriangleCaps |= DD_FLATSHADE;
+   else
+      ctx->_TriangleCaps &= ~DD_FLATSHADE;
+
    if (ctx->Driver.ShadeModel)
       ctx->Driver.ShadeModel( ctx, mode );
 }
@@ -441,6 +446,10 @@ _mesa_LightModelfv( GLenum pname, const GLfloat *params )
 	    return;
 	 FLUSH_VERTICES(ctx, _NEW_LIGHT);
 	 ctx->Light.Model.TwoSide = newbool;
+         if (ctx->Light.Enabled && ctx->Light.Model.TwoSide)
+            ctx->_TriangleCaps |= DD_TRI_LIGHT_TWOSIDE;
+         else
+            ctx->_TriangleCaps &= ~DD_TRI_LIGHT_TWOSIDE;
          break;
       case GL_LIGHT_MODEL_COLOR_CONTROL:
          if (params[0] == (GLfloat) GL_SINGLE_COLOR)
diff --git a/src/mesa/main/lines.c b/src/mesa/main/lines.c
index dc7195d..b464c4f 100644
--- a/src/mesa/main/lines.c
+++ b/src/mesa/main/lines.c
@@ -59,6 +59,11 @@ _mesa_LineWidth( GLfloat width )
 			    ctx->Const.MinLineWidth,
 			    ctx->Const.MaxLineWidth);
 
+   if (width != 1.0F)
+      ctx->_TriangleCaps |= DD_LINE_WIDTH;
+   else
+      ctx->_TriangleCaps &= ~DD_LINE_WIDTH;
+
    if (ctx->Driver.LineWidth)
       ctx->Driver.LineWidth(ctx, width);
 }
diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
index 71215d5..d00f2ef 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -1523,12 +1523,6 @@ struct gl_texture_unit
 
    struct gl_texture_object *_Current; /**< Points to really enabled tex obj */
 
-   struct gl_texture_object Saved1D;  /**< only used by glPush/PopAttrib */
-   struct gl_texture_object Saved2D;
-   struct gl_texture_object Saved3D;
-   struct gl_texture_object SavedCubeMap;
-   struct gl_texture_object SavedRect;
-
    /* GL_SGI_texture_color_table */
    struct gl_color_table ColorTable;
    struct gl_color_table ProxyColorTable;
@@ -2848,7 +2842,6 @@ struct mesa_display_list
  */
 struct gl_dlist_state
 {
-   struct mesa_display_list *CallStack[MAX_LIST_NESTING];
    GLuint CallDepth;		/**< Current recursion calling depth */
 
    struct mesa_display_list *CurrentList;
diff --git a/src/mesa/main/points.c b/src/mesa/main/points.c
index 408b68a..8825bb1 100644
--- a/src/mesa/main/points.c
+++ b/src/mesa/main/points.c
@@ -123,9 +123,15 @@ _mesa_PointParameterfvEXT( GLenum pname, const GLfloat *params)
 	       return;
 	    FLUSH_VERTICES(ctx, _NEW_POINT);
             COPY_3V(ctx->Point.Params, params);
+
             ctx->Point._Attenuated = (ctx->Point.Params[0] != 1.0 ||
                                       ctx->Point.Params[1] != 0.0 ||
                                       ctx->Point.Params[2] != 0.0);
+
+            if (ctx->Point._Attenuated)
+               ctx->_TriangleCaps |= DD_POINT_ATTEN;
+            else
+               ctx->_TriangleCaps &= ~DD_POINT_ATTEN;
          }
          else {
             _mesa_error(ctx, GL_INVALID_ENUM,
diff --git a/src/mesa/main/polygon.c b/src/mesa/main/polygon.c
index fd02e5a..564250b 100644
--- a/src/mesa/main/polygon.c
+++ b/src/mesa/main/polygon.c
@@ -167,6 +167,11 @@ _mesa_PolygonMode( GLenum face, GLenum mode )
       return;
    }
 
+   if (ctx->Polygon.FrontMode == GL_FILL && ctx->Polygon.BackMode == GL_FILL)
+      ctx->_TriangleCaps &= ~DD_TRI_UNFILLED;
+   else
+      ctx->_TriangleCaps |= DD_TRI_UNFILLED;
+
    if (ctx->Driver.PolygonMode)
       ctx->Driver.PolygonMode(ctx, face, mode);
 }
diff --git a/src/mesa/main/state.c b/src/mesa/main/state.c
index 96ee512..767161f 100644
--- a/src/mesa/main/state.c
+++ b/src/mesa/main/state.c
@@ -821,6 +821,16 @@ _mesa_init_exec_table(struct _glapi_table *exec)
 /*@{*/
 
 
+static void
+update_separate_specular( GLcontext *ctx )
+{
+   if (NEED_SECONDARY_COLOR(ctx))
+      ctx->_TriangleCaps |= DD_SEPARATE_SPECULAR;
+   else
+      ctx->_TriangleCaps &= ~DD_SEPARATE_SPECULAR;
+}
+
+
 /**
  * Update state dependent on vertex arrays.
  */
@@ -1045,6 +1055,26 @@ update_color(GLcontext *ctx)
 }
 
 
+/*
+ * Check polygon state and set DD_TRI_CULL_FRONT_BACK and/or DD_TRI_OFFSET
+ * in ctx->_TriangleCaps if needed.
+ */
+static void
+update_polygon( GLcontext *ctx )
+{
+   ctx->_TriangleCaps &= ~(DD_TRI_CULL_FRONT_BACK | DD_TRI_OFFSET);
+
+   if (ctx->Polygon.CullFlag && ctx->Polygon.CullFaceMode == GL_FRONT_AND_BACK)
+      ctx->_TriangleCaps |= DD_TRI_CULL_FRONT_BACK;
+
+   /* Any Polygon offsets enabled? */
+   if (ctx->Polygon.OffsetPoint ||
+       ctx->Polygon.OffsetLine ||
+       ctx->Polygon.OffsetFill) {
+      ctx->_TriangleCaps |= DD_TRI_OFFSET;
+   }
+}
+
 
 /**
  * Update the ctx->_TriangleCaps bitfield.
@@ -1052,6 +1082,7 @@ update_color(GLcontext *ctx)
  * This function must be called after other update_*() functions since
  * there are dependencies on some other derived values.
  */
+#if 0
 static void
 update_tricaps(GLcontext *ctx, GLbitfield new_state)
 {
@@ -1117,6 +1148,7 @@ update_tricaps(GLcontext *ctx, GLbitfield new_state)
    if (ctx->Stencil._TestTwoSide)
       ctx->_TriangleCaps |= DD_TRI_TWOSTENCIL;
 }
+#endif
 
 
 /**
@@ -1154,6 +1186,9 @@ _mesa_update_state_locked( GLcontext *ctx )
    if (new_state & (_NEW_SCISSOR | _NEW_BUFFERS | _NEW_VIEWPORT))
       _mesa_update_draw_buffer_bounds( ctx );
 
+   if (new_state & _NEW_POLYGON)
+      update_polygon( ctx );
+
    if (new_state & _NEW_LIGHT)
       _mesa_update_lighting( ctx );
 
@@ -1163,6 +1198,9 @@ _mesa_update_state_locked( GLcontext *ctx )
    if (new_state & _IMAGE_NEW_TRANSFER_STATE)
       _mesa_update_pixel( ctx, new_state );
 
+   if (new_state & _DD_NEW_SEPARATE_SPECULAR)
+      update_separate_specular( ctx );
+
    if (new_state & (_NEW_ARRAY | _NEW_PROGRAM))
       update_arrays( ctx );
 
@@ -1172,9 +1210,11 @@ _mesa_update_state_locked( GLcontext *ctx )
    if (new_state & _NEW_COLOR)
       update_color( ctx );
 
+#if 0
    if (new_state & (_NEW_POINT | _NEW_LINE | _NEW_POLYGON | _NEW_LIGHT
                     | _NEW_STENCIL | _DD_NEW_SEPARATE_SPECULAR))
       update_tricaps( ctx, new_state );
+#endif
 
    if (ctx->FragmentProgram._MaintainTexEnvProgram) {
       if (new_state & (_NEW_TEXTURE | _DD_NEW_SEPARATE_SPECULAR | _NEW_FOG))
diff --git a/src/mesa/main/texenvprogram.c b/src/mesa/main/texenvprogram.c
index 1a46c10..a6904f4 100644
--- a/src/mesa/main/texenvprogram.c
+++ b/src/mesa/main/texenvprogram.c
@@ -38,7 +38,7 @@
  * According to Glean's texCombine test, no more than 21 instructions
  * are needed.  Allow a few extra just in case.
  */
-#define MAX_INSTRUCTIONS 24
+#define MAX_INSTRUCTIONS ((MAX_TEXTURE_UNITS * 6) + 10) /* see bug 9829 */
 
 #define DISASSEM (MESA_VERBOSE & VERBOSE_DISASSEM)
 
diff --git a/src/mesa/main/texobj.c b/src/mesa/main/texobj.c
index 56d816e..7b36154 100644
--- a/src/mesa/main/texobj.c
+++ b/src/mesa/main/texobj.c
@@ -156,6 +156,11 @@ _mesa_delete_texture_object( GLcontext *ctx, struct gl_texture_object *texObj )
 
    (void) ctx;
 
+   /* Set Target to an invalid value.  With some assertions elsewhere
+    * we can try to detect possible use of deleted textures.
+    */
+   texObj->Target = 0x99;
+
    _mesa_free_colortable_data(&texObj->Palette);
 
    /* free the texture images */
@@ -188,6 +193,7 @@ void
 _mesa_copy_texture_object( struct gl_texture_object *dest,
                            const struct gl_texture_object *src )
 {
+   dest->Target = src->Target;
    dest->Name = src->Name;
    dest->Priority = src->Priority;
    dest->BorderColor[0] = src->BorderColor[0];
@@ -220,6 +226,92 @@ _mesa_copy_texture_object( struct gl_texture_object *dest,
 
 
 /**
+ * Check if the given texture object is valid by examining its Target field.
+ * For debugging only.
+ */
+static GLboolean
+valid_texture_object(const struct gl_texture_object *tex)
+{
+   switch (tex->Target) {
+   case 0:
+   case GL_TEXTURE_1D:
+   case GL_TEXTURE_2D:
+   case GL_TEXTURE_3D:
+   case GL_TEXTURE_CUBE_MAP_ARB:
+   case GL_TEXTURE_RECTANGLE_NV:
+      return GL_TRUE;
+   case 0x99:
+      _mesa_problem(NULL, "invalid reference to a deleted texture object");
+      return GL_FALSE;
+   default:
+      _mesa_problem(NULL, "invalid texture object Target value");
+      return GL_FALSE;
+   }
+}
+
+
+/**
+ * Reference (or unreference) a texture object.
+ * If '*ptr', decrement *ptr's refcount (and delete if it becomes zero).
+ * If 'tex' is non-null, increment its refcount.
+ */
+void
+_mesa_reference_texobj(struct gl_texture_object **ptr,
+                       struct gl_texture_object *tex)
+{
+   assert(ptr);
+   if (*ptr == tex) {
+      /* no change */
+      return;
+   }
+
+   if (*ptr) {
+      /* Unreference the old texture */
+      GLboolean deleteFlag = GL_FALSE;
+      struct gl_texture_object *oldTex = *ptr;
+
+      assert(valid_texture_object(oldTex));
+
+      _glthread_LOCK_MUTEX(oldTex->Mutex);
+      ASSERT(oldTex->RefCount > 0);
+      oldTex->RefCount--;
+
+      deleteFlag = (oldTex->RefCount == 0);
+      _glthread_UNLOCK_MUTEX(oldTex->Mutex);
+
+      if (deleteFlag) {
+         GET_CURRENT_CONTEXT(ctx);
+         if (ctx)
+            ctx->Driver.DeleteTexture(ctx, oldTex);
+         else
+            _mesa_problem(NULL, "Unable to delete texture, no context");
+      }
+
+      *ptr = NULL;
+   }
+   assert(!*ptr);
+
+   if (tex) {
+      /* reference new texture */
+      assert(valid_texture_object(tex));
+      _glthread_LOCK_MUTEX(tex->Mutex);
+      if (tex->RefCount == 0) {
+         /* this texture's being deleted (look just above) */
+         /* Not sure this can every really happen.  Warn if it does. */
+         _mesa_problem(NULL, "referencing deleted texture object");
+         *ptr = NULL;
+      }
+      else {
+         tex->RefCount++;
+         *ptr = tex;
+      }
+      _glthread_UNLOCK_MUTEX(tex->Mutex);
+   }
+}
+
+
+
+/**
  * Report why a texture object is incomplete.  
  *
  * \param t texture object.
@@ -620,8 +712,7 @@ unbind_texobj_from_fbo(GLcontext *ctx, struct gl_texture_object *texObj)
 
 /**
  * Check if the given texture object is bound to any texture image units and
- * unbind it if so.
- * XXX all RefCount accesses should be protected by a mutex.
+ * unbind it if so (revert to default textures).
  */
 static void
 unbind_texobj_from_texunits(GLcontext *ctx, struct gl_texture_object *texObj)
@@ -630,34 +721,20 @@ unbind_texobj_from_texunits(GLcontext *ctx, struct gl_texture_object *texObj)
 
    for (u = 0; u < MAX_TEXTURE_IMAGE_UNITS; u++) {
       struct gl_texture_unit *unit = &ctx->Texture.Unit[u];
-      struct gl_texture_object **curr = NULL;
-
       if (texObj == unit->Current1D) {
-         curr = &unit->Current1D;
-         unit->Current1D = ctx->Shared->Default1D;
+         _mesa_reference_texobj(&unit->Current1D, ctx->Shared->Default1D);
       }
       else if (texObj == unit->Current2D) {
-         curr = &unit->Current2D;
-         unit->Current2D = ctx->Shared->Default2D;
+         _mesa_reference_texobj(&unit->Current2D, ctx->Shared->Default2D);
       }
       else if (texObj == unit->Current3D) {
-         curr = &unit->Current3D;
-         unit->Current3D = ctx->Shared->Default3D;
+         _mesa_reference_texobj(&unit->Current3D, ctx->Shared->Default3D);
       }
       else if (texObj == unit->CurrentCubeMap) {
-         curr = &unit->CurrentCubeMap;
-         unit->CurrentCubeMap = ctx->Shared->DefaultCubeMap;
+         _mesa_reference_texobj(&unit->CurrentCubeMap, ctx->Shared->DefaultCubeMap);
       }
       else if (texObj == unit->CurrentRect) {
-         curr = &unit->CurrentRect;
-         unit->CurrentRect = ctx->Shared->DefaultRect;
-      }
-
-      if (curr) {
-         (*curr)->RefCount++;
-         texObj->RefCount--;
-         if (texObj == unit->_Current)
-            unit->_Current = *curr;
+         _mesa_reference_texobj(&unit->CurrentRect, ctx->Shared->DefaultRect);
       }
    }
 }
@@ -693,8 +770,6 @@ _mesa_DeleteTextures( GLsizei n, const GLuint *textures)
             = _mesa_lookup_texture(ctx, textures[i]);
 
          if (delObj) {
-	    GLboolean deleted;
-
 	    _mesa_lock_texture(ctx, delObj);
 
             /* Check if texture is bound to any framebuffer objects.
@@ -704,10 +779,12 @@ _mesa_DeleteTextures( GLsizei n, const GLuint *textures)
             unbind_texobj_from_fbo(ctx, delObj);
 
             /* Check if this texture is currently bound to any texture units.
-             * If so, unbind it and decrement the reference count.
+             * If so, unbind it.
              */
             unbind_texobj_from_texunits(ctx, delObj);
 
+	    _mesa_unlock_texture(ctx, delObj);
+
             ctx->NewState |= _NEW_TEXTURE;
 
             /* The texture _name_ is now free for re-use.
@@ -717,23 +794,10 @@ _mesa_DeleteTextures( GLsizei n, const GLuint *textures)
             _mesa_HashRemove(ctx->Shared->TexObjects, delObj->Name);
             _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
 
-            /* The actual texture object will not be freed until it's no
-             * longer bound in any context.
-             * XXX all RefCount accesses should be protected by a mutex.
+            /* Unreference the texobj.  If refcount hits zero, the texture
+             * will be deleted.
              */
-            delObj->RefCount--;
-	    deleted = (delObj->RefCount == 0);
-	    _mesa_unlock_texture(ctx, delObj);
-
-	    /* We know that refcount went to zero above, so this is
-	     * the only pointer left to delObj, so we don't have to
-	     * worry about locking any more:
-	     */
-            if (deleted) {
-               ASSERT(delObj->Name != 0); /* Never delete default tex objs */
-               ASSERT(ctx->Driver.DeleteTexture);
-               (*ctx->Driver.DeleteTexture)(ctx, delObj);
-            }
+            _mesa_reference_texobj(&delObj, NULL);
          }
       }
    }
@@ -761,7 +825,6 @@ _mesa_BindTexture( GLenum target, GLuint texName )
    GET_CURRENT_CONTEXT(ctx);
    const GLuint unit = ctx->Texture.CurrentUnit;
    struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
-   struct gl_texture_object *oldTexObj;
    struct gl_texture_object *newTexObj = NULL;
    ASSERT_OUTSIDE_BEGIN_END(ctx);
 
@@ -770,48 +833,6 @@ _mesa_BindTexture( GLenum target, GLuint texName )
                   _mesa_lookup_enum_by_nr(target), (GLint) texName);
 
    /*
-    * Get pointer to currently bound texture object (oldTexObj)
-    */
-   switch (target) {
-      case GL_TEXTURE_1D:
-         oldTexObj = texUnit->Current1D;
-         break;
-      case GL_TEXTURE_2D:
-         oldTexObj = texUnit->Current2D;
-         break;
-      case GL_TEXTURE_3D:
-         oldTexObj = texUnit->Current3D;
-         break;
-      case GL_TEXTURE_CUBE_MAP_ARB:
-         if (!ctx->Extensions.ARB_texture_cube_map) {
-            _mesa_error( ctx, GL_INVALID_ENUM, "glBindTexture(target)" );
-            return;
-         }
-         oldTexObj = texUnit->CurrentCubeMap;
-         break;
-      case GL_TEXTURE_RECTANGLE_NV:
-         if (!ctx->Extensions.NV_texture_rectangle) {
-            _mesa_error( ctx, GL_INVALID_ENUM, "glBindTexture(target)" );
-            return;
-         }
-         oldTexObj = texUnit->CurrentRect;
-         break;
-      default:
-         _mesa_error( ctx, GL_INVALID_ENUM, "glBindTexture(target)" );
-         return;
-   }
-
-   if (oldTexObj->Name == texName) {
-      /* XXX this might be wrong.  If the texobj is in use by another
-       * context and a texobj parameter was changed, this might be our
-       * only chance to update this context's hardware state.
-       * Note that some applications re-bind the same texture a lot so we
-       * want to handle that case quickly.
-       */
-      return;   /* rebinding the same texture- no change */
-   }
-
-   /*
     * Get pointer to new texture object (newTexObj)
     */
    if (texName == 0) {
@@ -879,28 +900,30 @@ _mesa_BindTexture( GLenum target, GLuint texName )
       newTexObj->Target = target;
    }
 
-   /* XXX all RefCount accesses should be protected by a mutex. */
-   newTexObj->RefCount++;
+   assert(valid_texture_object(newTexObj));
 
-   /* do the actual binding, but first flush outstanding vertices:
-    */
+   /* flush before changing binding */
    FLUSH_VERTICES(ctx, _NEW_TEXTURE);
 
+   /* Do the actual binding.  The refcount on the previously bound
+    * texture object will be decremented.  It'll be deleted if the
+    * count hits zero.
+    */
    switch (target) {
       case GL_TEXTURE_1D:
-         texUnit->Current1D = newTexObj;
+         _mesa_reference_texobj(&texUnit->Current1D, newTexObj);
          break;
       case GL_TEXTURE_2D:
-         texUnit->Current2D = newTexObj;
+         _mesa_reference_texobj(&texUnit->Current2D, newTexObj);
          break;
       case GL_TEXTURE_3D:
-         texUnit->Current3D = newTexObj;
+         _mesa_reference_texobj(&texUnit->Current3D, newTexObj);
          break;
       case GL_TEXTURE_CUBE_MAP_ARB:
-         texUnit->CurrentCubeMap = newTexObj;
+         _mesa_reference_texobj(&texUnit->CurrentCubeMap, newTexObj);
          break;
       case GL_TEXTURE_RECTANGLE_NV:
-         texUnit->CurrentRect = newTexObj;
+         _mesa_reference_texobj(&texUnit->CurrentRect, newTexObj);
          break;
       default:
          _mesa_problem(ctx, "bad target in BindTexture");
@@ -910,18 +933,6 @@ _mesa_BindTexture( GLenum target, GLuint texName )
    /* Pass BindTexture call to device driver */
    if (ctx->Driver.BindTexture)
       (*ctx->Driver.BindTexture)( ctx, target, newTexObj );
-
-   /* Decrement the reference count on the old texture and check if it's
-    * time to delete it.
-    */
-   /* XXX all RefCount accesses should be protected by a mutex. */
-   oldTexObj->RefCount--;
-   ASSERT(oldTexObj->RefCount >= 0);
-   if (oldTexObj->RefCount == 0) {
-      ASSERT(oldTexObj->Name != 0);
-      ASSERT(ctx->Driver.DeleteTexture);
-      (*ctx->Driver.DeleteTexture)( ctx, oldTexObj );
-   }
 }
 
 
diff --git a/src/mesa/main/texobj.h b/src/mesa/main/texobj.h
index ec7cf8c..9577e5e 100644
--- a/src/mesa/main/texobj.h
+++ b/src/mesa/main/texobj.h
@@ -58,6 +58,10 @@ _mesa_copy_texture_object( struct gl_texture_object *dest,
                            const struct gl_texture_object *src );
 
 extern void
+_mesa_reference_texobj(struct gl_texture_object **ptr,
+                       struct gl_texture_object *tex);
+
+extern void
 _mesa_test_texobj_completeness( const GLcontext *ctx,
                                 struct gl_texture_object *obj );
 
diff --git a/src/mesa/main/texstate.c b/src/mesa/main/texstate.c
index 1b45eae..a5966e7 100644
--- a/src/mesa/main/texstate.c
+++ b/src/mesa/main/texstate.c
@@ -63,31 +63,6 @@ static const struct gl_tex_env_combine_state default_combine_state = {
 };
 
 
-/**
- * Copy a texture binding.  Helper used by _mesa_copy_texture_state().
- */
-static void
-copy_texture_binding(const GLcontext *ctx,
-                     struct gl_texture_object **dst,
-                     struct gl_texture_object *src)
-{
-   /* only copy if names differ (per OpenGL SI) */
-   if ((*dst)->Name != src->Name) {
-      /* unbind/delete dest binding which we're changing */
-      (*dst)->RefCount--;
-      if ((*dst)->RefCount == 0) {
-         /* time to delete this texture object */
-         ASSERT((*dst)->Name != 0);
-         ASSERT(ctx->Driver.DeleteTexture);
-         /* XXX cast-away const, unfortunately */
-         (*ctx->Driver.DeleteTexture)((GLcontext *) ctx, *dst);
-      }
-      /* make new binding, incrementing ref count */
-      *dst = src;
-      src->RefCount++;
-   }
-}
-
 
 /**
  * Used by glXCopyContext to copy texture state from one context to another.
@@ -144,16 +119,16 @@ _mesa_copy_texture_state( const GLcontext *src, GLcontext *dst )
       /* copy texture object bindings, not contents of texture objects */
       _mesa_lock_context_textures(dst);
 
-      copy_texture_binding(src, &dst->Texture.Unit[i].Current1D,
-                           src->Texture.Unit[i].Current1D);
-      copy_texture_binding(src, &dst->Texture.Unit[i].Current2D,
-                           src->Texture.Unit[i].Current2D);
-      copy_texture_binding(src, &dst->Texture.Unit[i].Current3D,
-                           src->Texture.Unit[i].Current3D);
-      copy_texture_binding(src, &dst->Texture.Unit[i].CurrentCubeMap,
-                           src->Texture.Unit[i].CurrentCubeMap);
-      copy_texture_binding(src, &dst->Texture.Unit[i].CurrentRect,
-                           src->Texture.Unit[i].CurrentRect);
+      _mesa_reference_texobj(&dst->Texture.Unit[i].Current1D,
+                             src->Texture.Unit[i].Current1D);
+      _mesa_reference_texobj(&dst->Texture.Unit[i].Current2D,
+                             src->Texture.Unit[i].Current2D);
+      _mesa_reference_texobj(&dst->Texture.Unit[i].Current3D,
+                             src->Texture.Unit[i].Current3D);
+      _mesa_reference_texobj(&dst->Texture.Unit[i].CurrentCubeMap,
+                             src->Texture.Unit[i].CurrentCubeMap);
+      _mesa_reference_texobj(&dst->Texture.Unit[i].CurrentRect,
+                             src->Texture.Unit[i].CurrentRect);
 
       _mesa_unlock_context_textures(dst);
    }
@@ -3032,6 +3007,8 @@ alloc_proxy_textures( GLcontext *ctx )
    if (!ctx->Texture.ProxyRect)
       goto cleanup;
 
+   assert(ctx->Texture.Proxy1D->RefCount == 1);
+
    return GL_TRUE;
 
  cleanup:
@@ -3087,11 +3064,12 @@ init_texture_unit( GLcontext *ctx, GLuint unit )
    ASSIGN_4V( texUnit->EyePlaneR, 0.0, 0.0, 0.0, 0.0 );
    ASSIGN_4V( texUnit->EyePlaneQ, 0.0, 0.0, 0.0, 0.0 );
 
-   texUnit->Current1D = ctx->Shared->Default1D;
-   texUnit->Current2D = ctx->Shared->Default2D;
-   texUnit->Current3D = ctx->Shared->Default3D;
-   texUnit->CurrentCubeMap = ctx->Shared->DefaultCubeMap;
-   texUnit->CurrentRect = ctx->Shared->DefaultRect;
+   /* initialize current texture object ptrs to the shared default objects */
+   _mesa_reference_texobj(&texUnit->Current1D, ctx->Shared->Default1D);
+   _mesa_reference_texobj(&texUnit->Current2D, ctx->Shared->Default2D);
+   _mesa_reference_texobj(&texUnit->Current3D, ctx->Shared->Default3D);
+   _mesa_reference_texobj(&texUnit->CurrentCubeMap, ctx->Shared->DefaultCubeMap);
+   _mesa_reference_texobj(&texUnit->CurrentRect, ctx->Shared->DefaultRect);
 }
 
 
@@ -3106,21 +3084,20 @@ _mesa_init_texture(GLcontext *ctx)
    assert(MAX_TEXTURE_LEVELS >= MAX_3D_TEXTURE_LEVELS);
    assert(MAX_TEXTURE_LEVELS >= MAX_CUBE_TEXTURE_LEVELS);
 
-   /* Effectively bind the default textures to all texture units */
-   ctx->Shared->Default1D->RefCount += MAX_TEXTURE_UNITS;
-   ctx->Shared->Default2D->RefCount += MAX_TEXTURE_UNITS;
-   ctx->Shared->Default3D->RefCount += MAX_TEXTURE_UNITS;
-   ctx->Shared->DefaultCubeMap->RefCount += MAX_TEXTURE_UNITS;
-   ctx->Shared->DefaultRect->RefCount += MAX_TEXTURE_UNITS;
-
    /* Texture group */
    ctx->Texture.CurrentUnit = 0;      /* multitexture */
    ctx->Texture._EnabledUnits = 0;
-   for (i=0; i<MAX_TEXTURE_UNITS; i++)
-      init_texture_unit( ctx, i );
    ctx->Texture.SharedPalette = GL_FALSE;
    _mesa_init_colortable(&ctx->Texture.Palette);
 
+   for (i = 0; i < MAX_TEXTURE_UNITS; i++)
+      init_texture_unit( ctx, i );
+
+   /* After we're done initializing the context's texture state the default
+    * texture objects' refcounts should be at least MAX_TEXTURE_UNITS + 1.
+    */
+   assert(ctx->Shared->Default1D->RefCount >= MAX_TEXTURE_UNITS + 1);
+
    _mesa_TexEnvProgramCacheInit( ctx );
 
    /* Allocate proxy textures */
@@ -3132,12 +3109,22 @@ _mesa_init_texture(GLcontext *ctx)
 
 
 /**
- * Free dynamically-allocted texture data attached to the given context.
+ * Free dynamically-allocated texture data attached to the given context.
  */
 void
 _mesa_free_texture_data(GLcontext *ctx)
 {
-   GLuint i;
+   GLuint u;
+
+   /* unreference current textures */
+   for (u = 0; u < MAX_TEXTURE_IMAGE_UNITS; u++) {
+      struct gl_texture_unit *unit = ctx->Texture.Unit + u;
+      _mesa_reference_texobj(&unit->Current1D, NULL);
+      _mesa_reference_texobj(&unit->Current2D, NULL);
+      _mesa_reference_texobj(&unit->Current3D, NULL);
+      _mesa_reference_texobj(&unit->CurrentCubeMap, NULL);
+      _mesa_reference_texobj(&unit->CurrentRect, NULL);
+   }
 
    /* Free proxy texture objects */
    (ctx->Driver.DeleteTexture)(ctx,  ctx->Texture.Proxy1D );
@@ -3146,8 +3133,8 @@ _mesa_free_texture_data(GLcontext *ctx)
    (ctx->Driver.DeleteTexture)(ctx,  ctx->Texture.ProxyCubeMap );
    (ctx->Driver.DeleteTexture)(ctx,  ctx->Texture.ProxyRect );
 
-   for (i = 0; i < MAX_TEXTURE_IMAGE_UNITS; i++)
-      _mesa_free_colortable_data( &ctx->Texture.Unit[i].ColorTable );
+   for (u = 0; u < MAX_TEXTURE_IMAGE_UNITS; u++)
+      _mesa_free_colortable_data( &ctx->Texture.Unit[u].ColorTable );
 
    _mesa_TexEnvProgramCacheDestroy( ctx );
 }
diff --git a/src/mesa/main/version.h b/src/mesa/main/version.h
index 2c84579..2d3c68b 100644
--- a/src/mesa/main/version.h
+++ b/src/mesa/main/version.h
@@ -1,6 +1,6 @@
 /*
  * Mesa 3-D graphics library
- * Version:  7.0.1
+ * Version:  7.0.2
  *
  * Copyright (C) 1999-2007  Brian Paul   All Rights Reserved.
  *
@@ -30,8 +30,8 @@
 /* Mesa version */
 #define MESA_MAJOR 7
 #define MESA_MINOR 0
-#define MESA_PATCH 1
-#define MESA_VERSION_STRING "7.0.1"
+#define MESA_PATCH 2
+#define MESA_VERSION_STRING "7.0.2"
 
 /* To make version comparison easy */
 #define MESA_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
diff --git a/src/mesa/shader/arbprogparse.c b/src/mesa/shader/arbprogparse.c
index 5027264..6a87a17 100644
--- a/src/mesa/shader/arbprogparse.c
+++ b/src/mesa/shader/arbprogparse.c
@@ -624,6 +624,41 @@ program_error(GLcontext *ctx, GLint position, const char *descrip)
 }
 
 
+/**
+ * As above, but with an extra string parameter for more info.
+ */
+static void
+program_error2(GLcontext *ctx, GLint position, const char *descrip,
+               const char *var)
+{
+   if (descrip) {
+      const char *prefix = "glProgramString(", *suffix = ")";
+      char *str = (char *) _mesa_malloc(_mesa_strlen(descrip) +
+                                        _mesa_strlen(": ") +
+                                        _mesa_strlen(var) +
+                                        _mesa_strlen(prefix) +
+                                        _mesa_strlen(suffix) + 1);
+      if (str) {
+         _mesa_sprintf(str, "%s%s: %s%s", prefix, descrip, var, suffix);
+         _mesa_error(ctx, GL_INVALID_OPERATION, str);
+         _mesa_free(str);
+      }
+   }
+   {
+      char *str = (char *) _mesa_malloc(_mesa_strlen(descrip) +
+                                        _mesa_strlen(": ") +
+                                        _mesa_strlen(var) + 1);
+      if (str) {
+         _mesa_sprintf(str, "%s: %s", descrip, var);
+      }
+      _mesa_set_program_error(ctx, position, str);
+      if (str) {
+         _mesa_free(str);
+      }
+   }
+}
+
+
 
 /**
  * constructs an integer from 4 GLubytes in LE format
@@ -1217,10 +1252,10 @@ parse_state_single_item (GLcontext * ctx, const GLubyte ** inst,
 	    state_tokens[1] = coord;
 
             /* EYE or OBJECT */
-            type = *(*inst++);
+            type = *(*inst)++;
 
             /* 0 - s, 1 - t, 2 - r, 3 - q */
-            coord = *(*inst++);
+            coord = *(*inst)++;
 
             if (type == TEX_GEN_EYE) {
                switch (coord) {
@@ -1236,6 +1271,9 @@ parse_state_single_item (GLcontext * ctx, const GLubyte ** inst,
                   case COMPONENT_W:
                      state_tokens[2] = STATE_TEXGEN_EYE_Q;
                      break;
+                  default:
+                     _mesa_problem(ctx, "bad texgen component in "
+                                   "parse_state_single_item()");
                }
             }
             else {
@@ -1252,6 +1290,9 @@ parse_state_single_item (GLcontext * ctx, const GLubyte ** inst,
                   case COMPONENT_W:
                      state_tokens[2] = STATE_TEXGEN_OBJECT_Q;
                      break;
+                  default:
+                     _mesa_problem(ctx, "bad texgen component in "
+                                   "parse_state_single_item()");
                }
             }
          }
@@ -1274,7 +1315,7 @@ parse_state_single_item (GLcontext * ctx, const GLubyte ** inst,
          break;
 
       case STATE_POINT:
-         switch (*(*inst++)) {
+         switch (*(*inst)++) {
             case POINT_SIZE:
                state_tokens[0] = STATE_POINT_SIZE;
                break;
@@ -1678,18 +1719,14 @@ parse_attrib (GLcontext * ctx, const GLubyte ** inst, struct var_cache **vc_head
               struct arb_program *Program)
 {
    GLuint found;
-   char *error_msg;
    struct var_cache *attrib_var;
 
    attrib_var = parse_string (inst, vc_head, Program, &found);
    Program->Position = parse_position (inst);
    if (found) {
-      error_msg = (char *)
-         _mesa_malloc (_mesa_strlen ((char *) attrib_var->name) + 40);
-      _mesa_sprintf (error_msg, "Duplicate Varible Declaration: %s",
-                     attrib_var->name);
-      program_error(ctx, Program->Position, error_msg);
-      _mesa_free (error_msg);
+      program_error2(ctx, Program->Position,
+                     "Duplicate variable declaration",
+                     (char *) attrib_var->name);
       return 1;
    }
 
@@ -1867,12 +1904,9 @@ parse_param (GLcontext * ctx, const GLubyte ** inst, struct var_cache **vc_head,
    Program->Position = parse_position (inst);
 
    if (found) {
-      char *error_msg = (char *)
-         _mesa_malloc (_mesa_strlen ((char *) param_var->name) + 40);
-      _mesa_sprintf (error_msg, "Duplicate Varible Declaration: %s",
-                     param_var->name);
-      program_error (ctx, Program->Position, error_msg);
-      _mesa_free (error_msg);
+      program_error2(ctx, Program->Position,
+                     "Duplicate variable declaration",
+                     (char *) param_var->name);
       return 1;
    }
 
@@ -1967,12 +2001,9 @@ parse_temp (GLcontext * ctx, const GLubyte ** inst, struct var_cache **vc_head,
       temp_var = parse_string (inst, vc_head, Program, &found);
       Program->Position = parse_position (inst);
       if (found) {
-         char *error_msg = (char *)
-            _mesa_malloc (_mesa_strlen ((char *) temp_var->name) + 40);
-         _mesa_sprintf (error_msg, "Duplicate Varible Declaration: %s",
-                        temp_var->name);
-         program_error(ctx, Program->Position, error_msg);
-         _mesa_free (error_msg);
+         program_error2(ctx, Program->Position,
+                        "Duplicate variable declaration",
+                        (char *) temp_var->name);
          return 1;
       }
 
@@ -2013,12 +2044,9 @@ parse_output (GLcontext * ctx, const GLubyte ** inst, struct var_cache **vc_head
    output_var = parse_string (inst, vc_head, Program, &found);
    Program->Position = parse_position (inst);
    if (found) {
-      char *error_msg = (char *)
-         _mesa_malloc (_mesa_strlen ((char *) output_var->name) + 40);
-      _mesa_sprintf (error_msg, "Duplicate Varible Declaration: %s",
-                     output_var->name);
-      program_error (ctx, Program->Position, error_msg);
-      _mesa_free (error_msg);
+      program_error2(ctx, Program->Position,
+                     "Duplicate variable declaration",
+                     (char *) output_var->name);
       return 1;
    }
 
@@ -2044,12 +2072,9 @@ parse_alias (GLcontext * ctx, const GLubyte ** inst, struct var_cache **vc_head,
    Program->Position = parse_position (inst);
 
    if (found) {
-      char *error_msg = (char *)
-         _mesa_malloc (_mesa_strlen ((char *) temp_var->name) + 40);
-      _mesa_sprintf (error_msg, "Duplicate Varible Declaration: %s",
-                     temp_var->name);
-      program_error(ctx, Program->Position, error_msg);
-      _mesa_free (error_msg);
+      program_error2(ctx, Program->Position,
+                    "Duplicate variable declaration",
+                     (char *) temp_var->name);
       return 1;
    }
 
@@ -2059,12 +2084,9 @@ parse_alias (GLcontext * ctx, const GLubyte ** inst, struct var_cache **vc_head,
 
    if (!found)
    {
-      char *error_msg = (char *)
-         _mesa_malloc (_mesa_strlen ((char *) temp_var->name) + 40);
-      _mesa_sprintf (error_msg, "Alias value %s is not defined",
-                     temp_var->alias_binding->name);
-      program_error (ctx, Program->Position, error_msg);
-      _mesa_free (error_msg);
+      program_error2(ctx, Program->Position,
+                     "Undefined alias value",
+                     (char *) temp_var->alias_binding->name);
       return 1;
    }
 
@@ -2087,12 +2109,9 @@ parse_address (GLcontext * ctx, const GLubyte ** inst, struct var_cache **vc_hea
       temp_var = parse_string (inst, vc_head, Program, &found);
       Program->Position = parse_position (inst);
       if (found) {
-         char *error_msg = (char *)
-            _mesa_malloc (_mesa_strlen ((char *) temp_var->name) + 40);
-         _mesa_sprintf (error_msg, "Duplicate Varible Declaration: %s",
-                        temp_var->name);
-         program_error (ctx, Program->Position, error_msg);
-         _mesa_free (error_msg);
+         program_error2(ctx, Program->Position,
+                        "Duplicate variable declaration",
+                        (char *) temp_var->name);
          return 1;
       }
 
@@ -2445,8 +2464,9 @@ parse_src_reg (GLcontext * ctx, const GLubyte ** inst,
                Program->Position = parse_position (inst);
 
                if (!found) {
-                  program_error(ctx, Program->Position,
-                                "2: Undefined variable"); /* src->name */
+                  program_error2(ctx, Program->Position,
+                                 "Undefined variable",
+                                 (char *) src->name);
                   return 1;
                }
 
diff --git a/src/mesa/shader/atifragshader.c b/src/mesa/shader/atifragshader.c
index 4727c1a..854c911 100644
--- a/src/mesa/shader/atifragshader.c
+++ b/src/mesa/shader/atifragshader.c
@@ -440,7 +440,7 @@ _mesa_PassTexCoordATI(GLuint dst, GLuint coord, GLenum swizzle)
       _mesa_error(ctx, GL_INVALID_OPERATION, "glPassTexCoordATI(coord)");
       return;
    }
-   if ((swizzle < GL_SWIZZLE_STR_ATI) && (swizzle > GL_SWIZZLE_STQ_DQ_ATI)) {
+   if (!(swizzle >= GL_SWIZZLE_STR_ATI) && (swizzle <= GL_SWIZZLE_STQ_DQ_ATI)) {
       _mesa_error(ctx, GL_INVALID_ENUM, "glPassTexCoordATI(swizzle)");
       return;
    }
@@ -513,7 +513,7 @@ _mesa_SampleMapATI(GLuint dst, GLuint interp, GLenum swizzle)
       _mesa_error(ctx, GL_INVALID_OPERATION, "glSampleMapATI(interp)");
       return;
    }
-   if ((swizzle < GL_SWIZZLE_STR_ATI) && (swizzle > GL_SWIZZLE_STQ_DQ_ATI)) {
+   if (!(swizzle >= GL_SWIZZLE_STR_ATI) && (swizzle <= GL_SWIZZLE_STQ_DQ_ATI)) {
       _mesa_error(ctx, GL_INVALID_ENUM, "glSampleMapATI(swizzle)");
       return;
    }
diff --git a/src/mesa/shader/prog_statevars.c b/src/mesa/shader/prog_statevars.c
index 975a617..d37d7fb 100644
--- a/src/mesa/shader/prog_statevars.c
+++ b/src/mesa/shader/prog_statevars.c
@@ -507,6 +507,8 @@ _mesa_program_state_flags(const gl_state_index state[STATE_LENGTH])
       switch (state[1]) {
       case STATE_TEXRECT_SCALE:
 	 return _NEW_TEXTURE;
+      case STATE_FOG_PARAMS_OPTIMIZED:
+	 return _NEW_FOG;
       default:
          /* unknown state indexes are silently ignored and
          *  no flag set, since it is handled by the driver.
diff --git a/src/mesa/shader/shader_api.c b/src/mesa/shader/shader_api.c
index b794e30..06d24b4 100644
--- a/src/mesa/shader/shader_api.c
+++ b/src/mesa/shader/shader_api.c
@@ -378,7 +378,7 @@ _mesa_attach_shader(GLcontext *ctx, GLuint program, GLuint shader)
    struct gl_shader_program *shProg
       = _mesa_lookup_shader_program(ctx, program);
    struct gl_shader *sh = _mesa_lookup_shader(ctx, shader);
-   const GLuint n = shProg->NumShaders;
+   GLuint n;
    GLuint i;
 
    if (!shProg || !sh) {
@@ -387,6 +387,8 @@ _mesa_attach_shader(GLcontext *ctx, GLuint program, GLuint shader)
       return;
    }
 
+   n = shProg->NumShaders;
+
    for (i = 0; i < n; i++) {
       if (shProg->Shaders[i] == sh) {
          /* already attached */
@@ -548,7 +550,7 @@ _mesa_detach_shader(GLcontext *ctx, GLuint program, GLuint shader)
 {
    struct gl_shader_program *shProg
       = _mesa_lookup_shader_program(ctx, program);
-   const GLuint n = shProg->NumShaders;
+   GLuint n;
    GLuint i, j;
 
    if (!shProg) {
@@ -557,6 +559,8 @@ _mesa_detach_shader(GLcontext *ctx, GLuint program, GLuint shader)
       return;
    }
 
+   n = shProg->NumShaders;
+
    for (i = 0; i < n; i++) {
       if (shProg->Shaders[i]->Name == shader) {
          /* found it */
diff --git a/src/mesa/swrast/s_copypix.c b/src/mesa/swrast/s_copypix.c
index 012839c..ac7fa21 100644
--- a/src/mesa/swrast/s_copypix.c
+++ b/src/mesa/swrast/s_copypix.c
@@ -1,6 +1,6 @@
 /*
  * Mesa 3-D graphics library
- * Version:  6.5.3
+ * Version:  7.0.2
  *
  * Copyright (C) 1999-2007  Brian Paul   All Rights Reserved.
  *
@@ -71,13 +71,20 @@ regions_overlap(GLint srcx, GLint srcy,
    }
    else {
       /* add one pixel of slop when zooming, just to be safe */
-      if ((srcx > dstx + (width * zoomX) + 1) || (srcx + width + 1 < dstx)) {
+      if (srcx > (dstx + ((zoomX > 0.0F) ? (width * zoomX + 1.0F) : 0.0F))) {
+         /* src is completely right of dest */
+         return GL_FALSE;
+      }
+      else if (srcx + width + 1.0F < dstx + ((zoomX > 0.0F) ? 0.0F : (width * zoomX))) {
+         /* src is completely left of dest */
          return GL_FALSE;
       }
       else if ((srcy < dsty) && (srcy + height < dsty + (height * zoomY))) {
+         /* src is completely below dest */
          return GL_FALSE;
       }
       else if ((srcy > dsty) && (srcy + height > dsty + (height * zoomY))) {
+         /* src is completely above dest */
          return GL_FALSE;
       }
       else {
diff --git a/src/mesa/swrast/s_pointtemp.h b/src/mesa/swrast/s_pointtemp.h
index dddc2f7..9436464 100644
--- a/src/mesa/swrast/s_pointtemp.h
+++ b/src/mesa/swrast/s_pointtemp.h
@@ -217,9 +217,9 @@ NAME ( GLcontext *ctx, const SWvertex *vert )
       }
       else {
          /* even size */
-         xmin = (GLint) vert->win[0] - iRadius + 1;
+         xmin = (GLint) vert->win[0] - iRadius;
          xmax = xmin + iSize - 1;
-         ymin = (GLint) vert->win[1] - iRadius + 1;
+         ymin = (GLint) vert->win[1] - iRadius;
          ymax = ymin + iSize - 1;
       }
 #endif /*SMOOTH*/
diff --git a/src/mesa/swrast/s_span.c b/src/mesa/swrast/s_span.c
index 097d2c7..5814400 100644
--- a/src/mesa/swrast/s_span.c
+++ b/src/mesa/swrast/s_span.c
@@ -61,8 +61,11 @@ _swrast_span_default_z( 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);
+   else {
+      GLfloat tmpf = ctx->Current.RasterPos[2] * depthMax; 
+      tmpf = MIN2(tmpf, depthMax);
+      span->z = (GLint) tmpf;
+   }
    span->zStep = 0;
    span->interpMask |= SPAN_Z;
 }
diff --git a/src/mesa/tnl/t_draw.c b/src/mesa/tnl/t_draw.c
index 5b2b2ae..ff50d91 100644
--- a/src/mesa/tnl/t_draw.c
+++ b/src/mesa/tnl/t_draw.c
@@ -1,9 +1,8 @@
-
 /*
  * Mesa 3-D graphics library
- * Version:  6.5
+ * Version:  7.0.2
  *
- * 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"),
@@ -368,7 +367,7 @@ void _tnl_draw_prims( GLcontext *ctx,
 			_tnl_draw_prims );
       return;
    }
-   else if (max_index >= max) {
+   else if (max_index > max) {
       /* The software TNL pipeline has a fixed amount of storage for
        * vertices and it is necessary to split incoming drawing commands
        * if they exceed that limit.
diff --git a/src/mesa/tnl/t_vb_fog.c b/src/mesa/tnl/t_vb_fog.c
index 5440ff7..d8bca38 100644
--- a/src/mesa/tnl/t_vb_fog.c
+++ b/src/mesa/tnl/t_vb_fog.c
@@ -41,7 +41,6 @@
 
 struct fog_stage_data {
    GLvector4f fogcoord;		/* has actual storage allocated */
-   GLvector4f input;		/* points into VB->EyePtr Z values */
 };
 
 #define FOG_STAGE_DATA(stage) ((struct fog_stage_data *)stage->privatePtr)
@@ -91,7 +90,8 @@ init_static_data( void )
  * evaluating the GL_LINEAR, GL_EXP or GL_EXP2 fog function.
  * Fog coordinates are distances from the eye (typically between the
  * near and far clip plane distances).
- * Note the fog (eye Z) coords may be negative so we use ABS(z) below.
+ * Note that fogcoords may be negative, if eye z is source absolute
+ * value must be taken earlier.
  * Fog blend factors are in the range [0,1].
  */
 static void
@@ -114,7 +114,7 @@ compute_fog_blend_factors(GLcontext *ctx, GLvector4f *out, const GLvector4f *in)
       else
          d = 1.0F / (ctx->Fog.End - ctx->Fog.Start);
       for ( i = 0 ; i < n ; i++, STRIDE_F(v, stride)) {
-         const GLfloat z = FABSF(*v);
+         const GLfloat z = *v;
          GLfloat f = (end - z) * d;
 	 data[i][0] = CLAMP(f, 0.0F, 1.0F);
       }
@@ -122,14 +122,14 @@ compute_fog_blend_factors(GLcontext *ctx, GLvector4f *out, const GLvector4f *in)
    case GL_EXP:
       d = ctx->Fog.Density;
       for ( i = 0 ; i < n ; i++, STRIDE_F(v,stride)) {
-         const GLfloat z = FABSF(*v);
+         const GLfloat z = *v;
          NEG_EXP( data[i][0], d * z );
       }
       break;
    case GL_EXP2:
       d = ctx->Fog.Density*ctx->Fog.Density;
       for ( i = 0 ; i < n ; i++, STRIDE_F(v, stride)) {
-         const GLfloat z = FABSF(*v);
+         const GLfloat z = *v;
          NEG_EXP( data[i][0], d * z * z );
       }
       break;
@@ -153,6 +153,8 @@ run_fog_stage(GLcontext *ctx, struct tnl_pipeline_stage *stage)
 
 
    if (ctx->Fog.FogCoordinateSource == GL_FRAGMENT_DEPTH_EXT) {
+      GLuint i;
+      GLfloat *coord;
       /* Fog is computed from vertex or fragment Z values */
       /* source = VB->ObjPtr or VB->EyePtr coords */
       /* dest = VB->AttribPtr[_TNL_ATTRIB_FOG] = fog stage private storage */
@@ -167,11 +169,10 @@ run_fog_stage(GLcontext *ctx, struct tnl_pipeline_stage *stage)
 	  */
 	 input = &store->fogcoord;
 
-         /* NOTE: negate plane here so we get positive fog coords! */
-	 plane[0] = -m[2];
-	 plane[1] = -m[6];
-	 plane[2] = -m[10];
-	 plane[3] = -m[14];
+	 plane[0] = m[2];
+	 plane[1] = m[6];
+	 plane[2] = m[10];
+	 plane[3] = m[14];
 	 /* Full eye coords weren't required, just calculate the
 	  * eye Z values.
 	  */
@@ -180,18 +181,29 @@ run_fog_stage(GLcontext *ctx, struct tnl_pipeline_stage *stage)
 					      VB->ObjPtr, plane );
 
 	 input->count = VB->ObjPtr->count;
+
+	 /* make sure coords are really positive
+	    NOTE should avoid going through array twice */
+	 coord = input->start;
+	 for (i = 0; i < input->count; i++) {
+	    *coord = FABSF(*coord);
+	    STRIDE_F(coord, input->stride);
+	 }
       }
       else {
-         /* fog coordinates = eye Z coordinates (use ABS later) */
-	 input = &store->input;
+         /* fog coordinates = eye Z coordinates - need to copy for ABS */
+	 input = &store->fogcoord;
 
 	 if (VB->EyePtr->size < 2)
 	    _mesa_vector4f_clean_elem( VB->EyePtr, VB->Count, 2 );
 
-	 input->data = (GLfloat (*)[4]) &(VB->EyePtr->data[0][2]);
-	 input->start = VB->EyePtr->start+2;
-	 input->stride = VB->EyePtr->stride;
+	 input->stride = 4 * sizeof(GLfloat);
 	 input->count = VB->EyePtr->count;
+	 coord = VB->EyePtr->start;
+	 for (i = 0 ; i < VB->EyePtr->count; i++) {
+	    input->data[i][0] = FABSF(coord[2]);
+	    STRIDE_F(coord, VB->EyePtr->stride);
+	 }
       }
    }
    else {
@@ -234,7 +246,6 @@ alloc_fog_data(GLcontext *ctx, struct tnl_pipeline_stage *stage)
       return GL_FALSE;
 
    _mesa_vector4f_alloc( &store->fogcoord, 0, tnl->vb.Size, 32 );
-   _mesa_vector4f_init( &store->input, 0, NULL );
 
    if (!inited)
       init_static_data();
diff --git a/src/mesa/tnl/t_vp_build.c b/src/mesa/tnl/t_vp_build.c
index dff062a..6a6db06 100644
--- a/src/mesa/tnl/t_vp_build.c
+++ b/src/mesa/tnl/t_vp_build.c
@@ -1,8 +1,8 @@
 /*
  * Mesa 3-D graphics library
- * Version:  6.5
+ * Version:  7.1
  *
- * Copyright (C) 2006  Tungsten Graphics   All Rights Reserved.
+ * Copyright (C) 2007  Tungsten Graphics   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"),
@@ -33,11 +33,11 @@
 #include "glheader.h"
 #include "macros.h"
 #include "enums.h"
-#include "program.h"
-#include "prog_instruction.h"
-#include "prog_parameter.h"
-#include "prog_print.h"
-#include "prog_statevars.h"
+#include "shader/program.h"
+#include "shader/prog_instruction.h"
+#include "shader/prog_parameter.h"
+#include "shader/prog_print.h"
+#include "shader/prog_statevars.h"
 #include "t_context.h" /* NOTE: very light dependency on this */
 #include "t_vp_build.h"
 
@@ -457,9 +457,13 @@ static void register_matrix_param5( struct tnl_program *p,
 }
 
 
+/**
+ * Convert a ureg source register to a prog_src_register.
+ */
 static void emit_arg( struct prog_src_register *src,
 		      struct ureg reg )
 {
+   assert(reg.file != PROGRAM_OUTPUT);
    src->File = reg.file;
    src->Index = reg.idx;
    src->Swizzle = reg.swz;
@@ -469,9 +473,18 @@ static void emit_arg( struct prog_src_register *src,
    src->RelAddr = 0;
 }
 
+/**
+ * Convert a ureg dest register to a prog_dst_register.
+ */
 static void emit_dst( struct prog_dst_register *dst,
 		      struct ureg reg, GLuint mask )
 {
+   /* Check for legal output register type.  UNDEFINED will occur in
+    * instruction that don't produce a result (like END).
+    */
+   assert(reg.file == PROGRAM_TEMPORARY ||
+          reg.file == PROGRAM_OUTPUT ||
+          reg.file == PROGRAM_UNDEFINED);
    dst->File = reg.file;
    dst->Index = reg.idx;
    /* allow zero as a shorthand for xyzw */
@@ -686,7 +699,7 @@ static struct ureg get_eye_normal( struct tnl_program *p )
 	 struct ureg rescale = register_param2(p, STATE_INTERNAL,
 					       STATE_NORMAL_SCALE);
 
-	 emit_op2( p, OPCODE_MUL, p->eye_normal, 0, normal, 
+	 emit_op2( p, OPCODE_MUL, p->eye_normal, 0, p->eye_normal,
 		   swizzle1(rescale, X));
       }
    }
@@ -956,13 +969,19 @@ static void build_lighting( struct tnl_program *p )
 					       STATE_POSITION); 
 	    struct ureg V = get_eye_position(p);
 	    struct ureg dist = get_temp(p);
+	    struct ureg tmpPpli = get_temp(p);
 
 	    VPpli = get_temp(p); 
 	    half = get_temp(p);
  
-	    /* Calulate VPpli vector
+            /* In homogeneous object coordinates
+             */
+            emit_op1(p, OPCODE_RCP, dist, 0, swizzle1(Ppli, W));
+            emit_op2(p, OPCODE_MUL, tmpPpli, 0, Ppli, dist);
+
+	    /* Calculate VPpli vector
 	     */
-	    emit_op2(p, OPCODE_SUB, VPpli, 0, Ppli, V); 
+	    emit_op2(p, OPCODE_SUB, VPpli, 0, tmpPpli, V); 
 
 	    /* Normalize VPpli.  The dist value also used in
 	     * attenuation below.
@@ -994,6 +1013,7 @@ static void build_lighting( struct tnl_program *p )
 	    emit_normalize_vec3(p, half, half);
 
 	    release_temp(p, dist);
+	    release_temp(p, tmpPpli);
 	 }
 
 	 /* Calculate dot products:
@@ -1103,7 +1123,7 @@ static void build_fog( struct tnl_program *p )
 {
    struct ureg fog = register_output(p, VERT_RESULT_FOGC);
    struct ureg input;
-   
+
    if (p->state->fog_source_is_depth) {
       input = swizzle1(get_eye_position(p), Z);
    }
@@ -1111,39 +1131,48 @@ 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);
+      GLboolean useabs = (p->state->fog_mode != FOG_EXP2);
+
+      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 {
       /* results = incoming fog coords (compute fog per-fragment later) 
        *
        * KW:  Is it really necessary to do anything in this case?
+       * BP: Yes, we always need to compute the absolute value, unless
+       * we want to push that down into the fragment program...
        */
-      emit_op1(p, OPCODE_MOV, fog, WRITEMASK_X, input);
+      GLboolean useabs = GL_TRUE;
+      emit_op1(p, useabs ? OPCODE_ABS : OPCODE_MOV, fog, WRITEMASK_X, input);
    }
 }
  
diff --git a/src/mesa/vbo/vbo_save_draw.c b/src/mesa/vbo/vbo_save_draw.c
index 8940551..697d00e 100644
--- a/src/mesa/vbo/vbo_save_draw.c
+++ b/src/mesa/vbo/vbo_save_draw.c
@@ -132,9 +132,11 @@ static void vbo_bind_vertex_list( GLcontext *ctx,
    }
 
    for (attr = 0; attr < VBO_ATTRIB_MAX; attr++) {
-      if (node->attrsz[attr]) {
+      GLuint src = map[attr];
+
+      if (node->attrsz[src]) {
 	 arrays[attr].Ptr = (const GLubyte *)data;
-	 arrays[attr].Size = node->attrsz[attr];
+	 arrays[attr].Size = node->attrsz[src];
 	 arrays[attr].StrideB = node->vertex_size * sizeof(GLfloat);
 	 arrays[attr].Stride = node->vertex_size * sizeof(GLfloat);
 	 arrays[attr].Type = GL_FLOAT;
diff --git a/src/mesa/vbo/vbo_split_copy.c b/src/mesa/vbo/vbo_split_copy.c
index e142dde..b71a935 100644
--- a/src/mesa/vbo/vbo_split_copy.c
+++ b/src/mesa/vbo/vbo_split_copy.c
@@ -129,6 +129,13 @@ static GLuint attr_size( const struct gl_client_array *array )
  */
 static GLboolean check_flush( struct copy_context *copy )
 {
+   GLenum mode = copy->dstprim[copy->dstprim_nr].mode;
+
+   if (GL_TRIANGLE_STRIP == mode &&
+       copy->dstelt_nr & 1) { /* see bug9962 */
+      return GL_FALSE;
+   }
+
    if (copy->dstbuf_nr + 4 > copy->dstbuf_size)
       return GL_TRUE;
 
@@ -458,7 +465,7 @@ static void replay_init( struct copy_context *copy )
       dst->StrideB = copy->vertex_size;
       dst->Ptr = copy->dstbuf + offset;
       dst->Enabled = GL_TRUE;
-      dst->Normalized = GL_TRUE;
+      dst->Normalized = src->Normalized;
       dst->BufferObj = ctx->Array.NullBufferObj;
       dst->_MaxElement = copy->dstbuf_size; /* may be less! */
 
diff --git a/src/mesa/x86-64/xform4.S b/src/mesa/x86-64/xform4.S
index 65328f6..f512b3a 100644
--- a/src/mesa/x86-64/xform4.S
+++ b/src/mesa/x86-64/xform4.S
@@ -1,10 +1,8 @@
-/* $Id: xform4.S,v 1.2 2006/04/17 18:58:24 krh Exp $ */
-
 /*
  * Mesa 3-D graphics library
- * Version:  3.5
+ * Version:  7.0.1
  *
- * Copyright (C) 1999-2001  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"),
@@ -64,7 +62,7 @@ _mesa_x86_64_transform_points4_general:
 
 p4_general_loop:
 
-	movaps (%rdx), %xmm8		/* ox | oy | oz | ow */
+	movups (%rdx), %xmm8		/* ox | oy | oz | ow */
 	prefetchw 16(%rdi)
 
 	pshufd $0x00, %xmm8, %xmm0	/* ox | ox | ox | ox */
@@ -149,7 +147,7 @@ _mesa_x86_64_transform_points4_3d:
 
 p4_3d_loop:
 
-	movaps (%rdx), %xmm8		/* ox | oy | oz | ow */
+	movups (%rdx), %xmm8		/* ox | oy | oz | ow */
 	prefetchw 16(%rdi)
 
 	pshufd $0x00, %xmm8, %xmm0	/* ox | ox | ox | ox */