Merge commit '381d5e209815235911c4aab516037c868c8f695f'

This merges the patches from the series "[PATCH 00/14] More
client-side GLX house cleaning" that were posted to the mesa3d-dev
mailing list.  See
http://marc.info/?l=mesa3d-dev&m=126582985214612&w=2

Patches 01 through 04 eliminate a bunch of annoying warnings that I
get when building Mesa.

Patch 05 fixes an inconsistency between the implementation of
glXSwapIntervalMESA and the spec.  I chose to favor the code over the
spec in this case.  This also eliminated a warning.

Patches 06 through 12 clean up the way that context creation is
performed on the client.  When support for GLX_SGIX_fbconfig and the
related GLX 1.3 functions was added, I refactored a bunch
nuts-and-bolts of context creation to CreateContext.  The refactor was
a good idea, I just didn't do it right.

Patches 13 and 14 update glxgears_fbconfig to use GLX 1.3 interfaces.
diff --git a/Makefile b/Makefile
index 3a9c92b..ea5751d 100644
--- a/Makefile
+++ b/Makefile
@@ -173,11 +173,14 @@
 sunos5-v9-static \
 sunos5-v9-cc-g++ \
 ultrix-gcc:
-	@ if test -f configs/current || test -L configs/current ; then \
-		echo "Please run 'make realclean' before changing configs" ; \
-		exit 1 ; \
+	@ if test -f configs/current -o -L configs/current; then \
+		if ! cmp configs/$@ configs/current > /dev/null; then \
+			echo "Please run 'make realclean' before changing configs" ; \
+			exit 1 ; \
+		fi ; \
+	else \
+		cd configs && rm -f current && ln -s $@ current ; \
 	fi
-	(cd configs && rm -f current && ln -s $@ current)
 	$(MAKE) default
 
 
diff --git a/SConstruct b/SConstruct
index 964af7e..ea63b90 100644
--- a/SConstruct
+++ b/SConstruct
@@ -225,9 +225,10 @@
 	duplicate = 0 # http://www.scons.org/doc/0.97/HTML/scons-user/x2261.html
 )
 
-if 'progs' in COMMAND_LINE_TARGETS:
-    SConscript(
-        'progs/SConscript',
-        variant_dir = os.path.join('progs', env['build']),
-        duplicate = 0 # http://www.scons.org/doc/0.97/HTML/scons-user/x2261.html
-    )
+env.Default('src')
+
+SConscript(
+    'progs/SConscript',
+    variant_dir = os.path.join('progs', env['build']),
+    duplicate = 0 # http://www.scons.org/doc/0.97/HTML/scons-user/x2261.html
+)
diff --git a/configs/linux-cell b/configs/linux-cell
index 229ac73..e89a08c 100644
--- a/configs/linux-cell
+++ b/configs/linux-cell
@@ -25,12 +25,16 @@
 SDK = /opt/cell/sdk/usr
 
 
-CFLAGS = $(OPT_FLAGS) -mcpu=cell -Wall -Winline -Wmissing-prototypes \
-	-fPIC -m32 -std=c99 -mabi=altivec -maltivec \
+
+COMMON_C_CPP_FLAGS = $(OPT_FLAGS) -Wall -Winline \
+	-fPIC -m32 -mabi=altivec -maltivec \
 	-I. -I$(SDK)/include \
 	-DGALLIUM_CELL $(DEFINES)
 
-CXXFLAGS = $(CFLAGS)
+CFLAGS = $(COMMON_C_CPP_FLAGS) -Wmissing-prototypes -std=c99
+
+CXXFLAGS = $(COMMON_C_CPP_FLAGS)
+
 
 # Omitting glw here:
 SRC_DIRS = glsl mesa gallium gallium/winsys glu glut/glx glew
diff --git a/configure.ac b/configure.ac
index 27405bb..be06adf 100644
--- a/configure.ac
+++ b/configure.ac
@@ -20,7 +20,7 @@
 dnl Versions for external dependencies
 LIBDRM_REQUIRED=2.4.15
 LIBDRM_RADEON_REQUIRED=2.4.17
-DRI2PROTO_REQUIRED=2.2
+DRI2PROTO_REQUIRED=2.1
 GLPROTO_REQUIRED=1.4.11
 
 dnl Check for progs
diff --git a/docs/egl.html b/docs/egl.html
index 844cc32..82cc066 100644
--- a/docs/egl.html
+++ b/docs/egl.html
@@ -302,10 +302,18 @@
 client API renders to the specified render buffer for pixmap and pbuffer
 surfaces.</p>
 
+<h3><code>EGLDisplay</code> Mutex</h3>
+
+The <code>EGLDisplay</code> will be locked before calling any of the dispatch
+functions (well, except for GetProcAddress which does not take an
+<code>EGLDisplay</code>).  This guarantees that the same dispatch function will
+not be called with the sample display at the same time.  If a driver has access
+to an <code>EGLDisplay</code> without going through the EGL APIs, the driver
+should as well lock the display before using it.
+
 <h3>TODOs</h3>
 
 <ul>
-<li>Thread safety</li>
 <li>Pass the conformance tests</li>
 <li>Better automatic driver selection: <code>EGL_DISPLAY</code> loads all
 drivers and might eat too much memory.</li>
diff --git a/docs/relnotes-7.7.1.html b/docs/relnotes-7.7.1.html
index 959efd9..c3d42c1 100644
--- a/docs/relnotes-7.7.1.html
+++ b/docs/relnotes-7.7.1.html
@@ -44,6 +44,7 @@
 <li>Fixed mipmap generation bug caused by invalid viewport state.
 <li>Gallium SSE codegen for XPD didn't always work.
 <li>Fixed Windows build.
+<li>Fixed broken glMultiDrawElements().
 </ul>
 
 
diff --git a/docs/relnotes-7.8.html b/docs/relnotes-7.8.html
index 7510139..177d11e 100644
--- a/docs/relnotes-7.8.html
+++ b/docs/relnotes-7.8.html
@@ -36,6 +36,7 @@
 <ul>
 <li>GL_NV_conditional_render extension (swrast driver only)
 <li>GL_EXT_draw_buffers2 extension (swrast and i965 driver only)
+<li>GL_ARB_fragment_coord_conventions extension (for swrast and Gallium drivers)
 <li>Much improved support for <a href="egl.html">EGL in Mesa</a>
 <li>New state trackers for <a href="opengles.html">OpenGL ES 1.1 and 2.0</a>
 <li>Dedicated documentation for Gallium
diff --git a/include/GL/internal/dri_interface.h b/include/GL/internal/dri_interface.h
index 58540d6..cb99c27 100644
--- a/include/GL/internal/dri_interface.h
+++ b/include/GL/internal/dri_interface.h
@@ -269,22 +269,20 @@
  * Used by drivers that implement DRI2
  */
 #define __DRI2_FLUSH "DRI2_Flush"
-#define __DRI2_FLUSH_VERSION 2
+#define __DRI2_FLUSH_VERSION 3
 struct __DRI2flushExtensionRec {
     __DRIextension base;
     void (*flush)(__DRIdrawable *drawable);
 
     /**
-     * Flush all rendering queue in the driver to the drm and
-     * invalidate all buffers.  The driver will call out to
-     * getBuffers/getBuffersWithFormat before it starts rendering
-     * again.
+     * Ask the driver to call getBuffers/getBuffersWithFormat before
+     * it starts rendering again.
      *
-     * \param drawable the drawable to flush and invalidate
+     * \param drawable the drawable to invalidate
      *
-     * \since 2
+     * \since 3
      */
-    void (*flushInvalidate)(__DRIdrawable *drawable);
+    void (*invalidate)(__DRIdrawable *drawable);
 };
 
 
diff --git a/progs/demos/fslight.c b/progs/demos/fslight.c
index 395b7ca..91a5a80 100644
--- a/progs/demos/fslight.c
+++ b/progs/demos/fslight.c
@@ -467,8 +467,8 @@
    const char *version;
 
    version = (const char *) glGetString(GL_VERSION);
-   if (version[0] != '2' || version[1] != '.') {
-      printf("This program requires OpenGL 2.x, found %s\n", version);
+   if (version[0] == '1') {
+      printf("This program requires OpenGL 2.x or higher, found %s\n", version);
       exit(1);
    }
 
diff --git a/progs/es1/.gitignore b/progs/es1/.gitignore
index 4f14275..5e29a6b 100644
--- a/progs/es1/.gitignore
+++ b/progs/es1/.gitignore
@@ -1,5 +1,6 @@
 screen/gears
 screen/tri
+xegl/bindtex
 xegl/drawtex
 xegl/es1_info
 xegl/msaa
diff --git a/progs/fp/fp-tri.c b/progs/fp/fp-tri.c
index 70676d4..e45a799 100644
--- a/progs/fp/fp-tri.c
+++ b/progs/fp/fp-tri.c
@@ -188,6 +188,7 @@
    }
 
    glClearColor(.1, .3, .5, 0);
+   fclose(f);
 }
 
 static void Reshape(int width, int height)
diff --git a/src/gallium/state_trackers/python/retrace/README b/progs/gallium/python/retrace/README
similarity index 100%
rename from src/gallium/state_trackers/python/retrace/README
rename to progs/gallium/python/retrace/README
diff --git a/src/gallium/state_trackers/python/retrace/format.py b/progs/gallium/python/retrace/format.py
similarity index 100%
rename from src/gallium/state_trackers/python/retrace/format.py
rename to progs/gallium/python/retrace/format.py
diff --git a/src/gallium/state_trackers/python/retrace/interpreter.py b/progs/gallium/python/retrace/interpreter.py
similarity index 98%
rename from src/gallium/state_trackers/python/retrace/interpreter.py
rename to progs/gallium/python/retrace/interpreter.py
index 190db43..2db71a2 100755
--- a/src/gallium/state_trackers/python/retrace/interpreter.py
+++ b/progs/gallium/python/retrace/interpreter.py
@@ -272,6 +272,10 @@
     def get_paramf(self, param):
         pass
     
+    def context_create(self):
+        context = self.real.context_create()
+        return Context(self.interpreter, context)
+    
     def is_format_supported(self, format, target, tex_usage, geom_flags):
         return self.real.is_format_supported(format, target, tex_usage, geom_flags)
     
@@ -372,6 +376,9 @@
         pass
     
     def create_blend_state(self, state):
+        if isinstance(state, str):
+            state = gallium.Blend(state)
+            sys.stdout.write('\t%s\n' % state)
         return state
 
     def bind_blend_state(self, state):
@@ -430,12 +437,15 @@
 
     def delete_fs_state(self, state):
         pass
-    
+
     delete_vs_state = delete_fs_state
-    
+
     def set_blend_color(self, state):
         self.real.set_blend_color(state)
 
+    def set_stencil_ref(self, state):
+        self.real.set_stencil_ref(state)
+
     def set_clip_state(self, state):
         _state = gallium.Clip()
         _state.nr = state.nr
diff --git a/src/gallium/state_trackers/python/retrace/model.py b/progs/gallium/python/retrace/model.py
similarity index 100%
rename from src/gallium/state_trackers/python/retrace/model.py
rename to progs/gallium/python/retrace/model.py
diff --git a/src/gallium/state_trackers/python/retrace/parse.py b/progs/gallium/python/retrace/parse.py
similarity index 100%
rename from src/gallium/state_trackers/python/retrace/parse.py
rename to progs/gallium/python/retrace/parse.py
diff --git a/src/gallium/state_trackers/python/retrace/parser.py b/progs/gallium/python/retrace/parser.py
similarity index 100%
rename from src/gallium/state_trackers/python/retrace/parser.py
rename to progs/gallium/python/retrace/parser.py
diff --git a/src/gallium/state_trackers/python/samples/gs.py b/progs/gallium/python/samples/gs.py
similarity index 100%
rename from src/gallium/state_trackers/python/samples/gs.py
rename to progs/gallium/python/samples/gs.py
diff --git a/src/gallium/state_trackers/python/samples/tri.py b/progs/gallium/python/samples/tri.py
similarity index 100%
rename from src/gallium/state_trackers/python/samples/tri.py
rename to progs/gallium/python/samples/tri.py
diff --git a/src/gallium/state_trackers/python/tests/.gitignore b/progs/gallium/python/tests/.gitignore
similarity index 100%
rename from src/gallium/state_trackers/python/tests/.gitignore
rename to progs/gallium/python/tests/.gitignore
diff --git a/src/gallium/state_trackers/python/tests/base.py b/progs/gallium/python/tests/base.py
similarity index 100%
rename from src/gallium/state_trackers/python/tests/base.py
rename to progs/gallium/python/tests/base.py
diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/.gitignore b/progs/gallium/python/tests/regress/fragment-shader/.gitignore
similarity index 100%
rename from src/gallium/state_trackers/python/tests/regress/fragment-shader/.gitignore
rename to progs/gallium/python/tests/regress/fragment-shader/.gitignore
diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-abs.sh b/progs/gallium/python/tests/regress/fragment-shader/frag-abs.sh
similarity index 100%
rename from src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-abs.sh
rename to progs/gallium/python/tests/regress/fragment-shader/frag-abs.sh
diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-add.sh b/progs/gallium/python/tests/regress/fragment-shader/frag-add.sh
similarity index 100%
rename from src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-add.sh
rename to progs/gallium/python/tests/regress/fragment-shader/frag-add.sh
diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-cb-1d.sh b/progs/gallium/python/tests/regress/fragment-shader/frag-cb-1d.sh
similarity index 100%
rename from src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-cb-1d.sh
rename to progs/gallium/python/tests/regress/fragment-shader/frag-cb-1d.sh
diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-cb-2d.sh b/progs/gallium/python/tests/regress/fragment-shader/frag-cb-2d.sh
similarity index 100%
rename from src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-cb-2d.sh
rename to progs/gallium/python/tests/regress/fragment-shader/frag-cb-2d.sh
diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-dp3.sh b/progs/gallium/python/tests/regress/fragment-shader/frag-dp3.sh
similarity index 100%
rename from src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-dp3.sh
rename to progs/gallium/python/tests/regress/fragment-shader/frag-dp3.sh
diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-dp4.sh b/progs/gallium/python/tests/regress/fragment-shader/frag-dp4.sh
similarity index 100%
rename from src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-dp4.sh
rename to progs/gallium/python/tests/regress/fragment-shader/frag-dp4.sh
diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-dst.sh b/progs/gallium/python/tests/regress/fragment-shader/frag-dst.sh
similarity index 100%
rename from src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-dst.sh
rename to progs/gallium/python/tests/regress/fragment-shader/frag-dst.sh
diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-ex2.sh b/progs/gallium/python/tests/regress/fragment-shader/frag-ex2.sh
similarity index 100%
rename from src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-ex2.sh
rename to progs/gallium/python/tests/regress/fragment-shader/frag-ex2.sh
diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-flr.sh b/progs/gallium/python/tests/regress/fragment-shader/frag-flr.sh
similarity index 100%
rename from src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-flr.sh
rename to progs/gallium/python/tests/regress/fragment-shader/frag-flr.sh
diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-frc.sh b/progs/gallium/python/tests/regress/fragment-shader/frag-frc.sh
similarity index 100%
rename from src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-frc.sh
rename to progs/gallium/python/tests/regress/fragment-shader/frag-frc.sh
diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-lg2.sh b/progs/gallium/python/tests/regress/fragment-shader/frag-lg2.sh
similarity index 100%
rename from src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-lg2.sh
rename to progs/gallium/python/tests/regress/fragment-shader/frag-lg2.sh
diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-lit.sh b/progs/gallium/python/tests/regress/fragment-shader/frag-lit.sh
similarity index 100%
rename from src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-lit.sh
rename to progs/gallium/python/tests/regress/fragment-shader/frag-lit.sh
diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-lrp.sh b/progs/gallium/python/tests/regress/fragment-shader/frag-lrp.sh
similarity index 100%
rename from src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-lrp.sh
rename to progs/gallium/python/tests/regress/fragment-shader/frag-lrp.sh
diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-mad.sh b/progs/gallium/python/tests/regress/fragment-shader/frag-mad.sh
similarity index 100%
rename from src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-mad.sh
rename to progs/gallium/python/tests/regress/fragment-shader/frag-mad.sh
diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-max.sh b/progs/gallium/python/tests/regress/fragment-shader/frag-max.sh
similarity index 100%
rename from src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-max.sh
rename to progs/gallium/python/tests/regress/fragment-shader/frag-max.sh
diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-min.sh b/progs/gallium/python/tests/regress/fragment-shader/frag-min.sh
similarity index 100%
rename from src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-min.sh
rename to progs/gallium/python/tests/regress/fragment-shader/frag-min.sh
diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-mov.sh b/progs/gallium/python/tests/regress/fragment-shader/frag-mov.sh
similarity index 100%
rename from src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-mov.sh
rename to progs/gallium/python/tests/regress/fragment-shader/frag-mov.sh
diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-mul.sh b/progs/gallium/python/tests/regress/fragment-shader/frag-mul.sh
similarity index 100%
rename from src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-mul.sh
rename to progs/gallium/python/tests/regress/fragment-shader/frag-mul.sh
diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-rcp.sh b/progs/gallium/python/tests/regress/fragment-shader/frag-rcp.sh
similarity index 100%
rename from src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-rcp.sh
rename to progs/gallium/python/tests/regress/fragment-shader/frag-rcp.sh
diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-rsq.sh b/progs/gallium/python/tests/regress/fragment-shader/frag-rsq.sh
similarity index 100%
rename from src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-rsq.sh
rename to progs/gallium/python/tests/regress/fragment-shader/frag-rsq.sh
diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-sge.sh b/progs/gallium/python/tests/regress/fragment-shader/frag-sge.sh
similarity index 100%
rename from src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-sge.sh
rename to progs/gallium/python/tests/regress/fragment-shader/frag-sge.sh
diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-slt.sh b/progs/gallium/python/tests/regress/fragment-shader/frag-slt.sh
similarity index 100%
rename from src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-slt.sh
rename to progs/gallium/python/tests/regress/fragment-shader/frag-slt.sh
diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-srcmod-abs.sh b/progs/gallium/python/tests/regress/fragment-shader/frag-srcmod-abs.sh
similarity index 100%
rename from src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-srcmod-abs.sh
rename to progs/gallium/python/tests/regress/fragment-shader/frag-srcmod-abs.sh
diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-srcmod-absneg.sh b/progs/gallium/python/tests/regress/fragment-shader/frag-srcmod-absneg.sh
similarity index 100%
rename from src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-srcmod-absneg.sh
rename to progs/gallium/python/tests/regress/fragment-shader/frag-srcmod-absneg.sh
diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-srcmod-neg.sh b/progs/gallium/python/tests/regress/fragment-shader/frag-srcmod-neg.sh
similarity index 100%
rename from src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-srcmod-neg.sh
rename to progs/gallium/python/tests/regress/fragment-shader/frag-srcmod-neg.sh
diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-srcmod-swz.sh b/progs/gallium/python/tests/regress/fragment-shader/frag-srcmod-swz.sh
similarity index 100%
rename from src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-srcmod-swz.sh
rename to progs/gallium/python/tests/regress/fragment-shader/frag-srcmod-swz.sh
diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-sub.sh b/progs/gallium/python/tests/regress/fragment-shader/frag-sub.sh
similarity index 100%
rename from src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-sub.sh
rename to progs/gallium/python/tests/regress/fragment-shader/frag-sub.sh
diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-xpd.sh b/progs/gallium/python/tests/regress/fragment-shader/frag-xpd.sh
similarity index 100%
rename from src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-xpd.sh
rename to progs/gallium/python/tests/regress/fragment-shader/frag-xpd.sh
diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/fragment-shader.py b/progs/gallium/python/tests/regress/fragment-shader/fragment-shader.py
similarity index 100%
rename from src/gallium/state_trackers/python/tests/regress/fragment-shader/fragment-shader.py
rename to progs/gallium/python/tests/regress/fragment-shader/fragment-shader.py
diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/.gitignore b/progs/gallium/python/tests/regress/vertex-shader/.gitignore
similarity index 100%
rename from src/gallium/state_trackers/python/tests/regress/vertex-shader/.gitignore
rename to progs/gallium/python/tests/regress/vertex-shader/.gitignore
diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-abs.sh b/progs/gallium/python/tests/regress/vertex-shader/vert-abs.sh
similarity index 100%
rename from src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-abs.sh
rename to progs/gallium/python/tests/regress/vertex-shader/vert-abs.sh
diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-add.sh b/progs/gallium/python/tests/regress/vertex-shader/vert-add.sh
similarity index 100%
rename from src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-add.sh
rename to progs/gallium/python/tests/regress/vertex-shader/vert-add.sh
diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-arl.sh b/progs/gallium/python/tests/regress/vertex-shader/vert-arl.sh
similarity index 100%
rename from src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-arl.sh
rename to progs/gallium/python/tests/regress/vertex-shader/vert-arl.sh
diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-arr.sh b/progs/gallium/python/tests/regress/vertex-shader/vert-arr.sh
similarity index 100%
rename from src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-arr.sh
rename to progs/gallium/python/tests/regress/vertex-shader/vert-arr.sh
diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-cb-1d.sh b/progs/gallium/python/tests/regress/vertex-shader/vert-cb-1d.sh
similarity index 100%
rename from src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-cb-1d.sh
rename to progs/gallium/python/tests/regress/vertex-shader/vert-cb-1d.sh
diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-cb-2d.sh b/progs/gallium/python/tests/regress/vertex-shader/vert-cb-2d.sh
similarity index 100%
rename from src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-cb-2d.sh
rename to progs/gallium/python/tests/regress/vertex-shader/vert-cb-2d.sh
diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-dp3.sh b/progs/gallium/python/tests/regress/vertex-shader/vert-dp3.sh
similarity index 100%
rename from src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-dp3.sh
rename to progs/gallium/python/tests/regress/vertex-shader/vert-dp3.sh
diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-dp4.sh b/progs/gallium/python/tests/regress/vertex-shader/vert-dp4.sh
similarity index 100%
rename from src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-dp4.sh
rename to progs/gallium/python/tests/regress/vertex-shader/vert-dp4.sh
diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-dst.sh b/progs/gallium/python/tests/regress/vertex-shader/vert-dst.sh
similarity index 100%
rename from src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-dst.sh
rename to progs/gallium/python/tests/regress/vertex-shader/vert-dst.sh
diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-ex2.sh b/progs/gallium/python/tests/regress/vertex-shader/vert-ex2.sh
similarity index 100%
rename from src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-ex2.sh
rename to progs/gallium/python/tests/regress/vertex-shader/vert-ex2.sh
diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-flr.sh b/progs/gallium/python/tests/regress/vertex-shader/vert-flr.sh
similarity index 100%
rename from src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-flr.sh
rename to progs/gallium/python/tests/regress/vertex-shader/vert-flr.sh
diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-frc.sh b/progs/gallium/python/tests/regress/vertex-shader/vert-frc.sh
similarity index 100%
rename from src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-frc.sh
rename to progs/gallium/python/tests/regress/vertex-shader/vert-frc.sh
diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-lg2.sh b/progs/gallium/python/tests/regress/vertex-shader/vert-lg2.sh
similarity index 100%
rename from src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-lg2.sh
rename to progs/gallium/python/tests/regress/vertex-shader/vert-lg2.sh
diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-lit.sh b/progs/gallium/python/tests/regress/vertex-shader/vert-lit.sh
similarity index 100%
rename from src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-lit.sh
rename to progs/gallium/python/tests/regress/vertex-shader/vert-lit.sh
diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-lrp.sh b/progs/gallium/python/tests/regress/vertex-shader/vert-lrp.sh
similarity index 100%
rename from src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-lrp.sh
rename to progs/gallium/python/tests/regress/vertex-shader/vert-lrp.sh
diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-mad.sh b/progs/gallium/python/tests/regress/vertex-shader/vert-mad.sh
similarity index 100%
rename from src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-mad.sh
rename to progs/gallium/python/tests/regress/vertex-shader/vert-mad.sh
diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-max.sh b/progs/gallium/python/tests/regress/vertex-shader/vert-max.sh
similarity index 100%
rename from src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-max.sh
rename to progs/gallium/python/tests/regress/vertex-shader/vert-max.sh
diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-min.sh b/progs/gallium/python/tests/regress/vertex-shader/vert-min.sh
similarity index 100%
rename from src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-min.sh
rename to progs/gallium/python/tests/regress/vertex-shader/vert-min.sh
diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-mov.sh b/progs/gallium/python/tests/regress/vertex-shader/vert-mov.sh
similarity index 100%
rename from src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-mov.sh
rename to progs/gallium/python/tests/regress/vertex-shader/vert-mov.sh
diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-mul.sh b/progs/gallium/python/tests/regress/vertex-shader/vert-mul.sh
similarity index 100%
rename from src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-mul.sh
rename to progs/gallium/python/tests/regress/vertex-shader/vert-mul.sh
diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-rcp.sh b/progs/gallium/python/tests/regress/vertex-shader/vert-rcp.sh
similarity index 100%
rename from src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-rcp.sh
rename to progs/gallium/python/tests/regress/vertex-shader/vert-rcp.sh
diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-rsq.sh b/progs/gallium/python/tests/regress/vertex-shader/vert-rsq.sh
similarity index 100%
rename from src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-rsq.sh
rename to progs/gallium/python/tests/regress/vertex-shader/vert-rsq.sh
diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-sge.sh b/progs/gallium/python/tests/regress/vertex-shader/vert-sge.sh
similarity index 100%
rename from src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-sge.sh
rename to progs/gallium/python/tests/regress/vertex-shader/vert-sge.sh
diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-slt.sh b/progs/gallium/python/tests/regress/vertex-shader/vert-slt.sh
similarity index 100%
rename from src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-slt.sh
rename to progs/gallium/python/tests/regress/vertex-shader/vert-slt.sh
diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-srcmod-abs.sh b/progs/gallium/python/tests/regress/vertex-shader/vert-srcmod-abs.sh
similarity index 100%
rename from src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-srcmod-abs.sh
rename to progs/gallium/python/tests/regress/vertex-shader/vert-srcmod-abs.sh
diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-srcmod-absneg.sh b/progs/gallium/python/tests/regress/vertex-shader/vert-srcmod-absneg.sh
similarity index 100%
rename from src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-srcmod-absneg.sh
rename to progs/gallium/python/tests/regress/vertex-shader/vert-srcmod-absneg.sh
diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-srcmod-neg.sh b/progs/gallium/python/tests/regress/vertex-shader/vert-srcmod-neg.sh
similarity index 100%
rename from src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-srcmod-neg.sh
rename to progs/gallium/python/tests/regress/vertex-shader/vert-srcmod-neg.sh
diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-srcmod-swz.sh b/progs/gallium/python/tests/regress/vertex-shader/vert-srcmod-swz.sh
similarity index 100%
rename from src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-srcmod-swz.sh
rename to progs/gallium/python/tests/regress/vertex-shader/vert-srcmod-swz.sh
diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-sub.sh b/progs/gallium/python/tests/regress/vertex-shader/vert-sub.sh
similarity index 100%
rename from src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-sub.sh
rename to progs/gallium/python/tests/regress/vertex-shader/vert-sub.sh
diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-xpd.sh b/progs/gallium/python/tests/regress/vertex-shader/vert-xpd.sh
similarity index 100%
rename from src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-xpd.sh
rename to progs/gallium/python/tests/regress/vertex-shader/vert-xpd.sh
diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vertex-shader.py b/progs/gallium/python/tests/regress/vertex-shader/vertex-shader.py
similarity index 100%
rename from src/gallium/state_trackers/python/tests/regress/vertex-shader/vertex-shader.py
rename to progs/gallium/python/tests/regress/vertex-shader/vertex-shader.py
diff --git a/src/gallium/state_trackers/python/tests/surface_copy.py b/progs/gallium/python/tests/surface_copy.py
similarity index 100%
rename from src/gallium/state_trackers/python/tests/surface_copy.py
rename to progs/gallium/python/tests/surface_copy.py
diff --git a/src/gallium/state_trackers/python/tests/texture_render.py b/progs/gallium/python/tests/texture_render.py
similarity index 100%
rename from src/gallium/state_trackers/python/tests/texture_render.py
rename to progs/gallium/python/tests/texture_render.py
diff --git a/src/gallium/state_trackers/python/tests/texture_sample.py b/progs/gallium/python/tests/texture_sample.py
similarity index 100%
rename from src/gallium/state_trackers/python/tests/texture_sample.py
rename to progs/gallium/python/tests/texture_sample.py
diff --git a/src/gallium/state_trackers/python/tests/texture_transfer.py b/progs/gallium/python/tests/texture_transfer.py
similarity index 100%
rename from src/gallium/state_trackers/python/tests/texture_transfer.py
rename to progs/gallium/python/tests/texture_transfer.py
diff --git a/src/gallium/state_trackers/python/tests/tree.py b/progs/gallium/python/tests/tree.py
similarity index 100%
rename from src/gallium/state_trackers/python/tests/tree.py
rename to progs/gallium/python/tests/tree.py
diff --git a/progs/objviewer/glm.c b/progs/objviewer/glm.c
index 7f36cdf..7c964e4 100644
--- a/progs/objviewer/glm.c
+++ b/progs/objviewer/glm.c
@@ -421,6 +421,7 @@
       break;
     }
   }
+  fclose(file);
 }
 
 
@@ -475,6 +476,7 @@
     fprintf(file, "Ns %f\n", material->shininess);
     fprintf(file, "\n");
   }
+  fclose(file);
 }
 
 
diff --git a/progs/openvg/.gitignore b/progs/openvg/.gitignore
new file mode 100644
index 0000000..9b05e1e
--- /dev/null
+++ b/progs/openvg/.gitignore
@@ -0,0 +1,24 @@
+demos/lion
+demos/sp
+trivial/arc
+trivial/cap
+trivial/clear
+trivial/coord
+trivial/dash
+trivial/ellipse
+trivial/filter
+trivial/gradorigin
+trivial/lineto
+trivial/lingrad
+trivial/lookup
+trivial/mask4
+trivial/mask
+trivial/path3
+trivial/radialgrad
+trivial/readpixels
+trivial/roundedrect
+trivial/star-nonzero
+trivial/star-oddeven
+trivial/stroke2
+trivial/stroke
+trivial/vguarc
diff --git a/progs/redbook/Makefile b/progs/redbook/Makefile
index 0ba5fbb..b41e488 100644
--- a/progs/redbook/Makefile
+++ b/progs/redbook/Makefile
@@ -7,16 +7,84 @@
 
 LIB_DEP = $(TOP)/$(LIB_DIR)/$(GL_LIB_NAME) $(TOP)/$(LIB_DIR)/$(GLU_LIB_NAME) $(TOP)/$(LIB_DIR)/$(GLUT_LIB_NAME)
 
-LIBS = -L$(TOP)/$(LIB_DIR) -l$(GLUT_LIB) -l$(GLU_LIB) -l$(GL_LIB) $(APP_LIB_DEPS)
+LIBS = -L$(TOP)/$(LIB_DIR) -l$(GLUT_LIB) -l$(GLEW_LIB) -l$(GLU_LIB) -l$(GL_LIB) $(APP_LIB_DEPS)
 
-PROGS = aaindex aapoly aargb accanti accpersp alpha alpha3D anti \
-	bezcurve bezmesh checker clip colormat cube depthcue dof \
-	double drawf feedback fog fogindex font hello image light \
-	lines list material mipmap model movelight nurbs pickdepth \
-	picksquare plane planet polyoff polys quadric robot sccolorlight \
-	scene scenebamb sceneflat select smooth stencil stroke surface \
-	teaambient teapots tess tesswind texbind texgen texprox texsub \
-	texturesurf torus trim unproject varray wrap 
+PROGS = aaindex \
+	aapoly \
+	aargb \
+	accanti \
+	accpersp \
+	alpha \
+	alpha3D \
+	anti \
+	bezcurve \
+	bezmesh \
+	checker \
+	clip \
+	colormat \
+	combiner \
+	convolution \
+	cube \
+	cubemap \
+	depthcue \
+	dof \
+	double \
+	drawf \
+	feedback \
+	fog \
+	fogcoord \
+	fogindex \
+	font \
+	hello \
+	histogram \
+	image \
+	light \
+	lines \
+	list \
+	material \
+	minmax \
+	mipmap \
+	model \
+	movelight \
+	multitex \
+	multisamp \
+	mvarray \
+	nurbs \
+	pickdepth \
+	picksquare \
+	plane \
+	planet \
+	pointp \
+	polyoff \
+	polys \
+	quadric \
+	robot \
+	sccolorlight \
+	scene \
+	scenebamb \
+	sceneflat \
+	select \
+	shadowmap \
+	smooth \
+	stencil \
+	stroke \
+	surface \
+	surfpoints \
+	teaambient \
+	teapots \
+	tess \
+	tesswind \
+	texbind \
+	texgen \
+	texprox \
+	texsub \
+	texturesurf \
+	texture3d \
+	torus \
+	trim \
+	unproject \
+	varray \
+	wrap 
 
 
 
diff --git a/progs/redbook/SConscript b/progs/redbook/SConscript
index 24d7cff..750ad36 100644
--- a/progs/redbook/SConscript
+++ b/progs/redbook/SConscript
@@ -14,29 +14,39 @@
     'checker',
     'clip',
     'colormat',
+    'combiner',
+    'convolution',
     'cube',
+    'cubemap',
     'depthcue',
     'dof',
     'double',
     'drawf',
     'feedback',
     'fog',
+    'fogcoord',
     'fogindex',
     'font',
     'hello',
+    'histogram',
     'image',
     'light',
     'lines',
     'list',
     'material',
+    'minmax',
     'mipmap',
     'model',
     'movelight',
+    'multisamp',
+    'multitex',
+    'mvarray',
     'nurbs',
     'pickdepth',
     'picksquare',
     'plane',
     'planet',
+    'pointp',
     'polyoff',
     'polys',
     'quadric',
@@ -46,10 +56,12 @@
     'scene',
     'sceneflat',
     'select',
+    'shadowmap',
     'smooth',
     'stencil',
     'stroke',
     'surface',
+    'surfpoints',
     'teaambient',
     'teapots',
     'tess',
@@ -59,6 +71,7 @@
     'texprox',
     'texsub',
     'texturesurf',
+    'texture3d',
     'torus',
     'trim',
     'unproject',
diff --git a/progs/redbook/combiner.c b/progs/redbook/combiner.c
new file mode 100644
index 0000000..92e4de4
--- /dev/null
+++ b/progs/redbook/combiner.c
@@ -0,0 +1,379 @@
+/*
+ * Copyright (c) 1993-2003, Silicon Graphics, Inc.
+ * All Rights Reserved
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose and without fee is hereby granted, provided that the above
+ * copyright notice appear in all copies and that both the copyright
+ * notice and this permission notice appear in supporting documentation,
+ * and that the name of Silicon Graphics, Inc. not be used in
+ * advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission.
+ *
+ * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS" AND
+ * WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
+ * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
+ * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
+ * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION, LOSS OF
+ * PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF THIRD
+ * PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN ADVISED OF
+ * THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE POSSESSION, USE
+ * OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * US Government Users Restricted Rights 
+ * Use, duplication, or disclosure by the Government is subject to
+ * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
+ * (c)(1)(ii) of the Rights in Technical Data and Computer Software
+ * clause at DFARS 252.227-7013 and/or in similar or successor clauses
+ * in the FAR or the DOD or NASA FAR Supplement.  Unpublished - rights
+ * reserved under the copyright laws of the United States.
+ *
+ * Contractor/manufacturer is:
+ *	Silicon Graphics, Inc.
+ *	1500 Crittenden Lane
+ *	Mountain View, CA  94043
+ *	United State of America
+ *
+ * OpenGL(R) is a registered trademark of Silicon Graphics, Inc.
+ */
+
+/*  combiner.c
+ *  This program renders a variety of quads showing different
+ *  effects of texture combiner functions.
+ *
+ *  The first row renders an untextured polygon (so you can 
+ *  compare the fragment colors) and then the 2 textures.
+ *  The second row shows several different combiner functions
+ *  on a single texture:  replace, modulate, add, add-signed,
+ *  and subtract.  
+ *  The third row shows the interpolate combiner function
+ *  on a single texture with a constant color/alpha value,
+ *  varying the amount of interpolation.  
+ *  The fourth row uses multitexturing with two textures
+ *  and different combiner functions.
+ *  The fifth row are some combiner experiments:  using the
+ *  scaling factor and reversing the order of subtraction
+ *  for a combination function.
+ */
+#include <GL/glew.h>
+#include <GL/glut.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#define	imageWidth 8
+#define	imageHeight 8
+/*     arrays for two textures	    */
+static GLubyte image0[imageHeight][imageWidth][4];
+static GLubyte image1[imageHeight][imageWidth][4];
+
+static GLuint texName[4];
+
+static void makeImages(void)
+{
+   int i, j, c;
+   for (i = 0; i < imageHeight; i++) {
+      for (j = 0; j < imageWidth; j++) {
+         c = ((i&2)==0)*255;   /*  horiz b & w stripes  */
+         image0[i][j][0] = (GLubyte) c;
+         image0[i][j][1] = (GLubyte) c;
+         image0[i][j][2] = (GLubyte) c;
+         image0[i][j][3] = (GLubyte) 255;
+         c = ((j&4)!=0)*128;   /*  wider vertical 50% cyan and black stripes  */
+         image1[i][j][0] = (GLubyte) 0;
+         image1[i][j][1] = (GLubyte) c;
+         image1[i][j][2] = (GLubyte) c;
+         image1[i][j][3] = (GLubyte) 255;
+      }
+   }
+}
+
+static void init(void)
+{    
+   glClearColor (0.0, 0.0, 0.0, 0.0);
+   glShadeModel(GL_SMOOTH);
+
+   makeImages();
+   glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+
+   glGenTextures(4, texName);
+
+   glBindTexture(GL_TEXTURE_2D, texName[0]);
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+   glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, imageWidth, imageHeight, 
+                0, GL_RGBA, GL_UNSIGNED_BYTE, image0);
+
+   glBindTexture(GL_TEXTURE_2D, texName[1]);
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+   glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, imageWidth, imageHeight, 
+                0, GL_RGBA, GL_UNSIGNED_BYTE, image1);
+
+/*  smooth-shaded polygon with multiple texture coordinates  */
+   glNewList (1, GL_COMPILE);
+   glBegin(GL_QUADS);
+   glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 0.0, 0.0); 
+   glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 0.0, 0.0); 
+   glColor3f (0.5, 1.0, 0.25);
+   glVertex3f(0.0, 0.0, 0.0);
+   glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 0.0, 2.0); 
+   glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 0.0, 2.0); 
+   glColor3f (1.0, 1.0, 1.0);
+   glVertex3f(0.0, 1.0, 0.0);
+   glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 2.0, 2.0); 
+   glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 2.0, 2.0); 
+   glColor3f (1.0, 1.0, 1.0);
+   glVertex3f(1.0, 1.0, 0.0);
+   glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 2.0, 0.0); 
+   glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 2.0, 0.0); 
+   glColor3f (1.0, 0.5, 0.25);
+   glVertex3f(1.0, 0.0, 0.0);
+   glEnd();
+   glEndList ();
+}
+
+static void display(void)
+{
+   static GLfloat constColor[4] = {0.0, 0.0, 0.0, 0.0};  /*  for use as constant texture color  */
+
+   glClear(GL_COLOR_BUFFER_BIT);
+
+   glDisable(GL_TEXTURE_2D);  /*  untextured polygon--see the "fragment" colors  */
+   glPushMatrix();
+   glTranslatef(0.0, 5.0, 0.0);
+   glCallList(1);
+   glPopMatrix();
+
+   glEnable(GL_TEXTURE_2D);
+/*  draw ordinary textured polys; 1 texture unit; combine mode disabled  */
+   glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+   glPushMatrix();
+   glBindTexture(GL_TEXTURE_2D, texName[0]);
+   glTranslatef(1.0, 5.0, 0.0);
+   glCallList(1);
+   glPopMatrix();
+
+   glPushMatrix();
+   glBindTexture(GL_TEXTURE_2D, texName[1]);
+   glTranslatef(2.0, 5.0, 0.0);
+   glCallList(1);
+   glPopMatrix();
+
+/*  different combine modes enabled; 1 texture unit
+ *  defaults are:
+ *  glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE);
+ *  glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR);
+ *  glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PREVIOUS_ARB);
+ *  glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR);
+ */
+   glBindTexture(GL_TEXTURE_2D, texName[0]);
+   glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
+   glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_REPLACE);
+   glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE);
+   glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR);
+   glPushMatrix();
+   glTranslatef(1.0, 4.0, 0.0);
+   glCallList(1);
+   glPopMatrix();
+
+   glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE);
+   glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PREVIOUS_ARB);
+   glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR);
+   glPushMatrix();
+   glTranslatef(2.0, 4.0, 0.0);
+   glCallList(1);
+   glPopMatrix();
+
+   glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_ADD);
+   glPushMatrix();
+   glTranslatef(3.0, 4.0, 0.0);
+   glCallList(1);
+   glPopMatrix();
+
+   glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_ADD_SIGNED_ARB);
+   glPushMatrix();
+   glTranslatef(4.0, 4.0, 0.0);
+   glCallList(1);
+   glPopMatrix();
+
+   glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_SUBTRACT_ARB);
+   glPushMatrix();
+   glTranslatef(5.0, 4.0, 0.0);
+   glCallList(1);
+   glPopMatrix();
+
+/*  interpolate combine with constant color; 1 texture unit 
+ *  use different alpha values for constant color
+ *  defaults are:
+ *  glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE);
+ *  glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR);
+ *  glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PREVIOUS_ARB);
+ *  glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR);
+ *  glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE2_RGB_ARB, GL_CONSTANT_ARB);
+ *  glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND2_RGB_ARB, GL_SRC_ALPHA);
+ */
+   constColor[3] = 0.2;
+   glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, constColor);
+   glBindTexture(GL_TEXTURE_2D, texName[0]);
+   glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
+   glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_INTERPOLATE_ARB);
+   glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE);
+   glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR);
+   glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PREVIOUS_ARB);
+   glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR);
+   glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE2_RGB_ARB, GL_CONSTANT_ARB);
+   glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND2_RGB_ARB, GL_SRC_ALPHA);
+   glPushMatrix();
+   glTranslatef(1.0, 3.0, 0.0);
+   glCallList(1);
+   glPopMatrix();
+
+   constColor[3] = 0.4;
+   glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, constColor);
+   glPushMatrix();
+   glTranslatef(2.0, 3.0, 0.0);
+   glCallList(1);
+   glPopMatrix();
+
+   constColor[3] = 0.6;
+   glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, constColor);
+   glPushMatrix();
+   glTranslatef(3.0, 3.0, 0.0);
+   glCallList(1);
+   glPopMatrix();
+
+   constColor[4] = 0.8;
+   glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, constColor);
+   glPushMatrix();
+   glTranslatef(4.0, 3.0, 0.0);
+   glCallList(1);
+   glPopMatrix();
+
+/*  combine textures 0 & 1
+ *  defaults are:
+ *  glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE);
+ *  glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR);
+ *  glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PREVIOUS_ARB);
+ *  glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR);
+ */
+
+   glActiveTextureARB (GL_TEXTURE0_ARB);
+   glEnable (GL_TEXTURE_2D);
+   glBindTexture(GL_TEXTURE_2D, texName[0]);
+   glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+
+   glActiveTextureARB (GL_TEXTURE1_ARB);
+   glEnable (GL_TEXTURE_2D);
+   glBindTexture(GL_TEXTURE_2D, texName[1]);
+   glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
+   glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_REPLACE);
+   glPushMatrix();
+   glTranslatef(1.0, 2.0, 0.0);
+   glCallList(1);
+   glPopMatrix();
+
+   /*  try different combiner modes of texture unit 1  */
+   glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE);
+   glPushMatrix();
+   glTranslatef(2.0, 2.0, 0.0);
+   glCallList(1);
+   glPopMatrix();
+
+   glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_ADD);
+   glPushMatrix();
+   glTranslatef(3.0, 2.0, 0.0);
+   glCallList(1);
+   glPopMatrix();
+
+   glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_ADD_SIGNED_ARB);
+   glPushMatrix();
+   glTranslatef(4.0, 2.0, 0.0);
+   glCallList(1);
+   glPopMatrix();
+
+   glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_SUBTRACT_ARB);
+   glPushMatrix();
+   glTranslatef(5.0, 2.0, 0.0);
+   glCallList(1);
+   glPopMatrix();
+
+/*  some experiments */
+
+/*  see the effect of RGB_SCALE   */
+   glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, 2.0);
+   glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_REPLACE);
+   glPushMatrix();
+   glTranslatef(1.0, 1.0, 0.0);
+   glCallList(1);
+   glPopMatrix();
+
+   glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE);
+   glPushMatrix();
+   glTranslatef(2.0, 1.0, 0.0);
+   glCallList(1);
+   glPopMatrix();
+   glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, 1.0);
+
+/*  using SOURCE0 and SOURCE1, reverse the order of subtraction Arg1-Arg0  */
+
+   glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
+   glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_SUBTRACT_ARB);
+   glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PREVIOUS_ARB);
+   glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR);
+   glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_TEXTURE);
+   glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR);
+   glPushMatrix();
+   glTranslatef(5.0, 1.0, 0.0);
+   glCallList(1);
+   glPopMatrix();
+
+   glActiveTextureARB (GL_TEXTURE1_ARB);  /*  deactivate multitexturing  */
+   glDisable (GL_TEXTURE_2D);
+   glActiveTextureARB (GL_TEXTURE0_ARB);  /*  activate single texture unit  */
+
+   glFlush();
+}
+
+static void reshape(int w, int h)
+{
+   glViewport(0, 0, (GLsizei) w, (GLsizei) h);
+   glMatrixMode(GL_PROJECTION);
+   glLoadIdentity();
+   gluOrtho2D(0.0, 7.0, 0.0, 7.0);
+   glMatrixMode(GL_MODELVIEW);
+   glLoadIdentity();
+}
+
+static void keyboard (unsigned char key, int x, int y)
+{
+   switch (key) {
+      case 27:
+         exit(0);
+         break;
+      default:
+         break;
+   }
+}
+
+int main(int argc, char** argv)
+{
+   glutInit(&argc, argv);
+   glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
+   glutInitWindowSize(400, 400);
+   glutInitWindowPosition(100, 100);
+   glutCreateWindow(argv[0]);
+   glewInit();
+   init();
+   glutDisplayFunc(display);
+   glutReshapeFunc(reshape);
+   glutKeyboardFunc(keyboard);
+   glutMainLoop();
+   return 0; 
+}
diff --git a/progs/redbook/convolution.c b/progs/redbook/convolution.c
new file mode 100644
index 0000000..0898ef2
--- /dev/null
+++ b/progs/redbook/convolution.c
@@ -0,0 +1,214 @@
+/*
+ * Copyright (c) 1993-2003, Silicon Graphics, Inc.
+ * All Rights Reserved
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose and without fee is hereby granted, provided that the above
+ * copyright notice appear in all copies and that both the copyright
+ * notice and this permission notice appear in supporting documentation,
+ * and that the name of Silicon Graphics, Inc. not be used in
+ * advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission.
+ *
+ * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS" AND
+ * WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
+ * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
+ * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
+ * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION, LOSS OF
+ * PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF THIRD
+ * PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN ADVISED OF
+ * THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE POSSESSION, USE
+ * OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * US Government Users Restricted Rights 
+ * Use, duplication, or disclosure by the Government is subject to
+ * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
+ * (c)(1)(ii) of the Rights in Technical Data and Computer Software
+ * clause at DFARS 252.227-7013 and/or in similar or successor clauses
+ * in the FAR or the DOD or NASA FAR Supplement.  Unpublished - rights
+ * reserved under the copyright laws of the United States.
+ *
+ * Contractor/manufacturer is:
+ *	Silicon Graphics, Inc.
+ *	1500 Crittenden Lane
+ *	Mountain View, CA  94043
+ *	United State of America
+ *
+ * OpenGL(R) is a registered trademark of Silicon Graphics, Inc.
+ */
+
+/*
+ *  convolution.c
+ *  Use various 2D convolutions filters to find edges in an image.
+ *  
+ */
+#include <GL/glew.h>
+#include <GL/glut.h>
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+
+static GLuint bswap(GLuint x)
+{
+   const GLuint ui = 1;
+   const GLubyte *ubp = (const GLubyte *) &ui;
+   if (*ubp == 1) {
+      /* we're on little endiang so byteswap x */
+      GLsizei y =  ((x >> 24)
+                    | ((x >> 8) & 0xff00)
+                    | ((x << 8) & 0xff0000)
+                    | ((x << 24) & 0xff000000));
+      return y;
+   }
+   else {
+      return x;
+   }
+}
+
+
+static GLubyte *
+readImage( const char* filename, GLsizei* width, GLsizei *height )
+{
+    int       n;
+    GLubyte*  pixels;
+
+    FILE* infile = fopen( filename, "rb" );
+
+    if ( !infile ) {
+	fprintf( stderr, "Unable to open file '%s'\n", filename );
+        exit(1);
+    }
+
+    fread( width, sizeof( GLsizei ), 1, infile );
+    fread( height, sizeof( GLsizei ), 1, infile );
+
+    *width = bswap(*width);
+    *height = bswap(*height);
+
+    assert(*width > 0);
+    assert(*height > 0);
+
+    n = 3 * (*width) * (*height);
+
+    pixels = (GLubyte *) malloc( n * sizeof( GLubyte ));
+    if ( !pixels ) {
+	fprintf( stderr, "Unable to malloc() bytes for pixels\n" );
+	fclose( infile );
+	return NULL;
+    }
+
+    fread( pixels, sizeof( GLubyte ), n, infile );
+    
+    fclose( infile );
+
+    return pixels;
+}
+
+
+GLubyte  *pixels;
+GLsizei   width, height;
+
+GLfloat  horizontal[3][3] = {
+    { 0, -1, 0 },
+    { 0,  1, 0 },
+    { 0,  0, 0 }
+};
+
+GLfloat  vertical[3][3] = {
+    {  0, 0, 0 },
+    { -1, 1, 0 },
+    {  0, 0, 0 }
+};
+
+GLfloat  laplacian[3][3] = {
+    { -0.125, -0.125, -0.125 },
+    { -0.125,  1.0  , -0.125 },
+    { -0.125, -0.125, -0.125 },
+};
+
+
+static void init(void)
+{
+   if (!glutExtensionSupported("GL_ARB_imaging")) {
+      fprintf(stderr, "Sorry, this program requires GL_ARB_imaging.\n");
+      exit(1);
+   }
+
+   glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+   glClearColor(0.0, 0.0, 0.0, 0.0);
+
+   printf("Using the horizontal filter\n");
+   glConvolutionFilter2D(GL_CONVOLUTION_2D, GL_LUMINANCE,
+			 3, 3, GL_LUMINANCE, GL_FLOAT, horizontal);
+   glEnable(GL_CONVOLUTION_2D);
+}
+
+static void display(void)
+{
+   glClear(GL_COLOR_BUFFER_BIT);
+   glRasterPos2i( 1, 1);
+   glDrawPixels(width, height, GL_RGB, GL_UNSIGNED_BYTE, pixels);
+   glFlush();
+}
+
+static void reshape(int w, int h)
+{
+   glViewport(0, 0, (GLsizei) w, (GLsizei) h);
+   glMatrixMode(GL_PROJECTION);
+   glLoadIdentity();
+   glOrtho(0, w, 0, h, -1.0, 1.0);
+   glMatrixMode(GL_MODELVIEW);
+}
+
+static void keyboard(unsigned char key, int x, int y)
+{
+   switch (key) {
+       case 'h' :
+	   printf("Using a horizontal filter\n");
+	   glConvolutionFilter2D(GL_CONVOLUTION_2D, GL_LUMINANCE, 3, 3,
+				  GL_LUMINANCE, GL_FLOAT, horizontal);
+	   break;
+
+       case 'v' : 
+	   printf("Using the vertical filter\n");
+	   glConvolutionFilter2D(GL_CONVOLUTION_2D, GL_LUMINANCE, 3, 3,
+				  GL_LUMINANCE, GL_FLOAT, vertical);
+	   break;
+
+       case 'l' :
+	   printf("Using the laplacian filter\n");
+	   glConvolutionFilter2D(GL_CONVOLUTION_2D, GL_LUMINANCE, 3, 3,
+				  GL_LUMINANCE, GL_FLOAT, laplacian);
+	   break;
+
+       case 27:
+         exit(0);
+   }
+   glutPostRedisplay();
+}
+
+/*  Main Loop
+ *  Open window with initial window size, title bar, 
+ *  RGBA display mode, and handle input events.
+ */
+int main(int argc, char** argv)
+{
+   pixels = readImage("leeds.bin", &width, &height);
+
+   glutInit(&argc, argv);
+   glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA);
+   glutInitWindowSize(width, height);
+   glutInitWindowPosition(100, 100);
+   glutCreateWindow(argv[0]);
+   glewInit();
+   init();
+   glutReshapeFunc(reshape);
+   glutKeyboardFunc(keyboard);
+   glutDisplayFunc(display);
+   glutMainLoop();
+   return 0;
+}
diff --git a/progs/redbook/cubemap.c b/progs/redbook/cubemap.c
new file mode 100644
index 0000000..92026c7
--- /dev/null
+++ b/progs/redbook/cubemap.c
@@ -0,0 +1,205 @@
+/*
+ * Copyright (c) 1993-2003, Silicon Graphics, Inc.
+ * All Rights Reserved
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose and without fee is hereby granted, provided that the above
+ * copyright notice appear in all copies and that both the copyright
+ * notice and this permission notice appear in supporting documentation,
+ * and that the name of Silicon Graphics, Inc. not be used in
+ * advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission.
+ *
+ * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS" AND
+ * WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
+ * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
+ * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
+ * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION, LOSS OF
+ * PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF THIRD
+ * PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN ADVISED OF
+ * THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE POSSESSION, USE
+ * OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * US Government Users Restricted Rights 
+ * Use, duplication, or disclosure by the Government is subject to
+ * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
+ * (c)(1)(ii) of the Rights in Technical Data and Computer Software
+ * clause at DFARS 252.227-7013 and/or in similar or successor clauses
+ * in the FAR or the DOD or NASA FAR Supplement.  Unpublished - rights
+ * reserved under the copyright laws of the United States.
+ *
+ * Contractor/manufacturer is:
+ *	Silicon Graphics, Inc.
+ *	1500 Crittenden Lane
+ *	Mountain View, CA  94043
+ *	United State of America
+ *
+ * OpenGL(R) is a registered trademark of Silicon Graphics, Inc.
+ */
+
+/*  cubemap.c
+ *
+ *  This program demonstrates cube map textures.
+ *  Six different colored checker board textures are
+ *  created and applied to a lit sphere.
+ *
+ *  Pressing the 'f' and 'b' keys translate the viewer
+ *  forward and backward.
+ */
+
+#include <GL/glut.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#define	imageSize 4
+static GLubyte image1[imageSize][imageSize][4];
+static GLubyte image2[imageSize][imageSize][4];
+static GLubyte image3[imageSize][imageSize][4];
+static GLubyte image4[imageSize][imageSize][4];
+static GLubyte image5[imageSize][imageSize][4];
+static GLubyte image6[imageSize][imageSize][4];
+
+static GLdouble ztrans = 0.0;
+
+static void makeImages(void)
+{
+   int i, j, c;
+    
+   for (i = 0; i < imageSize; i++) {
+      for (j = 0; j < imageSize; j++) {
+         c = ( ((i & 0x1) == 0) ^ ((j & 0x1) == 0) ) * 255;
+         image1[i][j][0] = (GLubyte) c;
+         image1[i][j][1] = (GLubyte) c;
+         image1[i][j][2] = (GLubyte) c;
+         image1[i][j][3] = (GLubyte) 255;
+
+         image2[i][j][0] = (GLubyte) c;
+         image2[i][j][1] = (GLubyte) c;
+         image2[i][j][2] = (GLubyte) 0;
+         image2[i][j][3] = (GLubyte) 255;
+
+         image3[i][j][0] = (GLubyte) c;
+         image3[i][j][1] = (GLubyte) 0;
+         image3[i][j][2] = (GLubyte) c;
+         image3[i][j][3] = (GLubyte) 255;
+
+         image4[i][j][0] = (GLubyte) 0;
+         image4[i][j][1] = (GLubyte) c;
+         image4[i][j][2] = (GLubyte) c;
+         image4[i][j][3] = (GLubyte) 255;
+
+         image5[i][j][0] = (GLubyte) 255;
+         image5[i][j][1] = (GLubyte) c;
+         image5[i][j][2] = (GLubyte) c;
+         image5[i][j][3] = (GLubyte) 255;
+
+         image6[i][j][0] = (GLubyte) c;
+         image6[i][j][1] = (GLubyte) c;
+         image6[i][j][2] = (GLubyte) 255;
+         image6[i][j][3] = (GLubyte) 255;
+      }
+   }
+}
+
+static void init(void)
+{
+   GLfloat diffuse[4] = {1.0, 1.0, 1.0, 1.0};
+
+   glClearColor (0.0, 0.0, 0.0, 0.0);
+   glEnable(GL_DEPTH_TEST);
+   glShadeModel(GL_SMOOTH);
+
+   makeImages();
+   glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+   glTexParameteri(GL_TEXTURE_CUBE_MAP_EXT, GL_TEXTURE_WRAP_S, GL_REPEAT);
+   glTexParameteri(GL_TEXTURE_CUBE_MAP_EXT, GL_TEXTURE_WRAP_T, GL_REPEAT);
+   glTexParameteri(GL_TEXTURE_CUBE_MAP_EXT, GL_TEXTURE_WRAP_R, GL_REPEAT);
+   glTexParameteri(GL_TEXTURE_CUBE_MAP_EXT, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+   glTexParameteri(GL_TEXTURE_CUBE_MAP_EXT, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+   glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X_EXT, 0, GL_RGBA, imageSize, 
+                imageSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, image1);
+   glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X_EXT, 0, GL_RGBA, imageSize, 
+                imageSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, image4);
+   glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y_EXT, 0, GL_RGBA, imageSize,
+                imageSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, image2);
+   glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_EXT, 0, GL_RGBA, imageSize,
+                imageSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, image5);
+   glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z_EXT, 0, GL_RGBA, imageSize,
+                imageSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, image3);
+   glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT, 0, GL_RGBA, imageSize,
+                imageSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, image6);
+   glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_EXT);
+   glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_EXT);
+   glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_EXT); 
+   glEnable(GL_TEXTURE_GEN_S);
+   glEnable(GL_TEXTURE_GEN_T);
+   glEnable(GL_TEXTURE_GEN_R);
+
+   glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+
+   glEnable(GL_TEXTURE_CUBE_MAP_EXT);   
+   glEnable(GL_LIGHTING);
+   glEnable(GL_LIGHT0);
+   glEnable(GL_AUTO_NORMAL);
+   glEnable(GL_NORMALIZE);
+   glMaterialfv (GL_FRONT, GL_DIFFUSE, diffuse);
+}
+
+static void display(void)
+{
+   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+   glPushMatrix ();
+   glTranslatef (0.0, 0.0, ztrans);
+   glutSolidSphere (5.0, 20, 10);
+   glPopMatrix ();
+   glutSwapBuffers();
+}
+
+static void reshape(int w, int h)
+{
+   glViewport(0, 0, (GLsizei) w, (GLsizei) h);
+   glMatrixMode(GL_PROJECTION);
+   glLoadIdentity();
+   gluPerspective(40.0, (GLfloat) w/(GLfloat) h, 1.0, 300.0);
+   glMatrixMode(GL_MODELVIEW);
+   glLoadIdentity();
+   glTranslatef(0.0, 0.0, -20.0);
+}
+
+static void keyboard (unsigned char key, int x, int y)
+{
+   switch (key) {
+      case 'f':
+         ztrans = ztrans - 0.2;
+         glutPostRedisplay();
+         break;
+      case 'b':
+         ztrans = ztrans + 0.2;
+         glutPostRedisplay();
+         break;
+      case 27:
+         exit(0);
+         break;
+      default:
+         break;
+   }
+}
+
+int main(int argc, char** argv)
+{
+   glutInit(&argc, argv);
+   glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
+   glutInitWindowSize(400, 400);
+   glutInitWindowPosition(100, 100);
+   glutCreateWindow (argv[0]);
+   init ();
+   glutDisplayFunc(display);
+   glutReshapeFunc(reshape);
+   glutKeyboardFunc(keyboard);
+   glutMainLoop();
+   return 0;
+}
diff --git a/progs/redbook/fogcoord.c b/progs/redbook/fogcoord.c
new file mode 100644
index 0000000..17ef7ae
--- /dev/null
+++ b/progs/redbook/fogcoord.c
@@ -0,0 +1,194 @@
+/*
+ * Copyright (c) 1993-2003, Silicon Graphics, Inc.
+ * All Rights Reserved
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose and without fee is hereby granted, provided that the above
+ * copyright notice appear in all copies and that both the copyright
+ * notice and this permission notice appear in supporting documentation,
+ * and that the name of Silicon Graphics, Inc. not be used in
+ * advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission.
+ *
+ * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS" AND
+ * WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
+ * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
+ * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
+ * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION, LOSS OF
+ * PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF THIRD
+ * PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN ADVISED OF
+ * THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE POSSESSION, USE
+ * OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * US Government Users Restricted Rights 
+ * Use, duplication, or disclosure by the Government is subject to
+ * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
+ * (c)(1)(ii) of the Rights in Technical Data and Computer Software
+ * clause at DFARS 252.227-7013 and/or in similar or successor clauses
+ * in the FAR or the DOD or NASA FAR Supplement.  Unpublished - rights
+ * reserved under the copyright laws of the United States.
+ *
+ * Contractor/manufacturer is:
+ *	Silicon Graphics, Inc.
+ *	1500 Crittenden Lane
+ *	Mountain View, CA  94043
+ *	United State of America
+ *
+ * OpenGL(R) is a registered trademark of Silicon Graphics, Inc.
+ */
+
+/*
+ *  fogcoord.c
+ *
+ *  This program demonstrates the use of explicit fog 
+ *  coordinates.  You can press the keyboard and change 
+ *  the fog coordinate value at any vertex.  You can
+ *  also switch between using explicit fog coordinates 
+ *  and the default fog generation mode.
+ * 
+ *  Pressing the 'f' and 'b' keys move the viewer forward
+ *  and backwards. 
+ *  Pressing 'c' initiates the default fog generation.
+ *  Pressing capital 'C' restores explicit fog coordinates.
+ *  Pressing '1', '2', '3', '8', '9', and '0' add or
+ *  subtract from the fog coordinate values at one of the
+ *  three vertices of the triangle. 
+ */
+
+#include <GL/glew.h>
+#include <GL/glut.h>
+#include <math.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+static GLfloat f1, f2, f3;
+
+/*  Initialize fog
+ */
+static void init(void)
+{
+   GLfloat fogColor[4] = {0.0, 0.25, 0.25, 1.0};
+   f1 = 1.0f;
+   f2 = 5.0f;
+   f3 = 10.0f;
+
+   glEnable(GL_FOG);
+   glFogi (GL_FOG_MODE, GL_EXP);
+   glFogfv (GL_FOG_COLOR, fogColor);
+   glFogf (GL_FOG_DENSITY, 0.25);
+   glHint (GL_FOG_HINT, GL_DONT_CARE);
+   glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FOG_COORDINATE_EXT);
+   glClearColor(0.0, 0.25, 0.25, 1.0);  /* fog color */
+}
+
+/* display() draws a triangle at an angle.
+ */
+static void display(void)
+{
+   glClear(GL_COLOR_BUFFER_BIT);
+
+   glColor3f (1.0f, 0.75f, 0.0f);
+   glBegin (GL_TRIANGLES);
+   glFogCoordfEXT (f1); 
+   glVertex3f (2.0f, -2.0f, 0.0f);
+   glFogCoordfEXT (f2); 
+   glVertex3f (-2.0f, 0.0f, -5.0f);
+   glFogCoordfEXT (f3); 
+   glVertex3f (0.0f, 2.0f, -10.0f);
+   glEnd();
+
+   glutSwapBuffers();
+}
+
+static void reshape(int w, int h)
+{
+   glViewport(0, 0, (GLsizei) w, (GLsizei) h);
+   glMatrixMode(GL_PROJECTION);
+   glLoadIdentity();
+   gluPerspective (45.0, 1.0, 0.25, 25.0);
+   glMatrixMode(GL_MODELVIEW);
+   glLoadIdentity ();
+   glTranslatef (0.0, 0.0, -5.0);
+}
+
+static void keyboard(unsigned char key, int x, int y)
+{
+   switch (key) {
+      case 'c':
+         glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);
+         glutPostRedisplay();
+         break;
+      case 'C':
+         glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FOG_COORDINATE_EXT);
+         glutPostRedisplay();
+         break;
+      case '1':
+         f1 = f1 + 0.25; 
+         glutPostRedisplay();
+         break;
+      case '2':
+         f2 = f2 + 0.25; 
+         glutPostRedisplay();
+         break;
+      case '3':
+         f3 = f3 + 0.25; 
+         glutPostRedisplay();
+         break;
+      case '8':
+         if (f1 > 0.25) {
+            f1 = f1 - 0.25; 
+            glutPostRedisplay();
+         }
+         break;
+      case '9':
+         if (f2 > 0.25) {
+            f2 = f2 - 0.25; 
+            glutPostRedisplay();
+         }
+         break;
+      case '0':
+         if (f3 > 0.25) {
+            f3 = f3 - 0.25; 
+            glutPostRedisplay();
+         }
+         break;
+      case 'b':
+         glMatrixMode (GL_MODELVIEW);
+         glTranslatef (0.0, 0.0, -0.25);
+         glutPostRedisplay();
+         break;
+      case 'f':
+         glMatrixMode (GL_MODELVIEW);
+         glTranslatef (0.0, 0.0, 0.25);
+         glutPostRedisplay();
+         break;
+      case 27:
+         exit(0);
+         break;
+      default:
+         break;
+   }
+}
+
+
+/*  Main Loop
+ *  Open window with initial window size, title bar, 
+ *  RGBA display mode, depth buffer, and handle input events.
+ */
+int main(int argc, char** argv)
+{
+   glutInit(&argc, argv);
+   glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB);
+   glutInitWindowSize(500, 500);
+   glutCreateWindow(argv[0]);
+   glewInit();
+   init();
+   glutReshapeFunc (reshape);
+   glutKeyboardFunc (keyboard);
+   glutDisplayFunc (display);
+   glutMainLoop();
+   return 0;
+}
diff --git a/progs/redbook/histogram.c b/progs/redbook/histogram.c
new file mode 100644
index 0000000..70a5282
--- /dev/null
+++ b/progs/redbook/histogram.c
@@ -0,0 +1,209 @@
+/*
+ * Copyright (c) 1993-2003, Silicon Graphics, Inc.
+ * All Rights Reserved
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose and without fee is hereby granted, provided that the above
+ * copyright notice appear in all copies and that both the copyright
+ * notice and this permission notice appear in supporting documentation,
+ * and that the name of Silicon Graphics, Inc. not be used in
+ * advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission.
+ *
+ * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS" AND
+ * WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
+ * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
+ * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
+ * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION, LOSS OF
+ * PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF THIRD
+ * PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN ADVISED OF
+ * THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE POSSESSION, USE
+ * OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * US Government Users Restricted Rights 
+ * Use, duplication, or disclosure by the Government is subject to
+ * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
+ * (c)(1)(ii) of the Rights in Technical Data and Computer Software
+ * clause at DFARS 252.227-7013 and/or in similar or successor clauses
+ * in the FAR or the DOD or NASA FAR Supplement.  Unpublished - rights
+ * reserved under the copyright laws of the United States.
+ *
+ * Contractor/manufacturer is:
+ *	Silicon Graphics, Inc.
+ *	1500 Crittenden Lane
+ *	Mountain View, CA  94043
+ *	United State of America
+ *
+ * OpenGL(R) is a registered trademark of Silicon Graphics, Inc.
+ */
+
+/*
+ *  histogram.c
+ *  Compute the histogram of the image.  This program illustrates the
+ *  use of the glHistogram() function.
+ */
+
+#include <GL/glew.h>
+#include <GL/glut.h>
+#include <assert.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#define HISTOGRAM_SIZE  256   /* Must be a power of 2 */
+
+
+static GLubyte  *pixels;
+static GLsizei   width, height;
+
+
+
+static GLuint bswap(GLuint x)
+{
+   const GLuint ui = 1;
+   const GLubyte *ubp = (const GLubyte *) &ui;
+   if (*ubp == 1) {
+      /* we're on little endiang so byteswap x */
+      GLsizei y =  ((x >> 24)
+                    | ((x >> 8) & 0xff00)
+                    | ((x << 8) & 0xff0000)
+                    | ((x << 24) & 0xff000000));
+      return y;
+   }
+   else {
+      return x;
+   }
+}
+
+
+static GLubyte*
+readImage( const char* filename, GLsizei* width, GLsizei *height )
+{
+    int       n;
+    GLubyte*  pixels;
+
+    FILE* infile = fopen( filename, "rb" );
+
+    if ( !infile ) {
+	fprintf( stderr, "Unable to open file '%s'\n", filename );
+        exit(1);
+    }
+
+    fread( width, sizeof( GLsizei ), 1, infile );
+    fread( height, sizeof( GLsizei ), 1, infile );
+
+    *width = bswap(*width);
+    *height = bswap(*height);
+
+    n = 3 * (*width) * (*height);
+
+    pixels = (GLubyte *) malloc( n * sizeof( GLubyte ));
+    if ( !pixels ) {
+	fprintf( stderr, "Unable to malloc() bytes for pixels\n" );
+	fclose( infile );
+	return NULL;
+    }
+
+    fread( pixels, sizeof( GLubyte ), n, infile );
+    
+    fclose( infile );
+
+    return pixels;
+}
+
+static void init(void)
+{
+   if (!glutExtensionSupported("GL_ARB_imaging")) {
+      fprintf(stderr, "Sorry, this program requires GL_ARB_imaging.\n");
+      exit(1);
+   }
+
+   glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+   glClearColor(0.0, 0.0, 0.0, 0.0);
+
+   glHistogram(GL_HISTOGRAM, HISTOGRAM_SIZE, GL_RGB, GL_FALSE);
+   glEnable(GL_HISTOGRAM);
+}
+
+static void display(void)
+{
+   int i;
+   GLushort values[HISTOGRAM_SIZE][3];
+   
+   glClear(GL_COLOR_BUFFER_BIT);
+   glRasterPos2i(1, 1);
+   glDrawPixels(width, height, GL_RGB, GL_UNSIGNED_BYTE, pixels);
+   
+   glGetHistogram(GL_HISTOGRAM, GL_TRUE, GL_RGB, GL_UNSIGNED_SHORT, values);
+
+   /* Plot histogram */
+   
+   glBegin(GL_LINE_STRIP);
+   glColor3f(1.0, 0.0, 0.0);
+   for ( i = 0; i < HISTOGRAM_SIZE; i++ )
+       glVertex2s(i, values[i][0]);
+   glEnd();
+
+   glBegin(GL_LINE_STRIP);
+   glColor3f(0.0, 1.0, 0.0);
+   for ( i = 0; i < HISTOGRAM_SIZE; i++ )
+       glVertex2s(i, values[i][1]);
+   glEnd();
+
+   glBegin(GL_LINE_STRIP);
+   glColor3f(0.0, 0.0, 1.0);
+   for ( i = 0; i < HISTOGRAM_SIZE; i++ )
+       glVertex2s(i, values[i][2]);
+   glEnd();
+   glFlush();
+}
+
+static void reshape(int w, int h)
+{
+   glViewport(0, 0, (GLsizei) w, (GLsizei) h);
+   glMatrixMode(GL_PROJECTION);
+   glLoadIdentity();
+   glOrtho(0, 256, 0, 10000, -1.0, 1.0);
+   glMatrixMode(GL_MODELVIEW);
+}
+
+static void keyboard(unsigned char key, int x, int y)
+{
+   static GLboolean sink = GL_FALSE;
+    
+   switch (key) {
+      case 's' :
+	  sink = !sink;
+	  glHistogram(GL_HISTOGRAM, HISTOGRAM_SIZE, GL_RGB, sink);
+	  break;
+	  
+      case 27:
+         exit(0);
+   }
+   glutPostRedisplay();
+   
+}
+
+/*  Main Loop
+ *  Open window with initial window size, title bar, 
+ *  RGBA display mode, and handle input events.
+ */
+int main(int argc, char** argv)
+{
+   pixels = readImage("leeds.bin", &width, &height);    
+
+   glutInit(&argc, argv);
+   glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
+   glutInitWindowSize(width, height);
+   glutInitWindowPosition(100, 100);
+   glutCreateWindow(argv[0]);
+   glewInit();
+   init();
+   glutReshapeFunc(reshape);
+   glutKeyboardFunc(keyboard);
+   glutDisplayFunc(display);
+   glutMainLoop();
+   return 0;
+}
diff --git a/progs/redbook/leeds.bin b/progs/redbook/leeds.bin
new file mode 100644
index 0000000..5dc105e
--- /dev/null
+++ b/progs/redbook/leeds.bin
Binary files differ
diff --git a/progs/redbook/minmax.c b/progs/redbook/minmax.c
new file mode 100644
index 0000000..8281800
--- /dev/null
+++ b/progs/redbook/minmax.c
@@ -0,0 +1,177 @@
+/*
+ * Copyright (c) 1993-2003, Silicon Graphics, Inc.
+ * All Rights Reserved
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose and without fee is hereby granted, provided that the above
+ * copyright notice appear in all copies and that both the copyright
+ * notice and this permission notice appear in supporting documentation,
+ * and that the name of Silicon Graphics, Inc. not be used in
+ * advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission.
+ *
+ * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS" AND
+ * WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
+ * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
+ * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
+ * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION, LOSS OF
+ * PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF THIRD
+ * PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN ADVISED OF
+ * THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE POSSESSION, USE
+ * OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * US Government Users Restricted Rights 
+ * Use, duplication, or disclosure by the Government is subject to
+ * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
+ * (c)(1)(ii) of the Rights in Technical Data and Computer Software
+ * clause at DFARS 252.227-7013 and/or in similar or successor clauses
+ * in the FAR or the DOD or NASA FAR Supplement.  Unpublished - rights
+ * reserved under the copyright laws of the United States.
+ *
+ * Contractor/manufacturer is:
+ *	Silicon Graphics, Inc.
+ *	1500 Crittenden Lane
+ *	Mountain View, CA  94043
+ *	United State of America
+ *
+ * OpenGL(R) is a registered trademark of Silicon Graphics, Inc.
+ */
+
+/*
+ *  minmax.c
+ *  Determine the minimum and maximum values of a group of pixels.
+ *  This demonstrates use of the glMinmax() call.
+ */
+#include <GL/glew.h>
+#include <GL/glut.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+
+static GLubyte  *pixels;
+static GLsizei   width, height;
+
+
+static GLuint bswap(GLuint x)
+{
+   const GLuint ui = 1;
+   const GLubyte *ubp = (const GLubyte *) &ui;
+   if (*ubp == 1) {
+      /* we're on little endiang so byteswap x */
+      GLsizei y =  ((x >> 24)
+                    | ((x >> 8) & 0xff00)
+                    | ((x << 8) & 0xff0000)
+                    | ((x << 24) & 0xff000000));
+      return y;
+   }
+   else {
+      return x;
+   }
+}
+
+
+static GLubyte *
+readImage( const char* filename, GLsizei* width, GLsizei *height )
+{
+    int       n;
+    GLubyte*  pixels;
+
+    FILE* infile = fopen( filename, "rb" );
+
+    if ( !infile ) {
+	fprintf( stderr, "Unable to open file '%s'\n", filename );
+	return NULL;
+    }
+
+    fread( width, sizeof( GLsizei ), 1, infile );
+    fread( height, sizeof( GLsizei ), 1, infile );
+
+    *width = bswap(*width);
+    *height = bswap(*height);
+
+    n = 3 * (*width) * (*height);
+
+    pixels = (GLubyte *) malloc( n * sizeof( GLubyte ));
+    if ( !pixels ) {
+	fprintf( stderr, "Unable to malloc() bytes for pixels\n" );
+	fclose( infile );
+	return NULL;
+    }
+
+    fread( pixels, sizeof( GLubyte ), n, infile );
+    
+    fclose( infile );
+
+    return pixels;
+}
+
+static void init(void)
+{
+   if (!glutExtensionSupported("GL_ARB_imaging")) {
+      fprintf(stderr, "Sorry, this program requires GL_ARB_imaging.\n");
+      exit(1);
+   }
+
+   glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+   glClearColor(0.0, 0.0, 0.0, 0.0);
+
+   glMinmax(GL_MINMAX, GL_RGB, GL_FALSE);
+   glEnable(GL_MINMAX);
+}
+
+static void display(void)
+{
+   GLubyte  values[6];
+   
+   glClear(GL_COLOR_BUFFER_BIT);
+   glRasterPos2i(1, 1);
+   glDrawPixels(width, height, GL_RGB, GL_UNSIGNED_BYTE, pixels);
+   glFlush();
+   
+   glGetMinmax(GL_MINMAX, GL_TRUE, GL_RGB, GL_UNSIGNED_BYTE, values);
+   printf(" Red   : min = %d   max = %d\n", values[0], values[3]);
+   printf(" Green : min = %d   max = %d\n", values[1], values[4]);
+   printf(" Blue  : min = %d   max = %d\n", values[2], values[5]);
+}
+
+static void reshape(int w, int h)
+{
+   glViewport(0, 0, (GLsizei) w, (GLsizei) h);
+   glMatrixMode(GL_PROJECTION);
+   glLoadIdentity();
+   glOrtho(0, w, 0, h, -1.0, 1.0);
+   glMatrixMode(GL_MODELVIEW);
+}
+
+static void keyboard(unsigned char key, int x, int y)
+{
+   switch (key) {
+      case 27:
+         exit(0);
+   }
+}
+
+/*  Main Loop
+ *  Open window with initial window size, title bar, 
+ *  RGBA display mode, and handle input events.
+ */
+int main(int argc, char** argv)
+{
+   pixels = readImage("leeds.bin", &width, &height);    
+
+   glutInit(&argc, argv);
+   glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
+   glutInitWindowSize(width, height);
+   glutInitWindowPosition(100, 100);
+   glutCreateWindow(argv[0]);
+   glewInit();
+   init();
+   glutReshapeFunc(reshape);
+   glutKeyboardFunc(keyboard);
+   glutDisplayFunc(display);
+   glutMainLoop();
+   return 0;
+}
diff --git a/progs/redbook/multisamp.c b/progs/redbook/multisamp.c
new file mode 100644
index 0000000..38bd572
--- /dev/null
+++ b/progs/redbook/multisamp.c
@@ -0,0 +1,188 @@
+/*
+ * Copyright (c) 1993-2003, Silicon Graphics, Inc.
+ * All Rights Reserved
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose and without fee is hereby granted, provided that the above
+ * copyright notice appear in all copies and that both the copyright
+ * notice and this permission notice appear in supporting documentation,
+ * and that the name of Silicon Graphics, Inc. not be used in
+ * advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission.
+ *
+ * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS" AND
+ * WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
+ * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
+ * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
+ * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION, LOSS OF
+ * PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF THIRD
+ * PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN ADVISED OF
+ * THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE POSSESSION, USE
+ * OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * US Government Users Restricted Rights 
+ * Use, duplication, or disclosure by the Government is subject to
+ * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
+ * (c)(1)(ii) of the Rights in Technical Data and Computer Software
+ * clause at DFARS 252.227-7013 and/or in similar or successor clauses
+ * in the FAR or the DOD or NASA FAR Supplement.  Unpublished - rights
+ * reserved under the copyright laws of the United States.
+ *
+ * Contractor/manufacturer is:
+ *	Silicon Graphics, Inc.
+ *	1500 Crittenden Lane
+ *	Mountain View, CA  94043
+ *	United State of America
+ *
+ * OpenGL(R) is a registered trademark of Silicon Graphics, Inc.
+ */
+
+/*
+ *  multisamp.c
+ *  This program draws shows how to use multisampling to 
+ *  draw anti-aliased geometric primitives.  The same
+ *  display list, a pinwheel of triangles and lines of
+ *  varying widths, is rendered twice.  Multisampling is 
+ *  enabled when the left side is drawn.  Multisampling is
+ *  disabled when the right side is drawn.
+ *
+ *  Pressing the 'b' key toggles drawing of the checkerboard
+ *  background.  Antialiasing is sometimes easier to see
+ *  when objects are rendered over a contrasting background.
+ */
+#include <GL/glut.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+static int bgtoggle = 1;
+
+/*  
+ *  Print out state values related to multisampling.
+ *  Create display list with "pinwheel" of lines and
+ *  triangles. 
+ */
+static void init(void)
+{
+   static GLint buf[1], sbuf[1];
+   int i, j;
+
+   glClearColor(0.0, 0.0, 0.0, 0.0);
+   glGetIntegerv (GL_SAMPLE_BUFFERS_ARB, buf);
+   printf ("number of sample buffers is %d\n", buf[0]);
+   glGetIntegerv (GL_SAMPLES_ARB, sbuf);
+   printf ("number of samples is %d\n", sbuf[0]);
+
+   glNewList (1, GL_COMPILE);
+   for (i = 0; i < 19; i++) {
+      glPushMatrix();
+      glRotatef(360.0*(float)i/19.0, 0.0, 0.0, 1.0);
+      glColor3f (1.0, 1.0, 1.0);
+      glLineWidth((i%3)+1.0);
+      glBegin (GL_LINES);
+         glVertex2f (0.25, 0.05);
+         glVertex2f (0.9, 0.2);
+      glEnd ();
+      glColor3f (0.0, 1.0, 1.0);
+      glBegin (GL_TRIANGLES);
+         glVertex2f (0.25, 0.0);
+         glVertex2f (0.9, 0.0);
+         glVertex2f (0.875, 0.10);
+      glEnd ();
+      glPopMatrix();
+   }
+   glEndList ();
+
+   glNewList (2, GL_COMPILE);
+   glColor3f (1.0, 0.5, 0.0);
+   glBegin (GL_QUADS);
+   for (i = 0; i < 16; i++) {
+      for (j = 0; j < 16; j++) {
+         if (((i + j) % 2) == 0) {
+            glVertex2f (-2.0 + (i * 0.25), -2.0 + (j * 0.25));
+            glVertex2f (-2.0 + (i * 0.25), -1.75 + (j * 0.25));
+            glVertex2f (-1.75 + (i * 0.25), -1.75 + (j * 0.25));
+            glVertex2f (-1.75 + (i * 0.25), -2.0 + (j * 0.25));
+         }
+      }
+   }
+   glEnd ();
+   glEndList ();
+}
+
+/*  Draw two sets of primitives, so that you can 
+ *  compare the user of multisampling against its absence.
+ *
+ *  This code enables antialiasing and draws one display list
+ *  and disables and draws the other display list
+ */
+static void display(void)
+{
+   glClear(GL_COLOR_BUFFER_BIT);
+
+   if (bgtoggle) 
+      glCallList (2);
+
+   glEnable (GL_MULTISAMPLE_ARB);
+   glPushMatrix();
+   glTranslatef (-1.0, 0.0, 0.0);
+   glCallList (1);
+   glPopMatrix();
+
+   glDisable (GL_MULTISAMPLE_ARB);
+   glPushMatrix();
+   glTranslatef (1.0, 0.0, 0.0);
+   glCallList (1);
+   glPopMatrix();
+   glutSwapBuffers();
+}
+
+static void reshape(int w, int h)
+{
+   glViewport(0, 0, w, h);
+   glMatrixMode(GL_PROJECTION);
+   glLoadIdentity();
+   if (w <= (2 * h)) 
+      gluOrtho2D (-2.0, 2.0, 
+         -2.0*(GLfloat)h/(GLfloat)w, 2.0*(GLfloat)h/(GLfloat)w);
+   else 
+      gluOrtho2D (-2.0*(GLfloat)w/(GLfloat)h, 
+         2.0*(GLfloat)w/(GLfloat)h, -2.0, 2.0);
+   glMatrixMode(GL_MODELVIEW);
+   glLoadIdentity();
+}
+
+static void keyboard(unsigned char key, int x, int y)
+{
+   switch (key) {
+      case 'b':
+      case 'B':
+         bgtoggle = !bgtoggle;
+         glutPostRedisplay();
+         break;
+      case 27:  /*  Escape Key  */
+         exit(0);
+      default:
+         break;
+    }
+}
+
+/*  Main Loop
+ *  Open window with initial window size, title bar, 
+ *  RGBA display mode, and handle input events.
+ */
+int main(int argc, char** argv)
+{
+   glutInit(&argc, argv);
+   glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB | GLUT_MULTISAMPLE);
+   glutInitWindowSize (600, 300);
+   glutCreateWindow (argv[0]);
+   init();
+   glutReshapeFunc (reshape);
+   glutKeyboardFunc (keyboard);
+   glutDisplayFunc (display);
+   glutMainLoop();
+   return 0;
+}
diff --git a/progs/redbook/multitex.c b/progs/redbook/multitex.c
new file mode 100644
index 0000000..118f0ea
--- /dev/null
+++ b/progs/redbook/multitex.c
@@ -0,0 +1,177 @@
+/*
+ * Copyright (c) 1993-2003, Silicon Graphics, Inc.
+ * All Rights Reserved
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose and without fee is hereby granted, provided that the above
+ * copyright notice appear in all copies and that both the copyright
+ * notice and this permission notice appear in supporting documentation,
+ * and that the name of Silicon Graphics, Inc. not be used in
+ * advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission.
+ *
+ * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS" AND
+ * WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
+ * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
+ * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
+ * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION, LOSS OF
+ * PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF THIRD
+ * PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN ADVISED OF
+ * THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE POSSESSION, USE
+ * OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * US Government Users Restricted Rights 
+ * Use, duplication, or disclosure by the Government is subject to
+ * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
+ * (c)(1)(ii) of the Rights in Technical Data and Computer Software
+ * clause at DFARS 252.227-7013 and/or in similar or successor clauses
+ * in the FAR or the DOD or NASA FAR Supplement.  Unpublished - rights
+ * reserved under the copyright laws of the United States.
+ *
+ * Contractor/manufacturer is:
+ *	Silicon Graphics, Inc.
+ *	1500 Crittenden Lane
+ *	Mountain View, CA  94043
+ *	United State of America
+ *
+ * OpenGL(R) is a registered trademark of Silicon Graphics, Inc.
+ */
+
+/*  multitex.c
+ */
+#include <GL/glew.h>
+#include <GL/glut.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+
+static GLubyte texels0[32][32][4];
+static GLubyte texels1[16][16][4];
+
+static void makeCheckImages(void)
+{
+   int i, j;
+    
+   for (i = 0; i < 32; i++) {
+      for (j = 0; j < 32; j++) {
+         texels0[i][j][0] = (GLubyte) (255 * i / 31);
+         texels0[i][j][1] = (GLubyte) (255 * j / 31);
+         texels0[i][j][2] = (GLubyte) (i*j)/255;
+         texels0[i][j][3] = (GLubyte) 255;
+      }
+   }
+
+   for (i = 0; i < 16; i++) {
+      for (j = 0; j < 16; j++) {
+         texels1[i][j][0] = (GLubyte) 255;
+         texels1[i][j][1] = (GLubyte) (255 * i / 15);
+         texels1[i][j][2] = (GLubyte) (255 * j / 15);
+         texels1[i][j][3] = (GLubyte) 255;
+      }
+   }
+}
+
+static void init(void)
+{    
+   GLuint texNames[2];
+
+   glClearColor (0.0, 0.0, 0.0, 0.0);
+   glShadeModel(GL_FLAT);
+   glEnable(GL_DEPTH_TEST);
+
+   makeCheckImages();
+   glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+
+   glGenTextures(2, texNames);
+   glBindTexture(GL_TEXTURE_2D, texNames[0]);
+   glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 32, 32, 0, GL_RGBA, 
+		GL_UNSIGNED_BYTE, texels0);
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, 
+                   GL_NEAREST);
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, 
+                   GL_NEAREST);
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+
+   glBindTexture(GL_TEXTURE_2D, texNames[1]);
+   glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, 
+		GL_UNSIGNED_BYTE, texels1);
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+   /*  Use the two texture objects to define two texture units
+    *  for use in multitexturing  */
+   glActiveTextureARB (GL_TEXTURE0_ARB);
+   glEnable(GL_TEXTURE_2D);
+   glBindTexture(GL_TEXTURE_2D, texNames[0]);
+   glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+   glMatrixMode (GL_TEXTURE);
+      glLoadIdentity();
+      glTranslatef(0.5f, 0.5f, 0.0f);
+      glRotatef(45.0f, 0.0f, 0.0f, 1.0f);
+      glTranslatef(-0.5f, -0.5f, 0.0f);
+   glMatrixMode (GL_MODELVIEW);
+   glActiveTextureARB (GL_TEXTURE1_ARB);
+   glEnable(GL_TEXTURE_2D);
+   glBindTexture(GL_TEXTURE_2D, texNames[1]);
+   glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+}
+
+static void display(void)
+{
+   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+   glBegin(GL_TRIANGLES);
+   glMultiTexCoord2fARB (GL_TEXTURE0_ARB, 0.0, 0.0);
+   glMultiTexCoord2fARB (GL_TEXTURE1_ARB, 1.0, 0.0);
+   glVertex2f(0.0, 0.0);
+   glMultiTexCoord2fARB (GL_TEXTURE0_ARB, 0.5, 1.0);
+   glMultiTexCoord2fARB (GL_TEXTURE1_ARB, 0.5, 0.0);
+   glVertex2f(50.0, 100.0);
+   glMultiTexCoord2fARB (GL_TEXTURE0_ARB, 1.0, 0.0);
+   glMultiTexCoord2fARB (GL_TEXTURE1_ARB, 1.0, 1.0);
+   glVertex2f(100.0, 0.0);
+   glEnd();
+   glFlush();
+}
+
+static void reshape(int w, int h)
+{
+   glViewport(0, 0, (GLsizei) w, (GLsizei) h);
+   glMatrixMode(GL_PROJECTION);
+   glLoadIdentity();
+   if (w <= h)
+      gluOrtho2D(0.0, 100.0, 0.0, 100.0 * (GLdouble)h/(GLdouble)w);
+   else
+      gluOrtho2D(0.0, 100.0 * (GLdouble)w/(GLdouble)h, 0.0, 100.0);
+   glMatrixMode(GL_MODELVIEW);
+   glLoadIdentity();
+}
+
+static void keyboard(unsigned char key, int x, int y)
+{
+   switch (key) {
+      case 27:
+         exit(0);
+         break;
+   }
+}
+
+int main(int argc, char** argv)
+{
+   glutInit(&argc, argv);
+   glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
+   glutInitWindowSize(250, 250);
+   glutInitWindowPosition(100, 100);
+   glutCreateWindow(argv[0]);
+   glewInit();
+   init();
+   glutReshapeFunc(reshape);
+   glutDisplayFunc(display);
+   glutKeyboardFunc (keyboard);
+   glutMainLoop();
+   return 0; 
+}
diff --git a/progs/redbook/mvarray.c b/progs/redbook/mvarray.c
new file mode 100644
index 0000000..1022723
--- /dev/null
+++ b/progs/redbook/mvarray.c
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 1993-2003, Silicon Graphics, Inc.
+ * All Rights Reserved
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose and without fee is hereby granted, provided that the above
+ * copyright notice appear in all copies and that both the copyright
+ * notice and this permission notice appear in supporting documentation,
+ * and that the name of Silicon Graphics, Inc. not be used in
+ * advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission.
+ *
+ * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS" AND
+ * WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
+ * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
+ * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
+ * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION, LOSS OF
+ * PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF THIRD
+ * PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN ADVISED OF
+ * THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE POSSESSION, USE
+ * OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * US Government Users Restricted Rights 
+ * Use, duplication, or disclosure by the Government is subject to
+ * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
+ * (c)(1)(ii) of the Rights in Technical Data and Computer Software
+ * clause at DFARS 252.227-7013 and/or in similar or successor clauses
+ * in the FAR or the DOD or NASA FAR Supplement.  Unpublished - rights
+ * reserved under the copyright laws of the United States.
+ *
+ * Contractor/manufacturer is:
+ *	Silicon Graphics, Inc.
+ *	1500 Crittenden Lane
+ *	Mountain View, CA  94043
+ *	United State of America
+ *
+ * OpenGL(R) is a registered trademark of Silicon Graphics, Inc.
+ */
+
+/*
+ *  mvarray.c
+ *  This program demonstrates multiple vertex arrays,
+ *  specifically the OpenGL routine glMultiDrawElements().
+ */
+
+#include <GL/glew.h>
+#include <GL/glut.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#ifdef GL_VERSION_1_3
+
+static void setupPointer(void)
+{
+   static GLint vertices[] = {25, 25,
+                       75, 75,
+                       100, 125,
+                       150, 75,
+                       200, 175,
+                       250, 150,
+                       300, 125,
+                       100, 200,
+                       150, 250,
+                       200, 225,
+                       250, 300,
+                       300, 250};
+
+   glEnableClientState (GL_VERTEX_ARRAY);
+   glVertexPointer (2, GL_INT, 0, vertices);
+}
+
+static void init(void) 
+{
+   glClearColor (0.0, 0.0, 0.0, 0.0);
+   glShadeModel (GL_SMOOTH);
+   setupPointer ();
+}
+
+static void display(void)
+{
+   static GLubyte oneIndices[] = {0, 1, 2, 3, 4, 5, 6};
+   static GLubyte twoIndices[] = {1, 7, 8, 9, 10, 11};
+   static GLsizei count[] = {7, 6};
+   static GLvoid * indices[2] = {oneIndices, twoIndices};
+   
+   glClear (GL_COLOR_BUFFER_BIT);
+   glColor3f (1.0, 1.0, 1.0);
+   glMultiDrawElementsEXT (GL_LINE_STRIP, count, GL_UNSIGNED_BYTE,
+                           (const GLvoid **) indices, 2);
+   glFlush ();
+}
+
+static void reshape (int w, int h)
+{
+   glViewport (0, 0, (GLsizei) w, (GLsizei) h);
+   glMatrixMode (GL_PROJECTION);
+   glLoadIdentity ();
+   gluOrtho2D (0.0, (GLdouble) w, 0.0, (GLdouble) h);
+}
+
+static void keyboard(unsigned char key, int x, int y)
+{
+   switch (key) {
+      case 27:
+         exit(0);
+         break;
+   }
+}
+
+int main(int argc, char** argv)
+{
+   glutInit(&argc, argv);
+   glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
+   glutInitWindowSize (350, 350); 
+   glutInitWindowPosition (100, 100);
+   glutCreateWindow (argv[0]);
+   glewInit();
+   init ();
+   glutDisplayFunc(display); 
+   glutReshapeFunc(reshape);
+   glutKeyboardFunc (keyboard);
+   glutMainLoop();
+   return 0;
+}
+#else
+int main(int argc, char** argv)
+{
+    fprintf (stderr, "This program demonstrates a feature which is not in OpenGL Version 1.0.\n");
+    fprintf (stderr, "If your implementation of OpenGL Version 1.0 has the right extensions,\n");
+    fprintf (stderr, "you may be able to modify this program to make it run.\n");
+    return 0;
+}
+#endif
diff --git a/progs/redbook/pointp.c b/progs/redbook/pointp.c
new file mode 100644
index 0000000..b273623
--- /dev/null
+++ b/progs/redbook/pointp.c
@@ -0,0 +1,179 @@
+/*
+ * Copyright (c) 1993-2003, Silicon Graphics, Inc.
+ * All Rights Reserved
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose and without fee is hereby granted, provided that the above
+ * copyright notice appear in all copies and that both the copyright
+ * notice and this permission notice appear in supporting documentation,
+ * and that the name of Silicon Graphics, Inc. not be used in
+ * advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission.
+ *
+ * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS" AND
+ * WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
+ * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
+ * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
+ * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION, LOSS OF
+ * PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF THIRD
+ * PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN ADVISED OF
+ * THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE POSSESSION, USE
+ * OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * US Government Users Restricted Rights 
+ * Use, duplication, or disclosure by the Government is subject to
+ * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
+ * (c)(1)(ii) of the Rights in Technical Data and Computer Software
+ * clause at DFARS 252.227-7013 and/or in similar or successor clauses
+ * in the FAR or the DOD or NASA FAR Supplement.  Unpublished - rights
+ * reserved under the copyright laws of the United States.
+ *
+ * Contractor/manufacturer is:
+ *	Silicon Graphics, Inc.
+ *	1500 Crittenden Lane
+ *	Mountain View, CA  94043
+ *	United State of America
+ *
+ * OpenGL(R) is a registered trademark of Silicon Graphics, Inc.
+ */
+
+/*
+ *  pointp.c
+ *  This program demonstrates point parameters and their effect
+ *  on point primitives.
+ *  250 points are randomly generated within a 10 by 10 by 40
+ *  region, centered at the origin.  In some modes (including the
+ *  default), points that are closer to the viewer will appear larger.
+ *
+ *  Pressing the 'l', 'q', and 'c' keys switch the point
+ *  parameters attenuation mode to linear, quadratic, or constant,
+ *  respectively.  
+ *  Pressing the 'f' and 'b' keys move the viewer forward 
+ *  and backwards.  In either linear or quadratic attenuation
+ *  mode, the distance from the viewer to the point will change
+ *  the size of the point primitive.
+ *  Pressing the '+' and '-' keys will change the current point
+ *  size.  In this program, the point size is bounded, so it
+ *  will not get less than 2.0, nor greater than GL_POINT_SIZE_MAX.
+ */
+
+#include <GL/glew.h>
+#include <GL/glut.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+static GLfloat psize = 7.0;
+static GLfloat pmax[1];
+static GLfloat constant[3] = {1.0, 0.0, 0.0};
+static GLfloat linear[3] = {0.0, 0.12, 0.0};
+static GLfloat quadratic[3] = {0.0, 0.0, 0.01};
+
+static void init(void) 
+{
+   int i;
+
+   srand (12345);
+   
+   glNewList(1, GL_COMPILE);
+   glBegin (GL_POINTS);
+      for (i = 0; i < 250; i++) {
+          glColor3f (1.0, ((rand()/(float) RAND_MAX) * 0.5) + 0.5, 
+                          rand()/(float) RAND_MAX);
+/*  randomly generated vertices:
+    -5 < x < 5;  -5 < y < 5;  -5 < z < -45  */
+          glVertex3f ( ((rand()/(float)RAND_MAX) * 10.0) - 5.0, 
+                       ((rand()/(float)RAND_MAX) * 10.0) - 5.0, 
+                       ((rand()/(float)RAND_MAX) * 40.0) - 45.0); 
+      }
+   glEnd();
+   glEndList();
+
+   glEnable(GL_DEPTH_TEST);
+   glEnable(GL_POINT_SMOOTH);
+   glEnable(GL_BLEND);
+   glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 
+   glPointSize(psize);
+   glGetFloatv(GL_POINT_SIZE_MAX_EXT, pmax);
+
+   glPointParameterfvEXT (GL_DISTANCE_ATTENUATION_EXT, linear);
+   glPointParameterfEXT (GL_POINT_FADE_THRESHOLD_SIZE_EXT, 2.0);
+}
+
+static void display(void)
+{
+   glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+   glCallList (1);
+   glutSwapBuffers ();
+}
+
+static void reshape (int w, int h)
+{
+   glViewport (0, 0, (GLsizei) w, (GLsizei) h);
+   glMatrixMode (GL_PROJECTION);
+   glLoadIdentity ();
+   gluPerspective (35.0, 1.0, 0.25, 200.0);
+   glMatrixMode (GL_MODELVIEW);
+   glTranslatef (0.0, 0.0, -10.0);
+}
+
+static void keyboard(unsigned char key, int x, int y)
+{
+   switch (key) {
+      case 'b':
+            glMatrixMode (GL_MODELVIEW);
+            glTranslatef (0.0, 0.0, -0.5);
+            glutPostRedisplay();
+         break;
+      case 'c':
+            glPointParameterfvEXT (GL_DISTANCE_ATTENUATION_EXT, constant);
+            glutPostRedisplay();
+         break;
+      case 'f':
+            glMatrixMode (GL_MODELVIEW);
+            glTranslatef (0.0, 0.0, 0.5);
+            glutPostRedisplay();
+         break;
+      case 'l':
+            glPointParameterfvEXT (GL_DISTANCE_ATTENUATION_EXT, linear);
+            glutPostRedisplay();
+         break;
+      case 'q':
+            glPointParameterfvEXT (GL_DISTANCE_ATTENUATION_EXT, quadratic);
+            glutPostRedisplay();
+         break;
+      case '+':
+            if (psize < (pmax[0] + 1.0))
+               psize = psize + 1.0;
+            glPointSize (psize);
+            glutPostRedisplay();
+         break;
+      case '-':
+            if (psize >= 2.0)
+               psize = psize - 1.0;
+            glPointSize (psize);
+            glutPostRedisplay();
+         break;
+      case 27:
+         exit(0);
+         break;
+   }
+}
+
+int main(int argc, char** argv)
+{
+   glutInit(&argc, argv);
+   glutInitDisplayMode (GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH | GLUT_MULTISAMPLE);
+   glutInitWindowSize (500, 500); 
+   glutInitWindowPosition (100, 100);
+   glutCreateWindow (argv[0]);
+   glewInit();
+   init ();
+   glutDisplayFunc (display); 
+   glutReshapeFunc (reshape);
+   glutKeyboardFunc (keyboard);
+   glutMainLoop();
+   return 0;
+}
diff --git a/progs/redbook/shadowmap.c b/progs/redbook/shadowmap.c
new file mode 100644
index 0000000..f37191d
--- /dev/null
+++ b/progs/redbook/shadowmap.c
@@ -0,0 +1,352 @@
+/*
+ * Copyright (c) 1993-2003, Silicon Graphics, Inc.
+ * All Rights Reserved
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose and without fee is hereby granted, provided that the above
+ * copyright notice appear in all copies and that both the copyright
+ * notice and this permission notice appear in supporting documentation,
+ * and that the name of Silicon Graphics, Inc. not be used in
+ * advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission.
+ *
+ * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS" AND
+ * WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
+ * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
+ * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
+ * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION, LOSS OF
+ * PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF THIRD
+ * PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN ADVISED OF
+ * THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE POSSESSION, USE
+ * OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * US Government Users Restricted Rights 
+ * Use, duplication, or disclosure by the Government is subject to
+ * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
+ * (c)(1)(ii) of the Rights in Technical Data and Computer Software
+ * clause at DFARS 252.227-7013 and/or in similar or successor clauses
+ * in the FAR or the DOD or NASA FAR Supplement.  Unpublished - rights
+ * reserved under the copyright laws of the United States.
+ *
+ * Contractor/manufacturer is:
+ *	Silicon Graphics, Inc.
+ *	1500 Crittenden Lane
+ *	Mountain View, CA  94043
+ *	United State of America
+ *
+ * OpenGL(R) is a registered trademark of Silicon Graphics, Inc.
+ */
+
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <GL/glew.h>
+#include <GL/glut.h>
+/*#include "helpers.h"*/
+
+#define SHADOW_MAP_WIDTH      256
+#define SHADOW_MAP_HEIGHT     256
+
+#define PI       3.14159265359
+
+GLdouble    fovy      = 60.0;
+GLdouble    nearPlane = 10.0;
+GLdouble    farPlane  = 100.0;
+
+GLfloat     angle = 0.0;
+GLfloat     torusAngle = 0.0;
+
+GLfloat     lightPos[] = { 25.0, 25.0, 25.0, 1.0 };
+GLfloat     lookat[] = { 0.0, 0.0, 0.0 };
+GLfloat     up[] = { 0.0, 0.0, 1.0 };
+
+GLboolean showShadow = GL_FALSE;
+
+static void
+init( void )
+{
+    GLfloat  white[] = { 1.0, 1.0, 1.0, 1.0 };
+
+    glTexImage2D( GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, 
+  		  SHADOW_MAP_WIDTH, SHADOW_MAP_HEIGHT, 0,
+		  GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL );
+
+    glLightfv( GL_LIGHT0, GL_POSITION, lightPos );
+    glLightfv( GL_LIGHT0, GL_SPECULAR, white );
+    glLightfv( GL_LIGHT0, GL_DIFFUSE, white );
+
+    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
+    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
+    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
+    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
+    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL );
+    glTexParameteri( GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_LUMINANCE );
+    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE,
+		     GL_COMPARE_R_TO_TEXTURE );
+
+    glTexGeni( GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR );
+    glTexGeni( GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR );
+    glTexGeni( GL_R, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR );
+    glTexGeni( GL_Q, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR );
+
+    glColorMaterial( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE );
+
+    glCullFace( GL_BACK );
+
+    glEnable( GL_DEPTH_TEST );
+    glEnable( GL_LIGHT0 );
+    glEnable( GL_LIGHTING );
+    glEnable( GL_TEXTURE_2D );
+    glEnable( GL_TEXTURE_GEN_S );
+    glEnable( GL_TEXTURE_GEN_T );
+    glEnable( GL_TEXTURE_GEN_R );
+    glEnable( GL_TEXTURE_GEN_Q );
+    glEnable( GL_COLOR_MATERIAL );
+    glEnable( GL_CULL_FACE );
+}
+
+static void
+reshape( int width, int height )
+{
+    glViewport( 0, 0, width, height );
+
+    glMatrixMode( GL_PROJECTION );
+    glLoadIdentity();
+    gluPerspective( fovy, (GLdouble) width/height, nearPlane, farPlane );
+    glMatrixMode( GL_MODELVIEW );
+}
+
+static void
+idle( void )
+{
+    angle += PI / 10000;
+    torusAngle += .1;
+    glutPostRedisplay();
+}
+
+static void
+keyboard( unsigned char key, int x, int y )
+{
+    switch( key ) {
+    case 27:  /* Escape */
+      exit( 0 );
+      break;
+
+    case 't': {
+        static GLboolean textureOn = GL_TRUE;
+        textureOn = !textureOn;
+        if ( textureOn )
+	glEnable( GL_TEXTURE_2D );
+        else
+	glDisable( GL_TEXTURE_2D );
+      }
+      break;
+      
+    case 'm': {
+        static GLboolean compareMode = GL_TRUE;
+        compareMode = !compareMode;
+        printf( "Compare mode %s\n", compareMode ? "On" : "Off" );
+        glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE,
+		         compareMode ? GL_COMPARE_R_TO_TEXTURE : GL_NONE );
+      }
+      break;
+
+    case 'f': {
+        static GLboolean funcMode = GL_TRUE;
+        funcMode = !funcMode;
+        printf( "Operator %s\n", funcMode ? "GL_LEQUAL" : "GL_GEQUAL" );
+        glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC,
+		         funcMode ? GL_LEQUAL : GL_GEQUAL );
+      }
+      break;
+
+    case 's':
+      showShadow = !showShadow;
+      break;
+
+    case 'p': {
+        static GLboolean  animate = GL_TRUE;
+        animate = !animate;
+        glutIdleFunc( animate ? idle : NULL );
+      }
+      break;
+    }
+
+    glutPostRedisplay();
+}
+
+static void
+transposeMatrix( GLfloat m[16] )
+{
+    GLfloat  tmp;
+#define Swap( a, b )    tmp = a; a = b; b = tmp
+    Swap( m[1],  m[4]  );
+    Swap( m[2],  m[8]  );
+    Swap( m[3],  m[12] );
+    Swap( m[6],  m[9]  );
+    Swap( m[7],  m[13] );
+    Swap( m[11], m[14] );
+#undef Swap
+}
+
+static void
+drawObjects( GLboolean shadowRender )
+{
+    GLboolean textureOn = glIsEnabled( GL_TEXTURE_2D );
+
+    if ( shadowRender )
+        glDisable( GL_TEXTURE_2D );
+
+    if ( !shadowRender ) {
+        glNormal3f( 0, 0, 1 );
+        glColor3f( 1, 1, 1 );
+        glRectf( -20.0, -20.0, 20.0, 20.0 );
+    }
+    
+    glPushMatrix();
+    glTranslatef( 11, 11, 11 );
+    glRotatef( 54.73, -5, 5, 0 );
+    glRotatef( torusAngle, 1, 0, 0 );
+    glColor3f( 1, 0, 0 );
+    glutSolidTorus( 1, 4, 8, 36 );
+    glPopMatrix();
+
+    glPushMatrix();
+    glTranslatef( 2, 2, 2 );
+    glColor3f( 0, 0, 1 );
+    glutSolidCube( 4 );
+    glPopMatrix();
+
+    glPushMatrix();
+    glTranslatef( lightPos[0], lightPos[1], lightPos[2] );
+    glColor3f( 1, 1, 1 );
+    glutWireSphere( 0.5, 6, 6 );
+    glPopMatrix();
+
+    if ( shadowRender && textureOn ) 
+        glEnable( GL_TEXTURE_2D );
+}
+
+static void
+generateShadowMap( void )
+{
+    GLint    viewport[4];
+    GLfloat  lightPos[4];
+
+    glGetLightfv( GL_LIGHT0, GL_POSITION, lightPos );
+    glGetIntegerv( GL_VIEWPORT, viewport );
+
+    glViewport( 0, 0, SHADOW_MAP_WIDTH, SHADOW_MAP_HEIGHT );
+
+    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
+
+    glMatrixMode( GL_PROJECTION );
+    glPushMatrix();
+    glLoadIdentity();
+    gluPerspective( 80.0, 1.0, 10.0, 1000.0 );
+    glMatrixMode( GL_MODELVIEW );
+
+    glPushMatrix();
+    glLoadIdentity();
+    gluLookAt( lightPos[0], lightPos[1], lightPos[2],
+	       lookat[0], lookat[1], lookat[2],
+	       up[0], up[1], up[2] );
+
+    drawObjects( GL_TRUE );
+
+    glPopMatrix();
+    glMatrixMode( GL_PROJECTION );
+    glPopMatrix();
+    glMatrixMode( GL_MODELVIEW );
+
+    glCopyTexImage2D( GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, 0, 0,
+		      SHADOW_MAP_WIDTH, SHADOW_MAP_HEIGHT, 0 );
+
+    glViewport( viewport[0], viewport[1], viewport[2], viewport[3] );
+
+    if ( showShadow ) {
+      GLfloat depthImage[SHADOW_MAP_WIDTH][SHADOW_MAP_HEIGHT];
+      glReadPixels( 0, 0, SHADOW_MAP_WIDTH, SHADOW_MAP_HEIGHT, 
+		    GL_DEPTH_COMPONENT, GL_FLOAT, depthImage );
+      glWindowPos2f( viewport[2]/2, 0 );
+      glDrawPixels( SHADOW_MAP_WIDTH, SHADOW_MAP_HEIGHT, GL_LUMINANCE, 
+		    GL_FLOAT, depthImage );
+      glutSwapBuffers();
+    }
+}
+
+static void
+generateTextureMatrix( void )
+{
+    GLfloat  tmpMatrix[16];
+
+    /*
+     *  Set up projective texture matrix.  We use the GL_MODELVIEW matrix
+     *    stack and OpenGL matrix commands to make the matrix.
+     */
+    glPushMatrix();
+    glLoadIdentity();
+    glTranslatef( 0.5, 0.5, 0.0 );
+    glScalef( 0.5, 0.5, 1.0 );
+    gluPerspective( 60.0, 1.0, 1.0, 1000.0 );
+    gluLookAt( lightPos[0], lightPos[1], lightPos[2],
+	       lookat[0], lookat[1], lookat[2],
+	       up[0], up[1], up[2] );
+    glGetFloatv( GL_MODELVIEW_MATRIX, tmpMatrix );
+    glPopMatrix();
+
+    transposeMatrix( tmpMatrix );
+
+    glTexGenfv( GL_S, GL_OBJECT_PLANE, &tmpMatrix[0] );
+    glTexGenfv( GL_T, GL_OBJECT_PLANE, &tmpMatrix[4] );
+    glTexGenfv( GL_R, GL_OBJECT_PLANE, &tmpMatrix[8] );
+    glTexGenfv( GL_Q, GL_OBJECT_PLANE, &tmpMatrix[12] );
+}
+
+static void
+display( void )
+{
+    GLfloat  radius = 30;
+
+    generateShadowMap();
+    generateTextureMatrix();
+
+    if ( showShadow )
+      return;
+
+    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
+    
+    glPushMatrix();
+    gluLookAt( radius*cos(angle), radius*sin(angle), 30,
+	       lookat[0], lookat[1], lookat[2], 
+	       up[0], up[1], up[2] );
+    drawObjects( GL_FALSE );
+    glPopMatrix();
+
+    glutSwapBuffers();
+}
+
+int
+main( int argc, char** argv )
+{
+    glutInit( &argc, argv );
+    glutInitDisplayMode( GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE );
+    glutInitWindowSize( 512, 512 );
+    glutInitWindowPosition( 100, 100 );
+    glutCreateWindow( argv[0] );
+    glewInit();
+
+    init();
+
+    glutDisplayFunc( display );
+    glutReshapeFunc( reshape );
+    glutKeyboardFunc( keyboard );
+    glutIdleFunc( idle );
+
+    glutMainLoop();
+
+    return 0;
+}
diff --git a/progs/redbook/surfpoints.c b/progs/redbook/surfpoints.c
new file mode 100644
index 0000000..094f0da
--- /dev/null
+++ b/progs/redbook/surfpoints.c
@@ -0,0 +1,280 @@
+/*
+ * Copyright (c) 1993-2003, Silicon Graphics, Inc.
+ * All Rights Reserved
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose and without fee is hereby granted, provided that the above
+ * copyright notice appear in all copies and that both the copyright
+ * notice and this permission notice appear in supporting documentation,
+ * and that the name of Silicon Graphics, Inc. not be used in
+ * advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission.
+ *
+ * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS" AND
+ * WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
+ * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
+ * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
+ * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION, LOSS OF
+ * PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF THIRD
+ * PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN ADVISED OF
+ * THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE POSSESSION, USE
+ * OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * US Government Users Restricted Rights 
+ * Use, duplication, or disclosure by the Government is subject to
+ * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
+ * (c)(1)(ii) of the Rights in Technical Data and Computer Software
+ * clause at DFARS 252.227-7013 and/or in similar or successor clauses
+ * in the FAR or the DOD or NASA FAR Supplement.  Unpublished - rights
+ * reserved under the copyright laws of the United States.
+ *
+ * Contractor/manufacturer is:
+ *	Silicon Graphics, Inc.
+ *	1500 Crittenden Lane
+ *	Mountain View, CA  94043
+ *	United State of America
+ *
+ * OpenGL(R) is a registered trademark of Silicon Graphics, Inc.
+ */
+
+/*
+ *  surfpoints.c
+ *  This program is a modification of the earlier surface.c
+ *  program.  The vertex data are not directly rendered,
+ *  but are instead passed to the callback function.  
+ *  The values of the tessellated vertices are printed 
+ *  out there.
+ *
+ *  This program draws a NURBS surface in the shape of a 
+ *  symmetrical hill.  The 'c' keyboard key allows you to 
+ *  toggle the visibility of the control points themselves.  
+ *  Note that some of the control points are hidden by the  
+ *  surface itself.
+ */
+#include <GL/glut.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#ifdef GLU_VERSION_1_3
+
+#ifndef CALLBACK
+#define CALLBACK
+#endif
+
+GLfloat ctlpoints[4][4][3];
+int showPoints = 0;
+
+GLUnurbsObj *theNurb;
+
+/*
+ *  Initializes the control points of the surface to a small hill.
+ *  The control points range from -3 to +3 in x, y, and z
+ */
+static void init_surface(void)
+{
+   int u, v;
+   for (u = 0; u < 4; u++) {
+      for (v = 0; v < 4; v++) {
+         ctlpoints[u][v][0] = 2.0*((GLfloat)u - 1.5);
+         ctlpoints[u][v][1] = 2.0*((GLfloat)v - 1.5);
+
+         if ( (u == 1 || u == 2) && (v == 1 || v == 2))
+            ctlpoints[u][v][2] = 3.0;
+         else
+            ctlpoints[u][v][2] = -3.0;
+      }
+   }				
+}				
+
+static void CALLBACK nurbsError(GLenum errorCode)
+{
+   const GLubyte *estring;
+
+   estring = gluErrorString(errorCode);
+   fprintf (stderr, "Nurbs Error: %s\n", estring);
+   exit (0);
+}
+
+static void CALLBACK beginCallback(GLenum whichType)
+{
+   glBegin (whichType);  /*  resubmit rendering directive  */
+   printf ("glBegin(");
+   switch (whichType) {  /*  print diagnostic message  */
+      case GL_LINES:
+	 printf ("GL_LINES)\n");
+	 break;
+      case GL_LINE_LOOP:
+	 printf ("GL_LINE_LOOP)\n");
+	 break;
+      case GL_LINE_STRIP:
+	 printf ("GL_LINE_STRIP)\n");
+	 break;
+      case GL_TRIANGLES:
+	 printf ("GL_TRIANGLES)\n");
+	 break;
+      case GL_TRIANGLE_STRIP:
+	 printf ("GL_TRIANGLE_STRIP)\n");
+	 break;
+      case GL_TRIANGLE_FAN:
+	 printf ("GL_TRIANGLE_FAN)\n");
+	 break;
+      case GL_QUADS:
+	 printf ("GL_QUADS)\n");
+	 break;
+      case GL_QUAD_STRIP:
+	 printf ("GL_QUAD_STRIP)\n");
+	 break;
+      case GL_POLYGON:
+	 printf ("GL_POLYGON)\n");
+	 break;
+      default:
+	 break;
+   }
+}
+
+static void CALLBACK endCallback()
+{
+   glEnd();  /*  resubmit rendering directive  */
+   printf ("glEnd()\n");
+}
+
+static void CALLBACK vertexCallback(GLfloat *vertex)
+{
+   glVertex3fv(vertex);  /*  resubmit rendering directive  */
+   printf ("glVertex3f (%5.3f, %5.3f, %5.3f)\n", 
+	   vertex[0], vertex[1], vertex[2]);
+}
+
+static void CALLBACK normalCallback(GLfloat *normal)
+{
+   glNormal3fv(normal);  /*  resubmit rendering directive  */
+   printf ("glNormal3f (%5.3f, %5.3f, %5.3f)\n", 
+           normal[0], normal[1], normal[2]);
+}
+			
+/*  Initialize material property and depth buffer.
+ */
+static void init(void)
+{
+   GLfloat mat_diffuse[] = { 0.7, 0.7, 0.7, 1.0 };
+   GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 };
+   GLfloat mat_shininess[] = { 100.0 };
+
+   glClearColor (0.0, 0.0, 0.0, 0.0);
+   glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
+   glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
+   glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
+
+   glEnable(GL_LIGHTING);
+   glEnable(GL_LIGHT0);
+   glEnable(GL_DEPTH_TEST);
+   glEnable(GL_AUTO_NORMAL);
+   glEnable(GL_NORMALIZE);
+
+   init_surface();
+
+   theNurb = gluNewNurbsRenderer();
+   gluNurbsProperty(theNurb, GLU_NURBS_MODE, 
+		    GLU_NURBS_TESSELLATOR);
+   gluNurbsProperty(theNurb, GLU_SAMPLING_TOLERANCE, 25.0);
+   gluNurbsProperty(theNurb, GLU_DISPLAY_MODE, GLU_FILL);
+   gluNurbsCallback(theNurb, GLU_ERROR, nurbsError);
+   gluNurbsCallback(theNurb, GLU_NURBS_BEGIN, beginCallback);
+   gluNurbsCallback(theNurb, GLU_NURBS_VERTEX, vertexCallback);
+   gluNurbsCallback(theNurb, GLU_NURBS_NORMAL, normalCallback);
+   gluNurbsCallback(theNurb, GLU_NURBS_END, endCallback);
+
+}
+
+static void display(void)
+{
+   GLfloat knots[8] = {0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0};
+   int i, j;
+
+   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+   glPushMatrix();
+   glRotatef(330.0, 1.,0.,0.);
+   glScalef (0.5, 0.5, 0.5);
+
+   gluBeginSurface(theNurb);
+   gluNurbsSurface(theNurb, 
+                   8, knots, 8, knots,
+                   4 * 3, 3, &ctlpoints[0][0][0], 
+                   4, 4, GL_MAP2_VERTEX_3);
+   gluEndSurface(theNurb);
+
+   if (showPoints) {
+      glPointSize(5.0);
+      glDisable(GL_LIGHTING);
+      glColor3f(1.0, 1.0, 0.0);
+      glBegin(GL_POINTS);
+      for (i = 0; i < 4; i++) {
+         for (j = 0; j < 4; j++) {
+	    glVertex3f(ctlpoints[i][j][0], 
+               ctlpoints[i][j][1], ctlpoints[i][j][2]);
+         }
+      }
+      glEnd();
+      glEnable(GL_LIGHTING);
+   }
+   glPopMatrix();
+   glFlush();
+}
+
+static void reshape(int w, int h)
+{
+   glViewport(0, 0, (GLsizei) w, (GLsizei) h);
+   glMatrixMode(GL_PROJECTION);
+   glLoadIdentity();
+   gluPerspective (45.0, (GLdouble)w/(GLdouble)h, 3.0, 8.0);
+   glMatrixMode(GL_MODELVIEW);
+   glLoadIdentity();
+   glTranslatef (0.0, 0.0, -5.0);
+}
+
+static void keyboard(unsigned char key, int x, int y)
+{
+   switch (key) {
+      case 'c':
+      case 'C':
+         showPoints = !showPoints;
+         glutPostRedisplay();
+         break;
+      case 27:
+         exit(0);
+         break;
+      default:
+         break;
+   }
+}
+
+int main(int argc, char** argv)
+{
+   glutInit(&argc, argv);
+   glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
+   glutInitWindowSize (500, 500);
+   glutInitWindowPosition (100, 100);
+   glutCreateWindow(argv[0]);
+   init();
+   glutReshapeFunc(reshape);
+   glutDisplayFunc(display);
+   glutKeyboardFunc (keyboard);
+   glutMainLoop();
+   return 0; 
+}
+
+#else
+int main(int argc, char** argv)
+{
+    fprintf (stderr, "This program demonstrates a feature which is introduced in the\n");
+    fprintf (stderr, "OpenGL Utility Library (GLU) Version 1.3.\n");
+    fprintf (stderr, "If your implementation of GLU has the right extensions,\n");
+    fprintf (stderr, "you may be able to modify this program to make it run.\n");
+    return 0;
+}
+#endif
+
diff --git a/progs/redbook/texture3d.c b/progs/redbook/texture3d.c
new file mode 100644
index 0000000..c7b77c1
--- /dev/null
+++ b/progs/redbook/texture3d.c
@@ -0,0 +1,163 @@
+/*
+ * Copyright (c) 1993-2003, Silicon Graphics, Inc.
+ * All Rights Reserved
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose and without fee is hereby granted, provided that the above
+ * copyright notice appear in all copies and that both the copyright
+ * notice and this permission notice appear in supporting documentation,
+ * and that the name of Silicon Graphics, Inc. not be used in
+ * advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission.
+ *
+ * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS" AND
+ * WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
+ * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
+ * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
+ * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION, LOSS OF
+ * PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF THIRD
+ * PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN ADVISED OF
+ * THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE POSSESSION, USE
+ * OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * US Government Users Restricted Rights 
+ * Use, duplication, or disclosure by the Government is subject to
+ * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
+ * (c)(1)(ii) of the Rights in Technical Data and Computer Software
+ * clause at DFARS 252.227-7013 and/or in similar or successor clauses
+ * in the FAR or the DOD or NASA FAR Supplement.  Unpublished - rights
+ * reserved under the copyright laws of the United States.
+ *
+ * Contractor/manufacturer is:
+ *	Silicon Graphics, Inc.
+ *	1500 Crittenden Lane
+ *	Mountain View, CA  94043
+ *	United State of America
+ *
+ * OpenGL(R) is a registered trademark of Silicon Graphics, Inc.
+ */
+
+/*  texture3d.c
+ *  This program demonstrates using a three-dimensional texture.
+ *  It creates a 3D texture and then renders two rectangles
+ *  with different texture coordinates to obtain different
+ *  "slices" of the 3D texture.
+ */
+#include <GL/glew.h>
+#include <GL/glut.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#ifdef GL_VERSION_1_2
+#define	iWidth 16
+#define	iHeight 16
+#define iDepth 16
+
+static GLubyte image[iDepth][iHeight][iWidth][3];
+static GLuint texName;
+
+/*  Create a 16x16x16x3 array with different color values in
+ *  each array element [r, g, b].  Values range from 0 to 255.
+ */
+
+static void makeImage(void)
+{
+   int s, t, r;
+    
+   for (s = 0; s < 16; s++)
+      for (t = 0; t < 16; t++)
+         for (r = 0; r < 16; r++) {
+            image[r][t][s][0] = (GLubyte) (s * 17);
+            image[r][t][s][1] = (GLubyte) (t * 17);
+            image[r][t][s][2] = (GLubyte) (r * 17);
+         }
+}
+
+static void init(void)
+{    
+   glClearColor (0.0, 0.0, 0.0, 0.0);
+   glShadeModel(GL_FLAT);
+   glEnable(GL_DEPTH_TEST);
+
+   makeImage();
+   glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+
+   glGenTextures(1, &texName);
+   glBindTexture(GL_TEXTURE_3D, texName);
+   glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP);
+   glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP);
+   glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP);
+   glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, 
+                   GL_NEAREST);
+   glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, 
+                   GL_NEAREST);
+   glTexImage3D(GL_TEXTURE_3D, 0, GL_RGB, iWidth, iHeight,
+                iDepth, 0, GL_RGB, GL_UNSIGNED_BYTE, image);
+   glEnable(GL_TEXTURE_3D);
+}
+
+static void display(void)
+{
+   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+   glBegin(GL_QUADS);
+   glTexCoord3f(0.0, 0.0, 0.0); glVertex3f(-2.25, -1.0, 0.0);
+   glTexCoord3f(0.0, 1.0, 0.0); glVertex3f(-2.25, 1.0, 0.0);
+   glTexCoord3f(1.0, 1.0, 1.0); glVertex3f(-0.25, 1.0, 0.0);
+   glTexCoord3f(1.0, 0.0, 1.0); glVertex3f(-0.25, -1.0, 0.0);
+
+   glTexCoord3f(0.0, 0.0, 1.0); glVertex3f(0.25, -1.0, 0.0);
+   glTexCoord3f(0.0, 1.0, 1.0); glVertex3f(0.25, 1.0, 0.0);
+   glTexCoord3f(1.0, 1.0, 0.0); glVertex3f(2.25, 1.0, 0.0);
+   glTexCoord3f(1.0, 0.0, 0.0); glVertex3f(2.25, -1.0, 0.0);
+   glEnd();
+   glFlush();
+}
+
+static void reshape(int w, int h)
+{
+   glViewport(0, 0, (GLsizei) w, (GLsizei) h);
+   glMatrixMode(GL_PROJECTION);
+   glLoadIdentity();
+   gluPerspective(60.0, (GLfloat) w/(GLfloat) h, 1.0, 30.0);
+   glMatrixMode(GL_MODELVIEW);
+   glLoadIdentity();
+   glTranslatef(0.0, 0.0, -4.0);
+}
+
+static void keyboard(unsigned char key, int x, int y)
+{
+   switch (key) {
+      case 27:
+         exit(0);
+         break;
+   }
+}
+
+int main(int argc, char** argv)
+{
+   glutInit(&argc, argv);
+   glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
+   glutInitWindowSize(250, 250);
+   glutInitWindowPosition(100, 100);
+   glutCreateWindow(argv[0]);
+   glewInit();
+   init();
+   glutReshapeFunc(reshape);
+   glutDisplayFunc(display);
+   glutKeyboardFunc (keyboard);
+   glutMainLoop();
+   return 0; 
+}
+#else
+int main(int argc, char** argv)
+{
+    fprintf (stderr, "This program demonstrates a feature which is not in OpenGL Version 1.0 or 1.1.\n");
+    fprintf (stderr, "If your implementation of OpenGL has the right extensions,\n");
+    fprintf (stderr, "you may be able to modify this program to make it run.\n");
+    return 0;
+}
+#endif
+
diff --git a/progs/tests/vpeval.c b/progs/tests/vpeval.c
index 3e8a732..a4024b5 100644
--- a/progs/tests/vpeval.c
+++ b/progs/tests/vpeval.c
@@ -145,6 +145,11 @@
 
     printf("Using vertex program attribs? %s\n", program ? "yes" : "no");
 
+    if (program && !glutExtensionSupported("GL_NV_vertex_program")) {
+       printf("Sorry, this requires GL_NV_vertex_program\n");
+       exit(1);
+    }
+
     if (!program) {
         glMap2f(GL_MAP2_VERTEX_4,
                 0.0, 1.0, 4, 4,
diff --git a/progs/tests/vptest1.c b/progs/tests/vptest1.c
index 6e32b03..d83f9ca 100644
--- a/progs/tests/vptest1.c
+++ b/progs/tests/vptest1.c
@@ -113,6 +113,11 @@
 
    GLuint progs[5];
 
+   if (!glutExtensionSupported("GL_NV_vertex_program")) {
+      printf("Sorry, this program requires GL_NV_vertex_program\n");
+      exit(1);
+   }
+
    glGenProgramsNV(2, progs);
    assert(progs[0]);
    assert(progs[1]);
diff --git a/progs/tests/vptest2.c b/progs/tests/vptest2.c
index 4161b03..89cd6b1 100644
--- a/progs/tests/vptest2.c
+++ b/progs/tests/vptest2.c
@@ -144,6 +144,12 @@
    glutReshapeFunc( Reshape );
    glutKeyboardFunc( Key );
    glutDisplayFunc( Display );
+
+   if (!glutExtensionSupported("GL_NV_vertex_program")) {
+      printf("Sorry, this program requires GL_NV_vertex_program\n");
+      exit(1);
+   }
+
    Test1();
    Test2();
    Test3();
diff --git a/progs/tests/vptest3.c b/progs/tests/vptest3.c
index 4e4bfee..58ce227 100644
--- a/progs/tests/vptest3.c
+++ b/progs/tests/vptest3.c
@@ -93,6 +93,11 @@
 #endif
       "END\n";
 
+   if (!glutExtensionSupported("GL_NV_vertex_program")) {
+      printf("Sorry, this program requires GL_NV_vertex_program\n");
+      exit(1);
+   }
+
    glLoadProgramNV(GL_VERTEX_PROGRAM_NV, 1,
                    strlen(prog1),
                    (const GLubyte *) prog1);
diff --git a/scons/gallium.py b/scons/gallium.py
index a40a957..925effc 100644
--- a/scons/gallium.py
+++ b/scons/gallium.py
@@ -155,7 +155,9 @@
     # different scons versions building the same source file
     env['build'] = build_dir
     env.SConsignFile(os.path.join(build_dir, '.sconsign'))
-    env.CacheDir('build/cache')
+    if 'SCONS_CACHE_DIR' in os.environ:
+        print 'scons: Using build cache in %s.' % (os.environ['SCONS_CACHE_DIR'],)
+        env.CacheDir(os.environ['SCONS_CACHE_DIR'])
     env['CONFIGUREDIR'] = os.path.join(build_dir, 'conf')
     env['CONFIGURELOG'] = os.path.join(os.path.abspath(build_dir), 'config.log')
 
@@ -177,8 +179,9 @@
             '_WINDOWS',
             #'_UNICODE',
             #'UNICODE',
-            ('_WIN32_WINNT', '0x0501'), # minimum required OS version
-            ('WINVER', '0x0501'),
+            # http://msdn.microsoft.com/en-us/library/aa383745.aspx
+            ('_WIN32_WINNT', '0x0601'),
+            ('WINVER', '0x0601'),
         ]
         if msvc and env['toolchain'] != 'winddk':
             cppdefines += [
diff --git a/src/egl/main/eglapi.c b/src/egl/main/eglapi.c
index 364ad9c..2de1ac3 100644
--- a/src/egl/main/eglapi.c
+++ b/src/egl/main/eglapi.c
@@ -70,98 +70,55 @@
 
 
 /**
- * This is typically the first EGL function that an application calls.
- * We initialize our global vars and create a private _EGLDisplay object.
+ * Macros to help return an API entrypoint.
+ *
+ * These macros will unlock the display and record the error code.
  */
-EGLDisplay EGLAPIENTRY
-eglGetDisplay(EGLNativeDisplayType nativeDisplay)
-{
-   _EGLDisplay *dpy;
-   dpy = _eglFindDisplay(nativeDisplay);
-   if (!dpy) {
-      dpy = _eglNewDisplay(nativeDisplay);
-      if (dpy)
-         _eglLinkDisplay(dpy);
-   }
-   return _eglGetDisplayHandle(dpy);
-}
+#define _EGL_ERROR(disp, err, ret)              \
+   ({                                           \
+      if (disp)                                 \
+         _eglUnlockDisplay(disp);               \
+      /* EGL error codes are non-zero */        \
+      if (err)                                  \
+         _eglError(err, __FUNCTION__);          \
+      ret;                                      \
+   })
+#define _EGL_SUCCESS(disp, ret)  _EGL_ERROR(disp, EGL_SUCCESS, ret)
+/* record EGL_SUCCESS only when ret evaluates to true */
+#define _EGL_EVAL(disp, ret)  _EGL_ERROR(disp, (ret) ? EGL_SUCCESS : 0, ret)
 
 
 /**
- * This is typically the second EGL function that an application calls.
- * Here we load/initialize the actual hardware driver.
+ * A bunch of macros and checks to simplify error checking.
  */
-EGLBoolean EGLAPIENTRY
-eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
-{
-   _EGLDisplay *disp = _eglLookupDisplay(dpy);
-   EGLint major_int, minor_int;
-
-   if (!disp)
-      return _eglError(EGL_BAD_DISPLAY, __FUNCTION__);
-
-   if (!disp->Initialized) {
-      _EGLDriver *drv = disp->Driver;
-
-      if (!drv) {
-         _eglPreloadDrivers();
-         drv = _eglMatchDriver(disp);
-         if (!drv)
-            return _eglError(EGL_NOT_INITIALIZED, __FUNCTION__);
-      }
-
-      /* Initialize the particular display now */
-      if (!drv->API.Initialize(drv, disp, &major_int, &minor_int))
-         return _eglError(EGL_NOT_INITIALIZED, __FUNCTION__);
-
-      disp->APImajor = major_int;
-      disp->APIminor = minor_int;
-      snprintf(disp->Version, sizeof(disp->Version),
-               "%d.%d (%s)", major_int, minor_int, drv->Name);
-
-      /* limit to APIs supported by core */
-      disp->ClientAPIsMask &= _EGL_API_ALL_BITS;
-
-      disp->Driver = drv;
-      disp->Initialized = EGL_TRUE;
-   } else {
-      major_int = disp->APImajor;
-      minor_int = disp->APIminor;
-   }
-
-   /* Update applications version of major and minor if not NULL */
-   if ((major != NULL) && (minor != NULL)) {
-      *major = major_int;
-      *minor = minor_int;
-   }
-
-   return EGL_TRUE;
-}
+#define _EGL_CHECK_DISPLAY(disp, ret)                                   \
+   ({                                                                   \
+      _EGLDriver *__drv = _eglCheckDisplay(disp, __FUNCTION__);         \
+      if (!__drv)                                                       \
+         return _EGL_ERROR(disp, 0, ret);                               \
+      __drv;                                                            \
+   })
 
 
-EGLBoolean EGLAPIENTRY
-eglTerminate(EGLDisplay dpy)
-{
-   _EGLDisplay *disp = _eglLookupDisplay(dpy);
-
-   if (!disp)
-      return _eglError(EGL_BAD_DISPLAY, __FUNCTION__);
-
-   if (disp->Initialized) {
-      _EGLDriver *drv = disp->Driver;
-
-      drv->API.Terminate(drv, disp);
-      /* do not reset disp->Driver */
-      disp->Initialized = EGL_FALSE;
-   }
-
-   return EGL_TRUE;
-}
+#define _EGL_CHECK_OBJECT(disp, type, obj, ret)                         \
+   ({                                                                   \
+      _EGLDriver *__drv = _eglCheck ## type(disp, obj, __FUNCTION__);   \
+      if (!__drv)                                                       \
+         return _EGL_ERROR(disp, 0, ret);                               \
+      __drv;                                                            \
+   })
+#define _EGL_CHECK_SURFACE(disp, surf, ret)      \
+   _EGL_CHECK_OBJECT(disp, Surface, surf, ret)
+#define _EGL_CHECK_CONTEXT(disp, context, ret)   \
+   _EGL_CHECK_OBJECT(disp, Context, context, ret)
+#define _EGL_CHECK_CONFIG(disp, conf, ret)       \
+   _EGL_CHECK_OBJECT(disp, Config, conf, ret)
+#define _EGL_CHECK_SCREEN(disp, scrn, ret)       \
+   _EGL_CHECK_OBJECT(disp, Screen, scrn, ret)
+#define _EGL_CHECK_MODE(disp, m, ret)            \
+   _EGL_CHECK_OBJECT(disp, Mode, m, ret)
 
 
-/**
- * A bunch of check functions and declare macros to simply error checking.
- */
 static INLINE _EGLDriver *
 _eglCheckDisplay(_EGLDisplay *disp, const char *msg)
 {
@@ -219,38 +176,6 @@
 }
 
 
-#define _EGL_DECLARE_DD(dpy)                                   \
-   _EGLDisplay *disp = _eglLookupDisplay(dpy);                 \
-   _EGLDriver *drv;                                            \
-   do {                                                        \
-      drv = _eglCheckDisplay(disp, __FUNCTION__);              \
-      if (!drv)                                                \
-         return EGL_FALSE;                                     \
-   } while (0)
-
-
-#define _EGL_DECLARE_DD_AND_SURFACE(dpy, surface)              \
-   _EGLDisplay *disp = _eglLookupDisplay(dpy);                 \
-   _EGLSurface *surf = _eglLookupSurface((surface), disp);     \
-   _EGLDriver *drv;                                            \
-   do {                                                        \
-      drv = _eglCheckSurface(disp, surf, __FUNCTION__);        \
-      if (!drv)                                                \
-         return EGL_FALSE;                                     \
-   } while (0)
-
-
-#define _EGL_DECLARE_DD_AND_CONTEXT(dpy, ctx)                  \
-   _EGLDisplay *disp = _eglLookupDisplay(dpy);                 \
-   _EGLContext *context = _eglLookupContext((ctx), disp);      \
-   _EGLDriver *drv;                                            \
-   do {                                                        \
-      drv = _eglCheckContext(disp, context, __FUNCTION__);     \
-      if (!drv)                                                \
-         return EGL_FALSE;                                     \
-   } while (0)
-
-
 #ifdef EGL_MESA_screen_surface
 
 
@@ -282,36 +207,127 @@
 }
 
 
-#define _EGL_DECLARE_DD_AND_SCREEN(dpy, screen)                \
-   _EGLDisplay *disp = _eglLookupDisplay(dpy);                 \
-   _EGLScreen *scrn = _eglLookupScreen((screen), disp);        \
-   _EGLDriver *drv;                                            \
-   do {                                                        \
-      drv = _eglCheckScreen(disp, scrn, __FUNCTION__);         \
-      if (!drv)                                                \
-         return EGL_FALSE;                                     \
-   } while (0)
-
-
-#define _EGL_DECLARE_DD_AND_MODE(dpy, mode)                    \
-   _EGLDisplay *disp = _eglLookupDisplay(dpy);                 \
-   _EGLMode *m = _eglLookupMode((mode), disp);                 \
-   _EGLDriver *drv;                                            \
-   do {                                                        \
-      drv = _eglCheckMode(disp, m, __FUNCTION__);              \
-      if (!drv)                                                \
-         return EGL_FALSE;                                     \
-   } while (0)
-
-
 #endif /* EGL_MESA_screen_surface */
 
 
+/**
+ * Lookup and lock a display.
+ */
+static INLINE _EGLDisplay *
+_eglLockDisplay(EGLDisplay display)
+{
+   _EGLDisplay *dpy = _eglLookupDisplay(display);
+   if (dpy)
+      _eglLockMutex(&dpy->Mutex);
+   return dpy;
+}
+
+
+/**
+ * Unlock a display.
+ */
+static INLINE void
+_eglUnlockDisplay(_EGLDisplay *dpy)
+{
+   _eglUnlockMutex(&dpy->Mutex);
+}
+
+
+/**
+ * This is typically the first EGL function that an application calls.
+ * It associates a private _EGLDisplay object to the native display.
+ */
+EGLDisplay EGLAPIENTRY
+eglGetDisplay(EGLNativeDisplayType nativeDisplay)
+{
+   _EGLDisplay *dpy = _eglFindDisplay(nativeDisplay);
+   return _eglGetDisplayHandle(dpy);
+}
+
+
+/**
+ * This is typically the second EGL function that an application calls.
+ * Here we load/initialize the actual hardware driver.
+ */
+EGLBoolean EGLAPIENTRY
+eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
+{
+   _EGLDisplay *disp = _eglLockDisplay(dpy);
+   EGLint major_int, minor_int;
+
+   if (!disp)
+      return _EGL_ERROR(NULL, EGL_BAD_DISPLAY, EGL_FALSE);
+
+   if (!disp->Initialized) {
+      _EGLDriver *drv = disp->Driver;
+
+      if (!drv) {
+         _eglPreloadDrivers();
+         drv = _eglMatchDriver(disp);
+         if (!drv)
+            return _EGL_ERROR(disp, EGL_NOT_INITIALIZED, EGL_FALSE);
+      }
+
+      /* Initialize the particular display now */
+      if (!drv->API.Initialize(drv, disp, &major_int, &minor_int))
+         return _EGL_ERROR(disp, EGL_NOT_INITIALIZED, EGL_FALSE);
+
+      disp->APImajor = major_int;
+      disp->APIminor = minor_int;
+      snprintf(disp->Version, sizeof(disp->Version),
+               "%d.%d (%s)", major_int, minor_int, drv->Name);
+
+      /* limit to APIs supported by core */
+      disp->ClientAPIsMask &= _EGL_API_ALL_BITS;
+
+      disp->Driver = drv;
+      disp->Initialized = EGL_TRUE;
+   } else {
+      major_int = disp->APImajor;
+      minor_int = disp->APIminor;
+   }
+
+   /* Update applications version of major and minor if not NULL */
+   if ((major != NULL) && (minor != NULL)) {
+      *major = major_int;
+      *minor = minor_int;
+   }
+
+   return _EGL_SUCCESS(disp, EGL_TRUE);
+}
+
+
+EGLBoolean EGLAPIENTRY
+eglTerminate(EGLDisplay dpy)
+{
+   _EGLDisplay *disp = _eglLockDisplay(dpy);
+
+   if (!disp)
+      return _EGL_ERROR(NULL, EGL_BAD_DISPLAY, EGL_FALSE);
+
+   if (disp->Initialized) {
+      _EGLDriver *drv = disp->Driver;
+
+      drv->API.Terminate(drv, disp);
+      /* do not reset disp->Driver */
+      disp->Initialized = EGL_FALSE;
+   }
+
+   return _EGL_SUCCESS(disp, EGL_TRUE);
+}
+
+
 const char * EGLAPIENTRY
 eglQueryString(EGLDisplay dpy, EGLint name)
 {
-   _EGL_DECLARE_DD(dpy);
-   return drv->API.QueryString(drv, disp, name);
+   _EGLDisplay *disp = _eglLockDisplay(dpy);
+   _EGLDriver *drv;
+   const char *ret;
+
+   drv = _EGL_CHECK_DISPLAY(disp, NULL);
+   ret = drv->API.QueryString(drv, disp, name);
+
+   return _EGL_EVAL(disp, ret);
 }
 
 
@@ -319,8 +335,14 @@
 eglGetConfigs(EGLDisplay dpy, EGLConfig *configs,
               EGLint config_size, EGLint *num_config)
 {
-   _EGL_DECLARE_DD(dpy);
-   return drv->API.GetConfigs(drv, disp, configs, config_size, num_config);
+   _EGLDisplay *disp = _eglLockDisplay(dpy);
+   _EGLDriver *drv;
+   EGLBoolean ret;
+
+   drv = _EGL_CHECK_DISPLAY(disp, EGL_FALSE);
+   ret = drv->API.GetConfigs(drv, disp, configs, config_size, num_config);
+
+   return _EGL_EVAL(disp, ret);
 }
 
 
@@ -328,9 +350,15 @@
 eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs,
                 EGLint config_size, EGLint *num_config)
 {
-   _EGL_DECLARE_DD(dpy);
-   return drv->API.ChooseConfig(drv, disp, attrib_list, configs,
+   _EGLDisplay *disp = _eglLockDisplay(dpy);
+   _EGLDriver *drv;
+   EGLBoolean ret;
+
+   drv = _EGL_CHECK_DISPLAY(disp, EGL_FALSE);
+   ret = drv->API.ChooseConfig(drv, disp, attrib_list, configs,
                                 config_size, num_config);
+
+   return _EGL_EVAL(disp, ret);
 }
 
 
@@ -338,15 +366,15 @@
 eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config,
                    EGLint attribute, EGLint *value)
 {
-   _EGLDisplay *disp = _eglLookupDisplay(dpy);
+   _EGLDisplay *disp = _eglLockDisplay(dpy);
    _EGLConfig *conf = _eglLookupConfig(config, disp);
    _EGLDriver *drv;
+   EGLBoolean ret;
 
-   drv = _eglCheckConfig(disp, conf, __FUNCTION__);
-   if (!drv)
-      return EGL_FALSE;
+   drv = _EGL_CHECK_CONFIG(disp, conf, EGL_FALSE);
+   ret = drv->API.GetConfigAttrib(drv, disp, conf, attribute, value);
 
-   return drv->API.GetConfigAttrib(drv, disp, conf, attribute, value);
+   return _EGL_EVAL(disp, ret);
 }
 
 
@@ -354,34 +382,37 @@
 eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_list,
                  const EGLint *attrib_list)
 {
-   _EGLDisplay *disp = _eglLookupDisplay(dpy);
+   _EGLDisplay *disp = _eglLockDisplay(dpy);
    _EGLConfig *conf = _eglLookupConfig(config, disp);
    _EGLContext *share = _eglLookupContext(share_list, disp);
    _EGLDriver *drv;
    _EGLContext *context;
+   EGLContext ret;
 
-   drv = _eglCheckConfig(disp, conf, __FUNCTION__);
-   if (!drv)
-      return EGL_NO_CONTEXT;
-   if (!share && share_list != EGL_NO_CONTEXT) {
-      _eglError(EGL_BAD_CONTEXT, __FUNCTION__);
-      return EGL_NO_CONTEXT;
-   }
+   drv = _EGL_CHECK_CONFIG(disp, conf, EGL_NO_CONTEXT);
+   if (!share && share_list != EGL_NO_CONTEXT)
+      return _EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_NO_CONTEXT);
 
    context = drv->API.CreateContext(drv, disp, conf, share, attrib_list);
-   if (context)
-      return _eglLinkContext(context, disp);
-   else
-      return EGL_NO_CONTEXT;
+   ret = (context) ? _eglLinkContext(context, disp) : EGL_NO_CONTEXT;
+
+   return _EGL_EVAL(disp, ret);
 }
 
 
 EGLBoolean EGLAPIENTRY
 eglDestroyContext(EGLDisplay dpy, EGLContext ctx)
 {
-   _EGL_DECLARE_DD_AND_CONTEXT(dpy, ctx);
+   _EGLDisplay *disp = _eglLockDisplay(dpy);
+   _EGLContext *context = _eglLookupContext(ctx, disp);
+   _EGLDriver *drv;
+   EGLBoolean ret;
+
+   drv = _EGL_CHECK_CONTEXT(disp, context, EGL_FALSE);
    _eglUnlinkContext(context);
-   return drv->API.DestroyContext(drv, disp, context);
+   ret = drv->API.DestroyContext(drv, disp, context);
+
+   return _EGL_EVAL(disp, ret);
 }
 
 
@@ -389,32 +420,35 @@
 eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read,
                EGLContext ctx)
 {
-   _EGLDisplay *disp = _eglLookupDisplay(dpy);
+   _EGLDisplay *disp = _eglLockDisplay(dpy);
    _EGLContext *context = _eglLookupContext(ctx, disp);
    _EGLSurface *draw_surf = _eglLookupSurface(draw, disp);
    _EGLSurface *read_surf = _eglLookupSurface(read, disp);
    _EGLDriver *drv;
+   EGLBoolean ret;
 
    if (!disp)
-      return _eglError(EGL_BAD_DISPLAY, __FUNCTION__);
+      return _EGL_ERROR(disp, EGL_BAD_DISPLAY, EGL_FALSE);
    drv = disp->Driver;
 
    /* display is allowed to be uninitialized under certain condition */
    if (!disp->Initialized) {
       if (draw != EGL_NO_SURFACE || read != EGL_NO_SURFACE ||
           ctx != EGL_NO_CONTEXT)
-         return _eglError(EGL_BAD_DISPLAY, __FUNCTION__);
+         return _EGL_ERROR(disp, EGL_BAD_DISPLAY, EGL_FALSE);
    }
    if (!drv)
-      return EGL_TRUE;
+      return _EGL_SUCCESS(disp, EGL_TRUE);
 
    if (!context && ctx != EGL_NO_CONTEXT)
-      return _eglError(EGL_BAD_CONTEXT, __FUNCTION__);
+      return _EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_FALSE);
    if ((!draw_surf && draw != EGL_NO_SURFACE) ||
        (!read_surf && read != EGL_NO_SURFACE))
-      return _eglError(EGL_BAD_SURFACE, __FUNCTION__);
+      return _EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
 
-   return drv->API.MakeCurrent(drv, disp, draw_surf, read_surf, context);
+   ret = drv->API.MakeCurrent(drv, disp, draw_surf, read_surf, context);
+
+   return _EGL_EVAL(disp, ret);
 }
 
 
@@ -422,8 +456,15 @@
 eglQueryContext(EGLDisplay dpy, EGLContext ctx,
                 EGLint attribute, EGLint *value)
 {
-   _EGL_DECLARE_DD_AND_CONTEXT(dpy, ctx);
-   return drv->API.QueryContext(drv, disp, context, attribute, value);
+   _EGLDisplay *disp = _eglLockDisplay(dpy);
+   _EGLContext *context = _eglLookupContext(ctx, disp);
+   _EGLDriver *drv;
+   EGLBoolean ret;
+
+   drv = _EGL_CHECK_CONTEXT(disp, context, EGL_FALSE);
+   ret = drv->API.QueryContext(drv, disp, context, attribute, value);
+
+   return _EGL_EVAL(disp, ret);
 }
 
 
@@ -431,20 +472,18 @@
 eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config,
                        EGLNativeWindowType window, const EGLint *attrib_list)
 {
-   _EGLDisplay *disp = _eglLookupDisplay(dpy);
+   _EGLDisplay *disp = _eglLockDisplay(dpy);
    _EGLConfig *conf = _eglLookupConfig(config, disp);
    _EGLDriver *drv;
    _EGLSurface *surf;
+   EGLSurface ret;
 
-   drv = _eglCheckConfig(disp, conf, __FUNCTION__);
-   if (!drv)
-      return EGL_NO_SURFACE;
+   drv = _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE);
 
    surf = drv->API.CreateWindowSurface(drv, disp, conf, window, attrib_list);
-   if (surf)
-      return _eglLinkSurface(surf, disp);
-   else
-      return EGL_NO_SURFACE;
+   ret = (surf) ? _eglLinkSurface(surf, disp) : EGL_NO_SURFACE;
+
+   return _EGL_EVAL(disp, ret);
 }
 
 
@@ -452,20 +491,18 @@
 eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config,
                        EGLNativePixmapType pixmap, const EGLint *attrib_list)
 {
-   _EGLDisplay *disp = _eglLookupDisplay(dpy);
+   _EGLDisplay *disp = _eglLockDisplay(dpy);
    _EGLConfig *conf = _eglLookupConfig(config, disp);
    _EGLDriver *drv;
    _EGLSurface *surf;
+   EGLSurface ret;
 
-   drv = _eglCheckConfig(disp, conf, __FUNCTION__);
-   if (!drv)
-      return EGL_NO_SURFACE;
+   drv = _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE);
 
    surf = drv->API.CreatePixmapSurface(drv, disp, conf, pixmap, attrib_list);
-   if (surf)
-      return _eglLinkSurface(surf, disp);
-   else
-      return EGL_NO_SURFACE;
+   ret = (surf) ? _eglLinkSurface(surf, disp) : EGL_NO_SURFACE;
+
+   return _EGL_EVAL(disp, ret);
 }
 
 
@@ -473,79 +510,118 @@
 eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config,
                         const EGLint *attrib_list)
 {
-   _EGLDisplay *disp = _eglLookupDisplay(dpy);
+   _EGLDisplay *disp = _eglLockDisplay(dpy);
    _EGLConfig *conf = _eglLookupConfig(config, disp);
    _EGLDriver *drv;
    _EGLSurface *surf;
+   EGLSurface ret;
 
-   drv = _eglCheckConfig(disp, conf, __FUNCTION__);
-   if (!drv)
-      return EGL_NO_SURFACE;
+   drv = _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE);
 
    surf = drv->API.CreatePbufferSurface(drv, disp, conf, attrib_list);
-   if (surf)
-      return _eglLinkSurface(surf, disp);
-   else
-      return EGL_NO_SURFACE;
+   ret = (surf) ? _eglLinkSurface(surf, disp) : EGL_NO_SURFACE;
+
+   return _EGL_EVAL(disp, ret);
 }
 
 
 EGLBoolean EGLAPIENTRY
 eglDestroySurface(EGLDisplay dpy, EGLSurface surface)
 {
-   _EGL_DECLARE_DD_AND_SURFACE(dpy, surface);
+   _EGLDisplay *disp = _eglLockDisplay(dpy);
+   _EGLSurface *surf = _eglLookupSurface(surface, disp);
+   _EGLDriver *drv;
+   EGLBoolean ret;
+
+   drv = _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE);
    _eglUnlinkSurface(surf);
-   return drv->API.DestroySurface(drv, disp, surf);
+   ret = drv->API.DestroySurface(drv, disp, surf);
+
+   return _EGL_EVAL(disp, ret);
 }
 
 EGLBoolean EGLAPIENTRY
 eglQuerySurface(EGLDisplay dpy, EGLSurface surface,
                 EGLint attribute, EGLint *value)
 {
-   _EGL_DECLARE_DD_AND_SURFACE(dpy, surface);
-   return drv->API.QuerySurface(drv, disp, surf, attribute, value);
+   _EGLDisplay *disp = _eglLockDisplay(dpy);
+   _EGLSurface *surf = _eglLookupSurface(surface, disp);
+   _EGLDriver *drv;
+   EGLBoolean ret;
+
+   drv = _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE);
+   ret = drv->API.QuerySurface(drv, disp, surf, attribute, value);
+
+   return _EGL_EVAL(disp, ret);
 }
 
 EGLBoolean EGLAPIENTRY
 eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface,
                  EGLint attribute, EGLint value)
 {
-   _EGL_DECLARE_DD_AND_SURFACE(dpy, surface);
-   return drv->API.SurfaceAttrib(drv, disp, surf, attribute, value);
+   _EGLDisplay *disp = _eglLockDisplay(dpy);
+   _EGLSurface *surf = _eglLookupSurface(surface, disp);
+   _EGLDriver *drv;
+   EGLBoolean ret;
+
+   drv = _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE);
+   ret = drv->API.SurfaceAttrib(drv, disp, surf, attribute, value);
+
+   return _EGL_EVAL(disp, ret);
 }
 
 
 EGLBoolean EGLAPIENTRY
 eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
 {
-   _EGL_DECLARE_DD_AND_SURFACE(dpy, surface);
-   return drv->API.BindTexImage(drv, disp, surf, buffer);
+   _EGLDisplay *disp = _eglLockDisplay(dpy);
+   _EGLSurface *surf = _eglLookupSurface(surface, disp);
+   _EGLDriver *drv;
+   EGLBoolean ret;
+
+   drv = _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE);
+   ret = drv->API.BindTexImage(drv, disp, surf, buffer);
+
+   return _EGL_EVAL(disp, ret);
 }
 
 
 EGLBoolean EGLAPIENTRY
 eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
 {
-   _EGL_DECLARE_DD_AND_SURFACE(dpy, surface);
-   return drv->API.ReleaseTexImage(drv, disp, surf, buffer);
+   _EGLDisplay *disp = _eglLockDisplay(dpy);
+   _EGLSurface *surf = _eglLookupSurface(surface, disp);
+   _EGLDriver *drv;
+   EGLBoolean ret;
+
+   drv = _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE);
+   ret = drv->API.ReleaseTexImage(drv, disp, surf, buffer);
+
+   return _EGL_EVAL(disp, ret);
 }
 
 
 EGLBoolean EGLAPIENTRY
 eglSwapInterval(EGLDisplay dpy, EGLint interval)
 {
+   _EGLDisplay *disp = _eglLockDisplay(dpy);
    _EGLContext *ctx = _eglGetCurrentContext();
    _EGLSurface *surf;
-   _EGL_DECLARE_DD(dpy);
+   _EGLDriver *drv;
+   EGLBoolean ret;
+
+   drv = _EGL_CHECK_DISPLAY(disp, EGL_FALSE);
 
    if (!ctx || !_eglIsContextLinked(ctx) || ctx->Resource.Display != disp)
-      return _eglError(EGL_BAD_CONTEXT, __FUNCTION__);
+      return _EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_FALSE);
 
    surf = ctx->DrawSurface;
    if (!_eglIsSurfaceLinked(surf))
-      return _eglError(EGL_BAD_SURFACE, __FUNCTION__);
+      return _EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
 
-   return drv->API.SwapInterval(drv, disp, surf, interval);
+   ret = drv->API.SwapInterval(drv, disp, surf, interval);
+
+   return _EGL_EVAL(disp, ret);
 }
 
 
@@ -553,21 +629,35 @@
 eglSwapBuffers(EGLDisplay dpy, EGLSurface surface)
 {
    _EGLContext *ctx = _eglGetCurrentContext();
-   _EGL_DECLARE_DD_AND_SURFACE(dpy, surface);
+   _EGLDisplay *disp = _eglLockDisplay(dpy);
+   _EGLSurface *surf = _eglLookupSurface(surface, disp);
+   _EGLDriver *drv;
+   EGLBoolean ret;
+
+   drv = _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE);
 
    /* surface must be bound to current context in EGL 1.4 */
    if (!ctx || !_eglIsContextLinked(ctx) || surf != ctx->DrawSurface)
-      return _eglError(EGL_BAD_SURFACE, __FUNCTION__);
+      return _EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
 
-   return drv->API.SwapBuffers(drv, disp, surf);
+   ret = drv->API.SwapBuffers(drv, disp, surf);
+
+   return _EGL_EVAL(disp, ret);
 }
 
 
 EGLBoolean EGLAPIENTRY
 eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target)
 {
-   _EGL_DECLARE_DD_AND_SURFACE(dpy, surface);
-   return drv->API.CopyBuffers(drv, disp, surf, target);
+   _EGLDisplay *disp = _eglLockDisplay(dpy);
+   _EGLSurface *surf = _eglLookupSurface(surface, disp);
+   _EGLDriver *drv;
+   EGLBoolean ret;
+
+   drv = _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE);
+   ret = drv->API.CopyBuffers(drv, disp, surf, target);
+
+   return _EGL_EVAL(disp, ret);
 }
 
 
@@ -577,19 +667,24 @@
    _EGLContext *ctx = _eglGetCurrentContext();
    _EGLDisplay *disp;
    _EGLDriver *drv;
+   EGLBoolean ret;
 
    if (!ctx)
-      return EGL_TRUE;
+      return _EGL_SUCCESS(NULL, EGL_TRUE);
+
+   disp = ctx->Resource.Display;
+   _eglLockMutex(&disp->Mutex);
+
    /* let bad current context imply bad current surface */
    if (!_eglIsContextLinked(ctx) || !_eglIsSurfaceLinked(ctx->DrawSurface))
-      return _eglError(EGL_BAD_CURRENT_SURFACE, __FUNCTION__);
+      return _EGL_ERROR(disp, EGL_BAD_CURRENT_SURFACE, EGL_FALSE);
 
    /* a valid current context implies an initialized current display */
-   disp = ctx->Resource.Display;
    assert(disp->Initialized);
    drv = disp->Driver;
+   ret = drv->API.WaitClient(drv, disp, ctx);
 
-   return drv->API.WaitClient(drv, disp, ctx);
+   return _EGL_EVAL(disp, ret);
 }
 
 
@@ -603,7 +698,7 @@
    EGLBoolean ret;
 
    if (api_index != es_index && _eglIsCurrentThreadDummy())
-      return _eglError(EGL_BAD_ALLOC, "eglWaitGL");
+      return _EGL_ERROR(NULL, EGL_BAD_ALLOC, EGL_FALSE);
 
    t->CurrentAPIIndex = es_index;
    ret = eglWaitClient();
@@ -621,19 +716,24 @@
    _EGLContext *ctx = _eglGetCurrentContext();
    _EGLDisplay *disp;
    _EGLDriver *drv;
+   EGLBoolean ret;
 
    if (!ctx)
-      return EGL_TRUE;
+      return _EGL_SUCCESS(NULL, EGL_TRUE);
+
+   disp = ctx->Resource.Display;
+   _eglLockMutex(&disp->Mutex);
+
    /* let bad current context imply bad current surface */
    if (!_eglIsContextLinked(ctx) || !_eglIsSurfaceLinked(ctx->DrawSurface))
-      return _eglError(EGL_BAD_CURRENT_SURFACE, __FUNCTION__);
+      return _EGL_ERROR(disp, EGL_BAD_CURRENT_SURFACE, EGL_FALSE);
 
    /* a valid current context implies an initialized current display */
-   disp = ctx->Resource.Display;
    assert(disp->Initialized);
    drv = disp->Driver;
+   ret = drv->API.WaitNative(drv, disp, engine);
 
-   return drv->API.WaitNative(drv, disp, engine);
+   return _EGL_EVAL(disp, ret);
 }
 
 
@@ -641,7 +741,11 @@
 eglGetCurrentDisplay(void)
 {
    _EGLContext *ctx = _eglGetCurrentContext();
-   return (ctx) ? _eglGetDisplayHandle(ctx->Resource.Display) : EGL_NO_DISPLAY;
+   EGLDisplay ret;
+
+   ret = (ctx) ? _eglGetDisplayHandle(ctx->Resource.Display) : EGL_NO_DISPLAY;
+
+   return _EGL_SUCCESS(NULL, ret);
 }
 
 
@@ -649,7 +753,11 @@
 eglGetCurrentContext(void)
 {
    _EGLContext *ctx = _eglGetCurrentContext();
-   return _eglGetContextHandle(ctx);
+   EGLContext ret;
+
+   ret = _eglGetContextHandle(ctx);
+
+   return _EGL_SUCCESS(NULL, ret);
 }
 
 
@@ -657,10 +765,12 @@
 eglGetCurrentSurface(EGLint readdraw)
 {
    _EGLContext *ctx = _eglGetCurrentContext();
+   EGLint err = EGL_SUCCESS;
    _EGLSurface *surf;
+   EGLSurface ret;
 
    if (!ctx)
-      return EGL_NO_SURFACE;
+      return _EGL_SUCCESS(NULL, EGL_NO_SURFACE);
 
    switch (readdraw) {
    case EGL_DRAW:
@@ -670,12 +780,14 @@
       surf = ctx->ReadSurface;
       break;
    default:
-      _eglError(EGL_BAD_PARAMETER, __FUNCTION__);
       surf = NULL;
+      err = EGL_BAD_PARAMETER;
       break;
    }
 
-   return _eglGetSurfaceHandle(surf);
+   ret = _eglGetSurfaceHandle(surf);
+
+   return _EGL_ERROR(NULL, err, ret);
 }
 
 
@@ -719,27 +831,34 @@
       { NULL, NULL }
    };
    EGLint i;
+   _EGLProc ret;
 
    if (!procname)
-      return NULL;
+      return _EGL_SUCCESS(NULL, NULL);
+
+   ret = NULL;
    if (strncmp(procname, "egl", 3) == 0) {
       for (i = 0; egl_functions[i].name; i++) {
-         if (strcmp(egl_functions[i].name, procname) == 0)
-            return egl_functions[i].function;
+         if (strcmp(egl_functions[i].name, procname) == 0) {
+            ret = egl_functions[i].function;
+            break;
+         }
       }
    }
+   if (ret)
+      return _EGL_SUCCESS(NULL, ret);
 
    _eglPreloadDrivers();
 
    /* now loop over drivers to query their procs */
    for (i = 0; i < _eglGlobal.NumDrivers; i++) {
       _EGLDriver *drv = _eglGlobal.Drivers[i];
-      _EGLProc p = drv->API.GetProcAddress(drv, procname);
-      if (p)
-         return p;
+      ret = drv->API.GetProcAddress(drv, procname);
+      if (ret)
+         break;
    }
 
-   return NULL;
+   return _EGL_SUCCESS(NULL, ret);
 }
 
 
@@ -755,9 +874,16 @@
                   const EGLint *attrib_list, EGLModeMESA *modes,
                   EGLint modes_size, EGLint *num_modes)
 {
-   _EGL_DECLARE_DD_AND_SCREEN(dpy, screen);
-   return drv->API.ChooseModeMESA(drv, disp, scrn, attrib_list,
-                                  modes, modes_size, num_modes);
+   _EGLDisplay *disp = _eglLockDisplay(dpy);
+   _EGLScreen *scrn = _eglLookupScreen(screen, disp);
+   _EGLDriver *drv;
+   EGLBoolean ret;
+
+   drv = _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE);
+   ret = drv->API.ChooseModeMESA(drv, disp, scrn, attrib_list,
+         modes, modes_size, num_modes);
+
+   return _EGL_EVAL(disp, ret);
 }
 
 
@@ -765,8 +891,15 @@
 eglGetModesMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *modes,
                 EGLint mode_size, EGLint *num_mode)
 {
-   _EGL_DECLARE_DD_AND_SCREEN(dpy, screen);
-   return drv->API.GetModesMESA(drv, disp, scrn, modes, mode_size, num_mode);
+   _EGLDisplay *disp = _eglLockDisplay(dpy);
+   _EGLScreen *scrn = _eglLookupScreen(screen, disp);
+   _EGLDriver *drv;
+   EGLBoolean ret;
+
+   drv = _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE);
+   ret = drv->API.GetModesMESA(drv, disp, scrn, modes, mode_size, num_mode);
+
+   return _EGL_EVAL(disp, ret);
 }
 
 
@@ -774,8 +907,15 @@
 eglGetModeAttribMESA(EGLDisplay dpy, EGLModeMESA mode,
                      EGLint attribute, EGLint *value)
 {
-   _EGL_DECLARE_DD_AND_MODE(dpy, mode);
-   return drv->API.GetModeAttribMESA(drv, disp, m, attribute, value);
+   _EGLDisplay *disp = _eglLockDisplay(dpy);
+   _EGLMode *m = _eglLookupMode(mode, disp);
+   _EGLDriver *drv;
+   EGLBoolean ret;
+
+   drv = _EGL_CHECK_MODE(disp, m, EGL_FALSE);
+   ret = drv->API.GetModeAttribMESA(drv, disp, m, attribute, value);
+
+   return _EGL_EVAL(disp, ret);
 }
 
 
@@ -783,20 +923,20 @@
 eglCopyContextMESA(EGLDisplay dpy, EGLContext source, EGLContext dest,
                    EGLint mask)
 {
-   _EGLDisplay *disp = _eglLookupDisplay(dpy);
+   _EGLDisplay *disp = _eglLockDisplay(dpy);
    _EGLContext *source_context = _eglLookupContext(source, disp);
    _EGLContext *dest_context = _eglLookupContext(dest, disp);
    _EGLDriver *drv;
+   EGLBoolean ret;
 
-   drv = _eglCheckContext(disp, source_context, __FUNCTION__);
-   if (!drv || !dest_context) {
-      if (drv)
-         _eglError(EGL_BAD_CONTEXT, __FUNCTION__);
-      return EGL_FALSE;
-   }
+   drv = _EGL_CHECK_CONTEXT(disp, source_context, EGL_FALSE);
+   if (!dest_context)
+      return _EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_FALSE);
 
-   return drv->API.CopyContextMESA(drv, disp, source_context, dest_context,
-                                   mask);
+   ret = drv->API.CopyContextMESA(drv, disp,
+         source_context, dest_context, mask);
+
+   return _EGL_EVAL(disp, ret);
 }
 
 
@@ -804,9 +944,14 @@
 eglGetScreensMESA(EGLDisplay dpy, EGLScreenMESA *screens,
                   EGLint max_screens, EGLint *num_screens)
 {
-   _EGL_DECLARE_DD(dpy);
-   return drv->API.GetScreensMESA(drv, disp, screens,
-                                  max_screens, num_screens);
+   _EGLDisplay *disp = _eglLockDisplay(dpy);
+   _EGLDriver *drv;
+   EGLBoolean ret;
+
+   drv = _EGL_CHECK_DISPLAY(disp, EGL_FALSE);
+   ret = drv->API.GetScreensMESA(drv, disp, screens, max_screens, num_screens);
+
+   return _EGL_EVAL(disp, ret);
 }
 
 
@@ -814,20 +959,18 @@
 eglCreateScreenSurfaceMESA(EGLDisplay dpy, EGLConfig config,
                            const EGLint *attrib_list)
 {
-   _EGLDisplay *disp = _eglLookupDisplay(dpy);
+   _EGLDisplay *disp = _eglLockDisplay(dpy);
    _EGLConfig *conf = _eglLookupConfig(config, disp);
    _EGLDriver *drv;
    _EGLSurface *surf;
+   EGLSurface ret;
 
-   drv = _eglCheckConfig(disp, conf, __FUNCTION__);
-   if (!drv)
-      return EGL_NO_SURFACE;
+   drv = _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE);
 
    surf = drv->API.CreateScreenSurfaceMESA(drv, disp, conf, attrib_list);
-   if (surf)
-      return _eglLinkSurface(surf, disp);
-   else
-      return EGL_NO_SURFACE;
+   ret = (surf) ? _eglLinkSurface(surf, disp) : EGL_NO_SURFACE;
+
+   return _EGL_EVAL(disp, ret);
 }
 
 
@@ -835,29 +978,37 @@
 eglShowScreenSurfaceMESA(EGLDisplay dpy, EGLint screen,
                          EGLSurface surface, EGLModeMESA mode)
 {
-   _EGLDisplay *disp = _eglLookupDisplay(dpy);
+   _EGLDisplay *disp = _eglLockDisplay(dpy);
    _EGLScreen *scrn = _eglLookupScreen((EGLScreenMESA) screen, disp);
    _EGLSurface *surf = _eglLookupSurface(surface, disp);
    _EGLMode *m = _eglLookupMode(mode, disp);
    _EGLDriver *drv;
+   EGLBoolean ret;
 
-   drv = _eglCheckScreen(disp, scrn, __FUNCTION__);
-   if (!drv)
-      return EGL_FALSE;
+   drv = _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE);
    if (!surf && surface != EGL_NO_SURFACE)
-      return _eglError(EGL_BAD_SURFACE, __FUNCTION__);
+      return _EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
    if (!m && mode != EGL_NO_MODE_MESA)
-      return _eglError(EGL_BAD_MODE_MESA, __FUNCTION__);
+      return _EGL_ERROR(disp, EGL_BAD_MODE_MESA, EGL_FALSE);
 
-   return drv->API.ShowScreenSurfaceMESA(drv, disp, scrn, surf, m);
+   ret = drv->API.ShowScreenSurfaceMESA(drv, disp, scrn, surf, m);
+
+   return _EGL_EVAL(disp, ret);
 }
 
 
 EGLBoolean
 eglScreenPositionMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLint x, EGLint y)
 {
-   _EGL_DECLARE_DD_AND_SCREEN(dpy, screen);
-   return drv->API.ScreenPositionMESA(drv, disp, scrn, x, y);
+   _EGLDisplay *disp = _eglLockDisplay(dpy);
+   _EGLScreen *scrn = _eglLookupScreen(screen, disp);
+   _EGLDriver *drv;
+   EGLBoolean ret;
+
+   drv = _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE);
+   ret = drv->API.ScreenPositionMESA(drv, disp, scrn, x, y);
+
+   return _EGL_EVAL(disp, ret);
 }
 
 
@@ -865,8 +1016,15 @@
 eglQueryScreenMESA(EGLDisplay dpy, EGLScreenMESA screen,
                    EGLint attribute, EGLint *value)
 {
-   _EGL_DECLARE_DD_AND_SCREEN(dpy, screen);
-   return drv->API.QueryScreenMESA(drv, disp, scrn, attribute, value);
+   _EGLDisplay *disp = _eglLockDisplay(dpy);
+   _EGLScreen *scrn = _eglLookupScreen(screen, disp);
+   _EGLDriver *drv;
+   EGLBoolean ret;
+
+   drv = _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE);
+   ret = drv->API.QueryScreenMESA(drv, disp, scrn, attribute, value);
+
+   return _EGL_EVAL(disp, ret);
 }
 
 
@@ -874,49 +1032,51 @@
 eglQueryScreenSurfaceMESA(EGLDisplay dpy, EGLScreenMESA screen,
                           EGLSurface *surface)
 {
-   _EGLDisplay *disp = _eglLookupDisplay(dpy);
+   _EGLDisplay *disp = _eglLockDisplay(dpy);
    _EGLScreen *scrn = _eglLookupScreen((EGLScreenMESA) screen, disp);
    _EGLDriver *drv;
    _EGLSurface *surf;
+   EGLBoolean ret;
 
-   drv = _eglCheckScreen(disp, scrn, __FUNCTION__);
-   if (!drv)
-      return EGL_FALSE;
-
-   if (drv->API.QueryScreenSurfaceMESA(drv, disp, scrn, &surf) != EGL_TRUE)
-      surf = NULL;
-   if (surface)
+   drv = _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE);
+   ret = drv->API.QueryScreenSurfaceMESA(drv, disp, scrn, &surf);
+   if (ret && surface)
       *surface = _eglGetSurfaceHandle(surf);
-   return (surf != NULL);
+
+   return _EGL_EVAL(disp, ret);
 }
 
 
 EGLBoolean
 eglQueryScreenModeMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *mode)
 {
-   _EGLDisplay *disp = _eglLookupDisplay(dpy);
+   _EGLDisplay *disp = _eglLockDisplay(dpy);
    _EGLScreen *scrn = _eglLookupScreen((EGLScreenMESA) screen, disp);
    _EGLDriver *drv;
    _EGLMode *m;
+   EGLBoolean ret;
 
-   drv = _eglCheckScreen(disp, scrn, __FUNCTION__);
-   if (!drv)
-      return EGL_FALSE;
-
-   if (drv->API.QueryScreenModeMESA(drv, disp, scrn, &m) != EGL_TRUE)
-      m = NULL;
-   if (mode)
+   drv = _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE);
+   ret = drv->API.QueryScreenModeMESA(drv, disp, scrn, &m);
+   if (ret && mode)
       *mode = m->Handle;
 
-   return (m != NULL);
+   return _EGL_EVAL(disp, ret);
 }
 
 
 const char *
 eglQueryModeStringMESA(EGLDisplay dpy, EGLModeMESA mode)
 {
-   _EGL_DECLARE_DD_AND_MODE(dpy, mode);
-   return drv->API.QueryModeStringMESA(drv, disp, m);
+   _EGLDisplay *disp = _eglLockDisplay(dpy);
+   _EGLMode *m = _eglLookupMode(mode, disp);
+   _EGLDriver *drv;
+   const char *ret;
+
+   drv = _EGL_CHECK_MODE(disp, m, NULL);
+   ret = drv->API.QueryModeStringMESA(drv, disp, m);
+
+   return _EGL_EVAL(disp, ret);
 }
 
 
@@ -947,13 +1107,14 @@
    _EGLThreadInfo *t = _eglGetCurrentThread();
 
    if (_eglIsCurrentThreadDummy())
-      return _eglError(EGL_BAD_ALLOC, "eglBindAPI");
+      return _EGL_ERROR(NULL, EGL_BAD_ALLOC, EGL_FALSE);
 
    if (!_eglIsApiValid(api))
-      return _eglError(EGL_BAD_PARAMETER, "eglBindAPI");
+      return _EGL_ERROR(NULL, EGL_BAD_PARAMETER, EGL_FALSE);
 
    t->CurrentAPIIndex = _eglConvertApiToIndex(api);
-   return EGL_TRUE;
+
+   return _EGL_SUCCESS(NULL, EGL_TRUE);
 }
 
 
@@ -963,9 +1124,13 @@
 EGLenum
 eglQueryAPI(void)
 {
-   /* returns one of EGL_OPENGL_API, EGL_OPENGL_ES_API or EGL_OPENVG_API */
    _EGLThreadInfo *t = _eglGetCurrentThread();
-   return _eglConvertApiFromIndex(t->CurrentAPIIndex);
+   EGLenum ret;
+
+   /* returns one of EGL_OPENGL_API, EGL_OPENGL_ES_API or EGL_OPENVG_API */
+   ret = _eglConvertApiFromIndex(t->CurrentAPIIndex);
+
+   return _EGL_SUCCESS(NULL, ret);
 }
 
 
@@ -974,21 +1139,19 @@
                                  EGLClientBuffer buffer, EGLConfig config,
                                  const EGLint *attrib_list)
 {
-   _EGLDisplay *disp = _eglLookupDisplay(dpy);
+   _EGLDisplay *disp = _eglLockDisplay(dpy);
    _EGLConfig *conf = _eglLookupConfig(config, disp);
    _EGLDriver *drv;
    _EGLSurface *surf;
+   EGLSurface ret;
 
-   drv = _eglCheckConfig(disp, conf, __FUNCTION__);
-   if (!drv)
-      return EGL_NO_SURFACE;
+   drv = _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE);
 
    surf = drv->API.CreatePbufferFromClientBuffer(drv, disp, buftype, buffer,
                                                  conf, attrib_list);
-   if (surf)
-      return _eglLinkSurface(surf, disp);
-   else
-      return EGL_NO_SURFACE;
+   ret = (surf) ? _eglLinkSurface(surf, disp) : EGL_NO_SURFACE;
+
+   return _EGL_EVAL(disp, ret);
 }
 
 
@@ -1005,9 +1168,14 @@
          _EGLContext *ctx = t->CurrentContexts[i];
          if (ctx) {
             _EGLDisplay *disp = ctx->Resource.Display;
-            _EGLDriver *drv = disp->Driver;
+            _EGLDriver *drv;
+
             t->CurrentAPIIndex = i;
+
+            _eglLockMutex(&disp->Mutex);
+            drv = disp->Driver;
             (void) drv->API.MakeCurrent(drv, disp, NULL, NULL, NULL);
+            _eglUnlockMutex(&disp->Mutex);
          }
       }
 
@@ -1015,7 +1183,8 @@
    }
 
    _eglDestroyCurrentThread();
-   return EGL_TRUE;
+
+   return _EGL_SUCCESS(NULL, EGL_TRUE);
 }
 
 
@@ -1029,42 +1198,40 @@
 eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target,
                   EGLClientBuffer buffer, const EGLint *attr_list)
 {
-   _EGLDisplay *disp = _eglLookupDisplay(dpy);
+   _EGLDisplay *disp = _eglLockDisplay(dpy);
    _EGLContext *context = _eglLookupContext(ctx, disp);
    _EGLDriver *drv;
    _EGLImage *img;
+   EGLImageKHR ret;
 
-   drv = _eglCheckDisplay(disp, __FUNCTION__);
-   if (!drv)
-      return EGL_NO_IMAGE_KHR;
-   if (!context && ctx != EGL_NO_CONTEXT) {
-      _eglError(EGL_BAD_CONTEXT, __FUNCTION__);
-      return EGL_NO_IMAGE_KHR;
-   }
+   drv = _EGL_CHECK_DISPLAY(disp, EGL_NO_IMAGE_KHR);
+   if (!context && ctx != EGL_NO_CONTEXT)
+      return _EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_NO_IMAGE_KHR);
 
    img = drv->API.CreateImageKHR(drv,
          disp, context, target, buffer, attr_list);
-   if (img)
-      return _eglLinkImage(img, disp);
-   else
-      return EGL_NO_IMAGE_KHR;
+   ret = (img) ? _eglLinkImage(img, disp) : EGL_NO_IMAGE_KHR;
+
+   return _EGL_EVAL(disp, ret);
 }
 
 
-EGLBoolean eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR image)
+EGLBoolean
+eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR image)
 {
-   _EGLDisplay *disp = _eglLookupDisplay(dpy);
+   _EGLDisplay *disp = _eglLockDisplay(dpy);
    _EGLImage *img = _eglLookupImage(image, disp);
    _EGLDriver *drv;
+   EGLBoolean ret;
 
-   drv = _eglCheckDisplay(disp, __FUNCTION__);
-   if (!drv)
-      return EGL_FALSE;
+   drv = _EGL_CHECK_DISPLAY(disp, EGL_FALSE);
    if (!img)
-      return _eglError(EGL_BAD_PARAMETER, __FUNCTION__);
+      return _EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
 
    _eglUnlinkImage(img);
-   return drv->API.DestroyImageKHR(drv, disp, img);
+   ret = drv->API.DestroyImageKHR(drv, disp, img);
+
+   return _EGL_EVAL(disp, ret);
 }
 
 
diff --git a/src/egl/main/eglapi.h b/src/egl/main/eglapi.h
index c3676ec..3e2ba8d 100644
--- a/src/egl/main/eglapi.h
+++ b/src/egl/main/eglapi.h
@@ -45,6 +45,7 @@
 typedef EGLBoolean (*WaitClient_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx);
 typedef EGLBoolean (*WaitNative_t)(_EGLDriver *drv, _EGLDisplay *dpy, EGLint engine);
 
+/* this function may be called from multiple threads at the same time */
 typedef _EGLProc (*GetProcAddress_t)(_EGLDriver *drv, const char *procname);
 
 
diff --git a/src/egl/main/eglcurrent.c b/src/egl/main/eglcurrent.c
index 989c19a..c697bf7 100644
--- a/src/egl/main/eglcurrent.c
+++ b/src/egl/main/eglcurrent.c
@@ -248,19 +248,20 @@
 
 
 /**
- * Record EGL error code.
+ * Record EGL error code and return EGL_FALSE.
  */
 EGLBoolean
 _eglError(EGLint errCode, const char *msg)
 {
    _EGLThreadInfo *t = _eglGetCurrentThread();
-   const char *s;
 
    if (t == &dummy_thread)
       return EGL_FALSE;
 
-   if (t->LastError == EGL_SUCCESS) {
-      t->LastError = errCode;
+   t->LastError = errCode;
+
+   if (errCode != EGL_SUCCESS) {
+      const char *s;
 
       switch (errCode) {
       case EGL_BAD_ACCESS:
diff --git a/src/egl/main/egldisplay.c b/src/egl/main/egldisplay.c
index d7a8d14..f7dbe8e 100644
--- a/src/egl/main/egldisplay.c
+++ b/src/egl/main/egldisplay.c
@@ -45,72 +45,8 @@
 
 
 /**
- * Allocate a new _EGLDisplay object for the given nativeDisplay handle.
- * We'll also try to determine the device driver name at this time.
- *
- * Note that nativeDisplay may be an X Display ptr, or a string.
- */
-_EGLDisplay *
-_eglNewDisplay(EGLNativeDisplayType nativeDisplay)
-{
-   _EGLDisplay *dpy = (_EGLDisplay *) calloc(1, sizeof(_EGLDisplay));
-   if (dpy) {
-      dpy->NativeDisplay = nativeDisplay;
-   }
-   return dpy;
-}
-
-
-/**
- * Link a display to itself and return the handle of the link.
- * The handle can be passed to client directly.
- */
-EGLDisplay
-_eglLinkDisplay(_EGLDisplay *dpy)
-{
-   _eglLockMutex(_eglGlobal.Mutex);
-
-   dpy->Next = _eglGlobal.DisplayList;
-   _eglGlobal.DisplayList = dpy;
-
-   _eglUnlockMutex(_eglGlobal.Mutex);
-
-   return (EGLDisplay) dpy;
-}
-
-
-/**
- * Unlink a linked display from itself.
- * Accessing an unlinked display should generate EGL_BAD_DISPLAY error.
- */
-void
-_eglUnlinkDisplay(_EGLDisplay *dpy)
-{
-   _EGLDisplay *prev;
-
-   _eglLockMutex(_eglGlobal.Mutex);
-
-   prev = _eglGlobal.DisplayList;
-   if (prev != dpy) {
-      while (prev) {
-         if (prev->Next == dpy)
-            break;
-         prev = prev->Next;
-      }
-      assert(prev);
-      prev->Next = dpy->Next;
-   }
-   else {
-      _eglGlobal.DisplayList = dpy->Next;
-   }
-
-   _eglUnlockMutex(_eglGlobal.Mutex);
-}
-
-
-/**
- * Find the display corresponding to the specified native display id in all
- * linked displays.
+ * Find the display corresponding to the specified native display, or create a
+ * new one.
  */
 _EGLDisplay *
 _eglFindDisplay(EGLNativeDisplayType nativeDisplay)
@@ -119,18 +55,30 @@
 
    _eglLockMutex(_eglGlobal.Mutex);
 
+   /* search the display list first */
    dpy = _eglGlobal.DisplayList;
    while (dpy) {
-      if (dpy->NativeDisplay == nativeDisplay) {
-         _eglUnlockMutex(_eglGlobal.Mutex);
-         return dpy;
-      }
+      if (dpy->NativeDisplay == nativeDisplay)
+         break;
       dpy = dpy->Next;
    }
 
+   /* create a new display */
+   if (!dpy) {
+      dpy = (_EGLDisplay *) calloc(1, sizeof(_EGLDisplay));
+      if (dpy) {
+         _eglInitMutex(&dpy->Mutex);
+         dpy->NativeDisplay = nativeDisplay;
+
+         /* add to the display list */ 
+         dpy->Next = _eglGlobal.DisplayList;
+         _eglGlobal.DisplayList = dpy;
+      }
+   }
+
    _eglUnlockMutex(_eglGlobal.Mutex);
 
-   return NULL;
+   return dpy;
 }
 
 
diff --git a/src/egl/main/egldisplay.h b/src/egl/main/egldisplay.h
index 0390329..43b39bd 100644
--- a/src/egl/main/egldisplay.h
+++ b/src/egl/main/egldisplay.h
@@ -4,6 +4,7 @@
 
 #include "egltypedefs.h"
 #include "egldefines.h"
+#include "eglmutex.h"
 
 
 enum _egl_resource_type {
@@ -53,6 +54,8 @@
    /* used to link displays */
    _EGLDisplay *Next;
 
+   _EGLMutex Mutex;
+
    EGLNativeDisplayType NativeDisplay;
 
    EGLBoolean Initialized; /**< True if the display is initialized */
@@ -85,19 +88,7 @@
 
 
 extern _EGLDisplay *
-_eglNewDisplay(EGLNativeDisplayType displayName);
-
-
-extern EGLDisplay
-_eglLinkDisplay(_EGLDisplay *dpy);
-
-
-extern void
-_eglUnlinkDisplay(_EGLDisplay *dpy);
-
-
-extern _EGLDisplay *
-_eglFindDisplay(EGLNativeDisplayType nativeDisplay);
+_eglFindDisplay(EGLNativeDisplayType displayName);
 
 
 PUBLIC void
@@ -164,16 +155,6 @@
 }
 
 
-/**
- * Return true if the display is linked.
- */
-static INLINE EGLBoolean
-_eglIsDisplayLinked(_EGLDisplay *dpy)
-{
-   return (EGLBoolean) (_eglGetDisplayHandle(dpy) != EGL_NO_DISPLAY);
-}
-
-
 extern void
 _eglLinkResource(_EGLResource *res, _EGLResourceType type, _EGLDisplay *dpy);
 
diff --git a/src/egl/main/egldriver.c b/src/egl/main/egldriver.c
index a87c697..8748fe5 100644
--- a/src/egl/main/egldriver.c
+++ b/src/egl/main/egldriver.c
@@ -237,6 +237,10 @@
    _EGLDriver *best_drv = NULL;
    EGLint best_score = -1, i;
 
+   /*
+    * this function is called after preloading and the drivers never change
+    * after preloading.
+    */
    for (i = 0; i < _eglGlobal.NumDrivers; i++) {
       _EGLDriver *drv = _eglGlobal.Drivers[i];
       EGLint score;
@@ -529,14 +533,21 @@
 {
    EGLBoolean loaded;
 
+   /* protect the preloading process */
+   _eglLockMutex(_eglGlobal.Mutex);
+
    /* already preloaded */
-   if (_eglGlobal.NumDrivers)
+   if (_eglGlobal.NumDrivers) {
+      _eglUnlockMutex(_eglGlobal.Mutex);
       return EGL_TRUE;
+   }
 
    loaded = (_eglPreloadUserDriver() ||
              _eglPreloadDisplayDrivers() ||
              _eglPreloadDefaultDriver());
 
+   _eglUnlockMutex(_eglGlobal.Mutex);
+
    return loaded;
 }
 
@@ -548,6 +559,8 @@
 _eglUnloadDrivers(void)
 {
    EGLint i;
+
+   /* this is called at atexit time */
    for (i = 0; i < _eglGlobal.NumDrivers; i++) {
       _EGLDriver *drv = _eglGlobal.Drivers[i];
       lib_handle handle = drv->LibHandle;
diff --git a/src/egl/main/eglglobals.h b/src/egl/main/eglglobals.h
index cd1dd58..4368898 100644
--- a/src/egl/main/eglglobals.h
+++ b/src/egl/main/eglglobals.h
@@ -18,6 +18,7 @@
 
    EGLScreenMESA FreeScreenHandle;
 
+   /* these never change after preloading */
    EGLint NumDrivers;
    _EGLDriver *Drivers[10];
 
diff --git a/src/egl/main/eglscreen.c b/src/egl/main/eglscreen.c
index 97a405a..c47afd6 100644
--- a/src/egl/main/eglscreen.c
+++ b/src/egl/main/eglscreen.c
@@ -22,17 +22,22 @@
 #include "eglconfig.h"
 #include "eglsurface.h"
 #include "eglscreen.h"
+#include "eglmutex.h"
 
 
 /**
  * Return a new screen handle/ID.
  * NOTE: we never reuse these!
  */
-EGLScreenMESA
+static EGLScreenMESA
 _eglAllocScreenHandle(void)
 {
-   EGLScreenMESA s = _eglGlobal.FreeScreenHandle;
-   _eglGlobal.FreeScreenHandle++;
+   EGLScreenMESA s;
+   
+   _eglLockMutex(_eglGlobal.Mutex);
+   s = _eglGlobal.FreeScreenHandle++;
+   _eglUnlockMutex(_eglGlobal.Mutex);
+
    return s;
 }
 
diff --git a/src/egl/main/eglscreen.h b/src/egl/main/eglscreen.h
index c400ac3..0fd71f7 100644
--- a/src/egl/main/eglscreen.h
+++ b/src/egl/main/eglscreen.h
@@ -29,10 +29,6 @@
 };
 
 
-extern EGLScreenMESA
-_eglAllocScreenHandle(void);
-
-
 PUBLIC void
 _eglInitScreen(_EGLScreen *screen);
 
diff --git a/src/gallium/auxiliary/Makefile b/src/gallium/auxiliary/Makefile
index 507ca6e..ff76951 100644
--- a/src/gallium/auxiliary/Makefile
+++ b/src/gallium/auxiliary/Makefile
@@ -49,8 +49,10 @@
 	indices/u_indices_gen.c \
 	indices/u_unfilled_gen.c \
 	os/os_misc.c \
+	os/os_stream_log.c \
 	os/os_stream_stdc.c \
-	os/os_stream_wd.c \
+	os/os_stream_str.c \
+	os/os_stream_null.c \
 	os/os_time.c \
 	pipebuffer/pb_buffer_malloc.c \
 	pipebuffer/pb_bufmgr_alt.c \
@@ -91,9 +93,10 @@
 	translate/translate.c \
 	translate/translate_cache.c \
 	util/u_debug.c \
-	util/u_debug_dump.c \
 	util/u_debug_symbol.c \
 	util/u_debug_stack.c \
+	util/u_dump_defines.c \
+	util/u_dump_state.c \
 	util/u_bitmask.c \
 	util/u_blit.c \
 	util/u_blitter.c \
diff --git a/src/gallium/auxiliary/SConscript b/src/gallium/auxiliary/SConscript
index 9709344..b531ad2 100644
--- a/src/gallium/auxiliary/SConscript
+++ b/src/gallium/auxiliary/SConscript
@@ -83,8 +83,10 @@
     'indices/u_indices_gen.c',
     'indices/u_unfilled_gen.c',
     'os/os_misc.c',
+    'os/os_stream_log.c',
     'os/os_stream_stdc.c',
-    'os/os_stream_wd.c',
+    'os/os_stream_str.c',
+    'os/os_stream_null.c',
     'os/os_time.c',
     'pipebuffer/pb_buffer_fenced.c',
     'pipebuffer/pb_buffer_malloc.c',
@@ -131,10 +133,11 @@
     'util/u_cache.c',
     'util/u_cpu_detect.c',
     'util/u_debug.c',
-    'util/u_debug_dump.c',
     'util/u_debug_memory.c',
     'util/u_debug_stack.c',
     'util/u_debug_symbol.c',
+    'util/u_dump_defines.c',
+    'util/u_dump_state.c',
     'util/u_dl.c',
     'util/u_draw_quad.c',
     'util/u_format.c',
diff --git a/src/gallium/auxiliary/cso_cache/cso_context.c b/src/gallium/auxiliary/cso_cache/cso_context.c
index c638239..b5241fa 100644
--- a/src/gallium/auxiliary/cso_cache/cso_context.c
+++ b/src/gallium/auxiliary/cso_cache/cso_context.c
@@ -93,6 +93,7 @@
    struct pipe_framebuffer_state fb, fb_saved;
    struct pipe_viewport_state vp, vp_saved;
    struct pipe_blend_color blend_color;
+   struct pipe_stencil_ref stencil_ref, stencil_ref_saved;
 };
 
 
@@ -1057,8 +1058,6 @@
 }
 
 
-
-
 enum pipe_error cso_set_blend_color(struct cso_context *ctx,
                                     const struct pipe_blend_color *bc)
 {
@@ -1069,6 +1068,30 @@
    return PIPE_OK;
 }
 
+enum pipe_error cso_set_stencil_ref(struct cso_context *ctx,
+                                    const struct pipe_stencil_ref *sr)
+{
+   if (memcmp(&ctx->stencil_ref, sr, sizeof(ctx->stencil_ref))) {
+      ctx->stencil_ref = *sr;
+      ctx->pipe->set_stencil_ref(ctx->pipe, sr);
+   }
+   return PIPE_OK;
+}
+
+void cso_save_stencil_ref(struct cso_context *ctx)
+{
+   ctx->stencil_ref_saved = ctx->stencil_ref;
+}
+
+
+void cso_restore_stencil_ref(struct cso_context *ctx)
+{
+   if (memcmp(&ctx->stencil_ref, &ctx->stencil_ref_saved, sizeof(ctx->stencil_ref))) {
+      ctx->stencil_ref = ctx->stencil_ref_saved;
+      ctx->pipe->set_stencil_ref(ctx->pipe, &ctx->stencil_ref);
+   }
+}
+
 enum pipe_error cso_set_geometry_shader_handle(struct cso_context *ctx,
                                                void *handle)
 {
diff --git a/src/gallium/auxiliary/cso_cache/cso_context.h b/src/gallium/auxiliary/cso_cache/cso_context.h
index d2089b1..707b3c2 100644
--- a/src/gallium/auxiliary/cso_cache/cso_context.h
+++ b/src/gallium/auxiliary/cso_cache/cso_context.h
@@ -174,6 +174,12 @@
                                     const struct pipe_blend_color *bc);
 
 
+enum pipe_error cso_set_stencil_ref(struct cso_context *cso,
+                                    const struct pipe_stencil_ref *sr);
+void cso_save_stencil_ref(struct cso_context *cso);
+void cso_restore_stencil_ref(struct cso_context *cso);
+
+
 #ifdef	__cplusplus
 }
 #endif
diff --git a/src/gallium/auxiliary/draw/draw_pt.c b/src/gallium/auxiliary/draw/draw_pt.c
index f5ed32d..341353f 100644
--- a/src/gallium/auxiliary/draw/draw_pt.c
+++ b/src/gallium/auxiliary/draw/draw_pt.c
@@ -310,7 +310,7 @@
       debug_printf("Elements:\n");
       for (i = 0; i < draw->pt.nr_vertex_elements; i++) {
          debug_printf("  format=%s comps=%u\n",
-                      pf_name(draw->pt.vertex_element[i].src_format),
+                      util_format_name(draw->pt.vertex_element[i].src_format),
                       draw->pt.vertex_element[i].nr_components);
       }
       debug_printf("Buffers:\n");
diff --git a/src/gallium/auxiliary/draw/draw_vs.c b/src/gallium/auxiliary/draw/draw_vs.c
index 6bdd612..9085838 100644
--- a/src/gallium/auxiliary/draw/draw_vs.c
+++ b/src/gallium/auxiliary/draw/draw_vs.c
@@ -61,6 +61,7 @@
          }
          draw->vs.aligned_constant_storage[slot] = align_malloc(size, 16);
       }
+      assert(constants);
       memcpy((void *)draw->vs.aligned_constant_storage[slot],
              constants,
              size);
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c
index 57c2b76..e268862 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c
@@ -35,7 +35,7 @@
 #include "pipe/p_defines.h"
 #include "pipe/p_state.h"
 #include "util/u_debug.h"
-#include "util/u_debug_dump.h"
+#include "util/u_dump.h"
 #include "util/u_memory.h"
 #include "util/u_math.h"
 #include "util/u_format.h"
@@ -173,7 +173,7 @@
    case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER:
       /* FIXME */
       _debug_printf("llvmpipe: failed to translate texture wrap mode %s\n",
-                    debug_dump_tex_wrap(wrap_mode, TRUE));
+                    util_dump_tex_wrap(wrap_mode, TRUE));
       coord = lp_build_max(int_coord_bld, coord, int_coord_bld->zero);
       coord = lp_build_min(int_coord_bld, coord, length_minus_one);
       break;
diff --git a/src/gallium/auxiliary/os/os_stream.h b/src/gallium/auxiliary/os/os_stream.h
index bf30e65..693a062 100644
--- a/src/gallium/auxiliary/os/os_stream.h
+++ b/src/gallium/auxiliary/os/os_stream.h
@@ -37,25 +37,86 @@
 #include "pipe/p_compiler.h"
 
 
-struct os_stream;
-
-
 /**
- * Create a stream
- * @param filename relative or absolute path (necessary for windows)  
- * @param optional maximum file size (0 for a growable size).
+ * OS stream (FILE, socket, etc) abstraction.
  */
+struct os_stream
+{
+   void
+   (*close)(struct os_stream *stream);
+
+   boolean
+   (*write)(struct os_stream *stream, const void *data, size_t size);
+
+   void
+   (*flush)(struct os_stream *stream);
+};
+
+
+static INLINE void
+os_stream_close(struct os_stream *stream)
+{
+   if (!stream)
+      return;
+
+   stream->close(stream);
+}
+
+
+static INLINE boolean
+os_stream_write(struct os_stream *stream, const void *data, size_t size)
+{
+   if (!stream)
+      return FALSE;
+   return stream->write(stream, data, size);
+}
+
+
+static INLINE boolean
+os_stream_write_str(struct os_stream *stream, const char *str)
+{
+   size_t size;
+   if (!stream)
+      return FALSE;
+   for(size = 0; str[size]; ++size)
+      ;
+   return stream->write(stream, str, size);
+}
+
+
+static INLINE void
+os_stream_flush(struct os_stream *stream)
+{
+   stream->flush(stream);
+}
+
+
 struct os_stream *
-os_stream_create(const char *filename, size_t max_size);
+os_file_stream_create(const char *filename);
 
-boolean
-os_stream_write(struct os_stream *stream, const void *data, size_t size);
 
-void
-os_stream_flush(struct os_stream *stream);
+struct os_stream *
+os_null_stream_create(void);
 
-void
-os_stream_close(struct os_stream *stream);
+
+extern struct os_stream *
+os_log_stream;
+
+
+struct os_stream *
+os_str_stream_create(size_t initial_size);
+
+
+const char *
+os_str_stream_get(struct os_stream *stream);
+
+char *
+os_str_stream_get_and_close(struct os_stream *stream);
+
+
+#if defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY)
+#define os_file_stream_create(_filename) os_null_stream_create()
+#endif
 
 
 #endif /* _OS_STREAM_H_ */
diff --git a/src/gallium/auxiliary/os/os_stream_log.c b/src/gallium/auxiliary/os/os_stream_log.c
new file mode 100644
index 0000000..7cc2028
--- /dev/null
+++ b/src/gallium/auxiliary/os/os_stream_log.c
@@ -0,0 +1,81 @@
+/**************************************************************************
+ *
+ * Copyright 2008-2010 VMware, Inc.
+ * 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"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+/**
+ * @file
+ * Debug logging stream implementation.
+ */
+
+#include "os_memory.h"
+#include "os_misc.h"
+#include "os_stream.h"
+
+
+static void
+os_log_stream_close(struct os_stream *stream)
+{
+   (void)stream;
+}
+
+
+static boolean
+os_log_stream_write(struct os_stream *stream, const void *data, size_t size)
+{
+   char *str;
+
+   str = os_malloc(size + 1);
+   if (!str)
+      return FALSE;
+
+   memcpy(str, data, size);
+   str[size] = 0;
+
+   os_log_message(str);
+
+   os_free(str);
+
+   return TRUE;
+}
+
+
+static void
+os_log_stream_flush(struct os_stream *stream)
+{
+   (void)stream;
+}
+
+
+static struct os_stream
+os_log_stream_struct = {
+   &os_log_stream_close,
+   &os_log_stream_write,
+   &os_log_stream_flush
+};
+
+
+struct os_stream *
+os_log_stream = &os_log_stream_struct;
diff --git a/src/mesa/state_tracker/st_cb_viewport.c b/src/gallium/auxiliary/os/os_stream_null.c
similarity index 62%
rename from src/mesa/state_tracker/st_cb_viewport.c
rename to src/gallium/auxiliary/os/os_stream_null.c
index b29191a..128c4e8 100644
--- a/src/mesa/state_tracker/st_cb_viewport.c
+++ b/src/gallium/auxiliary/os/os_stream_null.c
@@ -1,8 +1,8 @@
 /**************************************************************************
- * 
- * Copyright 2009 VMware, Inc.
+ *
+ * Copyright 2008-2010 VMware, Inc.
  * 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"), to deal in the Software without restriction, including
@@ -10,41 +10,63 @@
  * distribute, sub license, and/or sell copies of the Software, and to
  * permit persons to whom the Software is furnished to do so, subject to
  * the following conditions:
- * 
+ *
  * The above copyright notice and this permission notice (including the
  * next paragraph) shall be included in all copies or substantial portions
  * of the Software.
- * 
+ *
  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- * 
+ *
  **************************************************************************/
 
-#include "main/glheader.h"
-#include "st_context.h"
-#include "st_cb_viewport.h"
+/**
+ * @file
+ * Null stream implementation.
+ */
 
-#include "pipe/p_context.h"
-#include "pipe/p_state.h"
-#include "pipe/p_defines.h"
+#include "os_memory.h"
+#include "os_stream.h"
 
 
-static void st_viewport(GLcontext * ctx, GLint x, GLint y,
-                        GLsizei width, GLsizei height)
+static void
+os_null_stream_close(struct os_stream *stream)
 {
-   struct st_context *st = ctx->st;
-
-   if (st->pipe->screen && st->pipe->screen->update_buffer)
-      st->pipe->screen->update_buffer( st->pipe->screen,
-                                       st->pipe->priv );
+   (void)stream;
 }
 
-void st_init_viewport_functions(struct dd_function_table *functions)
+
+static boolean
+os_null_stream_write(struct os_stream *stream, const void *data, size_t size)
 {
-   functions->Viewport = st_viewport;
+   (void)data;
+   (void)size;
+   return TRUE;
+}
+
+
+static void
+os_null_stream_flush(struct os_stream *stream)
+{
+   (void)stream;
+}
+
+
+static struct os_stream
+os_null_stream = {
+   &os_null_stream_close,
+   &os_null_stream_write,
+   &os_null_stream_flush
+};
+
+
+struct os_stream *
+os_null_stream_create()
+{
+   return &os_null_stream;
 }
diff --git a/src/gallium/auxiliary/os/os_stream_stdc.c b/src/gallium/auxiliary/os/os_stream_stdc.c
index caa60c0..9e7ed71 100644
--- a/src/gallium/auxiliary/os/os_stream_stdc.c
+++ b/src/gallium/auxiliary/os/os_stream_stdc.c
@@ -40,65 +40,73 @@
 #include "os_stream.h"
 
 
-struct os_stream 
+struct os_stdc_stream
 {
+   struct os_stream base;
+
    FILE *file;
 };
 
 
-struct os_stream *
-os_stream_create(const char *filename, size_t max_size)
+static INLINE struct os_stdc_stream *
+os_stdc_stream(struct os_stream *stream)
 {
-   struct os_stream *stream;
-   
-   (void)max_size;
-   
-   stream = (struct os_stream *)calloc(1, sizeof(struct os_stream));
-   if(!stream)
-      goto no_stream;
-   
-   stream->file = fopen(filename, "w");
-   if(!stream->file)
-      goto no_file;
-   
-   return stream;
-   
-no_file:
-   free(stream);
-no_stream:
-   return NULL;
+   return (struct os_stdc_stream *)stream;
 }
 
 
-boolean
-os_stream_write(struct os_stream *stream, const void *data, size_t size)
+static void
+os_stdc_stream_close(struct os_stream *_stream)
 {
-   if(!stream)
-      return FALSE;
-   
+   struct os_stdc_stream *stream = os_stdc_stream(_stream);
+
+   fclose(stream->file);
+
+   free(stream);
+}
+
+
+static boolean
+os_stdc_stream_write(struct os_stream *_stream, const void *data, size_t size)
+{
+   struct os_stdc_stream *stream = os_stdc_stream(_stream);
+
    return fwrite(data, size, 1, stream->file) == size ? TRUE : FALSE;
 }
 
 
-void
-os_stream_flush(struct os_stream *stream) 
+static void
+os_stdc_stream_flush(struct os_stream *_stream)
 {
-   if(!stream)
-      return;
-   
+   struct os_stdc_stream *stream = os_stdc_stream(_stream);
+
    fflush(stream->file);
 }
 
 
-void
-os_stream_close(struct os_stream *stream) 
+struct os_stream *
+os_file_stream_create(const char *filename)
 {
-   if(!stream)
-      return;
-   
-   fclose(stream->file);
+   struct os_stdc_stream *stream;
 
+   stream = (struct os_stdc_stream *)calloc(1, sizeof(*stream));
+   if(!stream)
+      goto no_stream;
+
+   stream->base.close = &os_stdc_stream_close;
+   stream->base.write = &os_stdc_stream_write;
+   stream->base.flush = &os_stdc_stream_flush;
+
+   stream->file = fopen(filename, "w");
+   if(!stream->file)
+      goto no_file;
+
+   return &stream->base;
+
+no_file:
    free(stream);
+no_stream:
+   return NULL;
 }
 
 
diff --git a/src/gallium/auxiliary/os/os_stream_str.c b/src/gallium/auxiliary/os/os_stream_str.c
new file mode 100644
index 0000000..b5c7270
--- /dev/null
+++ b/src/gallium/auxiliary/os/os_stream_str.c
@@ -0,0 +1,166 @@
+/**************************************************************************
+ *
+ * Copyright 2008-2010 VMware, Inc.
+ * 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"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+/**
+ * @file
+ * Malloc string stream implementation.
+ */
+
+#include "pipe/p_config.h"
+
+#include "os_memory.h"
+#include "os_stream.h"
+
+
+struct os_str_stream
+{
+   struct os_stream base;
+
+   char *str;
+
+   size_t size;
+   size_t written;
+};
+
+
+static INLINE struct os_str_stream *
+os_str_stream(struct os_stream *stream)
+{
+   return (struct os_str_stream *)stream;
+}
+
+
+static void
+os_str_stream_close(struct os_stream *_stream)
+{
+   struct os_str_stream *stream = os_str_stream(_stream);
+
+   os_free(stream->str);
+
+   os_free(stream);
+}
+
+
+static boolean
+os_str_stream_write(struct os_stream *_stream, const void *data, size_t size)
+{
+   struct os_str_stream *stream = os_str_stream(_stream);
+   size_t minimum_size;
+   boolean ret = TRUE;
+
+   minimum_size = stream->written + size + 1;
+   if (stream->size < minimum_size) {
+      size_t new_size = stream->size;
+      char * new_str;
+
+      do {
+         new_size *= 2;
+      } while (new_size < minimum_size);
+
+      new_str = os_realloc(stream->str, stream->size, new_size);
+      if (new_str) {
+         stream->str = new_str;
+         stream->size = new_size;
+      }
+      else {
+         size = stream->size - stream->written - 1;
+         ret = FALSE;
+      }
+   }
+
+   memcpy(stream->str + stream->written, data, size);
+   stream->written += size;
+
+   return ret;
+}
+
+
+static void
+os_str_stream_flush(struct os_stream *stream)
+{
+   (void)stream;
+}
+
+
+struct os_stream *
+os_str_stream_create(size_t size)
+{
+   struct os_str_stream *stream;
+
+   stream = (struct os_str_stream *)os_calloc(1, sizeof(*stream));
+   if(!stream)
+      goto no_stream;
+
+   stream->base.close = &os_str_stream_close;
+   stream->base.write = &os_str_stream_write;
+   stream->base.flush = &os_str_stream_flush;
+
+   stream->str = os_malloc(size);
+   if(!stream->str)
+      goto no_str;
+
+   stream->size = size;
+
+   return &stream->base;
+
+no_str:
+   os_free(stream);
+no_stream:
+   return NULL;
+}
+
+
+const char *
+os_str_stream_get(struct os_stream *_stream)
+{
+   struct os_str_stream *stream = os_str_stream(_stream);
+
+   if (!stream)
+      return NULL;
+
+   stream->str[stream->written] = 0;
+   return stream->str;
+}
+
+
+char *
+os_str_stream_get_and_close(struct os_stream *_stream)
+{
+   struct os_str_stream *stream = os_str_stream(_stream);
+   char *str;
+
+   if (!stream)
+      return NULL;
+
+   str = stream->str;
+
+   str[stream->written] = 0;
+
+   os_free(stream);
+
+   return str;
+}
diff --git a/src/gallium/auxiliary/os/os_stream_wd.c b/src/gallium/auxiliary/os/os_stream_wd.c
deleted file mode 100644
index a64cbca..0000000
--- a/src/gallium/auxiliary/os/os_stream_wd.c
+++ /dev/null
@@ -1,222 +0,0 @@
-/**************************************************************************
- *
- * Copyright 2008-2010 VMware, Inc.
- * 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"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- **************************************************************************/
-
-/**
- * @file
- * Stream implementation for the Windows Display driver.
- */
-
-#include "pipe/p_config.h"
-
-#if defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY)
-
-#include <windows.h>
-#include <winddi.h>
-
-#include "os_memory.h"
-#include "os_stream.h"
-
-
-#define MAP_FILE_SIZE (4*1024*1024)
-
-
-struct os_stream 
-{
-   char filename[MAX_PATH + 1];
-   WCHAR wFileName[MAX_PATH + 1];
-   boolean growable;
-   size_t map_size;
-   ULONG_PTR iFile;
-   char *pMap;
-   size_t written;
-   unsigned suffix;
-};
-
-
-static INLINE boolean
-os_stream_map(struct os_stream *stream)
-{
-   ULONG BytesInUnicodeString;
-   static char filename[MAX_PATH + 1];
-   unsigned filename_len;
-
-   if(stream->growable)
-      filename_len = snprintf(filename,
-                              sizeof(filename),
-                              "%s.%04x",
-                              stream->filename,
-                              stream->suffix++);
-   else
-      filename_len = snprintf(filename,
-                              sizeof(filename),
-                              "%s",
-                              stream->filename);
-
-   EngMultiByteToUnicodeN(
-         stream->wFileName,
-         sizeof(stream->wFileName),
-         &BytesInUnicodeString,
-         filename,
-         filename_len);
-   
-   stream->pMap = EngMapFile(stream->wFileName, stream->map_size, &stream->iFile);
-   if(!stream->pMap)
-      return FALSE;
-   
-   memset(stream->pMap, 0, stream->map_size);
-   stream->written = 0;
-   
-   return TRUE;
-}
-
-
-static INLINE void
-os_stream_unmap(struct os_stream *stream)
-{
-   EngUnmapFile(stream->iFile);
-   if(stream->written < stream->map_size) {
-      /* Truncate file size */
-      stream->pMap = EngMapFile(stream->wFileName, stream->written, &stream->iFile);
-      if(stream->pMap)
-         EngUnmapFile(stream->iFile);
-   }
-   
-   stream->pMap = NULL;
-}
-
-
-static INLINE void
-os_stream_full_qualified_filename(char *dst, size_t size, const char *src)
-{
-   boolean need_drive, need_root;
-   
-   if((('A' <= src[0] && src[0] <= 'Z') || ('a' <= src[0] && src[0] <= 'z')) && src[1] == ':') {
-      need_drive = FALSE;
-      need_root = src[2] == '\\' ? FALSE : TRUE;
-   }
-   else {
-      need_drive = TRUE;
-      need_root = src[0] == '\\' ? FALSE : TRUE;
-   }
-   
-   snprintf(dst, size,
-            "\\??\\%s%s%s",
-            need_drive ? "C:" : "",
-            need_root ? "\\" : "",
-            src);
-}
-
-
-struct os_stream *
-os_stream_create(const char *filename, size_t max_size)
-{
-   struct os_stream *stream;
-   
-   stream = CALLOC_STRUCT(os_stream);
-   if(!stream)
-      goto error1;
-   
-   os_stream_full_qualified_filename(stream->filename,
-                                       sizeof(stream->filename),
-                                       filename);
-   
-   if(max_size) {
-      stream->growable = FALSE;
-      stream->map_size = max_size;
-   }
-   else {
-      stream->growable = TRUE;
-      stream->map_size = MAP_FILE_SIZE;
-   }
-   
-   if(!os_stream_map(stream))
-      goto error2;
-   
-   return stream;
-   
-error2:
-   FREE(stream);
-error1:
-   return NULL;
-}
-
-
-static INLINE void
-os_stream_copy(struct os_stream *stream, const char *data, size_t size)
-{
-   assert(stream->written + size <= stream->map_size);
-   memcpy(stream->pMap + stream->written, data, size);
-   stream->written += size;
-}
-
-
-boolean
-os_stream_write(struct os_stream *stream, const void *data, size_t size)
-{
-   if(!stream)
-      return FALSE;
-   
-   if(!stream->pMap)
-      return FALSE;
-   
-   while(stream->written + size > stream->map_size) {
-      size_t step = stream->map_size - stream->written;
-      os_stream_copy(stream, data, step);
-      data = (const char *)data + step;
-      size -= step;
-      
-      os_stream_unmap(stream);
-      if(!stream->growable || !os_stream_map(stream))
-         return FALSE;
-   }
-
-   os_stream_copy(stream, data, size);
-   
-   return TRUE;
-}
-
-
-void
-os_stream_flush(struct os_stream *stream) 
-{
-   (void)stream;
-}
-
-
-void
-os_stream_close(struct os_stream *stream) 
-{
-   if(!stream)
-      return;
-   
-   os_stream_unmap(stream);
-
-   FREE(stream);
-}
-
-
-#endif
diff --git a/src/gallium/auxiliary/util/u_blitter.c b/src/gallium/auxiliary/util/u_blitter.c
index f3b4491..18f8606 100644
--- a/src/gallium/auxiliary/util/u_blitter.c
+++ b/src/gallium/auxiliary/util/u_blitter.c
@@ -60,13 +60,12 @@
    float vertices[4][2][4];   /**< {pos, color} or {pos, texcoord} */
 
    /* Templates for various state objects. */
-   struct pipe_depth_stencil_alpha_state template_dsa;
    struct pipe_sampler_state template_sampler_state;
 
    /* Constant state objects. */
    /* Vertex shaders. */
    void *vs_col; /**< Vertex shader which passes {pos, color} to the output */
-   void *vs_tex; /**<Vertex shader which passes {pos, texcoord} to the output.*/
+   void *vs_tex; /**< Vertex shader which passes {pos, texcoord} to the output.*/
 
    /* Fragment shaders. */
    /* FS which outputs a color to multiple color buffers. */
@@ -85,7 +84,7 @@
    void *blend_keep_color;    /**< blend state with writemask of 0 */
 
    /* Depth stencil alpha state. */
-   void *dsa_write_depth_stencil[0xff]; /**< indices are stencil clear values */
+   void *dsa_write_depth_stencil;
    void *dsa_write_depth_keep_stencil;
    void *dsa_keep_depth_stencil;
 
@@ -99,9 +98,9 @@
 struct blitter_context *util_blitter_create(struct pipe_context *pipe)
 {
    struct blitter_context_priv *ctx;
-   struct pipe_blend_state blend;
-   struct pipe_depth_stencil_alpha_state *dsa;
-   struct pipe_rasterizer_state rs_state;
+   struct pipe_blend_state blend = { 0 };
+   struct pipe_depth_stencil_alpha_state dsa = { { 0 } };
+   struct pipe_rasterizer_state rs_state = { 0 };
    struct pipe_sampler_state *sampler_state;
    unsigned i;
 
@@ -122,30 +121,30 @@
    ctx->blitter.saved_num_sampler_states = ~0;
 
    /* blend state objects */
-   memset(&blend, 0, sizeof(blend));
    ctx->blend_keep_color = pipe->create_blend_state(pipe, &blend);
 
    blend.rt[0].colormask = PIPE_MASK_RGBA;
    ctx->blend_write_color = pipe->create_blend_state(pipe, &blend);
 
    /* depth stencil alpha state objects */
-   dsa = &ctx->template_dsa;
    ctx->dsa_keep_depth_stencil =
-      pipe->create_depth_stencil_alpha_state(pipe, dsa);
+      pipe->create_depth_stencil_alpha_state(pipe, &dsa);
 
-   dsa->depth.enabled = 1;
-   dsa->depth.writemask = 1;
-   dsa->depth.func = PIPE_FUNC_ALWAYS;
+   dsa.depth.enabled = 1;
+   dsa.depth.writemask = 1;
+   dsa.depth.func = PIPE_FUNC_ALWAYS;
    ctx->dsa_write_depth_keep_stencil =
-      pipe->create_depth_stencil_alpha_state(pipe, dsa);
+      pipe->create_depth_stencil_alpha_state(pipe, &dsa);
 
-   dsa->stencil[0].enabled = 1;
-   dsa->stencil[0].func = PIPE_FUNC_ALWAYS;
-   dsa->stencil[0].fail_op = PIPE_STENCIL_OP_REPLACE;
-   dsa->stencil[0].zpass_op = PIPE_STENCIL_OP_REPLACE;
-   dsa->stencil[0].zfail_op = PIPE_STENCIL_OP_REPLACE;
-   dsa->stencil[0].valuemask = 0xff;
-   dsa->stencil[0].writemask = 0xff;
+   dsa.stencil[0].enabled = 1;
+   dsa.stencil[0].func = PIPE_FUNC_ALWAYS;
+   dsa.stencil[0].fail_op = PIPE_STENCIL_OP_REPLACE;
+   dsa.stencil[0].zpass_op = PIPE_STENCIL_OP_REPLACE;
+   dsa.stencil[0].zfail_op = PIPE_STENCIL_OP_REPLACE;
+   dsa.stencil[0].valuemask = 0xff;
+   dsa.stencil[0].writemask = 0xff;
+   ctx->dsa_write_depth_stencil =
+      pipe->create_depth_stencil_alpha_state(pipe, &dsa);
    /* The DSA state objects which write depth and stencil are created
     * on-demand. */
 
@@ -210,11 +209,7 @@
    pipe->delete_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil);
    pipe->delete_depth_stencil_alpha_state(pipe,
                                           ctx->dsa_write_depth_keep_stencil);
-
-   for (i = 0; i < 0xff; i++)
-      if (ctx->dsa_write_depth_stencil[i])
-         pipe->delete_depth_stencil_alpha_state(pipe,
-            ctx->dsa_write_depth_stencil[i]);
+   pipe->delete_depth_stencil_alpha_state(pipe, ctx->dsa_write_depth_stencil);
 
    pipe->delete_rasterizer_state(pipe, ctx->rs_state);
    pipe->delete_vs_state(pipe, ctx->vs_col);
@@ -266,6 +261,8 @@
    ctx->blitter.saved_fs = INVALID_PTR;
    ctx->blitter.saved_vs = INVALID_PTR;
 
+   pipe->set_stencil_ref(pipe, &ctx->blitter.saved_stencil_ref);
+
    /* restore the state objects which are required to be saved before copy/fill
     */
    if (ctx->blitter.saved_fb_state.nr_cbufs != ~0) {
@@ -413,26 +410,6 @@
 }
 
 static INLINE
-void *blitter_get_state_write_depth_stencil(
-               struct blitter_context_priv *ctx,
-               unsigned stencil)
-{
-   struct pipe_context *pipe = ctx->pipe;
-
-   stencil &= 0xff;
-
-   /* Create the DSA state on-demand. */
-   if (!ctx->dsa_write_depth_stencil[stencil]) {
-      ctx->template_dsa.stencil[0].ref_value = stencil;
-
-      ctx->dsa_write_depth_stencil[stencil] =
-         pipe->create_depth_stencil_alpha_state(pipe, &ctx->template_dsa);
-   }
-
-   return ctx->dsa_write_depth_stencil[stencil];
-}
-
-static INLINE
 void **blitter_get_sampler_state(struct blitter_context_priv *ctx,
                                  int miplevel)
 {
@@ -548,6 +525,7 @@
 {
    struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
    struct pipe_context *pipe = ctx->pipe;
+   struct pipe_stencil_ref sr = { { 0 } };
 
    assert(num_cbufs <= PIPE_MAX_COLOR_BUFS);
 
@@ -559,9 +537,11 @@
    else
       pipe->bind_blend_state(pipe, ctx->blend_keep_color);
 
-   if (clear_buffers & PIPE_CLEAR_DEPTHSTENCIL)
-      pipe->bind_depth_stencil_alpha_state(pipe,
-         blitter_get_state_write_depth_stencil(ctx, stencil));
+   if (clear_buffers & PIPE_CLEAR_DEPTHSTENCIL) {
+      sr.ref_value[0] = stencil & 0xff;
+      pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_write_depth_stencil);
+      pipe->set_stencil_ref(pipe, &sr);
+   }
    else
       pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil);
 
diff --git a/src/gallium/auxiliary/util/u_blitter.h b/src/gallium/auxiliary/util/u_blitter.h
index 3da5a6c..a2f1707 100644
--- a/src/gallium/auxiliary/util/u_blitter.h
+++ b/src/gallium/auxiliary/util/u_blitter.h
@@ -47,6 +47,7 @@
    void *saved_fs, *saved_vs; /**< fragment shader, vertex shader */
 
    struct pipe_framebuffer_state saved_fb_state;  /**< framebuffer state */
+   struct pipe_stencil_ref saved_stencil_ref;     /**< stencil ref */
 
    int saved_num_sampler_states;
    void *saved_sampler_states[32];
@@ -170,6 +171,13 @@
 }
 
 static INLINE
+void util_blitter_save_stencil_ref(struct blitter_context *blitter,
+                                   const struct pipe_stencil_ref *state)
+{
+   blitter->saved_stencil_ref = *state;
+}
+
+static INLINE
 void util_blitter_save_rasterizer(struct blitter_context *blitter,
                                   void *state)
 {
diff --git a/src/gallium/auxiliary/util/u_debug.c b/src/gallium/auxiliary/util/u_debug.c
index 4821b8a..858d52c 100644
--- a/src/gallium/auxiliary/util/u_debug.c
+++ b/src/gallium/auxiliary/util/u_debug.c
@@ -288,130 +288,13 @@
 }
 
 
-static const struct debug_named_value pipe_format_names[] = {
-#ifdef DEBUG
-   DEBUG_NAMED_VALUE(PIPE_FORMAT_NONE),
-   DEBUG_NAMED_VALUE(PIPE_FORMAT_A8R8G8B8_UNORM),
-   DEBUG_NAMED_VALUE(PIPE_FORMAT_X8R8G8B8_UNORM),
-   DEBUG_NAMED_VALUE(PIPE_FORMAT_B8G8R8A8_UNORM),
-   DEBUG_NAMED_VALUE(PIPE_FORMAT_B8G8R8X8_UNORM),
-   DEBUG_NAMED_VALUE(PIPE_FORMAT_A1R5G5B5_UNORM),
-   DEBUG_NAMED_VALUE(PIPE_FORMAT_A4R4G4B4_UNORM),
-   DEBUG_NAMED_VALUE(PIPE_FORMAT_R5G6B5_UNORM),
-   DEBUG_NAMED_VALUE(PIPE_FORMAT_A2B10G10R10_UNORM),
-   DEBUG_NAMED_VALUE(PIPE_FORMAT_L8_UNORM),
-   DEBUG_NAMED_VALUE(PIPE_FORMAT_A8_UNORM),
-   DEBUG_NAMED_VALUE(PIPE_FORMAT_I8_UNORM),
-   DEBUG_NAMED_VALUE(PIPE_FORMAT_A8L8_UNORM),
-   DEBUG_NAMED_VALUE(PIPE_FORMAT_L16_UNORM),
-   DEBUG_NAMED_VALUE(PIPE_FORMAT_YCBCR),
-   DEBUG_NAMED_VALUE(PIPE_FORMAT_YCBCR_REV),
-   DEBUG_NAMED_VALUE(PIPE_FORMAT_Z16_UNORM),
-   DEBUG_NAMED_VALUE(PIPE_FORMAT_Z32_UNORM),
-   DEBUG_NAMED_VALUE(PIPE_FORMAT_Z32_FLOAT),
-   DEBUG_NAMED_VALUE(PIPE_FORMAT_S8Z24_UNORM),
-   DEBUG_NAMED_VALUE(PIPE_FORMAT_Z24S8_UNORM),
-   DEBUG_NAMED_VALUE(PIPE_FORMAT_X8Z24_UNORM),
-   DEBUG_NAMED_VALUE(PIPE_FORMAT_Z24X8_UNORM),
-   DEBUG_NAMED_VALUE(PIPE_FORMAT_S8_UNORM),
-   DEBUG_NAMED_VALUE(PIPE_FORMAT_R64_FLOAT),
-   DEBUG_NAMED_VALUE(PIPE_FORMAT_R64G64_FLOAT),
-   DEBUG_NAMED_VALUE(PIPE_FORMAT_R64G64B64_FLOAT),
-   DEBUG_NAMED_VALUE(PIPE_FORMAT_R64G64B64A64_FLOAT),
-   DEBUG_NAMED_VALUE(PIPE_FORMAT_R32_FLOAT),
-   DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32_FLOAT),
-   DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32B32_FLOAT),
-   DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32B32A32_FLOAT),
-   DEBUG_NAMED_VALUE(PIPE_FORMAT_R32_UNORM),
-   DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32_UNORM),
-   DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32B32_UNORM),
-   DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32B32A32_UNORM),
-   DEBUG_NAMED_VALUE(PIPE_FORMAT_R32_USCALED),
-   DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32_USCALED),
-   DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32B32_USCALED),
-   DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32B32A32_USCALED),
-   DEBUG_NAMED_VALUE(PIPE_FORMAT_R32_SNORM),
-   DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32_SNORM),
-   DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32B32_SNORM),
-   DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32B32A32_SNORM),
-   DEBUG_NAMED_VALUE(PIPE_FORMAT_R32_SSCALED),
-   DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32_SSCALED),
-   DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32B32_SSCALED),
-   DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32B32A32_SSCALED),
-   DEBUG_NAMED_VALUE(PIPE_FORMAT_R16_UNORM),
-   DEBUG_NAMED_VALUE(PIPE_FORMAT_R16G16_UNORM),
-   DEBUG_NAMED_VALUE(PIPE_FORMAT_R16G16B16_UNORM),
-   DEBUG_NAMED_VALUE(PIPE_FORMAT_R16G16B16A16_UNORM),
-   DEBUG_NAMED_VALUE(PIPE_FORMAT_R16_USCALED),
-   DEBUG_NAMED_VALUE(PIPE_FORMAT_R16G16_USCALED),
-   DEBUG_NAMED_VALUE(PIPE_FORMAT_R16G16B16_USCALED),
-   DEBUG_NAMED_VALUE(PIPE_FORMAT_R16G16B16A16_USCALED),
-   DEBUG_NAMED_VALUE(PIPE_FORMAT_R16_SNORM),
-   DEBUG_NAMED_VALUE(PIPE_FORMAT_R16G16_SNORM),
-   DEBUG_NAMED_VALUE(PIPE_FORMAT_R16G16B16_SNORM),
-   DEBUG_NAMED_VALUE(PIPE_FORMAT_R16G16B16A16_SNORM),
-   DEBUG_NAMED_VALUE(PIPE_FORMAT_R16_SSCALED),
-   DEBUG_NAMED_VALUE(PIPE_FORMAT_R16G16_SSCALED),
-   DEBUG_NAMED_VALUE(PIPE_FORMAT_R16G16B16_SSCALED),
-   DEBUG_NAMED_VALUE(PIPE_FORMAT_R16G16B16A16_SSCALED),
-   DEBUG_NAMED_VALUE(PIPE_FORMAT_R8_UNORM),
-   DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8_UNORM),
-   DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8_UNORM),
-   DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8A8_UNORM),
-   DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8X8_UNORM),
-   DEBUG_NAMED_VALUE(PIPE_FORMAT_R8_USCALED),
-   DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8_USCALED),
-   DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8_USCALED),
-   DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8A8_USCALED),
-   DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8X8_USCALED),
-   DEBUG_NAMED_VALUE(PIPE_FORMAT_R8_SNORM),
-   DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8_SNORM),
-   DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8_SNORM),
-   DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8A8_SNORM),
-   DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8X8_SNORM),
-   DEBUG_NAMED_VALUE(PIPE_FORMAT_B6G5R5_SNORM),
-   DEBUG_NAMED_VALUE(PIPE_FORMAT_A8B8G8R8_SNORM),
-   DEBUG_NAMED_VALUE(PIPE_FORMAT_X8B8G8R8_SNORM),
-   DEBUG_NAMED_VALUE(PIPE_FORMAT_R8_SSCALED),
-   DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8_SSCALED),
-   DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8_SSCALED),
-   DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8A8_SSCALED),
-   DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8X8_SSCALED),
-   DEBUG_NAMED_VALUE(PIPE_FORMAT_L8_SRGB),
-   DEBUG_NAMED_VALUE(PIPE_FORMAT_A8L8_SRGB),
-   DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8_SRGB),
-   DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8A8_SRGB),
-   DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8X8_SRGB),
-   DEBUG_NAMED_VALUE(PIPE_FORMAT_A8R8G8B8_SRGB),
-   DEBUG_NAMED_VALUE(PIPE_FORMAT_X8R8G8B8_SRGB),
-   DEBUG_NAMED_VALUE(PIPE_FORMAT_B8G8R8A8_SRGB),
-   DEBUG_NAMED_VALUE(PIPE_FORMAT_B8G8R8X8_SRGB),
-   DEBUG_NAMED_VALUE(PIPE_FORMAT_X8UB8UG8SR8S_NORM),
-   DEBUG_NAMED_VALUE(PIPE_FORMAT_B6UG5SR5S_NORM),
-   DEBUG_NAMED_VALUE(PIPE_FORMAT_DXT1_RGB),
-   DEBUG_NAMED_VALUE(PIPE_FORMAT_DXT1_RGBA),
-   DEBUG_NAMED_VALUE(PIPE_FORMAT_DXT3_RGBA),
-   DEBUG_NAMED_VALUE(PIPE_FORMAT_DXT5_RGBA),
-   DEBUG_NAMED_VALUE(PIPE_FORMAT_DXT1_SRGB),
-   DEBUG_NAMED_VALUE(PIPE_FORMAT_DXT1_SRGBA),
-   DEBUG_NAMED_VALUE(PIPE_FORMAT_DXT3_SRGBA),
-   DEBUG_NAMED_VALUE(PIPE_FORMAT_DXT5_SRGBA),
-#endif
-   DEBUG_NAMED_VALUE_END
-};
-
 #ifdef DEBUG
 void debug_print_format(const char *msg, unsigned fmt )
 {
-   debug_printf("%s: %s\n", msg, debug_dump_enum(pipe_format_names, fmt)); 
+   debug_printf("%s: %s\n", msg, util_format_name(fmt));
 }
 #endif
 
-const char *pf_name( enum pipe_format format )
-{
-   return debug_dump_enum(pipe_format_names, format);
-}
-
 
 
 static const struct debug_named_value pipe_prim_names[] = {
@@ -707,7 +590,7 @@
    bmih.biClrUsed = 0;
    bmih.biClrImportant = 0;
 
-   stream = os_stream_create(filename, bmfh.bfSize);
+   stream = os_file_stream_create(filename);
    if(!stream)
       goto error1;
 
diff --git a/src/gallium/auxiliary/util/u_debug_dump.h b/src/gallium/auxiliary/util/u_debug_dump.h
deleted file mode 100644
index 19b130a..0000000
--- a/src/gallium/auxiliary/util/u_debug_dump.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/**************************************************************************
- * 
- * Copyright 2009 VMware, Inc.
- * 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"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- * 
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- * 
- **************************************************************************/
-
-/**
- * @file
- * Dump data in human/machine readable format.
- * 
- * @author Jose Fonseca <jfonseca@vmware.com>
- */
-
-#ifndef U_DEBUG_DUMP_H_
-#define U_DEBUG_DUMP_H_
-
-
-#include "pipe/p_compiler.h"
-#include "pipe/p_state.h"
-
-
-#ifdef	__cplusplus
-extern "C" {
-#endif
-
-
-const char *
-debug_dump_blend_factor(unsigned value, boolean shortened);
-
-const char *
-debug_dump_blend_func(unsigned value, boolean shortened);
-
-const char *
-debug_dump_func(unsigned value, boolean shortened);
-
-const char *
-debug_dump_tex_target(unsigned value, boolean shortened);
-
-const char *
-debug_dump_tex_wrap(unsigned value, boolean shortened);
-
-const char *
-debug_dump_tex_mipfilter(unsigned value, boolean shortened);
-
-const char *
-debug_dump_tex_filter(unsigned value, boolean shortened);
-
-
-/* FIXME: Move the other debug_dump_xxx functions out of u_debug.h into here. */
-
-
-#ifdef	__cplusplus
-}
-#endif
-
-#endif /* U_DEBUG_H_ */
diff --git a/src/gallium/auxiliary/util/u_dump.h b/src/gallium/auxiliary/util/u_dump.h
new file mode 100644
index 0000000..379f18e
--- /dev/null
+++ b/src/gallium/auxiliary/util/u_dump.h
@@ -0,0 +1,173 @@
+/**************************************************************************
+ * 
+ * Copyright 2009 VMware, Inc.
+ * 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"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * 
+ **************************************************************************/
+
+/**
+ * @file
+ * Dump data in human/machine readable format.
+ * 
+ * @author Jose Fonseca <jfonseca@vmware.com>
+ */
+
+#ifndef U_DEBUG_DUMP_H_
+#define U_DEBUG_DUMP_H_
+
+
+#include "pipe/p_compiler.h"
+#include "pipe/p_state.h"
+
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+
+#define UTIL_DUMP_INVALID_NAME "<invalid>"
+
+
+struct os_stream;
+
+
+/* Duplicated here for convenience */
+extern struct os_stream *
+os_log_stream;
+
+
+/*
+ * p_defines.h
+ *
+ * XXX: These functions don't really dump anything -- just translate into
+ * strings so a verb better than "dump" should be used instead, in order to
+ * free up the namespace to the true dumper functions.
+ */
+
+const char *
+util_dump_blend_factor(unsigned value, boolean shortened);
+
+const char *
+util_dump_blend_func(unsigned value, boolean shortened);
+
+const char *
+util_dump_func(unsigned value, boolean shortened);
+
+const char *
+util_dump_tex_target(unsigned value, boolean shortened);
+
+const char *
+util_dump_tex_wrap(unsigned value, boolean shortened);
+
+const char *
+util_dump_tex_mipfilter(unsigned value, boolean shortened);
+
+const char *
+util_dump_tex_filter(unsigned value, boolean shortened);
+
+
+/*
+ * p_state.h, through an os_stream
+ */
+
+void
+util_dump_template(struct os_stream *stream,
+                   const struct pipe_texture *templat);
+
+void
+util_dump_rasterizer_state(struct os_stream *stream,
+                           const struct pipe_rasterizer_state *state);
+
+void
+util_dump_poly_stipple(struct os_stream *stream,
+                       const struct pipe_poly_stipple *state);
+
+void
+util_dump_viewport_state(struct os_stream *stream,
+                         const struct pipe_viewport_state *state);
+
+void
+util_dump_scissor_state(struct os_stream *stream,
+                        const struct pipe_scissor_state *state);
+
+void
+util_dump_clip_state(struct os_stream *stream,
+                     const struct pipe_clip_state *state);
+
+void
+util_dump_shader_state(struct os_stream *stream,
+                       const struct pipe_shader_state *state);
+
+void
+util_dump_depth_stencil_alpha_state(struct os_stream *stream,
+                                    const struct pipe_depth_stencil_alpha_state *state);
+
+void
+util_dump_rt_blend_state(struct os_stream *stream,
+                         const struct pipe_rt_blend_state *state);
+
+void
+util_dump_blend_state(struct os_stream *stream,
+                      const struct pipe_blend_state *state);
+
+void
+util_dump_blend_color(struct os_stream *stream,
+                      const struct pipe_blend_color *state);
+
+void
+util_dump_stencil_ref(struct os_stream *stream,
+                      const struct pipe_stencil_ref *state);
+
+void
+util_dump_framebuffer_state(struct os_stream *stream,
+                            const struct pipe_framebuffer_state *state);
+
+void
+util_dump_sampler_state(struct os_stream *stream,
+                        const struct pipe_sampler_state *state);
+
+void
+util_dump_surface(struct os_stream *stream,
+                  const struct pipe_surface *state);
+
+void
+util_dump_transfer(struct os_stream *stream,
+                   const struct pipe_transfer *state);
+
+void
+util_dump_vertex_buffer(struct os_stream *stream,
+                        const struct pipe_vertex_buffer *state);
+
+void
+util_dump_vertex_element(struct os_stream *stream,
+                         const struct pipe_vertex_element *state);
+
+
+/* FIXME: Move the other debug_dump_xxx functions out of u_debug.h into here. */
+
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif /* U_DEBUG_H_ */
diff --git a/src/gallium/auxiliary/util/u_debug_dump.c b/src/gallium/auxiliary/util/u_dump_defines.c
similarity index 69%
rename from src/gallium/auxiliary/util/u_debug_dump.c
rename to src/gallium/auxiliary/util/u_dump_defines.c
index 61624d0..96a2256 100644
--- a/src/gallium/auxiliary/util/u_debug_dump.c
+++ b/src/gallium/auxiliary/util/u_dump_defines.c
@@ -28,15 +28,12 @@
 
 #include "util/u_memory.h"
 #include "util/u_debug.h" 
-#include "util/u_debug_dump.h" 
-
-
-#define DEBUG_DUMP_INVALID_NAME "<invalid>"
+#include "util/u_dump.h"
 
 
 #if 0
 static const char *
-debug_dump_strip_prefix(const char *name,
+util_dump_strip_prefix(const char *name,
                         const char *prefix) 
 {
    const char *stripped;
@@ -55,30 +52,30 @@
 #endif
 
 static const char *
-debug_dump_enum_continuous(unsigned value, 
+util_dump_enum_continuous(unsigned value,
                            unsigned num_names,
                            const char **names)
 {
    if (value >= num_names)
-      return DEBUG_DUMP_INVALID_NAME;
+      return UTIL_DUMP_INVALID_NAME;
    return names[value];
 }
 
 
-#define DEFINE_DEBUG_DUMP_CONTINUOUS(_name) \
+#define DEFINE_UTIL_DUMP_CONTINUOUS(_name) \
    const char * \
-   debug_dump_##_name(unsigned value, boolean shortened) \
+   util_dump_##_name(unsigned value, boolean shortened) \
    { \
       if(shortened) \
-         return debug_dump_enum_continuous(value, Elements(debug_dump_##_name##_short_names), debug_dump_##_name##_short_names); \
+         return util_dump_enum_continuous(value, Elements(util_dump_##_name##_short_names), util_dump_##_name##_short_names); \
       else \
-         return debug_dump_enum_continuous(value, Elements(debug_dump_##_name##_names), debug_dump_##_name##_names); \
+         return util_dump_enum_continuous(value, Elements(util_dump_##_name##_names), util_dump_##_name##_names); \
    }
 
 
 static const char *
-debug_dump_blend_factor_names[] = {
-   DEBUG_DUMP_INVALID_NAME, /* 0x0 */
+util_dump_blend_factor_names[] = {
+   UTIL_DUMP_INVALID_NAME, /* 0x0 */
    "PIPE_BLENDFACTOR_ONE",
    "PIPE_BLENDFACTOR_SRC_COLOR",
    "PIPE_BLENDFACTOR_SRC_ALPHA",
@@ -89,18 +86,18 @@
    "PIPE_BLENDFACTOR_CONST_ALPHA",
    "PIPE_BLENDFACTOR_SRC1_COLOR",
    "PIPE_BLENDFACTOR_SRC1_ALPHA",
-   DEBUG_DUMP_INVALID_NAME, /* 0x0b */
-   DEBUG_DUMP_INVALID_NAME, /* 0x0c */
-   DEBUG_DUMP_INVALID_NAME, /* 0x0d */
-   DEBUG_DUMP_INVALID_NAME, /* 0x0e */
-   DEBUG_DUMP_INVALID_NAME, /* 0x0f */
-   DEBUG_DUMP_INVALID_NAME, /* 0x10 */
+   UTIL_DUMP_INVALID_NAME, /* 0x0b */
+   UTIL_DUMP_INVALID_NAME, /* 0x0c */
+   UTIL_DUMP_INVALID_NAME, /* 0x0d */
+   UTIL_DUMP_INVALID_NAME, /* 0x0e */
+   UTIL_DUMP_INVALID_NAME, /* 0x0f */
+   UTIL_DUMP_INVALID_NAME, /* 0x10 */
    "PIPE_BLENDFACTOR_ZERO",
    "PIPE_BLENDFACTOR_INV_SRC_COLOR",
    "PIPE_BLENDFACTOR_INV_SRC_ALPHA",
    "PIPE_BLENDFACTOR_INV_DST_ALPHA",
    "PIPE_BLENDFACTOR_INV_DST_COLOR",
-   DEBUG_DUMP_INVALID_NAME, /* 0x16 */
+   UTIL_DUMP_INVALID_NAME, /* 0x16 */
    "PIPE_BLENDFACTOR_INV_CONST_COLOR",
    "PIPE_BLENDFACTOR_INV_CONST_ALPHA",
    "PIPE_BLENDFACTOR_INV_SRC1_COLOR",
@@ -108,8 +105,8 @@
 };
 
 static const char *
-debug_dump_blend_factor_short_names[] = {
-   DEBUG_DUMP_INVALID_NAME, /* 0x0 */
+util_dump_blend_factor_short_names[] = {
+   UTIL_DUMP_INVALID_NAME, /* 0x0 */
    "one",
    "src_color",
    "src_alpha",
@@ -120,29 +117,29 @@
    "const_alpha",
    "src1_color",
    "src1_alpha",
-   DEBUG_DUMP_INVALID_NAME, /* 0x0b */
-   DEBUG_DUMP_INVALID_NAME, /* 0x0c */
-   DEBUG_DUMP_INVALID_NAME, /* 0x0d */
-   DEBUG_DUMP_INVALID_NAME, /* 0x0e */
-   DEBUG_DUMP_INVALID_NAME, /* 0x0f */
-   DEBUG_DUMP_INVALID_NAME, /* 0x10 */
+   UTIL_DUMP_INVALID_NAME, /* 0x0b */
+   UTIL_DUMP_INVALID_NAME, /* 0x0c */
+   UTIL_DUMP_INVALID_NAME, /* 0x0d */
+   UTIL_DUMP_INVALID_NAME, /* 0x0e */
+   UTIL_DUMP_INVALID_NAME, /* 0x0f */
+   UTIL_DUMP_INVALID_NAME, /* 0x10 */
    "zero",
    "inv_src_color",
    "inv_src_alpha",
    "inv_dst_alpha",
    "inv_dst_color",
-   DEBUG_DUMP_INVALID_NAME, /* 0x16 */
+   UTIL_DUMP_INVALID_NAME, /* 0x16 */
    "inv_const_color",
    "inv_const_alpha",
    "inv_src1_color",
    "inv_src1_alpha"
 };
 
-DEFINE_DEBUG_DUMP_CONTINUOUS(blend_factor)
+DEFINE_UTIL_DUMP_CONTINUOUS(blend_factor)
 
 
 static const char *
-debug_dump_blend_func_names[] = {
+util_dump_blend_func_names[] = {
    "PIPE_BLEND_ADD",
    "PIPE_BLEND_SUBTRACT",
    "PIPE_BLEND_REVERSE_SUBTRACT",
@@ -151,7 +148,7 @@
 };
 
 static const char *
-debug_dump_blend_func_short_names[] = {
+util_dump_blend_func_short_names[] = {
    "add",
    "sub",
    "rev_sub",
@@ -159,11 +156,11 @@
    "max"
 };
 
-DEFINE_DEBUG_DUMP_CONTINUOUS(blend_func)
+DEFINE_UTIL_DUMP_CONTINUOUS(blend_func)
 
 
 static const char *
-debug_dump_func_names[] = {
+util_dump_func_names[] = {
    "PIPE_FUNC_NEVER",
    "PIPE_FUNC_LESS",
    "PIPE_FUNC_EQUAL",
@@ -175,7 +172,7 @@
 };
 
 static const char *
-debug_dump_func_short_names[] = {
+util_dump_func_short_names[] = {
    "never",
    "less",
    "equal",
@@ -186,11 +183,11 @@
    "always"
 };
 
-DEFINE_DEBUG_DUMP_CONTINUOUS(func)
+DEFINE_UTIL_DUMP_CONTINUOUS(func)
 
 
 static const char *
-debug_dump_tex_target_names[] = {
+util_dump_tex_target_names[] = {
    "PIPE_TEXTURE_1D",
    "PIPE_TEXTURE_2D",
    "PIPE_TEXTURE_3D",
@@ -198,18 +195,18 @@
 };
 
 static const char *
-debug_dump_tex_target_short_names[] = {
+util_dump_tex_target_short_names[] = {
    "1d",
    "2d",
    "3d",
    "cube"
 };
 
-DEFINE_DEBUG_DUMP_CONTINUOUS(tex_target)
+DEFINE_UTIL_DUMP_CONTINUOUS(tex_target)
 
 
 static const char *
-debug_dump_tex_wrap_names[] = {
+util_dump_tex_wrap_names[] = {
    "PIPE_TEX_WRAP_REPEAT",
    "PIPE_TEX_WRAP_CLAMP",
    "PIPE_TEX_WRAP_CLAMP_TO_EDGE",
@@ -221,7 +218,7 @@
 };
 
 static const char *
-debug_dump_tex_wrap_short_names[] = {
+util_dump_tex_wrap_short_names[] = {
    "repeat",
    "clamp",
    "clamp_to_edge",
@@ -232,36 +229,36 @@
    "mirror_clamp_to_border"
 };
 
-DEFINE_DEBUG_DUMP_CONTINUOUS(tex_wrap)
+DEFINE_UTIL_DUMP_CONTINUOUS(tex_wrap)
 
 
 static const char *
-debug_dump_tex_mipfilter_names[] = {
+util_dump_tex_mipfilter_names[] = {
    "PIPE_TEX_MIPFILTER_NEAREST",
    "PIPE_TEX_MIPFILTER_LINEAR",
    "PIPE_TEX_MIPFILTER_NONE"
 };
 
 static const char *
-debug_dump_tex_mipfilter_short_names[] = {
+util_dump_tex_mipfilter_short_names[] = {
    "nearest",
    "linear",
    "none"
 };
 
-DEFINE_DEBUG_DUMP_CONTINUOUS(tex_mipfilter)
+DEFINE_UTIL_DUMP_CONTINUOUS(tex_mipfilter)
 
 
 static const char *
-debug_dump_tex_filter_names[] = {
+util_dump_tex_filter_names[] = {
    "PIPE_TEX_FILTER_NEAREST",
    "PIPE_TEX_FILTER_LINEAR"
 };
 
 static const char *
-debug_dump_tex_filter_short_names[] = {
+util_dump_tex_filter_short_names[] = {
    "nearest",
    "linear"
 };
 
-DEFINE_DEBUG_DUMP_CONTINUOUS(tex_filter)
+DEFINE_UTIL_DUMP_CONTINUOUS(tex_filter)
diff --git a/src/gallium/auxiliary/util/u_dump_state.c b/src/gallium/auxiliary/util/u_dump_state.c
new file mode 100644
index 0000000..eaf4ec9
--- /dev/null
+++ b/src/gallium/auxiliary/util/u_dump_state.c
@@ -0,0 +1,709 @@
+/**************************************************************************
+ *
+ * Copyright 2008-2010 VMware, Inc.
+ * 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"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+
+#include "pipe/p_compiler.h"
+#include "os/os_stream.h"
+#include "util/u_memory.h"
+#include "util/u_string.h"
+#include "util/u_format.h"
+#include "tgsi/tgsi_dump.h"
+
+#include "u_dump.h"
+
+
+/*
+ * Dump primitives
+ */
+
+static INLINE void
+util_stream_writef(struct os_stream *stream, const char *format, ...)
+{
+   static char buf[1024];
+   unsigned len;
+   va_list ap;
+   va_start(ap, format);
+   len = util_vsnprintf(buf, sizeof(buf), format, ap);
+   va_end(ap);
+   os_stream_write(stream, buf, len);
+}
+
+static void
+util_dump_bool(struct os_stream *stream, int value)
+{
+   util_stream_writef(stream, "%c", value ? '1' : '0');
+}
+
+static void
+util_dump_int(struct os_stream *stream, long long int value)
+{
+   util_stream_writef(stream, "%lli", value);
+}
+
+static void
+util_dump_uint(struct os_stream *stream, long long unsigned value)
+{
+   util_stream_writef(stream, "%llu", value);
+}
+
+static void
+util_dump_float(struct os_stream *stream, double value)
+{
+   util_stream_writef(stream, "%g", value);
+}
+
+static void
+util_dump_string(struct os_stream *stream, const char *str)
+{
+   os_stream_write_str(stream, "\"");
+   os_stream_write_str(stream, str);
+   os_stream_write_str(stream, "\"");
+}
+
+static void
+util_dump_enum(struct os_stream *stream, const char *value)
+{
+   os_stream_write_str(stream, value);
+}
+
+static void
+util_dump_array_begin(struct os_stream *stream)
+{
+   os_stream_write_str(stream, "{");
+}
+
+static void
+util_dump_array_end(struct os_stream *stream)
+{
+   os_stream_write_str(stream, "}");
+}
+
+static void
+util_dump_elem_begin(struct os_stream *stream)
+{
+}
+
+static void
+util_dump_elem_end(struct os_stream *stream)
+{
+   os_stream_write_str(stream, ", ");
+}
+
+static void
+util_dump_struct_begin(struct os_stream *stream, const char *name)
+{
+   os_stream_write_str(stream, "{");
+}
+
+static void
+util_dump_struct_end(struct os_stream *stream)
+{
+   os_stream_write_str(stream, "}");
+}
+
+static void
+util_dump_member_begin(struct os_stream *stream, const char *name)
+{
+   util_stream_writef(stream, "%s = ", name);
+}
+
+static void
+util_dump_member_end(struct os_stream *stream)
+{
+   os_stream_write_str(stream, ", ");
+}
+
+static void
+util_dump_null(struct os_stream *stream)
+{
+   os_stream_write_str(stream, "NULL");
+}
+
+static void
+util_dump_ptr(struct os_stream *stream, const void *value)
+{
+   if(value)
+      util_stream_writef(stream, "0x%08lx", (unsigned long)(uintptr_t)value);
+   else
+      util_dump_null(stream);
+}
+
+
+/*
+ * Code saving macros.
+ */
+
+#define util_dump_arg(_stream, _type, _arg) \
+   do { \
+      util_dump_arg_begin(_stream, #_arg); \
+      util_dump_##_type(_stream, _arg); \
+      util_dump_arg_end(_stream); \
+   } while(0)
+
+#define util_dump_ret(_stream, _type, _arg) \
+   do { \
+      util_dump_ret_begin(_stream); \
+      util_dump_##_type(_stream, _arg); \
+      util_dump_ret_end(_stream); \
+   } while(0)
+
+#define util_dump_array(_stream, _type, _obj, _size) \
+   do { \
+      size_t idx; \
+      util_dump_array_begin(_stream); \
+      for(idx = 0; idx < (_size); ++idx) { \
+         util_dump_elem_begin(_stream); \
+         util_dump_##_type(_stream, (_obj)[idx]); \
+         util_dump_elem_end(_stream); \
+      } \
+      util_dump_array_end(_stream); \
+   } while(0)
+
+#define util_dump_struct_array(_stream, _type, _obj, _size) \
+   do { \
+      size_t idx; \
+      util_dump_array_begin(_stream); \
+      for(idx = 0; idx < (_size); ++idx) { \
+         util_dump_elem_begin(_stream); \
+         util_dump_##_type(_stream, &(_obj)[idx]); \
+         util_dump_elem_end(_stream); \
+      } \
+      util_dump_array_end(_stream); \
+   } while(0)
+
+#define util_dump_member(_stream, _type, _obj, _member) \
+   do { \
+      util_dump_member_begin(_stream, #_member); \
+      util_dump_##_type(_stream, (_obj)->_member); \
+      util_dump_member_end(_stream); \
+   } while(0)
+
+#define util_dump_arg_array(_stream, _type, _arg, _size) \
+   do { \
+      util_dump_arg_begin(_stream, #_arg); \
+      util_dump_array(_stream, _type, _arg, _size); \
+      util_dump_arg_end(_stream); \
+   } while(0)
+
+#define util_dump_member_array(_stream, _type, _obj, _member) \
+   do { \
+      util_dump_member_begin(_stream, #_member); \
+      util_dump_array(_stream, _type, (_obj)->_member, sizeof((_obj)->_member)/sizeof((_obj)->_member[0])); \
+      util_dump_member_end(_stream); \
+   } while(0)
+
+
+
+/*
+ * Wrappers for enum -> string dumpers.
+ */
+
+
+static void
+util_dump_format(struct os_stream *stream, enum pipe_format format)
+{
+   util_dump_enum(stream, util_format_name(format));
+}
+
+
+static void
+util_dump_enum_blend_factor(struct os_stream *stream, unsigned value)
+{
+   util_dump_enum(stream, util_dump_blend_factor(value, TRUE));
+}
+
+static void
+util_dump_enum_blend_func(struct os_stream *stream, unsigned value)
+{
+   util_dump_enum(stream, util_dump_blend_func(value, TRUE));
+}
+
+static void
+util_dump_enum_func(struct os_stream *stream, unsigned value)
+{
+   util_dump_enum(stream, util_dump_func(value, TRUE));
+}
+
+
+/*
+ * Public functions
+ */
+
+
+void
+util_dump_template(struct os_stream *stream, const struct pipe_texture *templat)
+{
+   if(!templat) {
+      util_dump_null(stream);
+      return;
+   }
+
+   util_dump_struct_begin(stream, "pipe_texture");
+
+   util_dump_member(stream, int, templat, target);
+   util_dump_member(stream, format, templat, format);
+
+   util_dump_member_begin(stream, "width");
+   util_dump_uint(stream, templat->width0);
+   util_dump_member_end(stream);
+
+   util_dump_member_begin(stream, "height");
+   util_dump_uint(stream, templat->height0);
+   util_dump_member_end(stream);
+
+   util_dump_member_begin(stream, "depth");
+   util_dump_uint(stream, templat->depth0);
+   util_dump_member_end(stream);
+
+   util_dump_member(stream, uint, templat, last_level);
+   util_dump_member(stream, uint, templat, tex_usage);
+
+   util_dump_struct_end(stream);
+}
+
+
+void
+util_dump_rasterizer_state(struct os_stream *stream, const struct pipe_rasterizer_state *state)
+{
+   if(!state) {
+      util_dump_null(stream);
+      return;
+   }
+
+   util_dump_struct_begin(stream, "pipe_rasterizer_state");
+
+   util_dump_member(stream, bool, state, flatshade);
+   util_dump_member(stream, bool, state, light_twoside);
+   util_dump_member(stream, uint, state, front_winding);
+   util_dump_member(stream, uint, state, cull_mode);
+   util_dump_member(stream, uint, state, fill_cw);
+   util_dump_member(stream, uint, state, fill_ccw);
+   util_dump_member(stream, bool, state, offset_cw);
+   util_dump_member(stream, bool, state, offset_ccw);
+   util_dump_member(stream, bool, state, scissor);
+   util_dump_member(stream, bool, state, poly_smooth);
+   util_dump_member(stream, bool, state, poly_stipple_enable);
+   util_dump_member(stream, bool, state, point_smooth);
+   util_dump_member(stream, uint, state, sprite_coord_enable);
+   util_dump_member(stream, bool, state, sprite_coord_mode);
+   util_dump_member(stream, bool, state, point_quad_rasterization);
+   util_dump_member(stream, bool, state, point_size_per_vertex);
+   util_dump_member(stream, bool, state, multisample);
+   util_dump_member(stream, bool, state, line_smooth);
+   util_dump_member(stream, bool, state, line_stipple_enable);
+   util_dump_member(stream, uint, state, line_stipple_factor);
+   util_dump_member(stream, uint, state, line_stipple_pattern);
+   util_dump_member(stream, bool, state, line_last_pixel);
+   util_dump_member(stream, bool, state, bypass_vs_clip_and_viewport);
+   util_dump_member(stream, bool, state, flatshade_first);
+   util_dump_member(stream, bool, state, gl_rasterization_rules);
+
+   util_dump_member(stream, float, state, line_width);
+   util_dump_member(stream, float, state, point_size);
+   util_dump_member(stream, float, state, offset_units);
+   util_dump_member(stream, float, state, offset_scale);
+
+   util_dump_struct_end(stream);
+}
+
+
+void
+util_dump_poly_stipple(struct os_stream *stream, const struct pipe_poly_stipple *state)
+{
+   if(!state) {
+      util_dump_null(stream);
+      return;
+   }
+
+   util_dump_struct_begin(stream, "pipe_poly_stipple");
+
+   util_dump_member_begin(stream, "stipple");
+   util_dump_member_array(stream, uint, state, stipple);
+   util_dump_member_end(stream);
+
+   util_dump_struct_end(stream);
+}
+
+
+void
+util_dump_viewport_state(struct os_stream *stream, const struct pipe_viewport_state *state)
+{
+   if(!state) {
+      util_dump_null(stream);
+      return;
+   }
+
+   util_dump_struct_begin(stream, "pipe_viewport_state");
+
+   util_dump_member_array(stream, float, state, scale);
+   util_dump_member_array(stream, float, state, translate);
+
+   util_dump_struct_end(stream);
+}
+
+
+void
+util_dump_scissor_state(struct os_stream *stream, const struct pipe_scissor_state *state)
+{
+   if(!state) {
+      util_dump_null(stream);
+      return;
+   }
+
+   util_dump_struct_begin(stream, "pipe_scissor_state");
+
+   util_dump_member(stream, uint, state, minx);
+   util_dump_member(stream, uint, state, miny);
+   util_dump_member(stream, uint, state, maxx);
+   util_dump_member(stream, uint, state, maxy);
+
+   util_dump_struct_end(stream);
+}
+
+
+void
+util_dump_clip_state(struct os_stream *stream, const struct pipe_clip_state *state)
+{
+   unsigned i;
+
+   if(!state) {
+      util_dump_null(stream);
+      return;
+   }
+
+   util_dump_struct_begin(stream, "pipe_clip_state");
+
+   util_dump_member_begin(stream, "ucp");
+   util_dump_array_begin(stream);
+   for(i = 0; i < PIPE_MAX_CLIP_PLANES; ++i) {
+      util_dump_elem_begin(stream);
+      util_dump_array(stream, float, state->ucp[i], 4);
+      util_dump_elem_end(stream);
+   }
+   util_dump_array_end(stream);
+   util_dump_member_end(stream);
+
+   util_dump_member(stream, uint, state, nr);
+
+   util_dump_struct_end(stream);
+}
+
+
+void
+util_dump_shader_state(struct os_stream *stream, const struct pipe_shader_state *state)
+{
+   char str[8192];
+
+   if(!state) {
+      util_dump_null(stream);
+      return;
+   }
+
+   tgsi_dump_str(state->tokens, 0, str, sizeof(str));
+
+   util_dump_struct_begin(stream, "pipe_shader_state");
+
+   util_dump_member_begin(stream, "tokens");
+   util_dump_string(stream, str);
+   util_dump_member_end(stream);
+
+   util_dump_struct_end(stream);
+}
+
+
+void
+util_dump_depth_stencil_alpha_state(struct os_stream *stream, const struct pipe_depth_stencil_alpha_state *state)
+{
+   unsigned i;
+
+   if(!state) {
+      util_dump_null(stream);
+      return;
+   }
+
+   util_dump_struct_begin(stream, "pipe_depth_stencil_alpha_state");
+
+   util_dump_member_begin(stream, "depth");
+   util_dump_struct_begin(stream, "pipe_depth_state");
+   util_dump_member(stream, bool, &state->depth, enabled);
+   if (state->depth.enabled) {
+      util_dump_member(stream, bool, &state->depth, writemask);
+      util_dump_member(stream, enum_func, &state->depth, func);
+   }
+   util_dump_struct_end(stream);
+   util_dump_member_end(stream);
+
+   util_dump_member_begin(stream, "stencil");
+   util_dump_array_begin(stream);
+   for(i = 0; i < Elements(state->stencil); ++i) {
+      util_dump_elem_begin(stream);
+      util_dump_struct_begin(stream, "pipe_stencil_state");
+      util_dump_member(stream, bool, &state->stencil[i], enabled);
+      if (state->stencil[i].enabled) {
+         util_dump_member(stream, enum_func, &state->stencil[i], func);
+         util_dump_member(stream, uint, &state->stencil[i], fail_op);
+         util_dump_member(stream, uint, &state->stencil[i], zpass_op);
+         util_dump_member(stream, uint, &state->stencil[i], zfail_op);
+         util_dump_member(stream, uint, &state->stencil[i], valuemask);
+         util_dump_member(stream, uint, &state->stencil[i], writemask);
+      }
+      util_dump_struct_end(stream);
+      util_dump_elem_end(stream);
+   }
+   util_dump_array_end(stream);
+   util_dump_member_end(stream);
+
+   util_dump_member_begin(stream, "alpha");
+   util_dump_struct_begin(stream, "pipe_alpha_state");
+   util_dump_member(stream, bool, &state->alpha, enabled);
+   if (state->alpha.enabled) {
+      util_dump_member(stream, enum_func, &state->alpha, func);
+      util_dump_member(stream, float, &state->alpha, ref_value);
+   }
+   util_dump_struct_end(stream);
+   util_dump_member_end(stream);
+
+   util_dump_struct_end(stream);
+}
+
+void
+util_dump_rt_blend_state(struct os_stream *stream, const struct pipe_rt_blend_state *state)
+{
+   util_dump_struct_begin(stream, "pipe_rt_blend_state");
+
+   util_dump_member(stream, uint, state, blend_enable);
+   if (state->blend_enable) {
+      util_dump_member(stream, enum_blend_func, state, rgb_func);
+      util_dump_member(stream, enum_blend_factor, state, rgb_src_factor);
+      util_dump_member(stream, enum_blend_factor, state, rgb_dst_factor);
+
+      util_dump_member(stream, enum_blend_func, state, alpha_func);
+      util_dump_member(stream, enum_blend_factor, state, alpha_src_factor);
+      util_dump_member(stream, enum_blend_factor, state, alpha_dst_factor);
+   }
+
+   util_dump_member(stream, uint, state, colormask);
+
+   util_dump_struct_end(stream);
+}
+
+void
+util_dump_blend_state(struct os_stream *stream, const struct pipe_blend_state *state)
+{
+   unsigned valid_entries = 1;
+
+   if(!state) {
+      util_dump_null(stream);
+      return;
+   }
+
+   util_dump_struct_begin(stream, "pipe_blend_state");
+
+   util_dump_member(stream, bool, state, dither);
+
+   util_dump_member(stream, bool, state, logicop_enable);
+   if (state->logicop_enable) {
+      util_dump_member(stream, enum_func, state, logicop_func);
+   }
+   else {
+      util_dump_member(stream, bool, state, independent_blend_enable);
+
+      util_dump_member_begin(stream, "rt");
+      if (state->independent_blend_enable)
+         valid_entries = PIPE_MAX_COLOR_BUFS;
+      util_dump_struct_array(stream, rt_blend_state, state->rt, valid_entries);
+      util_dump_member_end(stream);
+   }
+
+   util_dump_struct_end(stream);
+}
+
+
+void
+util_dump_blend_color(struct os_stream *stream, const struct pipe_blend_color *state)
+{
+   if(!state) {
+      util_dump_null(stream);
+      return;
+   }
+
+   util_dump_struct_begin(stream, "pipe_blend_color");
+
+   util_dump_member_array(stream, float, state, color);
+
+   util_dump_struct_end(stream);
+}
+
+void
+util_dump_stencil_ref(struct os_stream *stream, const struct pipe_stencil_ref *state)
+{
+   if(!state) {
+      util_dump_null(stream);
+      return;
+   }
+
+   util_dump_struct_begin(stream, "pipe_stencil_ref");
+
+   util_dump_member_array(stream, uint, state, ref_value);
+
+   util_dump_struct_end(stream);
+}
+
+void
+util_dump_framebuffer_state(struct os_stream *stream, const struct pipe_framebuffer_state *state)
+{
+   util_dump_struct_begin(stream, "pipe_framebuffer_state");
+
+   util_dump_member(stream, uint, state, width);
+   util_dump_member(stream, uint, state, height);
+   util_dump_member(stream, uint, state, nr_cbufs);
+   util_dump_member_array(stream, ptr, state, cbufs);
+   util_dump_member(stream, ptr, state, zsbuf);
+
+   util_dump_struct_end(stream);
+}
+
+
+void
+util_dump_sampler_state(struct os_stream *stream, const struct pipe_sampler_state *state)
+{
+   if(!state) {
+      util_dump_null(stream);
+      return;
+   }
+
+   util_dump_struct_begin(stream, "pipe_sampler_state");
+
+   util_dump_member(stream, uint, state, wrap_s);
+   util_dump_member(stream, uint, state, wrap_t);
+   util_dump_member(stream, uint, state, wrap_r);
+   util_dump_member(stream, uint, state, min_img_filter);
+   util_dump_member(stream, uint, state, min_mip_filter);
+   util_dump_member(stream, uint, state, mag_img_filter);
+   util_dump_member(stream, uint, state, compare_mode);
+   util_dump_member(stream, enum_func, state, compare_func);
+   util_dump_member(stream, bool, state, normalized_coords);
+   util_dump_member(stream, uint, state, max_anisotropy);
+   util_dump_member(stream, float, state, lod_bias);
+   util_dump_member(stream, float, state, min_lod);
+   util_dump_member(stream, float, state, max_lod);
+   util_dump_member_array(stream, float, state, border_color);
+
+   util_dump_struct_end(stream);
+}
+
+
+void
+util_dump_surface(struct os_stream *stream, const struct pipe_surface *state)
+{
+   if(!state) {
+      util_dump_null(stream);
+      return;
+   }
+
+   util_dump_struct_begin(stream, "pipe_surface");
+
+   util_dump_member(stream, format, state, format);
+   util_dump_member(stream, uint, state, width);
+   util_dump_member(stream, uint, state, height);
+
+   util_dump_member(stream, uint, state, layout);
+   util_dump_member(stream, uint, state, offset);
+   util_dump_member(stream, uint, state, usage);
+
+   util_dump_member(stream, ptr, state, texture);
+   util_dump_member(stream, uint, state, face);
+   util_dump_member(stream, uint, state, level);
+   util_dump_member(stream, uint, state, zslice);
+
+   util_dump_struct_end(stream);
+}
+
+
+void
+util_dump_transfer(struct os_stream *stream, const struct pipe_transfer *state)
+{
+   if(!state) {
+      util_dump_null(stream);
+      return;
+   }
+
+   util_dump_struct_begin(stream, "pipe_transfer");
+
+   util_dump_member(stream, uint, state, width);
+   util_dump_member(stream, uint, state, height);
+
+   util_dump_member(stream, uint, state, stride);
+   util_dump_member(stream, uint, state, usage);
+
+   util_dump_member(stream, ptr, state, texture);
+   util_dump_member(stream, uint, state, face);
+   util_dump_member(stream, uint, state, level);
+   util_dump_member(stream, uint, state, zslice);
+
+   util_dump_struct_end(stream);
+}
+
+
+void
+util_dump_vertex_buffer(struct os_stream *stream, const struct pipe_vertex_buffer *state)
+{
+   if(!state) {
+      util_dump_null(stream);
+      return;
+   }
+
+   util_dump_struct_begin(stream, "pipe_vertex_buffer");
+
+   util_dump_member(stream, uint, state, stride);
+   util_dump_member(stream, uint, state, max_index);
+   util_dump_member(stream, uint, state, buffer_offset);
+   util_dump_member(stream, ptr, state, buffer);
+
+   util_dump_struct_end(stream);
+}
+
+
+void
+util_dump_vertex_element(struct os_stream *stream, const struct pipe_vertex_element *state)
+{
+   if(!state) {
+      util_dump_null(stream);
+      return;
+   }
+
+   util_dump_struct_begin(stream, "pipe_vertex_element");
+
+   util_dump_member(stream, uint, state, src_offset);
+
+   util_dump_member(stream, uint, state, vertex_buffer_index);
+   util_dump_member(stream, uint, state, nr_components);
+
+   util_dump_member(stream, format, state, src_format);
+
+   util_dump_struct_end(stream);
+}
diff --git a/src/gallium/auxiliary/util/u_format.h b/src/gallium/auxiliary/util/u_format.h
index 4323bc8..2fbbb83 100644
--- a/src/gallium/auxiliary/util/u_format.h
+++ b/src/gallium/auxiliary/util/u_format.h
@@ -156,6 +156,19 @@
  * Format query functions.
  */
 
+static INLINE const char *
+util_format_name(enum pipe_format format)
+{
+   const struct util_format_description *desc = util_format_description(format);
+
+   assert(format);
+   if (!format) {
+      return "???";
+   }
+
+   return desc->name;
+}
+
 static INLINE boolean 
 util_format_is_compressed(enum pipe_format format)
 {
diff --git a/src/gallium/docs/source/context.rst b/src/gallium/docs/source/context.rst
index a766957..9080add 100644
--- a/src/gallium/docs/source/context.rst
+++ b/src/gallium/docs/source/context.rst
@@ -49,8 +49,9 @@
 
 These pieces of state are too small, variable, and/or trivial to have CSO
 objects. They all follow simple, one-method binding calls, e.g.
-``set_edgeflags``.
-
+``set_blend_color``.
+* ``set_stencil_ref`` sets the stencil front and back reference values
+  which are used as comparison values in stencil test.
 * ``set_blend_color``
 * ``set_clip_state``
 * ``set_polygon_stipple``
diff --git a/src/gallium/docs/source/cso/dsa.rst b/src/gallium/docs/source/cso/dsa.rst
index 12abaa9..1bbe381 100644
--- a/src/gallium/docs/source/cso/dsa.rst
+++ b/src/gallium/docs/source/cso/dsa.rst
@@ -11,9 +11,9 @@
 
 During actual execution, the order of operations done on fragments is always:
 
+* Alpha
 * Stencil
 * Depth
-* Alpha
 
 Depth Members
 -------------
@@ -28,15 +28,18 @@
 Stencil Members
 ---------------
 
-XXX document valuemask, writemask
-
 enabled
     Whether the stencil test is enabled. For the second stencil, whether the
-    two-sided stencil is enabled.
+    two-sided stencil is enabled. If two-sided stencil is disabled, the other
+    fields for the second array member are not valid.
 func
     The stencil test function. One of PIPE_FUNC.
-ref_value
-    Stencil test reference value; used for certain functions.
+valuemask
+    Stencil test value mask; this is ANDed with the value in the stencil
+    buffer and the reference value before doing the stencil comparison test.
+writemask
+    Stencil test writemask; this controls which bits of the stencil buffer
+    are written.
 fail_op
     The operation to carry out if the stencil test fails. One of
     PIPE_STENCIL_OP.
diff --git a/src/gallium/docs/source/cso/sampler.rst b/src/gallium/docs/source/cso/sampler.rst
index 044ffff..77979fc 100644
--- a/src/gallium/docs/source/cso/sampler.rst
+++ b/src/gallium/docs/source/cso/sampler.rst
@@ -45,4 +45,6 @@
     RGBA color used for out-of-bounds coordinates.
 max_anisotropy
     Maximum filtering to apply anisotropically to textures. Setting this to
-    1.0 effectively disables anisotropic filtering.
+    0 disables anisotropic filtering. Any other setting enables anisotropic
+    filtering, however it's not unexpected some drivers only will change their
+    filtering with a setting of 2 and higher.
diff --git a/src/gallium/drivers/cell/common.h b/src/gallium/drivers/cell/common.h
index 7f2b33c..bbb112f 100644
--- a/src/gallium/drivers/cell/common.h
+++ b/src/gallium/drivers/cell/common.h
@@ -230,6 +230,7 @@
 {
    opcode_t opcode;    /**< CELL_CMD_STATE_RASTERIZER */
    struct pipe_rasterizer_state rasterizer;
+   uint32_t pad[1];
 };
 
 
@@ -326,7 +327,7 @@
    opcode_t opcode;         /**< CELL_CMD_STATE_SAMPLER */
    uint unit;
    struct pipe_sampler_state state;
-   uint32_t pad_[2];
+   uint32_t pad_[3];
 };
 
 
diff --git a/src/gallium/drivers/cell/ppu/cell_context.h b/src/gallium/drivers/cell/ppu/cell_context.h
index 905cd5d..a77cc5b 100644
--- a/src/gallium/drivers/cell/ppu/cell_context.h
+++ b/src/gallium/drivers/cell/ppu/cell_context.h
@@ -114,6 +114,7 @@
    struct spe_function logic_op;
 
    struct pipe_blend_color blend_color;
+   struct pipe_stencil_ref stencil_ref;
    struct pipe_clip_state clip;
    struct pipe_buffer *constants[2];
    struct pipe_framebuffer_state framebuffer;
diff --git a/src/gallium/drivers/cell/ppu/cell_gen_fragment.c b/src/gallium/drivers/cell/ppu/cell_gen_fragment.c
index 0dab340..70683bb 100644
--- a/src/gallium/drivers/cell/ppu/cell_gen_fragment.c
+++ b/src/gallium/drivers/cell/ppu/cell_gen_fragment.c
@@ -1175,7 +1175,8 @@
  */
 static void
 gen_stencil_test(struct spe_function *f,
-                 const struct pipe_stencil_state *state, 
+                 const struct pipe_stencil_state *state,
+                 const unsigned ref_value,
                  uint stencil_max_value,
                  int fragment_mask_reg,
                  int fbS_reg, 
@@ -1189,7 +1190,7 @@
    case PIPE_FUNC_EQUAL:
       if (state->valuemask == stencil_max_value) {
          /* stencil_pass = fragment_mask & (s == reference) */
-         spe_compare_equal_uint(f, stencil_pass_reg, fbS_reg, state->ref_value);
+         spe_compare_equal_uint(f, stencil_pass_reg, fbS_reg, ref_value);
          spe_and(f, stencil_pass_reg, fragment_mask_reg, stencil_pass_reg);
       }
       else {
@@ -1197,7 +1198,7 @@
          uint tmp_masked_stencil = spe_allocate_available_register(f);
          spe_and_uint(f, tmp_masked_stencil, fbS_reg, state->valuemask);
          spe_compare_equal_uint(f, stencil_pass_reg, tmp_masked_stencil,
-                                state->valuemask & state->ref_value);
+                                state->valuemask & ref_value);
          spe_and(f, stencil_pass_reg, fragment_mask_reg, stencil_pass_reg);
          spe_release_register(f, tmp_masked_stencil);
       }
@@ -1206,7 +1207,7 @@
    case PIPE_FUNC_NOTEQUAL:
       if (state->valuemask == stencil_max_value) {
          /* stencil_pass = fragment_mask & ~(s == reference) */
-         spe_compare_equal_uint(f, stencil_pass_reg, fbS_reg, state->ref_value);
+         spe_compare_equal_uint(f, stencil_pass_reg, fbS_reg, ref_value);
          spe_andc(f, stencil_pass_reg, fragment_mask_reg, stencil_pass_reg);
       }
       else {
@@ -1214,7 +1215,7 @@
          int tmp_masked_stencil = spe_allocate_available_register(f);
          spe_and_uint(f, tmp_masked_stencil, fbS_reg, state->valuemask);
          spe_compare_equal_uint(f, stencil_pass_reg, tmp_masked_stencil,
-                                state->valuemask & state->ref_value);
+                                state->valuemask & ref_value);
          spe_andc(f, stencil_pass_reg, fragment_mask_reg, stencil_pass_reg);
          spe_release_register(f, tmp_masked_stencil);
       }
@@ -1223,7 +1224,7 @@
    case PIPE_FUNC_LESS:
       if (state->valuemask == stencil_max_value) {
          /* stencil_pass = fragment_mask & (reference < s)  */
-         spe_compare_greater_uint(f, stencil_pass_reg, fbS_reg, state->ref_value);
+         spe_compare_greater_uint(f, stencil_pass_reg, fbS_reg, ref_value);
          spe_and(f, stencil_pass_reg, fragment_mask_reg, stencil_pass_reg);
       }
       else {
@@ -1231,7 +1232,7 @@
          int tmp_masked_stencil = spe_allocate_available_register(f);
          spe_and_uint(f, tmp_masked_stencil, fbS_reg, state->valuemask);
          spe_compare_greater_uint(f, stencil_pass_reg, tmp_masked_stencil,
-                                  state->valuemask & state->ref_value);
+                                  state->valuemask & ref_value);
          spe_and(f, stencil_pass_reg, fragment_mask_reg, stencil_pass_reg);
          spe_release_register(f, tmp_masked_stencil);
       }
@@ -1246,7 +1247,7 @@
           * treats its operands as unsigned - no sign extension.
           */
          int tmp_reg = spe_allocate_available_register(f);
-         spe_load_uint(f, tmp_reg, state->ref_value);
+         spe_load_uint(f, tmp_reg, ref_value);
          spe_clgt(f, stencil_pass_reg, tmp_reg, fbS_reg);
          spe_and(f, stencil_pass_reg, fragment_mask_reg, stencil_pass_reg);
          spe_release_register(f, tmp_reg);
@@ -1255,7 +1256,7 @@
          /* stencil_pass = fragment_mask & ((reference&mask) > (s&mask)) */
          int tmp_reg = spe_allocate_available_register(f);
          int tmp_masked_stencil = spe_allocate_available_register(f);
-         spe_load_uint(f, tmp_reg, state->valuemask & state->ref_value);
+         spe_load_uint(f, tmp_reg, state->valuemask & ref_value);
          spe_and_uint(f, tmp_masked_stencil, fbS_reg, state->valuemask);
          spe_clgt(f, stencil_pass_reg, tmp_reg, tmp_masked_stencil);
          spe_and(f, stencil_pass_reg, fragment_mask_reg, stencil_pass_reg);
@@ -1269,7 +1270,7 @@
          /* stencil_pass = fragment_mask & (reference >= s) 
           *              = fragment_mask & ~(s > reference) */
          spe_compare_greater_uint(f, stencil_pass_reg, fbS_reg,
-                                  state->ref_value);
+                                  ref_value);
          spe_andc(f, stencil_pass_reg, fragment_mask_reg, stencil_pass_reg);
       }
       else {
@@ -1277,7 +1278,7 @@
          int tmp_masked_stencil = spe_allocate_available_register(f);
          spe_and_uint(f, tmp_masked_stencil, fbS_reg, state->valuemask);
          spe_compare_greater_uint(f, stencil_pass_reg, tmp_masked_stencil,
-                                  state->valuemask & state->ref_value);
+                                  state->valuemask & ref_value);
          spe_andc(f, stencil_pass_reg, fragment_mask_reg, stencil_pass_reg);
          spe_release_register(f, tmp_masked_stencil);
       }
@@ -1289,7 +1290,7 @@
           *               = fragment_mask & ~(reference > s) */
          /* As above, we have to do this by loading a register */
          int tmp_reg = spe_allocate_available_register(f);
-         spe_load_uint(f, tmp_reg, state->ref_value);
+         spe_load_uint(f, tmp_reg, ref_value);
          spe_clgt(f, stencil_pass_reg, tmp_reg, fbS_reg);
          spe_andc(f, stencil_pass_reg, fragment_mask_reg, stencil_pass_reg);
          spe_release_register(f, tmp_reg);
@@ -1298,7 +1299,7 @@
          /* stencil_pass = fragment_mask & ~((reference&mask) > (s&mask)) */
          int tmp_reg = spe_allocate_available_register(f);
          int tmp_masked_stencil = spe_allocate_available_register(f);
-         spe_load_uint(f, tmp_reg, state->ref_value & state->valuemask);
+         spe_load_uint(f, tmp_reg, ref_value & state->valuemask);
          spe_and_uint(f, tmp_masked_stencil, fbS_reg, state->valuemask);
          spe_clgt(f, stencil_pass_reg, tmp_reg, tmp_masked_stencil);
          spe_andc(f, stencil_pass_reg, fragment_mask_reg, stencil_pass_reg);
@@ -1453,6 +1454,7 @@
 static void
 gen_get_stencil_values(struct spe_function *f,
                        const struct pipe_stencil_state *stencil,
+                       const unsigned ref_value,
                        const uint depth_enabled,
                        int fbS_reg, 
                        int *fail_reg,
@@ -1488,7 +1490,7 @@
    }
    else {
       *fail_reg = spe_allocate_available_register(f);
-      gen_stencil_values(f, stencil->fail_op, stencil->ref_value, 
+      gen_stencil_values(f, stencil->fail_op, ref_value, 
          0xff, fbS_reg, *fail_reg);
    }
 
@@ -1501,7 +1503,7 @@
    }
    else {
       *zfail_reg = spe_allocate_available_register(f);
-      gen_stencil_values(f, stencil->zfail_op, stencil->ref_value, 
+      gen_stencil_values(f, stencil->zfail_op, ref_value, 
          0xff, fbS_reg, *zfail_reg);
    }
 
@@ -1516,7 +1518,7 @@
    }
    else {
       *zpass_reg = spe_allocate_available_register(f);
-      gen_stencil_values(f, stencil->zpass_op, stencil->ref_value, 
+      gen_stencil_values(f, stencil->zpass_op, ref_value, 
          0xff, fbS_reg, *zpass_reg);
    }
 }
@@ -1528,7 +1530,8 @@
  */
 static boolean
 gen_stencil_depth_test(struct spe_function *f, 
-                       const struct pipe_depth_stencil_alpha_state *dsa, 
+                       const struct pipe_depth_stencil_alpha_state *dsa,
+                       const struct pipe_stencil_ref *stencil_ref,
                        const uint facing,
                        const int mask_reg, const int fragZ_reg, 
                        const int fbZ_reg, const int fbS_reg)
@@ -1551,6 +1554,7 @@
    int stencil_writemask_reg;
    int zmask_reg;
    int newS_reg;
+   unsigned ref_value;
 
    /* Stenciling is quite complex: up to six different configurable stencil 
     * operations/calculations can be required (three each for front-facing
@@ -1579,9 +1583,11 @@
     */
    if (facing == CELL_FACING_BACK && dsa->stencil[1].enabled) {
       stencil = &dsa->stencil[1];
+      ref_value = stencil_ref->ref_value[1];
    }
    else {
       stencil = &dsa->stencil[0];
+      ref_value = stencil_ref->ref_value[0];
    }
 
    /* Calculate the writemask.  If the writemask is trivial (either
@@ -1641,7 +1647,7 @@
     */
    spe_comment(f, 0, "Running basic stencil test");
    stencil_pass_reg = spe_allocate_available_register(f);
-   gen_stencil_test(f, stencil, 0xff, mask_reg, fbS_reg, stencil_pass_reg);
+   gen_stencil_test(f, stencil, ref_value, 0xff, mask_reg, fbS_reg, stencil_pass_reg);
 
    /* Generate code that, given the mask of valid fragments and the
     * mask of valid fragments that passed the stencil test, computes
@@ -1678,7 +1684,7 @@
       spe_comment(f, 0, facing == CELL_FACING_FRONT
                   ? "Computing front-facing stencil values"
                   : "Computing back-facing stencil values");
-      gen_get_stencil_values(f, stencil, dsa->depth.enabled, fbS_reg, 
+      gen_get_stencil_values(f, stencil, ref_value, dsa->depth.enabled, fbS_reg, 
          &stencil_fail_values, &stencil_pass_depth_fail_values, 
          &stencil_pass_depth_pass_values);
    }  
@@ -1818,6 +1824,7 @@
 static void
 gen_depth_stencil(struct cell_context *cell,
                   const struct pipe_depth_stencil_alpha_state *dsa,
+                  const struct pipe_stencil_ref *stencil_ref,
                   struct spe_function *f,
                   uint facing,
                   int mask_reg,
@@ -1940,7 +1947,7 @@
        * gen_stencil_depth_test() function must ignore the
        * fbZ_reg register if depth is not enabled.
        */
-      write_depth_stencil = gen_stencil_depth_test(f, dsa, facing,
+      write_depth_stencil = gen_stencil_depth_test(f, dsa, stencil_ref, facing,
                                                    mask_reg, fragZ_reg,
                                                    fbZ_reg, fbS_reg);
    }
@@ -2029,6 +2036,7 @@
                            struct spe_function *f)
 {
    const struct pipe_depth_stencil_alpha_state *dsa = cell->depth_stencil;
+   const struct pipe_stencil_ref *stencil_ref = &cell->stencil_ref;
    const struct pipe_blend_state *blend = cell->blend;
    const struct pipe_blend_color *blend_color = &cell->blend_color;
    const enum pipe_format color_format = cell->framebuffer.cbufs[0]->format;
@@ -2101,7 +2109,7 @@
 
    /* generate depth and/or stencil test code */
    if (dsa->depth.enabled || dsa->stencil[0].enabled) {
-      gen_depth_stencil(cell, dsa, f,
+      gen_depth_stencil(cell, dsa, stencil_ref, f,
                         facing,
                         mask_reg,
                         depth_tile_reg,
diff --git a/src/gallium/drivers/cell/ppu/cell_pipe_state.c b/src/gallium/drivers/cell/ppu/cell_pipe_state.c
index 3259c58..3d8b440 100644
--- a/src/gallium/drivers/cell/ppu/cell_pipe_state.c
+++ b/src/gallium/drivers/cell/ppu/cell_pipe_state.c
@@ -113,6 +113,19 @@
 
 
 static void
+cell_set_stencil_ref(struct pipe_context *pipe,
+                     const struct pipe_stencil_ref *stencil_ref)
+{
+   struct cell_context *cell = cell_context(pipe);
+
+   draw_flush(cell->draw);
+
+   cell->stencil_ref = *stencil_ref;
+
+   cell->dirty |= CELL_NEW_DEPTH_STENCIL;
+}
+
+static void
 cell_set_clip_state(struct pipe_context *pipe,
                     const struct pipe_clip_state *clip)
 {
@@ -397,6 +410,7 @@
    cell->pipe.delete_rasterizer_state = cell_delete_rasterizer_state;
 
    cell->pipe.set_blend_color = cell_set_blend_color;
+   cell->pipe.set_stencil_ref = cell_set_stencil_ref;
    cell->pipe.set_clip_state = cell_set_clip_state;
 
    cell->pipe.set_framebuffer_state = cell_set_framebuffer_state;
diff --git a/src/gallium/drivers/cell/ppu/cell_screen.c b/src/gallium/drivers/cell/ppu/cell_screen.c
index 7681e34..449855f 100644
--- a/src/gallium/drivers/cell/ppu/cell_screen.c
+++ b/src/gallium/drivers/cell/ppu/cell_screen.c
@@ -33,6 +33,7 @@
 #include "pipe/p_screen.h"
 
 #include "cell/common.h"
+#include "cell_context.h"
 #include "cell_screen.h"
 #include "cell_texture.h"
 #include "cell_winsys.h"
@@ -58,6 +59,8 @@
    switch (param) {
    case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS:
       return CELL_MAX_SAMPLERS;
+   case PIPE_CAP_MAX_COMBINED_SAMPLERS:
+      return CELL_MAX_SAMPLERS;
    case PIPE_CAP_NPOT_TEXTURES:
       return 1;
    case PIPE_CAP_TWO_SIDED_STENCIL:
diff --git a/src/gallium/drivers/cell/ppu/cell_state_emit.c b/src/gallium/drivers/cell/ppu/cell_state_emit.c
index 282f05b..a59c782 100644
--- a/src/gallium/drivers/cell/ppu/cell_state_emit.c
+++ b/src/gallium/drivers/cell/ppu/cell_state_emit.c
@@ -28,6 +28,7 @@
 #include "util/u_inlines.h"
 #include "util/u_memory.h"
 #include "util/u_math.h"
+#include "util/u_format.h"
 #include "cell_context.h"
 #include "cell_gen_fragment.h"
 #include "cell_state.h"
@@ -207,8 +208,8 @@
       fb->width = cell->framebuffer.width;
       fb->height = cell->framebuffer.height;
 #if 0
-      printf("EMIT color format %s\n", pf_name(fb->color_format));
-      printf("EMIT depth format %s\n", pf_name(fb->depth_format));
+      printf("EMIT color format %s\n", util_format_name(fb->color_format));
+      printf("EMIT depth format %s\n", util_format_name(fb->depth_format));
 #endif
    }
 
diff --git a/src/gallium/drivers/cell/ppu/cell_state_per_fragment.c b/src/gallium/drivers/cell/ppu/cell_state_per_fragment.c
index 21af7ed..07be5e9 100644
--- a/src/gallium/drivers/cell/ppu/cell_state_per_fragment.c
+++ b/src/gallium/drivers/cell/ppu/cell_state_per_fragment.c
@@ -282,6 +282,7 @@
  */
 static int
 emit_stencil_test(struct pipe_depth_stencil_alpha_state *dsa,
+                  struct pipe_stencil_ref *sr,
                   unsigned face,
                   struct spe_function *f,
                   int mask,
@@ -296,7 +297,7 @@
    int stencil_pass = spe_allocate_available_register(f);
    int face_stencil = spe_allocate_available_register(f);
    int stencil_src = stencil;
-   const unsigned ref = (dsa->stencil[face].ref_value
+   const unsigned ref = (sr->ref_value[face]
                          & dsa->stencil[face].valuemask);
    boolean complement = FALSE;
    int stored;
@@ -406,7 +407,7 @@
 
          emit_stencil_op(f, face_stencil, stencil_src, stencil_fail,
                          dsa->stencil[face].fail_op,
-                         dsa->stencil[face].ref_value);
+                         sr->ref_value[face]);
 
          stencil_src = face_stencil;
       }
@@ -421,7 +422,7 @@
 
          emit_stencil_op(f, face_stencil, stencil_src, depth_fail,
                          dsa->stencil[face].zfail_op,
-                         dsa->stencil[face].ref_value);
+                         sr->ref_value[face]);
          stencil_src = face_stencil;
       }
 
@@ -429,7 +430,7 @@
           && (dsa->stencil[face].zpass_op != PIPE_STENCIL_OP_KEEP)) {
          emit_stencil_op(f, face_stencil, stencil_src, depth_pass,
                          dsa->stencil[face].zpass_op,
-                         dsa->stencil[face].ref_value);
+                         sr->ref_value[face]);
          stencil_src = face_stencil;
       }
    }
@@ -463,7 +464,8 @@
 
 
 void
-cell_generate_depth_stencil_test(struct cell_depth_stencil_alpha_state *cdsa)
+cell_generate_depth_stencil_test(struct cell_depth_stencil_alpha_state *cdsa,
+                                 struct pipe_stencil_ref *sr)
 {
    struct pipe_depth_stencil_alpha_state *const dsa = &cdsa->base;
    struct spe_function *const f = &cdsa->code;
@@ -499,13 +501,13 @@
 
    if (dsa->stencil[0].enabled) {
       const int front_depth_pass = spe_allocate_available_register(f);
-      int front_stencil = emit_stencil_test(dsa, 0, f, mask,
+      int front_stencil = emit_stencil_test(dsa, sr, 0, f, mask,
                                             depth_mask, depth_complement,
                                             stencil, front_depth_pass);
 
       if (dsa->stencil[1].enabled) {
          const int back_depth_pass = spe_allocate_available_register(f);
-         int back_stencil = emit_stencil_test(dsa, 1, f, mask,
+         int back_stencil = emit_stencil_test(dsa, sr, 1, f, mask,
                                               depth_mask,  depth_complement,
                                               stencil, back_depth_pass);
 
@@ -579,7 +581,7 @@
                 dsa->stencil[i].zfail_op,
                 dsa->stencil[i].zpass_op);
          printf("#    ref value / value mask / write mask: %02x %02x %02x\n",
-                dsa->stencil[i].ref_value,
+                sr->ref_value[i],
                 dsa->stencil[i].valuemask,
                 dsa->stencil[i].writemask);
       }
diff --git a/src/gallium/drivers/failover/fo_context.h b/src/gallium/drivers/failover/fo_context.h
index 191a44c..bb1a168 100644
--- a/src/gallium/drivers/failover/fo_context.h
+++ b/src/gallium/drivers/failover/fo_context.h
@@ -51,9 +51,10 @@
 #define FO_NEW_VERTEX          0x2000
 #define FO_NEW_VERTEX_SHADER   0x4000
 #define FO_NEW_BLEND_COLOR     0x8000
-#define FO_NEW_CLEAR_COLOR     0x10000
-#define FO_NEW_VERTEX_BUFFER   0x20000
-#define FO_NEW_VERTEX_ELEMENT  0x40000
+#define FO_NEW_STENCIL_REF     0x10000
+#define FO_NEW_CLEAR_COLOR     0x20000
+#define FO_NEW_VERTEX_BUFFER   0x40000
+#define FO_NEW_VERTEX_ELEMENT  0x80000
 
 
 
@@ -79,6 +80,7 @@
    const struct fo_state     *vertex_shader;
 
    struct pipe_blend_color blend_color;
+   struct pipe_stencil_ref stencil_ref;
    struct pipe_clip_state clip;
    struct pipe_framebuffer_state framebuffer;
    struct pipe_poly_stipple poly_stipple;
diff --git a/src/gallium/drivers/failover/fo_state.c b/src/gallium/drivers/failover/fo_state.c
index c189d1d..970606a 100644
--- a/src/gallium/drivers/failover/fo_state.c
+++ b/src/gallium/drivers/failover/fo_state.c
@@ -90,7 +90,7 @@
 
 static void
 failover_set_blend_color( struct pipe_context *pipe,
-			  const struct pipe_blend_color *blend_color )
+                          const struct pipe_blend_color *blend_color )
 {
    struct failover_context *failover = failover_context(pipe);
 
@@ -100,9 +100,21 @@
    failover->hw->set_blend_color( failover->hw, blend_color );
 }
 
+static void
+failover_set_stencil_ref( struct pipe_context *pipe,
+                          const struct pipe_stencil_ref *stencil_ref )
+{
+   struct failover_context *failover = failover_context(pipe);
+
+   failover->stencil_ref = *stencil_ref;
+   failover->dirty |= FO_NEW_STENCIL_REF;
+   failover->sw->set_stencil_ref( failover->sw, stencil_ref );
+   failover->hw->set_stencil_ref( failover->hw, stencil_ref );
+}
+
 static void 
 failover_set_clip_state( struct pipe_context *pipe,
-			 const struct pipe_clip_state *clip )
+                         const struct pipe_clip_state *clip )
 {
    struct failover_context *failover = failover_context(pipe);
 
@@ -533,6 +545,7 @@
    failover->pipe.delete_vs_state = failover_delete_vs_state;
 
    failover->pipe.set_blend_color = failover_set_blend_color;
+   failover->pipe.set_stencil_ref = failover_set_stencil_ref;
    failover->pipe.set_clip_state = failover_set_clip_state;
    failover->pipe.set_framebuffer_state = failover_set_framebuffer_state;
    failover->pipe.set_polygon_stipple = failover_set_polygon_stipple;
diff --git a/src/gallium/drivers/failover/fo_state_emit.c b/src/gallium/drivers/failover/fo_state_emit.c
index a3341e3..5c00080 100644
--- a/src/gallium/drivers/failover/fo_state_emit.c
+++ b/src/gallium/drivers/failover/fo_state_emit.c
@@ -65,7 +65,10 @@
 
    if (failover->dirty & FO_NEW_DEPTH_STENCIL)
       failover->sw->bind_depth_stencil_alpha_state( failover->sw,
-						    failover->depth_stencil->sw_state );
+                                                    failover->depth_stencil->sw_state );
+
+   if (failover->dirty & FO_NEW_STENCIL_REF)
+      failover->sw->set_stencil_ref( failover->sw, &failover->stencil_ref );
 
    if (failover->dirty & FO_NEW_FRAMEBUFFER)
       failover->sw->set_framebuffer_state( failover->sw, &failover->framebuffer );
diff --git a/src/gallium/drivers/i915/i915_context.h b/src/gallium/drivers/i915/i915_context.h
index 1479d22..da769e7 100644
--- a/src/gallium/drivers/i915/i915_context.h
+++ b/src/gallium/drivers/i915/i915_context.h
@@ -232,6 +232,7 @@
    struct i915_fragment_shader *fs;
 
    struct pipe_blend_color blend_color;
+   struct pipe_stencil_ref stencil_ref;
    struct pipe_clip_state clip;
    /* XXX unneded */
    struct pipe_buffer *constants[PIPE_SHADER_TYPES];
diff --git a/src/gallium/drivers/i915/i915_state.c b/src/gallium/drivers/i915/i915_state.c
index beb26e9..6216991 100644
--- a/src/gallium/drivers/i915/i915_state.c
+++ b/src/gallium/drivers/i915/i915_state.c
@@ -190,7 +190,7 @@
 }
 
 static void i915_set_blend_color( struct pipe_context *pipe,
-			     const struct pipe_blend_color *blend_color )
+                                  const struct pipe_blend_color *blend_color )
 {
    struct i915_context *i915 = i915_context(pipe);
    draw_flush(i915->draw);
@@ -200,6 +200,17 @@
    i915->dirty |= I915_NEW_BLEND;
 }
 
+static void i915_set_stencil_ref( struct pipe_context *pipe,
+                                  const struct pipe_stencil_ref *stencil_ref )
+{
+   struct i915_context *i915 = i915_context(pipe);
+   draw_flush(i915->draw);
+
+   i915->stencil_ref = *stencil_ref;
+
+   i915->dirty |= I915_NEW_DEPTH_STENCIL;
+}
+
 static void *
 i915_create_sampler_state(struct pipe_context *pipe,
                           const struct pipe_sampler_state *sampler)
@@ -217,10 +228,10 @@
    minFilt = translate_img_filter( sampler->min_img_filter );
    magFilt = translate_img_filter( sampler->mag_img_filter );
    
-   if (sampler->max_anisotropy > 1.0)
+   if (sampler->max_anisotropy > 1)
       minFilt = magFilt = FILTER_ANISOTROPIC;
 
-   if (sampler->max_anisotropy > 2.0) {
+   if (sampler->max_anisotropy > 2) {
       cso->state[0] |= SS2_MAX_ANISO_4;
    }
 
@@ -334,11 +345,9 @@
       int fop  = i915_translate_stencil_op(depth_stencil->stencil[0].fail_op);
       int dfop = i915_translate_stencil_op(depth_stencil->stencil[0].zfail_op);
       int dpop = i915_translate_stencil_op(depth_stencil->stencil[0].zpass_op);
-      int ref  = depth_stencil->stencil[0].ref_value & 0xff;
 
       cso->stencil_LIS5 |= (S5_STENCIL_TEST_ENABLE |
                             S5_STENCIL_WRITE_ENABLE |
-                            (ref  << S5_STENCIL_REF_SHIFT) |
                             (test << S5_STENCIL_TEST_FUNC_SHIFT) |
                             (fop  << S5_STENCIL_FAIL_SHIFT) |
                             (dfop << S5_STENCIL_PASS_Z_FAIL_SHIFT) |
@@ -350,7 +359,6 @@
       int fop   = i915_translate_stencil_op(depth_stencil->stencil[1].fail_op);
       int dfop  = i915_translate_stencil_op(depth_stencil->stencil[1].zfail_op);
       int dpop  = i915_translate_stencil_op(depth_stencil->stencil[1].zpass_op);
-      int ref   = depth_stencil->stencil[1].ref_value & 0xff;
       int tmask = depth_stencil->stencil[1].valuemask & 0xff;
       int wmask = depth_stencil->stencil[1].writemask & 0xff;
 
@@ -359,7 +367,6 @@
                      BFO_ENABLE_STENCIL_TWO_SIDE |
                      BFO_ENABLE_STENCIL_REF |
                      BFO_STENCIL_TWO_SIDE |
-                     (ref  << BFO_STENCIL_REF_SHIFT) |
                      (test << BFO_STENCIL_TEST_SHIFT) |
                      (fop  << BFO_STENCIL_FAIL_SHIFT) |
                      (dfop << BFO_STENCIL_PASS_Z_FAIL_SHIFT) |
@@ -777,6 +784,7 @@
    i915->base.delete_vs_state = i915_delete_vs_state;
 
    i915->base.set_blend_color = i915_set_blend_color;
+   i915->base.set_stencil_ref = i915_set_stencil_ref;
    i915->base.set_clip_state = i915_set_clip_state;
    i915->base.set_constant_buffer = i915_set_constant_buffer;
    i915->base.set_framebuffer_state = i915_set_framebuffer_state;
diff --git a/src/gallium/drivers/i915/i915_state_dynamic.c b/src/gallium/drivers/i915/i915_state_dynamic.c
index 86126a5..9c6723b 100644
--- a/src/gallium/drivers/i915/i915_state_dynamic.c
+++ b/src/gallium/drivers/i915/i915_state_dynamic.c
@@ -94,9 +94,16 @@
 
 static void upload_BFO( struct i915_context *i915 )
 {
+   unsigned bfo[2];
+   bfo[0] = i915->depth_stencil->bfo[0];
+   bfo[1] = i915->depth_stencil->bfo[1];
+   /* I don't get it only allowed to set a ref mask when the enable bit is set? */
+   if (bfo[0] & BFO_ENABLE_STENCIL_REF) {
+      bfo[0] |= i915->stencil_ref.ref_value[1] << BFO_STENCIL_REF_SHIFT;
+   }
    set_dynamic_indirect( i915,
 			 I915_DYNAMIC_BFO_0,
-			 &(i915->depth_stencil->bfo[0]),
+			 &(bfo[0]),
 			 2 );
 }
 
diff --git a/src/gallium/drivers/i915/i915_state_immediate.c b/src/gallium/drivers/i915/i915_state_immediate.c
index 8c16bb4..d2c6f15 100644
--- a/src/gallium/drivers/i915/i915_state_immediate.c
+++ b/src/gallium/drivers/i915/i915_state_immediate.c
@@ -129,6 +129,8 @@
    unsigned LIS5 = 0;
 
    LIS5 |= i915->depth_stencil->stencil_LIS5;
+   /* hope it's safe to set stencil ref value even if stencil test is disabled? */
+   LIS5 |= i915->stencil_ref.ref_value[0] << S5_STENCIL_REF_SHIFT;
 
    LIS5 |= i915->blend->LIS5;
 
diff --git a/src/gallium/drivers/i965/brw_cc.c b/src/gallium/drivers/i965/brw_cc.c
index 4a54327..cc8e380 100644
--- a/src/gallium/drivers/i965/brw_cc.c
+++ b/src/gallium/drivers/i965/brw_cc.c
@@ -65,14 +65,33 @@
    return ca.cc3;
 }
 
+static INLINE struct brw_cc1
+combine_cc1( struct brw_cc1 a, struct brw_cc1 b )
+{
+   union { struct brw_cc1 cc1; unsigned i; } ca, cb;
+   ca.cc1 = a;
+   cb.cc1 = b;
+   ca.i |= cb.i;
+   return ca.cc1;
+}
+
+static INLINE struct brw_cc2
+combine_cc2( struct brw_cc2 a, struct brw_cc2 b )
+{
+   union { struct brw_cc2 cc2; unsigned i; } ca, cb;
+   ca.cc2 = a;
+   cb.cc2 = b;
+   ca.i |= cb.i;
+   return ca.cc2;
+}
 
 static int prepare_cc_unit( struct brw_context *brw )
 {
    brw->cc.cc.cc0 = brw->curr.zstencil->cc0;
-   brw->cc.cc.cc1 = brw->curr.zstencil->cc1;
-   brw->cc.cc.cc2 = brw->curr.zstencil->cc2;
+   brw->cc.cc.cc1 = combine_cc1( brw->curr.zstencil->cc1, brw->curr.cc1_stencil_ref );
+   brw->cc.cc.cc2 = combine_cc2( brw->curr.zstencil->cc2, brw->curr.blend->cc2 );
    brw->cc.cc.cc3 = combine_cc3( brw->curr.zstencil->cc3, brw->curr.blend->cc3 );
-   
+
    brw->cc.cc.cc5 = brw->curr.blend->cc5;
    brw->cc.cc.cc6 = brw->curr.blend->cc6;
    brw->cc.cc.cc7 = brw->curr.zstencil->cc7;
diff --git a/src/gallium/drivers/i965/brw_context.h b/src/gallium/drivers/i965/brw_context.h
index 19fda42..12cfa7b 100644
--- a/src/gallium/drivers/i965/brw_context.h
+++ b/src/gallium/drivers/i965/brw_context.h
@@ -153,7 +153,6 @@
    struct brw_surf_ss0 ss0;
 };
 
-
 struct brw_rasterizer_state;
 
 struct brw_immediate_data {
@@ -560,12 +559,14 @@
 
       struct pipe_scissor_state scissor;
       struct pipe_viewport_state viewport;
+      struct pipe_stencil_ref stencil_ref;
       struct pipe_framebuffer_state fb;
       struct pipe_clip_state ucp;
       struct pipe_buffer *vertex_constants;
       struct pipe_buffer *fragment_constants;
 
       struct brw_blend_constant_color bcc;
+      struct brw_cc1 cc1_stencil_ref;
       struct brw_polygon_stipple bps;
       struct brw_cc_viewport ccv;
 
diff --git a/src/gallium/drivers/i965/brw_pipe_depth.c b/src/gallium/drivers/i965/brw_pipe_depth.c
index e010d76..b7000d5 100644
--- a/src/gallium/drivers/i965/brw_pipe_depth.c
+++ b/src/gallium/drivers/i965/brw_pipe_depth.c
@@ -72,7 +72,6 @@
 	 translate_stencil_op(templ->stencil[0].zfail_op);
       zstencil->cc0.stencil_pass_depth_pass_op =
 	 translate_stencil_op(templ->stencil[0].zpass_op);
-      zstencil->cc1.stencil_ref = templ->stencil[0].ref_value;
       zstencil->cc1.stencil_write_mask = templ->stencil[0].writemask;
       zstencil->cc1.stencil_test_mask = templ->stencil[0].valuemask;
 
@@ -86,7 +85,6 @@
 	    translate_stencil_op(templ->stencil[1].zfail_op);
 	 zstencil->cc0.bf_stencil_pass_depth_pass_op =
 	    translate_stencil_op(templ->stencil[1].zpass_op);
-	 zstencil->cc1.bf_stencil_ref = templ->stencil[1].ref_value;
 	 zstencil->cc2.bf_stencil_write_mask = templ->stencil[1].writemask;
 	 zstencil->cc2.bf_stencil_test_mask = templ->stencil[1].valuemask;
       }
@@ -159,9 +157,19 @@
    FREE(cso);
 }
 
+static void brw_set_stencil_ref(struct pipe_context *pipe,
+                                const struct pipe_stencil_ref *stencil_ref)
+{
+   struct brw_context *brw = brw_context(pipe);
+   brw->curr.cc1_stencil_ref.stencil_ref = stencil_ref->ref_value[0];
+   brw->curr.cc1_stencil_ref.bf_stencil_ref = stencil_ref->ref_value[1];
+
+   brw->state.dirty.mesa |= PIPE_NEW_DEPTH_STENCIL_ALPHA;
+}
 
 void brw_pipe_depth_stencil_init( struct brw_context *brw )
 {
+   brw->base.set_stencil_ref = brw_set_stencil_ref;
    brw->base.create_depth_stencil_alpha_state = brw_create_depth_stencil_state;
    brw->base.bind_depth_stencil_alpha_state = brw_bind_depth_stencil_state;
    brw->base.delete_depth_stencil_alpha_state = brw_delete_depth_stencil_state;
diff --git a/src/gallium/drivers/i965/brw_pipe_sampler.c b/src/gallium/drivers/i965/brw_pipe_sampler.c
index 6aab561..c7c0e2a 100644
--- a/src/gallium/drivers/i965/brw_pipe_sampler.c
+++ b/src/gallium/drivers/i965/brw_pipe_sampler.c
@@ -114,14 +114,12 @@
 
    /* XXX: anisotropy logic slightly changed: 
     */
-   if (template->max_anisotropy > 1.0) {
+   if (template->max_anisotropy > 1) {
       sampler->ss0.min_filter = BRW_MAPFILTER_ANISOTROPIC; 
       sampler->ss0.mag_filter = BRW_MAPFILTER_ANISOTROPIC;
 
-      if (template->max_anisotropy > 2.0) {
-	 sampler->ss3.max_aniso = MIN2((template->max_anisotropy - 2) / 2,
-				       BRW_ANISORATIO_16);
-      }
+      sampler->ss3.max_aniso = MIN2((template->max_anisotropy - 2) / 2,
+                                    BRW_ANISORATIO_16);
    }
 
    sampler->ss1.r_wrap_mode = translate_wrap_mode(template->wrap_r);
diff --git a/src/gallium/drivers/identity/id_context.c b/src/gallium/drivers/identity/id_context.c
index 9955380..8248b2a 100644
--- a/src/gallium/drivers/identity/id_context.c
+++ b/src/gallium/drivers/identity/id_context.c
@@ -389,6 +389,17 @@
 }
 
 static void
+identity_set_stencil_ref(struct pipe_context *_pipe,
+                         const struct pipe_stencil_ref *stencil_ref)
+{
+   struct identity_context *id_pipe = identity_context(_pipe);
+   struct pipe_context *pipe = id_pipe->pipe;
+
+   pipe->set_stencil_ref(pipe,
+                         stencil_ref);
+}
+
+static void
 identity_set_clip_state(struct pipe_context *_pipe,
                         const struct pipe_clip_state *clip)
 {
@@ -723,6 +734,7 @@
    id_pipe->base.bind_vs_state = identity_bind_vs_state;
    id_pipe->base.delete_vs_state = identity_delete_vs_state;
    id_pipe->base.set_blend_color = identity_set_blend_color;
+   id_pipe->base.set_stencil_ref = identity_set_stencil_ref;
    id_pipe->base.set_clip_state = identity_set_clip_state;
    id_pipe->base.set_constant_buffer = identity_set_constant_buffer;
    id_pipe->base.set_framebuffer_state = identity_set_framebuffer_state;
diff --git a/src/gallium/drivers/llvmpipe/lp_context.c b/src/gallium/drivers/llvmpipe/lp_context.c
index eded68b..9120226 100644
--- a/src/gallium/drivers/llvmpipe/lp_context.c
+++ b/src/gallium/drivers/llvmpipe/lp_context.c
@@ -146,6 +146,7 @@
    llvmpipe->pipe.delete_vs_state = llvmpipe_delete_vs_state;
 
    llvmpipe->pipe.set_blend_color = llvmpipe_set_blend_color;
+   llvmpipe->pipe.set_stencil_ref = llvmpipe_set_stencil_ref;
    llvmpipe->pipe.set_clip_state = llvmpipe_set_clip_state;
    llvmpipe->pipe.set_constant_buffer = llvmpipe_set_constant_buffer;
    llvmpipe->pipe.set_framebuffer_state = llvmpipe_set_framebuffer_state;
diff --git a/src/gallium/drivers/llvmpipe/lp_context.h b/src/gallium/drivers/llvmpipe/lp_context.h
index 3bde485..955c7eb 100644
--- a/src/gallium/drivers/llvmpipe/lp_context.h
+++ b/src/gallium/drivers/llvmpipe/lp_context.h
@@ -61,6 +61,7 @@
 
    /** Other rendering state */
    struct pipe_blend_color blend_color;
+   struct pipe_stencil_ref stencil_ref;
    struct pipe_clip_state clip;
    struct pipe_buffer *constants[PIPE_SHADER_TYPES];
    struct pipe_framebuffer_state framebuffer;
diff --git a/src/gallium/drivers/llvmpipe/lp_rast_tri.c b/src/gallium/drivers/llvmpipe/lp_rast_tri.c
index 3f76f15..0334705 100644
--- a/src/gallium/drivers/llvmpipe/lp_rast_tri.c
+++ b/src/gallium/drivers/llvmpipe/lp_rast_tri.c
@@ -146,41 +146,54 @@
 do_block_16( struct lp_rasterizer_task *rast_task,
              const struct lp_rast_triangle *tri,
              int x, int y,
+             int c0,
              int c1,
-             int c2,
-             int c3 )
+             int c2 )
 {
-   const int eo1 = tri->eo1 * 4;
-   const int eo2 = tri->eo2 * 4;
-   const int eo3 = tri->eo3 * 4;
-   const int *step0 = tri->inputs.step[0];
-   const int *step1 = tri->inputs.step[1];
-   const int *step2 = tri->inputs.step[2];
-   int i;
+   unsigned mask = 0;
+   int eo[3];
+   int c[3];
+   int i, j;
 
    assert(x % 16 == 0);
    assert(y % 16 == 0);
 
-   for (i = 0; i < 16; i++) {
-      int cx1 = c1 + step0[i] * 4;
-      int cx2 = c2 + step1[i] * 4;
-      int cx3 = c3 + step2[i] * 4;
+   eo[0] = tri->eo1 * 4;
+   eo[1] = tri->eo2 * 4;
+   eo[2] = tri->eo3 * 4;
 
-      if (cx1 + eo1 < 0 ||
-          cx2 + eo2 < 0 ||
-          cx3 + eo3 < 0) {
-         /* the block is completely outside the triangle - nop */
-         LP_COUNT(nr_empty_4);
+   c[0] = c0;
+   c[1] = c1;
+   c[2] = c2;
+
+   for (j = 0; j < 3; j++) {
+      const int *step = tri->inputs.step[j];
+      const int cx = c[j] + eo[j];
+
+      /* Mask has bits set whenever we are outside any of the edges.
+       */
+      for (i = 0; i < 16; i++) {
+         int out = cx + step[i] * 4;
+         mask |= (out >> 31) & (1 << i);
       }
-      else {
-         int px = x + pos_table4[i][0];
-         int py = y + pos_table4[i][1];
-         /* Don't bother testing if the 4x4 block is entirely in/out of
-          * the triangle.  It's a little faster to do it in the jit code.
-          */
-         LP_COUNT(nr_non_empty_4);
-         do_block_4(rast_task, tri, px, py, cx1, cx2, cx3);
-      }
+   }
+
+   mask = ~mask & 0xffff;
+   while (mask) {
+      int i = ffs(mask) - 1;
+      int px = x + pos_table4[i][0];
+      int py = y + pos_table4[i][1];
+      int cx1 = c0 + tri->inputs.step[0][i] * 4;
+      int cx2 = c1 + tri->inputs.step[1][i] * 4;
+      int cx3 = c2 + tri->inputs.step[2][i] * 4;
+
+      mask &= ~(1 << i);
+
+      /* Don't bother testing if the 4x4 block is entirely in/out of
+       * the triangle.  It's a little faster to do it in the jit code.
+       */
+      LP_COUNT(nr_non_empty_4);
+      do_block_4(rast_task, tri, px, py, cx1, cx2, cx3);
    }
 }
 
@@ -199,53 +212,79 @@
 
    int x = rast_task->x;
    int y = rast_task->y;
-   unsigned i;
+   int ei[3], eo[3], c[3];
+   unsigned outmask, inmask, partial_mask;
+   unsigned i, j;
 
-   int c1 = tri->c1 + tri->dx12 * y - tri->dy12 * x;
-   int c2 = tri->c2 + tri->dx23 * y - tri->dy23 * x;
-   int c3 = tri->c3 + tri->dx31 * y - tri->dy31 * x;
+   c[0] = tri->c1 + tri->dx12 * y - tri->dy12 * x;
+   c[1] = tri->c2 + tri->dx23 * y - tri->dy23 * x;
+   c[2] = tri->c3 + tri->dx31 * y - tri->dy31 * x;
 
-   int ei1 = tri->ei1 * 16;
-   int ei2 = tri->ei2 * 16;
-   int ei3 = tri->ei3 * 16;
+   eo[0] = tri->eo1 * 16;
+   eo[1] = tri->eo2 * 16;
+   eo[2] = tri->eo3 * 16;
 
-   int eo1 = tri->eo1 * 16;
-   int eo2 = tri->eo2 * 16;
-   int eo3 = tri->eo3 * 16;
+   ei[0] = tri->ei1 * 16;
+   ei[1] = tri->ei2 * 16;
+   ei[2] = tri->ei3 * 16;
 
-   LP_DBG(DEBUG_RAST, "lp_rast_triangle\n");
+   outmask = 0;
+   inmask = 0xffff;
 
-   /* Walk over the tile to build a list of 4x4 pixel blocks which will
-    * be filled/shaded.  We do this at two granularities: 16x16 blocks
-    * and then 4x4 blocks.
+   for (j = 0; j < 3; j++) {
+      const int *step = tri->inputs.step[j];
+      const int cox = c[j] + eo[j];
+      const int cio = ei[j]- eo[j];
+
+      /* Outmask has bits set whenever we are outside any of the
+       * edges.
+       */
+      /* Inmask has bits set whenever we are inside all of the edges.
+       */
+      for (i = 0; i < 16; i++) {
+         int out = cox + step[i] * 16;
+         int in = out + cio;
+         outmask |= (out >> 31) & (1 << i);
+         inmask &= ~((in >> 31) & (1 << i));
+      }
+   }
+
+   assert((outmask & inmask) == 0);
+
+   if (outmask == 0xffff)
+      return;
+
+   /* Invert mask, so that bits are set whenever we are at least
+    * partially inside all of the edges:
     */
-   for (i = 0; i < 16; i++) {
-      int cx1 = c1 + (tri->inputs.step[0][i] * 16);
-      int cx2 = c2 + (tri->inputs.step[1][i] * 16);
-      int cx3 = c3 + (tri->inputs.step[2][i] * 16);
+   partial_mask = ~inmask & ~outmask & 0xffff;
 
-      if (cx1 + eo1 < 0 ||
-          cx2 + eo2 < 0 ||
-          cx3 + eo3 < 0) {
-         /* the block is completely outside the triangle - nop */
-         LP_COUNT(nr_empty_16);
-      }
-      else {
-         int px = x + pos_table16[i][0];
-         int py = y + pos_table16[i][1];
+   /* Iterate over partials:
+    */
+   while (partial_mask) {
+      int i = ffs(partial_mask) - 1;
+      int px = x + pos_table16[i][0];
+      int py = y + pos_table16[i][1];
+      int cx1 = c[0] + tri->inputs.step[0][i] * 16;
+      int cx2 = c[1] + tri->inputs.step[1][i] * 16;
+      int cx3 = c[2] + tri->inputs.step[2][i] * 16;
 
-         if (cx1 + ei1 > 0 &&
-             cx2 + ei2 > 0 &&
-             cx3 + ei3 > 0) {
-            /* the block is completely inside the triangle */
-            LP_COUNT(nr_fully_covered_16);
-            block_full_16(rast_task, tri, px, py);
-         }
-         else {
-            /* the block is partially in/out of the triangle */
-            LP_COUNT(nr_partially_covered_16);
-            do_block_16(rast_task, tri, px, py, cx1, cx2, cx3);
-         }
-      }
+      partial_mask &= ~(1 << i);
+
+      LP_COUNT(nr_partially_covered_16);
+      do_block_16(rast_task, tri, px, py, cx1, cx2, cx3);
+   }
+
+   /* Iterate over fulls: 
+    */
+   while (inmask) {
+      int i = ffs(inmask) - 1;
+      int px = x + pos_table16[i][0];
+      int py = y + pos_table16[i][1];
+
+      inmask &= ~(1 << i);
+
+      LP_COUNT(nr_fully_covered_16);
+      block_full_16(rast_task, tri, px, py);
    }
 }
diff --git a/src/gallium/drivers/llvmpipe/lp_scene_queue.c b/src/gallium/drivers/llvmpipe/lp_scene_queue.c
index 43d74e4..975db43 100644
--- a/src/gallium/drivers/llvmpipe/lp_scene_queue.c
+++ b/src/gallium/drivers/llvmpipe/lp_scene_queue.c
@@ -92,6 +92,8 @@
    struct scene_packet packet;
    enum pipe_error ret;
 
+   packet.scene = NULL;
+
    ret = util_ringbuffer_dequeue(queue->ring,
                                  &packet.header,
                                  sizeof packet / 4,
diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c
index 538492b..cb87366 100644
--- a/src/gallium/drivers/llvmpipe/lp_setup.c
+++ b/src/gallium/drivers/llvmpipe/lp_setup.c
@@ -251,6 +251,7 @@
    set_scene_state( setup, SETUP_FLUSHED );
 
    /* re-get scene pointer, may have a new scene after flushing */
+   (void) scene;
    scene = lp_setup_get_current_scene(setup);
 
    util_copy_framebuffer_state(&setup->fb, fb);
diff --git a/src/gallium/drivers/llvmpipe/lp_state.h b/src/gallium/drivers/llvmpipe/lp_state.h
index 8f68f12..9beba32 100644
--- a/src/gallium/drivers/llvmpipe/lp_state.h
+++ b/src/gallium/drivers/llvmpipe/lp_state.h
@@ -152,13 +152,16 @@
 void llvmpipe_delete_rasterizer_state(struct pipe_context *, void *);
 
 void llvmpipe_set_framebuffer_state( struct pipe_context *,
-			     const struct pipe_framebuffer_state * );
+                                     const struct pipe_framebuffer_state * );
 
 void llvmpipe_set_blend_color( struct pipe_context *pipe,
                                const struct pipe_blend_color *blend_color );
 
+void llvmpipe_set_stencil_ref( struct pipe_context *pipe,
+                               const struct pipe_stencil_ref *stencil_ref );
+
 void llvmpipe_set_clip_state( struct pipe_context *,
-			     const struct pipe_clip_state * );
+                              const struct pipe_clip_state * );
 
 void llvmpipe_set_constant_buffer(struct pipe_context *,
                                   uint shader, uint index,
diff --git a/src/gallium/drivers/llvmpipe/lp_state_blend.c b/src/gallium/drivers/llvmpipe/lp_state_blend.c
index 9b950e8..4ee2847 100644
--- a/src/gallium/drivers/llvmpipe/lp_state_blend.c
+++ b/src/gallium/drivers/llvmpipe/lp_state_blend.c
@@ -33,7 +33,7 @@
 
 #include "util/u_memory.h"
 #include "util/u_math.h"
-#include "util/u_debug_dump.h"
+#include "util/u_dump.h"
 #include "draw/draw_context.h"
 #include "lp_screen.h"
 #include "lp_context.h"
@@ -121,3 +121,24 @@
 {
    FREE( depth );
 }
+
+void llvmpipe_set_stencil_ref( struct pipe_context *pipe,
+                               const struct pipe_stencil_ref *stencil_ref )
+{
+   struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
+
+   if(!stencil_ref)
+      return;
+
+   if(memcmp(&llvmpipe->stencil_ref, stencil_ref, sizeof *stencil_ref) == 0)
+      return;
+
+   draw_flush(llvmpipe->draw);
+
+   memcpy(&llvmpipe->stencil_ref, stencil_ref, sizeof *stencil_ref);
+
+   /* not sure. want new flag? */
+   llvmpipe->dirty |= LP_NEW_DEPTH_STENCIL_ALPHA;
+}
+
+
diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.c b/src/gallium/drivers/llvmpipe/lp_state_fs.c
index 15c10d8..90dae3f 100644
--- a/src/gallium/drivers/llvmpipe/lp_state_fs.c
+++ b/src/gallium/drivers/llvmpipe/lp_state_fs.c
@@ -65,7 +65,7 @@
 #include "util/u_inlines.h"
 #include "util/u_memory.h"
 #include "util/u_format.h"
-#include "util/u_debug_dump.h"
+#include "util/u_dump.h"
 #include "os/os_time.h"
 #include "pipe/p_shader_tokens.h"
 #include "draw/draw_context.h"
@@ -861,49 +861,49 @@
 
       tgsi_dump(shader->base.tokens, 0);
       if(key->depth.enabled) {
-         debug_printf("depth.format = %s\n", pf_name(key->zsbuf_format));
-         debug_printf("depth.func = %s\n", debug_dump_func(key->depth.func, TRUE));
+         debug_printf("depth.format = %s\n", util_format_name(key->zsbuf_format));
+         debug_printf("depth.func = %s\n", util_dump_func(key->depth.func, TRUE));
          debug_printf("depth.writemask = %u\n", key->depth.writemask);
       }
       if(key->alpha.enabled) {
-         debug_printf("alpha.func = %s\n", debug_dump_func(key->alpha.func, TRUE));
+         debug_printf("alpha.func = %s\n", util_dump_func(key->alpha.func, TRUE));
          debug_printf("alpha.ref_value = %f\n", key->alpha.ref_value);
       }
       if(key->blend.logicop_enable) {
          debug_printf("blend.logicop_func = %u\n", key->blend.logicop_func);
       }
       else if(key->blend.rt[0].blend_enable) {
-         debug_printf("blend.rgb_func = %s\n",   debug_dump_blend_func  (key->blend.rt[0].rgb_func, TRUE));
-         debug_printf("rgb_src_factor = %s\n",   debug_dump_blend_factor(key->blend.rt[0].rgb_src_factor, TRUE));
-         debug_printf("rgb_dst_factor = %s\n",   debug_dump_blend_factor(key->blend.rt[0].rgb_dst_factor, TRUE));
-         debug_printf("alpha_func = %s\n",       debug_dump_blend_func  (key->blend.rt[0].alpha_func, TRUE));
-         debug_printf("alpha_src_factor = %s\n", debug_dump_blend_factor(key->blend.rt[0].alpha_src_factor, TRUE));
-         debug_printf("alpha_dst_factor = %s\n", debug_dump_blend_factor(key->blend.rt[0].alpha_dst_factor, TRUE));
+         debug_printf("blend.rgb_func = %s\n",   util_dump_blend_func  (key->blend.rt[0].rgb_func, TRUE));
+         debug_printf("rgb_src_factor = %s\n",   util_dump_blend_factor(key->blend.rt[0].rgb_src_factor, TRUE));
+         debug_printf("rgb_dst_factor = %s\n",   util_dump_blend_factor(key->blend.rt[0].rgb_dst_factor, TRUE));
+         debug_printf("alpha_func = %s\n",       util_dump_blend_func  (key->blend.rt[0].alpha_func, TRUE));
+         debug_printf("alpha_src_factor = %s\n", util_dump_blend_factor(key->blend.rt[0].alpha_src_factor, TRUE));
+         debug_printf("alpha_dst_factor = %s\n", util_dump_blend_factor(key->blend.rt[0].alpha_dst_factor, TRUE));
       }
       debug_printf("blend.colormask = 0x%x\n", key->blend.rt[0].colormask);
       for(i = 0; i < PIPE_MAX_SAMPLERS; ++i) {
          if(key->sampler[i].format) {
             debug_printf("sampler[%u] = \n", i);
             debug_printf("  .format = %s\n",
-                         pf_name(key->sampler[i].format));
+                         util_format_name(key->sampler[i].format));
             debug_printf("  .target = %s\n",
-                         debug_dump_tex_target(key->sampler[i].target, TRUE));
+                         util_dump_tex_target(key->sampler[i].target, TRUE));
             debug_printf("  .pot = %u %u %u\n",
                          key->sampler[i].pot_width,
                          key->sampler[i].pot_height,
                          key->sampler[i].pot_depth);
             debug_printf("  .wrap = %s %s %s\n",
-                         debug_dump_tex_wrap(key->sampler[i].wrap_s, TRUE),
-                         debug_dump_tex_wrap(key->sampler[i].wrap_t, TRUE),
-                         debug_dump_tex_wrap(key->sampler[i].wrap_r, TRUE));
+                         util_dump_tex_wrap(key->sampler[i].wrap_s, TRUE),
+                         util_dump_tex_wrap(key->sampler[i].wrap_t, TRUE),
+                         util_dump_tex_wrap(key->sampler[i].wrap_r, TRUE));
             debug_printf("  .min_img_filter = %s\n",
-                         debug_dump_tex_filter(key->sampler[i].min_img_filter, TRUE));
+                         util_dump_tex_filter(key->sampler[i].min_img_filter, TRUE));
             debug_printf("  .min_mip_filter = %s\n",
-                         debug_dump_tex_mipfilter(key->sampler[i].min_mip_filter, TRUE));
+                         util_dump_tex_mipfilter(key->sampler[i].min_mip_filter, TRUE));
             debug_printf("  .mag_img_filter = %s\n",
-                         debug_dump_tex_filter(key->sampler[i].mag_img_filter, TRUE));
+                         util_dump_tex_filter(key->sampler[i].mag_img_filter, TRUE));
             if(key->sampler[i].compare_mode != PIPE_TEX_COMPARE_NONE)
-               debug_printf("  .compare_func = %s\n", debug_dump_func(key->sampler[i].compare_func, TRUE));
+               debug_printf("  .compare_func = %s\n", util_dump_func(key->sampler[i].compare_func, TRUE));
             debug_printf("  .normalized_coords = %u\n", key->sampler[i].normalized_coords);
          }
       }
diff --git a/src/gallium/drivers/llvmpipe/lp_test.h b/src/gallium/drivers/llvmpipe/lp_test.h
index ca0f737..a9b9994 100644
--- a/src/gallium/drivers/llvmpipe/lp_test.h
+++ b/src/gallium/drivers/llvmpipe/lp_test.h
@@ -51,7 +51,7 @@
 #include "pipe/p_state.h"
 #include "util/u_format.h"
 #include "util/u_math.h"
-#include "util/u_debug_dump.h"
+#include "util/u_dump.h"
 
 #include "gallivm/lp_bld_type.h"
 
diff --git a/src/gallium/drivers/llvmpipe/lp_test_blend.c b/src/gallium/drivers/llvmpipe/lp_test_blend.c
index e49b705..5c9d418 100644
--- a/src/gallium/drivers/llvmpipe/lp_test_blend.c
+++ b/src/gallium/drivers/llvmpipe/lp_test_blend.c
@@ -109,12 +109,12 @@
 
    fprintf(fp,
            "%s\t%s\t%s\t%s\t%s\t%s\n",
-           debug_dump_blend_func(blend->rt[0].rgb_func, TRUE),
-           debug_dump_blend_factor(blend->rt[0].rgb_src_factor, TRUE),
-           debug_dump_blend_factor(blend->rt[0].rgb_dst_factor, TRUE),
-           debug_dump_blend_func(blend->rt[0].alpha_func, TRUE),
-           debug_dump_blend_factor(blend->rt[0].alpha_src_factor, TRUE),
-           debug_dump_blend_factor(blend->rt[0].alpha_dst_factor, TRUE));
+           util_dump_blend_func(blend->rt[0].rgb_func, TRUE),
+           util_dump_blend_factor(blend->rt[0].rgb_src_factor, TRUE),
+           util_dump_blend_factor(blend->rt[0].rgb_dst_factor, TRUE),
+           util_dump_blend_func(blend->rt[0].alpha_func, TRUE),
+           util_dump_blend_factor(blend->rt[0].alpha_src_factor, TRUE),
+           util_dump_blend_factor(blend->rt[0].alpha_dst_factor, TRUE));
 
    fflush(fp);
 }
@@ -136,12 +136,12 @@
 
    fprintf(fp,
            " %s=%s %s=%s %s=%s %s=%s %s=%s %s=%s",
-           "rgb_func",         debug_dump_blend_func(blend->rt[0].rgb_func, TRUE),
-           "rgb_src_factor",   debug_dump_blend_factor(blend->rt[0].rgb_src_factor, TRUE),
-           "rgb_dst_factor",   debug_dump_blend_factor(blend->rt[0].rgb_dst_factor, TRUE),
-           "alpha_func",       debug_dump_blend_func(blend->rt[0].alpha_func, TRUE),
-           "alpha_src_factor", debug_dump_blend_factor(blend->rt[0].alpha_src_factor, TRUE),
-           "alpha_dst_factor", debug_dump_blend_factor(blend->rt[0].alpha_dst_factor, TRUE));
+           "rgb_func",         util_dump_blend_func(blend->rt[0].rgb_func, TRUE),
+           "rgb_src_factor",   util_dump_blend_factor(blend->rt[0].rgb_src_factor, TRUE),
+           "rgb_dst_factor",   util_dump_blend_factor(blend->rt[0].rgb_dst_factor, TRUE),
+           "alpha_func",       util_dump_blend_func(blend->rt[0].alpha_func, TRUE),
+           "alpha_src_factor", util_dump_blend_factor(blend->rt[0].alpha_src_factor, TRUE),
+           "alpha_dst_factor", util_dump_blend_factor(blend->rt[0].alpha_dst_factor, TRUE));
 
    fprintf(fp, " ...\n");
    fflush(fp);
diff --git a/src/gallium/drivers/nouveau/nouveau_screen.c b/src/gallium/drivers/nouveau/nouveau_screen.c
index 156cb2d..81bc296 100644
--- a/src/gallium/drivers/nouveau/nouveau_screen.c
+++ b/src/gallium/drivers/nouveau/nouveau_screen.c
@@ -55,7 +55,7 @@
 {
 	struct nouveau_device *dev = nouveau_screen(pscreen)->device;
 	struct nouveau_bo *bo = NULL;
-	uint32_t flags = NOUVEAU_BO_MAP;
+	uint32_t flags = NOUVEAU_BO_MAP, tile_mode = 0, tile_flags = 0;
 	int ret;
 
 	if (usage & NOUVEAU_BUFFER_USAGE_TRANSFER)
@@ -77,13 +77,15 @@
 			flags |= NOUVEAU_BO_VRAM;
 
 		if (dev->chipset == 0x50 || dev->chipset >= 0x80) {
-			flags |= NOUVEAU_BO_TILED;
 			if (usage & NOUVEAU_BUFFER_USAGE_ZETA)
-				flags |= NOUVEAU_BO_ZTILE;
+				tile_flags = 0x2800;
+			else
+				tile_flags = 0x7000;
 		}
 	}
 
-	ret = nouveau_bo_new(dev, flags, alignment, size, &bo);
+	ret = nouveau_bo_new_tile(dev, flags, alignment, size,
+				  tile_mode, tile_flags, &bo);
 	if (ret)
 		return NULL;
 
diff --git a/src/gallium/drivers/nouveau/nouveau_stateobj.h b/src/gallium/drivers/nouveau/nouveau_stateobj.h
index e844f6a..5357e98 100644
--- a/src/gallium/drivers/nouveau/nouveau_stateobj.h
+++ b/src/gallium/drivers/nouveau/nouveau_stateobj.h
@@ -229,7 +229,6 @@
 static INLINE void
 so_emit(struct nouveau_channel *chan, struct nouveau_stateobj *so)
 {
-	struct nouveau_pushbuf *pb = chan->pushbuf;
 	unsigned nr, i;
 	int ret = 0;
 
@@ -260,7 +259,7 @@
 	for (i = 0; i < so->cur_reloc; i++) {
 		struct nouveau_stateobj_reloc *r = &so->reloc[i];
 
-		if ((ret = nouveau_pushbuf_emit_reloc(chan, pb->cur - nr +
+		if ((ret = nouveau_pushbuf_emit_reloc(chan, chan->cur - nr +
 						r->push_offset, r->bo, r->data,
 						0, r->flags, r->vor, r->tor))) {
 			debug_printf("so_emit failed reloc with error %d\n", ret);
@@ -272,7 +271,6 @@
 static INLINE void
 so_emit_reloc_markers(struct nouveau_channel *chan, struct nouveau_stateobj *so)
 {
-	struct nouveau_pushbuf *pb = chan->pushbuf;
 	struct nouveau_grobj *gr = NULL;
 	unsigned i;
 	int ret = 0;
@@ -318,8 +316,6 @@
 			debug_printf("OUT_RELOC failed %d\n", ret);
 			assert(0);
 		}
-
-		pb->remaining -= 2;
 	}
 }
 
diff --git a/src/gallium/drivers/nv30/nv30_context.h b/src/gallium/drivers/nv30/nv30_context.h
index b3b26f7..ca3d6ac 100644
--- a/src/gallium/drivers/nv30/nv30_context.h
+++ b/src/gallium/drivers/nv30/nv30_context.h
@@ -61,7 +61,8 @@
 	NV30_STATE_VTXBUF = 31,
 	NV30_STATE_VTXFMT = 32,
 	NV30_STATE_VTXATTR = 33,
-	NV30_STATE_MAX = 34
+	NV30_STATE_SR = 34,
+	NV30_STATE_MAX = 35
 };
 
 #include "nv30_screen.h"
@@ -79,6 +80,7 @@
 #define NV30_NEW_FRAGPROG	(1 << 10)
 #define NV30_NEW_ARRAYS		(1 << 11)
 #define NV30_NEW_UCP		(1 << 12)
+#define NV30_NEW_SR		(1 << 13)
 
 struct nv30_rasterizer_state {
 	struct pipe_rasterizer_state pipe;
@@ -129,6 +131,7 @@
 	struct nv30_zsa_state *zsa;
 	struct nv30_blend_state *blend;
 	struct pipe_blend_color blend_colour;
+	struct pipe_stencil_ref stencil_ref;
 	struct pipe_viewport_state viewport;
 	struct pipe_framebuffer_state framebuffer;
 	struct pipe_buffer *idxbuf;
@@ -194,6 +197,7 @@
 extern struct nv30_state_entry nv30_state_framebuffer;
 extern struct nv30_state_entry nv30_state_fragtex;
 extern struct nv30_state_entry nv30_state_vbo;
+extern struct nv30_state_entry nv30_state_sr;
 
 /* nv30_vbo.c */
 extern void nv30_draw_arrays(struct pipe_context *, unsigned mode,
diff --git a/src/gallium/drivers/nv30/nv30_fragtex.c b/src/gallium/drivers/nv30/nv30_fragtex.c
index 0cc3172..9f4a104 100644
--- a/src/gallium/drivers/nv30/nv30_fragtex.c
+++ b/src/gallium/drivers/nv30/nv30_fragtex.c
@@ -1,3 +1,5 @@
+#include "util/u_format.h"
+
 #include "nv30_context.h"
 #include "nouveau/nouveau_util.h"
 
@@ -50,7 +52,7 @@
 		tf++;
 	}
 
-	NOUVEAU_ERR("unknown texture format %s\n", pf_name(pipe_format));
+	NOUVEAU_ERR("unknown texture format %s\n", util_format_name(pipe_format));
 	return NULL;
 }
 
diff --git a/src/gallium/drivers/nv30/nv30_screen.c b/src/gallium/drivers/nv30/nv30_screen.c
index 8f9b26e..aef37d3 100644
--- a/src/gallium/drivers/nv30/nv30_screen.c
+++ b/src/gallium/drivers/nv30/nv30_screen.c
@@ -28,7 +28,7 @@
 {
 	switch (param) {
 	case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS:
-		return 16;
+		return 8;
 	case PIPE_CAP_NPOT_TEXTURES:
 		return 0;
 	case PIPE_CAP_TWO_SIDED_STENCIL:
@@ -64,6 +64,8 @@
 	case NOUVEAU_CAP_HW_VTXBUF:
 	case NOUVEAU_CAP_HW_IDXBUF:
 		return 1;
+	case PIPE_CAP_MAX_COMBINED_SAMPLERS:
+		return 16;
 	case PIPE_CAP_INDEP_BLEND_ENABLE:
 		return 0;
 	case PIPE_CAP_INDEP_BLEND_FUNC:
diff --git a/src/gallium/drivers/nv30/nv30_state.c b/src/gallium/drivers/nv30/nv30_state.c
index f775938..d911c80 100644
--- a/src/gallium/drivers/nv30/nv30_state.c
+++ b/src/gallium/drivers/nv30/nv30_state.c
@@ -139,13 +139,13 @@
 
 	ps->en = 0;
 
-	if (cso->max_anisotropy >= 8.0) {
+	if (cso->max_anisotropy >= 8) {
 		ps->en |= NV34TCL_TX_ENABLE_ANISO_8X;
 	} else
-	if (cso->max_anisotropy >= 4.0) {
+	if (cso->max_anisotropy >= 4) {
 		ps->en |= NV34TCL_TX_ENABLE_ANISO_4X;
 	} else
-	if (cso->max_anisotropy >= 2.0) {
+	if (cso->max_anisotropy >= 2) {
 		ps->en |= NV34TCL_TX_ENABLE_ANISO_2X;
 	}
 
@@ -435,7 +435,7 @@
 {
 	struct nv30_context *nv30 = nv30_context(pipe);
 	struct nv30_zsa_state *zsaso = CALLOC(1, sizeof(*zsaso));
-	struct nouveau_stateobj *so = so_new(5, 21, 0);
+	struct nouveau_stateobj *so = so_new(6, 20, 0);
 	struct nouveau_grobj *rankine = nv30->screen->rankine;
 
 	so_method(so, rankine, NV34TCL_DEPTH_FUNC, 3);
@@ -449,11 +449,11 @@
 	so_data  (so, float_to_ubyte(cso->alpha.ref_value));
 
 	if (cso->stencil[0].enabled) {
-		so_method(so, rankine, NV34TCL_STENCIL_FRONT_ENABLE, 8);
+		so_method(so, rankine, NV34TCL_STENCIL_FRONT_ENABLE, 3);
 		so_data  (so, cso->stencil[0].enabled ? 1 : 0);
 		so_data  (so, cso->stencil[0].writemask);
 		so_data  (so, nvgl_comparison_op(cso->stencil[0].func));
-		so_data  (so, cso->stencil[0].ref_value);
+		so_method(so, rankine, NV34TCL_STENCIL_FRONT_FUNC_MASK, 4);
 		so_data  (so, cso->stencil[0].valuemask);
 		so_data  (so, nvgl_stencil_op(cso->stencil[0].fail_op));
 		so_data  (so, nvgl_stencil_op(cso->stencil[0].zfail_op));
@@ -464,11 +464,11 @@
 	}
 
 	if (cso->stencil[1].enabled) {
-		so_method(so, rankine, NV34TCL_STENCIL_BACK_ENABLE, 8);
+		so_method(so, rankine, NV34TCL_STENCIL_BACK_ENABLE, 3);
 		so_data  (so, cso->stencil[1].enabled ? 1 : 0);
 		so_data  (so, cso->stencil[1].writemask);
 		so_data  (so, nvgl_comparison_op(cso->stencil[1].func));
-		so_data  (so, cso->stencil[1].ref_value);
+		so_method(so, rankine, NV34TCL_STENCIL_BACK_FUNC_MASK, 4);
 		so_data  (so, cso->stencil[1].valuemask);
 		so_data  (so, nvgl_stencil_op(cso->stencil[1].fail_op));
 		so_data  (so, nvgl_stencil_op(cso->stencil[1].zfail_op));
@@ -583,6 +583,16 @@
 }
 
 static void
+nv30_set_stencil_ref(struct pipe_context *pipe,
+		     const struct pipe_stencil_ref *sr)
+{
+	struct nv30_context *nv30 = nv30_context(pipe);
+
+	nv30->stencil_ref = *sr;
+	nv30->dirty |= NV30_NEW_SR;
+}
+
+static void
 nv30_set_clip_state(struct pipe_context *pipe,
 		    const struct pipe_clip_state *clip)
 {
@@ -704,6 +714,7 @@
 	nv30->pipe.delete_fs_state = nv30_fp_state_delete;
 
 	nv30->pipe.set_blend_color = nv30_set_blend_color;
+        nv30->pipe.set_stencil_ref = nv30_set_stencil_ref;
 	nv30->pipe.set_clip_state = nv30_set_clip_state;
 	nv30->pipe.set_constant_buffer = nv30_set_constant_buffer;
 	nv30->pipe.set_framebuffer_state = nv30_set_framebuffer_state;
diff --git a/src/gallium/drivers/nv30/nv30_state_emit.c b/src/gallium/drivers/nv30/nv30_state_emit.c
index d9650f6..deefe7f 100644
--- a/src/gallium/drivers/nv30/nv30_state_emit.c
+++ b/src/gallium/drivers/nv30/nv30_state_emit.c
@@ -12,6 +12,7 @@
 	&nv30_state_blend,
 	&nv30_state_blend_colour,
 	&nv30_state_zsa,
+	&nv30_state_sr,
 	&nv30_state_viewport,
 	&nv30_state_vbo,
 	NULL
diff --git a/src/gallium/drivers/nv30/nv30_state_zsa.c b/src/gallium/drivers/nv30/nv30_state_zsa.c
index 0940b72..88cd74f 100644
--- a/src/gallium/drivers/nv30/nv30_state_zsa.c
+++ b/src/gallium/drivers/nv30/nv30_state_zsa.c
@@ -15,3 +15,27 @@
 		.hw = NV30_STATE_ZSA
 	}
 };
+
+static boolean
+nv30_state_sr_validate(struct nv30_context *nv30)
+{
+	struct nouveau_stateobj *so = so_new(2, 2, 0);
+	struct pipe_stencil_ref *sr = &nv30->stencil_ref;
+
+	so_method(so, nv30->screen->rankine, NV34TCL_STENCIL_FRONT_FUNC_REF, 1);
+	so_data  (so, sr->ref_value[0]);
+	so_method(so, nv30->screen->rankine, NV34TCL_STENCIL_BACK_FUNC_REF, 1);
+	so_data  (so, sr->ref_value[1]);
+
+	so_ref(so, &nv30->state.hw[NV30_STATE_SR]);
+	so_ref(NULL, &so);
+	return TRUE;
+}
+
+struct nv30_state_entry nv30_state_sr = {
+	.validate = nv30_state_sr_validate,
+	.dirty = {
+		.pipe = NV30_NEW_SR,
+		.hw = NV30_STATE_SR
+	}
+};
diff --git a/src/gallium/drivers/nv30/nv30_vbo.c b/src/gallium/drivers/nv30/nv30_vbo.c
index a83ddf1..e48823a 100644
--- a/src/gallium/drivers/nv30/nv30_vbo.c
+++ b/src/gallium/drivers/nv30/nv30_vbo.c
@@ -1,6 +1,7 @@
 #include "pipe/p_context.h"
 #include "pipe/p_state.h"
 #include "util/u_inlines.h"
+#include "util/u_format.h"
 
 #include "nv30_context.h"
 #include "nv30_state.h"
@@ -34,7 +35,7 @@
 		*fmt = NV34TCL_VTXFMT_TYPE_USHORT;
 		break;
 	default:
-		NOUVEAU_ERR("Unknown format %s\n", pf_name(pipe));
+		NOUVEAU_ERR("Unknown format %s\n", util_format_name(pipe));
 		return 1;
 	}
 
@@ -60,7 +61,7 @@
 		*ncomp = 4;
 		break;
 	default:
-		NOUVEAU_ERR("Unknown format %s\n", pf_name(pipe));
+		NOUVEAU_ERR("Unknown format %s\n", util_format_name(pipe));
 		return 1;
 	}
 
@@ -185,7 +186,7 @@
 
 		nv30_state_emit(nv30);
 
-		vc = nouveau_vbuf_split(chan->pushbuf->remaining, 6, 256,
+		vc = nouveau_vbuf_split(AVAIL_RING(chan), 6, 256,
 					mode, start, count, &restart);
 		if (!vc) {
 			FIRE_RING(chan);
@@ -239,7 +240,7 @@
 
 		nv30_state_emit(nv30);
 
-		vc = nouveau_vbuf_split(chan->pushbuf->remaining, 6, 2,
+		vc = nouveau_vbuf_split(AVAIL_RING(chan), 6, 2,
 					mode, start, count, &restart);
 		if (vc == 0) {
 			FIRE_RING(chan);
@@ -290,7 +291,7 @@
 
 		nv30_state_emit(nv30);
 
-		vc = nouveau_vbuf_split(chan->pushbuf->remaining, 6, 2,
+		vc = nouveau_vbuf_split(AVAIL_RING(chan), 6, 2,
 					mode, start, count, &restart);
 		if (vc == 0) {
 			FIRE_RING(chan);
@@ -341,7 +342,7 @@
 
 		nv30_state_emit(nv30);
 
-		vc = nouveau_vbuf_split(chan->pushbuf->remaining, 5, 1,
+		vc = nouveau_vbuf_split(AVAIL_RING(chan), 5, 1,
 					mode, start, count, &restart);
 		if (vc == 0) {
 			FIRE_RING(chan);
@@ -417,7 +418,7 @@
 
 		nv30_state_emit(nv30);
 
-		vc = nouveau_vbuf_split(chan->pushbuf->remaining, 6, 256,
+		vc = nouveau_vbuf_split(AVAIL_RING(chan), 6, 256,
 					mode, start, count, &restart);
 		if (!vc) {
 			FIRE_RING(chan);
diff --git a/src/gallium/drivers/nv40/nv40_context.h b/src/gallium/drivers/nv40/nv40_context.h
index 958a48f..4861924 100644
--- a/src/gallium/drivers/nv40/nv40_context.h
+++ b/src/gallium/drivers/nv40/nv40_context.h
@@ -61,7 +61,8 @@
 	NV40_STATE_VTXBUF = 31,
 	NV40_STATE_VTXFMT = 32,
 	NV40_STATE_VTXATTR = 33,
-	NV40_STATE_MAX = 34
+	NV40_STATE_SR = 34,
+	NV40_STATE_MAX = 35
 };
 
 #include "nv40_screen.h"
@@ -79,6 +80,7 @@
 #define NV40_NEW_FRAGPROG	(1 << 10)
 #define NV40_NEW_ARRAYS		(1 << 11)
 #define NV40_NEW_UCP		(1 << 12)
+#define NV40_NEW_SR		(1 << 13)
 
 struct nv40_rasterizer_state {
 	struct pipe_rasterizer_state pipe;
@@ -144,6 +146,7 @@
 	struct nv40_zsa_state *zsa;
 	struct nv40_blend_state *blend;
 	struct pipe_blend_color blend_colour;
+	struct pipe_stencil_ref stencil_ref;
 	struct pipe_viewport_state viewport;
 	struct pipe_framebuffer_state framebuffer;
 	struct pipe_buffer *idxbuf;
@@ -215,6 +218,7 @@
 extern struct nv40_state_entry nv40_state_fragtex;
 extern struct nv40_state_entry nv40_state_vbo;
 extern struct nv40_state_entry nv40_state_vtxfmt;
+extern struct nv40_state_entry nv40_state_sr;
 
 /* nv40_vbo.c */
 extern void nv40_draw_arrays(struct pipe_context *, unsigned mode,
diff --git a/src/gallium/drivers/nv40/nv40_draw.c b/src/gallium/drivers/nv40/nv40_draw.c
index 60ab49f..48bd84d 100644
--- a/src/gallium/drivers/nv40/nv40_draw.c
+++ b/src/gallium/drivers/nv40/nv40_draw.c
@@ -88,12 +88,11 @@
 
 	struct nv40_screen *screen = nv40->screen;
 	struct nouveau_channel *chan = screen->base.channel;
-	struct nouveau_pushbuf *pb = chan->pushbuf;
 	struct nouveau_grobj *curie = screen->curie;
 	unsigned i;
 
 	/* Ensure there's room for 4xfloat32 + potentially 3 begin/end */
-	if (pb->remaining < ((count * 20) + 6)) {
+	if (AVAIL_RING(chan) < ((count * 20) + 6)) {
 		if (rs->prim != NV40TCL_BEGIN_END_STOP) {
 			NOUVEAU_ERR("AIII, missed flush\n");
 			assert(0);
@@ -121,7 +120,7 @@
 	/* If it's likely we'll need to empty the push buffer soon, finish
 	 * off the primitive now.
 	 */
-	if (pb->remaining < ((count * 20) + 6)) {
+	if (AVAIL_RING(chan) < ((count * 20) + 6)) {
 		BEGIN_RING(chan, curie, NV40TCL_BEGIN_END, 1);
 		OUT_RING  (chan, NV40TCL_BEGIN_END_STOP);
 		rs->prim = NV40TCL_BEGIN_END_STOP;
diff --git a/src/gallium/drivers/nv40/nv40_fragtex.c b/src/gallium/drivers/nv40/nv40_fragtex.c
index aad9198..7a28d57 100644
--- a/src/gallium/drivers/nv40/nv40_fragtex.c
+++ b/src/gallium/drivers/nv40/nv40_fragtex.c
@@ -1,3 +1,5 @@
+#include "util/u_format.h"
+
 #include "nv40_context.h"
 
 #define _(m,tf,ts0x,ts0y,ts0z,ts0w,ts1x,ts1y,ts1z,ts1w,sx,sy,sz,sw)            \
@@ -53,7 +55,7 @@
 		tf++;
 	}
 
-	NOUVEAU_ERR("unknown texture format %s\n", pf_name(pipe_format));
+	NOUVEAU_ERR("unknown texture format %s\n", util_format_name(pipe_format));
 	return NULL;
 }
 
diff --git a/src/gallium/drivers/nv40/nv40_screen.c b/src/gallium/drivers/nv40/nv40_screen.c
index 001147e..edee4b9 100644
--- a/src/gallium/drivers/nv40/nv40_screen.c
+++ b/src/gallium/drivers/nv40/nv40_screen.c
@@ -62,6 +62,8 @@
 	case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
 	case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
 		return 0;
+	case PIPE_CAP_MAX_COMBINED_SAMPLERS:
+		return 16;
 	default:
 		NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param);
 		return 0;
diff --git a/src/gallium/drivers/nv40/nv40_state.c b/src/gallium/drivers/nv40/nv40_state.c
index 51b40e5..4f28675 100644
--- a/src/gallium/drivers/nv40/nv40_state.c
+++ b/src/gallium/drivers/nv40/nv40_state.c
@@ -132,26 +132,26 @@
 		    (wrap_mode(cso->wrap_r) << NV40TCL_TEX_WRAP_R_SHIFT));
 
 	ps->en = 0;
-	if (cso->max_anisotropy >= 2.0) {
+	if (cso->max_anisotropy >= 2) {
 		/* no idea, binary driver sets it, works without it.. meh.. */
 		ps->wrap |= (1 << 5);
 
-		if (cso->max_anisotropy >= 16.0) {
+		if (cso->max_anisotropy >= 16) {
 			ps->en |= NV40TCL_TEX_ENABLE_ANISO_16X;
 		} else
-		if (cso->max_anisotropy >= 12.0) {
+		if (cso->max_anisotropy >= 12) {
 			ps->en |= NV40TCL_TEX_ENABLE_ANISO_12X;
 		} else
-		if (cso->max_anisotropy >= 10.0) {
+		if (cso->max_anisotropy >= 10) {
 			ps->en |= NV40TCL_TEX_ENABLE_ANISO_10X;
 		} else
-		if (cso->max_anisotropy >= 8.0) {
+		if (cso->max_anisotropy >= 8) {
 			ps->en |= NV40TCL_TEX_ENABLE_ANISO_8X;
 		} else
-		if (cso->max_anisotropy >= 6.0) {
+		if (cso->max_anisotropy >= 6) {
 			ps->en |= NV40TCL_TEX_ENABLE_ANISO_6X;
 		} else
-		if (cso->max_anisotropy >= 4.0) {
+		if (cso->max_anisotropy >= 4) {
 			ps->en |= NV40TCL_TEX_ENABLE_ANISO_4X;
 		} else {
 			ps->en |= NV40TCL_TEX_ENABLE_ANISO_2X;
@@ -310,7 +310,7 @@
 {
 	struct nv40_context *nv40 = nv40_context(pipe);
 	struct nv40_rasterizer_state *rsso = CALLOC(1, sizeof(*rsso));
-	struct nouveau_stateobj *so = so_new(8, 18, 0);
+	struct nouveau_stateobj *so = so_new(9, 19, 0);
 	struct nouveau_grobj *curie = nv40->screen->curie;
 
 	/*XXX: ignored:
@@ -445,7 +445,7 @@
 {
 	struct nv40_context *nv40 = nv40_context(pipe);
 	struct nv40_zsa_state *zsaso = CALLOC(1, sizeof(*zsaso));
-	struct nouveau_stateobj *so = so_new(4, 21, 0);
+	struct nouveau_stateobj *so = so_new(6, 20, 0);
 	struct nouveau_grobj *curie = nv40->screen->curie;
 
 	so_method(so, curie, NV40TCL_DEPTH_FUNC, 3);
@@ -459,11 +459,11 @@
 	so_data  (so, float_to_ubyte(cso->alpha.ref_value));
 
 	if (cso->stencil[0].enabled) {
-		so_method(so, curie, NV40TCL_STENCIL_FRONT_ENABLE, 8);
+		so_method(so, curie, NV40TCL_STENCIL_FRONT_ENABLE, 3);
 		so_data  (so, cso->stencil[0].enabled ? 1 : 0);
 		so_data  (so, cso->stencil[0].writemask);
 		so_data  (so, nvgl_comparison_op(cso->stencil[0].func));
-		so_data  (so, cso->stencil[0].ref_value);
+		so_method(so, curie, NV40TCL_STENCIL_FRONT_FUNC_MASK, 4);
 		so_data  (so, cso->stencil[0].valuemask);
 		so_data  (so, nvgl_stencil_op(cso->stencil[0].fail_op));
 		so_data  (so, nvgl_stencil_op(cso->stencil[0].zfail_op));
@@ -474,11 +474,11 @@
 	}
 
 	if (cso->stencil[1].enabled) {
-		so_method(so, curie, NV40TCL_STENCIL_BACK_ENABLE, 8);
+		so_method(so, curie, NV40TCL_STENCIL_BACK_ENABLE, 3);
 		so_data  (so, cso->stencil[1].enabled ? 1 : 0);
 		so_data  (so, cso->stencil[1].writemask);
 		so_data  (so, nvgl_comparison_op(cso->stencil[1].func));
-		so_data  (so, cso->stencil[1].ref_value);
+		so_method(so, curie, NV40TCL_STENCIL_BACK_FUNC_MASK, 4);
 		so_data  (so, cso->stencil[1].valuemask);
 		so_data  (so, nvgl_stencil_op(cso->stencil[1].fail_op));
 		so_data  (so, nvgl_stencil_op(cso->stencil[1].zfail_op));
@@ -592,6 +592,16 @@
 	nv40->dirty |= NV40_NEW_BCOL;
 }
 
+ static void
+nv40_set_stencil_ref(struct pipe_context *pipe,
+		     const struct pipe_stencil_ref *sr)
+{
+	struct nv40_context *nv40 = nv40_context(pipe);
+
+	nv40->stencil_ref = *sr;
+	nv40->dirty |= NV40_NEW_SR;
+}
+
 static void
 nv40_set_clip_state(struct pipe_context *pipe,
 		    const struct pipe_clip_state *clip)
@@ -719,6 +729,7 @@
 	nv40->pipe.delete_fs_state = nv40_fp_state_delete;
 
 	nv40->pipe.set_blend_color = nv40_set_blend_color;
+        nv40->pipe.set_stencil_ref = nv40_set_stencil_ref;
 	nv40->pipe.set_clip_state = nv40_set_clip_state;
 	nv40->pipe.set_constant_buffer = nv40_set_constant_buffer;
 	nv40->pipe.set_framebuffer_state = nv40_set_framebuffer_state;
diff --git a/src/gallium/drivers/nv40/nv40_state_emit.c b/src/gallium/drivers/nv40/nv40_state_emit.c
index 1c4007a..8990f30 100644
--- a/src/gallium/drivers/nv40/nv40_state_emit.c
+++ b/src/gallium/drivers/nv40/nv40_state_emit.c
@@ -13,6 +13,7 @@
 	&nv40_state_blend,
 	&nv40_state_blend_colour,
 	&nv40_state_zsa,
+	&nv40_state_sr,
 	&nv40_state_viewport,
 	&nv40_state_vbo,
 	NULL
@@ -29,6 +30,7 @@
 	&nv40_state_blend,
 	&nv40_state_blend_colour,
 	&nv40_state_zsa,
+	&nv40_state_sr,
 	&nv40_state_viewport,
 	&nv40_state_vtxfmt,
 	NULL
diff --git a/src/gallium/drivers/nv40/nv40_state_zsa.c b/src/gallium/drivers/nv40/nv40_state_zsa.c
index fb76067..9cbe7da 100644
--- a/src/gallium/drivers/nv40/nv40_state_zsa.c
+++ b/src/gallium/drivers/nv40/nv40_state_zsa.c
@@ -15,3 +15,27 @@
 		.hw = NV40_STATE_ZSA
 	}
 };
+
+static boolean
+nv40_state_sr_validate(struct nv40_context *nv40)
+{
+	struct nouveau_stateobj *so = so_new(2, 2, 0);
+	struct pipe_stencil_ref *sr = &nv40->stencil_ref;
+
+	so_method(so, nv40->screen->curie, NV40TCL_STENCIL_FRONT_FUNC_REF, 1);
+	so_data  (so, sr->ref_value[0]);
+	so_method(so, nv40->screen->curie, NV40TCL_STENCIL_BACK_FUNC_REF, 1);
+	so_data  (so, sr->ref_value[1]);
+
+	so_ref(so, &nv40->state.hw[NV40_STATE_SR]);
+	so_ref(NULL, &so);
+	return TRUE;
+}
+
+struct nv40_state_entry nv40_state_sr = {
+	.validate = nv40_state_sr_validate,
+	.dirty = {
+		.pipe = NV40_NEW_SR,
+		.hw = NV40_STATE_SR
+	}
+};
diff --git a/src/gallium/drivers/nv40/nv40_vbo.c b/src/gallium/drivers/nv40/nv40_vbo.c
index 1e14edc..7812460 100644
--- a/src/gallium/drivers/nv40/nv40_vbo.c
+++ b/src/gallium/drivers/nv40/nv40_vbo.c
@@ -1,6 +1,7 @@
 #include "pipe/p_context.h"
 #include "pipe/p_state.h"
 #include "util/u_inlines.h"
+#include "util/u_format.h"
 
 #include "nv40_context.h"
 #include "nv40_state.h"
@@ -34,7 +35,7 @@
 		*fmt = NV40TCL_VTXFMT_TYPE_USHORT;
 		break;
 	default:
-		NOUVEAU_ERR("Unknown format %s\n", pf_name(pipe));
+		NOUVEAU_ERR("Unknown format %s\n", util_format_name(pipe));
 		return 1;
 	}
 
@@ -60,7 +61,7 @@
 		*ncomp = 4;
 		break;
 	default:
-		NOUVEAU_ERR("Unknown format %s\n", pf_name(pipe));
+		NOUVEAU_ERR("Unknown format %s\n", util_format_name(pipe));
 		return 1;
 	}
 
@@ -186,7 +187,7 @@
 
 		nv40_state_emit(nv40);
 
-		vc = nouveau_vbuf_split(chan->pushbuf->remaining, 6, 256,
+		vc = nouveau_vbuf_split(AVAIL_RING(chan), 6, 256,
 					mode, start, count, &restart);
 		if (!vc) {
 			FIRE_RING(chan);
@@ -240,7 +241,7 @@
 
 		nv40_state_emit(nv40);
 
-		vc = nouveau_vbuf_split(chan->pushbuf->remaining, 6, 2,
+		vc = nouveau_vbuf_split(AVAIL_RING(chan), 6, 2,
 					mode, start, count, &restart);
 		if (vc == 0) {
 			FIRE_RING(chan);
@@ -291,7 +292,7 @@
 
 		nv40_state_emit(nv40);
 
-		vc = nouveau_vbuf_split(chan->pushbuf->remaining, 6, 2,
+		vc = nouveau_vbuf_split(AVAIL_RING(chan), 6, 2,
 					mode, start, count, &restart);
 		if (vc == 0) {
 			FIRE_RING(chan);
@@ -342,7 +343,7 @@
 
 		nv40_state_emit(nv40);
 
-		vc = nouveau_vbuf_split(chan->pushbuf->remaining, 5, 1,
+		vc = nouveau_vbuf_split(AVAIL_RING(chan), 5, 1,
 					mode, start, count, &restart);
 		if (vc == 0) {
 			FIRE_RING(chan);
@@ -418,7 +419,7 @@
 
 		nv40_state_emit(nv40);
 
-		vc = nouveau_vbuf_split(chan->pushbuf->remaining, 6, 256,
+		vc = nouveau_vbuf_split(AVAIL_RING(chan), 6, 256,
 					mode, start, count, &restart);
 		if (!vc) {
 			FIRE_RING(chan);
diff --git a/src/gallium/drivers/nv50/nv50_context.h b/src/gallium/drivers/nv50/nv50_context.h
index 14cef4c..b4de3e2 100644
--- a/src/gallium/drivers/nv50/nv50_context.h
+++ b/src/gallium/drivers/nv50/nv50_context.h
@@ -50,6 +50,7 @@
 #define NV50_NEW_ARRAYS		(1 << 14)
 #define NV50_NEW_SAMPLER	(1 << 15)
 #define NV50_NEW_TEXTURE	(1 << 16)
+#define NV50_NEW_STENCIL_REF	(1 << 17)
 
 struct nv50_blend_stateobj {
 	struct pipe_blend_state pipe;
@@ -120,6 +121,7 @@
 	struct nouveau_stateobj *blend;
 	struct nouveau_stateobj *blend_colour;
 	struct nouveau_stateobj *zsa;
+	struct nouveau_stateobj *stencil_ref;
 	struct nouveau_stateobj *rast;
 	struct nouveau_stateobj *stipple;
 	struct nouveau_stateobj *scissor;
@@ -155,6 +157,7 @@
 	struct nv50_zsa_stateobj *zsa;
 	struct nv50_rasterizer_stateobj *rasterizer;
 	struct pipe_blend_color blend_colour;
+	struct pipe_stencil_ref stencil_ref;
 	struct pipe_poly_stipple stipple;
 	struct pipe_scissor_state scissor;
 	struct pipe_viewport_state viewport;
diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c
index 8c4478e..2232461 100644
--- a/src/gallium/drivers/nv50/nv50_screen.c
+++ b/src/gallium/drivers/nv50/nv50_screen.c
@@ -134,7 +134,7 @@
 	case NOUVEAU_CAP_HW_VTXBUF:
 		return 1;
 	case NOUVEAU_CAP_HW_IDXBUF:
-		return 0;
+		return 1;
 	case PIPE_CAP_INDEP_BLEND_ENABLE:
 		return 1;
 	case PIPE_CAP_INDEP_BLEND_FUNC:
diff --git a/src/gallium/drivers/nv50/nv50_state.c b/src/gallium/drivers/nv50/nv50_state.c
index 7c531b5..7d30490 100644
--- a/src/gallium/drivers/nv50/nv50_state.c
+++ b/src/gallium/drivers/nv50/nv50_state.c
@@ -202,18 +202,18 @@
 		break;
 	}
 
-	if (cso->max_anisotropy >= 16.0)
+	if (cso->max_anisotropy >= 16)
 		tsc[0] |= (7 << 20);
 	else
-	if (cso->max_anisotropy >= 12.0)
+	if (cso->max_anisotropy >= 12)
 		tsc[0] |= (6 << 20);
 	else {
-		tsc[0] |= (int)(cso->max_anisotropy * 0.5f) << 20;
+		tsc[0] |= (cso->max_anisotropy >> 1) << 20;
 
-		if (cso->max_anisotropy >= 4.0)
+		if (cso->max_anisotropy >= 4)
 			tsc[1] |= NV50TSC_1_1_UNKN_ANISO_35;
 		else
-		if (cso->max_anisotropy >= 2.0)
+		if (cso->max_anisotropy >= 2)
 			tsc[1] |= NV50TSC_1_1_UNKN_ANISO_15;
 	}
 
@@ -447,7 +447,7 @@
 {
 	struct nouveau_grobj *tesla = nv50_context(pipe)->screen->tesla;
 	struct nv50_zsa_stateobj *zsa = CALLOC_STRUCT(nv50_zsa_stateobj);
-	struct nouveau_stateobj *so = so_new(8, 22, 0);
+	struct nouveau_stateobj *so = so_new(9, 21, 0);
 
 	so_method(so, tesla, NV50TCL_DEPTH_WRITE_ENABLE, 1);
 	so_data  (so, cso->depth.writemask ? 1 : 0);
@@ -462,13 +462,13 @@
 	}
 
 	if (cso->stencil[0].enabled) {
-		so_method(so, tesla, NV50TCL_STENCIL_FRONT_ENABLE, 8);
+		so_method(so, tesla, NV50TCL_STENCIL_FRONT_ENABLE, 5);
 		so_data  (so, 1);
 		so_data  (so, nvgl_stencil_op(cso->stencil[0].fail_op));
 		so_data  (so, nvgl_stencil_op(cso->stencil[0].zfail_op));
 		so_data  (so, nvgl_stencil_op(cso->stencil[0].zpass_op));
 		so_data  (so, nvgl_comparison_op(cso->stencil[0].func));
-		so_data  (so, cso->stencil[0].ref_value);
+		so_method(so, tesla, NV50TCL_STENCIL_FRONT_MASK, 2);
 		so_data  (so, cso->stencil[0].writemask);
 		so_data  (so, cso->stencil[0].valuemask);
 	} else {
@@ -483,8 +483,7 @@
 		so_data  (so, nvgl_stencil_op(cso->stencil[1].zfail_op));
 		so_data  (so, nvgl_stencil_op(cso->stencil[1].zpass_op));
 		so_data  (so, nvgl_comparison_op(cso->stencil[1].func));
-		so_method(so, tesla, NV50TCL_STENCIL_BACK_FUNC_REF, 3);
-		so_data  (so, cso->stencil[1].ref_value);
+		so_method(so, tesla, NV50TCL_STENCIL_BACK_MASK, 2);
 		so_data  (so, cso->stencil[1].writemask);
 		so_data  (so, cso->stencil[1].valuemask);
 	} else {
@@ -633,6 +632,16 @@
 	nv50->dirty |= NV50_NEW_BLEND_COLOUR;
 }
 
+ static void
+nv50_set_stencil_ref(struct pipe_context *pipe,
+		     const struct pipe_stencil_ref *sr)
+{
+	struct nv50_context *nv50 = nv50_context(pipe);
+
+	nv50->stencil_ref = *sr;
+	nv50->dirty |= NV50_NEW_STENCIL_REF;
+}
+
 static void
 nv50_set_clip_state(struct pipe_context *pipe,
 		    const struct pipe_clip_state *clip)
@@ -761,6 +770,7 @@
 	nv50->pipe.delete_gs_state = nv50_gp_state_delete;
 
 	nv50->pipe.set_blend_color = nv50_set_blend_color;
+        nv50->pipe.set_stencil_ref = nv50_set_stencil_ref;
 	nv50->pipe.set_clip_state = nv50_set_clip_state;
 	nv50->pipe.set_constant_buffer = nv50_set_constant_buffer;
 	nv50->pipe.set_framebuffer_state = nv50_set_framebuffer_state;
diff --git a/src/gallium/drivers/nv50/nv50_state_validate.c b/src/gallium/drivers/nv50/nv50_state_validate.c
index ee28fa6..efab94c 100644
--- a/src/gallium/drivers/nv50/nv50_state_validate.c
+++ b/src/gallium/drivers/nv50/nv50_state_validate.c
@@ -20,6 +20,8 @@
  * SOFTWARE.
  */
 
+#include "util/u_format.h"
+
 #include "nv50_context.h"
 #include "nouveau/nouveau_stateobj.h"
 
@@ -79,7 +81,7 @@
 		NV50_CBUF_FORMAT_CASE(R16G16_UNORM);
 		default:
 			NOUVEAU_ERR("AIIII unknown format %s\n",
-				    pf_name(fb->cbufs[i]->format));
+			            util_format_name(fb->cbufs[i]->format));
 			so_data(so, NV50TCL_RT_FORMAT_X8R8G8B8_UNORM);
 			break;
 		}
@@ -116,7 +118,7 @@
 		NV50_ZETA_FORMAT_CASE(Z32_FLOAT);
 		default:
 			NOUVEAU_ERR("AIIII unknown format %s\n",
-				    pf_name(fb->zsbuf->format));
+			            util_format_name(fb->zsbuf->format));
 			so_data(so, NV50TCL_ZETA_FORMAT_S8Z24_UNORM);
 			break;
 		}
@@ -205,6 +207,8 @@
 			nv50->state.dirty |= NV50_NEW_RASTERIZER;
 		if (nv50->state.blend_colour)
 			nv50->state.dirty |= NV50_NEW_BLEND_COLOUR;
+		if (nv50->state.stencil_ref)
+			nv50->state.dirty |= NV50_NEW_STENCIL_REF;
 		if (nv50->state.stipple)
 			nv50->state.dirty |= NV50_NEW_STIPPLE;
 		if (nv50->state.scissor)
@@ -242,6 +246,8 @@
 		so_emit(chan, nv50->state.rast);
 	if (nv50->state.dirty & NV50_NEW_BLEND_COLOUR)
 		so_emit(chan, nv50->state.blend_colour);
+	if (nv50->state.dirty & NV50_NEW_STENCIL_REF)
+		so_emit(chan, nv50->state.stencil_ref);
 	if (nv50->state.dirty & NV50_NEW_STIPPLE)
 		so_emit(chan, nv50->state.stipple);
 	if (nv50->state.dirty & NV50_NEW_SCISSOR)
@@ -325,6 +331,16 @@
 		so_ref(NULL, &so);
 	}
 
+	if (nv50->dirty & NV50_NEW_STENCIL_REF) {
+		so = so_new(2, 2, 0);
+		so_method(so, tesla, NV50TCL_STENCIL_FRONT_FUNC_REF, 1);
+		so_data  (so, nv50->stencil_ref.ref_value[0]);
+		so_method(so, tesla, NV50TCL_STENCIL_BACK_FUNC_REF, 1);
+		so_data  (so, nv50->stencil_ref.ref_value[1]);
+		so_ref(so, &nv50->state.stencil_ref);
+		so_ref(NULL, &so);
+	}
+
 	if (nv50->dirty & NV50_NEW_STIPPLE) {
 		so = so_new(1, 32, 0);
 		so_method(so, tesla, NV50TCL_POLYGON_STIPPLE_PATTERN(0), 32);
diff --git a/src/gallium/drivers/nv50/nv50_transfer.c b/src/gallium/drivers/nv50/nv50_transfer.c
index d08b4d7..7c360e9 100644
--- a/src/gallium/drivers/nv50/nv50_transfer.c
+++ b/src/gallium/drivers/nv50/nv50_transfer.c
@@ -313,7 +313,7 @@
 		while (count) {
 			unsigned nr = MIN2(count, 1792);
 
-			if (chan->pushbuf->remaining <= nr) {
+			if (AVAIL_RING(chan) <= nr) {
 				FIRE_RING (chan);
 
 				BEGIN_RING(chan, eng2d,
@@ -321,7 +321,7 @@
 				OUT_RELOCh(chan, bo, dst_offset, reloc);
 				OUT_RELOCl(chan, bo, dst_offset, reloc);
 			}
-			assert(chan->pushbuf->remaining > nr);
+			assert(AVAIL_RING(chan) > nr);
 
 			BEGIN_RING(chan, eng2d,
 				   NV50_2D_SIFC_DATA | (2 << 29), nr);
diff --git a/src/gallium/drivers/nv50/nv50_vbo.c b/src/gallium/drivers/nv50/nv50_vbo.c
index ca2f806..1c8ee0b 100644
--- a/src/gallium/drivers/nv50/nv50_vbo.c
+++ b/src/gallium/drivers/nv50/nv50_vbo.c
@@ -23,7 +23,6 @@
 #include "pipe/p_context.h"
 #include "pipe/p_state.h"
 #include "util/u_inlines.h"
-
 #include "util/u_format.h"
 
 #include "nv50_context.h"
@@ -151,7 +150,7 @@
 	hw_size = nv50_vbo_size_to_hw(size, ve->nr_components);
 
 	if (!hw_type || !hw_size) {
-		NOUVEAU_ERR("unsupported vbo format: %s\n", pf_name(pf));
+		NOUVEAU_ERR("unsupported vbo format: %s\n", util_format_name(pf));
 		abort();
 		return 0x24e80000;
 	}
@@ -674,8 +673,6 @@
 	struct pipe_screen *pscreen = pipe->screen;
 	void *map;
 	
-	map = pipe_buffer_map(pscreen, indexBuffer, PIPE_BUFFER_USAGE_CPU_READ);
-
 	nv50_state_validate(nv50);
 
 	BEGIN_RING(chan, tesla, 0x142c, 1);
@@ -686,14 +683,35 @@
 	BEGIN_RING(chan, tesla, NV50TCL_VERTEX_BEGIN, 1);
 	OUT_RING  (chan, nv50_prim(mode));
 
-	nv50_draw_elements_inline(nv50, map, indexSize, start, count);
+	if (!nv50->vbo_fifo && indexSize == 4) {
+		BEGIN_RING(chan, tesla, NV50TCL_VB_ELEMENT_U32 | 0x30000, 0);
+		OUT_RING  (chan, count);
+		nouveau_pushbuf_submit(chan, nouveau_bo(indexBuffer),
+				       start << 2, count << 2);
+	} else
+	if (!nv50->vbo_fifo && indexSize == 2) {
+		unsigned vb_start = (start & ~1);
+		unsigned vb_end = (start + count + 1) & ~1;
+		unsigned dwords = (vb_end - vb_start) >> 1;
+
+		BEGIN_RING(chan, tesla, NV50TCL_VB_ELEMENT_U16_SETUP, 1);
+		OUT_RING  (chan, ((start & 1) << 31) | count);
+		BEGIN_RING(chan, tesla, NV50TCL_VB_ELEMENT_U16 | 0x30000, 0);
+		OUT_RING  (chan, dwords);
+		nouveau_pushbuf_submit(chan, nouveau_bo(indexBuffer),
+				       vb_start << 1, dwords << 2);
+		BEGIN_RING(chan, tesla, NV50TCL_VB_ELEMENT_U16_SETUP, 1);
+		OUT_RING  (chan, 0);
+	} else {
+		map = pipe_buffer_map(pscreen, indexBuffer,
+				      PIPE_BUFFER_USAGE_CPU_READ);
+		nv50_draw_elements_inline(nv50, map, indexSize, start, count);
+		nv50_unmap_vbufs(nv50);
+		pipe_buffer_unmap(pscreen, indexBuffer);
+	}
 
 	BEGIN_RING(chan, tesla, NV50TCL_VERTEX_END, 1);
 	OUT_RING  (chan, 0);
-
-	nv50_unmap_vbufs(nv50);
-
-	pipe_buffer_unmap(pscreen, indexBuffer);
 }
 
 static INLINE boolean
diff --git a/src/gallium/drivers/r300/r300_blit.c b/src/gallium/drivers/r300/r300_blit.c
index cdedb30..eb9b0be 100644
--- a/src/gallium/drivers/r300/r300_blit.c
+++ b/src/gallium/drivers/r300/r300_blit.c
@@ -22,11 +22,15 @@
 
 #include "r300_blit.h"
 #include "r300_context.h"
+#include "r300_texture.h"
+
+#include "util/u_format.h"
 
 static void r300_blitter_save_states(struct r300_context* r300)
 {
     util_blitter_save_blend(r300->blitter, r300->blend_state.state);
     util_blitter_save_depth_stencil_alpha(r300->blitter, r300->dsa_state.state);
+    util_blitter_save_stencil_ref(r300->blitter, &(r300->stencil_ref));
     util_blitter_save_rasterizer(r300->blitter, r300->rs_state.state);
     util_blitter_save_fragment_shader(r300->blitter, r300->fs);
     util_blitter_save_vertex_shader(r300->blitter, r300->vs);
@@ -85,13 +89,13 @@
                        buffers, rgba, depth, stencil);
 }
 
-/* Copy a block of pixels from one surface to another. */
-void r300_surface_copy(struct pipe_context* pipe,
-                       struct pipe_surface* dst,
-                       unsigned dstx, unsigned dsty,
-                       struct pipe_surface* src,
-                       unsigned srcx, unsigned srcy,
-                       unsigned width, unsigned height)
+/* Copy a block of pixels from one surface to another using HW. */
+static void r300_hw_copy(struct pipe_context* pipe,
+                         struct pipe_surface* dst,
+                         unsigned dstx, unsigned dsty,
+                         struct pipe_surface* src,
+                         unsigned srcx, unsigned srcy,
+                         unsigned width, unsigned height)
 {
     struct r300_context* r300 = r300_context(pipe);
 
@@ -113,6 +117,63 @@
                       dst, dstx, dsty, src, srcx, srcy, width, height, TRUE);
 }
 
+/* Copy a block of pixels from one surface to another. */
+void r300_surface_copy(struct pipe_context* pipe,
+                       struct pipe_surface* dst,
+                       unsigned dstx, unsigned dsty,
+                       struct pipe_surface* src,
+                       unsigned srcx, unsigned srcy,
+                       unsigned width, unsigned height)
+{
+    enum pipe_format old_format = dst->texture->format;
+    enum pipe_format new_format = old_format;
+
+    assert(dst->texture->format == src->texture->format);
+
+    if (!pipe->screen->is_format_supported(pipe->screen,
+                                           old_format, src->texture->target,
+                                           PIPE_TEXTURE_USAGE_RENDER_TARGET |
+                                           PIPE_TEXTURE_USAGE_SAMPLER, 0)) {
+        switch (util_format_get_blocksize(old_format)) {
+            case 1:
+                new_format = PIPE_FORMAT_I8_UNORM;
+                break;
+            case 2:
+                new_format = PIPE_FORMAT_A4R4G4B4_UNORM;
+                break;
+            case 4:
+                new_format = PIPE_FORMAT_A8R8G8B8_UNORM;
+                break;
+            default:
+                debug_printf("r300: surface_copy: Unhandled format: %s. Falling back to software.\n"
+                             "r300: surface_copy: Software fallback doesn't work for tiled textures.\n",
+                             util_format_name(old_format));
+        }
+    }
+
+    if (old_format != new_format) {
+        dst->format = new_format;
+        src->format = new_format;
+
+        r300_texture_reinterpret_format(pipe->screen,
+                                        dst->texture, new_format);
+        r300_texture_reinterpret_format(pipe->screen,
+                                        src->texture, new_format);
+    }
+
+    r300_hw_copy(pipe, dst, dstx, dsty, src, srcx, srcy, width, height);
+
+    if (old_format != new_format) {
+        dst->format = old_format;
+        src->format = old_format;
+
+        r300_texture_reinterpret_format(pipe->screen,
+                                        dst->texture, old_format);
+        r300_texture_reinterpret_format(pipe->screen,
+                                        src->texture, old_format);
+    }
+}
+
 /* Fill a region of a surface with a constant value. */
 void r300_surface_fill(struct pipe_context* pipe,
                        struct pipe_surface* dst,
diff --git a/src/gallium/drivers/r300/r300_context.c b/src/gallium/drivers/r300/r300_context.c
index 14820ca..f631b4e 100644
--- a/src/gallium/drivers/r300/r300_context.c
+++ b/src/gallium/drivers/r300/r300_context.c
@@ -34,7 +34,8 @@
 #include "r300_screen.h"
 #include "r300_state_invariant.h"
 #include "r300_texture.h"
-#include "r300_winsys.h"
+
+#include "radeon_winsys.h"
 
 static void r300_destroy_context(struct pipe_context* context)
 {
diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h
index 8461757..1eba8a8 100644
--- a/src/gallium/drivers/r300/r300_context.h
+++ b/src/gallium/drivers/r300/r300_context.h
@@ -155,8 +155,7 @@
 
 struct r300_constant_buffer {
     /* Buffer of constants */
-    /* XXX first number should be raised */
-    float constants[32][4];
+    float constants[256][4];
     /* Total number of constants */
     unsigned count;
 };
@@ -207,6 +206,9 @@
     /* Size of one zslice or face based on the texture target */
     unsigned layer_size[PIPE_MAX_TEXTURE_LEVELS];
 
+    /* Whether the mipmap level is macrotiled. */
+    enum r300_buffer_tiling mip_macrotile[PIPE_MAX_TEXTURE_LEVELS];
+
     /**
      * If non-zero, override the natural texture layout with
      * a custom stride (in bytes).
@@ -318,6 +320,8 @@
     struct pipe_vertex_element vertex_element[PIPE_MAX_ATTRIBS];
     int vertex_element_count;
 
+    struct pipe_stencil_ref stencil_ref;
+
     /* Bitmask of dirty state objects. */
     uint32_t dirty_state;
     /* Flag indicating whether or not the HW is dirty. */
diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c
index de6ba65..88fe166 100644
--- a/src/gallium/drivers/r300/r300_emit.c
+++ b/src/gallium/drivers/r300/r300_emit.c
@@ -114,6 +114,7 @@
     struct r300_screen* r300screen = r300_screen(r300->context.screen);
     struct pipe_framebuffer_state* fb =
         (struct pipe_framebuffer_state*)r300->fb_state.state;
+    struct pipe_stencil_ref stencil_ref = r300->stencil_ref;
     CS_LOCALS(r300);
 
     BEGIN_CS(r300screen->caps->is_r500 ? 8 : 6);
@@ -128,10 +129,10 @@
         OUT_CS(0);
     }
 
-    OUT_CS(dsa->stencil_ref_mask);
+    OUT_CS(dsa->stencil_ref_mask | stencil_ref.ref_value[0]);
 
     if (r300screen->caps->is_r500) {
-        OUT_CS_REG(R500_ZB_STENCILREFMASK_BF, dsa->stencil_ref_bf);
+        OUT_CS_REG(R500_ZB_STENCILREFMASK_BF, dsa->stencil_ref_bf | stencil_ref.ref_value[1]);
     }
     END_CS;
 }
@@ -387,8 +388,7 @@
     int i;
     CS_LOCALS(r300);
 
-    BEGIN_CS((10 * fb->nr_cbufs) + (2 * (4 - fb->nr_cbufs)) +
-             (fb->zsbuf ? 10 : 0) + 6);
+    BEGIN_CS((10 * fb->nr_cbufs) + (fb->zsbuf ? 10 : 0) + 6);
 
     /* Flush and free renderbuffer caches. */
     OUT_CS_REG(R300_RB3D_DSTCACHE_CTLSTAT,
@@ -403,12 +403,10 @@
         if (r300screen->caps->is_r500) {
             OUT_CS_REG(R300_RB3D_CCTL,
                 R300_RB3D_CCTL_NUM_MULTIWRITES(fb->nr_cbufs) |
-                R300_RB3D_CCTL_INDEPENDENT_COLORFORMAT_ENABLE_ENABLE |
-                R300_RB3D_CCTL_INDEPENDENT_COLOR_CHANNEL_MASK_ENABLE);
+                R300_RB3D_CCTL_INDEPENDENT_COLORFORMAT_ENABLE_ENABLE);
         } else {
             OUT_CS_REG(R300_RB3D_CCTL,
-                R300_RB3D_CCTL_NUM_MULTIWRITES(fb->nr_cbufs) |
-                R300_RB3D_CCTL_INDEPENDENT_COLORFORMAT_ENABLE_ENABLE);
+                R300_RB3D_CCTL_NUM_MULTIWRITES(fb->nr_cbufs));
         }
     } else {
         OUT_CS_REG(R300_RB3D_CCTL, 0x0);
@@ -426,7 +424,7 @@
         OUT_CS_REG_SEQ(R300_RB3D_COLORPITCH0 + (4 * i), 1);
         OUT_CS_RELOC(tex->buffer, tex->pitch[surf->level] |
                      r300_translate_colorformat(tex->tex.format) |
-                     R300_COLOR_TILE(tex->macrotile) |
+                     R300_COLOR_TILE(tex->mip_macrotile[surf->level]) |
                      R300_COLOR_MICROTILE(tex->microtile),
                      0, RADEON_GEM_DOMAIN_VRAM, 0);
 
@@ -434,11 +432,6 @@
             r300_translate_out_fmt(surf->format));
     }
 
-    /* Disable unused colorbuffers. */
-    for (; i < 4; i++) {
-        OUT_CS_REG(R300_US_OUT_FMT_0 + (4 * i), R300_US_OUT_FMT_UNUSED);
-    }
-
     /* Set up a zbuffer. */
     if (fb->zsbuf) {
         surf = fb->zsbuf;
@@ -452,7 +445,7 @@
 
         OUT_CS_REG_SEQ(R300_ZB_DEPTHPITCH, 1);
         OUT_CS_RELOC(tex->buffer, tex->pitch[surf->level] |
-                     R300_DEPTHMACROTILE(tex->macrotile) |
+                     R300_DEPTHMACROTILE(tex->mip_macrotile[surf->level]) |
                      R300_DEPTHMICROTILE(tex->microtile),
                      0, RADEON_GEM_DOMAIN_VRAM, 0);
     }
@@ -636,17 +629,19 @@
     struct r300_rs_block* rs = (struct r300_rs_block*)state;
     unsigned i;
     struct r300_screen* r300screen = r300_screen(r300->context.screen);
+    /* It's the same for both INST and IP tables */
+    unsigned count = (rs->inst_count & R300_RS_INST_COUNT_MASK) + 1;
     CS_LOCALS(r300);
 
     DBG(r300, DBG_DRAW, "r300: RS emit:\n");
 
-    BEGIN_CS(21);
+    BEGIN_CS(5 + count*2);
     if (r300screen->caps->is_r500) {
-        OUT_CS_REG_SEQ(R500_RS_IP_0, 8);
+        OUT_CS_REG_SEQ(R500_RS_IP_0, count);
     } else {
-        OUT_CS_REG_SEQ(R300_RS_IP_0, 8);
+        OUT_CS_REG_SEQ(R300_RS_IP_0, count);
     }
-    for (i = 0; i < 8; i++) {
+    for (i = 0; i < count; i++) {
         OUT_CS(rs->ip[i]);
         DBG(r300, DBG_DRAW, "    : ip %d: 0x%08x\n", i, rs->ip[i]);
     }
@@ -656,11 +651,11 @@
     OUT_CS(rs->inst_count);
 
     if (r300screen->caps->is_r500) {
-        OUT_CS_REG_SEQ(R500_RS_INST_0, 8);
+        OUT_CS_REG_SEQ(R500_RS_INST_0, count);
     } else {
-        OUT_CS_REG_SEQ(R300_RS_INST_0, 8);
+        OUT_CS_REG_SEQ(R300_RS_INST_0, count);
     }
-    for (i = 0; i < 8; i++) {
+    for (i = 0; i < count; i++) {
         OUT_CS(rs->inst[i]);
         DBG(r300, DBG_DRAW, "    : inst %d: 0x%08x\n", i, rs->inst[i]);
     }
@@ -1153,14 +1148,15 @@
         for (i = 0; i < MIN2(r300->sampler_count, r300->texture_count); i++) {
   	    if (r300->dirty_state &
 		((R300_NEW_SAMPLER << i) | (R300_NEW_TEXTURE << i))) {
-		if (r300->textures[i]) 
+		if (r300->textures[i]) {
 		    r300_emit_texture(r300,
 				      r300->sampler_states[i],
 				      r300->textures[i],
 				      i);
+                    dirty_tex |= r300->dirty_state & (R300_NEW_TEXTURE << i);
+                }
                 r300->dirty_state &=
                     ~((R300_NEW_SAMPLER << i) | (R300_NEW_TEXTURE << i));
-                dirty_tex++;
             }
         }
         r300->dirty_state &= ~(R300_ANY_NEW_SAMPLERS | R300_ANY_NEW_TEXTURES);
diff --git a/src/gallium/drivers/r300/r300_reg.h b/src/gallium/drivers/r300/r300_reg.h
index 3618138..a049da6 100644
--- a/src/gallium/drivers/r300/r300_reg.h
+++ b/src/gallium/drivers/r300/r300_reg.h
@@ -244,6 +244,9 @@
 #       define R300_DATA_TYPE_SHORT_4                   7
 #       define R300_DATA_TYPE_VECTOR_3_TTT              8
 #       define R300_DATA_TYPE_VECTOR_3_EET              9
+#       define R300_DATA_TYPE_FLOAT_8                   10
+#       define R300_DATA_TYPE_FLT16_2                   11
+#       define R300_DATA_TYPE_FLT16_4                   12
 #       define R300_SKIP_DWORDS_SHIFT                   4
 #       define R300_DST_VEC_LOC_SHIFT                   8
 #       define R300_LAST_VEC                            (1 << 13)
diff --git a/src/gallium/drivers/r300/r300_screen.c b/src/gallium/drivers/r300/r300_screen.c
index 13cd04a..b892c08 100644
--- a/src/gallium/drivers/r300/r300_screen.c
+++ b/src/gallium/drivers/r300/r300_screen.c
@@ -152,12 +152,12 @@
             } else {
                 return 0;
             }
+        case PIPE_CAP_MAX_CONST_BUFFERS:
+            return 1;
+        case PIPE_CAP_MAX_CONST_BUFFER_SIZE:
+            return 256;
         case PIPE_CAP_INDEP_BLEND_ENABLE:
-            if (r300screen->caps->is_r500) {
-                return 1;
-            } else {
-                return 0;
-            }
+            return 0;
         case PIPE_CAP_INDEP_BLEND_FUNC:
             return 0;
         case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
@@ -220,9 +220,6 @@
     switch (format) {
         /* Supported formats. */
         /* Colorbuffer */
-        case PIPE_FORMAT_A4R4G4B4_UNORM:
-        case PIPE_FORMAT_R5G6B5_UNORM:
-        case PIPE_FORMAT_A1R5G5B5_UNORM:
         case PIPE_FORMAT_A8_UNORM:
         case PIPE_FORMAT_L8_UNORM:
             retval = usage &
@@ -246,6 +243,9 @@
             break;
 
         /* Colorbuffer or texture */
+        case PIPE_FORMAT_R5G6B5_UNORM:
+        case PIPE_FORMAT_A1R5G5B5_UNORM:
+        case PIPE_FORMAT_A4R4G4B4_UNORM:
         case PIPE_FORMAT_A8R8G8B8_UNORM:
         case PIPE_FORMAT_X8R8G8B8_UNORM:
         case PIPE_FORMAT_R8G8B8A8_UNORM:
@@ -281,7 +281,7 @@
         case PIPE_FORMAT_X8Z24_UNORM:
             SCREEN_DBG(r300_screen(screen), DBG_TEX,
                        "r300: Note: Got unsupported format: %s in %s\n",
-                       pf_name(format), __FUNCTION__);
+                       util_format_name(format), __FUNCTION__);
             return FALSE;
 
         /* XXX Add all remaining gallium-supported formats,
@@ -290,7 +290,7 @@
         default:
             /* Unknown format... */
             debug_printf("r300: Warning: Got unknown format: %s in %s\n",
-                pf_name(format), __FUNCTION__);
+                util_format_name(format), __FUNCTION__);
             break;
     }
 
diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c
index 99ecae9..34bf81c 100644
--- a/src/gallium/drivers/r300/r300_state.c
+++ b/src/gallium/drivers/r300/r300_state.c
@@ -38,6 +38,8 @@
 #include "r300_fs.h"
 #include "r300_vs.h"
 
+#include "radeon_winsys.h"
+
 /* r300_state: Functions used to intialize state context by translating
  * Gallium state objects into semi-native r300 state objects. */
 
@@ -425,7 +427,7 @@
             (r300_translate_stencil_op(state->stencil[0].zfail_op) <<
                 R300_S_FRONT_ZFAIL_OP_SHIFT);
 
-        dsa->stencil_ref_mask = (state->stencil[0].ref_value) |
+        dsa->stencil_ref_mask =
                 (state->stencil[0].valuemask << R300_STENCILMASK_SHIFT) |
                 (state->stencil[0].writemask << R300_STENCILWRITEMASK_SHIFT);
 
@@ -444,7 +446,7 @@
             if (caps->is_r500)
             {
                 dsa->z_buffer_control |= R500_STENCIL_REFMASK_FRONT_BACK;
-                dsa->stencil_ref_bf = (state->stencil[1].ref_value) |
+                dsa->stencil_ref_bf =
                     (state->stencil[1].valuemask <<
                     R300_STENCILMASK_SHIFT) |
                     (state->stencil[1].writemask <<
@@ -488,6 +490,77 @@
     FREE(state);
 }
 
+static void r300_set_stencil_ref(struct pipe_context* pipe,
+                                 const struct pipe_stencil_ref* sr)
+{
+    struct r300_context* r300 = r300_context(pipe);
+    r300->stencil_ref = *sr;
+    r300->dsa_state.dirty = TRUE;
+}
+
+/* This switcheroo is needed just because of goddamned MACRO_SWITCH. */
+static void r300_fb_update_tiling_flags(struct r300_context *r300,
+                               const struct pipe_framebuffer_state *old_state,
+                               const struct pipe_framebuffer_state *new_state)
+{
+    struct r300_texture *tex;
+    unsigned i, j, level;
+
+    /* Reset tiling flags for old surfaces to default values. */
+    for (i = 0; i < old_state->nr_cbufs; i++) {
+        for (j = 0; j < new_state->nr_cbufs; j++) {
+            if (old_state->cbufs[i]->texture == new_state->cbufs[j]->texture) {
+                break;
+            }
+        }
+        /* If not binding the surface again... */
+        if (j != new_state->nr_cbufs) {
+            continue;
+        }
+
+        tex = (struct r300_texture*)old_state->cbufs[i]->texture;
+
+        if (tex) {
+            r300->winsys->buffer_set_tiling(r300->winsys, tex->buffer,
+                                            tex->pitch[0],
+                                            tex->microtile != 0,
+                                            tex->macrotile != 0);
+        }
+    }
+    if (old_state->zsbuf &&
+        (!new_state->zsbuf ||
+         old_state->zsbuf->texture != new_state->zsbuf->texture)) {
+        tex = (struct r300_texture*)old_state->zsbuf->texture;
+
+        if (tex) {
+            r300->winsys->buffer_set_tiling(r300->winsys, tex->buffer,
+                                            tex->pitch[0],
+                                            tex->microtile != 0,
+                                            tex->macrotile != 0);
+        }
+    }
+
+    /* Set tiling flags for new surfaces. */
+    for (i = 0; i < new_state->nr_cbufs; i++) {
+        tex = (struct r300_texture*)new_state->cbufs[i]->texture;
+        level = new_state->cbufs[i]->level;
+
+        r300->winsys->buffer_set_tiling(r300->winsys, tex->buffer,
+                                        tex->pitch[level],
+                                        tex->microtile != 0,
+                                        tex->mip_macrotile[level] != 0);
+    }
+    if (new_state->zsbuf) {
+        tex = (struct r300_texture*)new_state->zsbuf->texture;
+        level = new_state->zsbuf->level;
+
+        r300->winsys->buffer_set_tiling(r300->winsys, tex->buffer,
+                                        tex->pitch[level],
+                                        tex->microtile != 0,
+                                        tex->mip_macrotile[level] != 0);
+    }
+}
+
 static void
     r300_set_framebuffer_state(struct pipe_context* pipe,
                                const struct pipe_framebuffer_state* state)
@@ -497,9 +570,6 @@
     unsigned max_width, max_height;
     uint32_t zbuffer_bpp = 0;
 
-    r300->fb_state.size = (10 * state->nr_cbufs) +
-        (2 * (4 - state->nr_cbufs)) +
-        (state->zsbuf ? 10 : 0) + 6;
 
     if (state->nr_cbufs > 4) {
         debug_printf("r300: Implementation error: Too many MRTs in %s, "
@@ -521,13 +591,17 @@
         return;
     }
 
+
     if (r300->draw) {
         draw_flush(r300->draw);
     }
 
     memcpy(r300->fb_state.state, state, sizeof(struct pipe_framebuffer_state));
 
-    /* Don't rely on the order of states being set for the first time. */
+    r300->fb_state.size = (10 * state->nr_cbufs) + (state->zsbuf ? 10 : 0) + 6;
+
+    r300_fb_update_tiling_flags(r300, r300->fb_state.state, state);
+
     /* XXX wait what */
     r300->blend_state.dirty = TRUE;
     r300->dsa_state.dirty = TRUE;
@@ -794,7 +868,7 @@
     sampler->filter0 |= r300_translate_tex_filters(state->min_img_filter,
                                                    state->mag_img_filter,
                                                    state->min_mip_filter,
-                                                   state->max_anisotropy > 1.0);
+                                                   state->max_anisotropy > 0);
 
     /* Unfortunately, r300-r500 don't support floating-point mipmap lods. */
     /* We must pass these to the emit function to clamp them properly. */
@@ -1076,7 +1150,9 @@
                                      struct pipe_buffer *buf)
 {
     struct r300_context* r300 = r300_context(pipe);
+    struct r300_screen *r300screen = r300_screen(pipe->screen);
     void *mapped;
+    int max_size = 0;
 
     if (buf == NULL || buf->size == 0 ||
         (mapped = pipe_buffer_map(pipe->screen, buf, PIPE_BUFFER_USAGE_CPU_READ)) == NULL)
@@ -1086,6 +1162,33 @@
     }
 
     assert((buf->size % 4 * sizeof(float)) == 0);
+
+    /* Check the size of the constant buffer. */
+    switch (shader) {
+        case PIPE_SHADER_VERTEX:
+            max_size = 256;
+            break;
+        case PIPE_SHADER_FRAGMENT:
+            if (r300screen->caps->is_r500) {
+                max_size = 256;
+            /* XXX Implement emission of r400's extended constant buffer. */
+            /*} else if (r300screen->caps->is_r400) {
+                max_size = 64;*/
+            } else {
+                max_size = 32;
+            }
+            break;
+        default:
+            assert(0);
+    }
+
+    /* XXX Subtract immediates and RC_STATE_* variables. */
+    if (buf->size > (sizeof(float) * 4 * max_size)) {
+        debug_printf("r300: Max size of the constant buffer is "
+                      "%i*4 floats.\n", max_size);
+        abort();
+    }
+
     memcpy(r300->shader_constants[shader].constants, mapped, buf->size);
     r300->shader_constants[shader].count = buf->size / (4 * sizeof(float));
     pipe_buffer_unmap(pipe->screen, buf);
@@ -1112,6 +1215,8 @@
     r300->context.bind_depth_stencil_alpha_state = r300_bind_dsa_state;
     r300->context.delete_depth_stencil_alpha_state = r300_delete_dsa_state;
 
+    r300->context.set_stencil_ref = r300_set_stencil_ref;
+
     r300->context.set_framebuffer_state = r300_set_framebuffer_state;
 
     r300->context.create_fs_state = r300_create_fs_state;
diff --git a/src/gallium/drivers/r300/r300_state_derived.c b/src/gallium/drivers/r300/r300_state_derived.c
index bad9e76..2cbce92 100644
--- a/src/gallium/drivers/r300/r300_state_derived.c
+++ b/src/gallium/drivers/r300/r300_state_derived.c
@@ -306,7 +306,7 @@
                                  struct r300_shader_semantics* fs_inputs)
 {
     struct r300_rs_block rs = { { 0 } };
-    int i, col_count = 0, tex_count = 0, fp_offset = 0;
+    int i, col_count = 0, tex_count = 0, fp_offset = 0, count;
     void (*rX00_rs_col)(struct r300_rs_block*, int, int, boolean);
     void (*rX00_rs_col_write)(struct r300_rs_block*, int, int);
     void (*rX00_rs_tex)(struct r300_rs_block*, int, int, boolean);
@@ -410,11 +410,13 @@
     rs.count = (tex_count*4) | (col_count << R300_IC_COUNT_SHIFT) |
         R300_HIRES_EN;
 
-    rs.inst_count = MAX3(col_count - 1, tex_count - 1, 0);
+    count = MAX3(col_count, tex_count, 1);
+    rs.inst_count = count - 1;
 
     /* Now, after all that, see if we actually need to update the state. */
     if (memcmp(r300->rs_block_state.state, &rs, sizeof(struct r300_rs_block))) {
         memcpy(r300->rs_block_state.state, &rs, sizeof(struct r300_rs_block));
+        r300->rs_block_state.size = 5 + count;
         r300->rs_block_state.dirty = TRUE;
     }
 }
diff --git a/src/gallium/drivers/r300/r300_state_inlines.h b/src/gallium/drivers/r300/r300_state_inlines.h
index 5df6815..6ee6cd0 100644
--- a/src/gallium/drivers/r300/r300_state_inlines.h
+++ b/src/gallium/drivers/r300/r300_state_inlines.h
@@ -312,15 +312,15 @@
     return retval;
 }
 
-static INLINE uint32_t r300_anisotropy(float max_aniso)
+static INLINE uint32_t r300_anisotropy(unsigned max_aniso)
 {
-    if (max_aniso >= 16.0f) {
+    if (max_aniso >= 16) {
         return R300_TX_MAX_ANISO_16_TO_1;
-    } else if (max_aniso >= 8.0f) {
+    } else if (max_aniso >= 8) {
         return R300_TX_MAX_ANISO_8_TO_1;
-    } else if (max_aniso >= 4.0f) {
+    } else if (max_aniso >= 4) {
         return R300_TX_MAX_ANISO_4_TO_1;
-    } else if (max_aniso >= 2.0f) {
+    } else if (max_aniso >= 2) {
         return R300_TX_MAX_ANISO_2_TO_1;
     } else {
         return R300_TX_MAX_ANISO_1_TO_1;
@@ -367,7 +367,7 @@
         default:
             debug_printf("r300: Implementation error: "
                 "Got unsupported color format %s in %s\n",
-                pf_name(format), __FUNCTION__);
+                util_format_name(format), __FUNCTION__);
             assert(0);
             break;
     }
@@ -389,7 +389,7 @@
         default:
             debug_printf("r300: Implementation error: "
                 "Got unsupported ZS format %s in %s\n",
-                pf_name(format), __FUNCTION__);
+                util_format_name(format), __FUNCTION__);
             assert(0);
             break;
     }
@@ -403,10 +403,14 @@
 static INLINE uint32_t r300_translate_out_fmt(enum pipe_format format)
 {
     switch (format) {
+        case PIPE_FORMAT_R5G6B5_UNORM:
+            /* C_5_6_5 is missing in US_OUT_FMT, but C4_8 works just fine. */
+        case PIPE_FORMAT_A1R5G5B5_UNORM:
+            /* C_1_5_5_5 is missing in US_OUT_FMT, but C4_8 works just fine. */
+        case PIPE_FORMAT_A4R4G4B4_UNORM:
+            /* C4_4 is missing in US_OUT_FMT, but C4_8 works just fine. */
         case PIPE_FORMAT_A8R8G8B8_UNORM:
         case PIPE_FORMAT_X8R8G8B8_UNORM:
-        /* XXX */
-        case PIPE_FORMAT_Z24S8_UNORM:
             return R300_US_OUT_FMT_C4_8 |
                 R300_C0_SEL_B | R300_C1_SEL_G |
                 R300_C2_SEL_R | R300_C3_SEL_A;
@@ -428,7 +432,7 @@
         default:
             debug_printf("r300: Implementation error: "
                 "Got unsupported output format %s in %s\n",
-                pf_name(format), __FUNCTION__);
+                util_format_name(format), __FUNCTION__);
             assert(0);
             return R300_US_OUT_FMT_UNUSED;
     }
@@ -494,7 +498,7 @@
 
     if (desc->layout != UTIL_FORMAT_LAYOUT_ARITH &&
         desc->layout != UTIL_FORMAT_LAYOUT_ARRAY) {
-        debug_printf("r300: Bad format %s in %s:%d\n", pf_name(format),
+        debug_printf("r300: Bad format %s in %s:%d\n", util_format_name(format),
             __FUNCTION__, __LINE__);
         assert(0);
     }
@@ -503,12 +507,20 @@
         /* Half-floats, floats, doubles */
         case UTIL_FORMAT_TYPE_FLOAT:
             switch (util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, 0)) {
+                case 16:
+                    /* XXX Supported only on RV350 and later. */
+                    if (components > 2) {
+                        result = R300_DATA_TYPE_FLT16_4;
+                    } else {
+                        result = R300_DATA_TYPE_FLT16_2;
+                    }
+                    break;
                 case 32:
                     result = R300_DATA_TYPE_FLOAT_1 + (components - 1);
                     break;
                 default:
                     debug_printf("r300: Bad format %s in %s:%d\n",
-                        pf_name(format), __FUNCTION__, __LINE__);
+                        util_format_name(format), __FUNCTION__, __LINE__);
                     assert(0);
             }
             break;
@@ -529,7 +541,7 @@
                     break;
                 default:
                     debug_printf("r300: Bad format %s in %s:%d\n",
-                        pf_name(format), __FUNCTION__, __LINE__);
+                        util_format_name(format), __FUNCTION__, __LINE__);
                     debug_printf("r300: util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, 0) == %d\n",
                         util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, 0));
                     assert(0);
@@ -537,7 +549,7 @@
             break;
         default:
             debug_printf("r300: Bad format %s in %s:%d\n",
-                pf_name(format), __FUNCTION__, __LINE__);
+                util_format_name(format), __FUNCTION__, __LINE__);
             assert(0);
     }
 
@@ -561,7 +573,7 @@
     if (desc->layout != UTIL_FORMAT_LAYOUT_ARITH &&
         desc->layout != UTIL_FORMAT_LAYOUT_ARRAY) {
         debug_printf("r300: Bad format %s in %s:%d\n",
-            pf_name(format), __FUNCTION__, __LINE__);
+            util_format_name(format), __FUNCTION__, __LINE__);
         return 0;
     }
 
diff --git a/src/gallium/drivers/r300/r300_texture.c b/src/gallium/drivers/r300/r300_texture.c
index 417a573..34a49be 100644
--- a/src/gallium/drivers/r300/r300_texture.c
+++ b/src/gallium/drivers/r300/r300_texture.c
@@ -85,6 +85,20 @@
                pt->width0, pt->height0, pt->last_level);
 }
 
+void r300_texture_reinterpret_format(struct pipe_screen *screen,
+                                     struct pipe_texture *tex,
+                                     enum pipe_format new_format)
+{
+    struct r300_screen *r300screen = r300_screen(screen);
+
+    SCREEN_DBG(r300screen, DBG_TEX, "r300: Reinterpreting format: %s -> %s\n",
+               util_format_name(tex->format), util_format_name(new_format));
+
+    tex->format = new_format;
+
+    r300_setup_texture_state(r300_screen(screen), (struct r300_texture*)tex);
+}
+
 unsigned r300_texture_get_offset(struct r300_texture* tex, unsigned level,
                                  unsigned zslice, unsigned face)
 {
@@ -109,18 +123,40 @@
  * Return the width (dim==TILE_WIDTH) or height (dim==TILE_HEIGHT) of one tile
  * of the given texture.
  */
-static unsigned r300_texture_get_tile_size(struct r300_texture* tex, int dim)
+static unsigned r300_texture_get_tile_size(struct r300_texture* tex,
+                                           int dim, boolean macrotile)
 {
     unsigned pixsize, tile_size;
 
     pixsize = util_format_get_blocksize(tex->tex.format);
-    tile_size = microblock_table[util_logbase2(pixsize)][tex->microtile][dim] *
-                (tex->macrotile == R300_BUFFER_TILED ? 8 : 1);
+    tile_size = microblock_table[util_logbase2(pixsize)][tex->microtile][dim];
+
+    if (macrotile) {
+        tile_size *= 8;
+    }
 
     assert(tile_size);
     return tile_size;
 }
 
+/* Return true if macrotiling should be enabled on the miplevel. */
+static boolean r300_texture_macro_switch(struct r300_texture *tex,
+                                         unsigned level,
+                                         boolean rv350_mode)
+{
+    unsigned tile_width, width;
+
+    tile_width = r300_texture_get_tile_size(tex, TILE_WIDTH, TRUE);
+    width = u_minify(tex->tex.width0, level);
+
+    /* See TX_FILTER1_n.MACRO_SWITCH. */
+    if (rv350_mode) {
+        return width >= tile_width;
+    } else {
+        return width > tile_width;
+    }
+}
+
 /**
  * Return the stride, in bytes, of the texture images of the given texture
  * at the given level.
@@ -143,8 +179,10 @@
     width = u_minify(tex->tex.width0, level);
 
     if (!util_format_is_compressed(tex->tex.format)) {
-        tile_width = r300_texture_get_tile_size(tex, TILE_WIDTH);
+        tile_width = r300_texture_get_tile_size(tex, TILE_WIDTH,
+                                                tex->mip_macrotile[level]);
         width = align(width, tile_width);
+
         return util_format_get_stride(tex->tex.format, width);
     } else {
         return align(util_format_get_stride(tex->tex.format, width), 32);
@@ -159,7 +197,8 @@
     height = u_minify(tex->tex.height0, level);
 
     if (!util_format_is_compressed(tex->tex.format)) {
-        tile_height = r300_texture_get_tile_size(tex, TILE_HEIGHT);
+        tile_height = r300_texture_get_tile_size(tex, TILE_HEIGHT,
+                                                 tex->mip_macrotile[level]);
         height = align(height, tile_height);
     }
 
@@ -171,11 +210,17 @@
 {
     struct pipe_texture* base = &tex->tex;
     unsigned stride, size, layer_size, nblocksy, i;
+    boolean rv350_mode = screen->caps->family >= CHIP_FAMILY_RV350;
 
     SCREEN_DBG(screen, DBG_TEX, "r300: Making miptree for texture, format %s\n",
-               pf_name(base->format));
+               util_format_name(base->format));
 
     for (i = 0; i <= base->last_level; i++) {
+        /* Let's see if this miplevel can be macrotiled. */
+        tex->mip_macrotile[i] = (tex->macrotile == R300_BUFFER_TILED &&
+                                 r300_texture_macro_switch(tex, i, rv350_mode)) ?
+                                 R300_BUFFER_TILED : R300_BUFFER_LINEAR;
+
         stride = r300_texture_get_stride(screen, tex, i);
         nblocksy = r300_texture_get_nblocksy(tex, i);
         layer_size = stride * nblocksy;
@@ -185,15 +230,16 @@
         else
             size = layer_size * u_minify(base->depth0, i);
 
-        tex->offset[i] = align(tex->size, 32);
+        tex->offset[i] = tex->size;
         tex->size = tex->offset[i] + size;
         tex->layer_size[i] = layer_size;
         tex->pitch[i] = stride / util_format_get_blocksize(base->format);
 
         SCREEN_DBG(screen, DBG_TEX, "r300: Texture miptree: Level %d "
-                "(%dx%dx%d px, pitch %d bytes) %d bytes total\n",
+                "(%dx%dx%d px, pitch %d bytes) %d bytes total, macrotiled %s\n",
                 i, u_minify(base->width0, i), u_minify(base->height0, i),
-                u_minify(base->depth0, i), stride, tex->size);
+                u_minify(base->depth0, i), stride, tex->size,
+                tex->mip_macrotile[i] ? "TRUE" : "FALSE");
     }
 }
 
diff --git a/src/gallium/drivers/r300/r300_texture.h b/src/gallium/drivers/r300/r300_texture.h
index 961bdcc..b9c3ab8 100644
--- a/src/gallium/drivers/r300/r300_texture.h
+++ b/src/gallium/drivers/r300/r300_texture.h
@@ -24,6 +24,7 @@
 #define R300_TEXTURE_H
 
 #include "pipe/p_video_state.h"
+#include "util/u_format.h"
 
 #include "r300_reg.h"
 
@@ -37,6 +38,10 @@
 unsigned r300_texture_get_offset(struct r300_texture* tex, unsigned level,
                                  unsigned zslice, unsigned face);
 
+void r300_texture_reinterpret_format(struct pipe_screen *screen,
+                                     struct pipe_texture *tex,
+                                     enum pipe_format new_format);
+
 /* Translate a pipe_format into a useful texture format for sampling.
  *
  * R300_EASY_TX_FORMAT swizzles the texture.
@@ -59,12 +64,20 @@
             return R300_EASY_TX_FORMAT(X, X, X, ONE, X8) |
                 R300_TX_FORMAT_GAMMA;
         /* X16 */
+        case PIPE_FORMAT_A4R4G4B4_UNORM:
+            return R300_EASY_TX_FORMAT(X, Y, Z, W, W4Z4Y4X4);
         case PIPE_FORMAT_R16_UNORM:
         case PIPE_FORMAT_Z16_UNORM:
             return R300_EASY_TX_FORMAT(X, X, X, X, X16);
         case PIPE_FORMAT_R16_SNORM:
             return R300_EASY_TX_FORMAT(X, X, X, X, X16) |
                 R300_TX_FORMAT_SIGNED;
+        /* Z5Y6X5 */
+        case PIPE_FORMAT_R5G6B5_UNORM:
+            return R300_EASY_TX_FORMAT(X, Y, Z, ONE, Z5Y6X5);
+        /* W1Z5Y5X5*/
+        case PIPE_FORMAT_A1R5G5B5_UNORM:
+            return R300_EASY_TX_FORMAT(X, Y, Z, W, W1Z5Y5X5);
         /* Y8X8 */
         case PIPE_FORMAT_A8L8_UNORM:
             return R300_EASY_TX_FORMAT(X, X, X, Y, Y8X8);
@@ -109,7 +122,7 @@
         default:
             debug_printf("r300: Implementation error: "
                 "Got unsupported texture format %s in %s\n",
-                pf_name(format), __FUNCTION__);
+                util_format_name(format), __FUNCTION__);
             assert(0);
             break;
     }
diff --git a/src/gallium/drivers/r300/r300_winsys.h b/src/gallium/drivers/r300/r300_winsys.h
index f4a8ae1..40fb8a9 100644
--- a/src/gallium/drivers/r300/r300_winsys.h
+++ b/src/gallium/drivers/r300/r300_winsys.h
@@ -33,9 +33,8 @@
 
 #include "pipe/p_defines.h"
 #include "pipe/p_state.h"
-#include "util/u_simple_screen.h"
 
-#include "radeon_winsys.h"
+struct radeon_winsys;
 
 /* Creates a new r300 screen. */
 struct pipe_screen* r300_create_screen(struct radeon_winsys* radeon_winsys);
diff --git a/src/gallium/drivers/softpipe/sp_context.c b/src/gallium/drivers/softpipe/sp_context.c
index 2b22ce2..ddc35bc 100644
--- a/src/gallium/drivers/softpipe/sp_context.c
+++ b/src/gallium/drivers/softpipe/sp_context.c
@@ -246,6 +246,7 @@
    softpipe->pipe.delete_gs_state = softpipe_delete_gs_state;
 
    softpipe->pipe.set_blend_color = softpipe_set_blend_color;
+   softpipe->pipe.set_stencil_ref = softpipe_set_stencil_ref;
    softpipe->pipe.set_clip_state = softpipe_set_clip_state;
    softpipe->pipe.set_constant_buffer = softpipe_set_constant_buffer;
    softpipe->pipe.set_framebuffer_state = softpipe_set_framebuffer_state;
diff --git a/src/gallium/drivers/softpipe/sp_context.h b/src/gallium/drivers/softpipe/sp_context.h
index 62f9e7a..95def72 100644
--- a/src/gallium/drivers/softpipe/sp_context.h
+++ b/src/gallium/drivers/softpipe/sp_context.h
@@ -62,6 +62,7 @@
 
    /** Other rendering state */
    struct pipe_blend_color blend_color;
+   struct pipe_stencil_ref stencil_ref;
    struct pipe_clip_state clip;
    struct pipe_buffer *constants[PIPE_SHADER_TYPES][PIPE_MAX_CONSTANT_BUFFERS];
    struct pipe_framebuffer_state framebuffer;
diff --git a/src/gallium/drivers/softpipe/sp_quad_depth_test.c b/src/gallium/drivers/softpipe/sp_quad_depth_test.c
index a981775..499eebd 100644
--- a/src/gallium/drivers/softpipe/sp_quad_depth_test.c
+++ b/src/gallium/drivers/softpipe/sp_quad_depth_test.c
@@ -519,7 +519,7 @@
    failOp  = softpipe->depth_stencil->stencil[face].fail_op;
    zFailOp = softpipe->depth_stencil->stencil[face].zfail_op;
    zPassOp = softpipe->depth_stencil->stencil[face].zpass_op;
-   ref     = softpipe->depth_stencil->stencil[face].ref_value;
+   ref     = softpipe->stencil_ref.ref_value[face];
    wrtMask = softpipe->depth_stencil->stencil[face].writemask;
    valMask = softpipe->depth_stencil->stencil[face].valuemask;
 
diff --git a/src/gallium/drivers/softpipe/sp_state.h b/src/gallium/drivers/softpipe/sp_state.h
index a83cae7..4370bbe 100644
--- a/src/gallium/drivers/softpipe/sp_state.h
+++ b/src/gallium/drivers/softpipe/sp_state.h
@@ -132,13 +132,16 @@
 void softpipe_delete_rasterizer_state(struct pipe_context *, void *);
 
 void softpipe_set_framebuffer_state( struct pipe_context *,
-			     const struct pipe_framebuffer_state * );
+                                     const struct pipe_framebuffer_state * );
 
 void softpipe_set_blend_color( struct pipe_context *pipe,
                                const struct pipe_blend_color *blend_color );
 
+void softpipe_set_stencil_ref( struct pipe_context *pipe,
+                               const struct pipe_stencil_ref *stencil_ref );
+
 void softpipe_set_clip_state( struct pipe_context *,
-			     const struct pipe_clip_state * );
+                              const struct pipe_clip_state * );
 
 void softpipe_set_constant_buffer(struct pipe_context *,
                                   uint shader, uint index,
diff --git a/src/gallium/drivers/softpipe/sp_state_blend.c b/src/gallium/drivers/softpipe/sp_state_blend.c
index 95ab323..c63a49e 100644
--- a/src/gallium/drivers/softpipe/sp_state_blend.c
+++ b/src/gallium/drivers/softpipe/sp_state_blend.c
@@ -61,7 +61,7 @@
 
 
 void softpipe_set_blend_color( struct pipe_context *pipe,
-			     const struct pipe_blend_color *blend_color )
+                               const struct pipe_blend_color *blend_color )
 {
    struct softpipe_context *softpipe = softpipe_context(pipe);
 
@@ -80,7 +80,7 @@
 
 void *
 softpipe_create_depth_stencil_state(struct pipe_context *pipe,
-				    const struct pipe_depth_stencil_alpha_state *depth_stencil)
+                                    const struct pipe_depth_stencil_alpha_state *depth_stencil)
 {
    return mem_dup(depth_stencil, sizeof(*depth_stencil));
 }
@@ -101,3 +101,13 @@
 {
    FREE( depth );
 }
+
+void softpipe_set_stencil_ref( struct pipe_context *pipe,
+                               const struct pipe_stencil_ref *stencil_ref )
+{
+   struct softpipe_context *softpipe = softpipe_context(pipe);
+
+   softpipe->stencil_ref = *stencil_ref;
+
+   softpipe->dirty |= SP_NEW_DEPTH_STENCIL_ALPHA;
+}
diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.c b/src/gallium/drivers/softpipe/sp_tex_sample.c
index 473ec3e..ecd6b39 100644
--- a/src/gallium/drivers/softpipe/sp_tex_sample.c
+++ b/src/gallium/drivers/softpipe/sp_tex_sample.c
@@ -1327,6 +1327,11 @@
 }
 
 
+/**
+ * Compute nearest mipmap level from texcoords.
+ * Then sample the texture level for four elements of a quad.
+ * \param c0  the LOD bias factors, or absolute LODs (depending on control)
+ */
 static void
 mip_filter_nearest(struct tgsi_sampler *tgsi_sampler,
                    const float s[QUAD_SIZE],
@@ -1563,8 +1568,8 @@
 
 
 /**
- * Compute which cube face is referenced by each texcoord and put that
- * info into the sampler faces[] array.  Then sample the cube faces
+ * Use 3D texcoords to choose a cube face, then sample the 2D cube faces.
+ * Put face info into the sampler faces[] array.
  */
 static void
 sample_cube(struct tgsi_sampler *tgsi_sampler,
@@ -1578,11 +1583,12 @@
    struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler);
    unsigned j;
    float ssss[4], tttt[4];
+   unsigned face;
 
    /*
      major axis
-     direction     target                             sc     tc    ma
-     ----------    -------------------------------    ---    ---   ---
+     direction    target                             sc     tc    ma
+     ----------   -------------------------------    ---    ---   ---
      +rx          TEXTURE_CUBE_MAP_POSITIVE_X_EXT    -rz    -ry   rx
      -rx          TEXTURE_CUBE_MAP_NEGATIVE_X_EXT    +rz    -ry   rx
      +ry          TEXTURE_CUBE_MAP_POSITIVE_Y_EXT    +rx    +rz   ry
@@ -1590,56 +1596,96 @@
      +rz          TEXTURE_CUBE_MAP_POSITIVE_Z_EXT    +rx    -ry   rz
      -rz          TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT    -rx    -ry   rz
    */
-   for (j = 0; j < QUAD_SIZE; j++) {
-      float rx = s[j];
-      float ry = t[j];
-      float rz = p[j];
+
+   /* First choose the cube face.
+    * Use the same cube face for all four pixels in the quad.
+    *
+    * This isn't ideal, but if we want to use a different cube face
+    * per pixel in the quad, we'd have to also compute the per-face
+    * LOD here too.  That's because the four post-face-selection
+    * texcoords are no longer related to each other (they're
+    * per-face!)  so we can't use subtraction to compute the partial
+    * deriviates to compute the LOD.  Doing so (near cube edges
+    * anyway) gives us pretty much random values.
+    */
+   {
+      /* use the average of the four pixel's texcoords to choose the face */
+      const float rx = 0.25 * (s[0] + s[1] + s[2] + s[3]);
+      const float ry = 0.25 * (t[0] + t[1] + t[2] + t[3]);
+      const float rz = 0.25 * (p[0] + p[1] + p[2] + p[3]);
       const float arx = fabsf(rx), ary = fabsf(ry), arz = fabsf(rz);
-      unsigned face;
-      float sc, tc, ma;
 
       if (arx >= ary && arx >= arz) {
          if (rx >= 0.0F) {
             face = PIPE_TEX_FACE_POS_X;
-            sc = -rz;
-            tc = -ry;
-            ma = arx;
          }
          else {
             face = PIPE_TEX_FACE_NEG_X;
-            sc = rz;
-            tc = -ry;
-            ma = arx;
          }
       }
       else if (ary >= arx && ary >= arz) {
          if (ry >= 0.0F) {
             face = PIPE_TEX_FACE_POS_Y;
-            sc = rx;
-            tc = rz;
-            ma = ary;
          }
          else {
             face = PIPE_TEX_FACE_NEG_Y;
-            sc = rx;
-            tc = -rz;
-            ma = ary;
          }
       }
       else {
          if (rz > 0.0F) {
             face = PIPE_TEX_FACE_POS_Z;
-            sc = rx;
-            tc = -ry;
-            ma = arz;
          }
          else {
             face = PIPE_TEX_FACE_NEG_Z;
-            sc = -rx;
-            tc = -ry;
-            ma = arz;
          }
       }
+   }
+
+   /* Now compute the 2D _face_ texture coords from the
+    * 3D _cube_ texture coords.
+    */
+   for (j = 0; j < QUAD_SIZE; j++) {
+      const float rx = s[j], ry = t[j], rz = p[j];
+      const float arx = fabsf(rx), ary = fabsf(ry), arz = fabsf(rz);
+      float sc, tc, ma;
+
+      switch (face) {
+      case PIPE_TEX_FACE_POS_X:
+         sc = -rz;
+         tc = -ry;
+         ma = arx;
+         break;
+      case PIPE_TEX_FACE_NEG_X:
+         sc = rz;
+         tc = -ry;
+         ma = arx;
+         break;
+      case PIPE_TEX_FACE_POS_Y:
+         sc = rx;
+         tc = rz;
+         ma = ary;
+         break;
+      case PIPE_TEX_FACE_NEG_Y:
+         sc = rx;
+         tc = -rz;
+         ma = ary;
+         break;
+      case PIPE_TEX_FACE_POS_Z:
+         sc = rx;
+         tc = -ry;
+         ma = arz;
+         break;
+      case PIPE_TEX_FACE_NEG_Z:
+         sc = -rx;
+         tc = -ry;
+         ma = arz;
+         break;
+      default:
+         assert(0 && "bad cube face");
+         sc = 0.0F;
+         tc = 0.0F;
+         ma = 0.0F;
+      }
 
       {
 	 const float ima = 1.0 / ma;
diff --git a/src/gallium/drivers/softpipe/sp_video_context.c b/src/gallium/drivers/softpipe/sp_video_context.c
index d8b5b31..7a3a636 100644
--- a/src/gallium/drivers/softpipe/sp_video_context.c
+++ b/src/gallium/drivers/softpipe/sp_video_context.c
@@ -209,7 +209,6 @@
       dsa.stencil[i].fail_op = PIPE_STENCIL_OP_KEEP;
       dsa.stencil[i].zpass_op = PIPE_STENCIL_OP_KEEP;
       dsa.stencil[i].zfail_op = PIPE_STENCIL_OP_KEEP;
-      dsa.stencil[i].ref_value = 0;
       dsa.stencil[i].valuemask = 0;
       dsa.stencil[i].writemask = 0;
    }
diff --git a/src/gallium/drivers/svga/svga_context.h b/src/gallium/drivers/svga/svga_context.h
index f9a641c..03302e2 100644
--- a/src/gallium/drivers/svga/svga_context.h
+++ b/src/gallium/drivers/svga/svga_context.h
@@ -116,7 +116,6 @@
    /* SVGA3D has one ref/mask/writemask triple shared between front &
     * back face stencil.  We really need two:
     */
-   unsigned stencil_ref:8;
    unsigned stencil_mask:8;
    unsigned stencil_writemask:8;
 
@@ -199,6 +198,7 @@
    struct pipe_poly_stipple poly_stipple;
    struct pipe_scissor_state scissor;
    struct pipe_blend_color blend_color;
+   struct pipe_stencil_ref stencil_ref;
    struct pipe_clip_state clip;
    struct pipe_viewport_state viewport;
 
@@ -376,6 +376,7 @@
 #define SVGA_NEW_VS_RESULT           0x1000000
 #define SVGA_NEW_ZERO_STRIDE         0x2000000
 #define SVGA_NEW_TEXTURE_FLAGS       0x4000000
+#define SVGA_NEW_STENCIL_REF         0x8000000
 
 
 
diff --git a/src/gallium/drivers/svga/svga_draw.c b/src/gallium/drivers/svga/svga_draw.c
index f4d2d89..8b7ca2e 100644
--- a/src/gallium/drivers/svga/svga_draw.c
+++ b/src/gallium/drivers/svga/svga_draw.c
@@ -253,7 +253,9 @@
          assert(index_bias >= 0);
          assert(min_index <= max_index);
          assert(offset + index_bias*stride < size);
-         assert(offset + (index_bias + min_index)*stride < size);
+         if (min_index != ~0) {
+            assert(offset + (index_bias + min_index) * stride < size);
+         }
 
          switch (hwtnl->cmd.vdecl[i].identity.type) {
          case SVGA3D_DECLTYPE_FLOAT1:
@@ -314,7 +316,9 @@
          }
 
          assert(!stride || width <= stride);
-         assert(offset + (index_bias + max_index)*stride + width <= size);
+         if (max_index != ~0) {
+            assert(offset + (index_bias + max_index) * stride + width <= size);
+         }
       }
 
       assert(range->indexWidth == range->indexArray.stride);
diff --git a/src/gallium/drivers/svga/svga_pipe_blend.c b/src/gallium/drivers/svga/svga_pipe_blend.c
index 9dd6fb0..b60117f 100644
--- a/src/gallium/drivers/svga/svga_pipe_blend.c
+++ b/src/gallium/drivers/svga/svga_pipe_blend.c
@@ -228,7 +228,7 @@
 
    svga->curr.blend_color = *blend_color;
 
-   svga->dirty |= SVGA_NEW_BLEND;
+   svga->dirty |= SVGA_NEW_BLEND_COLOR;
 }
 
 
diff --git a/src/gallium/drivers/svga/svga_pipe_depthstencil.c b/src/gallium/drivers/svga/svga_pipe_depthstencil.c
index 12bbd23..c317bec 100644
--- a/src/gallium/drivers/svga/svga_pipe_depthstencil.c
+++ b/src/gallium/drivers/svga/svga_pipe_depthstencil.c
@@ -89,7 +89,6 @@
       /* SVGA3D has one ref/mask/writemask triple shared between front &
        * back face stencil.  We really need two:
        */
-      ds->stencil_ref       = templ->stencil[0].ref_value & 0xff;
       ds->stencil_mask      = templ->stencil[0].valuemask & 0xff;
       ds->stencil_writemask = templ->stencil[0].writemask & 0xff;
    }
@@ -102,7 +101,6 @@
       ds->stencil[1].zfail  = svga_translate_stencil_op(templ->stencil[1].zfail_op);
       ds->stencil[1].pass   = svga_translate_stencil_op(templ->stencil[1].zpass_op);
 
-      ds->stencil_ref       = templ->stencil[1].ref_value & 0xff;
       ds->stencil_mask      = templ->stencil[1].valuemask & 0xff;
       ds->stencil_writemask = templ->stencil[1].writemask & 0xff;
    }
@@ -139,12 +137,24 @@
 }
 
 
+static void svga_set_stencil_ref( struct pipe_context *pipe,
+                                  const struct pipe_stencil_ref *stencil_ref )
+{
+   struct svga_context *svga = svga_context(pipe);
+
+   svga->curr.stencil_ref = *stencil_ref;
+
+   svga->dirty |= SVGA_NEW_STENCIL_REF;
+}
+
 
 void svga_init_depth_stencil_functions( struct svga_context *svga )
 {
    svga->pipe.create_depth_stencil_alpha_state = svga_create_depth_stencil_state;
    svga->pipe.bind_depth_stencil_alpha_state = svga_bind_depth_stencil_state;
    svga->pipe.delete_depth_stencil_alpha_state = svga_delete_depth_stencil_state;
+
+   svga->pipe.set_stencil_ref = svga_set_stencil_ref;
 }
 
 
diff --git a/src/gallium/drivers/svga/svga_pipe_sampler.c b/src/gallium/drivers/svga/svga_pipe_sampler.c
index b700813..224c4f4 100644
--- a/src/gallium/drivers/svga/svga_pipe_sampler.c
+++ b/src/gallium/drivers/svga/svga_pipe_sampler.c
@@ -27,7 +27,6 @@
 #include "pipe/p_defines.h"
 #include "util/u_math.h"
 #include "util/u_memory.h"
-#include "util/u_pack_color.h"
 #include "tgsi/tgsi_parse.h"
 
 #include "svga_context.h"
@@ -97,13 +96,12 @@
 {
    struct svga_context *svga = svga_context(pipe);
    struct svga_sampler_state *cso = CALLOC_STRUCT( svga_sampler_state );
-   union util_color uc;
    
    cso->mipfilter = translate_mip_filter(sampler->min_mip_filter);
    cso->magfilter = translate_img_filter( sampler->mag_img_filter );
    cso->minfilter = translate_img_filter( sampler->min_img_filter );
-   cso->aniso_level = MAX2( (unsigned) sampler->max_anisotropy, 1 );
-   if(cso->aniso_level != 1)
+   cso->aniso_level = MAX2( sampler->max_anisotropy, 1 );
+   if(sampler->max_anisotropy)
       cso->magfilter = cso->minfilter = SVGA3D_TEX_FILTER_ANISOTROPIC;
    cso->lod_bias = sampler->lod_bias;
    cso->addressu = translate_wrap_mode(sampler->wrap_s);
@@ -114,14 +112,12 @@
    cso->compare_func = sampler->compare_func;
 
    {
-      ubyte r = float_to_ubyte(sampler->border_color[0]);
-      ubyte g = float_to_ubyte(sampler->border_color[1]);
-      ubyte b = float_to_ubyte(sampler->border_color[2]);
-      ubyte a = float_to_ubyte(sampler->border_color[3]);
+      uint32 r = float_to_ubyte(sampler->border_color[0]);
+      uint32 g = float_to_ubyte(sampler->border_color[1]);
+      uint32 b = float_to_ubyte(sampler->border_color[2]);
+      uint32 a = float_to_ubyte(sampler->border_color[3]);
 
-      util_pack_color_ub( r, g, b, a,
-                          PIPE_FORMAT_B8G8R8A8_UNORM, &uc);
-      cso->bordercolor = uc.ui;
+      cso->bordercolor = (a << 24) | (r << 16) | (g << 8) | b;
    }
 
    /* No SVGA3D support for:
diff --git a/src/gallium/drivers/svga/svga_screen.c b/src/gallium/drivers/svga/svga_screen.c
index 735cdfd..414ac52 100644
--- a/src/gallium/drivers/svga/svga_screen.c
+++ b/src/gallium/drivers/svga/svga_screen.c
@@ -104,7 +104,9 @@
       return SVGA_MAX_POINTSIZE;
 
    case PIPE_CAP_MAX_TEXTURE_ANISOTROPY:
-      return 4.0;
+      if(!sws->get_cap(sws, SVGA3D_DEVCAP_MAX_TEXTURE_ANISOTROPY, &result))
+         return 4.0;
+      return result.u;
 
    case PIPE_CAP_MAX_TEXTURE_LOD_BIAS:
       return 16.0;
@@ -133,12 +135,33 @@
       return 1;
    case PIPE_CAP_TEXTURE_SHADOW_MAP:
       return 1;
+
    case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
-      return SVGA_MAX_TEXTURE_LEVELS;
+      {
+         unsigned levels = SVGA_MAX_TEXTURE_LEVELS;
+         if (sws->get_cap(sws, SVGA3D_DEVCAP_MAX_TEXTURE_WIDTH, &result))
+            levels = MIN2(util_logbase2(result.u) + 1, levels);
+         else
+            levels = 12 /* 2048x2048 */;
+         if (sws->get_cap(sws, SVGA3D_DEVCAP_MAX_TEXTURE_HEIGHT, &result))
+            levels = MIN2(util_logbase2(result.u) + 1, levels);
+         else
+            levels = 12 /* 2048x2048 */;
+         return levels;
+      }
+
    case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
-      return 8;  /* max 128x128x128 */
+      if (!sws->get_cap(sws, SVGA3D_DEVCAP_MAX_VOLUME_EXTENT, &result))
+         return 8;  /* max 128x128x128 */
+      return MIN2(util_logbase2(result.u) + 1, SVGA_MAX_TEXTURE_LEVELS);
+
    case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
-      return SVGA_MAX_TEXTURE_LEVELS;
+      /*
+       * No mechanism to query the host, and at least limited to 2048x2048 on
+       * certain hardware.
+       */
+      return MIN2(screen->get_paramf(screen, PIPE_CAP_MAX_TEXTURE_2D_LEVELS),
+                  12.0 /* 2048x2048 */);
 
    case PIPE_CAP_TEXTURE_MIRROR_REPEAT: /* req. for GL 1.4 */
       return 1;
diff --git a/src/gallium/drivers/svga/svga_screen_texture.h b/src/gallium/drivers/svga/svga_screen_texture.h
index 43853d4..24c1f78 100644
--- a/src/gallium/drivers/svga/svga_screen_texture.h
+++ b/src/gallium/drivers/svga/svga_screen_texture.h
@@ -39,7 +39,7 @@
 enum SVGA3dSurfaceFormat;
 
 
-#define SVGA_MAX_TEXTURE_LEVELS 12 /* 2048x2048 */
+#define SVGA_MAX_TEXTURE_LEVELS 16
 
 
 /**
diff --git a/src/gallium/drivers/svga/svga_state_rss.c b/src/gallium/drivers/svga/svga_state_rss.c
index 5ce9b4e..107cc40 100644
--- a/src/gallium/drivers/svga/svga_state_rss.c
+++ b/src/gallium/drivers/svga/svga_state_rss.c
@@ -100,6 +100,17 @@
       }
    }
 
+   if (dirty & SVGA_NEW_BLEND_COLOR) {
+      uint32 color;
+      uint32 r = float_to_ubyte(svga->curr.blend_color.color[0]);
+      uint32 g = float_to_ubyte(svga->curr.blend_color.color[1]);
+      uint32 b = float_to_ubyte(svga->curr.blend_color.color[2]);
+      uint32 a = float_to_ubyte(svga->curr.blend_color.color[3]);
+
+      color = (a << 24) | (r << 16) | (g << 8) | b;
+
+      EMIT_RS( svga, color, BLENDCOLOR, fail );
+   }
 
    if (dirty & (SVGA_NEW_DEPTH_STENCIL | SVGA_NEW_RAST)) {
       const struct svga_depth_stencil_state *curr = svga->curr.depth; 
@@ -123,8 +134,7 @@
          EMIT_RS( svga, curr->stencil[0].fail,  STENCILFAIL, fail );
          EMIT_RS( svga, curr->stencil[0].zfail, STENCILZFAIL, fail );
          EMIT_RS( svga, curr->stencil[0].pass,  STENCILPASS, fail );
-         
-         EMIT_RS( svga, curr->stencil_ref, STENCILREF, fail );
+
          EMIT_RS( svga, curr->stencil_mask, STENCILMASK, fail );
          EMIT_RS( svga, curr->stencil_writemask, STENCILWRITEMASK, fail );
       }
@@ -160,7 +170,6 @@
          EMIT_RS( svga, curr->stencil[ccw].zfail, CCWSTENCILZFAIL, fail );
          EMIT_RS( svga, curr->stencil[ccw].pass,  CCWSTENCILPASS, fail );
 
-         EMIT_RS( svga, curr->stencil_ref, STENCILREF, fail );
          EMIT_RS( svga, curr->stencil_mask, STENCILMASK, fail );
          EMIT_RS( svga, curr->stencil_writemask, STENCILWRITEMASK, fail );
       }
@@ -178,6 +187,9 @@
       }
    }
 
+   if (dirty & SVGA_NEW_STENCIL_REF) {
+      EMIT_RS( svga, svga->curr.stencil_ref.ref_value[0], STENCILREF, fail );
+   }
 
    if (dirty & SVGA_NEW_RAST)
    {
@@ -231,13 +243,10 @@
       memcpy( rs,
               queue.rs,
               queue.rs_count * sizeof queue.rs[0]);
-      
+
       SVGA_FIFOCommitAll( svga->swc );
    }
 
-   /* Also blend color:
-    */
-
    return 0;
 
 fail:
@@ -257,7 +266,9 @@
    "hw rss state",
 
    (SVGA_NEW_BLEND |
+    SVGA_NEW_BLEND_COLOR |
     SVGA_NEW_DEPTH_STENCIL |
+    SVGA_NEW_STENCIL_REF |
     SVGA_NEW_RAST |
     SVGA_NEW_FRAME_BUFFER |
     SVGA_NEW_NEED_PIPELINE),
diff --git a/src/gallium/drivers/svga/svga_tgsi_insn.c b/src/gallium/drivers/svga/svga_tgsi_insn.c
index be821e9..6debd98 100644
--- a/src/gallium/drivers/svga/svga_tgsi_insn.c
+++ b/src/gallium/drivers/svga/svga_tgsi_insn.c
@@ -525,6 +525,7 @@
       break;
    default:
       assert(0);
+      opcode = inst_token( SVGA3DOP_NOP );
       break;
    }
 
diff --git a/src/gallium/drivers/svga/svgadump/svga_shader.h b/src/gallium/drivers/svga/svgadump/svga_shader.h
index 9217af2..5db64bf 100644
--- a/src/gallium/drivers/svga/svgadump/svga_shader.h
+++ b/src/gallium/drivers/svga/svgadump/svga_shader.h
@@ -98,21 +98,33 @@
 #define PS_TEXTURETYPE_CUBE      SVGA3DSAMP_CUBE
 #define PS_TEXTURETYPE_VOLUME    SVGA3DSAMP_VOLUME
 
-struct ps_sampleinfo
+struct sh_sampleinfo
 {
    unsigned unused:27;
    unsigned texture_type:4;
    unsigned is_reg:1;
 };
 
-struct vs_semantic
+struct sh_semantic
 {
-   unsigned usage:5;
-   unsigned unused1:11;
+   unsigned usage:4;
+   unsigned unused1:12;
    unsigned usage_index:4;
-   unsigned unused2:12;
+   unsigned unused2:11;
+   unsigned is_reg:1;
 };
 
+#define SH_WRITEMASK_0              0x1
+#define SH_WRITEMASK_1              0x2
+#define SH_WRITEMASK_2              0x4
+#define SH_WRITEMASK_3              0x8
+#define SH_WRITEMASK_ALL            0xf
+
+#define SH_DSTMOD_NONE              0x0
+#define SH_DSTMOD_SATURATE          0x1
+#define SH_DSTMOD_PARTIALPRECISION  0x2
+#define SH_DSTMOD_MSAMPCENTROID     0x4
+
 struct sh_dstreg
 {
    unsigned number:11;
@@ -136,17 +148,12 @@
 {
    struct sh_op op;
    union {
-      struct {
-         struct ps_sampleinfo sampleinfo;
-      } ps;
-      struct {
-         struct vs_semantic semantic;
-      } vs;
+      struct sh_sampleinfo sampleinfo;
+      struct sh_semantic semantic;
    } u;
    struct sh_dstreg reg;
 };
 
-
 struct sh_srcreg
 {
    unsigned number:11;
diff --git a/src/gallium/drivers/svga/svgadump/svga_shader_dump.c b/src/gallium/drivers/svga/svgadump/svga_shader_dump.c
index 70e27d8..705ca29 100644
--- a/src/gallium/drivers/svga/svgadump/svga_shader_dump.c
+++ b/src/gallium/drivers/svga/svgadump/svga_shader_dump.c
@@ -40,102 +40,139 @@
 
 struct dump_info
 {
-   SVGA3dShaderVersion version;
+   uint32 version;
    boolean is_ps;
+   int indent;
 };
 
+#define DUMP_MAX_OP_SRC 4
+
+struct dump_op
+{
+   struct sh_op op;
+   struct sh_dstreg dst;
+   struct sh_srcreg dstind;
+   struct sh_srcreg src[DUMP_MAX_OP_SRC];
+   struct sh_srcreg srcind[DUMP_MAX_OP_SRC];
+   struct sh_srcreg p0;
+};
+
+static void
+dump_indent(int indent)
+{
+   int i;
+
+   for (i = 0; i < indent; ++i) {
+      _debug_printf("  ");
+   }
+}
+
 static void dump_op( struct sh_op op, const char *mnemonic )
 {
-   assert( op.predicated == 0 );
    assert( op.is_reg == 0 );
 
+   if (op.predicated) {
+      _debug_printf("(p0) ");
+   }
    if (op.coissue)
       _debug_printf( "+" );
    _debug_printf( "%s", mnemonic );
-   switch (op.control) {
-   case 0:
+
+   switch (op.opcode) {
+   case SVGA3DOP_TEX:
+      switch (op.control) {
+      case 0:
+         break;
+      case 1 /* PROJECT */:
+         _debug_printf("p");
+         break;
+      case 2 /* BIAS */:
+         _debug_printf("b");
+         break;
+      default:
+         assert(0);
+      }
       break;
-   case SVGA3DOPCONT_PROJECT:
-      _debug_printf( "p" );
+
+   case SVGA3DOP_IFC:
+   case SVGA3DOP_BREAKC:
+   case SVGA3DOP_SETP:
+      switch (op.control) {
+      case SVGA3DOPCOMP_GT:
+         _debug_printf("_gt");
+         break;
+      case SVGA3DOPCOMP_EQ:
+         _debug_printf("_eq");
+         break;
+      case SVGA3DOPCOMP_GE:
+         _debug_printf("_ge");
+         break;
+      case SVGA3DOPCOMP_LT:
+         _debug_printf("_lt");
+         break;
+      case SVGA3DOPCOMPC_NE:
+         _debug_printf("_ne");
+         break;
+      case SVGA3DOPCOMP_LE:
+         _debug_printf("_le");
+         break;
+      default:
+         assert(0);
+      }
       break;
-   case SVGA3DOPCONT_BIAS:
-      _debug_printf( "b" );
-      break;
+
    default:
-      assert( 0 );
+      assert(op.control == 0);
    }
 }
 
-
-static void dump_comp_op( struct sh_op op, const char *mnemonic )
+static void
+format_reg(const char *name,
+           const struct sh_reg reg,
+           const struct sh_srcreg *indreg)
 {
-   assert( op.is_reg == 0 );
+   if (reg.relative) {
+      assert(indreg);
 
-   if (op.coissue)
-      _debug_printf( "+" );
-   _debug_printf( "%s", mnemonic );
-   switch (op.control) {
-   case SVGA3DOPCOMP_RESERVED0:
-      break;
-   case SVGA3DOPCOMP_GT:
-      _debug_printf("_gt");
-      break;
-   case SVGA3DOPCOMP_EQ:
-      _debug_printf("_eq");
-      break;
-   case SVGA3DOPCOMP_GE:
-      _debug_printf("_ge");
-      break;
-   case SVGA3DOPCOMP_LT:
-      _debug_printf("_lt");
-      break;
-   case SVGA3DOPCOMPC_NE:
-      _debug_printf("_ne");
-      break;
-   case SVGA3DOPCOMP_LE:
-      _debug_printf("_le");
-      break;
-   case SVGA3DOPCOMP_RESERVED1:
-   default:
-      assert( 0 );
+      if (sh_srcreg_type(*indreg) == SVGA3DREG_LOOP) {
+         _debug_printf("%s[aL+%u]", name, reg.number);
+      } else {
+         _debug_printf("%s[a%u.x+%u]", name, indreg->number, reg.number);
+      }
+   } else {
+      _debug_printf("%s%u", name, reg.number);
    }
 }
 
-
 static void dump_reg( struct sh_reg reg, struct sh_srcreg *indreg, const struct dump_info *di )
 {
-   assert( sh_reg_type( reg ) == SVGA3DREG_CONST || reg.relative == 0 );
    assert( reg.is_reg == 1 );
 
    switch (sh_reg_type( reg )) {
    case SVGA3DREG_TEMP:
-      _debug_printf( "r%u", reg.number );
+      format_reg("r", reg, NULL);
       break;
 
    case SVGA3DREG_INPUT:
-      _debug_printf( "v%u", reg.number );
+      format_reg("v", reg, indreg);
       break;
 
    case SVGA3DREG_CONST:
-      if (reg.relative) {
-         if (sh_srcreg_type( *indreg ) == SVGA3DREG_LOOP)
-            _debug_printf( "c[aL+%u]", reg.number );
-         else
-            _debug_printf( "c[a%u.x+%u]", indreg->number, reg.number );
-      }
-      else
-         _debug_printf( "c%u", reg.number );
+      format_reg("c", reg, indreg);
       break;
 
    case SVGA3DREG_ADDR:    /* VS */
    /* SVGA3DREG_TEXTURE */ /* PS */
-      if (di->is_ps)
-         _debug_printf( "t%u", reg.number );
-      else
-         _debug_printf( "a%u", reg.number );
+      assert(!reg.relative);
+      if (di->is_ps) {
+         format_reg("t", reg, NULL);
+      } else {
+         format_reg("a", reg, NULL);
+      }
       break;
 
    case SVGA3DREG_RASTOUT:
+      assert(!reg.relative);
       switch (reg.number) {
       case 0 /*POSITION*/:
          _debug_printf( "oPos" );
@@ -154,64 +191,69 @@
 
    case SVGA3DREG_ATTROUT:
       assert( reg.number < 2 );
-      _debug_printf( "oD%u", reg.number );
+      format_reg("oD", reg, NULL);
       break;
 
-   case SVGA3DREG_TEXCRDOUT:
-   /* SVGA3DREG_OUTPUT */
-      _debug_printf( "oT%u", reg.number );
+   case SVGA3DREG_TEXCRDOUT:  /* VS */
+   /* SVGA3DREG_OUTPUT */     /* VS3.0+ */
+      if (!di->is_ps && di->version >= SVGA3D_VS_30) {
+         format_reg("o", reg, indreg);
+      } else {
+         format_reg("oT", reg, NULL);
+      }
       break;
 
    case SVGA3DREG_COLOROUT:
-      _debug_printf( "oC%u", reg.number );
+      format_reg("oC", reg, NULL);
       break;
 
    case SVGA3DREG_DEPTHOUT:
-      _debug_printf( "oD%u", reg.number );
+      assert(!reg.relative);
+      assert(reg.number == 0);
+      _debug_printf("oDepth");
       break;
 
    case SVGA3DREG_SAMPLER:
-      _debug_printf( "s%u", reg.number );
+      format_reg("s", reg, NULL);
       break;
 
    case SVGA3DREG_CONSTBOOL:
-      assert( !reg.relative );
-      _debug_printf( "b%u", reg.number );
+      format_reg("b", reg, NULL);
       break;
 
    case SVGA3DREG_CONSTINT:
-      assert( !reg.relative );
-      _debug_printf( "i%u", reg.number );
+      format_reg("i", reg, NULL);
       break;
 
    case SVGA3DREG_LOOP:
+      assert(!reg.relative);
       assert( reg.number == 0 );
       _debug_printf( "aL" );
       break;
 
    case SVGA3DREG_MISCTYPE:
+      assert(!reg.relative);
       switch (reg.number) {
       case SVGA3DMISCREG_POSITION:
-         _debug_printf( "vPos" );
+         _debug_printf("vPos");
          break;
       case SVGA3DMISCREG_FACE:
-         _debug_printf( "vFace" );
+         _debug_printf("vFace");
          break;
       default:
          assert(0);
-         break;
+         _debug_printf("???");
       }
       break;
 
    case SVGA3DREG_LABEL:
-      _debug_printf( "l%u", reg.number );
+      format_reg("l", reg, NULL);
       break;
 
    case SVGA3DREG_PREDICATE:
-      _debug_printf( "p%u", reg.number );
+      format_reg("p", reg, NULL);
       break;
 
-
    default:
       assert( 0 );
       _debug_printf( "???" );
@@ -233,8 +275,11 @@
    _debug_printf( bdata ? "TRUE" : "FALSE" );
 }
 
-static void dump_sampleinfo( struct ps_sampleinfo sampleinfo )
+static void
+dump_sampleinfo(struct sh_sampleinfo sampleinfo)
 {
+   assert( sampleinfo.is_reg == 1 );
+
    switch (sampleinfo.texture_type) {
    case SVGA3DSAMP_2D:
       _debug_printf( "_2d" );
@@ -250,68 +295,72 @@
    }
 }
 
-
-static void dump_usageinfo( struct vs_semantic semantic )
+static void
+dump_semantic(uint usage,
+              uint usage_index)
 {
-   switch (semantic.usage) {
+   switch (usage) {
    case SVGA3D_DECLUSAGE_POSITION:
-      _debug_printf("_position" );
+      _debug_printf("_position");
       break;
    case SVGA3D_DECLUSAGE_BLENDWEIGHT:
-      _debug_printf("_blendweight" );
+      _debug_printf("_blendweight");
       break;
    case SVGA3D_DECLUSAGE_BLENDINDICES:
-      _debug_printf("_blendindices" );
+      _debug_printf("_blendindices");
       break;
    case SVGA3D_DECLUSAGE_NORMAL:
-      _debug_printf("_normal" );
+      _debug_printf("_normal");
       break;
    case SVGA3D_DECLUSAGE_PSIZE:
-      _debug_printf("_psize" );
+      _debug_printf("_psize");
       break;
    case SVGA3D_DECLUSAGE_TEXCOORD:
       _debug_printf("_texcoord");
       break;
    case SVGA3D_DECLUSAGE_TANGENT:
-      _debug_printf("_tangent" );
+      _debug_printf("_tangent");
       break;
    case SVGA3D_DECLUSAGE_BINORMAL:
-      _debug_printf("_binormal" );
+      _debug_printf("_binormal");
       break;
    case SVGA3D_DECLUSAGE_TESSFACTOR:
-      _debug_printf("_tessfactor" );
+      _debug_printf("_tessfactor");
       break;
    case SVGA3D_DECLUSAGE_POSITIONT:
-      _debug_printf("_positiont" );
+      _debug_printf("_positiont");
       break;
    case SVGA3D_DECLUSAGE_COLOR:
-      _debug_printf("_color" );
+      _debug_printf("_color");
       break;
    case SVGA3D_DECLUSAGE_FOG:
-      _debug_printf("_fog" );
+      _debug_printf("_fog");
       break;
    case SVGA3D_DECLUSAGE_DEPTH:
-      _debug_printf("_depth" );
+      _debug_printf("_depth");
       break;
    case SVGA3D_DECLUSAGE_SAMPLE:
       _debug_printf("_sample");
       break;
    default:
-      assert( 0 );
-      return;
+      assert(!"Unknown usage");
+      _debug_printf("_???");
    }
 
-   if (semantic.usage_index != 0) {
-      _debug_printf("%d", semantic.usage_index );
+   if (usage_index) {
+      _debug_printf("%u", usage_index);
    }
 }
 
-static void dump_dstreg( struct sh_dstreg dstreg, const struct dump_info *di )
+static void
+dump_dstreg(struct sh_dstreg dstreg,
+            struct sh_srcreg *indreg,
+            const struct dump_info *di)
 {
    union {
       struct sh_reg reg;
       struct sh_dstreg dstreg;
-   } u;
+   } u = { { 0 } };
 
    assert( (dstreg.modifier & (SVGA3DDSTMOD_SATURATE | SVGA3DDSTMOD_PARTIALPRECISION)) == dstreg.modifier );
 
@@ -346,7 +395,7 @@
    _debug_printf( " " );
 
    u.dstreg = dstreg;
-   dump_reg( u.reg, NULL, di );
+   dump_reg( u.reg, indreg, di);
    if (dstreg.write_mask != SVGA3DWRITEMASK_ALL) {
       _debug_printf( "." );
       if (dstreg.write_mask & SVGA3DWRITEMASK_0)
@@ -362,23 +411,13 @@
 
 static void dump_srcreg( struct sh_srcreg srcreg, struct sh_srcreg *indreg, const struct dump_info *di )
 {
-   union {
-      struct sh_reg reg;
-      struct sh_srcreg srcreg;
-   } u;
-
    switch (srcreg.modifier) {
    case SVGA3DSRCMOD_NEG:
    case SVGA3DSRCMOD_BIASNEG:
    case SVGA3DSRCMOD_SIGNNEG:
    case SVGA3DSRCMOD_X2NEG:
-      _debug_printf( "-" );
-      break;
-   case SVGA3DSRCMOD_ABS:
-      _debug_printf( "|" );
-      break;
    case SVGA3DSRCMOD_ABSNEG:
-      _debug_printf( "-|" );
+      _debug_printf( "-" );
       break;
    case SVGA3DSRCMOD_COMP:
       _debug_printf( "1-" );
@@ -386,19 +425,13 @@
    case SVGA3DSRCMOD_NOT:
       _debug_printf( "!" );
    }
-
-   u.srcreg = srcreg;
-   dump_reg( u.reg, indreg, di );
+   dump_reg( *(struct sh_reg *) &srcreg, indreg, di );
    switch (srcreg.modifier) {
    case SVGA3DSRCMOD_NONE:
    case SVGA3DSRCMOD_NEG:
    case SVGA3DSRCMOD_COMP:
    case SVGA3DSRCMOD_NOT:
       break;
-   case SVGA3DSRCMOD_ABS:
-   case SVGA3DSRCMOD_ABSNEG:
-      _debug_printf( "|" );
-      break;
    case SVGA3DSRCMOD_BIAS:
    case SVGA3DSRCMOD_BIASNEG:
       _debug_printf( "_bias" );
@@ -417,6 +450,10 @@
    case SVGA3DSRCMOD_DW:
       _debug_printf( "_dw" );
       break;
+   case SVGA3DSRCMOD_ABS:
+   case SVGA3DSRCMOD_ABSNEG:
+      _debug_printf("_abs");
+      break;
    default:
       assert( 0 );
    }
@@ -434,58 +471,132 @@
    }
 }
 
+static void
+parse_op(struct dump_info *di,
+         const uint **token,
+         struct dump_op *op,
+         uint num_dst,
+         uint num_src)
+{
+   uint i;
+
+   assert(num_dst <= 1);
+   assert(num_src <= DUMP_MAX_OP_SRC);
+
+   op->op = *(struct sh_op *)*token;
+   *token += sizeof(struct sh_op) / sizeof(uint);
+
+   if (num_dst >= 1) {
+      op->dst = *(struct sh_dstreg *)*token;
+      *token += sizeof(struct sh_dstreg) / sizeof(uint);
+      if (op->dst.relative &&
+          (!di->is_ps && di->version >= SVGA3D_VS_30)) {
+         op->dstind = *(struct sh_srcreg *)*token;
+         *token += sizeof(struct sh_srcreg) / sizeof(uint);
+      }
+   }
+
+   if (op->op.predicated) {
+      op->p0 = *(struct sh_srcreg *)*token;
+      *token += sizeof(struct sh_srcreg) / sizeof(uint);
+   }
+
+   for (i = 0; i < num_src; ++i) {
+      op->src[i] = *(struct sh_srcreg *)*token;
+      *token += sizeof(struct sh_srcreg) / sizeof(uint);
+      if (op->src[i].relative &&
+          ((!di->is_ps && di->version >= SVGA3D_VS_20) ||
+          (di->is_ps && di->version >= SVGA3D_PS_30))) {
+         op->srcind[i] = *(struct sh_srcreg *)*token;
+         *token += sizeof(struct sh_srcreg) / sizeof(uint);
+      }
+   }
+}
+
+static void
+dump_inst(struct dump_info *di,
+          const unsigned **assem,
+          struct sh_op op,
+          const struct sh_opcode_info *info)
+{
+   struct dump_op dop;
+   boolean not_first_arg = FALSE;
+   uint i;
+
+   assert(info->num_dst <= 1);
+
+   di->indent -= info->pre_dedent;
+   dump_indent(di->indent);
+   di->indent += info->post_indent;
+
+   dump_op(op, info->mnemonic);
+
+   parse_op(di, assem, &dop, info->num_dst, info->num_src);
+   if (info->num_dst > 0) {
+      dump_dstreg(dop.dst, &dop.dstind, di);
+      not_first_arg = TRUE;
+   }
+
+   for (i = 0; i < info->num_src; i++) {
+      if (not_first_arg) {
+         _debug_printf(", ");
+      } else {
+         _debug_printf(" ");
+      }
+      dump_srcreg(dop.src[i], &dop.srcind[i], di);
+      not_first_arg = TRUE;
+   }
+
+   _debug_printf("\n");
+}
+
 void
 svga_shader_dump(
    const unsigned *assem,
    unsigned dwords,
    unsigned do_binary )
 {
-   const unsigned *start = assem;
    boolean finished = FALSE;
    struct dump_info di;
-   unsigned i;
 
-   if (do_binary) {
-      for (i = 0; i < dwords; i++) 
-         _debug_printf("  0x%08x,\n", assem[i]);
-      
-      _debug_printf("\n\n");
-   }
-
-   di.version.value = *assem++;
-   di.is_ps = (di.version.type == SVGA3D_PS_TYPE);
+   di.version = *assem++;
+   di.is_ps = (di.version & 0xFFFF0000) == 0xFFFF0000;
+   di.indent = 0;
 
    _debug_printf(
       "%s_%u_%u\n",
       di.is_ps ? "ps" : "vs",
-      di.version.major,
-      di.version.minor );
+      (di.version >> 8) & 0xff,
+      di.version & 0xff );
 
    while (!finished) {
       struct sh_op op = *(struct sh_op *) assem;
 
-      if (assem - start >= dwords) {
-         _debug_printf("... ran off end of buffer\n");
-         assert(0);
-         return;
-      }
-
       switch (op.opcode) {
       case SVGA3DOP_DCL:
          {
             struct sh_dcl dcl = *(struct sh_dcl *) assem;
 
             _debug_printf( "dcl" );
-            if (sh_dstreg_type( dcl.reg ) == SVGA3DREG_SAMPLER)
-               dump_sampleinfo( dcl.u.ps.sampleinfo );
-            else if (di.is_ps) {
-               if (di.version.major == 3 && 
-                   sh_dstreg_type( dcl.reg ) != SVGA3DREG_MISCTYPE)
-                  dump_usageinfo( dcl.u.vs.semantic );
+            switch (sh_dstreg_type(dcl.reg)) {
+            case SVGA3DREG_INPUT:
+               if ((di.is_ps && di.version >= SVGA3D_PS_30) ||
+                   (!di.is_ps && di.version >= SVGA3D_VS_30)) {
+                  dump_semantic(dcl.u.semantic.usage,
+                                dcl.u.semantic.usage_index);
+               }
+               break;
+            case SVGA3DREG_TEXCRDOUT:
+               if (!di.is_ps && di.version >= SVGA3D_VS_30) {
+                  dump_semantic(dcl.u.semantic.usage,
+                                dcl.u.semantic.usage_index);
+               }
+               break;
+            case SVGA3DREG_SAMPLER:
+               dump_sampleinfo( dcl.u.sampleinfo );
+               break;
             }
-            else
-               dump_usageinfo( dcl.u.vs.semantic );
-            dump_dstreg( dcl.reg, &di );
+            dump_dstreg(dcl.reg, NULL, &di);
             _debug_printf( "\n" );
             assem += sizeof( struct sh_dcl ) / sizeof( unsigned );
          }
@@ -518,54 +629,38 @@
          break;
 
       case SVGA3DOP_TEXCOORD:
-         assert( di.is_ps );
-         dump_op( op, "texcoord" );
-         if (0) {
-            struct sh_dstop dstop = *(struct sh_dstop *) assem;
-            dump_dstreg( dstop.dst, &di );
-            assem += sizeof( struct sh_dstop ) / sizeof( unsigned );
+         {
+            struct sh_opcode_info info = *svga_opcode_info(op.opcode);
+
+            assert(di.is_ps);
+            if (di.version > SVGA3D_PS_13) {
+               assert(info.num_src == 0);
+
+               info.num_src = 1;
+            }
+
+            dump_inst(&di, &assem, op, &info);
          }
-         else {
-            struct sh_unaryop unaryop = *(struct sh_unaryop *) assem;
-            dump_dstreg( unaryop.dst, &di );
-            _debug_printf( ", " );
-            dump_srcreg( unaryop.src, NULL, &di );
-            assem += sizeof( struct sh_unaryop ) / sizeof( unsigned );
-         }
-         _debug_printf( "\n" );
          break;
 
       case SVGA3DOP_TEX:
-         assert( di.is_ps );
-         if (0) {
-            dump_op( op, "tex" );
-            if (0) {
-               struct sh_dstop dstop = *(struct sh_dstop *) assem;
+         {
+            struct sh_opcode_info info = *svga_opcode_info(op.opcode);
 
-               dump_dstreg( dstop.dst, &di );
-               assem += sizeof( struct sh_dstop ) / sizeof( unsigned );
+            assert(di.is_ps);
+            if (di.version > SVGA3D_PS_13) {
+               assert(info.num_src == 0);
+
+               if (di.version > SVGA3D_PS_14) {
+                  info.num_src = 2;
+                  info.mnemonic = "texld";
+               } else {
+                  info.num_src = 1;
+               }
             }
-            else {
-               struct sh_unaryop unaryop = *(struct sh_unaryop *) assem;
 
-               dump_dstreg( unaryop.dst, &di );
-               _debug_printf( ", " );
-               dump_srcreg( unaryop.src, NULL, &di );
-               assem += sizeof( struct sh_unaryop ) / sizeof( unsigned );
-            }
+            dump_inst(&di, &assem, op, &info);
          }
-         else {
-            struct sh_binaryop binaryop = *(struct sh_binaryop *) assem;
-
-            dump_op( op, "texld" );
-            dump_dstreg( binaryop.dst, &di );
-            _debug_printf( ", " );
-            dump_srcreg( binaryop.src0, NULL, &di );
-            _debug_printf( ", " );
-            dump_srcreg( binaryop.src1, NULL, &di );
-            assem += sizeof( struct sh_binaryop ) / sizeof( unsigned );
-         }
-         _debug_printf( "\n" );
          break;
 
       case SVGA3DOP_DEF:
@@ -581,6 +676,21 @@
          }
          break;
 
+      case SVGA3DOP_SINCOS:
+         {
+            struct sh_opcode_info info = *svga_opcode_info(op.opcode);
+
+            if ((di.is_ps && di.version >= SVGA3D_PS_30) ||
+                (!di.is_ps && di.version >= SVGA3D_VS_30)) {
+               assert(info.num_src == 3);
+
+               info.num_src = 1;
+            }
+
+            dump_inst(&di, &assem, op, &info);
+         }
+         break;
+
       case SVGA3DOP_PHASE:
          _debug_printf( "phase\n" );
          assem += sizeof( struct sh_op ) / sizeof( unsigned );
@@ -595,59 +705,15 @@
          }
          break;
 
-      case SVGA3DOP_RET:
-         _debug_printf( "ret\n" );
-         assem += sizeof( struct sh_op ) / sizeof( unsigned );
-         break;
-
       case SVGA3DOP_END:
-         _debug_printf( "end\n" );
          finished = TRUE;
          break;
 
       default:
          {
-            const struct sh_opcode_info *info = svga_opcode_info( op.opcode );
-            uint i;
-            uint num_src = info->num_src + op.predicated;
-            boolean not_first_arg = FALSE;
+            const struct sh_opcode_info *info = svga_opcode_info(op.opcode);
 
-            assert( info->num_dst <= 1 );
-
-            if (op.opcode == SVGA3DOP_SINCOS && di.version.major < 3)
-               num_src += 2;
-
-            dump_comp_op( op, info->mnemonic );
-            assem += sizeof( struct sh_op ) / sizeof( unsigned );
-
-            if (info->num_dst > 0) {
-               struct sh_dstreg dstreg = *(struct sh_dstreg *) assem;
-
-               dump_dstreg( dstreg, &di );
-               assem += sizeof( struct sh_dstreg ) / sizeof( unsigned );
-               not_first_arg = TRUE;
-            }
-
-            for (i = 0; i < num_src; i++) {
-               struct sh_srcreg srcreg;
-               struct sh_srcreg indreg;
-
-               srcreg = *(struct sh_srcreg *) assem;
-               assem += sizeof( struct sh_srcreg ) / sizeof( unsigned );
-               if (srcreg.relative && !di.is_ps && di.version.major >= 2) {
-                  indreg = *(struct sh_srcreg *) assem;
-                  assem += sizeof( struct sh_srcreg ) / sizeof( unsigned );
-               }
-
-               if (not_first_arg)
-                  _debug_printf( ", " );
-               else
-                  _debug_printf( " " );
-               dump_srcreg( srcreg, &indreg, &di );
-               not_first_arg = TRUE;
-            }
-
-            _debug_printf( "\n" );
+            dump_inst(&di, &assem, op, info);
          }
       }
    }
diff --git a/src/gallium/drivers/svga/svgadump/svga_shader_op.c b/src/gallium/drivers/svga/svgadump/svga_shader_op.c
index 8343bfd..95612a8 100644
--- a/src/gallium/drivers/svga/svgadump/svga_shader_op.c
+++ b/src/gallium/drivers/svga/svgadump/svga_shader_op.c
@@ -41,103 +41,103 @@
 
 static struct sh_opcode_info opcode_info[] =
 {
-   { "nop",          0, 0, SVGA3DOP_NOP          },
-   { "mov",          1, 1, SVGA3DOP_MOV,         },
-   { "add",          1, 2, SVGA3DOP_ADD,         },
-   { "sub",          1, 2, SVGA3DOP_SUB,         },
-   { "mad",          1, 3, SVGA3DOP_MAD,         },
-   { "mul",          1, 2, SVGA3DOP_MUL,         },
-   { "rcp",          1, 1, SVGA3DOP_RCP,         },
-   { "rsq",          1, 1, SVGA3DOP_RSQ,         },
-   { "dp3",          1, 2, SVGA3DOP_DP3,         },
-   { "dp4",          1, 2, SVGA3DOP_DP4,         },
-   { "min",          1, 2, SVGA3DOP_MIN,         },
-   { "max",          1, 2, SVGA3DOP_MAX,         },
-   { "slt",          1, 2, SVGA3DOP_SLT,         },
-   { "sge",          1, 2, SVGA3DOP_SGE,         },
-   { "exp",          1, 1, SVGA3DOP_EXP,         },
-   { "log",          1, 1, SVGA3DOP_LOG,         },
-   { "lit",          1, 1, SVGA3DOP_LIT,         },
-   { "dst",          1, 2, SVGA3DOP_DST,         },
-   { "lrp",          1, 3, SVGA3DOP_LRP,         },
-   { "frc",          1, 1, SVGA3DOP_FRC,         },
-   { "m4x4",         1, 2, SVGA3DOP_M4x4,        },
-   { "m4x3",         1, 2, SVGA3DOP_M4x3,        },
-   { "m3x4",         1, 2, SVGA3DOP_M3x4,        },
-   { "m3x3",         1, 2, SVGA3DOP_M3x3,        },
-   { "m3x2",         1, 2, SVGA3DOP_M3x2,        },
-   { "call",         0, 1, SVGA3DOP_CALL,        },
-   { "callnz",       0, 2, SVGA3DOP_CALLNZ,      },
-   { "loop",         0, 2, SVGA3DOP_LOOP,        },
-   { "ret",          0, 0, SVGA3DOP_RET,         },
-   { "endloop",      0, 0, SVGA3DOP_ENDLOOP,     },
-   { "label",        0, 1, SVGA3DOP_LABEL,       },
-   { "dcl",          0, 0, SVGA3DOP_DCL,         },
-   { "pow",          1, 2, SVGA3DOP_POW,         },
-   { "crs",          1, 2, SVGA3DOP_CRS,         },
-   { "sgn",          1, 3, SVGA3DOP_SGN,         },
-   { "abs",          1, 1, SVGA3DOP_ABS,         },
-   { "nrm",          1, 1, SVGA3DOP_NRM,         }, /* 3-componenet normalization */
-   { "sincos",       1, 1, SVGA3DOP_SINCOS,      },
-   { "rep",          0, 1, SVGA3DOP_REP,         },
-   { "endrep",       0, 0, SVGA3DOP_ENDREP,      },
-   { "if",           0, 1, SVGA3DOP_IF,          },
-   { "ifc",          0, 2, SVGA3DOP_IFC,         },
-   { "else",         0, 0, SVGA3DOP_ELSE,        },
-   { "endif",        0, 0, SVGA3DOP_ENDIF,       },
-   { "break",        0, 0, SVGA3DOP_BREAK,       },
-   { "breakc",       0, 0, SVGA3DOP_BREAKC,      },
-   { "mova",         1, 1, SVGA3DOP_MOVA,        },
-   { "defb",         0, 0, SVGA3DOP_DEFB,        },
-   { "defi",         0, 0, SVGA3DOP_DEFI,        },
-   { "???",          0, 0, SVGA3DOP_INVALID,     },
-   { "???",          0, 0, SVGA3DOP_INVALID,     },
-   { "???",          0, 0, SVGA3DOP_INVALID,     },
-   { "???",          0, 0, SVGA3DOP_INVALID,     },
-   { "???",          0, 0, SVGA3DOP_INVALID,     },
-   { "???",          0, 0, SVGA3DOP_INVALID,     },
-   { "???",          0, 0, SVGA3DOP_INVALID,     },
-   { "???",          0, 0, SVGA3DOP_INVALID,     },
-   { "???",          0, 0, SVGA3DOP_INVALID,     },
-   { "???",          0, 0, SVGA3DOP_INVALID,     },
-   { "???",          0, 0, SVGA3DOP_INVALID,     },
-   { "???",          0, 0, SVGA3DOP_INVALID,     },
-   { "???",          0, 0, SVGA3DOP_INVALID,     },
-   { "???",          0, 0, SVGA3DOP_INVALID,     },
-   { "???",          0, 0, SVGA3DOP_INVALID,     },
-   { "texcoord",     0, 0, SVGA3DOP_TEXCOORD,    },
-   { "texkill",      1, 0, SVGA3DOP_TEXKILL,     },
-   { "tex",          0, 0, SVGA3DOP_TEX,         },
-   { "texbem",       1, 1, SVGA3DOP_TEXBEM,      },
-   { "texbeml",      1, 1, SVGA3DOP_TEXBEML,     },
-   { "texreg2ar",    1, 1, SVGA3DOP_TEXREG2AR,   },
-   { "texreg2gb",    1, 1, SVGA3DOP_TEXREG2GB,   },
-   { "texm3x2pad",   1, 1, SVGA3DOP_TEXM3x2PAD,  },
-   { "texm3x2tex",   1, 1, SVGA3DOP_TEXM3x2TEX,  },
-   { "texm3x3pad",   1, 1, SVGA3DOP_TEXM3x3PAD,  },
-   { "texm3x3tex",   1, 1, SVGA3DOP_TEXM3x3TEX,  },
-   { "reserved0",    0, 0, SVGA3DOP_RESERVED0,   },
-   { "texm3x3spec",  1, 2, SVGA3DOP_TEXM3x3SPEC, },
-   { "texm3x3vspec", 1, 1, SVGA3DOP_TEXM3x3VSPEC,},
-   { "expp",         1, 1, SVGA3DOP_EXPP,        },
-   { "logp",         1, 1, SVGA3DOP_LOGP,        },
-   { "cnd",          1, 3, SVGA3DOP_CND,         },
-   { "def",          0, 0, SVGA3DOP_DEF,         },
-   { "texreg2rgb",   1, 1, SVGA3DOP_TEXREG2RGB,  },
-   { "texdp3tex",    1, 1, SVGA3DOP_TEXDP3TEX,   },
-   { "texm3x2depth", 1, 1, SVGA3DOP_TEXM3x2DEPTH,},
-   { "texdp3",       1, 1, SVGA3DOP_TEXDP3,      },
-   { "texm3x3",      1, 1, SVGA3DOP_TEXM3x3,     },
-   { "texdepth",     1, 0, SVGA3DOP_TEXDEPTH,    },
-   { "cmp",          1, 3, SVGA3DOP_CMP,         },
-   { "bem",          1, 2, SVGA3DOP_BEM,         },
-   { "dp2add",       1, 3, SVGA3DOP_DP2ADD,      },
-   { "dsx",          1, 1, SVGA3DOP_INVALID,     },
-   { "dsy",          1, 1, SVGA3DOP_INVALID,     },
-   { "texldd",       1, 1, SVGA3DOP_INVALID,     },
-   { "setp",         1, 2, SVGA3DOP_SETP,        },
-   { "texldl",       1, 1, SVGA3DOP_INVALID,     },
-   { "breakp",       1, 1, SVGA3DOP_INVALID,     },
+   { "nop",          0, 0, 0, 0, SVGA3DOP_NOP          },
+   { "mov",          1, 1, 0, 0, SVGA3DOP_MOV,         },
+   { "add",          1, 2, 0, 0, SVGA3DOP_ADD,         },
+   { "sub",          1, 2, 0, 0, SVGA3DOP_SUB,         },
+   { "mad",          1, 3, 0, 0, SVGA3DOP_MAD,         },
+   { "mul",          1, 2, 0, 0, SVGA3DOP_MUL,         },
+   { "rcp",          1, 1, 0, 0, SVGA3DOP_RCP,         },
+   { "rsq",          1, 1, 0, 0, SVGA3DOP_RSQ,         },
+   { "dp3",          1, 2, 0, 0, SVGA3DOP_DP3,         },
+   { "dp4",          1, 2, 0, 0, SVGA3DOP_DP4,         },
+   { "min",          1, 2, 0, 0, SVGA3DOP_MIN,         },
+   { "max",          1, 2, 0, 0, SVGA3DOP_MAX,         },
+   { "slt",          1, 2, 0, 0, SVGA3DOP_SLT,         },
+   { "sge",          1, 2, 0, 0, SVGA3DOP_SGE,         },
+   { "exp",          1, 1, 0, 0, SVGA3DOP_EXP,         },
+   { "log",          1, 1, 0, 0, SVGA3DOP_LOG,         },
+   { "lit",          1, 1, 0, 0, SVGA3DOP_LIT,         },
+   { "dst",          1, 2, 0, 0, SVGA3DOP_DST,         },
+   { "lrp",          1, 3, 0, 0, SVGA3DOP_LRP,         },
+   { "frc",          1, 1, 0, 0, SVGA3DOP_FRC,         },
+   { "m4x4",         1, 2, 0, 0, SVGA3DOP_M4x4,        },
+   { "m4x3",         1, 2, 0, 0, SVGA3DOP_M4x3,        },
+   { "m3x4",         1, 2, 0, 0, SVGA3DOP_M3x4,        },
+   { "m3x3",         1, 2, 0, 0, SVGA3DOP_M3x3,        },
+   { "m3x2",         1, 2, 0, 0, SVGA3DOP_M3x2,        },
+   { "call",         0, 1, 0, 0, SVGA3DOP_CALL,        },
+   { "callnz",       0, 2, 0, 0, SVGA3DOP_CALLNZ,      },
+   { "loop",         0, 2, 0, 1, SVGA3DOP_LOOP,        },
+   { "ret",          0, 0, 0, 0, SVGA3DOP_RET,         },
+   { "endloop",      0, 0, 1, 0, SVGA3DOP_ENDLOOP,     },
+   { "label",        0, 1, 0, 0, SVGA3DOP_LABEL,       },
+   { "dcl",          0, 0, 0, 0, SVGA3DOP_DCL,         },
+   { "pow",          1, 2, 0, 0, SVGA3DOP_POW,         },
+   { "crs",          1, 2, 0, 0, SVGA3DOP_CRS,         },
+   { "sgn",          1, 3, 0, 0, SVGA3DOP_SGN,         },
+   { "abs",          1, 1, 0, 0, SVGA3DOP_ABS,         },
+   { "nrm",          1, 1, 0, 0, SVGA3DOP_NRM,         }, /* 3-componenet normalization */
+   { "sincos",       1, 3, 0, 0, SVGA3DOP_SINCOS,      },
+   { "rep",          0, 1, 0, 1, SVGA3DOP_REP,         },
+   { "endrep",       0, 0, 1, 0, SVGA3DOP_ENDREP,      },
+   { "if",           0, 1, 0, 1, SVGA3DOP_IF,          },
+   { "ifc",          0, 2, 0, 1, SVGA3DOP_IFC,         },
+   { "else",         0, 0, 1, 1, SVGA3DOP_ELSE,        },
+   { "endif",        0, 0, 1, 0, SVGA3DOP_ENDIF,       },
+   { "break",        0, 0, 0, 0, SVGA3DOP_BREAK,       },
+   { "breakc",       0, 2, 0, 0, SVGA3DOP_BREAKC,      },
+   { "mova",         1, 1, 0, 0, SVGA3DOP_MOVA,        },
+   { "defb",         0, 0, 0, 0, SVGA3DOP_DEFB,        },
+   { "defi",         0, 0, 0, 0, SVGA3DOP_DEFI,        },
+   { "???",          0, 0, 0, 0, SVGA3DOP_INVALID,     },
+   { "???",          0, 0, 0, 0, SVGA3DOP_INVALID,     },
+   { "???",          0, 0, 0, 0, SVGA3DOP_INVALID,     },
+   { "???",          0, 0, 0, 0, SVGA3DOP_INVALID,     },
+   { "???",          0, 0, 0, 0, SVGA3DOP_INVALID,     },
+   { "???",          0, 0, 0, 0, SVGA3DOP_INVALID,     },
+   { "???",          0, 0, 0, 0, SVGA3DOP_INVALID,     },
+   { "???",          0, 0, 0, 0, SVGA3DOP_INVALID,     },
+   { "???",          0, 0, 0, 0, SVGA3DOP_INVALID,     },
+   { "???",          0, 0, 0, 0, SVGA3DOP_INVALID,     },
+   { "???",          0, 0, 0, 0, SVGA3DOP_INVALID,     },
+   { "???",          0, 0, 0, 0, SVGA3DOP_INVALID,     },
+   { "???",          0, 0, 0, 0, SVGA3DOP_INVALID,     },
+   { "???",          0, 0, 0, 0, SVGA3DOP_INVALID,     },
+   { "???",          0, 0, 0, 0, SVGA3DOP_INVALID,     },
+   { "texcoord",     1, 0, 0, 0, SVGA3DOP_TEXCOORD,    },
+   { "texkill",      1, 0, 0, 0, SVGA3DOP_TEXKILL,     },
+   { "tex",          1, 0, 0, 0, SVGA3DOP_TEX,         },
+   { "texbem",       1, 1, 0, 0, SVGA3DOP_TEXBEM,      },
+   { "texbeml",      1, 1, 0, 0, SVGA3DOP_TEXBEML,     },
+   { "texreg2ar",    1, 1, 0, 0, SVGA3DOP_TEXREG2AR,   },
+   { "texreg2gb",    1, 1, 0, 0, SVGA3DOP_TEXREG2GB,   },
+   { "texm3x2pad",   1, 1, 0, 0, SVGA3DOP_TEXM3x2PAD,  },
+   { "texm3x2tex",   1, 1, 0, 0, SVGA3DOP_TEXM3x2TEX,  },
+   { "texm3x3pad",   1, 1, 0, 0, SVGA3DOP_TEXM3x3PAD,  },
+   { "texm3x3tex",   1, 1, 0, 0, SVGA3DOP_TEXM3x3TEX,  },
+   { "reserved0",    0, 0, 0, 0, SVGA3DOP_RESERVED0,   },
+   { "texm3x3spec",  1, 2, 0, 0, SVGA3DOP_TEXM3x3SPEC, },
+   { "texm3x3vspec", 1, 1, 0, 0, SVGA3DOP_TEXM3x3VSPEC,},
+   { "expp",         1, 1, 0, 0, SVGA3DOP_EXPP,        },
+   { "logp",         1, 1, 0, 0, SVGA3DOP_LOGP,        },
+   { "cnd",          1, 3, 0, 0, SVGA3DOP_CND,         },
+   { "def",          0, 0, 0, 0, SVGA3DOP_DEF,         },
+   { "texreg2rgb",   1, 1, 0, 0, SVGA3DOP_TEXREG2RGB,  },
+   { "texdp3tex",    1, 1, 0, 0, SVGA3DOP_TEXDP3TEX,   },
+   { "texm3x2depth", 1, 1, 0, 0, SVGA3DOP_TEXM3x2DEPTH,},
+   { "texdp3",       1, 1, 0, 0, SVGA3DOP_TEXDP3,      },
+   { "texm3x3",      1, 1, 0, 0, SVGA3DOP_TEXM3x3,     },
+   { "texdepth",     1, 0, 0, 0, SVGA3DOP_TEXDEPTH,    },
+   { "cmp",          1, 3, 0, 0, SVGA3DOP_CMP,         },
+   { "bem",          1, 2, 0, 0, SVGA3DOP_BEM,         },
+   { "dp2add",       1, 3, 0, 0, SVGA3DOP_DP2ADD,      },
+   { "dsx",          1, 1, 0, 0, SVGA3DOP_INVALID,     },
+   { "dsy",          1, 1, 0, 0, SVGA3DOP_INVALID,     },
+   { "texldd",       1, 4, 0, 0, SVGA3DOP_INVALID,     },
+   { "setp",         1, 2, 0, 0, SVGA3DOP_SETP,        },
+   { "texldl",       1, 2, 0, 0, SVGA3DOP_INVALID,     },
+   { "breakp",       0, 1, 0, 0, SVGA3DOP_INVALID,     },
 };
 
 const struct sh_opcode_info *svga_opcode_info( uint op )
diff --git a/src/gallium/drivers/svga/svgadump/svga_shader_op.h b/src/gallium/drivers/svga/svgadump/svga_shader_op.h
index e558de0..a5ccae5 100644
--- a/src/gallium/drivers/svga/svgadump/svga_shader_op.h
+++ b/src/gallium/drivers/svga/svgadump/svga_shader_op.h
@@ -38,6 +38,8 @@
    const char *mnemonic;
    unsigned num_dst:8;
    unsigned num_src:8;
+   unsigned pre_dedent:1;
+   unsigned post_indent:1;
    unsigned svga_opcode:16;
 };
 
diff --git a/src/gallium/drivers/trace/tr_context.c b/src/gallium/drivers/trace/tr_context.c
index 34ceaa4..df40fba 100644
--- a/src/gallium/drivers/trace/tr_context.c
+++ b/src/gallium/drivers/trace/tr_context.c
@@ -792,6 +792,24 @@
 
 
 static INLINE void
+trace_context_set_stencil_ref(struct pipe_context *_pipe,
+                              const struct pipe_stencil_ref *state)
+{
+   struct trace_context *tr_ctx = trace_context(_pipe);
+   struct pipe_context *pipe = tr_ctx->pipe;
+
+   trace_dump_call_begin("pipe_context", "set_stencil_ref");
+
+   trace_dump_arg(ptr, pipe);
+   trace_dump_arg(stencil_ref, state);
+
+   pipe->set_stencil_ref(pipe, state);
+
+   trace_dump_call_end();
+}
+
+
+static INLINE void
 trace_context_set_clip_state(struct pipe_context *_pipe,
                              const struct pipe_clip_state *state)
 {
@@ -817,24 +835,19 @@
    struct trace_context *tr_ctx = trace_context(_pipe);
    struct pipe_context *pipe = tr_ctx->pipe;
 
-   if (buffer)
+   if (buffer) {
       trace_screen_user_buffer_update(_pipe->screen, buffer);
+      buffer = trace_buffer_unwrap(tr_ctx, buffer);
+   }
 
    trace_dump_call_begin("pipe_context", "set_constant_buffer");
 
    trace_dump_arg(ptr, pipe);
    trace_dump_arg(uint, shader);
    trace_dump_arg(uint, index);
-   trace_dump_arg(constant_buffer, buffer);
+   trace_dump_arg(ptr, buffer);
 
-   /* XXX hmm? */
-   if (buffer) {
-      struct pipe_buffer *_buffer;
-      _buffer = trace_buffer_unwrap(tr_ctx, buffer);
-      pipe->set_constant_buffer(pipe, shader, index, _buffer);
-   } else {
-      pipe->set_constant_buffer(pipe, shader, index, buffer);
-   }
+   pipe->set_constant_buffer(pipe, shader, index, buffer);
 
    trace_dump_call_end();
 }
@@ -1291,6 +1304,7 @@
    tr_ctx->base.bind_vs_state = trace_context_bind_vs_state;
    tr_ctx->base.delete_vs_state = trace_context_delete_vs_state;
    tr_ctx->base.set_blend_color = trace_context_set_blend_color;
+   tr_ctx->base.set_stencil_ref = trace_context_set_stencil_ref;
    tr_ctx->base.set_clip_state = trace_context_set_clip_state;
    tr_ctx->base.set_constant_buffer = trace_context_set_constant_buffer;
    tr_ctx->base.set_framebuffer_state = trace_context_set_framebuffer_state;
diff --git a/src/gallium/drivers/trace/tr_dump.c b/src/gallium/drivers/trace/tr_dump.c
index 8de451c..1affafd 100644
--- a/src/gallium/drivers/trace/tr_dump.c
+++ b/src/gallium/drivers/trace/tr_dump.c
@@ -250,7 +250,7 @@
 
    if(!stream) {
 
-      stream = os_stream_create(filename, 0);
+      stream = os_file_stream_create(filename);
       if(!stream)
          return FALSE;
 
diff --git a/src/gallium/drivers/trace/tr_dump_state.c b/src/gallium/drivers/trace/tr_dump_state.c
index 6648539..6da186a 100644
--- a/src/gallium/drivers/trace/tr_dump_state.c
+++ b/src/gallium/drivers/trace/tr_dump_state.c
@@ -28,6 +28,7 @@
 
 #include "pipe/p_compiler.h"
 #include "util/u_memory.h"
+#include "util/u_format.h"
 #include "tgsi/tgsi_dump.h"
 
 #include "tr_dump.h"
@@ -39,18 +40,7 @@
    if (!trace_dumping_enabled_locked())
       return;
 
-   trace_dump_enum(pf_name(format) );
-}
-
-
-static void trace_dump_reference(const struct pipe_reference *reference)
-{
-   if (!trace_dumping_enabled_locked())
-      return;
-
-   trace_dump_struct_begin("pipe_reference");
-   trace_dump_member(int, reference, count);
-   trace_dump_struct_end();
+   trace_dump_enum(util_format_name(format) );
 }
 
 
@@ -227,24 +217,6 @@
 }
 
 
-void trace_dump_constant_buffer(const struct pipe_buffer *state)
-{
-   if (!trace_dumping_enabled_locked())
-      return;
-
-   if(!state) {
-      trace_dump_null();
-      return;
-   }
-
-   trace_dump_struct_begin("pipe_constant_buffer");
-
-   trace_dump_reference(&state->reference);
-
-   trace_dump_struct_end();
-}
-
-
 void trace_dump_shader_state(const struct pipe_shader_state *state)
 {
    static char str[8192];
@@ -301,7 +273,6 @@
       trace_dump_member(uint, &state->stencil[i], fail_op);
       trace_dump_member(uint, &state->stencil[i], zpass_op);
       trace_dump_member(uint, &state->stencil[i], zfail_op);
-      trace_dump_member(uint, &state->stencil[i], ref_value);
       trace_dump_member(uint, &state->stencil[i], valuemask);
       trace_dump_member(uint, &state->stencil[i], writemask);
       trace_dump_struct_end();
@@ -321,23 +292,8 @@
    trace_dump_struct_end();
 }
 
-static void trace_dump_rt_blend_state(const struct pipe_rt_blend_state *state)
-{
-   trace_dump_member(uint, state, rgb_func);
-   trace_dump_member(uint, state, rgb_src_factor);
-   trace_dump_member(uint, state, rgb_dst_factor);
-
-   trace_dump_member(uint, state, alpha_func);
-   trace_dump_member(uint, state, alpha_src_factor);
-   trace_dump_member(uint, state, alpha_dst_factor);
-
-   trace_dump_member(uint, state, colormask);
-
-}
-
 void trace_dump_blend_state(const struct pipe_blend_state *state)
 {
-   unsigned valid_entries = 1;
    if (!trace_dumping_enabled_locked())
       return;
 
@@ -346,21 +302,7 @@
       return;
    }
 
-   trace_dump_struct_begin("pipe_blend_state");
-
-   trace_dump_member(bool, state, dither);
-
-   trace_dump_member(bool, state, logicop_enable);
-   trace_dump_member(uint, state, logicop_func);
-
-   trace_dump_member(bool, state, independent_blend_enable);
-
-   if (state->independent_blend_enable)
-      valid_entries = PIPE_MAX_COLOR_BUFS;
-
-   trace_dump_struct_array(rt_blend_state, state->rt, valid_entries);
-
-   trace_dump_struct_end();
+   trace_dump_bytes(state, sizeof *state);
 }
 
 
@@ -381,6 +323,22 @@
    trace_dump_struct_end();
 }
 
+void trace_dump_stencil_ref(const struct pipe_stencil_ref *state)
+{
+   if (!trace_dumping_enabled_locked())
+      return;
+
+   if(!state) {
+      trace_dump_null();
+      return;
+   }
+
+   trace_dump_struct_begin("pipe_stencil_ref");
+
+   trace_dump_member_array(uint, state, ref_value);
+
+   trace_dump_struct_end();
+}
 
 void trace_dump_framebuffer_state(const struct pipe_framebuffer_state *state)
 {
@@ -420,11 +378,11 @@
    trace_dump_member(uint, state, compare_mode);
    trace_dump_member(uint, state, compare_func);
    trace_dump_member(bool, state, normalized_coords);
+   trace_dump_member(uint, state, max_anisotropy);
    trace_dump_member(float, state, lod_bias);
    trace_dump_member(float, state, min_lod);
    trace_dump_member(float, state, max_lod);
    trace_dump_member_array(float, state, border_color);
-   trace_dump_member(float, state, max_anisotropy);
 
    trace_dump_struct_end();
 }
@@ -442,8 +400,6 @@
 
    trace_dump_struct_begin("pipe_surface");
 
-   trace_dump_reference(&state->reference);
-
    trace_dump_member(format, state, format);
    trace_dump_member(uint, state, width);
    trace_dump_member(uint, state, height);
diff --git a/src/gallium/drivers/trace/tr_dump_state.h b/src/gallium/drivers/trace/tr_dump_state.h
index c7860fd..3400367 100644
--- a/src/gallium/drivers/trace/tr_dump_state.h
+++ b/src/gallium/drivers/trace/tr_dump_state.h
@@ -47,8 +47,6 @@
 
 void trace_dump_clip_state(const struct pipe_clip_state *state);
 
-void trace_dump_constant_buffer(const struct pipe_buffer *state);
-
 void trace_dump_token(const struct tgsi_token *token);
 
 void trace_dump_shader_state(const struct pipe_shader_state *state);
@@ -59,6 +57,8 @@
 
 void trace_dump_blend_color(const struct pipe_blend_color *state);
 
+void trace_dump_stencil_ref(const struct pipe_stencil_ref *state);
+
 void trace_dump_framebuffer_state(const struct pipe_framebuffer_state *state);
 
 void trace_dump_sampler_state(const struct pipe_sampler_state *state);
diff --git a/src/gallium/include/pipe/p_context.h b/src/gallium/include/pipe/p_context.h
index f1e6a60..f82b779 100644
--- a/src/gallium/include/pipe/p_context.h
+++ b/src/gallium/include/pipe/p_context.h
@@ -186,8 +186,11 @@
    void (*set_blend_color)( struct pipe_context *,
                             const struct pipe_blend_color * );
 
+   void (*set_stencil_ref)( struct pipe_context *,
+                            const struct pipe_stencil_ref * );
+
    void (*set_clip_state)( struct pipe_context *,
-			   const struct pipe_clip_state * );
+                            const struct pipe_clip_state * );
 
    void (*set_constant_buffer)( struct pipe_context *,
                                 uint shader, uint index,
diff --git a/src/gallium/include/pipe/p_format.h b/src/gallium/include/pipe/p_format.h
index 2894e13..f33b063 100644
--- a/src/gallium/include/pipe/p_format.h
+++ b/src/gallium/include/pipe/p_format.h
@@ -165,11 +165,6 @@
    PIPE_FORMAT_COUNT
 };
 
-/**
- * Builds pipe format name from format token.
- */
-extern const char *pf_name( enum pipe_format format );
-
 
 enum pipe_video_chroma_format
 {
diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h
index 6836957..5ac5c87 100644
--- a/src/gallium/include/pipe/p_state.h
+++ b/src/gallium/include/pipe/p_state.h
@@ -199,9 +199,8 @@
    unsigned fail_op:3;  /**< PIPE_STENCIL_OP_x */
    unsigned zpass_op:3; /**< PIPE_STENCIL_OP_x */
    unsigned zfail_op:3; /**< PIPE_STENCIL_OP_x */
-   ubyte ref_value;
-   ubyte valuemask;
-   ubyte writemask;
+   unsigned valuemask:8;
+   unsigned writemask:8;
 };
 
 
@@ -251,6 +250,10 @@
    float color[4];
 };
 
+struct pipe_stencil_ref
+{
+   ubyte ref_value[2];
+};
 
 struct pipe_framebuffer_state
 {
@@ -278,10 +281,10 @@
    unsigned compare_mode:1;      /**< PIPE_TEX_COMPARE_x */
    unsigned compare_func:3;      /**< PIPE_FUNC_x */
    unsigned normalized_coords:1; /**< Are coords normalized to [0,1]? */
+   unsigned max_anisotropy:6;
    float lod_bias;               /**< LOD/lambda bias */
    float min_lod, max_lod;       /**< LOD clamp range, after bias */
    float border_color[4];
-   float max_anisotropy;
 };
 
 
diff --git a/src/gallium/state_trackers/dri/dri_context.c b/src/gallium/state_trackers/dri/dri_context.c
index 5033c3c..908cef4 100644
--- a/src/gallium/state_trackers/dri/dri_context.c
+++ b/src/gallium/state_trackers/dri/dri_context.c
@@ -166,10 +166,8 @@
       if (__dri1_api_hooks) {
 	 dri1_update_drawables(ctx, draw, read);
       } else {
-	 if (driDrawPriv)
-	    dri_get_buffers(driDrawPriv);
-	 if (driDrawPriv != driReadPriv && driReadPriv)
-	    dri_get_buffers(driReadPriv);
+	 dri_update_buffer(ctx->pipe->screen,
+			   ctx->pipe->priv);
       }
    } else {
       st_make_current(NULL, NULL, NULL);
diff --git a/src/gallium/state_trackers/dri/dri_drawable.c b/src/gallium/state_trackers/dri/dri_drawable.c
index ff21f2f..4d7596a 100644
--- a/src/gallium/state_trackers/dri/dri_drawable.c
+++ b/src/gallium/state_trackers/dri/dri_drawable.c
@@ -132,14 +132,22 @@
    boolean have_depth = FALSE;
    int i, count;
 
-   buffers = (*dri_screen->dri2.loader->getBuffers) (dri_drawable,
-						     &dri_drawable->w,
-						     &dri_drawable->h,
-						     drawable->attachments,
-						     drawable->
-						     num_attachments, &count,
-						     dri_drawable->
-						     loaderPrivate);
+   if ((dri_screen->dri2.loader
+        && (dri_screen->dri2.loader->base.version > 2)
+        && (dri_screen->dri2.loader->getBuffersWithFormat != NULL)))
+      buffers = (*dri_screen->dri2.loader->getBuffersWithFormat)
+                (dri_drawable, &dri_drawable->w, &dri_drawable->h,
+                 drawable->attachments, drawable->num_attachments,
+                 &count, dri_drawable->loaderPrivate);
+   else
+      buffers = (*dri_screen->dri2.loader->getBuffers) (dri_drawable,
+                                                        &dri_drawable->w,
+                                                        &dri_drawable->h,
+                                                        drawable->attachments,
+                                                        drawable->
+                                                        num_attachments, &count,
+                                                        dri_drawable->
+                                                        loaderPrivate);
 
    if (buffers == NULL) {
       return;
@@ -276,7 +284,20 @@
 {
    struct dri_context *ctx = (struct dri_context *)context_private;
 
+   if (ctx->d_stamp == *ctx->dPriv->pStamp &&
+       ctx->r_stamp == *ctx->rPriv->pStamp)
+      return;
+
+   ctx->d_stamp = *ctx->dPriv->pStamp;
+   ctx->r_stamp = *ctx->rPriv->pStamp;
+
+   st_flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL);
+
+   /* Ask the X server for new renderbuffers. */
    dri_get_buffers(ctx->dPriv);
+   if (ctx->dPriv != ctx->rPriv)
+      dri_get_buffers(ctx->rPriv);
+
 }
 
 void
@@ -346,12 +367,12 @@
    case 24:
       if (visual->stencilBits == 0) {
 	 drawable->depth_stencil_format = (screen->d_depth_bits_last) ?
-	    PIPE_FORMAT_X8Z24_UNORM:
-	    PIPE_FORMAT_Z24X8_UNORM;
+                                          PIPE_FORMAT_X8Z24_UNORM:
+                                          PIPE_FORMAT_Z24X8_UNORM;
       } else {
 	 drawable->depth_stencil_format = (screen->sd_depth_bits_last) ?
-	    PIPE_FORMAT_S8Z24_UNORM:
-	    PIPE_FORMAT_Z24S8_UNORM;
+                                          PIPE_FORMAT_S8Z24_UNORM:
+                                          PIPE_FORMAT_Z24S8_UNORM;
       }
       break;
    case 32:
@@ -375,23 +396,49 @@
    /* setup dri2 buffers information */
    /* TODO incase of double buffer visual, delay fake creation */
    i = 0;
-   drawable->attachments[i++] = __DRI_BUFFER_FRONT_LEFT;
-   if (!screen->auto_fake_front)
-      drawable->attachments[i++] = __DRI_BUFFER_FAKE_FRONT_LEFT;
-   if (visual->doubleBufferMode)
-      drawable->attachments[i++] = __DRI_BUFFER_BACK_LEFT;
-   if (visual->depthBits && visual->stencilBits)
-      drawable->attachments[i++] = __DRI_BUFFER_DEPTH_STENCIL;
-   else if (visual->depthBits)
-      drawable->attachments[i++] = __DRI_BUFFER_DEPTH;
-   else if (visual->stencilBits)
-      drawable->attachments[i++] = __DRI_BUFFER_STENCIL;
-   drawable->num_attachments = i;
+   if (sPriv->dri2.loader
+       && (sPriv->dri2.loader->base.version > 2)
+       && (sPriv->dri2.loader->getBuffersWithFormat != NULL)) {
+      drawable->attachments[i++] = __DRI_BUFFER_FRONT_LEFT;
+      drawable->attachments[i++] = visual->rgbBits;
+      if (!screen->auto_fake_front)  {
+         drawable->attachments[i++] = __DRI_BUFFER_FAKE_FRONT_LEFT;
+         drawable->attachments[i++] = visual->rgbBits;
+      }
+      if (visual->doubleBufferMode) {
+         drawable->attachments[i++] = __DRI_BUFFER_BACK_LEFT;
+         drawable->attachments[i++] = visual->rgbBits;
+      }
+      if (visual->depthBits && visual->stencilBits) {
+         drawable->attachments[i++] = __DRI_BUFFER_DEPTH_STENCIL;
+         drawable->attachments[i++] = visual->depthBits + visual->stencilBits;
+      } else if (visual->depthBits) {
+         drawable->attachments[i++] = __DRI_BUFFER_DEPTH;
+         drawable->attachments[i++] = visual->depthBits;
+      } else if (visual->stencilBits) {
+         drawable->attachments[i++] = __DRI_BUFFER_STENCIL;
+         drawable->attachments[i++] = visual->stencilBits;
+      }
+      drawable->num_attachments = i / 2;
+   } else {
+      drawable->attachments[i++] = __DRI_BUFFER_FRONT_LEFT;
+      if (!screen->auto_fake_front)
+         drawable->attachments[i++] = __DRI_BUFFER_FAKE_FRONT_LEFT;
+      if (visual->doubleBufferMode)
+         drawable->attachments[i++] = __DRI_BUFFER_BACK_LEFT;
+      if (visual->depthBits && visual->stencilBits)
+         drawable->attachments[i++] = __DRI_BUFFER_DEPTH_STENCIL;
+      else if (visual->depthBits)
+         drawable->attachments[i++] = __DRI_BUFFER_DEPTH;
+      else if (visual->stencilBits)
+         drawable->attachments[i++] = __DRI_BUFFER_STENCIL;
+      drawable->num_attachments = i;
+   }
 
    drawable->desired_fences = 2;
 
    return GL_TRUE;
- fail:
+fail:
    FREE(drawable);
    return GL_FALSE;
 }
diff --git a/src/gallium/state_trackers/dri/dri_screen.c b/src/gallium/state_trackers/dri/dri_screen.c
index 4064976..77d6402 100644
--- a/src/gallium/state_trackers/dri/dri_screen.c
+++ b/src/gallium/state_trackers/dri/dri_screen.c
@@ -61,6 +61,17 @@
    dri2_set_tex_buffer2,
 };
 
+static void
+dri2_flush_drawable(__DRIdrawable *draw)
+{
+}
+
+static const __DRI2flushExtension dri2FlushExtension = {
+    { __DRI2_FLUSH, __DRI2_FLUSH_VERSION },
+    dri2_flush_drawable,
+    dri2InvalidateDrawable,
+};
+
    static const __DRIextension *dri_screen_extensions[] = {
       &driReadDrawableExtension,
       &driCopySubBufferExtension.base,
@@ -68,6 +79,7 @@
       &driFrameTrackingExtension.base,
       &driMediaStreamCounterExtension.base,
       &dri2TexBufferExtension.base,
+      &dri2FlushExtension.base,
       NULL
    };
 
@@ -97,12 +109,6 @@
    stencil_bits_array[0] = 0;
    depth_buffer_factor = 1;
 
-   pf_z16 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_Z16_UNORM,
-					  PIPE_TEXTURE_2D,
-					  PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0);
-   pf_z32 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_Z32_UNORM,
-					  PIPE_TEXTURE_2D,
-					  PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0);
    pf_x8z24 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_X8Z24_UNORM,
 					    PIPE_TEXTURE_2D,
 					    PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0);
@@ -115,9 +121,6 @@
    pf_z24s8 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_Z24S8_UNORM,
 					    PIPE_TEXTURE_2D,
 					    PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0);
-   pf_r5g6b5 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_R5G6B5_UNORM,
-					     PIPE_TEXTURE_2D,
-					     PIPE_TEXTURE_USAGE_RENDER_TARGET, 0);
    pf_a8r8g8b8 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_A8R8G8B8_UNORM,
 					       PIPE_TEXTURE_2D,
 					       PIPE_TEXTURE_USAGE_RENDER_TARGET, 0);
@@ -125,6 +128,26 @@
 					       PIPE_TEXTURE_2D,
 					       PIPE_TEXTURE_USAGE_RENDER_TARGET, 0);
 
+   /* we support buffers with different depths only if we can tell the driver
+    * the actual depth of each of them. */
+   if (screen->sPriv->dri2.loader
+       && (screen->sPriv->dri2.loader->base.version > 2)
+       && (screen->sPriv->dri2.loader->getBuffersWithFormat != NULL)) {
+      pf_z16 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_Z16_UNORM,
+                                             PIPE_TEXTURE_2D,
+                                             PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0);
+      pf_z32 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_Z32_UNORM,
+                                             PIPE_TEXTURE_2D,
+                                             PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0);
+      pf_r5g6b5 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_R5G6B5_UNORM,
+                                                PIPE_TEXTURE_2D,
+                                                PIPE_TEXTURE_USAGE_RENDER_TARGET, 0);
+   } else {
+      pf_z16 = FALSE;
+      pf_z32 = FALSE;
+      pf_r5g6b5 = FALSE;
+   }
+
    if (pf_z16) {
       depth_bits_array[depth_buffer_factor] = 16;
       stencil_bits_array[depth_buffer_factor++] = 0;
diff --git a/src/gallium/state_trackers/glx/xlib/glx_usefont.c b/src/gallium/state_trackers/glx/xlib/glx_usefont.c
index 16e5ce6..e502198 100644
--- a/src/gallium/state_trackers/glx/xlib/glx_usefont.c
+++ b/src/gallium/state_trackers/glx/xlib/glx_usefont.c
@@ -33,7 +33,6 @@
 #include "main/context.h"
 #include "main/imports.h"
 #include <GL/glx.h>
-#include "pipe/p_compiler.h"
 
 
 /* Some debugging info.  */
diff --git a/src/gallium/state_trackers/python/README b/src/gallium/state_trackers/python/README
index e03d546..4a06073 100644
--- a/src/gallium/state_trackers/python/README
+++ b/src/gallium/state_trackers/python/README
@@ -30,7 +30,7 @@
 
 and then try running
 
-  python src/gallium/state_trackers/python/samples/tri.py
+  python progs/gallium/python/samples/tri.py
 
 which should show a triangle.
 
diff --git a/src/gallium/state_trackers/python/gallium.i b/src/gallium/state_trackers/python/gallium.i
index 99e177b..ffb084e 100644
--- a/src/gallium/state_trackers/python/gallium.i
+++ b/src/gallium/state_trackers/python/gallium.i
@@ -41,13 +41,15 @@
 #include "pipe/p_screen.h"
 #include "pipe/p_context.h"
 #include "pipe/p_shader_tokens.h"
-#include "cso_cache/cso_context.h"
+#include "os/os_stream.h"
 #include "util/u_inlines.h"
 #include "util/u_draw_quad.h"
 #include "util/u_tile.h"
 #include "util/u_math.h"
 #include "util/u_format.h"
+#include "util/u_dump.h"
 #include "util/u_memory.h"
+#include "cso_cache/cso_context.h"
 #include "tgsi/tgsi_text.h"
 #include "tgsi/tgsi_dump.h"
 
@@ -93,7 +95,7 @@
 
 %include "p_compiler.i"
 %include "p_defines.h";
-%include "p_format.i"
+%include "p_format.h"
 
 %include "p_device.i"
 %include "p_context.i"
diff --git a/src/gallium/state_trackers/python/p_context.i b/src/gallium/state_trackers/python/p_context.i
index ce893da..3f36ccb 100644
--- a/src/gallium/state_trackers/python/p_context.i
+++ b/src/gallium/state_trackers/python/p_context.i
@@ -130,11 +130,15 @@
    /*
     * Parameter-like state (or properties)
     */
-   
+
    void set_blend_color(const struct pipe_blend_color *state ) {
       cso_set_blend_color($self->cso, state);
    }
 
+   void set_stencil_ref(const struct pipe_stencil_ref *state ) {
+      cso_set_stencil_ref($self->cso, state);
+   }
+
    void set_clip(const struct pipe_clip_state *state ) {
       $self->pipe->set_clip_state($self->pipe, state);
    }
diff --git a/src/gallium/state_trackers/python/p_format.i b/src/gallium/state_trackers/python/p_format.i
deleted file mode 100644
index 68df009..0000000
--- a/src/gallium/state_trackers/python/p_format.i
+++ /dev/null
@@ -1,154 +0,0 @@
-/**************************************************************************
- * 
- * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
- * Copyright (c) 2008 VMware, Inc.
- * 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"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- * 
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- * 
- **************************************************************************/
-
-/* 
- * XXX: SWIG can't parse p_format.h, so we need to duplicate the relevant 
- * declarations here 
- */
-
-%{
-#include "pipe/p_format.h" 
-%}
-
-enum pipe_format {
-   PIPE_FORMAT_NONE,
-   PIPE_FORMAT_A8R8G8B8_UNORM,
-   PIPE_FORMAT_X8R8G8B8_UNORM,
-   PIPE_FORMAT_B8G8R8A8_UNORM,
-   PIPE_FORMAT_B8G8R8X8_UNORM,
-   PIPE_FORMAT_A1R5G5B5_UNORM,
-   PIPE_FORMAT_A4R4G4B4_UNORM,
-   PIPE_FORMAT_R5G6B5_UNORM,
-   PIPE_FORMAT_A2B10G10R10_UNORM,
-   PIPE_FORMAT_L8_UNORM,
-   PIPE_FORMAT_A8_UNORM,
-   PIPE_FORMAT_I8_UNORM,
-   PIPE_FORMAT_A8L8_UNORM,
-   PIPE_FORMAT_L16_UNORM,
-   PIPE_FORMAT_YCBCR,
-   PIPE_FORMAT_YCBCR_REV,
-   PIPE_FORMAT_Z16_UNORM,
-   PIPE_FORMAT_Z32_UNORM,
-   PIPE_FORMAT_Z32_FLOAT,
-   PIPE_FORMAT_S8Z24_UNORM,
-   PIPE_FORMAT_Z24S8_UNORM,
-   PIPE_FORMAT_X8Z24_UNORM,
-   PIPE_FORMAT_Z24X8_UNORM,
-   PIPE_FORMAT_S8_UNORM,
-   PIPE_FORMAT_R64_FLOAT,
-   PIPE_FORMAT_R64G64_FLOAT,
-   PIPE_FORMAT_R64G64B64_FLOAT,
-   PIPE_FORMAT_R64G64B64A64_FLOAT,
-   PIPE_FORMAT_R32_FLOAT,
-   PIPE_FORMAT_R32G32_FLOAT,
-   PIPE_FORMAT_R32G32B32_FLOAT,
-   PIPE_FORMAT_R32G32B32A32_FLOAT,
-   PIPE_FORMAT_R32_UNORM,
-   PIPE_FORMAT_R32G32_UNORM,
-   PIPE_FORMAT_R32G32B32_UNORM,
-   PIPE_FORMAT_R32G32B32A32_UNORM,
-   PIPE_FORMAT_R32_USCALED,
-   PIPE_FORMAT_R32G32_USCALED,
-   PIPE_FORMAT_R32G32B32_USCALED,
-   PIPE_FORMAT_R32G32B32A32_USCALED,
-   PIPE_FORMAT_R32_SNORM,
-   PIPE_FORMAT_R32G32_SNORM,
-   PIPE_FORMAT_R32G32B32_SNORM,
-   PIPE_FORMAT_R32G32B32A32_SNORM,
-   PIPE_FORMAT_R32_SSCALED,
-   PIPE_FORMAT_R32G32_SSCALED,
-   PIPE_FORMAT_R32G32B32_SSCALED,
-   PIPE_FORMAT_R32G32B32A32_SSCALED,
-   PIPE_FORMAT_R16_UNORM,
-   PIPE_FORMAT_R16G16_UNORM,
-   PIPE_FORMAT_R16G16B16_UNORM,
-   PIPE_FORMAT_R16G16B16A16_UNORM,
-   PIPE_FORMAT_R16_USCALED,
-   PIPE_FORMAT_R16G16_USCALED,
-   PIPE_FORMAT_R16G16B16_USCALED,
-   PIPE_FORMAT_R16G16B16A16_USCALED,
-   PIPE_FORMAT_R16_SNORM,
-   PIPE_FORMAT_R16G16_SNORM,
-   PIPE_FORMAT_R16G16B16_SNORM,
-   PIPE_FORMAT_R16G16B16A16_SNORM,
-   PIPE_FORMAT_R16_SSCALED,
-   PIPE_FORMAT_R16G16_SSCALED,
-   PIPE_FORMAT_R16G16B16_SSCALED,
-   PIPE_FORMAT_R16G16B16A16_SSCALED,
-   PIPE_FORMAT_R8_UNORM,
-   PIPE_FORMAT_R8G8_UNORM,
-   PIPE_FORMAT_R8G8B8_UNORM,
-   PIPE_FORMAT_R8G8B8A8_UNORM,
-   PIPE_FORMAT_R8G8B8X8_UNORM,
-   PIPE_FORMAT_R8_USCALED,
-   PIPE_FORMAT_R8G8_USCALED,
-   PIPE_FORMAT_R8G8B8_USCALED,
-   PIPE_FORMAT_R8G8B8A8_USCALED,
-   PIPE_FORMAT_R8G8B8X8_USCALED,
-   PIPE_FORMAT_R8_SNORM,
-   PIPE_FORMAT_R8G8_SNORM,
-   PIPE_FORMAT_R8G8B8_SNORM,
-   PIPE_FORMAT_R8G8B8A8_SNORM,
-   PIPE_FORMAT_R8G8B8X8_SNORM,
-   PIPE_FORMAT_B6G5R5_SNORM,
-   PIPE_FORMAT_A8B8G8R8_SNORM,
-   PIPE_FORMAT_X8B8G8R8_SNORM,
-   PIPE_FORMAT_R8_SSCALED,
-   PIPE_FORMAT_R8G8_SSCALED,
-   PIPE_FORMAT_R8G8B8_SSCALED,
-   PIPE_FORMAT_R8G8B8A8_SSCALED,
-   PIPE_FORMAT_R8G8B8X8_SSCALED,
-   PIPE_FORMAT_R32_FIXED,
-   PIPE_FORMAT_R32G32_FIXED,
-   PIPE_FORMAT_R32G32B32_FIXED,
-   PIPE_FORMAT_R32G32B32A32_FIXED,
-
-   PIPE_FORMAT_L8_SRGB,
-   PIPE_FORMAT_A8L8_SRGB,
-   PIPE_FORMAT_R8G8B8_SRGB,
-   PIPE_FORMAT_R8G8B8A8_SRGB,
-   PIPE_FORMAT_R8G8B8X8_SRGB,
-   PIPE_FORMAT_A8R8G8B8_SRGB,
-   PIPE_FORMAT_X8R8G8B8_SRGB,
-   PIPE_FORMAT_B8G8R8A8_SRGB,
-   PIPE_FORMAT_B8G8R8X8_SRGB,
-
-   PIPE_FORMAT_X8UB8UG8SR8S_NORM,
-   PIPE_FORMAT_B6UG5SR5S_NORM,
-
-   PIPE_FORMAT_DXT1_RGB,
-   PIPE_FORMAT_DXT1_RGBA,
-   PIPE_FORMAT_DXT3_RGBA,
-   PIPE_FORMAT_DXT5_RGBA,
-
-   PIPE_FORMAT_DXT1_SRGB,
-   PIPE_FORMAT_DXT1_SRGBA,
-   PIPE_FORMAT_DXT3_SRGBA,
-   PIPE_FORMAT_DXT5_SRGBA,
-};
-
diff --git a/src/gallium/state_trackers/python/p_state.i b/src/gallium/state_trackers/python/p_state.i
index 90f157e..5afe4d4 100644
--- a/src/gallium/state_trackers/python/p_state.i
+++ b/src/gallium/state_trackers/python/p_state.i
@@ -44,6 +44,53 @@
 %array_class(struct pipe_stencil_state, StencilArray);
 
 
+%extend pipe_rt_blend_state
+{
+   struct pipe_rt_blend_state *
+   __getitem__(int index) 
+   {
+      if(index < 0 || index >= PIPE_MAX_COLOR_BUFS)
+         SWIG_exception(SWIG_ValueError, "index out of bounds");
+      return $self + index;
+   fail:
+      return NULL;
+   };
+};
+
+
+%extend pipe_blend_state
+{
+   pipe_blend_state(void)
+   {
+      return CALLOC_STRUCT(pipe_blend_state);
+   }
+
+   %cstring_input_binary(const char *STRING, unsigned LENGTH);
+   pipe_blend_state(const char *STRING, unsigned LENGTH)
+   {
+      struct pipe_blend_state *state;
+      state = CALLOC_STRUCT(pipe_framebuffer_state);
+      if (state) {
+         LENGTH = MIN2(sizeof *state, LENGTH);
+         memcpy(state, STRING, LENGTH);
+      }
+      return state;
+   }
+
+   %cstring_output_allocate_size(char **STRING, int *LENGTH, os_free(*$1));
+   void __str__(char **STRING, int *LENGTH)
+   {
+      struct os_stream *stream;
+
+      stream = os_str_stream_create(1);
+      util_dump_blend_state(stream, $self);
+
+      *STRING = os_str_stream_get_and_close(stream);
+      *LENGTH = strlen(*STRING);
+   }
+};
+
+
 %extend pipe_framebuffer_state {
    
    pipe_framebuffer_state(void) {
diff --git a/src/gallium/state_trackers/python/st_device.c b/src/gallium/state_trackers/python/st_device.c
index 1146a8b..a3798a5 100644
--- a/src/gallium/state_trackers/python/st_device.c
+++ b/src/gallium/state_trackers/python/st_device.c
@@ -157,7 +157,7 @@
    
    st_device_reference(&st_ctx->st_dev, st_dev);
    
-   st_ctx->pipe = st_dev->screen->create_context(st_dev->screen, NULL);
+   st_ctx->pipe = st_dev->screen->context_create(st_dev->screen, NULL);
    if(!st_ctx->pipe) {
       st_context_destroy(st_ctx);
       return NULL;
diff --git a/src/gallium/state_trackers/vega/polygon.c b/src/gallium/state_trackers/vega/polygon.c
index f56ea0c..c06dbf5 100644
--- a/src/gallium/state_trackers/vega/polygon.c
+++ b/src/gallium/state_trackers/vega/polygon.c
@@ -307,6 +307,7 @@
 void polygon_fill(struct polygon *poly, struct vg_context *ctx)
 {
    struct pipe_depth_stencil_alpha_state dsa;
+   struct pipe_stencil_ref sr;
    struct pipe_blend_state blend;
    VGfloat bounds[4];
    VGfloat min_x, min_y, max_x, max_y;
@@ -325,6 +326,9 @@
    set_blend_for_fill(&blend);
 
    memset(&dsa, 0, sizeof(struct pipe_depth_stencil_alpha_state));
+   memset(&sr, 0, sizeof(struct pipe_stencil_ref));
+   /* only need a fixed 0. Rely on default or move it out at least? */
+   cso_set_stencil_ref(ctx->cso_context, &sr);
 
    cso_save_blend(ctx->cso_context);
    cso_save_depth_stencil_alpha(ctx->cso_context);
@@ -336,7 +340,6 @@
       dsa.stencil[0].zfail_op = PIPE_STENCIL_OP_KEEP;
       dsa.stencil[0].zpass_op = PIPE_STENCIL_OP_INVERT;
       dsa.stencil[0].func = PIPE_FUNC_ALWAYS;
-      dsa.stencil[0].ref_value = 0;
       dsa.stencil[0].valuemask = ~0;
 
       cso_set_blend(ctx->cso_context, &blend);
@@ -352,7 +355,6 @@
          dsa.stencil[0].zfail_op = PIPE_STENCIL_OP_KEEP;
          dsa.stencil[0].zpass_op = PIPE_STENCIL_OP_INCR_WRAP;
          dsa.stencil[0].func = PIPE_FUNC_ALWAYS;
-         dsa.stencil[0].ref_value = 0;
          dsa.stencil[0].valuemask = ~0;
 
          /* back */
@@ -362,7 +364,6 @@
          dsa.stencil[1].zfail_op = PIPE_STENCIL_OP_KEEP;
          dsa.stencil[1].zpass_op = PIPE_STENCIL_OP_DECR_WRAP;
          dsa.stencil[1].func = PIPE_FUNC_ALWAYS;
-         dsa.stencil[1].ref_value = 0;
          dsa.stencil[1].valuemask = ~0;
 
          cso_set_blend(ctx->cso_context, &blend);
@@ -375,7 +376,6 @@
 
          cso_save_rasterizer(ctx->cso_context);
          dsa.stencil[0].func = PIPE_FUNC_ALWAYS;
-         dsa.stencil[0].ref_value = 0;
          dsa.stencil[0].valuemask = ~0;
 
          raster.cull_mode = raster.front_winding ^ PIPE_WINDING_BOTH;
@@ -407,7 +407,6 @@
    dsa.stencil[0].fail_op = PIPE_STENCIL_OP_REPLACE;
    dsa.stencil[0].zfail_op = PIPE_STENCIL_OP_REPLACE;
    dsa.stencil[0].zpass_op = PIPE_STENCIL_OP_REPLACE;
-   dsa.stencil[0].ref_value = 0;
    dsa.stencil[0].valuemask = dsa.stencil[0].writemask;
    dsa.stencil[1].enabled = 0;
    memcpy(&dsa.depth, &ctx->state.g3d.dsa.depth,
@@ -425,6 +424,7 @@
 {
    struct array *polys = polyarray->array;
    struct pipe_depth_stencil_alpha_state dsa;
+   struct pipe_stencil_ref sr;
    struct pipe_blend_state blend;
    VGfloat min_x = polyarray->min_x;
    VGfloat min_y = polyarray->min_y;
@@ -442,6 +442,9 @@
    set_blend_for_fill(&blend);
 
    memset(&dsa, 0, sizeof(struct pipe_depth_stencil_alpha_state));
+   memset(&sr, 0, sizeof(struct pipe_stencil_ref));
+   /* only need a fixed 0. Rely on default or move it out at least? */
+   cso_set_stencil_ref(ctx->cso_context, &sr);
 
    cso_save_blend(ctx->cso_context);
    cso_save_depth_stencil_alpha(ctx->cso_context);
@@ -453,7 +456,6 @@
       dsa.stencil[0].zfail_op = PIPE_STENCIL_OP_KEEP;
       dsa.stencil[0].zpass_op = PIPE_STENCIL_OP_INVERT;
       dsa.stencil[0].func = PIPE_FUNC_ALWAYS;
-      dsa.stencil[0].ref_value = 0;
       dsa.stencil[0].valuemask = ~0;
 
       cso_set_blend(ctx->cso_context, &blend);
@@ -472,7 +474,6 @@
          dsa.stencil[0].zfail_op = PIPE_STENCIL_OP_KEEP;
          dsa.stencil[0].zpass_op = PIPE_STENCIL_OP_INCR_WRAP;
          dsa.stencil[0].func = PIPE_FUNC_ALWAYS;
-         dsa.stencil[0].ref_value = 0;
          dsa.stencil[0].valuemask = ~0;
 
          /* back */
@@ -482,7 +483,6 @@
          dsa.stencil[1].zfail_op = PIPE_STENCIL_OP_KEEP;
          dsa.stencil[1].zpass_op = PIPE_STENCIL_OP_DECR_WRAP;
          dsa.stencil[1].func = PIPE_FUNC_ALWAYS;
-         dsa.stencil[1].ref_value = 0;
          dsa.stencil[1].valuemask = ~0;
 
          cso_set_blend(ctx->cso_context, &blend);
@@ -498,7 +498,6 @@
 
          cso_save_rasterizer(ctx->cso_context);
          dsa.stencil[0].func = PIPE_FUNC_ALWAYS;
-         dsa.stencil[0].ref_value = 0;
          dsa.stencil[0].valuemask = ~0;
 
          raster.cull_mode = raster.front_winding ^ PIPE_WINDING_BOTH;
@@ -536,7 +535,6 @@
    dsa.stencil[0].fail_op = PIPE_STENCIL_OP_REPLACE;
    dsa.stencil[0].zfail_op = PIPE_STENCIL_OP_REPLACE;
    dsa.stencil[0].zpass_op = PIPE_STENCIL_OP_REPLACE;
-   dsa.stencil[0].ref_value = 0;
    dsa.stencil[0].valuemask = dsa.stencil[0].writemask;
    dsa.stencil[1].enabled = 0;
    memcpy(&dsa.depth, &ctx->state.g3d.dsa.depth,
diff --git a/src/gallium/state_trackers/wgl/opengl32.def b/src/gallium/state_trackers/wgl/opengl32.def
index 5daa6dd..01a29d0 100644
--- a/src/gallium/state_trackers/wgl/opengl32.def
+++ b/src/gallium/state_trackers/wgl/opengl32.def
@@ -362,7 +362,7 @@
 	wglShareLists
 	wglSwapBuffers
 	wglSwapLayerBuffers
-;	wglSwapMultipleBuffers
+	wglSwapMultipleBuffers
 	wglUseFontBitmapsA
 	wglUseFontBitmapsW
 	wglUseFontOutlinesA
diff --git a/src/gallium/state_trackers/wgl/opengl32.mingw.def b/src/gallium/state_trackers/wgl/opengl32.mingw.def
index 6ebb31a..0bceee0 100644
--- a/src/gallium/state_trackers/wgl/opengl32.mingw.def
+++ b/src/gallium/state_trackers/wgl/opengl32.mingw.def
@@ -362,7 +362,7 @@
 	wglShareLists = wglShareLists@8
 	wglSwapBuffers = wglSwapBuffers@4
 	wglSwapLayerBuffers = wglSwapLayerBuffers@8
-;	wglSwapMultipleBuffers = wglSwapMultipleBuffers@8
+	wglSwapMultipleBuffers = wglSwapMultipleBuffers@8
 	wglUseFontBitmapsA = wglUseFontBitmapsA@16
 	wglUseFontBitmapsW = wglUseFontBitmapsW@16
 	wglUseFontOutlinesA = wglUseFontOutlinesA@32
diff --git a/src/gallium/state_trackers/wgl/stw_context.c b/src/gallium/state_trackers/wgl/stw_context.c
index 0785d2c..05ccd5f 100644
--- a/src/gallium/state_trackers/wgl/stw_context.c
+++ b/src/gallium/state_trackers/wgl/stw_context.c
@@ -75,6 +75,9 @@
    struct stw_context *dst;
    BOOL ret = FALSE;
 
+   if (!stw_dev)
+      return FALSE;
+
    pipe_mutex_lock( stw_dev->ctx_mutex );
    
    src = stw_lookup_context_locked( dhrcSource );
@@ -102,13 +105,15 @@
    struct stw_context *ctx2;
    BOOL ret = FALSE;
 
+   if (!stw_dev)
+      return FALSE;
+
    pipe_mutex_lock( stw_dev->ctx_mutex );
    
    ctx1 = stw_lookup_context_locked( dhglrc1 );
    ctx2 = stw_lookup_context_locked( dhglrc2 );
 
-   if (ctx1 && ctx2 &&
-       ctx1->iPixelFormat == ctx2->iPixelFormat) { 
+   if (ctx1 && ctx2) {
       ret = _mesa_share_state(ctx2->st->ctx, ctx1->st->ctx);
    }
 
diff --git a/src/gallium/state_trackers/wgl/stw_device.c b/src/gallium/state_trackers/wgl/stw_device.c
index 7785aba..e5fa6ac 100644
--- a/src/gallium/state_trackers/wgl/stw_device.c
+++ b/src/gallium/state_trackers/wgl/stw_device.c
@@ -152,24 +152,27 @@
 void
 stw_cleanup(void)
 {
-   unsigned i;
+   DHGLRC dhglrc;
 
    debug_printf("%s\n", __FUNCTION__);
 
    if (!stw_dev)
       return;
    
+   /*
+    * Abort cleanup if there are still active contexts. In some situations
+    * this DLL may be unloaded before the DLL that is using GL contexts is.
+    */
    pipe_mutex_lock( stw_dev->ctx_mutex );
-   {
-      /* Ensure all contexts are destroyed */
-      i = handle_table_get_first_handle(stw_dev->ctx_table);
-      while (i) {
-         DrvDeleteContext(i);
-         i = handle_table_get_next_handle(stw_dev->ctx_table, i);
-      }
-      handle_table_destroy(stw_dev->ctx_table);
-   }
+   dhglrc = handle_table_get_first_handle(stw_dev->ctx_table);
    pipe_mutex_unlock( stw_dev->ctx_mutex );
+   if (dhglrc) {
+      debug_printf("%s: contexts still active -- cleanup aborted\n", __FUNCTION__);
+      stw_dev = NULL;
+      return;
+   }
+
+   handle_table_destroy(stw_dev->ctx_table);
 
    stw_framebuffer_cleanup();
    
diff --git a/src/gallium/state_trackers/wgl/stw_framebuffer.c b/src/gallium/state_trackers/wgl/stw_framebuffer.c
index 129a6298..02de21c 100644
--- a/src/gallium/state_trackers/wgl/stw_framebuffer.c
+++ b/src/gallium/state_trackers/wgl/stw_framebuffer.c
@@ -179,7 +179,7 @@
    if(!tls_data)
       return 0;
    
-   if (nCode < 0)
+   if (nCode < 0 || !stw_dev)
        return CallNextHookEx(tls_data->hCallWndProcHook, nCode, wParam, lParam);
 
    if (pParams->message == WM_WINDOWPOSCHANGED) {
@@ -332,6 +332,9 @@
    struct stw_framebuffer *fb;
    struct stw_framebuffer *next;
 
+   if (!stw_dev)
+      return;
+
    pipe_mutex_lock( stw_dev->fb_mutex );
 
    fb = stw_dev->fb_head;
@@ -387,6 +390,9 @@
 {
    struct stw_framebuffer *fb;
 
+   if (!stw_dev)
+      return NULL;
+
    pipe_mutex_lock( stw_dev->fb_mutex );
    fb = stw_framebuffer_from_hdc_locked(hdc);
    pipe_mutex_unlock( stw_dev->fb_mutex );
@@ -421,6 +427,9 @@
    uint index;
    struct stw_framebuffer *fb;
 
+   if (!stw_dev)
+      return FALSE;
+
    index = (uint) iPixelFormat - 1;
    count = stw_pixelformat_get_extended_count();
    if (index >= count)
@@ -475,6 +484,9 @@
    struct pipe_screen *screen;
    struct pipe_surface *surface;
 
+   if (!stw_dev)
+      return FALSE;
+
    fb = stw_framebuffer_from_hdc( hdc );
    if (fb == NULL)
       return FALSE;
@@ -576,6 +588,9 @@
    struct stw_framebuffer *fb;
    struct pipe_surface *surface = NULL;
 
+   if (!stw_dev)
+      return FALSE;
+
    fb = stw_framebuffer_from_hdc( hdc );
    if (fb == NULL)
       return FALSE;
diff --git a/src/gallium/state_trackers/wgl/stw_getprocaddress.c b/src/gallium/state_trackers/wgl/stw_getprocaddress.c
index 8875dc2..d43a55f 100644
--- a/src/gallium/state_trackers/wgl/stw_getprocaddress.c
+++ b/src/gallium/state_trackers/wgl/stw_getprocaddress.c
@@ -34,6 +34,8 @@
 
 #include "glapi/glapi.h"
 #include "stw_ext_gallium.h"
+#include "stw_device.h"
+#include "stw_icd.h"
 
 struct stw_extension_entry
 {
@@ -73,6 +75,9 @@
 {
    const struct stw_extension_entry *entry;
 
+   if (!stw_dev)
+      return NULL;
+
    if (lpszProc[0] == 'w' && lpszProc[1] == 'g' && lpszProc[2] == 'l')
       for (entry = stw_extension_entries; entry->name; entry++)
          if (strcmp( lpszProc, entry->name ) == 0)
diff --git a/src/gallium/state_trackers/wgl/stw_pixelformat.c b/src/gallium/state_trackers/wgl/stw_pixelformat.c
index 7d4c243..b750b03 100644
--- a/src/gallium/state_trackers/wgl/stw_pixelformat.c
+++ b/src/gallium/state_trackers/wgl/stw_pixelformat.c
@@ -302,6 +302,9 @@
 
    (void) hdc;
 
+   if (!stw_dev)
+      return 0;
+
    count = stw_pixelformat_get_extended_count();
    index = (uint) iPixelFormat - 1;
 
diff --git a/src/gallium/state_trackers/wgl/stw_wgl.c b/src/gallium/state_trackers/wgl/stw_wgl.c
index bb199fd..5fbb7bf 100644
--- a/src/gallium/state_trackers/wgl/stw_wgl.c
+++ b/src/gallium/state_trackers/wgl/stw_wgl.c
@@ -97,6 +97,19 @@
 }
 
 
+WINGDIAPI DWORD WINAPI
+wglSwapMultipleBuffers(UINT n,
+                       CONST WGLSWAP *ps)
+{
+   UINT i;
+
+   for (i =0; i < n; ++i)
+      wglSwapBuffers(ps->hdc);
+
+   return 0;
+}
+
+
 WINGDIAPI BOOL APIENTRY
 wglSwapLayerBuffers(
    HDC hdc,
diff --git a/src/gallium/state_trackers/wgl/stw_wgl.h b/src/gallium/state_trackers/wgl/stw_wgl.h
index a981799..57baaf0 100644
--- a/src/gallium/state_trackers/wgl/stw_wgl.h
+++ b/src/gallium/state_trackers/wgl/stw_wgl.h
@@ -59,5 +59,21 @@
                   int iPixelFormat,
                   CONST PIXELFORMATDESCRIPTOR *ppfd);
 
+#if defined(__MINGW32__) || (WINVER < 0x0500)
+
+typedef struct _WGLSWAP
+{
+   HDC hdc;
+   UINT uiFlags;
+} WGLSWAP;
+
+#define WGL_SWAPMULTIPLE_MAX 16
+
+WINGDIAPI DWORD WINAPI
+wglSwapMultipleBuffers(UINT n,
+                       CONST WGLSWAP *ps);
+
+#endif
+
 
 #endif /* STW_WGL_H_ */
diff --git a/src/gallium/state_trackers/xorg/xorg_dri2.c b/src/gallium/state_trackers/xorg/xorg_dri2.c
index 7457fe1..5b67392 100644
--- a/src/gallium/state_trackers/xorg/xorg_dri2.c
+++ b/src/gallium/state_trackers/xorg/xorg_dri2.c
@@ -103,14 +103,26 @@
 	    pipe_texture_reference(&tex, exa_priv->depth_stencil_tex);
         else {
 	    struct pipe_texture template;
+            unsigned depthBits = (format != 0) ? format : pDraw->depth;
 	    memset(&template, 0, sizeof(template));
 	    template.target = PIPE_TEXTURE_2D;
-	    if (buffer->attachment == DRI2BufferDepth)
-		template.format = ms->ds_depth_bits_last ?
-		    PIPE_FORMAT_X8Z24_UNORM : PIPE_FORMAT_Z24X8_UNORM;
-	    else
-		template.format = ms->ds_depth_bits_last ?
-		    PIPE_FORMAT_S8Z24_UNORM : PIPE_FORMAT_Z24S8_UNORM;
+	    if (buffer->attachment == DRI2BufferDepth) {
+               switch(depthBits) {
+               case 16:
+                  template.format = PIPE_FORMAT_Z16_UNORM;
+                  break;
+               case 32:
+                  template.format = PIPE_FORMAT_Z32_UNORM;
+                  break;
+               default:
+                  template.format = ms->ds_depth_bits_last ?
+                                    PIPE_FORMAT_X8Z24_UNORM : PIPE_FORMAT_Z24X8_UNORM;
+                  break;
+               }
+            } else {
+               template.format = ms->ds_depth_bits_last ?
+                                 PIPE_FORMAT_S8Z24_UNORM : PIPE_FORMAT_Z24S8_UNORM;
+            }
 	    template.width0 = pDraw->width;
 	    template.height0 = pDraw->height;
 	    template.depth0 = 1;
diff --git a/src/gallium/state_trackers/xorg/xorg_exa.c b/src/gallium/state_trackers/xorg/xorg_exa.c
index ae66c4b..665efdc 100644
--- a/src/gallium/state_trackers/xorg/xorg_exa.c
+++ b/src/gallium/state_trackers/xorg/xorg_exa.c
@@ -45,6 +45,7 @@
 #include "util/u_rect.h"
 #include "util/u_math.h"
 #include "util/u_debug.h"
+#include "util/u_format.h"
 
 #define DEBUG_PRINT 0
 #define ROUND_UP_TEXTURES 1
@@ -360,7 +361,7 @@
     if (!exa->scrn->is_format_supported(exa->scrn, priv->tex->format,
                                         priv->tex->target,
                                         PIPE_TEXTURE_USAGE_RENDER_TARGET, 0)) {
-	XORG_FALLBACK("format %s", pf_name(priv->tex->format));
+	XORG_FALLBACK("format %s", util_format_name(priv->tex->format));
     }
 
     return xorg_solid_bind_state(exa, priv, fg);
@@ -441,12 +442,12 @@
     if (!exa->scrn->is_format_supported(exa->scrn, priv->tex->format,
                                         priv->tex->target,
                                         PIPE_TEXTURE_USAGE_RENDER_TARGET, 0))
-	XORG_FALLBACK("pDst format %s", pf_name(priv->tex->format));
+	XORG_FALLBACK("pDst format %s", util_format_name(priv->tex->format));
 
     if (!exa->scrn->is_format_supported(exa->scrn, src_priv->tex->format,
                                         src_priv->tex->target,
                                         PIPE_TEXTURE_USAGE_SAMPLER, 0))
-	XORG_FALLBACK("pSrc format %s", pf_name(src_priv->tex->format));
+	XORG_FALLBACK("pSrc format %s", util_format_name(src_priv->tex->format));
 
     exa->copy.src = src_priv;
     exa->copy.dst = priv;
@@ -652,7 +653,7 @@
    if (!exa->scrn->is_format_supported(exa->scrn, priv->tex->format,
                                        priv->tex->target,
                                        PIPE_TEXTURE_USAGE_RENDER_TARGET, 0))
-      XORG_FALLBACK("pDst format: %s", pf_name(priv->tex->format));
+      XORG_FALLBACK("pDst format: %s", util_format_name(priv->tex->format));
 
    if (priv->picture_format != pDstPicture->format)
       XORG_FALLBACK("pDst pic_format: %s != %s",
@@ -667,7 +668,7 @@
       if (!exa->scrn->is_format_supported(exa->scrn, priv->tex->format,
                                           priv->tex->target,
                                           PIPE_TEXTURE_USAGE_SAMPLER, 0))
-         XORG_FALLBACK("pSrc format: %s", pf_name(priv->tex->format));
+         XORG_FALLBACK("pSrc format: %s", util_format_name(priv->tex->format));
 
       if (!picture_check_formats(priv, pSrcPicture))
          XORG_FALLBACK("pSrc pic_format: %s != %s",
@@ -684,7 +685,7 @@
       if (!exa->scrn->is_format_supported(exa->scrn, priv->tex->format,
                                           priv->tex->target,
                                           PIPE_TEXTURE_USAGE_SAMPLER, 0))
-         XORG_FALLBACK("pMask format: %s", pf_name(priv->tex->format));
+         XORG_FALLBACK("pMask format: %s", util_format_name(priv->tex->format));
 
       if (!picture_check_formats(priv, pMaskPicture))
          XORG_FALLBACK("pMask pic_format: %s != %s",
diff --git a/src/gallium/winsys/drm/radeon/core/radeon_buffer.c b/src/gallium/winsys/drm/radeon/core/radeon_buffer.c
index 3b1c386..5cbf0dd 100644
--- a/src/gallium/winsys/drm/radeon/core/radeon_buffer.c
+++ b/src/gallium/winsys/drm/radeon/core/radeon_buffer.c
@@ -217,9 +217,10 @@
                                      boolean microtiled,
                                      boolean macrotiled)
 {
+    struct radeon_winsys_priv *priv = ((struct radeon_winsys *)ws)->priv;
     struct radeon_pipe_buffer *radeon_buffer =
         (struct radeon_pipe_buffer*)buffer;
-    uint32_t flags = 0;
+    uint32_t flags = 0, old_flags, old_pitch;
 
     if (microtiled) {
         flags |= RADEON_BO_FLAGS_MICRO_TILE;
@@ -228,7 +229,17 @@
         flags |= RADEON_BO_FLAGS_MACRO_TILE;
     }
 
-    radeon_bo_set_tiling(radeon_buffer->bo, flags, pitch);
+    radeon_bo_get_tiling(radeon_buffer->bo, &old_flags, &old_pitch);
+
+    if (flags != old_flags || pitch != old_pitch) {
+        /* Tiling determines how DRM treats the buffer data.
+         * We must flush CS when changing it if the buffer is referenced. */
+        if (radeon_bo_is_referenced_by_cs(radeon_buffer->bo, priv->cs)) {
+            priv->flush_cb(priv->flush_data);
+        }
+
+        radeon_bo_set_tiling(radeon_buffer->bo, flags, pitch);
+    }
 }
 
 static void radeon_fence_reference(struct pipe_winsys *ws,
diff --git a/src/gallium/winsys/drm/radeon/python/README b/src/gallium/winsys/drm/radeon/python/README
index d9e49bc..339836a 100644
--- a/src/gallium/winsys/drm/radeon/python/README
+++ b/src/gallium/winsys/drm/radeon/python/README
@@ -12,4 +12,4 @@
 
   export PYTHONPATH=$PWD/build/linux-x86-debug/gallium/winsys/drm/radeon/python:$PWD/build/linux-x86-debug/gallium/state_trackers/python 
  
-  python src/gallium/state_trackers/python/samples/tri.py
+  python progs/gallium/python/samples/tri.py
diff --git a/src/gallium/winsys/gdi/gdi_llvmpipe_winsys.c b/src/gallium/winsys/gdi/gdi_llvmpipe_winsys.c
index 03dbd76..e9e5990 100644
--- a/src/gallium/winsys/gdi/gdi_llvmpipe_winsys.c
+++ b/src/gallium/winsys/gdi/gdi_llvmpipe_winsys.c
@@ -251,13 +251,13 @@
 {
    switch (fdwReason) {
    case DLL_PROCESS_ATTACH:
-      if (!stw_init(&stw_winsys)) {
-         return FALSE;
-      }
-      return stw_init_thread();
+      stw_init(&stw_winsys);
+      stw_init_thread();
+      break;
 
    case DLL_THREAD_ATTACH:
-      return stw_init_thread();
+      stw_init_thread();
+      break;
 
    case DLL_THREAD_DETACH:
       stw_cleanup_thread();
diff --git a/src/gallium/winsys/gdi/gdi_softpipe_winsys.c b/src/gallium/winsys/gdi/gdi_softpipe_winsys.c
index 2078020..71360e5 100644
--- a/src/gallium/winsys/gdi/gdi_softpipe_winsys.c
+++ b/src/gallium/winsys/gdi/gdi_softpipe_winsys.c
@@ -297,13 +297,13 @@
 {
    switch (fdwReason) {
    case DLL_PROCESS_ATTACH:
-      if (!stw_init(&stw_winsys)) {
-         return FALSE;
-      }
-      return stw_init_thread();
+      stw_init(&stw_winsys);
+      stw_init_thread();
+      break;
 
    case DLL_THREAD_ATTACH:
-      return stw_init_thread();
+      stw_init_thread();
+      break;
 
    case DLL_THREAD_DETACH:
       stw_cleanup_thread();
diff --git a/src/glsl/apps/process.c b/src/glsl/apps/process.c
index 2d2ab91..e65f35c 100644
--- a/src/glsl/apps/process.c
+++ b/src/glsl/apps/process.c
@@ -47,6 +47,7 @@
    unsigned int i;
 
    if (argc != 3) {
+      printf("Usage: process infile outfile\n");
       return 1;
    }
 
diff --git a/src/glsl/apps/purify.c b/src/glsl/apps/purify.c
index 8c01f4f..3019e8b 100644
--- a/src/glsl/apps/purify.c
+++ b/src/glsl/apps/purify.c
@@ -45,6 +45,7 @@
    FILE *out;
 
    if (argc != 3) {
+      printf("Usage: purify infile outfile\n");
       return 1;
    }
 
diff --git a/src/glsl/apps/tokenise.c b/src/glsl/apps/tokenise.c
index 9ff7315..c70c3cc 100644
--- a/src/glsl/apps/tokenise.c
+++ b/src/glsl/apps/tokenise.c
@@ -46,6 +46,7 @@
    unsigned int i;
 
    if (argc != 3) {
+      printf("Usage: tokenize infile outfile\n");
       return 1;
    }
 
diff --git a/src/glsl/apps/version.c b/src/glsl/apps/version.c
index 40a4a06..0420f97 100644
--- a/src/glsl/apps/version.c
+++ b/src/glsl/apps/version.c
@@ -45,6 +45,7 @@
    FILE *out;
 
    if (argc != 3) {
+      printf("Usage: version infile outfile\n");
       return 1;
    }
 
diff --git a/src/glsl/cl/sl_cl_parse.c b/src/glsl/cl/sl_cl_parse.c
index e256ab8..8106ff6 100644
--- a/src/glsl/cl/sl_cl_parse.c
+++ b/src/glsl/cl/sl_cl_parse.c
@@ -120,6 +120,11 @@
 #define TYPE_CENTER                                95
 #define TYPE_CENTROID                              96
 
+/* layout qualifiers */
+#define LAYOUT_QUALIFIER_NONE                      0
+#define LAYOUT_QUALIFIER_UPPER_LEFT                1
+#define LAYOUT_QUALIFIER_PIXEL_CENTER_INTEGER      2
+
 /* type specifier */
 #define TYPE_SPECIFIER_VOID                        0
 #define TYPE_SPECIFIER_BOOL                        1
@@ -297,6 +302,10 @@
    int out;
    int inout;
 
+   int layout;
+   int origin_upper_left;
+   int pixel_center_integer;
+
    int _struct;
 
    int __constructor;
@@ -316,6 +325,9 @@
 
    int _false;
    int _true;
+
+   int all;
+   int _GL_ARB_fragment_coord_conventions;
 };
 
 
@@ -334,6 +346,8 @@
    unsigned int shader_type;
    unsigned int parsing_builtin;
 
+   unsigned int fragment_coord_conventions:1;
+
    char error[256];
    int process_error;
 };
@@ -451,6 +465,10 @@
       case SL_PP_IDENTIFIER:
       case SL_PP_UINT:
       case SL_PP_FLOAT:
+      case SL_PP_EXTENSION_REQUIRE:
+      case SL_PP_EXTENSION_ENABLE:
+      case SL_PP_EXTENSION_WARN:
+      case SL_PP_EXTENSION_DISABLE:
       case SL_PP_EOF:
          ctx->tokens_read++;
          break;
@@ -462,6 +480,10 @@
 }
 
 
+/**
+ * Try to parse/match a particular token.
+ * \return 0 for success, -1 for error.
+ */
 static int
 _parse_token(struct parse_context *ctx,
              enum sl_pp_token token,
@@ -477,6 +499,10 @@
 }
 
 
+/**
+ * Try to parse an identifer.
+ * \return 0 for success, -1 for error
+ */
 static int
 _parse_id(struct parse_context *ctx,
           int id,
@@ -707,8 +733,65 @@
 
 
 static int
-_parse_type_qualifier(struct parse_context *ctx,
-                      struct parse_state *ps)
+_parse_layout_qualifier(struct parse_context *ctx,
+                        struct parse_state *ps)
+{
+   if (_parse_id(ctx, ctx->dict.layout, ps) == 0) {
+      if (!ctx->fragment_coord_conventions) {
+         _error(ctx, "GL_ARB_fragment_coord_conventions extension must be enabled "
+                     "in order to use a layout qualifier");
+         return -1;
+      }
+
+      /* Layout qualifiers are only defined for fragment shaders,
+       * so do an early check.
+       */
+      if (ctx->shader_type != 1) {
+         _error(ctx, "layout qualifiers are only valid for fragment shaders");
+         return -1;
+      }
+
+      /* start of a parenthesised list of layout qualifiers */
+
+      if (_parse_token(ctx, SL_PP_LPAREN, ps)) {
+         _error(ctx, "expected `('");
+         return -1;
+      }
+
+      /* parse comma-separated ID list */
+      while (1) {
+         if (_parse_id(ctx, ctx->dict.origin_upper_left, ps) == 0) {
+            _emit(ctx, &ps->out, LAYOUT_QUALIFIER_UPPER_LEFT);
+         }
+         else if (_parse_id(ctx, ctx->dict.pixel_center_integer, ps) == 0) {
+            _emit(ctx, &ps->out, LAYOUT_QUALIFIER_PIXEL_CENTER_INTEGER);
+         }
+         else {
+            _error(ctx, "expected a layout qualifier name");
+            return -1;
+         }
+
+         if (_parse_token(ctx, SL_PP_RPAREN, ps) == 0) {
+            /* all done */
+            break;
+         }
+         else if (_parse_token(ctx, SL_PP_COMMA, ps) == 0) {
+            /* another layout qualifier is coming */
+         }
+         else {
+            _error(ctx, "expected `,' or `)'");
+            return -1;
+         }
+      }
+   }
+
+   return 0;
+}
+
+
+static int
+_parse_storage_qualifier(struct parse_context *ctx,
+                         struct parse_state *ps)
 {
    struct parse_state p = *ps;
    const struct sl_pp_token_info *input = _fetch_token(ctx, p.in);
@@ -1006,13 +1089,19 @@
 {
    struct parse_state p = *ps;
 
+   if (_parse_layout_qualifier(ctx, &p)) {
+      return -1;
+   }
+   _emit(ctx, &p.out, LAYOUT_QUALIFIER_NONE);
+
    if (_parse_invariant_qualifier(ctx, &p)) {
       _emit(ctx, &p.out, TYPE_VARIANT);
    }
+
    if (_parse_centroid_qualifier(ctx, &p)) {
       _emit(ctx, &p.out, TYPE_CENTER);
    }
-   if (_parse_type_qualifier(ctx, &p)) {
+   if (_parse_storage_qualifier(ctx, &p)) {
       _emit(ctx, &p.out, TYPE_QUALIFIER_NONE);
    }
    if (_parse_precision(ctx, &p)) {
@@ -1698,7 +1787,7 @@
 
    (void) e;
 
-   if (_parse_type_qualifier(ctx, &p)) {
+   if (_parse_storage_qualifier(ctx, &p)) {
       _emit(ctx, &p.out, TYPE_QUALIFIER_NONE);
    }
    _parse_parameter_qualifier(ctx, &p);
@@ -2679,14 +2768,59 @@
 
 
 static int
+_parse_extensions(struct parse_context *ctx,
+                  struct parse_state *ps)
+{
+   for (;;) {
+      const struct sl_pp_token_info *input = _fetch_token(ctx, ps->in);
+      unsigned int enable;
+
+      if (!input) {
+         return -1;
+      }
+
+      switch (input->token) {
+      case SL_PP_EXTENSION_REQUIRE:
+      case SL_PP_EXTENSION_ENABLE:
+      case SL_PP_EXTENSION_WARN:
+         enable = 1;
+         break;
+      case SL_PP_EXTENSION_DISABLE:
+         enable = 0;
+         break;
+      default:
+         return 0;
+      }
+
+      ps->in++;
+      if (input->data.extension == ctx->dict.all) {
+         ctx->fragment_coord_conventions = enable;
+      }
+      else if (input->data.extension == ctx->dict._GL_ARB_fragment_coord_conventions) {
+         ctx->fragment_coord_conventions = enable;
+      }
+   }
+}
+
+
+static int
 _parse_translation_unit(struct parse_context *ctx,
                         struct parse_state *ps)
 {
    _emit(ctx, &ps->out, REVISION);
+   if (_parse_extensions(ctx, ps)) {
+      return -1;
+   }
    if (_parse_external_declaration(ctx, ps)) {
       return -1;
    }
-   while (_parse_external_declaration(ctx, ps) == 0) {
+   for (;;) {
+      if (_parse_extensions(ctx, ps)) {
+         return -1;
+      }
+      if (_parse_external_declaration(ctx, ps)) {
+         break;
+      }
    }
    _emit(ctx, &ps->out, EXTERNAL_NULL);
    if (_parse_token(ctx, SL_PP_EOF, ps)) {
@@ -2772,6 +2906,10 @@
    ADD_NAME(ctx, out);
    ADD_NAME(ctx, inout);
 
+   ADD_NAME(ctx, layout);
+   ADD_NAME(ctx, origin_upper_left);
+   ADD_NAME(ctx, pixel_center_integer);
+
    ADD_NAME_STR(ctx, _struct, "struct");
 
    ADD_NAME(ctx, __constructor);
@@ -2792,12 +2930,17 @@
    ADD_NAME_STR(ctx, _false, "false");
    ADD_NAME_STR(ctx, _true, "true");
 
+   ADD_NAME(ctx, all);
+   ADD_NAME_STR(ctx, _GL_ARB_fragment_coord_conventions, "GL_ARB_fragment_coord_conventions");
+
    ctx.out_buf = NULL;
    ctx.out_cap = 0;
 
    ctx.shader_type = shader_type;
    ctx.parsing_builtin = 1;
 
+   ctx.fragment_coord_conventions = 0;
+
    ctx.error[0] = '\0';
    ctx.process_error = 0;
 
diff --git a/src/glsl/pp/sl_pp_context.h b/src/glsl/pp/sl_pp_context.h
index 983a09c..8abb970 100644
--- a/src/glsl/pp/sl_pp_context.h
+++ b/src/glsl/pp/sl_pp_context.h
@@ -45,7 +45,6 @@
 
 struct sl_pp_extension {
    int name;   /*< GL_VENDOR_extension_name */
-   int enabled;
 };
 
 struct sl_pp_predefined {
@@ -53,6 +52,15 @@
    int value;
 };
 
+union sl_pp_if_state {
+   struct {
+      unsigned int condition:1;
+      unsigned int went_thru_else:1;
+      unsigned int had_true_cond:1;
+   } u;
+   unsigned int value;
+};
+
 struct sl_pp_context {
    char *cstr_pool;
    unsigned int cstr_pool_max;
@@ -68,7 +76,7 @@
    struct sl_pp_predefined predefined[SL_PP_MAX_PREDEFINED];
    unsigned int num_predefined;
 
-   unsigned int if_stack[SL_PP_MAX_IF_NESTING];
+   union sl_pp_if_state if_stack[SL_PP_MAX_IF_NESTING];
    unsigned int if_ptr;
    unsigned int if_value;
 
diff --git a/src/glsl/pp/sl_pp_extension.c b/src/glsl/pp/sl_pp_extension.c
index 777e42d..d119677 100644
--- a/src/glsl/pp/sl_pp_extension.c
+++ b/src/glsl/pp/sl_pp_extension.c
@@ -53,8 +53,6 @@
       return -1;
    }
 
-   ext.enabled = 0;
-
    context->extensions[context->num_extensions++] = ext;
 
    assert(context->num_extensions <= sizeof(context->extensions));
@@ -62,6 +60,7 @@
    return 0;
 }
 
+
 /**
  * Process a "#extension name: behavior" directive.
  */
@@ -75,7 +74,6 @@
    int extension_name = -1;
    int behavior = -1;
    struct sl_pp_token_info out;
-   struct sl_pp_extension *extension = NULL;
 
    /* Grab the extension name. */
    if (first < last && input[first].token == SL_PP_IDENTIFIER) {
@@ -97,7 +95,6 @@
       for (i = 0; i < context->num_extensions; i++) {
          if (extension_name == context->extensions[i].name) {
             out.data.extension = extension_name;
-            extension = &context->extensions[i];
             break;
          }
       }
@@ -137,7 +134,6 @@
          return -1;
       }
       out.token = SL_PP_EXTENSION_REQUIRE;
-      extension->enabled = 1;
    } else if (behavior == context->dict.enable) {
       if (out.data.extension == -1) {
          /* Warning: the extension cannot be enabled. */
@@ -148,21 +144,18 @@
          return -1;
       }
       out.token = SL_PP_EXTENSION_ENABLE;
-      extension->enabled = 1;
    } else if (behavior == context->dict.warn) {
       if (out.data.extension == -1) {
          /* Warning: the extension is not supported. */
          return 0;
       }
       out.token = SL_PP_EXTENSION_WARN;
-      extension->enabled = 0;
    } else if (behavior == context->dict.disable) {
       if (out.data.extension == -1) {
          /* Warning: the extension is not supported. */
          return 0;
       }
       out.token = SL_PP_EXTENSION_DISABLE;
-      extension->enabled = 0;
    } else {
       strcpy(context->error_msg, "unrecognised behavior name");
       return -1;
diff --git a/src/glsl/pp/sl_pp_if.c b/src/glsl/pp/sl_pp_if.c
index 272c3a2..25cb7a3 100644
--- a/src/glsl/pp/sl_pp_if.c
+++ b/src/glsl/pp/sl_pp_if.c
@@ -40,7 +40,7 @@
 
    for (i = 0; i < context->num_extensions; i++) {
       if (macro_name == context->extensions[i].name) {
-         return context->extensions[i].enabled;
+         return 1;
       }
    }
 
@@ -108,7 +108,7 @@
    unsigned int i;
 
    for (i = context->if_ptr; i < SL_PP_MAX_IF_NESTING; i++) {
-      if (!(context->if_stack[i] & 1)) {
+      if (!context->if_stack[i].u.condition) {
          return 0;
       }
    }
@@ -182,7 +182,8 @@
    free(state.out);
 
    context->if_ptr--;
-   context->if_stack[context->if_ptr] = result ? 1 : 0;
+   context->if_stack[context->if_ptr].value = 0;
+   context->if_stack[context->if_ptr].u.condition = result ? 1 : 0;
    context->if_value = _evaluate_if_stack(context);
 
    return 0;
@@ -191,19 +192,24 @@
 static int
 _parse_else(struct sl_pp_context *context)
 {
+   union sl_pp_if_state *state = &context->if_stack[context->if_ptr];
+
    if (context->if_ptr == SL_PP_MAX_IF_NESTING) {
       strcpy(context->error_msg, "no matching `#if'");
       return -1;
    }
 
-   /* Bit b1 indicates we already went through #else. */
-   if (context->if_stack[context->if_ptr] & 2) {
+   if (state->u.went_thru_else) {
       strcpy(context->error_msg, "no matching `#if'");
       return -1;
    }
 
-   /* Invert current condition value and mark that we are in the #else block. */
-   context->if_stack[context->if_ptr] = (1 - (context->if_stack[context->if_ptr] & 1)) | 2;
+   /* Once we had a true condition, the subsequent #elifs should always be false. */
+   state->u.had_true_cond |= state->u.condition;
+
+   /* Update current condition value and mark that we are in the #else block. */
+   state->u.condition = !(state->u.had_true_cond | state->u.condition);
+   state->u.went_thru_else = 1;
    context->if_value = _evaluate_if_stack(context);
 
    return 0;
@@ -233,7 +239,8 @@
       switch (input[i].token) {
       case SL_PP_IDENTIFIER:
          context->if_ptr--;
-         context->if_stack[context->if_ptr] = _macro_is_defined(context, input[i].data.identifier);
+         context->if_stack[context->if_ptr].value = 0;
+         context->if_stack[context->if_ptr].u.condition = _macro_is_defined(context, input[i].data.identifier);
          context->if_value = _evaluate_if_stack(context);
          return 0;
 
@@ -267,7 +274,8 @@
       switch (input[i].token) {
       case SL_PP_IDENTIFIER:
          context->if_ptr--;
-         context->if_stack[context->if_ptr] = !_macro_is_defined(context, input[i].data.identifier);
+         context->if_stack[context->if_ptr].value = 0;
+         context->if_stack[context->if_ptr].u.condition = !_macro_is_defined(context, input[i].data.identifier);
          context->if_value = _evaluate_if_stack(context);
          return 0;
 
@@ -292,7 +300,7 @@
       return -1;
    }
 
-   if (context->if_stack[context->if_ptr] & 1) {
+   if (context->if_stack[context->if_ptr].u.condition) {
       context->if_ptr++;
       if (_parse_if(context, buffer)) {
          return -1;
@@ -300,7 +308,7 @@
    }
 
    /* We are still in the #if block. */
-   context->if_stack[context->if_ptr] = context->if_stack[context->if_ptr] & ~2;
+   context->if_stack[context->if_ptr].u.went_thru_else = 0;
 
    return 0;
 }
diff --git a/src/glsl/pp/sl_pp_process.c b/src/glsl/pp/sl_pp_process.c
index f89986d..315ad9b 100644
--- a/src/glsl/pp/sl_pp_process.c
+++ b/src/glsl/pp/sl_pp_process.c
@@ -87,6 +87,7 @@
       int found_eof = 0;
 
       if (context->process_state.out_len) {
+         assert(context->process_state.out);
          *output = context->process_state.out[0];
 
          if (context->process_state.out_len > 1) {
diff --git a/src/glu/mesa/mipmap.c b/src/glu/mesa/mipmap.c
index d85ce9b..ad6b6e6 100644
--- a/src/glu/mesa/mipmap.c
+++ b/src/glu/mesa/mipmap.c
@@ -287,7 +287,11 @@
       }
       break;
    default:
-      return GLU_INVALID_ENUM;
+      {
+         free(tempin);
+         free(tempout);
+         return GLU_INVALID_ENUM;
+      }
    }
 
 
@@ -670,6 +674,7 @@
 	 break;
       default:
 	 /* Not implemented */
+	 free(texture);
 	 return GLU_ERROR;
       }
    }
diff --git a/src/glu/mini/mipmap.c b/src/glu/mini/mipmap.c
index a655d21..1cf739a 100644
--- a/src/glu/mini/mipmap.c
+++ b/src/glu/mini/mipmap.c
@@ -287,7 +287,11 @@
       }
       break;
    default:
-      return GLU_INVALID_ENUM;
+      {
+         free(tempin);
+         free(tempout);
+         return GLU_INVALID_ENUM;
+      }
    }
 
 
diff --git a/src/glu/sgi/libnurbs/internals/arc.h b/src/glu/sgi/libnurbs/internals/arc.h
index e986019..ca397f3 100644
--- a/src/glu/sgi/libnurbs/internals/arc.h
+++ b/src/glu/sgi/libnurbs/internals/arc.h
@@ -108,6 +108,9 @@
 inline
 Arc::Arc( Arc *j, PwlArc *p )
 {
+    prev = NULL;
+    next = NULL;
+    link = NULL;
     bezierArc = NULL;
     pwlArc = p;
     type = j->type;
@@ -123,6 +126,9 @@
 inline
 Arc::Arc( arc_side side, long _nuid )
 {
+    prev = NULL;
+    next = NULL;
+    link = NULL;
     bezierArc = NULL;
     pwlArc = NULL;
     type = 0;
diff --git a/src/glu/sgi/libnurbs/internals/bin.cc b/src/glu/sgi/libnurbs/internals/bin.cc
index 54b4061..ff75b86 100644
--- a/src/glu/sgi/libnurbs/internals/bin.cc
+++ b/src/glu/sgi/libnurbs/internals/bin.cc
@@ -49,6 +49,7 @@
 Bin::Bin()
 {
     head = NULL;
+    current = NULL;
 }
 
 Bin::~Bin()
diff --git a/src/glu/sgi/libnurbs/internals/bufpool.cc b/src/glu/sgi/libnurbs/internals/bufpool.cc
index 8cc847a..53ac1a5 100644
--- a/src/glu/sgi/libnurbs/internals/bufpool.cc
+++ b/src/glu/sgi/libnurbs/internals/bufpool.cc
@@ -60,6 +60,9 @@
     curblock	= 0;
     freelist	= 0;
     nextfree	= 0;
+    for (int i = 0; i < NBLOCKS; i++) {
+        blocklist[i] = 0;
+    }
 }
 
 /*-----------------------------------------------------------------------------
diff --git a/src/glu/sgi/libnurbs/internals/curve.cc b/src/glu/sgi/libnurbs/internals/curve.cc
index 33e2752..b7c4d4a 100644
--- a/src/glu/sgi/libnurbs/internals/curve.cc
+++ b/src/glu/sgi/libnurbs/internals/curve.cc
@@ -60,6 +60,12 @@
     cullval = mapdesc->isCulling() ? CULL_ACCEPT : CULL_TRIVIAL_ACCEPT;
     order = geo->qspec[0].order;
     stride = MAXCOORDS;
+    for( int i = 0; i < MAXORDER * MAXCOORDS; i++ ) {
+        cpts[i] = 0;
+        spts[i] = 0;
+    }
+    stepsize = 0;
+    minstepsize = 0;
 
     REAL *ps  = geo->cpts; 
     Quiltspec_ptr qs = geo->qspec;
diff --git a/src/glu/sgi/libnurbs/internals/curvelist.cc b/src/glu/sgi/libnurbs/internals/curvelist.cc
index abfebb7..8f2ee46 100644
--- a/src/glu/sgi/libnurbs/internals/curvelist.cc
+++ b/src/glu/sgi/libnurbs/internals/curvelist.cc
@@ -53,20 +53,23 @@
     range[0] = pta;
     range[1] = ptb;
     range[2] = ptb - pta;
+    needsSubdivision = 0;
+    stepsize = 0;
 }
 
 Curvelist::Curvelist( Curvelist &upper, REAL value )
 {
-    Curvelist &lower = *this;
     curve = 0;
     for( Curve *c = upper.curve; c; c = c->next )
 	curve = new Curve( *c, value, curve );
 
-    lower.range[0] = upper.range[0];
-    lower.range[1] = value;
-    lower.range[2] = value - upper.range[0];
+    range[0] = upper.range[0];
+    range[1] = value;
+    range[2] = value - upper.range[0];
     upper.range[0] = value;
     upper.range[2] = upper.range[1] - value;
+    needsSubdivision = 0;
+    stepsize = 0;
 }
 
 Curvelist::~Curvelist()
diff --git a/src/glu/sgi/libnurbs/nurbtess/monoChain.cc b/src/glu/sgi/libnurbs/nurbtess/monoChain.cc
index b17b940..cb28129 100644
--- a/src/glu/sgi/libnurbs/nurbtess/monoChain.cc
+++ b/src/glu/sgi/libnurbs/nurbtess/monoChain.cc
@@ -264,6 +264,7 @@
 	  prevCusp = temp;	  
 	}
     }
+  assert(ret);
   ret->insert(new monoChain(prevCusp, firstCusp));
 
   return ret;
diff --git a/src/glu/sgi/libnurbs/nurbtess/primitiveStream.cc b/src/glu/sgi/libnurbs/nurbtess/primitiveStream.cc
index 26d0534..dfdbd4e 100644
--- a/src/glu/sgi/libnurbs/nurbtess/primitiveStream.cc
+++ b/src/glu/sgi/libnurbs/nurbtess/primitiveStream.cc
@@ -156,6 +156,8 @@
   index_vertices = 0;
   size_lengths = sizeLengths;
   size_vertices = sizeVertices; 
+
+  counter = 0; 
 }
 
 primStream::~primStream()
diff --git a/src/glut/glx/glut_cmap.c b/src/glut/glx/glut_cmap.c
index e8d9e1f..e6cb742 100644
--- a/src/glut/glx/glut_cmap.c
+++ b/src/glut/glx/glut_cmap.c
@@ -348,7 +348,7 @@
   Window *winlist;
   Colormap *cmaplist;
   Status status;
-  int maxcmaps, num;
+  int maxcmaps, num, i;
 
   assert(!window->parent);
   maxcmaps = MaxCmapsOfScreen(ScreenOfDisplay(__glutDisplay,
@@ -357,6 +357,9 @@
      and cmaplist, but we could. */
   winlist = (Window *) malloc(maxcmaps * sizeof(Window));
   cmaplist = (Colormap *) malloc(maxcmaps * sizeof(Colormap));
+  for (i = 0; i < maxcmaps; i++) {
+    cmaplist[i] = 0;
+  }
   num = findColormaps(window, winlist, cmaplist, 0, maxcmaps);
   if (num < 2) {
     /* Property no longer needed; remove it. */
diff --git a/src/glut/glx/glut_overlay.c b/src/glut/glx/glut_overlay.c
index db1abe0..3243465 100644
--- a/src/glut/glx/glut_overlay.c
+++ b/src/glut/glx/glut_overlay.c
@@ -388,6 +388,7 @@
   if (!overlay->vis) {
     __glutFatalError("lacks overlay support.");
   }
+  overlay->ctx = NULL;
 #if defined(GLX_VERSION_1_1) && defined(GLX_SGIX_fbconfig)
   if (fbc) {
     window->ctx = __glut_glXCreateContextWithConfigSGIX(__glutDisplay, fbc,
diff --git a/src/glx/dri2.c b/src/glx/dri2.c
index 91053d3..5de55cd 100644
--- a/src/glx/dri2.c
+++ b/src/glx/dri2.c
@@ -81,15 +81,13 @@
                                    dri2Info,
                                    dri2ExtensionName,
                                    &dri2ExtensionHooks,
-                                   1, NULL)
+                                   0, NULL)
 
 static Bool
 DRI2WireToEvent(Display *dpy, XEvent *event, xEvent *wire)
 {
    XExtDisplayInfo *info = DRI2FindDisplay(dpy);
    XExtDisplayInfo *glx_info = __glXFindDisplay(dpy);
-   static int glx_event_base;
-   static Bool found_glx_info = False;
 
    XextCheckExtension(dpy, info, dri2ExtensionName, False);
 
@@ -126,7 +124,15 @@
       return True;
    }
 #endif
+#ifdef DRI2_InvalidateBuffers
+   case DRI2_InvalidateBuffers:
+   {
+      xDRI2InvalidateBuffers *awire = (xDRI2InvalidateBuffers *)wire;
 
+      dri2InvalidateBuffers(dpy, awire->drawable);
+      return False;
+   }
+#endif
    default:
       /* client doesn't support server event */
       break;
@@ -174,6 +180,7 @@
    XExtDisplayInfo *info = DRI2FindDisplay(dpy);
    xDRI2QueryVersionReply rep;
    xDRI2QueryVersionReq *req;
+   int i, nevents;
 
    XextCheckExtension(dpy, info, dri2ExtensionName, False);
 
@@ -193,6 +200,24 @@
    UnlockDisplay(dpy);
    SyncHandle();
 
+   switch (rep.minorVersion) {
+   case 1:
+	   nevents = 0;
+	   break;
+   case 2:
+	   nevents = 1;
+	   break;
+   case 3:
+   default:
+	   nevents = 2;
+	   break;
+   }
+	
+   for (i = 0; i < nevents; i++) {
+       XESetWireToEvent (dpy, info->codes->first_event + i, DRI2WireToEvent);
+       XESetEventToWire (dpy, info->codes->first_event + i, DRI2EventToWire);
+   }
+
    return True;
 }
 
diff --git a/src/glx/dri2_glx.c b/src/glx/dri2_glx.c
index 15a3ea5..29d589c 100644
--- a/src/glx/dri2_glx.c
+++ b/src/glx/dri2_glx.c
@@ -67,6 +67,7 @@
    int driMinor;
    int driPatch;
    int swapAvailable;
+   int invalidateAvailable;
 };
 
 struct __GLXDRIcontextPrivateRec
@@ -310,12 +311,18 @@
    XFixesDestroyRegion(pdraw->psc->dpy, region);
 }
 
-
 static void
-dri2FlushFrontBuffer(__DRIdrawable * driDrawable, void *loaderPrivate)
+dri2FlushFrontBuffer(__DRIdrawable *driDrawable, void *loaderPrivate)
 {
-   (void) driDrawable;
-   dri2WaitGL((__GLXDRIdrawable *) loaderPrivate);
+   __GLXDRIdrawablePrivate *pdraw = loaderPrivate;
+   __GLXdisplayPrivate *priv = __glXInitialize(pdraw->base.psc->dpy);
+   __GLXDRIdisplayPrivate *pdp = (__GLXDRIdisplayPrivate *)priv->dri2Display;
+
+   /* Old servers don't send invalidate events */
+   if (!pdp->invalidateAvailable)
+       dri2InvalidateBuffers(priv->dpy, pdraw->base.xDrawable);
+
+   dri2WaitGL(loaderPrivate);
 }
 
 
@@ -375,6 +382,10 @@
     	(*pdraw->psc->f->flush)(pdraw->driDrawable);
 #endif
 
+    /* Old servers don't send invalidate events */
+    if (!pdp->invalidateAvailable)
+       dri2InvalidateBuffers(dpyPriv->dpy, pdraw->xDrawable);
+
     /* Old servers can't handle swapbuffers */
     if (!pdp->swapAvailable) {
        dri2CopySubBuffer(pdraw, 0, 0, priv->width, priv->height);
@@ -386,11 +397,6 @@
 		    remainder, &ret);
 #endif
 
-#if __DRI2_FLUSH_VERSION >= 2
-    if (pdraw->psc->f)
-       (*pdraw->psc->f->flushInvalidate)(pdraw->driDrawable);
-#endif
-
     return ret;
 }
 
@@ -485,6 +491,17 @@
    NULL
 };
 
+_X_HIDDEN void
+dri2InvalidateBuffers(Display *dpy, XID drawable)
+{
+   __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, NULL);
+
+#if __DRI2_FLUSH_VERSION >= 3
+   if (pdraw && pdraw->psc->f)
+       pdraw->psc->f->invalidate(pdraw->driDrawable);
+#endif
+}
+
 static __GLXDRIscreen *
 dri2CreateScreen(__GLXscreenConfigs * psc, int screen,
                  __GLXdisplayPrivate * priv)
@@ -651,11 +668,8 @@
    }
 
    pdp->driPatch = 0;
-   pdp->swapAvailable = 0;
-#ifdef X_DRI2SwapBuffers
-   if (pdp->driMinor >= 2)
-      pdp->swapAvailable = 1;
-#endif
+   pdp->swapAvailable = (pdp->driMinor >= 2);
+   pdp->invalidateAvailable = (pdp->driMinor >= 3);
 
    pdp->base.destroyDisplay = dri2DestroyDisplay;
    pdp->base.createScreen = dri2CreateScreen;
diff --git a/src/glx/dri_glx.c b/src/glx/dri_glx.c
index 0ff53c3..f9fe9a2 100644
--- a/src/glx/dri_glx.c
+++ b/src/glx/dri_glx.c
@@ -323,6 +323,7 @@
 
    framebuffer.base = MAP_FAILED;
    framebuffer.dev_priv = NULL;
+   framebuffer.size = 0;
 
    if (!XF86DRIOpenConnection(dpy, scrn, &hSAREA, &BusID)) {
       ErrorMessageF("XF86DRIOpenConnection failed\n");
diff --git a/src/glx/glx_pbuffer.c b/src/glx/glx_pbuffer.c
index a0a0223..4c122ba 100644
--- a/src/glx/glx_pbuffer.c
+++ b/src/glx/glx_pbuffer.c
@@ -186,10 +186,6 @@
 
 
 #ifdef GLX_DIRECT_RENDERING
-extern __GLXDRIdrawable *GetGLXDRIDrawable(Display * dpy,
-                                           GLXDrawable drawable,
-                                           int *const scrn_num);
-
 static GLenum
 determineTextureTarget(const int *attribs, int numAttribs)
 {
diff --git a/src/glx/glxclient.h b/src/glx/glxclient.h
index e0b286b..04ce781 100644
--- a/src/glx/glxclient.h
+++ b/src/glx/glxclient.h
@@ -182,6 +182,8 @@
 extern __GLXDRIdisplay *driswCreateDisplay(Display * dpy);
 extern __GLXDRIdisplay *driCreateDisplay(Display * dpy);
 extern __GLXDRIdisplay *dri2CreateDisplay(Display * dpy);
+extern void dri2InvalidateBuffers(Display *dpy, XID drawable);
+
 
 extern void DRI_glXUseXFont(Font font, int first, int count, int listbase);
 
@@ -798,6 +800,10 @@
 /* So that dri2.c:DRI2WireToEvent() can access
  * glx_info->codes->first_event */
 XExtDisplayInfo *__glXFindDisplay (Display *dpy);
+
+extern __GLXDRIdrawable *
+GetGLXDRIDrawable(Display *dpy, GLXDrawable drawable, int *const scrn_num);
+
 #endif
 
 #endif /* !__GLX_client_h__ */
diff --git a/src/glx/glxcmds.c b/src/glx/glxcmds.c
index 706d63b..704e9a0 100644
--- a/src/glx/glxcmds.c
+++ b/src/glx/glxcmds.c
@@ -110,10 +110,6 @@
    XSetErrorHandler(oldXErrorHandler);
 }
 
-extern __GLXDRIdrawable *GetGLXDRIDrawable(Display * dpy,
-                                           GLXDrawable drawable,
-                                           int *const scrn_num);
-
 /**
  * Get the __DRIdrawable for the drawable associated with a GLXContext
  *
diff --git a/src/mesa/SConscript b/src/mesa/SConscript
index ea5bad2..0726fcb 100644
--- a/src/mesa/SConscript
+++ b/src/mesa/SConscript
@@ -174,7 +174,6 @@
 		'state_tracker/st_cb_readpixels.c',
 		'state_tracker/st_cb_strings.c',
 		'state_tracker/st_cb_texture.c',
-		'state_tracker/st_cb_viewport.c',
 		'state_tracker/st_context.c',
 		'state_tracker/st_debug.c',
 		'state_tracker/st_draw.c',
diff --git a/src/mesa/drivers/common/driverfuncs.c b/src/mesa/drivers/common/driverfuncs.c
index 5c5e178..49d4aae 100644
--- a/src/mesa/drivers/common/driverfuncs.c
+++ b/src/mesa/drivers/common/driverfuncs.c
@@ -26,7 +26,6 @@
 #include "main/glheader.h"
 #include "main/imports.h"
 #include "main/arrayobj.h"
-#include "main/buffers.h"
 #include "main/context.h"
 #include "main/framebuffer.h"
 #include "main/mipmap.h"
@@ -50,7 +49,6 @@
 #endif
 
 #include "shader/program.h"
-#include "shader/prog_execute.h"
 #include "shader/shader_api.h"
 #include "tnl/tnl.h"
 #include "swrast/swrast.h"
diff --git a/src/mesa/drivers/common/meta.c b/src/mesa/drivers/common/meta.c
index e500359..7116d92 100644
--- a/src/mesa/drivers/common/meta.c
+++ b/src/mesa/drivers/common/meta.c
@@ -56,7 +56,6 @@
 #include "main/stencil.h"
 #include "main/texobj.h"
 #include "main/texenv.h"
-#include "main/texformat.h"
 #include "main/teximage.h"
 #include "main/texparam.h"
 #include "main/texstate.h"
diff --git a/src/mesa/drivers/dri/common/dri_metaops.c b/src/mesa/drivers/dri/common/dri_metaops.c
index c7bea07..dfb7d64 100644
--- a/src/mesa/drivers/dri/common/dri_metaops.c
+++ b/src/mesa/drivers/dri/common/dri_metaops.c
@@ -27,17 +27,9 @@
  **************************************************************************/
 
 #include "main/arrayobj.h"
-#include "main/attrib.h"
-#include "main/blend.h"
 #include "main/bufferobj.h"
-#include "main/buffers.h"
-#include "main/depth.h"
 #include "main/enable.h"
 #include "main/matrix.h"
-#include "main/macros.h"
-#include "main/polygon.h"
-#include "main/shaders.h"
-#include "main/stencil.h"
 #include "main/texstate.h"
 #include "main/varray.h"
 #include "main/viewport.h"
diff --git a/src/mesa/drivers/dri/common/dri_util.c b/src/mesa/drivers/dri/common/dri_util.c
index 3649c29..b891fca 100644
--- a/src/mesa/drivers/dri/common/dri_util.c
+++ b/src/mesa/drivers/dri/common/dri_util.c
@@ -454,7 +454,6 @@
 
     pdp->driScreenPriv = psp;
     pdp->driContextPriv = &psp->dummyContextPriv;
-    pdp->validBuffers = GL_FALSE;
 
     if (!(*psp->DriverAPI.CreateBuffer)(psp, pdp, &config->modes,
 					renderType == GLX_PIXMAP_BIT)) {
@@ -485,8 +484,11 @@
     if (!pdraw)
     	return NULL;
 
-    pdraw->pClipRects = _mesa_malloc(sizeof *pdraw->pBackClipRects);
-    pdraw->pBackClipRects = _mesa_malloc(sizeof *pdraw->pBackClipRects);
+    pdraw->pClipRects = &pdraw->dri2.clipRect;
+    pdraw->pBackClipRects = &pdraw->dri2.clipRect;
+
+    pdraw->pStamp = &pdraw->dri2.stamp;
+    *pdraw->pStamp = pdraw->lastStamp + 1;
 
     return pdraw;
 }
@@ -507,11 +509,11 @@
 
 	psp = pdp->driScreenPriv;
         (*psp->DriverAPI.DestroyBuffer)(pdp);
-	if (pdp->pClipRects) {
+	if (pdp->pClipRects && pdp->pClipRects != &pdp->dri2.clipRect) {
 	    _mesa_free(pdp->pClipRects);
 	    pdp->pClipRects = NULL;
 	}
-	if (pdp->pBackClipRects) {
+	if (pdp->pBackClipRects && pdp->pClipRects != &pdp->dri2.clipRect) {
 	    _mesa_free(pdp->pBackClipRects);
 	    pdp->pBackClipRects = NULL;
 	}
@@ -581,7 +583,8 @@
 
     pcp->driScreenPriv = psp;
     pcp->driDrawablePriv = NULL;
-
+    pcp->loaderPrivate = data;
+    
     /* When the first context is created for a screen, initialize a "dummy"
      * context.
      */
@@ -948,4 +951,10 @@
    return usage;
 }
 
+void
+dri2InvalidateDrawable(__DRIdrawable *drawable)
+{
+    drawable->dri2.stamp++;
+}
+
 /*@}*/
diff --git a/src/mesa/drivers/dri/common/dri_util.h b/src/mesa/drivers/dri/common/dri_util.h
index 95df702..8f0cd4c 100644
--- a/src/mesa/drivers/dri/common/dri_util.h
+++ b/src/mesa/drivers/dri/common/dri_util.h
@@ -295,7 +295,8 @@
     unsigned int index;
 
     /**
-     * Pointer to the "drawable has changed ID" stamp in the SAREA.
+     * Pointer to the "drawable has changed ID" stamp in the SAREA (or
+     * to dri2.stamp if DRI2 is being used).
      */
     unsigned int *pStamp;
 
@@ -377,7 +378,10 @@
      */
     unsigned int swap_interval;
 
-    GLboolean validBuffers;
+    struct {
+	unsigned int stamp;
+	drm_clip_rect_t clipRect;
+    } dri2;
 };
 
 /**
@@ -413,6 +417,11 @@
      * Pointer to screen on which this context was created.
      */
     __DRIscreen *driScreenPriv;
+
+    /**
+     * The loaders's private context data.  This structure is opaque.
+     */
+    void *loaderPrivate;
 };
 
 /**
@@ -550,4 +559,7 @@
 extern GLint
 driIntersectArea( drm_clip_rect_t rect1, drm_clip_rect_t rect2 );
 
+extern void
+dri2InvalidateDrawable(__DRIdrawable *drawable);
+
 #endif /* _DRI_UTIL_H_ */
diff --git a/src/mesa/drivers/dri/common/drirenderbuffer.c b/src/mesa/drivers/dri/common/drirenderbuffer.c
index 3126ea8..fe38f60 100644
--- a/src/mesa/drivers/dri/common/drirenderbuffer.c
+++ b/src/mesa/drivers/dri/common/drirenderbuffer.c
@@ -1,7 +1,6 @@
 
 #include "main/mtypes.h"
 #include "main/formats.h"
-#include "main/framebuffer.h"
 #include "main/renderbuffer.h"
 #include "main/imports.h"
 #include "drirenderbuffer.h"
diff --git a/src/mesa/drivers/dri/common/xmlconfig.c b/src/mesa/drivers/dri/common/xmlconfig.c
index 46ba2ff..477259e 100644
--- a/src/mesa/drivers/dri/common/xmlconfig.c
+++ b/src/mesa/drivers/dri/common/xmlconfig.c
@@ -39,13 +39,6 @@
 #include "dri_util.h"
 #include "xmlconfig.h"
 
-/*
- * OS dependent ways of getting the name of the running program
- */
-#if (defined(__unix__) || defined(unix)) && !defined(USG)
-#include <sys/param.h>
-#endif
-
 #undef GET_PROGRAM_NAME
 
 #if (defined(__GNU_LIBRARY__) || defined(__GLIBC__)) && !defined(__UCLIBC__)
diff --git a/src/mesa/drivers/dri/i965/brw_state_cache.c b/src/mesa/drivers/dri/i965/brw_state_cache.c
index 5fc47b0..1369d97 100644
--- a/src/mesa/drivers/dri/i965/brw_state_cache.c
+++ b/src/mesa/drivers/dri/i965/brw_state_cache.c
@@ -59,15 +59,7 @@
 #include "main/imports.h"
 #include "brw_state.h"
 #include "intel_batchbuffer.h"
-
-/* XXX: Fixme - have to include these to get the sizes of the prog_key
- * structs:
- */
 #include "brw_wm.h"
-#include "brw_vs.h"
-#include "brw_clip.h"
-#include "brw_sf.h"
-#include "brw_gs.h"
 
 
 static GLuint
diff --git a/src/mesa/drivers/dri/intel/intel_context.c b/src/mesa/drivers/dri/intel/intel_context.c
index e9315a5..81d5a32 100644
--- a/src/mesa/drivers/dri/intel/intel_context.c
+++ b/src/mesa/drivers/dri/intel/intel_context.c
@@ -195,7 +195,6 @@
    __DRIscreen *screen;
    int i, count;
    unsigned int attachments[10];
-   uint32_t name;
    const char *region_name;
 
    if (INTEL_DEBUG & DEBUG_DRI)
@@ -324,11 +323,8 @@
        if (rb == NULL)
 	  continue;
 
-       if (rb->region) {
-	  dri_bo_flink(rb->region->buffer, &name);
-	  if (name == buffers[i].name)
+       if (rb->region && rb->region->name == buffers[i].name)
 	     continue;
-       }
 
        if (INTEL_DEBUG & DEBUG_DRI)
 	  fprintf(stderr,
@@ -360,11 +356,8 @@
 	  if (rb != NULL) {
 	     struct intel_region *stencil_region = NULL;
 
-	     if (rb->region) {
-		dri_bo_flink(rb->region->buffer, &name);
-		if (name == buffers[i].name)
+	     if (rb->region && rb->region->name == buffers[i].name)
 		   continue;
-	     }
 
 	     intel_region_reference(&stencil_region, region);
 	     intel_renderbuffer_set_region(rb, stencil_region);
@@ -373,8 +366,8 @@
        }
    }
 
-   drawable->validBuffers = GL_TRUE;
    driUpdateFramebufferSize(&intel->ctx, drawable);
+   drawable->lastStamp = drawable->dri2.stamp;
 }
 
 void
diff --git a/src/mesa/drivers/dri/intel/intel_regions.c b/src/mesa/drivers/dri/intel/intel_regions.c
index e2859e4..881653ff 100644
--- a/src/mesa/drivers/dri/intel/intel_regions.c
+++ b/src/mesa/drivers/dri/intel/intel_regions.c
@@ -42,6 +42,7 @@
 #include <sys/ioctl.h>
 #include <errno.h>
 
+#include <main/hash.h>
 #include "intel_context.h"
 #include "intel_regions.h"
 #include "intel_blit.h"
@@ -228,10 +229,24 @@
 			      GLuint width, GLuint height, GLuint pitch,
 			      GLuint handle, const char *name)
 {
-   struct intel_region *region;
+   struct intel_region *region, *dummy;
    dri_bo *buffer;
    int ret;
 
+   region = _mesa_HashLookup(intel->intelScreen->named_regions, handle);
+   if (region != NULL) {
+      dummy = NULL;
+      if (region->width != width || region->height != height ||
+	  region->cpp != cpp || region->pitch != pitch) {
+	 fprintf(stderr,
+		 "Region for name %d already exists but is not compatible\n",
+		 handle);
+	 return NULL;
+      }
+      intel_region_reference(&dummy, region);
+      return dummy;
+   }
+
    buffer = intel_bo_gem_create_from_name(intel->bufmgr, name, handle);
 
    region = intel_region_alloc_internal(intel, cpp,
@@ -248,6 +263,10 @@
       return NULL;
    }
 
+   region->name = handle;
+   region->screen = intel->intelScreen;
+   _mesa_HashInsert(intel->intelScreen->named_regions, handle, region);
+
    return region;
 }
 
@@ -287,6 +306,9 @@
       region->pbo = NULL;
       dri_bo_unreference(region->buffer);
 
+      if (region->name > 0)
+	 _mesa_HashRemove(region->screen->named_regions, region->name);
+
       free(region);
    }
    *region_handle = NULL;
diff --git a/src/mesa/drivers/dri/intel/intel_regions.h b/src/mesa/drivers/dri/intel/intel_regions.h
index 860ae11..6d36f3d 100644
--- a/src/mesa/drivers/dri/intel/intel_regions.h
+++ b/src/mesa/drivers/dri/intel/intel_regions.h
@@ -67,6 +67,9 @@
    uint32_t tiling; /**< Which tiling mode the region is in */
    uint32_t bit_6_swizzle; /**< GEM flag for address swizzling requirement */
    struct intel_buffer_object *pbo;     /* zero-copy uploads */
+
+   uint32_t name; /**< Global name for the bo */
+   struct intel_screen *screen;
 };
 
 
diff --git a/src/mesa/drivers/dri/intel/intel_screen.c b/src/mesa/drivers/dri/intel/intel_screen.c
index 6dc20d0..8eed8ee 100644
--- a/src/mesa/drivers/dri/intel/intel_screen.c
+++ b/src/mesa/drivers/dri/intel/intel_screen.c
@@ -29,6 +29,7 @@
 #include "main/context.h"
 #include "main/framebuffer.h"
 #include "main/renderbuffer.h"
+#include "main/hash.h"
 
 #include "utils.h"
 #include "xmlpool.h"
@@ -122,22 +123,19 @@
 }
 
 static void
-intelDRI2FlushInvalidate(__DRIdrawable *drawable)
+intelDRI2Invalidate(__DRIdrawable *drawable)
 {
    struct intel_context *intel = drawable->driContextPriv->driverPrivate;
 
    intel->using_dri2_swapbuffers = GL_TRUE;
-
-   intelDRI2Flush(drawable);
-   drawable->validBuffers = GL_FALSE;
-
+   dri2InvalidateDrawable(drawable);
    intel_update_renderbuffers(intel->driContext, drawable);
 }
 
 static const struct __DRI2flushExtensionRec intelFlushExtension = {
     { __DRI2_FLUSH, __DRI2_FLUSH_VERSION },
     intelDRI2Flush,
-    intelDRI2FlushInvalidate,
+    intelDRI2Invalidate,
 };
 
 static const __DRIextension *intelScreenExtensions[] = {
@@ -167,6 +165,11 @@
 }
 
 static void
+nop_callback(GLuint key, void *data, void *userData)
+{
+}
+
+static void
 intelDestroyScreen(__DRIscreen * sPriv)
 {
    struct intel_screen *intelScreen = sPriv->private;
@@ -174,6 +177,12 @@
    dri_bufmgr_destroy(intelScreen->bufmgr);
    driDestroyOptionInfo(&intelScreen->optionCache);
 
+   /* Some regions may still have references to them at this point, so
+    * flush the hash table to prevent _mesa_DeleteHashTable() from
+    * complaining about the hash not being empty; */
+   _mesa_HashDeleteAll(intelScreen->named_regions, nop_callback, NULL);
+   _mesa_DeleteHashTable(intelScreen->named_regions);
+
    FREE(intelScreen);
    sPriv->private = NULL;
 }
@@ -324,6 +333,8 @@
    else
       intelScreen->kernel_exec_fencing = GL_FALSE;
 
+   intelScreen->named_regions = _mesa_NewHashTable();
+
    return GL_TRUE;
 }
 
diff --git a/src/mesa/drivers/dri/intel/intel_screen.h b/src/mesa/drivers/dri/intel/intel_screen.h
index c31b836..1ce476d 100644
--- a/src/mesa/drivers/dri/intel/intel_screen.h
+++ b/src/mesa/drivers/dri/intel/intel_screen.h
@@ -47,6 +47,7 @@
    GLboolean no_vbo;
    dri_bufmgr *bufmgr;
    GLboolean kernel_exec_fencing;
+   struct _mesa_HashTable *named_regions;
 
    /**
    * Configuration cache with default values for all contexts
diff --git a/src/mesa/drivers/dri/intel/intel_tex_image.c b/src/mesa/drivers/dri/intel/intel_tex_image.c
index d63292e..bc4e5c6 100644
--- a/src/mesa/drivers/dri/intel/intel_tex_image.c
+++ b/src/mesa/drivers/dri/intel/intel_tex_image.c
@@ -748,7 +748,7 @@
    if (!intelObj)
       return;
 
-   if (!dPriv->validBuffers)
+   if (dPriv->lastStamp != *dPriv->pStamp)
       intel_update_renderbuffers(pDRICtx, dPriv);
 
    rb = intel_get_renderbuffer(fb, BUFFER_FRONT_LEFT);
diff --git a/src/mesa/drivers/dri/nouveau/nouveau_bo_state.c b/src/mesa/drivers/dri/nouveau/nouveau_bo_state.c
index 664632f..fc5f77b 100644
--- a/src/mesa/drivers/dri/nouveau/nouveau_bo_state.c
+++ b/src/mesa/drivers/dri/nouveau/nouveau_bo_state.c
@@ -32,7 +32,6 @@
 		       uint32_t flags)
 {
 	struct nouveau_channel *chan = context_chan(ctx);
-	struct nouveau_pushbuf *push = chan->pushbuf;
 	uint32_t packet;
 
 	if (m->gr->bound == NOUVEAU_GROBJ_UNBOUND)
@@ -41,11 +40,10 @@
 	if (MARK_RING(chan, 2, 2))
 		return GL_FALSE;
 
-	push->remaining -= 2;
 	packet = (m->gr->subc << 13) | (1 << 18) | m->mthd;
 
 	if (flags) {
-		if (nouveau_pushbuf_emit_reloc(chan, push->cur++, m->bo,
+		if (nouveau_pushbuf_emit_reloc(chan, chan->cur++, m->bo,
 					       packet, 0, flags |
 					       (m->flags & (NOUVEAU_BO_VRAM |
 							    NOUVEAU_BO_GART |
@@ -53,10 +51,10 @@
 					       0, 0))
 			goto fail;
 	} else {
-		*(push->cur++) = packet;
+		*(chan->cur++) = packet;
 	}
 
-	if (nouveau_pushbuf_emit_reloc(chan, push->cur++, m->bo, m->data,
+	if (nouveau_pushbuf_emit_reloc(chan, chan->cur++, m->bo, m->data,
 				       m->data2, flags | m->flags,
 				       m->vor, m->tor))
 		goto fail;
diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.c b/src/mesa/drivers/dri/nouveau/nouveau_context.c
index b87b8db..6117f68 100644
--- a/src/mesa/drivers/dri/nouveau/nouveau_context.c
+++ b/src/mesa/drivers/dri/nouveau/nouveau_context.c
@@ -140,6 +140,8 @@
 	__DRIbuffer *buffers = NULL;
 	int i = 0, count, ret;
 
+	*stamp = *drawable->pStamp;
+
 	attachments[i++] = __DRI_BUFFER_FRONT_LEFT;
 	if (fb->Visual.doubleBufferMode)
 		attachments[i++] = __DRI_BUFFER_BACK_LEFT;
@@ -218,10 +220,11 @@
 		struct nouveau_context *nctx = dri_ctx->driverPrivate;
 		GLcontext *ctx = &nctx->base;
 
-		if (nctx->screen->context != nctx) {
-			nctx->screen->context = nctx;
-			BITSET_ONES(nctx->dirty);
-		}
+		if (nctx->screen->context == nctx)
+			return GL_TRUE;
+
+		nctx->screen->context = nctx;
+		BITSET_ONES(nctx->dirty);
 
 		/* Ask the X server for new renderbuffers. */
 		nouveau_update_renderbuffers(dri_ctx, dri_draw,
@@ -267,6 +270,28 @@
 nouveau_validate_framebuffer(GLcontext *ctx)
 {
 	struct nouveau_context *nctx = to_nouveau_context(ctx);
+	__DRIcontext *dri_ctx = to_nouveau_context(ctx)->dri_context;
+	__DRIdrawable *dri_draw = dri_ctx->driDrawablePriv;
+	__DRIdrawable *dri_read = dri_ctx->driReadablePriv;
+
+	if ((ctx->DrawBuffer->Name == 0 &&
+	     nctx->drawable.d_stamp != *dri_draw->pStamp) ||
+	    (dri_draw != dri_read &&
+	     ctx->ReadBuffer->Name == 0 &&
+	     nctx->drawable.r_stamp != *dri_read->pStamp)) {
+		if (nctx->drawable.dirty)
+			ctx->Driver.Flush(ctx);
+
+		/* Ask the X server for new renderbuffers. */
+		nouveau_update_renderbuffers(dri_ctx, dri_draw,
+					     &nctx->drawable.d_stamp);
+		if (dri_draw != dri_read)
+			nouveau_update_renderbuffers(dri_ctx, dri_read,
+						     &nctx->drawable.r_stamp);
+
+		if (nouveau_next_dirty_state(ctx) >= 0)
+			FIRE_RING(context_chan(ctx));
+	}
 
 	/* Someone's planning to draw something really soon. */
 	nctx->drawable.dirty = GL_TRUE;
diff --git a/src/mesa/drivers/dri/nouveau/nouveau_screen.c b/src/mesa/drivers/dri/nouveau/nouveau_screen.c
index 6abab8c..3f9f3a3 100644
--- a/src/mesa/drivers/dri/nouveau/nouveau_screen.c
+++ b/src/mesa/drivers/dri/nouveau/nouveau_screen.c
@@ -247,7 +247,19 @@
 		(struct gl_framebuffer **)&drawable->driverPrivate, NULL);
 }
 
+static void
+nouveau_drawable_flush(__DRIdrawable *draw)
+{
+}
+
+static const struct __DRI2flushExtensionRec nouveau_flush_extension = {
+    { __DRI2_FLUSH, __DRI2_FLUSH_VERSION },
+    nouveau_drawable_flush,
+    dri2InvalidateDrawable,
+};
+
 static const __DRIextension *nouveau_screen_extensions[] = {
+    &nouveau_flush_extension.base,
     NULL
 };
 
diff --git a/src/mesa/drivers/dri/nouveau/nouveau_swtnl_t.c b/src/mesa/drivers/dri/nouveau/nouveau_swtnl_t.c
index 8fa922f..a1609a0 100644
--- a/src/mesa/drivers/dri/nouveau/nouveau_swtnl_t.c
+++ b/src/mesa/drivers/dri/nouveau/nouveau_swtnl_t.c
@@ -210,7 +210,7 @@
 	swtnl_bind_vertices(ctx);
 
 	while (count) {
-		push = get_max_vertices(ctx, NULL, chan->pushbuf->remaining);
+		push = get_max_vertices(ctx, NULL, AVAIL_RING(chan));
 		push = MIN2(push / 12 * 12, count);
 		count -= push;
 
diff --git a/src/mesa/drivers/dri/nouveau/nouveau_vbo_t.c b/src/mesa/drivers/dri/nouveau/nouveau_vbo_t.c
index ba1192a..02c8580 100644
--- a/src/mesa/drivers/dri/nouveau/nouveau_vbo_t.c
+++ b/src/mesa/drivers/dri/nouveau/nouveau_vbo_t.c
@@ -319,7 +319,7 @@
 					  min_index, max_index);
 		}
 
-		if (count > get_max_vertices(ctx, ib, chan->pushbuf->remaining))
+		if (count > get_max_vertices(ctx, ib, AVAIL_RING(chan)))
 			WAIT_RING(chan, PUSHBUF_DWORDS);
 
 		BATCH_BEGIN(nvgl_primitive(prims[i].mode));
@@ -355,7 +355,7 @@
 			end = start + prims[i].count;
 
 		if (prims[i].count > get_max_vertices(ctx, ib,
-						      chan->pushbuf->remaining))
+						      AVAIL_RING(chan)))
 			WAIT_RING(chan, PUSHBUF_DWORDS);
 
 		BATCH_BEGIN(nvgl_primitive(prims[i].mode));
diff --git a/src/mesa/drivers/dri/r300/r300_draw.c b/src/mesa/drivers/dri/r300/r300_draw.c
index 4ae0d6f..3efa0e3 100644
--- a/src/mesa/drivers/dri/r300/r300_draw.c
+++ b/src/mesa/drivers/dri/r300/r300_draw.c
@@ -332,7 +332,7 @@
 {
 	r300ContextPtr r300 = R300_CONTEXT(ctx);
 	struct r300_vertex_buffer *vbuf = &r300->vbuf;
-	struct vertex_attribute r300_attr;
+	struct vertex_attribute r300_attr = { 0 };
 	GLenum type;
 	GLuint stride;
 
diff --git a/src/mesa/drivers/dri/r300/r300_vertprog.c b/src/mesa/drivers/dri/r300/r300_vertprog.c
index e6fa57d..3a8d5fb 100644
--- a/src/mesa/drivers/dri/r300/r300_vertprog.c
+++ b/src/mesa/drivers/dri/r300/r300_vertprog.c
@@ -234,7 +234,7 @@
 	struct r300_vertex_program_compiler compiler;
 
 	vp = _mesa_calloc(sizeof(*vp));
-	vp->Base = (struct gl_vertex_program *) _mesa_clone_program(ctx, &mesa_vp->Base);
+	vp->Base = _mesa_clone_vertex_program(ctx, mesa_vp);
 	_mesa_memcpy(&vp->key, wanted_key, sizeof(vp->key));
 
 	rc_init(&compiler.Base);
diff --git a/src/mesa/drivers/dri/r600/r700_assembler.c b/src/mesa/drivers/dri/r600/r700_assembler.c
index 89adb77..d0059fa 100644
--- a/src/mesa/drivers/dri/r600/r700_assembler.c
+++ b/src/mesa/drivers/dri/r600/r700_assembler.c
@@ -830,6 +830,8 @@
 	if(GL_TRUE == pFetchMethod->bEnableMini) //More conditions here
 	{
 		//TODO : mini fetch
+		mega_fetch_count = 0;
+		is_mega_fetch_flag = 0;
 	}
 	else
 	{
@@ -922,6 +924,8 @@
 	if(GL_TRUE == pFetchMethod->bEnableMini) //More conditions here
 	{
 		//TODO : mini fetch
+		mega_fetch_count = 0;
+		is_mega_fetch_flag = 0;
 	}
 	else
 	{
@@ -2260,7 +2264,7 @@
 
 GLboolean assemble_alu_instruction(r700_AssemblerBase *pAsm)
 {
-    R700ALUInstruction            * alu_instruction_ptr;
+    R700ALUInstruction            * alu_instruction_ptr = NULL;
     R700ALUInstructionHalfLiteral * alu_instruction_ptr_hl;
     R700ALUInstructionFullLiteral * alu_instruction_ptr_fl;
 
diff --git a/src/mesa/drivers/dri/r600/r700_chip.c b/src/mesa/drivers/dri/r600/r700_chip.c
index e0be749..a742dbc 100644
--- a/src/mesa/drivers/dri/r600/r700_chip.c
+++ b/src/mesa/drivers/dri/r600/r700_chip.c
@@ -200,7 +200,8 @@
     }
     else
     {
-        nVBsize = paos->count * pStreamDesc->stride;
+        nVBsize = (paos->count - 1) * pStreamDesc->stride
+                  + pStreamDesc->size * getTypeSize(pStreamDesc->type);
     }
 
     uSQ_VTX_CONSTANT_WORD0_0 = paos->offset;
@@ -218,11 +219,11 @@
         SETfield(uSQ_VTX_CONSTANT_WORD2_0, SQ_NUM_FORMAT_NORM,
 	             SQ_VTX_CONSTANT_WORD2_0__NUM_FORMAT_ALL_shift, SQ_VTX_CONSTANT_WORD2_0__NUM_FORMAT_ALL_mask);
     }
-    //else
-    //{
-    //    SETfield(uSQ_VTX_CONSTANT_WORD2_0, SQ_NUM_FORMAT_INT,
-	//             SQ_VTX_CONSTANT_WORD2_0__NUM_FORMAT_ALL_shift, SQ_VTX_CONSTANT_WORD2_0__NUM_FORMAT_ALL_mask);
-    //}
+    else
+    {
+        SETfield(uSQ_VTX_CONSTANT_WORD2_0, SQ_NUM_FORMAT_SCALED,
+	             SQ_VTX_CONSTANT_WORD2_0__NUM_FORMAT_ALL_shift, SQ_VTX_CONSTANT_WORD2_0__NUM_FORMAT_ALL_mask);
+    }
 
     if(1 == pStreamDesc->_signed)
     {
diff --git a/src/mesa/drivers/dri/r600/r700_vertprog.c b/src/mesa/drivers/dri/r600/r700_vertprog.c
index 618f7e1..46481cd 100644
--- a/src/mesa/drivers/dri/r600/r700_vertprog.c
+++ b/src/mesa/drivers/dri/r600/r700_vertprog.c
@@ -308,7 +308,7 @@
 	unsigned int i;
 
 	vp = _mesa_calloc(sizeof(*vp));
-	vp->mesa_program = (struct gl_vertex_program *)_mesa_clone_program(ctx, &mesa_vp->Base);
+	vp->mesa_program = _mesa_clone_vertex_program(ctx, mesa_vp);
 
 	if (mesa_vp->IsPositionInvariant)
 	{
diff --git a/src/mesa/main/clear.c b/src/mesa/main/clear.c
index 4a3c111..8085bed 100644
--- a/src/mesa/main/clear.c
+++ b/src/mesa/main/clear.c
@@ -236,7 +236,7 @@
          mask |= BUFFER_BIT_BACK_RIGHT;
       break;
    default:
-      if (drawbuffer < 0 || drawbuffer >= ctx->Const.MaxDrawBuffers) {
+      if (drawbuffer < 0 || drawbuffer >= (GLint)ctx->Const.MaxDrawBuffers) {
          mask = INVALID_MASK;
       }
       else if (att[BUFFER_COLOR0 + drawbuffer].Renderbuffer) {
@@ -306,11 +306,11 @@
              * floating point state var.  This will not always work.  We'll
              * need a new ctx->Driver.ClearBuffer() hook....
              */
-            GLfloat clearSave[4];
+            GLclampf clearSave[4];
             /* save color */
             COPY_4V(clearSave, ctx->Color.ClearColor);
             /* set color */
-            COPY_4V(ctx->Color.ClearColor, value);
+            COPY_4V_CAST(ctx->Color.ClearColor, value, GLclampf);
             if (ctx->Driver.ClearColor)
                ctx->Driver.ClearColor(ctx, ctx->Color.ClearColor);
             /* clear buffer(s) */
@@ -365,11 +365,11 @@
              * floating point state var.  This will not always work.  We'll
              * need a new ctx->Driver.ClearBuffer() hook....
              */
-            GLfloat clearSave[4];
+            GLclampf clearSave[4];
             /* save color */
             COPY_4V(clearSave, ctx->Color.ClearColor);
             /* set color */
-            COPY_4V(ctx->Color.ClearColor, value);
+            COPY_4V_CAST(ctx->Color.ClearColor, value, GLclampf);
             if (ctx->Driver.ClearColor)
                ctx->Driver.ClearColor(ctx, ctx->Color.ClearColor);
             /* clear buffer(s) */
@@ -423,7 +423,7 @@
           * XXX in the future we may have a new ctx->Driver.ClearBuffer()
           * hook instead.
           */
-         const GLfloat clearSave = ctx->Depth.Clear;
+         const GLclampd clearSave = ctx->Depth.Clear;
          ctx->Depth.Clear = *value;
          if (ctx->Driver.ClearDepth)
             ctx->Driver.ClearDepth(ctx, *value);
@@ -443,11 +443,11 @@
             return;
          }
          else if (mask) {
-            GLfloat clearSave[4];
+            GLclampf clearSave[4];
             /* save color */
             COPY_4V(clearSave, ctx->Color.ClearColor);
             /* set color */
-            COPY_4V(ctx->Color.ClearColor, value);
+            COPY_4V_CAST(ctx->Color.ClearColor, value, GLclampf);
             if (ctx->Driver.ClearColor)
                ctx->Driver.ClearColor(ctx, ctx->Color.ClearColor);
             /* clear buffer(s) */
@@ -503,7 +503,7 @@
 
    {
       /* save current clear values */
-      const GLfloat clearDepthSave = ctx->Depth.Clear;
+      const GLclampd clearDepthSave = ctx->Depth.Clear;
       const GLuint clearStencilSave = ctx->Stencil.Clear;
 
       /* set new clear values */
diff --git a/src/mesa/main/extensions.c b/src/mesa/main/extensions.c
index e132022..87c1fac 100644
--- a/src/mesa/main/extensions.c
+++ b/src/mesa/main/extensions.c
@@ -50,8 +50,7 @@
    { OFF, "GL_ARB_depth_clamp",                F(ARB_depth_clamp) },
    { ON,  "GL_ARB_draw_buffers",               F(ARB_draw_buffers) },
    { OFF, "GL_ARB_draw_elements_base_vertex",  F(ARB_draw_elements_base_vertex) },
-   /* TODO: uncomment the following line once GLSL layout(...) support is implemented */
-   /* { OFF, "GL_ARB_fragment_coord_conventions", F(ARB_fragment_coord_conventions) }, */
+   { OFF, "GL_ARB_fragment_coord_conventions", F(ARB_fragment_coord_conventions) },
    { OFF, "GL_ARB_fragment_program",           F(ARB_fragment_program) },
    { OFF, "GL_ARB_fragment_program_shadow",    F(ARB_fragment_program_shadow) },
    { OFF, "GL_ARB_fragment_shader",            F(ARB_fragment_shader) },
@@ -133,6 +132,7 @@
    { ON,  "GL_EXT_texture",                    F(EXT_texture) },
    { ON,  "GL_EXT_texture3D",                  F(EXT_texture3D) },
    { OFF, "GL_EXT_texture_compression_s3tc",   F(EXT_texture_compression_s3tc) },
+   { OFF, "GL_EXT_texture_cube_map",           F(ARB_texture_cube_map) },
    { ON,  "GL_EXT_texture_edge_clamp",         F(SGIS_texture_edge_clamp) },
    { OFF, "GL_EXT_texture_env_add",            F(EXT_texture_env_add) },
    { OFF, "GL_EXT_texture_env_combine",        F(EXT_texture_env_combine) },
@@ -211,6 +211,7 @@
    ctx->Extensions.ARB_depth_texture = GL_TRUE;
    /*ctx->Extensions.ARB_draw_buffers = GL_TRUE;*/
    ctx->Extensions.ARB_draw_elements_base_vertex = GL_TRUE;
+   ctx->Extensions.ARB_fragment_coord_conventions = GL_TRUE;
 #if FEATURE_ARB_fragment_program
    ctx->Extensions.ARB_fragment_program = GL_TRUE;
    ctx->Extensions.ARB_fragment_program_shadow = GL_TRUE;
diff --git a/src/mesa/main/get.c b/src/mesa/main/get.c
index 2724774..60fef55 100644
--- a/src/mesa/main/get.c
+++ b/src/mesa/main/get.c
@@ -7,7 +7,6 @@
 #include "context.h"
 #include "enable.h"
 #include "extensions.h"
-#include "fbobject.h"
 #include "get.h"
 #include "macros.h"
 #include "mtypes.h"
diff --git a/src/mesa/main/get_gen.py b/src/mesa/main/get_gen.py
index 9ae3ce0..64aa2ac 100644
--- a/src/mesa/main/get_gen.py
+++ b/src/mesa/main/get_gen.py
@@ -27,6 +27,7 @@
 
 
 import string
+import sys
 
 
 GLint = 1
@@ -1134,7 +1135,7 @@
 		elif returnType == GLint64:
 			function = "GetInteger64v"
 		else:
-			abort()
+			sys.exit(1)
 
 	if returnType == GLint64:
 		print "#if FEATURE_ARB_sync"
@@ -1225,7 +1226,6 @@
 #include "context.h"
 #include "enable.h"
 #include "extensions.h"
-#include "fbobject.h"
 #include "get.h"
 #include "macros.h"
 #include "mtypes.h"
diff --git a/src/mesa/main/hash.c b/src/mesa/main/hash.c
index 08c6456..fdfbe6b 100644
--- a/src/mesa/main/hash.c
+++ b/src/mesa/main/hash.c
@@ -128,7 +128,7 @@
  * \return pointer to user's data or NULL if key not in table
  */
 void *
-_mesa_HashLookup(const struct _mesa_HashTable *table, GLuint key)
+_mesa_HashLookup(struct _mesa_HashTable *table, GLuint key)
 {
    GLuint pos;
    const struct HashEntry *entry;
@@ -137,13 +137,16 @@
    assert(key);
 
    pos = HASH_FUNC(key);
+   _glthread_LOCK_MUTEX(table->Mutex);
    entry = table->Table[pos];
    while (entry) {
       if (entry->Key == key) {
-	 return entry->Data;
+         _glthread_UNLOCK_MUTEX(table->Mutex);
+         return entry->Data;
       }
       entry = entry->Next;
    }
+   _glthread_UNLOCK_MUTEX(table->Mutex);
    return NULL;
 }
 
@@ -191,10 +194,12 @@
 
    /* alloc and insert new table entry */
    entry = MALLOC_STRUCT(HashEntry);
-   entry->Key = key;
-   entry->Data = data;
-   entry->Next = table->Table[pos];
-   table->Table[pos] = entry;
+   if (entry) {
+      entry->Key = key;
+      entry->Data = data;
+      entry->Next = table->Table[pos];
+      table->Table[pos] = entry;
+   }
 
    _glthread_UNLOCK_MUTEX(table->Mutex);
 }
diff --git a/src/mesa/main/hash.h b/src/mesa/main/hash.h
index d18db76..4f916f9 100644
--- a/src/mesa/main/hash.h
+++ b/src/mesa/main/hash.h
@@ -39,7 +39,7 @@
 
 extern void _mesa_DeleteHashTable(struct _mesa_HashTable *table);
 
-extern void *_mesa_HashLookup(const struct _mesa_HashTable *table, GLuint key);
+extern void *_mesa_HashLookup(struct _mesa_HashTable *table, GLuint key);
 
 extern void _mesa_HashInsert(struct _mesa_HashTable *table, GLuint key, void *data);
 
diff --git a/src/mesa/main/image.c b/src/mesa/main/image.c
index 81993e7..468f2a9 100644
--- a/src/mesa/main/image.c
+++ b/src/mesa/main/image.c
@@ -5662,7 +5662,7 @@
       /* chop off [t, 1] part */
       ASSERT(t >= 0.0 && t <= 1.0);
       *dstX1 = maxValue;
-      bias = (*srcX0 < *srcX1) ? 0.5 : -0.5;
+      bias = (*srcX0 < *srcX1) ? 0.5F : -0.5F;
       *srcX1 = *srcX0 + (GLint) (t * (*srcX1 - *srcX0) + bias);
    }
    else if (*dstX0 > maxValue) {
@@ -5672,7 +5672,7 @@
       /* chop off [t, 1] part */
       ASSERT(t >= 0.0 && t <= 1.0);
       *dstX0 = maxValue;
-      bias = (*srcX0 < *srcX1) ? -0.5 : 0.5;
+      bias = (*srcX0 < *srcX1) ? -0.5F : 0.5F;
       *srcX0 = *srcX1 + (GLint) (t * (*srcX0 - *srcX1) + bias);
    }
 }
@@ -5695,7 +5695,7 @@
       /* chop off [0, t] part */
       ASSERT(t >= 0.0 && t <= 1.0);
       *dstX0 = minValue;
-      bias = (*srcX0 < *srcX1) ? 0.5 : -0.5; /* flipped??? */
+      bias = (*srcX0 < *srcX1) ? 0.5F : -0.5F; /* flipped??? */
       *srcX0 = *srcX0 + (GLint) (t * (*srcX1 - *srcX0) + bias);
    }
    else if (*dstX1 < minValue) {
@@ -5705,7 +5705,7 @@
       /* chop off [0, t] part */
       ASSERT(t >= 0.0 && t <= 1.0);
       *dstX1 = minValue;
-      bias = (*srcX0 < *srcX1) ? 0.5 : -0.5;
+      bias = (*srcX0 < *srcX1) ? 0.5F : -0.5F;
       *srcX1 = *srcX1 + (GLint) (t * (*srcX0 - *srcX1) + bias);
    }
 }
diff --git a/src/mesa/main/imports.h b/src/mesa/main/imports.h
index 3843f50..e3d2ac9 100644
--- a/src/mesa/main/imports.h
+++ b/src/mesa/main/imports.h
@@ -412,13 +412,19 @@
  * Source for the fallback implementation is
  * Sean Eron Anderson's webpage "Bit Twiddling Hacks"
  * http://graphics.stanford.edu/~seander/bithacks.html
+ *
+ * When using builtin function have to do some work
+ * for case when passed values 1 to prevent hiting
+ * undefined result from __builtin_clz. Undefined
+ * results would be different depending on optimization
+ * level used for build.
  */
 static INLINE int32_t
 _mesa_next_pow_two_32(uint32_t x)
 {
 #ifdef __GNUC__
-	x--;
-	return 1 << ((__builtin_clz(x) ^ 31) + 1);
+	uint32_t y = (x != 1);
+	return (1 + y) << ((__builtin_clz(x - y) ^ 31) );
 #else
 	x--;
 	x |= x >> 1;
@@ -435,11 +441,11 @@
 _mesa_next_pow_two_64(uint64_t x)
 {
 #ifdef __GNUC__
-	x--;
+	uint64_t y = (x != 1);
 	if (sizeof(x) == sizeof(long))
-		return 1 << ((__builtin_clzl(x) ^ 63) + 1);
+		return (1 + y) << ((__builtin_clzl(x - y) ^ 63));
 	else
-		return 1 << ((__builtin_clzll(x) ^ 63) + 1);
+		return (1 + y) << ((__builtin_clzll(x - y) ^ 63));
 #else
 	x--;
 	x |= x >> 1;
diff --git a/src/mesa/main/macros.h b/src/mesa/main/macros.h
index 55578ad..38a97fd 100644
--- a/src/mesa/main/macros.h
+++ b/src/mesa/main/macros.h
@@ -83,14 +83,14 @@
 
 
 /** Convert GLuint in [0,4294967295] to GLfloat in [0.0,1.0] */
-#define UINT_TO_FLOAT(U)    ((GLfloat) (U) * (1.0F / 4294967295.0))
+#define UINT_TO_FLOAT(U)    ((GLfloat) ((U) * (1.0F / 4294967295.0)))
 
 /** Convert GLfloat in [0.0,1.0] to GLuint in [0,4294967295] */
 #define FLOAT_TO_UINT(X)    ((GLuint) ((X) * 4294967295.0))
 
 
 /** Convert GLint in [-2147483648,2147483647] to GLfloat in [-1.0,1.0] */
-#define INT_TO_FLOAT(I)     ((2.0F * (I) + 1.0F) * (1.0F/4294967294.0))
+#define INT_TO_FLOAT(I)     ((GLfloat) ((2.0F * (I) + 1.0F) * (1.0F/4294967294.0)))
 
 /** Convert GLfloat in [-1.0,1.0] to GLint in [-2147483648,2147483647] */
 /* causes overflow:
diff --git a/src/mesa/main/texgetimage.c b/src/mesa/main/texgetimage.c
index 66d01c1..6b3355a 100644
--- a/src/mesa/main/texgetimage.c
+++ b/src/mesa/main/texgetimage.c
@@ -590,7 +590,7 @@
 {
    struct gl_texture_object *texObj;
    struct gl_texture_image *texImage;
-   const GLuint maxLevels = _mesa_max_texture_levels(ctx, target);
+   const GLint maxLevels = _mesa_max_texture_levels(ctx, target);
    GLenum baseFormat;
 
    if (maxLevels == 0) {
@@ -776,7 +776,7 @@
 {
    struct gl_texture_object *texObj;
    struct gl_texture_image *texImage;
-   const GLuint maxLevels = _mesa_max_texture_levels(ctx, target);
+   const GLint maxLevels = _mesa_max_texture_levels(ctx, target);
 
    if (maxLevels == 0) {
       _mesa_error(ctx, GL_INVALID_ENUM, "glGetCompressedTexImage(target=0x%x)",
diff --git a/src/mesa/main/texstore.c b/src/mesa/main/texstore.c
index fcd0a56..78612b0 100644
--- a/src/mesa/main/texstore.c
+++ b/src/mesa/main/texstore.c
@@ -2678,7 +2678,7 @@
 static GLboolean
 _mesa_texstore_z24_s8(TEXSTORE_PARAMS)
 {
-   const GLfloat depthScale = (GLfloat) 0xffffff;
+   const GLuint depthScale = 0xffffff;
    const GLint srcRowStride
       = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType)
       / sizeof(GLuint);
@@ -2752,7 +2752,7 @@
             _mesa_unpack_depth_span(ctx, srcWidth,
                                     GL_UNSIGNED_INT_24_8_EXT, /* dst type */
                                     dstRow, /* dst addr */
-                                    (GLuint) depthScale,
+                                    depthScale,
                                     srcType, src, srcPacking);
             /* get the 8-bit stencil values */
             _mesa_unpack_stencil_span(ctx, srcWidth,
diff --git a/src/mesa/shader/nvprogram.c b/src/mesa/shader/nvprogram.c
index 87f295e..c3b10f5 100644
--- a/src/mesa/shader/nvprogram.c
+++ b/src/mesa/shader/nvprogram.c
@@ -570,15 +570,15 @@
 					inst->DstReg.Index + 1);
       }
       if (inst->SrcReg[0].File == PROGRAM_TEMPORARY) {
-	 program->NumTemporaries = MAX2(program->NumTemporaries,
+	 program->NumTemporaries = MAX2((GLint)program->NumTemporaries,
 					inst->SrcReg[0].Index + 1);
       }
       if (inst->SrcReg[1].File == PROGRAM_TEMPORARY) {
-	 program->NumTemporaries = MAX2(program->NumTemporaries,
+	 program->NumTemporaries = MAX2((GLint)program->NumTemporaries,
 					inst->SrcReg[1].Index + 1);
       }
       if (inst->SrcReg[2].File == PROGRAM_TEMPORARY) {
-	 program->NumTemporaries = MAX2(program->NumTemporaries,
+	 program->NumTemporaries = MAX2((GLint)program->NumTemporaries,
 					inst->SrcReg[2].Index + 1);
       }
    }
diff --git a/src/mesa/shader/prog_execute.c b/src/mesa/shader/prog_execute.c
index 7781cb3..ee422e7 100644
--- a/src/mesa/shader/prog_execute.c
+++ b/src/mesa/shader/prog_execute.c
@@ -599,13 +599,13 @@
 
    if (inst->CondUpdate) {
       if (writeMask & WRITEMASK_X)
-         machine->CondCodes[0] = generate_cc(value[0]);
+         machine->CondCodes[0] = generate_cc((float)value[0]);
       if (writeMask & WRITEMASK_Y)
-         machine->CondCodes[1] = generate_cc(value[1]);
+         machine->CondCodes[1] = generate_cc((float)value[1]);
       if (writeMask & WRITEMASK_Z)
-         machine->CondCodes[2] = generate_cc(value[2]);
+         machine->CondCodes[2] = generate_cc((float)value[2]);
       if (writeMask & WRITEMASK_W)
-         machine->CondCodes[3] = generate_cc(value[3]);
+         machine->CondCodes[3] = generate_cc((float)value[3]);
 #if DEBUG_PROG
       printf("CondCodes=(%s,%s,%s,%s) for:\n",
              _mesa_condcode_string(machine->CondCodes[0]),
@@ -1000,7 +1000,7 @@
                val = -FLT_MAX;
             }
             else {
-               val = log(a[0]) * 1.442695F;
+               val = (float)(log(a[0]) * 1.442695F);
             }
             result[0] = result[1] = result[2] = result[3] = val;
             store_vector4(inst, machine, result);
@@ -1065,7 +1065,7 @@
 		  /* The fast LOG2 macro doesn't meet the precision
 		   * requirements.
 		   */
-                  q[2] = (log(t[0]) * 1.442695F);
+                  q[2] = (float)(log(t[0]) * 1.442695F);
                }
             }
             else {
@@ -1780,15 +1780,10 @@
          break;
       case OPCODE_PRINT:
          {
-            if (inst->SrcReg[0].File != -1) {
-               GLfloat a[4];
-               fetch_vector4(&inst->SrcReg[0], machine, a);
-               _mesa_printf("%s%g, %g, %g, %g\n", (const char *) inst->Data,
-                            a[0], a[1], a[2], a[3]);
-            }
-            else {
-               _mesa_printf("%s\n", (const char *) inst->Data);
-            }
+            GLfloat a[4];
+            fetch_vector4(&inst->SrcReg[0], machine, a);
+            _mesa_printf("%s%g, %g, %g, %g\n", (const char *) inst->Data,
+                         a[0], a[1], a[2], a[3]);
          }
          break;
       case OPCODE_END:
diff --git a/src/mesa/shader/prog_parameter.c b/src/mesa/shader/prog_parameter.c
index 5822510..d4970c4 100644
--- a/src/mesa/shader/prog_parameter.c
+++ b/src/mesa/shader/prog_parameter.c
@@ -209,7 +209,7 @@
 {
    /* first check if this is a duplicate constant */
    GLint pos;
-   for (pos = 0; pos < paramList->NumParameters; pos++) {
+   for (pos = 0; pos < (GLint)paramList->NumParameters; pos++) {
       const GLfloat *pvals = paramList->ParameterValues[pos];
       if (pvals[0] == values[0] &&
           pvals[1] == values[1] &&
diff --git a/src/mesa/shader/program.c b/src/mesa/shader/program.c
index aaf5f96..18ef6d5 100644
--- a/src/mesa/shader/program.c
+++ b/src/mesa/shader/program.c
@@ -505,6 +505,8 @@
          struct gl_fragment_program *fpc = (struct gl_fragment_program *) clone;
          fpc->FogOption = fp->FogOption;
          fpc->UsesKill = fp->UsesKill;
+         fpc->OriginUpperLeft = fp->OriginUpperLeft;
+         fpc->PixelCenterInteger = fp->PixelCenterInteger;
       }
       break;
    default:
diff --git a/src/mesa/shader/program.h b/src/mesa/shader/program.h
index 0187a2c..af9f417 100644
--- a/src/mesa/shader/program.h
+++ b/src/mesa/shader/program.h
@@ -108,6 +108,22 @@
 extern struct gl_program *
 _mesa_clone_program(GLcontext *ctx, const struct gl_program *prog);
 
+static INLINE struct gl_vertex_program *
+_mesa_clone_vertex_program(GLcontext *ctx,
+                           const struct gl_vertex_program *prog)
+{
+   return (struct gl_vertex_program *) _mesa_clone_program(ctx, &prog->Base);
+}
+
+
+static INLINE struct gl_fragment_program *
+_mesa_clone_fragment_program(GLcontext *ctx,
+                             const struct gl_fragment_program *prog)
+{
+   return (struct gl_fragment_program *) _mesa_clone_program(ctx, &prog->Base);
+}
+
+
 extern  GLboolean
 _mesa_insert_instructions(struct gl_program *prog, GLuint start, GLuint count);
 
diff --git a/src/mesa/shader/slang/slang_codegen.c b/src/mesa/shader/slang/slang_codegen.c
index 83098b7..fe4bddf 100644
--- a/src/mesa/shader/slang/slang_codegen.c
+++ b/src/mesa/shader/slang/slang_codegen.c
@@ -3117,7 +3117,7 @@
    if (start >= end)
       return GL_FALSE; /* degenerate case */
 
-   if (end - start > MAX_FOR_LOOP_UNROLL_ITERATIONS) {
+   if ((GLuint)(end - start) > MAX_FOR_LOOP_UNROLL_ITERATIONS) {
       slang_info_log_print(A->log,
                            "Note: 'for (%s=%d; %s<%d; ++%s)' is too"
                            " many iterations to unroll",
diff --git a/src/mesa/shader/slang/slang_compile.c b/src/mesa/shader/slang/slang_compile.c
index 8522741..33964e0 100644
--- a/src/mesa/shader/slang/slang_compile.c
+++ b/src/mesa/shader/slang/slang_compile.c
@@ -239,7 +239,7 @@
    }
 
    parse_identifier_str(ctx, &flt);
-   flt = strdup(flt);
+   flt = _mesa_strdup(flt);
    if (!flt) {
       return 0;
    }
@@ -636,6 +636,38 @@
 }
 
 
+/* Layout qualifiers */
+#define LAYOUT_QUALIFIER_NONE                      0
+#define LAYOUT_QUALIFIER_UPPER_LEFT                1
+#define LAYOUT_QUALIFIER_PIXEL_CENTER_INTEGER      2
+
+static int
+parse_layout_qualifiers(slang_parse_ctx * C, slang_layout_qualifier *layout)
+{
+   *layout = 0x0;
+
+   /* the layout qualifiers come as a list of LAYOUT_QUALIFER_x tokens,
+    * terminated by LAYOUT_QUALIFIER_NONE.
+    */
+   while (1) {
+      GLuint c = *C->I++;
+      switch (c) {
+      case LAYOUT_QUALIFIER_NONE:
+         /* end of list of qualifiers */
+         return 1;
+      case LAYOUT_QUALIFIER_UPPER_LEFT:
+         *layout |= SLANG_LAYOUT_UPPER_LEFT_BIT;
+         break;
+      case LAYOUT_QUALIFIER_PIXEL_CENTER_INTEGER:
+         *layout |= SLANG_LAYOUT_PIXEL_CENTER_INTEGER_BIT;
+         break;
+      default:
+         assert(0 && "Bad layout qualifier");
+      }
+   }
+}
+
+
 /* type qualifier */
 #define TYPE_QUALIFIER_NONE 0
 #define TYPE_QUALIFIER_CONST 1
@@ -907,9 +939,12 @@
 parse_fully_specified_type(slang_parse_ctx * C, slang_output_ctx * O,
                            slang_fully_specified_type * type)
 {
+   if (!parse_layout_qualifiers(C, &type->layout))
+      RETURN0;
+
    if (!parse_type_variant(C, &type->variant))
       RETURN0;
-  
+
    if (!parse_type_centroid(C, &type->centroid))
       RETURN0;
 
@@ -2029,6 +2064,30 @@
 
 
 /**
+ * Check if it's OK to re-declare a variable with the given new type.
+ * This happens when applying layout qualifiers to gl_FragCoord or
+ * (re)setting an array size.
+ * If redeclaration is OK, return a pointer to the incoming variable
+ * updated with new type info.  Else return NULL;
+ */
+static slang_variable *
+redeclare_variable(slang_variable *var, 
+                   const slang_fully_specified_type *type)
+{
+   if (slang_fully_specified_types_compatible(&var->type, type)) {
+      /* replace orig var layout with new layout */
+      var->type.layout = type->layout;
+
+      /* XXX there may be other type updates in the future here */
+
+      return var;
+   }
+   else
+      return NULL;
+}
+
+
+/**
  * Parse the initializer for a variable declaration.
  */
 static int
@@ -2036,7 +2095,7 @@
                       const slang_fully_specified_type * type)
 {
    GET_CURRENT_CONTEXT(ctx); /* a hack */
-   slang_variable *var;
+   slang_variable *var = NULL, *prevDecl;
    slang_atom a_name;
 
    /* empty init declatator (without name, e.g. "float ;") */
@@ -2046,29 +2105,41 @@
    a_name = parse_identifier(C);
 
    /* check if name is already in this scope */
-   if (_slang_variable_locate(O->vars, a_name, GL_FALSE)) {
-      slang_info_log_error(C->L,
+   prevDecl = _slang_variable_locate(O->vars, a_name, C->global_scope);
+   if (prevDecl) {
+      /* A var with this name has already been declared.
+       * Check if redeclaring the var with a different type/layout is legal.
+       */
+      if (C->global_scope) {
+         var = redeclare_variable(prevDecl, type);
+      }
+      if (!var) {
+         slang_info_log_error(C->L,
                    "declaration of '%s' conflicts with previous declaration",
                    (char *) a_name);
-      RETURN0;
+         RETURN0;
+      }
    }
 
-   /* make room for the new variable and initialize it */
-   var = slang_variable_scope_grow(O->vars);
    if (!var) {
-      slang_info_log_memory(C->L);
-      RETURN0;
-   }
+      /* make room for a new variable and initialize it */
+      var = slang_variable_scope_grow(O->vars);
+      if (!var) {
+         slang_info_log_memory(C->L);
+         RETURN0;
+      }
 
-   /* copy the declarator type qualifier/etc info, parse the identifier */
-   var->type.qualifier = type->qualifier;
-   var->type.centroid = type->centroid;
-   var->type.precision = type->precision;
-   var->type.variant = type->variant;
-   var->type.array_len = type->array_len;
-   var->a_name = a_name;
-   if (var->a_name == SLANG_ATOM_NULL)
-      RETURN0;
+      /* copy the declarator type qualifier/etc info, parse the identifier */
+      var->type.qualifier = type->qualifier;
+      var->type.centroid = type->centroid;
+      var->type.precision = type->precision;
+      var->type.variant = type->variant;
+      var->type.layout = type->layout;
+      var->type.array_len = type->array_len;
+      var->a_name = a_name;
+      if (var->a_name == SLANG_ATOM_NULL)
+         RETURN0;
+   }
 
    switch (*C->I++) {
    case VARIABLE_NONE:
@@ -2169,6 +2240,21 @@
             RETURN0;
       }
    }
+
+   if (var->type.qualifier == SLANG_QUAL_FIXEDINPUT &&
+       var->a_name == slang_atom_pool_atom(C->atoms, "gl_FragCoord")) {
+      /* set the program's PixelCenterInteger, OriginUpperLeft fields */
+      struct gl_fragment_program *fragProg =
+         (struct gl_fragment_program *) O->program;
+
+      if (var->type.layout & SLANG_LAYOUT_UPPER_LEFT_BIT) {
+         fragProg->OriginUpperLeft = GL_TRUE;
+      }
+      if (var->type.layout & SLANG_LAYOUT_PIXEL_CENTER_INTEGER_BIT) {
+         fragProg->PixelCenterInteger = GL_TRUE;
+      }
+   }
+
    return 1;
 }
 
@@ -2615,6 +2701,11 @@
       return GL_FALSE;
    }
 
+   if (type == SLANG_UNIT_FRAGMENT_SHADER) {
+      sl_pp_context_add_extension(context, "GL_ARB_fragment_coord_conventions");
+   }
+
+
 #if FEATURE_es2_glsl
    if (sl_pp_context_add_predefined(context, "GL_ES", "1") ||
        sl_pp_context_add_predefined(context, "GL_FRAGMENT_PRECISION_HIGH", "1")) {
diff --git a/src/mesa/shader/slang/slang_emit.c b/src/mesa/shader/slang/slang_emit.c
index c9ecbd2..0f67036 100644
--- a/src/mesa/shader/slang/slang_emit.c
+++ b/src/mesa/shader/slang/slang_emit.c
@@ -1122,6 +1122,8 @@
          return inst;
       }
    }
+#else
+   (void) inst;
 #endif
 
    if (!alloc_node_storage(emitInfo, n, n->Children[0]->Store->Size))
diff --git a/src/mesa/shader/slang/slang_link.c b/src/mesa/shader/slang/slang_link.c
index df524ce..75b0022 100644
--- a/src/mesa/shader/slang/slang_link.c
+++ b/src/mesa/shader/slang/slang_link.c
@@ -773,7 +773,7 @@
    _mesa_reference_vertprog(ctx, &shProg->VertexProgram, NULL);
    if (vertProg) {
       struct gl_vertex_program *linked_vprog =
-         vertex_program(_mesa_clone_program(ctx, &vertProg->Base));
+         _mesa_clone_vertex_program(ctx, vertProg);
       shProg->VertexProgram = linked_vprog; /* refcount OK */
       /* vertex program ID not significant; just set Id for debugging purposes */
       shProg->VertexProgram->Base.Id = shProg->Name;
@@ -783,7 +783,7 @@
    _mesa_reference_fragprog(ctx, &shProg->FragmentProgram, NULL);
    if (fragProg) {
       struct gl_fragment_program *linked_fprog = 
-         fragment_program(_mesa_clone_program(ctx, &fragProg->Base));
+         _mesa_clone_fragment_program(ctx, fragProg);
       shProg->FragmentProgram = linked_fprog; /* refcount OK */
       /* vertex program ID not significant; just set Id for debugging purposes */
       shProg->FragmentProgram->Base.Id = shProg->Name;
diff --git a/src/mesa/shader/slang/slang_typeinfo.c b/src/mesa/shader/slang/slang_typeinfo.c
index 4a48bc8..a96f2fb 100644
--- a/src/mesa/shader/slang/slang_typeinfo.c
+++ b/src/mesa/shader/slang/slang_typeinfo.c
@@ -258,6 +258,7 @@
    z.precision = y->precision;
    z.variant = y->variant;
    z.centroid = y->centroid;
+   z.layout = y->layout;
    z.array_len = y->array_len;
    if (!slang_type_specifier_copy(&z.specifier, &y->specifier)) {
       slang_fully_specified_type_destruct(&z);
@@ -269,6 +270,32 @@
 }
 
 
+/**
+ * Test if two fully specified types are compatible.  This is a bit
+ * looser than testing for equality.  We don't check the precision,
+ * variant, centroid, etc. information.
+ * XXX this may need some tweaking.
+ */
+GLboolean
+slang_fully_specified_types_compatible(const slang_fully_specified_type * x,
+                                       const slang_fully_specified_type * y)
+{
+   if (!slang_type_specifier_equal(&x->specifier, &y->specifier))
+      return GL_FALSE;
+
+   if (x->qualifier == SLANG_QUAL_FIXEDINPUT &&
+       y->qualifier == SLANG_QUAL_VARYING)
+      ; /* ok */
+   else if (x->qualifier != y->qualifier)
+      return GL_FALSE;
+
+   /* Note: don't compare precision, variant, centroid */
+
+   /* XXX array length? */
+
+   return GL_TRUE;
+}
+
 
 GLvoid
 slang_type_specifier_ctr(slang_type_specifier * self)
diff --git a/src/mesa/shader/slang/slang_typeinfo.h b/src/mesa/shader/slang/slang_typeinfo.h
index e6fecd3..aa5f14e 100644
--- a/src/mesa/shader/slang/slang_typeinfo.h
+++ b/src/mesa/shader/slang/slang_typeinfo.h
@@ -68,6 +68,18 @@
 } slang_type_centroid;
 
 
+/**
+ * These only apply to gl_FragCoord, but other layout qualifiers may
+ * appear in the future.
+ */
+typedef enum slang_layout_qualifier_
+{
+   SLANG_LAYOUT_NONE                      = 0x0,
+   SLANG_LAYOUT_UPPER_LEFT_BIT            = 0x1,
+   SLANG_LAYOUT_PIXEL_CENTER_INTEGER_BIT  = 0x2
+} slang_layout_qualifier;
+
+
 typedef enum slang_type_qualifier_
 {
    SLANG_QUAL_NONE,
@@ -170,8 +182,8 @@
 
 
 extern GLboolean
-slang_type_specifier_compatible(const slang_type_specifier * x,
-                                const slang_type_specifier * y);
+slang_type_specifier_compatible(const slang_type_specifier *x,
+                                const slang_type_specifier *y);
 
 
 typedef struct slang_fully_specified_type_
@@ -181,6 +193,7 @@
    slang_type_precision precision;
    slang_type_variant variant;
    slang_type_centroid centroid;
+   slang_layout_qualifier layout;
    GLint array_len;           /**< -1 if not an array type */
 } slang_fully_specified_type;
 
@@ -194,6 +207,9 @@
 slang_fully_specified_type_copy(slang_fully_specified_type *,
 				const slang_fully_specified_type *);
 
+GLboolean
+slang_fully_specified_types_compatible(const slang_fully_specified_type * x,
+                                       const slang_fully_specified_type * y);
 
 
 typedef struct slang_typeinfo_
diff --git a/src/mesa/sources.mak b/src/mesa/sources.mak
index 12d4c28..3543319 100644
--- a/src/mesa/sources.mak
+++ b/src/mesa/sources.mak
@@ -204,7 +204,6 @@
 	state_tracker/st_cb_readpixels.c \
 	state_tracker/st_cb_strings.c \
 	state_tracker/st_cb_texture.c \
-	state_tracker/st_cb_viewport.c \
 	state_tracker/st_context.c \
 	state_tracker/st_debug.c \
 	state_tracker/st_draw.c \
diff --git a/src/mesa/state_tracker/st_atom.c b/src/mesa/state_tracker/st_atom.c
index 73df44d..6a7ebff 100644
--- a/src/mesa/state_tracker/st_atom.c
+++ b/src/mesa/state_tracker/st_atom.c
@@ -35,7 +35,8 @@
 #include "st_cb_bitmap.h"
 #include "st_program.h"
 
-       
+#include "pipe/p_context.h"
+
 
 /**
  * This is used to initialize st->atoms[].
@@ -135,6 +136,10 @@
 
    check_program_state( st );
 
+   if (st->pipe->screen->update_buffer)
+      st->pipe->screen->update_buffer(st->pipe->screen,
+				      st->pipe->priv);
+
    if (state->st == 0)
       return;
 
diff --git a/src/mesa/state_tracker/st_atom_depth.c b/src/mesa/state_tracker/st_atom_depth.c
index 88b80a0..3c07afb 100644
--- a/src/mesa/state_tracker/st_atom_depth.c
+++ b/src/mesa/state_tracker/st_atom_depth.c
@@ -94,9 +94,11 @@
 update_depth_stencil_alpha(struct st_context *st)
 {
    struct pipe_depth_stencil_alpha_state *dsa = &st->state.depth_stencil;
+   struct pipe_stencil_ref sr;
    GLcontext *ctx = st->ctx;
 
    memset(dsa, 0, sizeof(*dsa));
+   memset(&sr, 0, sizeof(sr));
 
    if (ctx->Depth.Test && ctx->DrawBuffer->Visual.depthBits > 0) {
       dsa->depth.enabled = 1;
@@ -110,9 +112,9 @@
       dsa->stencil[0].fail_op = gl_stencil_op_to_pipe(ctx->Stencil.FailFunc[0]);
       dsa->stencil[0].zfail_op = gl_stencil_op_to_pipe(ctx->Stencil.ZFailFunc[0]);
       dsa->stencil[0].zpass_op = gl_stencil_op_to_pipe(ctx->Stencil.ZPassFunc[0]);
-      dsa->stencil[0].ref_value = ctx->Stencil.Ref[0] & 0xff;
       dsa->stencil[0].valuemask = ctx->Stencil.ValueMask[0] & 0xff;
       dsa->stencil[0].writemask = ctx->Stencil.WriteMask[0] & 0xff;
+      sr.ref_value[0] = ctx->Stencil.Ref[0] & 0xff;
 
       if (ctx->Stencil._TestTwoSide) {
          const GLuint back = ctx->Stencil._BackFace;
@@ -121,13 +123,17 @@
          dsa->stencil[1].fail_op = gl_stencil_op_to_pipe(ctx->Stencil.FailFunc[back]);
          dsa->stencil[1].zfail_op = gl_stencil_op_to_pipe(ctx->Stencil.ZFailFunc[back]);
          dsa->stencil[1].zpass_op = gl_stencil_op_to_pipe(ctx->Stencil.ZPassFunc[back]);
-         dsa->stencil[1].ref_value = ctx->Stencil.Ref[back] & 0xff;
          dsa->stencil[1].valuemask = ctx->Stencil.ValueMask[back] & 0xff;
          dsa->stencil[1].writemask = ctx->Stencil.WriteMask[back] & 0xff;
+         sr.ref_value[1] = ctx->Stencil.Ref[back] & 0xff;
       }
       else {
+         /* This should be unnecessary. Drivers must not expect this to
+          * contain valid data, except the enabled bit
+          */
          dsa->stencil[1] = dsa->stencil[0];
          dsa->stencil[1].enabled = 0;
+         sr.ref_value[1] = sr.ref_value[0];
       }
    }
 
@@ -138,6 +144,7 @@
    }
 
    cso_set_depth_stencil_alpha(st->cso_context, dsa);
+   cso_set_stencil_ref(st->cso_context, &sr);
 }
 
 
diff --git a/src/mesa/state_tracker/st_atom_sampler.c b/src/mesa/state_tracker/st_atom_sampler.c
index 9d63f1c..a8262a5 100644
--- a/src/mesa/state_tracker/st_atom_sampler.c
+++ b/src/mesa/state_tracker/st_atom_sampler.c
@@ -211,7 +211,7 @@
                             teximg ? teximg->_BaseFormat : GL_RGBA,
                             sampler->border_color);
 
-	 sampler->max_anisotropy = texobj->MaxAnisotropy;
+	 sampler->max_anisotropy = (texobj->MaxAnisotropy == 1.0 ? 0 : (GLuint)texobj->MaxAnisotropy);
 
          /* only care about ARB_shadow, not SGI shadow */
          if (texobj->CompareMode == GL_COMPARE_R_TO_TEXTURE) {
diff --git a/src/mesa/state_tracker/st_atom_shader.c b/src/mesa/state_tracker/st_atom_shader.c
index ea16719..ad151ed 100644
--- a/src/mesa/state_tracker/st_atom_shader.c
+++ b/src/mesa/state_tracker/st_atom_shader.c
@@ -59,7 +59,7 @@
 translate_fp(struct st_context *st,
              struct st_fragment_program *stfp)
 {
-   if (!stfp->state.tokens) {
+   if (!stfp->tgsi.tokens) {
       assert(stfp->Base.Base.NumInstructions > 0);
 
       st_translate_fragment_program(st, stfp);
diff --git a/src/mesa/state_tracker/st_cb_clear.c b/src/mesa/state_tracker/st_cb_clear.c
index 0c7bcb8..898c322 100644
--- a/src/mesa/state_tracker/st_cb_clear.c
+++ b/src/mesa/state_tracker/st_cb_clear.c
@@ -215,6 +215,7 @@
    */
 
    cso_save_blend(st->cso_context);
+   cso_save_stencil_ref(st->cso_context);
    cso_save_depth_stencil_alpha(st->cso_context);
    cso_save_rasterizer(st->cso_context);
    cso_save_fragment_shader(st->cso_context);
@@ -254,14 +255,17 @@
       }
 
       if (stencil) {
+         struct pipe_stencil_ref stencil_ref;
+         memset(&stencil_ref, 0, sizeof(stencil_ref));
          depth_stencil.stencil[0].enabled = 1;
          depth_stencil.stencil[0].func = PIPE_FUNC_ALWAYS;
          depth_stencil.stencil[0].fail_op = PIPE_STENCIL_OP_REPLACE;
          depth_stencil.stencil[0].zpass_op = PIPE_STENCIL_OP_REPLACE;
          depth_stencil.stencil[0].zfail_op = PIPE_STENCIL_OP_REPLACE;
-         depth_stencil.stencil[0].ref_value = ctx->Stencil.Clear;
          depth_stencil.stencil[0].valuemask = 0xff;
          depth_stencil.stencil[0].writemask = ctx->Stencil.WriteMask[0] & 0xff;
+         stencil_ref.ref_value[0] = ctx->Stencil.Clear;
+         cso_set_stencil_ref(st->cso_context, &stencil_ref);
       }
 
       cso_set_depth_stencil_alpha(st->cso_context, &depth_stencil);
@@ -277,10 +281,12 @@
 
    /* Restore pipe state */
    cso_restore_blend(st->cso_context);
+   cso_restore_stencil_ref(st->cso_context);
    cso_restore_depth_stencil_alpha(st->cso_context);
    cso_restore_rasterizer(st->cso_context);
    cso_restore_fragment_shader(st->cso_context);
    cso_restore_vertex_shader(st->cso_context);
+
 }
 
 
diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c
index 2a084ca..36c0a2b 100644
--- a/src/mesa/state_tracker/st_cb_drawpixels.c
+++ b/src/mesa/state_tracker/st_cb_drawpixels.c
@@ -93,8 +93,9 @@
 /**
  * Make fragment shader for glDraw/CopyPixels.  This shader is made
  * by combining the pixel transfer shader with the user-defined shader.
+ * \return pointer to Gallium driver fragment shader
  */
-static struct st_fragment_program *
+static void *
 combined_drawpix_fragment_program(GLcontext *ctx)
 {
    struct st_context *st = st_context(ctx);
@@ -113,7 +114,7 @@
        */
       if (is_passthrough_program(&st->fp->Base)) {
          stfp = (struct st_fragment_program *)
-            _mesa_clone_program(ctx, &st->pixel_xfer.program->Base.Base);
+            _mesa_clone_fragment_program(ctx, &st->pixel_xfer.program->Base);
       }
       else {
 #if 0
@@ -156,7 +157,7 @@
     */
    st_upload_constants(st, stfp->Base.Base.Parameters, PIPE_SHADER_FRAGMENT);
 
-   return stfp;
+   return stfp->driver_shader;
 }
 
 
@@ -164,8 +165,9 @@
  * Create fragment shader that does a TEX() instruction to get a Z
  * value, then writes to FRAG_RESULT_DEPTH.
  * Pass fragment color through as-is.
+ * \return pointer to the Gallium driver fragment shader
  */
-static struct st_fragment_program *
+static void *
 make_fragment_shader_z(struct st_context *st)
 {
    GLcontext *ctx = st->ctx;
@@ -173,7 +175,7 @@
    GLuint ic = 0;
 
    if (st->drawpix.z_shader) {
-      return st->drawpix.z_shader;
+      return st->drawpix.z_shader->driver_shader;
    }
 
    /*
@@ -223,7 +225,7 @@
    st->drawpix.z_shader = (struct st_fragment_program *) p;
    st_translate_fragment_program(st, st->drawpix.z_shader);
 
-   return st->drawpix.z_shader;
+   return st->drawpix.z_shader->driver_shader;
 }
 
 
@@ -233,8 +235,8 @@
  * vertex position and texcoord (and optionally, color).
  */
 static void *
-st_make_passthrough_vertex_shader(struct st_context *st, 
-                                  GLboolean passColor)
+make_passthrough_vertex_shader(struct st_context *st, 
+                               GLboolean passColor)
 {
    if (!st->drawpix.vert_shaders[passColor]) {
       struct ureg_program *ureg = 
@@ -270,8 +272,12 @@
 }
 
 
+/**
+ * Return a texture internalFormat for drawing/copying an image
+ * of the given type.
+ */
 static GLenum
-_mesa_base_format(GLenum format)
+base_format(GLenum format)
 {
    switch (format) {
    case GL_DEPTH_COMPONENT:
@@ -306,7 +312,7 @@
    GLenum baseFormat;
    int ptw, pth;
 
-   baseFormat = _mesa_base_format(format);
+   baseFormat = base_format(format);
 
    mformat = st_ChooseTextureFormat(ctx, baseFormat, format, type);
    assert(mformat);
@@ -764,10 +770,8 @@
               GLenum format, GLenum type,
               const struct gl_pixelstore_attrib *unpack, const GLvoid *pixels)
 {
-   struct st_fragment_program *stfp;
-   void *driver_vp;
+   void *driver_vp, *driver_fp;
    struct st_context *st = st_context(ctx);
-   struct pipe_surface *ps;
    const GLfloat *color;
 
    if (format == GL_STENCIL_INDEX ||
@@ -783,15 +787,13 @@
    st_validate_state(st);
 
    if (format == GL_DEPTH_COMPONENT) {
-      ps = st->state.framebuffer.zsbuf;
-      stfp = make_fragment_shader_z(st);
-      driver_vp = st_make_passthrough_vertex_shader(st, GL_TRUE);
+      driver_fp = make_fragment_shader_z(st);
+      driver_vp = make_passthrough_vertex_shader(st, GL_TRUE);
       color = ctx->Current.RasterColor;
    }
    else {
-      ps = st->state.framebuffer.cbufs[0];
-      stfp = combined_drawpix_fragment_program(ctx);
-      driver_vp = st_make_passthrough_vertex_shader(st, GL_FALSE);
+      driver_fp = combined_drawpix_fragment_program(ctx);
+      driver_vp = make_passthrough_vertex_shader(st, GL_FALSE);
       color = NULL;
    }
 
@@ -804,7 +806,7 @@
                             width, height, ctx->Pixel.ZoomX, ctx->Pixel.ZoomY,
                             pt, 
                             driver_vp, 
-                            stfp->driver_shader,
+                            driver_fp,
                             color, GL_FALSE);
          pipe_texture_reference(&pt, NULL);
       }
@@ -922,8 +924,7 @@
    struct pipe_context *pipe = st->pipe;
    struct pipe_screen *screen = pipe->screen;
    struct st_renderbuffer *rbRead;
-   void *driver_vp;
-   struct st_fragment_program *stfp;
+   void *driver_vp, *driver_fp;
    struct pipe_texture *pt;
    GLfloat *color;
    enum pipe_format srcFormat, texFormat;
@@ -970,15 +971,15 @@
    if (type == GL_COLOR) {
       rbRead = st_get_color_read_renderbuffer(ctx);
       color = NULL;
-      stfp = combined_drawpix_fragment_program(ctx);
-      driver_vp = st_make_passthrough_vertex_shader(st, GL_FALSE);
+      driver_fp = combined_drawpix_fragment_program(ctx);
+      driver_vp = make_passthrough_vertex_shader(st, GL_FALSE);
    }
    else {
       assert(type == GL_DEPTH);
       rbRead = st_renderbuffer(ctx->ReadBuffer->_DepthBuffer);
       color = ctx->Current.Attrib[VERT_ATTRIB_COLOR0];
-      stfp = make_fragment_shader_z(st);
-      driver_vp = st_make_passthrough_vertex_shader(st, GL_TRUE);
+      driver_fp = make_fragment_shader_z(st);
+      driver_vp = make_passthrough_vertex_shader(st, GL_TRUE);
    }
 
    srcFormat = rbRead->texture->format;
@@ -1112,7 +1113,7 @@
                       width, height, ctx->Pixel.ZoomX, ctx->Pixel.ZoomY,
                       pt, 
                       driver_vp, 
-                      stfp->driver_shader,
+                      driver_fp,
                       color, GL_TRUE);
 
    pipe_texture_reference(&pt, NULL);
diff --git a/src/mesa/state_tracker/st_cb_program.c b/src/mesa/state_tracker/st_cb_program.c
index 82ef557..2361b2e 100644
--- a/src/mesa/state_tracker/st_cb_program.c
+++ b/src/mesa/state_tracker/st_cb_program.c
@@ -148,9 +148,9 @@
             stfp->driver_shader = NULL;
          }
          
-         if (stfp->state.tokens) {
-            st_free_tokens(stfp->state.tokens);
-            stfp->state.tokens = NULL;
+         if (stfp->tgsi.tokens) {
+            st_free_tokens(stfp->tgsi.tokens);
+            stfp->tgsi.tokens = NULL;
          }
 
          if (stfp->bitmap_program) {
@@ -193,9 +193,9 @@
          stfp->driver_shader = NULL;
       }
 
-      if (stfp->state.tokens) {
-         st_free_tokens(stfp->state.tokens);
-         stfp->state.tokens = NULL;
+      if (stfp->tgsi.tokens) {
+         st_free_tokens(stfp->tgsi.tokens);
+         stfp->tgsi.tokens = NULL;
       }
 
       if (st->fp == stfp)
diff --git a/src/mesa/state_tracker/st_cb_queryobj.c b/src/mesa/state_tracker/st_cb_queryobj.c
index 2281d10..dc40c5d 100644
--- a/src/mesa/state_tracker/st_cb_queryobj.c
+++ b/src/mesa/state_tracker/st_cb_queryobj.c
@@ -130,13 +130,8 @@
 {
    struct pipe_context *pipe = ctx->st->pipe;
    struct st_query_object *stq = st_query_object(q);
-
-   if (!q->Ready) {
-      q->Ready = pipe->get_query_result(pipe, 
-					stq->pq,
-					FALSE,
-					&q->Result);
-   }
+   assert(!q->Ready);   /* we should not get called if Ready is TRUE */
+   q->Ready = pipe->get_query_result(pipe, stq->pq, FALSE, &q->Result);
 }
 
 
diff --git a/src/mesa/state_tracker/st_cb_rasterpos.c b/src/mesa/state_tracker/st_cb_rasterpos.c
index 42a1377..4692891 100644
--- a/src/mesa/state_tracker/st_cb_rasterpos.c
+++ b/src/mesa/state_tracker/st_cb_rasterpos.c
@@ -251,6 +251,14 @@
 
    /* draw the point */
    st_feedback_draw_vbo(ctx, rs->arrays, &rs->prim, 1, NULL, GL_TRUE, 0, 1);
+
+   /* restore draw's rasterization stage depending on rendermode */
+   if (ctx->RenderMode == GL_FEEDBACK) {
+      draw_set_rasterize_stage(draw, st->feedback_stage);
+   }
+   else if (ctx->RenderMode == GL_SELECT) {
+      draw_set_rasterize_stage(draw, st->selection_stage);
+   }
 }
 
 
diff --git a/src/mesa/state_tracker/st_cb_viewport.h b/src/mesa/state_tracker/st_cb_viewport.h
deleted file mode 100644
index 44948e5..0000000
--- a/src/mesa/state_tracker/st_cb_viewport.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/**************************************************************************
- * 
- * Copyright 2009 VMware, Inc.
- * 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"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- * 
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- * 
- **************************************************************************/
-
-extern void
-st_init_viewport_functions(struct dd_function_table *functions);
diff --git a/src/mesa/state_tracker/st_context.c b/src/mesa/state_tracker/st_context.c
index 8f6a0c2..5b3987d 100644
--- a/src/mesa/state_tracker/st_context.c
+++ b/src/mesa/state_tracker/st_context.c
@@ -56,7 +56,6 @@
 #include "st_cb_texture.h"
 #include "st_cb_flush.h"
 #include "st_cb_strings.h"
-#include "st_cb_viewport.h"
 #include "st_atom.h"
 #include "st_draw.h"
 #include "st_extensions.h"
@@ -343,7 +342,6 @@
    st_init_texture_functions(functions);
    st_init_flush_functions(functions);
    st_init_string_functions(functions);
-   st_init_viewport_functions(functions);
 
    functions->UpdateState = st_invalidate_state;
 }
diff --git a/src/mesa/state_tracker/st_debug.c b/src/mesa/state_tracker/st_debug.c
index 6e699ca..5dbabfa 100644
--- a/src/mesa/state_tracker/st_debug.c
+++ b/src/mesa/state_tracker/st_debug.c
@@ -87,11 +87,11 @@
 #endif
 
    if (st->vp->varients)
-      tgsi_dump( st->vp->varients[0].state.tokens, 0 );
+      tgsi_dump( st->vp->varients[0].tgsi.tokens, 0 );
    if (st->vp->Base.Base.Parameters)
       _mesa_print_parameter_list(st->vp->Base.Base.Parameters);
 
-   tgsi_dump( st->fp->state.tokens, 0 );
+   tgsi_dump( st->fp->tgsi.tokens, 0 );
    if (st->fp->Base.Base.Parameters)
       _mesa_print_parameter_list(st->fp->Base.Base.Parameters);
 }
diff --git a/src/mesa/state_tracker/st_draw.c b/src/mesa/state_tracker/st_draw.c
index e1dcb15..4b48c16 100644
--- a/src/mesa/state_tracker/st_draw.c
+++ b/src/mesa/state_tracker/st_draw.c
@@ -56,6 +56,7 @@
 #include "pipe/p_context.h"
 #include "pipe/p_defines.h"
 #include "util/u_inlines.h"
+#include "util/u_format.h"
 
 
 static GLuint double_types[4] = {
@@ -596,7 +597,7 @@
          printf("vlements[%d].vbuffer_index = %u\n", i, velements[i].vertex_buffer_index);
          printf("vlements[%d].src_offset = %u\n", i, velements[i].src_offset);
          printf("vlements[%d].nr_comps = %u\n", i, velements[i].nr_components);
-         printf("vlements[%d].format = %s\n", i, pf_name(velements[i].src_format));
+         printf("vlements[%d].format = %s\n", i, util_format_name(velements[i].src_format));
       }
    }
 #endif
@@ -645,20 +646,18 @@
       }
 
       /* draw */
-      if (nr_prims == 1 && pipe->draw_range_elements != NULL) {
-         i = 0;
-
+      if (pipe->draw_range_elements && min_index != ~0 && max_index != ~0) {
          /* XXX: exercise temporary path to pass min/max directly
           * through to driver & draw module.  These interfaces still
           * need a bit of work...
           */
-         prim = translate_prim( ctx, prims[i].mode );
+         for (i = 0; i < nr_prims; i++) {
+            prim = translate_prim( ctx, prims[i].mode );
 
-         pipe->draw_range_elements(pipe, indexBuf, indexSize,
-                                   min_index,
-                                   max_index,
-                                   prim,
-                                   prims[i].start + indexOffset, prims[i].count);
+            pipe->draw_range_elements(pipe, indexBuf, indexSize,
+                                      min_index, max_index, prim,
+                                      prims[i].start + indexOffset, prims[i].count);
+         }
       }
       else {
          for (i = 0; i < nr_prims; i++) {
diff --git a/src/mesa/state_tracker/st_draw_feedback.c b/src/mesa/state_tracker/st_draw_feedback.c
index 75ad1a9..087f2f2 100644
--- a/src/mesa/state_tracker/st_draw_feedback.c
+++ b/src/mesa/state_tracker/st_draw_feedback.c
@@ -119,7 +119,7 @@
 
    /* must get these after state validation! */
    vp = ctx->st->vp;
-   vs = &st->vp_varient->state;
+   vs = &st->vp_varient->tgsi;
 
    if (!st->vp_varient->draw_shader) {
       st->vp_varient->draw_shader = draw_create_vertex_shader(draw, vs);
diff --git a/src/mesa/state_tracker/st_format.c b/src/mesa/state_tracker/st_format.c
index 3ffc2ae..851c16f 100644
--- a/src/mesa/state_tracker/st_format.c
+++ b/src/mesa/state_tracker/st_format.c
@@ -85,7 +85,7 @@
    if (desc->layout == UTIL_FORMAT_LAYOUT_ARITH ||
        desc->layout == UTIL_FORMAT_LAYOUT_ARRAY) {
 #if 0
-      printf("%s\n", pf_name( format ) );
+      printf("%s\n", util_format_name( format ) );
 #endif
 
       /* Data type */
diff --git a/src/mesa/state_tracker/st_program.c b/src/mesa/state_tracker/st_program.c
index 21ad6fe..7ce3938 100644
--- a/src/mesa/state_tracker/st_program.c
+++ b/src/mesa/state_tracker/st_program.c
@@ -68,8 +68,8 @@
       if (vpv->draw_shader)
          draw_delete_vertex_shader( st->draw, vpv->draw_shader );
       
-      if (vpv->state.tokens)
-         st_free_tokens(vpv->state.tokens);
+      if (vpv->tgsi.tokens)
+         st_free_tokens(vpv->tgsi.tokens);
       
       FREE( vpv );
 
@@ -236,13 +236,13 @@
    if (error)
       goto fail;
 
-   vpv->state.tokens = ureg_get_tokens( ureg, NULL );
-   if (!vpv->state.tokens)
+   vpv->tgsi.tokens = ureg_get_tokens( ureg, NULL );
+   if (!vpv->tgsi.tokens)
       goto fail;
 
    ureg_destroy( ureg );
 
-   vpv->driver_shader = pipe->create_vs_state(pipe, &vpv->state);
+   vpv->driver_shader = pipe->create_vs_state(pipe, &vpv->tgsi);
 
    if ((ST_DEBUG & DEBUG_TGSI) && (ST_DEBUG & DEBUG_MESA)) {
       _mesa_print_program(&stvp->Base.Base);
@@ -250,7 +250,7 @@
    }
 
    if (ST_DEBUG & DEBUG_TGSI) {
-      tgsi_dump( vpv->state.tokens, 0 );
+      tgsi_dump( vpv->tgsi.tokens, 0 );
       debug_printf("\n");
    }
 
@@ -278,12 +278,14 @@
    struct pipe_context *pipe = st->pipe;
    GLuint outputMapping[FRAG_RESULT_MAX];
    GLuint inputMapping[FRAG_ATTRIB_MAX];
-   GLuint interpMode[16];  /* XXX size? */
+   GLuint interpMode[PIPE_MAX_SHADER_INPUTS];  /* XXX size? */
    GLuint attr;
    enum pipe_error error;
    const GLbitfield inputsRead = stfp->Base.Base.InputsRead;
    struct ureg_program *ureg;
 
+   ubyte input_semantic_name[PIPE_MAX_SHADER_INPUTS];
+   ubyte input_semantic_index[PIPE_MAX_SHADER_INPUTS];
    uint fs_num_inputs = 0;
 
    ubyte fs_output_semantic_name[PIPE_MAX_SHADER_OUTPUTS];
@@ -301,28 +303,28 @@
 
          switch (attr) {
          case FRAG_ATTRIB_WPOS:
-            stfp->input_semantic_name[slot] = TGSI_SEMANTIC_POSITION;
-            stfp->input_semantic_index[slot] = 0;
+            input_semantic_name[slot] = TGSI_SEMANTIC_POSITION;
+            input_semantic_index[slot] = 0;
             interpMode[slot] = TGSI_INTERPOLATE_LINEAR;
             break;
          case FRAG_ATTRIB_COL0:
-            stfp->input_semantic_name[slot] = TGSI_SEMANTIC_COLOR;
-            stfp->input_semantic_index[slot] = 0;
+            input_semantic_name[slot] = TGSI_SEMANTIC_COLOR;
+            input_semantic_index[slot] = 0;
             interpMode[slot] = TGSI_INTERPOLATE_LINEAR;
             break;
          case FRAG_ATTRIB_COL1:
-            stfp->input_semantic_name[slot] = TGSI_SEMANTIC_COLOR;
-            stfp->input_semantic_index[slot] = 1;
+            input_semantic_name[slot] = TGSI_SEMANTIC_COLOR;
+            input_semantic_index[slot] = 1;
             interpMode[slot] = TGSI_INTERPOLATE_LINEAR;
             break;
          case FRAG_ATTRIB_FOGC:
-            stfp->input_semantic_name[slot] = TGSI_SEMANTIC_FOG;
-            stfp->input_semantic_index[slot] = 0;
+            input_semantic_name[slot] = TGSI_SEMANTIC_FOG;
+            input_semantic_index[slot] = 0;
             interpMode[slot] = TGSI_INTERPOLATE_PERSPECTIVE;
             break;
          case FRAG_ATTRIB_FACE:
-            stfp->input_semantic_name[slot] = TGSI_SEMANTIC_FACE;
-            stfp->input_semantic_index[slot] = 0;
+            input_semantic_name[slot] = TGSI_SEMANTIC_FACE;
+            input_semantic_index[slot] = 0;
             interpMode[slot] = TGSI_INTERPOLATE_CONSTANT;
             break;
          case FRAG_ATTRIB_PNTC:
@@ -331,8 +333,8 @@
              * shader input is the point coord attribute so that it can set
              * up the right vertex attribute values.
              */
-            stfp->input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
-            stfp->input_semantic_index[slot] = 0;
+            input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
+            input_semantic_index[slot] = 0;
             interpMode[slot] = TGSI_INTERPOLATE_PERSPECTIVE;
             break;
 
@@ -365,8 +367,8 @@
              * readability of the generated TGSI.
              */
             assert(attr >= FRAG_ATTRIB_TEX0);
-            stfp->input_semantic_index[slot] = (attr - FRAG_ATTRIB_TEX0);
-            stfp->input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
+            input_semantic_index[slot] = (attr - FRAG_ATTRIB_TEX0);
+            input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
             interpMode[slot] = TGSI_INTERPOLATE_PERSPECTIVE;
             break;
          }
@@ -428,8 +430,8 @@
                                 /* inputs */
                                 fs_num_inputs,
                                 inputMapping,
-                                stfp->input_semantic_name,
-                                stfp->input_semantic_index,
+                                input_semantic_name,
+                                input_semantic_index,
                                 interpMode,
                                 /* outputs */
                                 fs_num_outputs,
@@ -437,9 +439,9 @@
                                 fs_output_semantic_name,
                                 fs_output_semantic_index, FALSE );
 
-   stfp->state.tokens = ureg_get_tokens( ureg, NULL );
+   stfp->tgsi.tokens = ureg_get_tokens( ureg, NULL );
    ureg_destroy( ureg );
-   stfp->driver_shader = pipe->create_fs_state(pipe, &stfp->state);
+   stfp->driver_shader = pipe->create_fs_state(pipe, &stfp->tgsi);
 
    if ((ST_DEBUG & DEBUG_TGSI) && (ST_DEBUG & DEBUG_MESA)) {
       _mesa_print_program(&stfp->Base.Base);
@@ -447,7 +449,7 @@
    }
 
    if (ST_DEBUG & DEBUG_TGSI) {
-      tgsi_dump( stfp->state.tokens, 0/*TGSI_DUMP_VERBOSE*/ );
+      tgsi_dump( stfp->tgsi.tokens, 0/*TGSI_DUMP_VERBOSE*/ );
       debug_printf("\n");
    }
 }
diff --git a/src/mesa/state_tracker/st_program.h b/src/mesa/state_tracker/st_program.h
index d9822e5..1b3f75c 100644
--- a/src/mesa/state_tracker/st_program.h
+++ b/src/mesa/state_tracker/st_program.h
@@ -52,10 +52,7 @@
    struct gl_fragment_program Base;
    GLuint serialNo;
 
-   ubyte input_semantic_name[PIPE_MAX_SHADER_INPUTS];
-   ubyte input_semantic_index[PIPE_MAX_SHADER_INPUTS];
-
-   struct pipe_shader_state state;
+   struct pipe_shader_state tgsi;
    void *driver_shader;
 
    /** Program prefixed with glBitmap prologue */
@@ -82,9 +79,11 @@
     */
    struct st_vp_varient_key key;
 
-   /** TGSI tokens -- why?
+   /**
+    * TGSI tokens (to later generate a 'draw' module shader for
+    * selection/feedback/rasterpos)
     */
-   struct pipe_shader_state state;
+   struct pipe_shader_state tgsi;
 
    /** Driver's compiled shader */
    void *driver_shader;
diff --git a/src/mesa/swrast/s_aatritemp.h b/src/mesa/swrast/s_aatritemp.h
index a8b22c5..76d4005 100644
--- a/src/mesa/swrast/s_aatritemp.h
+++ b/src/mesa/swrast/s_aatritemp.h
@@ -328,11 +328,11 @@
          
 #if defined(DO_ATTRIBS)
          /* compute attributes at left-most fragment */
-         span.attrStart[FRAG_ATTRIB_WPOS][3] = solve_plane(ix + 1.5, iy + 0.5F, wPlane);
+         span.attrStart[FRAG_ATTRIB_WPOS][3] = solve_plane(ix + 1.5F, iy + 0.5F, wPlane);
          ATTRIB_LOOP_BEGIN
             GLuint c;
             for (c = 0; c < 4; c++) {
-               span.attrStart[attr][c] = solve_plane(ix + 1.5, iy + 0.5F, attrPlane[attr][c]);
+               span.attrStart[attr][c] = solve_plane(ix + 1.5F, iy + 0.5F, attrPlane[attr][c]);
             }
          ATTRIB_LOOP_END
 #endif
diff --git a/src/mesa/swrast/s_atifragshader.c b/src/mesa/swrast/s_atifragshader.c
index 05da64d..0f06cdf 100644
--- a/src/mesa/swrast/s_atifragshader.c
+++ b/src/mesa/swrast/s_atifragshader.c
@@ -86,7 +86,7 @@
          q = 0.000000001F;
       values[0] = s / q;
       values[1] = t / q;
-      values[2] = 1.0 / q;
+      values[2] = 1.0F / q;
       break;
    }
    values[3] = 0.0;
@@ -138,7 +138,7 @@
 	 val[i] = 1 - val[i];
 
       if (mod & GL_BIAS_BIT_ATI)
-	 val[i] = val[i] - 0.5;
+	 val[i] = val[i] - 0.5F;
 
       if (mod & GL_2X_BIT_ATI)
 	 val[i] = 2 * val[i];
diff --git a/src/mesa/swrast/s_clear.c b/src/mesa/swrast/s_clear.c
index 21167a6..820297f 100644
--- a/src/mesa/swrast/s_clear.c
+++ b/src/mesa/swrast/s_clear.c
@@ -77,7 +77,7 @@
       UNCLAMPED_FLOAT_TO_USHORT(clearColor[BCOMP], ctx->Color.ClearColor[2]);
       UNCLAMPED_FLOAT_TO_USHORT(clearColor[ACOMP], ctx->Color.ClearColor[3]);
       for (i = 0; i < width; i++) {
-         COPY_4V(span.array->rgba[i], clearColor);
+         COPY_4V_CAST(span.array->rgba[i], clearColor, GLchan);
       }
    }
    else {
diff --git a/src/mesa/swrast/s_texcombine.c b/src/mesa/swrast/s_texcombine.c
index 95e2c08..f322663 100644
--- a/src/mesa/swrast/s_texcombine.c
+++ b/src/mesa/swrast/s_texcombine.c
@@ -368,7 +368,7 @@
                            (arg0[i][GCOMP] - 0.5F) * (arg1[i][GCOMP] - 0.5F) +
                            (arg0[i][BCOMP] - 0.5F) * (arg1[i][BCOMP] - 0.5F))
                * 4.0F * scaleRGB;
-            dot = CLAMP(dot, 0.0, 1.0F);
+            dot = CLAMP(dot, 0.0F, 1.0F);
             rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = dot;
          }
          break;
diff --git a/src/mesa/swrast_setup/ss_context.c b/src/mesa/swrast_setup/ss_context.c
index 61172f9..23d3cb3 100644
--- a/src/mesa/swrast_setup/ss_context.c
+++ b/src/mesa/swrast_setup/ss_context.c
@@ -122,7 +122,7 @@
                            swsetup->last_index_bitset)) {
       DECLARE_RENDERINPUTS(index_bitset);
       struct tnl_attr_map map[_TNL_ATTRIB_MAX];
-      int i, e = 0;
+      unsigned int i, e = 0;
 
       swsetup->intColors = intColors;
 
diff --git a/src/mesa/swrast_setup/ss_tritmp.h b/src/mesa/swrast_setup/ss_tritmp.h
index d9bf54d..b9b78e1 100644
--- a/src/mesa/swrast_setup/ss_tritmp.h
+++ b/src/mesa/swrast_setup/ss_tritmp.h
@@ -132,9 +132,9 @@
 		  saved_index[1] = v[1]->attrib[FRAG_ATTRIB_CI][0];
 		  saved_index[2] = v[2]->attrib[FRAG_ATTRIB_CI][0];
 		  
-		  SS_IND(v[0]->attrib[FRAG_ATTRIB_CI][0], (GLuint) vbindex[e0]);
-		  SS_IND(v[1]->attrib[FRAG_ATTRIB_CI][0], (GLuint) vbindex[e1]);
-		  SS_IND(v[2]->attrib[FRAG_ATTRIB_CI][0], (GLuint) vbindex[e2]);
+		  SS_IND(v[0]->attrib[FRAG_ATTRIB_CI][0], vbindex[e0]);
+		  SS_IND(v[1]->attrib[FRAG_ATTRIB_CI][0], vbindex[e1]);
+		  SS_IND(v[2]->attrib[FRAG_ATTRIB_CI][0], vbindex[e2]);
 	       }
 	    }
 	 }
@@ -159,9 +159,9 @@
 	    offset += MAX2(dzdx, dzdy) * ctx->Polygon.OffsetFactor;
 	 }
          /* new Z values */
-         oz0 = CLAMP(v[0]->attrib[FRAG_ATTRIB_WPOS][2] + offset, 0.0, max);
-         oz1 = CLAMP(v[1]->attrib[FRAG_ATTRIB_WPOS][2] + offset, 0.0, max);
-         oz2 = CLAMP(v[2]->attrib[FRAG_ATTRIB_WPOS][2] + offset, 0.0, max);
+         oz0 = CLAMP(v[0]->attrib[FRAG_ATTRIB_WPOS][2] + offset, 0.0F, max);
+         oz1 = CLAMP(v[1]->attrib[FRAG_ATTRIB_WPOS][2] + offset, 0.0F, max);
+         oz2 = CLAMP(v[2]->attrib[FRAG_ATTRIB_WPOS][2] + offset, 0.0F, max);
       }
    }
 
diff --git a/src/mesa/tnl/t_draw.c b/src/mesa/tnl/t_draw.c
index 812d712..149f693 100644
--- a/src/mesa/tnl/t_draw.c
+++ b/src/mesa/tnl/t_draw.c
@@ -429,7 +429,7 @@
 			_tnl_vbo_draw_prims );
       return;
    }
-   else if (max_index + max_basevertex > max) {
+   else if ((GLint)max_index + max_basevertex > 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/vbo/vbo_exec_array.c b/src/mesa/vbo/vbo_exec_array.c
index 88502f3..a284e40 100644
--- a/src/mesa/vbo/vbo_exec_array.c
+++ b/src/mesa/vbo/vbo_exec_array.c
@@ -935,13 +935,13 @@
       vbo->draw_prims(ctx, exec->array.inputs, prim, primcount, &ib,
 		      GL_FALSE, ~0, ~0);
    } else {
+      /* render one prim at a time */
       for (i = 0; i < primcount; i++) {
 	 ib.count = count[i];
 	 ib.type = type;
 	 ib.obj = ctx->Array.ElementArrayBufferObj;
 	 ib.ptr = indices[i];
 
-
 	 prim[0].begin = 1;
 	 prim[0].end = 1;
 	 prim[0].weak = 0;
@@ -954,11 +954,12 @@
 	    prim[0].basevertex = basevertex[i];
 	 else
 	    prim[0].basevertex = 0;
-      }
 
-      vbo->draw_prims(ctx, exec->array.inputs, prim, 1, &ib,
-		      GL_FALSE, ~0, ~0);
+         vbo->draw_prims(ctx, exec->array.inputs, prim, 1, &ib,
+                         GL_FALSE, ~0, ~0);
+      }
    }
+
    _mesa_free(prim);
 }